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 <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 // Filter 00076 mFilterList = Filter::restore( mCore->config(), "Filter" ); 00077 mFilterSelectionWidget->setItems( filterNames() ); 00078 mFilterSelectionWidget->setCurrentItem( KABPrefs::instance()->mCurrentFilter ); 00079 00080 // Tell the views to reread their config, since they may have 00081 // been modified by global settings 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 // write the view name list 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 // Check that this isn't the same as the current active view 00171 if ( mActiveView && ( mActiveView->caption() == name ) ) 00172 return; 00173 00174 // At this point we know the view that should be active is not 00175 // currently active. We will try to find the new on in the list. If 00176 // we can't find it, it means it hasn't been instantiated, so we will 00177 // create it on demand. 00178 00179 view = mViewDict.find( name ); 00180 00181 // Check if we found the view. If we didn't, then we need to create it 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 // The manager just relays the signals 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 // If we found or created the view, raise it and refresh it 00213 if ( view ) { 00214 mActiveView = view; 00215 mViewWidgetStack->raiseWidget( view ); 00216 // Set the proper filter in the view. By setting the combo 00217 // box, the activated slot will be called, which will push 00218 // the filter to the view and refresh it. 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 // Update the inc search widget to show the fields in the new active 00231 // view. 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 // Save the filters so the dialog has the latest set 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 // 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 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 // remove the view from the config file 00300 KConfig *config = mCore->config(); 00301 config->deleteGroup( mActiveView->caption() ); 00302 00303 mViewDict.remove( mActiveView->caption() ); 00304 mActiveView = 0; 00305 00306 // we are in an invalid state now, but that should be fixed after 00307 // we emit the signal 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 // Check for name conflicts 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 // Add the new one to the list 00339 mViewNameList.append( newName ); 00340 00341 // write the view to the config file, 00342 KConfig *config = mCore->config(); 00343 config->deleteGroup( newName ); 00344 KConfigGroupSaver saver( config, newName ); 00345 config->writeEntry( "Type", type ); 00346 00347 // try to set the active view 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() ) { // not yet in address book 00410 mCore->addressBook()->insertAddressee( *it ); 00411 emit modified(); 00412 } 00413 } 00414 00415 mActiveView->refresh(); 00416 } 00417 } 00418 00419 void ViewManager::startDrag() 00420 { 00421 // Get the list of all the selected addressees 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 // Check if we have a view. Since the filter combo is created before 00453 // the view, this slot could be called before there is a valid view. 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"
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:58:09 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003