kaddressbook Library API Documentation

viewmanager.cpp

00001 /* 00002 This file is part of KAddressBook. 00003 Copyright (c) 2002 Mike Pilone <mpilone@slac.com> 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or 00008 (at your option) any later version. 00009 00010 This program is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software 00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 00019 As a special exception, permission is given to link this program 00020 with any edition of Qt, and distribute the resulting executable, 00021 without including the source code for Qt in the source distribution. 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()->mViewNames; 00073 QString activeViewName = KABPrefs::instance()->mCurrentView; 00074 00075 mActionSelectView->setItems( mViewNameList ); 00076 00077 // Filter 00078 mFilterList = Filter::restore( mCore->config(), "Filter" ); 00079 mFilterSelectionWidget->setItems( filterNames() ); 00080 mFilterSelectionWidget->setCurrentItem( KABPrefs::instance()->mCurrentFilter ); 00081 00082 // Tell the views to reread their config, since they may have 00083 // been modified by global settings 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()->mCurrentFilter = mFilterSelectionWidget->currentItem(); 00105 00106 // write the view name list 00107 KABPrefs::instance()->mViewNames = mViewNameList; 00108 00109 if ( mActiveView ) 00110 KABPrefs::instance()->mCurrentView = 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 QStringList uids = selectedUids(); 00133 QStringList::Iterator it; 00134 for ( it = uids.begin(); it != uids.end(); ++it ) { 00135 KABC::Addressee addr = mCore->addressBook()->findByUid( *it ); 00136 if ( !addr.isEmpty() ) 00137 list.append( addr ); 00138 } 00139 00140 return list; 00141 } 00142 00143 void ViewManager::setFilterSelectionWidget( FilterSelectionWidget *wdg ) 00144 { 00145 mFilterSelectionWidget = wdg; 00146 } 00147 00148 KABC::Field *ViewManager::currentSortField() const 00149 { 00150 if ( mActiveView ) 00151 return mActiveView->sortField(); 00152 else 00153 return 0; 00154 } 00155 00156 void ViewManager::setSelected( const QString &uid, bool selected ) 00157 { 00158 if ( mActiveView ) 00159 mActiveView->setSelected( uid, selected ); 00160 } 00161 00162 void ViewManager::unloadViews() 00163 { 00164 mViewDict.clear(); 00165 mActiveView = 0; 00166 } 00167 00168 void ViewManager::setActiveView( const QString &name ) 00169 { 00170 KAddressBookView *view = 0; 00171 00172 // Check that this isn't the same as the current active view 00173 if ( mActiveView && ( mActiveView->caption() == name ) ) 00174 return; 00175 00176 // At this point we know the view that should be active is not 00177 // currently active. We will try to find the new on in the list. If 00178 // we can't find it, it means it hasn't been instantiated, so we will 00179 // create it on demand. 00180 00181 view = mViewDict.find( name ); 00182 00183 // Check if we found the view. If we didn't, then we need to create it 00184 if ( view == 0 ) { 00185 KConfig *config = mCore->config(); 00186 KConfigGroupSaver saver( config, name ); 00187 QString type = config->readEntry( "Type", "Table" ); 00188 00189 kdDebug(5720) << "ViewManager::setActiveView: creating view - " << name << endl; 00190 00191 ViewFactory *factory = mViewFactoryDict.find( type ); 00192 if ( factory ) 00193 view = factory->view( mCore, mViewWidgetStack ); 00194 00195 if ( view ) { 00196 view->setCaption( name ); 00197 mViewDict.insert( name, view ); 00198 mViewWidgetStack->addWidget( view ); 00199 view->readConfig( config ); 00200 00201 // The manager just relays the signals 00202 connect( view, SIGNAL( selected( const QString& ) ), 00203 SIGNAL( selected( const QString & ) ) ); 00204 connect( view, SIGNAL( executed( const QString& ) ), 00205 SIGNAL( executed( const QString& ) ) ); 00206 connect( view, SIGNAL( modified() ), SIGNAL( modified() ) ); 00207 connect( view, SIGNAL( dropped( QDropEvent* ) ), 00208 SLOT( dropped( QDropEvent* ) ) ); 00209 connect( view, SIGNAL( startDrag() ), SLOT( startDrag() ) ); 00210 connect( view, SIGNAL( sortFieldChanged() ), SIGNAL( sortFieldChanged() ) ); 00211 } 00212 } 00213 00214 // If we found or created the view, raise it and refresh it 00215 if ( view ) { 00216 mActiveView = view; 00217 mViewWidgetStack->raiseWidget( view ); 00218 // Set the proper filter in the view. By setting the combo 00219 // box, the activated slot will be called, which will push 00220 // the filter to the view and refresh it. 00221 if ( view->defaultFilterType() == KAddressBookView::None ) { 00222 mFilterSelectionWidget->setCurrentItem( 0 ); 00223 setActiveFilter( 0 ); 00224 } else if ( view->defaultFilterType() == KAddressBookView::Active ) { 00225 setActiveFilter( mFilterSelectionWidget->currentItem() ); 00226 } else { 00227 uint pos = filterPosition( view->defaultFilterName() ); 00228 mFilterSelectionWidget->setCurrentItem( pos ); 00229 setActiveFilter( pos ); 00230 } 00231 00232 // Update the inc search widget to show the fields in the new active 00233 // view. 00234 mActiveView->refresh(); 00235 00236 } else 00237 kdDebug(5720) << "ViewManager::setActiveView: unable to find view\n"; 00238 } 00239 00240 void ViewManager::refreshView( const QString &uid ) 00241 { 00242 if ( mActiveView ) 00243 mActiveView->refresh( uid ); 00244 } 00245 00246 void ViewManager::editView() 00247 { 00248 if ( !mActiveView ) 00249 return; 00250 00251 ViewFactory *factory = mViewFactoryDict.find( mActiveView->type() ); 00252 ViewConfigureWidget *wdg = 0; 00253 00254 if ( factory ) { 00255 // Save the filters so the dialog has the latest set 00256 Filter::save( mCore->config(), "Filter", mFilterList ); 00257 00258 wdg = factory->configureWidget( mCore->addressBook(), 0 ); 00259 } 00260 00261 if ( wdg ) { 00262 ViewConfigureDialog dlg( wdg, mActiveView->caption(), this ); 00263 00264 KConfigGroupSaver saver( mCore->config(), mActiveView->caption() ); 00265 dlg.restoreSettings( mCore->config() ); 00266 00267 if ( dlg.exec() ) { 00268 dlg.saveSettings( mCore->config() ); 00269 mActiveView->readConfig( mCore->config() ); 00270 // Set the proper filter in the view. By setting the combo 00271 // box, the activated slot will be called, which will push 00272 // the filter to the view and refresh it. 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 mActiveView->refresh(); 00285 } 00286 } 00287 } 00288 00289 void ViewManager::deleteView() 00290 { 00291 QString text = i18n( "<qt>Are you sure that you want to delete the view <b>%1</b>?</qt>" ) 00292 .arg( mActiveView->caption() ); 00293 QString caption = i18n( "Confirm Delete" ); 00294 00295 if ( KMessageBox::warningContinueCancel( this, text, caption, KGuiItem( i18n("&Delete"), "editdelete") ) == KMessageBox::Continue ) { 00296 mViewNameList.remove( mActiveView->caption() ); 00297 00298 // remove the view from the config file 00299 KConfig *config = mCore->config(); 00300 config->deleteGroup( mActiveView->caption() ); 00301 00302 mViewDict.remove( mActiveView->caption() ); 00303 mActiveView = 0; 00304 00305 // we are in an invalid state now, but that should be fixed after 00306 // we emit the signal 00307 mActionSelectView->setItems( mViewNameList ); 00308 if ( mViewNameList.count() > 0 ) { 00309 mActionSelectView->setCurrentItem( 0 ); 00310 setActiveView( mViewNameList[ 0 ] ); 00311 } 00312 mActionDeleteView->setEnabled( mViewNameList.count() > 1 ); 00313 } 00314 } 00315 00316 void ViewManager::addView() 00317 { 00318 AddViewDialog dialog( &mViewFactoryDict, this ); 00319 00320 if ( dialog.exec() ) { 00321 QString newName = dialog.viewName(); 00322 QString type = dialog.viewType(); 00323 00324 // Check for name conflicts 00325 bool firstConflict = true; 00326 int numTries = 1; 00327 while ( mViewNameList.contains( newName ) > 0 ) { 00328 if ( !firstConflict ) { 00329 newName = newName.left( newName.length() - 4 ); 00330 firstConflict = false; 00331 } 00332 00333 newName = QString( "%1 <%2>" ).arg( newName ).arg( numTries ); 00334 numTries++; 00335 } 00336 00337 // Add the new one to the list 00338 mViewNameList.append( newName ); 00339 00340 // write the view to the config file, 00341 KConfig *config = mCore->config(); 00342 config->deleteGroup( newName ); 00343 KConfigGroupSaver saver( config, newName ); 00344 config->writeEntry( "Type", type ); 00345 00346 // try to set the active view 00347 mActionSelectView->setItems( mViewNameList ); 00348 mActionSelectView->setCurrentItem( mViewNameList.findIndex( newName ) ); 00349 setActiveView( newName ); 00350 00351 editView(); 00352 00353 mActionDeleteView->setEnabled( mViewNameList.count() > 1 ); 00354 } 00355 } 00356 00357 void ViewManager::createViewFactories() 00358 { 00359 KTrader::OfferList plugins = KTrader::self()->query( "KAddressBook/View" ); 00360 KTrader::OfferList::ConstIterator it; 00361 for ( it = plugins.begin(); it != plugins.end(); ++it ) { 00362 if ( !(*it)->hasServiceType( "KAddressBook/View" ) ) 00363 continue; 00364 00365 KLibFactory *factory = KLibLoader::self()->factory( (*it)->library().latin1() ); 00366 00367 if ( !factory ) { 00368 kdDebug(5720) << "ViewManager::createViewFactories(): Factory creation failed" << endl; 00369 continue; 00370 } 00371 00372 ViewFactory *viewFactory = static_cast<ViewFactory*>( factory ); 00373 00374 if ( !viewFactory ) { 00375 kdDebug(5720) << "ViewManager::createViewFactories(): Cast failed" << endl; 00376 continue; 00377 } 00378 00379 mViewFactoryDict.insert( viewFactory->type(), viewFactory ); 00380 } 00381 } 00382 00383 void ViewManager::dropped( QDropEvent *e ) 00384 { 00385 kdDebug(5720) << "ViewManager::dropped: got a drop event" << endl; 00386 00387 // don't allow drops from our own drags 00388 if ( e->source() == this ) 00389 return; 00390 00391 QString clipText, vcards; 00392 KURL::List urls; 00393 00394 if ( KURLDrag::decode( e, urls) ) { 00395 KURL::List::Iterator it = urls.begin(); 00396 int c = urls.count(); 00397 if ( c > 1 ) { 00398 QString questionString = i18n( "Import one contact into your addressbook?", "Import %n contacts into your addressbook?", c ); 00399 if ( KMessageBox::questionYesNo( this, questionString, i18n( "Import Contacts?" ) ) == KMessageBox::Yes ) { 00400 for ( ; it != urls.end(); ++it ) 00401 emit urlDropped( *it ); 00402 } 00403 } else if ( c == 1 ) 00404 emit urlDropped( *it ); 00405 } else if ( KVCardDrag::decode( e, vcards ) ) { 00406 KABC::VCardConverter converter; 00407 00408 KABC::Addressee::List list = converter.parseVCards( vcards ); 00409 KABC::Addressee::List::Iterator it; 00410 for ( it = list.begin(); it != list.end(); ++it ) { 00411 KABC::Addressee a = mCore->addressBook()->findByUid( (*it).uid() ); 00412 if ( a.isEmpty() ) { // not yet in address book 00413 mCore->addressBook()->insertAddressee( *it ); 00414 emit modified(); 00415 } 00416 } 00417 00418 mActiveView->refresh(); 00419 } 00420 } 00421 00422 void ViewManager::startDrag() 00423 { 00424 // Get the list of all the selected addressees 00425 KABC::Addressee::List addrList; 00426 QStringList uidList = selectedUids(); 00427 if ( uidList.isEmpty() ) 00428 return; 00429 kdDebug(5720) << "ViewManager::startDrag: starting to drag" << endl; 00430 00431 QStringList::Iterator it; 00432 for ( it = uidList.begin(); it != uidList.end(); ++it ) 00433 addrList.append( mCore->addressBook()->findByUid( *it ) ); 00434 00435 KMultipleDrag *drag = new KMultipleDrag( this ); 00436 00437 KABC::VCardConverter converter; 00438 QString vcards = converter.createVCards( addrList ); 00439 00440 KTempDir tempDir; 00441 if ( tempDir.status() == 0 ) { 00442 QString fileName; 00443 if ( addrList.count() == 1 ) 00444 fileName = addrList[ 0 ].givenName() + "_" + addrList[ 0 ].familyName() + ".vcf"; 00445 else 00446 fileName = "contacts.vcf"; 00447 00448 QFile tempFile( tempDir.name() + "/" + fileName ); 00449 if ( tempFile.open( IO_WriteOnly ) ) { 00450 tempFile.writeBlock( vcards.utf8() ); 00451 tempFile.close(); 00452 00453 KURLDrag *urlDrag = new KURLDrag( KURL( tempFile.name() ), this ); 00454 drag->addDragObject( urlDrag ); 00455 } 00456 } 00457 00458 drag->addDragObject( new KVCardDrag( vcards, this ) ); 00459 drag->addDragObject( new QTextDrag( AddresseeUtil::addresseesToEmails( addrList ), this ) ); 00460 00461 drag->setPixmap( KGlobal::iconLoader()->loadIcon( "vcard", KIcon::Desktop ) ); 00462 drag->dragCopy(); 00463 } 00464 00465 void ViewManager::setActiveFilter( int index ) 00466 { 00467 Filter currentFilter; 00468 00469 if ( ( index - 1 ) < 0 ) 00470 currentFilter = Filter(); 00471 else 00472 currentFilter = mFilterList[ index - 1 ]; 00473 00474 // Check if we have a view. Since the filter combo is created before 00475 // the view, this slot could be called before there is a valid view. 00476 if ( mActiveView ) { 00477 mActiveView->setFilter( currentFilter ); 00478 mActiveView->refresh(); 00479 emit selected( QString::null ); 00480 } 00481 } 00482 00483 void ViewManager::configureFilters() 00484 { 00485 FilterDialog dlg( this ); 00486 00487 dlg.setFilters( mFilterList ); 00488 00489 if ( dlg.exec() ) 00490 mFilterList = dlg.filters(); 00491 00492 uint pos = mFilterSelectionWidget->currentItem(); 00493 mFilterSelectionWidget->setItems( filterNames() ); 00494 mFilterSelectionWidget->setCurrentItem( pos ); 00495 setActiveFilter( pos ); 00496 } 00497 00498 QStringList ViewManager::filterNames() const 00499 { 00500 QStringList names( i18n( "None" ) ); 00501 00502 Filter::List::ConstIterator it; 00503 for ( it = mFilterList.begin(); it != mFilterList.end(); ++it ) 00504 names.append( (*it).name() ); 00505 00506 return names; 00507 } 00508 00509 int ViewManager::filterPosition( const QString &name ) const 00510 { 00511 int pos = 0; 00512 00513 Filter::List::ConstIterator it; 00514 for ( it = mFilterList.begin(); it != mFilterList.end(); ++it, ++pos ) 00515 if ( name == (*it).name() ) 00516 return pos + 1; 00517 00518 return 0; 00519 } 00520 00521 void ViewManager::initActions() 00522 { 00523 mActionSelectView = new KSelectAction( i18n( "Select View" ), 0, mCore->actionCollection(), "select_view" ); 00524 #if KDE_VERSION >= 309 00525 mActionSelectView->setMenuAccelsEnabled( false ); 00526 #endif 00527 connect( mActionSelectView, SIGNAL( activated( const QString& ) ), 00528 SLOT( setActiveView( const QString& ) ) ); 00529 00530 KAction *action; 00531 00532 action = new KAction( i18n( "Modify View..." ), "configure", 0, this, 00533 SLOT( editView() ), mCore->actionCollection(), 00534 "view_modify" ); 00535 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." ) ); 00536 00537 action = new KAction( i18n( "Add View..." ), "window_new", 0, this, 00538 SLOT( addView() ), mCore->actionCollection(), 00539 "view_add" ); 00540 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." ) ); 00541 00542 mActionDeleteView = new KAction( i18n( "Delete View" ), "view_remove", 0, 00543 this, SLOT( deleteView() ), 00544 mCore->actionCollection(), "view_delete" ); 00545 mActionDeleteView->setWhatsThis( i18n( "By pressing this button you can delete the actual view, which you have added before." ) ); 00546 00547 action = new KAction( i18n( "Refresh View" ), "reload", 0, this, 00548 SLOT( refreshView() ), mCore->actionCollection(), 00549 "view_refresh" ); 00550 action->setWhatsThis( i18n( "The view will be refreshed by pressing this button." ) ); 00551 00552 action = new KAction( i18n( "Edit &Filters..." ), "filter", 0, this, 00553 SLOT( configureFilters() ), mCore->actionCollection(), 00554 "options_edit_filters" ); 00555 action->setWhatsThis( i18n( "Edit the contact filters<p>You will be presented with a dialog, where you can add, remove and edit filters." ) ); 00556 } 00557 00558 void ViewManager::initGUI() 00559 { 00560 QHBoxLayout *layout = new QHBoxLayout( this ); 00561 mViewWidgetStack = new QWidgetStack( this ); 00562 layout->addWidget( mViewWidgetStack ); 00563 } 00564 00565 #include "viewmanager.moc"
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 1 15:19:05 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003