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 <tqfile.h>
00025 #include <tqlayout.h>
00026 #include <tqwidgetstack.h>
00027
00028 #include <libtdepim/kvcarddrag.h>
00029 #include <tdeabc/addressbook.h>
00030 #include <tdeabc/vcardconverter.h>
00031 #include <tdeactionclasses.h>
00032 #include <tdeconfig.h>
00033 #include <kdebug.h>
00034 #include <tdeversion.h>
00035 #include <kiconloader.h>
00036 #include <tdelocale.h>
00037 #include <tdemessagebox.h>
00038 #include <tdemultipledrag.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, TQWidget *parent, const char *name )
00053 : TQWidget( 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 TQString 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 TQDictIterator<KAddressBookView> it( mViewDict );
00085 for ( it.toFirst(); it.current(); ++it ) {
00086 TDEConfigGroupSaver 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 TQDictIterator<KAddressBookView> it( mViewDict );
00098 for ( it.toFirst(); it.current(); ++it ) {
00099 TDEConfigGroupSaver 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 TQStringList ViewManager::selectedUids() const
00114 {
00115 if ( mActiveView ) {
00116 return mActiveView->selectedUids();
00117 } else
00118 return TQStringList();
00119 }
00120
00121 TQStringList ViewManager::selectedEmails() const
00122 {
00123 if ( mActiveView )
00124 return mActiveView->selectedEmails();
00125 else
00126 return TQStringList();
00127 }
00128
00129 TDEABC::Addressee::List ViewManager::selectedAddressees() const
00130 {
00131 TDEABC::Addressee::List list;
00132
00133 const TQStringList uids = selectedUids();
00134 TQStringList::ConstIterator it;
00135 for ( it = uids.begin(); it != uids.end(); ++it ) {
00136 TDEABC::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 TDEABC::Field *ViewManager::currentSortField() const
00150 {
00151 if ( mActiveView )
00152 return mActiveView->sortField();
00153 else
00154 return 0;
00155 }
00156
00157 TDEABC::Field::List ViewManager::viewFields() const
00158 {
00159
00160
00161
00162
00163
00164 return TDEABC::Field::List();
00165 }
00166
00167 void ViewManager::setSelected( const TQString &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 TQString &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 TDEConfig *config = mCore->config();
00203 TDEConfigGroupSaver saver( config, name );
00204 TQString 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, TQT_SIGNAL( selected( const TQString& ) ),
00220 TQT_SIGNAL( selected( const TQString & ) ) );
00221 connect( view, TQT_SIGNAL( executed( const TQString& ) ),
00222 TQT_SIGNAL( executed( const TQString& ) ) );
00223 connect( view, TQT_SIGNAL( modified() ), TQT_SIGNAL( modified() ) );
00224 connect( view, TQT_SIGNAL( dropped( TQDropEvent* ) ),
00225 TQT_SLOT( dropped( TQDropEvent* ) ) );
00226 connect( view, TQT_SIGNAL( startDrag() ), TQT_SLOT( startDrag() ) );
00227 connect( view, TQT_SIGNAL( sortFieldChanged() ), TQT_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 TQString &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 TDEConfigGroupSaver 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 TQString text = i18n( "<qt>Are you sure that you want to delete the view <b>%1</b>?</qt>" )
00310 .arg( mActiveView->caption() );
00311 TQString caption = i18n( "Confirm Delete" );
00312
00313 if ( KMessageBox::warningContinueCancel( this, text, caption, KGuiItem( i18n("&Delete"), "edit-delete") ) == KMessageBox::Continue ) {
00314 mViewNameList.remove( mActiveView->caption() );
00315
00316
00317 TDEConfig *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 TQString newName = dialog.viewName();
00340 TQString 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 = TQString( "%1 <%2>" ).arg( newName ).arg( numTries );
00352 numTries++;
00353 }
00354
00355
00356 mViewNameList.append( newName );
00357
00358
00359 TDEConfig *config = mCore->config();
00360 config->deleteGroup( newName );
00361 TDEConfigGroupSaver 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 TDETrader::OfferList plugins = TDETrader::self()->query( "KAddressBook/View",
00390 TQString( "[X-TDE-KAddressBook-ViewPluginVersion] == %1" ).arg( KAB_VIEW_PLUGIN_VERSION ) );
00391 TDETrader::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( TQDropEvent *e )
00415 {
00416 kdDebug(5720) << "ViewManager::dropped: got a drop event" << endl;
00417
00418
00419 if ( e->source() == this )
00420 return;
00421
00422 TDEABC::Addressee::List list;
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 TQString 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, list ) ) {
00437 TDEABC::Addressee::List::ConstIterator it;
00438 for ( it = list.begin(); it != list.end(); ++it ) {
00439 TDEABC::Addressee a = mCore->addressBook()->findByUid( (*it).uid() );
00440 if ( a.isEmpty() ) {
00441 mCore->addressBook()->insertAddressee( *it );
00442 emit modified();
00443 }
00444 }
00445
00446 mActiveView->refresh();
00447 }
00448 }
00449
00450 void ViewManager::startDrag()
00451 {
00452
00453 TDEABC::Addressee::List addrList;
00454 const TQStringList uidList = selectedUids();
00455 if ( uidList.isEmpty() )
00456 return;
00457
00458 kdDebug(5720) << "ViewManager::startDrag: starting to drag" << endl;
00459
00460 TQStringList::ConstIterator it;
00461 for ( it = uidList.begin(); it != uidList.end(); ++it )
00462 addrList.append( mCore->addressBook()->findByUid( *it ) );
00463
00464 KMultipleDrag *drag = new KMultipleDrag( this );
00465
00466 TDEABC::VCardConverter converter;
00467 #if defined(KABC_VCARD_ENCODING_FIX)
00468 TQCString vcards = converter.createVCardsRaw( addrList );
00469 #else
00470 TQString vcards = converter.createVCards( addrList );
00471 #endif
00472
00473
00474 drag->addDragObject( new TQTextDrag( AddresseeUtil::addresseesToEmails( addrList ), this ) );
00475 drag->addDragObject( new KVCardDrag( vcards, this ) );
00476
00477 KTempDir tempDir;
00478
00479 if ( tempDir.status() == 0 ) {
00480 TQString fileName;
00481 if ( addrList.count() == 1 )
00482 fileName = addrList[ 0 ].givenName() + "_" + addrList[ 0 ].familyName() + ".vcf";
00483 else
00484 fileName = "contacts.vcf";
00485
00486 TQFile tempFile( tempDir.name() + "/" + fileName );
00487 if ( tempFile.open( IO_WriteOnly ) ) {
00488 #if defined(KABC_VCARD_ENCODING_FIX)
00489 tempFile.writeBlock( vcards, vcards.length() );
00490 #else
00491 tempFile.writeBlock( vcards.utf8() );
00492 #endif
00493 tempFile.close();
00494
00495 KURLDrag *urlDrag = new KURLDrag( KURL( tempFile.name() ), this );
00496 drag->addDragObject( urlDrag );
00497 }
00498 }
00499
00500 drag->setPixmap( TDEGlobal::iconLoader()->loadIcon( "x-office-address-book", TDEIcon::Desktop ) );
00501 drag->dragCopy();
00502 }
00503
00504 void ViewManager::setActiveFilter( int index )
00505 {
00506 Filter currentFilter;
00507
00508 if ( ( index - 1 ) < 0 )
00509 currentFilter = Filter();
00510 else if ( ( index - 1 ) < 1 ) {
00511 currentFilter = Filter();
00512 currentFilter.setMatchRule(Filter::NotMatching);
00513 }
00514 else
00515 currentFilter = mFilterList[ index - 2 ];
00516
00517
00518
00519 if ( mActiveView ) {
00520 mActiveView->setFilter( currentFilter );
00521 mActiveView->refresh();
00522 emit selected( TQString() );
00523 }
00524 }
00525
00526 void ViewManager::configureFilters()
00527 {
00528 FilterDialog dlg( this );
00529
00530 dlg.setFilters( mFilterList );
00531
00532 if ( dlg.exec() )
00533 mFilterList = dlg.filters();
00534
00535 uint pos = mFilterSelectionWidget->currentItem();
00536 mFilterSelectionWidget->setItems( filterNames() );
00537 mFilterSelectionWidget->setCurrentItem( pos );
00538 setActiveFilter( pos );
00539 }
00540
00541 TQStringList ViewManager::filterNames() const
00542 {
00543 TQStringList names( i18n( "None" ) );
00544 names.append( i18n( "Unfiled" ) );
00545
00546 Filter::List::ConstIterator it;
00547 for ( it = mFilterList.begin(); it != mFilterList.end(); ++it )
00548 names.append( (*it).name() );
00549
00550 return names;
00551 }
00552
00553 int ViewManager::filterPosition( const TQString &name ) const
00554 {
00555 int pos = 0;
00556
00557 Filter::List::ConstIterator it;
00558 for ( it = mFilterList.begin(); it != mFilterList.end(); ++it, ++pos )
00559 if ( name == (*it).name() )
00560 return pos + 2;
00561
00562 return 0;
00563 }
00564
00565 void ViewManager::initActions()
00566 {
00567 mActionSelectView = new TDESelectAction( i18n( "Select View" ), 0, mCore->actionCollection(), "select_view" );
00568 #if TDE_VERSION >= 309
00569 mActionSelectView->setMenuAccelsEnabled( false );
00570 #endif
00571 connect( mActionSelectView, TQT_SIGNAL( activated( const TQString& ) ),
00572 TQT_SLOT( setActiveView( const TQString& ) ) );
00573
00574 TDEAction *action;
00575
00576 action = new TDEAction( i18n( "Modify View..." ), "configure", 0, TQT_TQOBJECT(this),
00577 TQT_SLOT( editView() ), mCore->actionCollection(),
00578 "view_modify" );
00579 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." ) );
00580
00581 action = new TDEAction( i18n( "Add View..." ), "window-new", 0, TQT_TQOBJECT(this),
00582 TQT_SLOT( addView() ), mCore->actionCollection(),
00583 "view_add" );
00584 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." ) );
00585
00586 mActionDeleteView = new TDEAction( i18n( "Delete View" ), "view_remove", 0,
00587 TQT_TQOBJECT(this), TQT_SLOT( deleteView() ),
00588 mCore->actionCollection(), "view_delete" );
00589 mActionDeleteView->setWhatsThis( i18n( "By pressing this button you can delete the actual view, which you have added before." ) );
00590
00591 action = new TDEAction( i18n( "Refresh View" ), "reload", 0, TQT_TQOBJECT(this),
00592 TQT_SLOT( refreshView() ), mCore->actionCollection(),
00593 "view_refresh" );
00594 action->setWhatsThis( i18n( "The view will be refreshed by pressing this button." ) );
00595
00596 action = new TDEAction( i18n( "Edit &Filters..." ), "filter", 0, TQT_TQOBJECT(this),
00597 TQT_SLOT( configureFilters() ), mCore->actionCollection(),
00598 "options_edit_filters" );
00599 action->setWhatsThis( i18n( "Edit the contact filters<p>You will be presented with a dialog, where you can add, remove and edit filters." ) );
00600 }
00601
00602 void ViewManager::initGUI()
00603 {
00604 TQHBoxLayout *layout = new TQHBoxLayout( this );
00605 mViewWidgetStack = new TQWidgetStack( this );
00606 layout->addWidget( mViewWidgetStack );
00607 }
00608
00609 #include "viewmanager.moc"