kaddressbook

kabcore.cpp
1 /*
2  This file is part of KAddressbook.
3  Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 
19  As a special exception, permission is given to link this program
20  with any edition of TQt, and distribute the resulting executable,
21  without including the source code for TQt in the source distribution.
22 */
23 
24 // Needed for ugly hack, to be removed in 4.0
25 #include <unistd.h> // for usleep
26 #include <tqeventloop.h>
27 
28 #include <tqclipboard.h>
29 #include <tqdir.h>
30 #include <tqfile.h>
31 #include <tqlabel.h>
32 #include <tqlayout.h>
33 #include <tqptrlist.h>
34 #include <tqwidgetstack.h>
35 #include <tqregexp.h>
36 #include <tqvbox.h>
37 #include <tqtooltip.h>
38 #include <tqwhatsthis.h>
39 
40 #include <tdeabc/addresseelist.h>
41 #include <tdeabc/errorhandler.h>
42 #include <tdeabc/resource.h>
43 #include <tdeabc/stdaddressbook.h>
44 #include <tdeabc/vcardconverter.h>
45 #include <tdeabc/resourcefile.h>
46 #include <tdeaboutdata.h>
47 #include <tdeaccelmanager.h>
48 #include <tdeapplication.h>
49 #include <dcopclient.h>
50 #include <tdeactionclasses.h>
51 #include <tdecmdlineargs.h>
52 #include <kcmultidialog.h>
53 #include <kdebug.h>
54 #include <tdeimproxy.h>
55 #include <tdelocale.h>
56 #include <tdemessagebox.h>
57 #include <kprinter.h>
58 #include <kprotocolinfo.h>
59 #include <kpushbutton.h>
60 #include <tderesources/selectdialog.h>
61 #include <kstandarddirs.h>
62 #include <kstatusbar.h>
63 #include <kstdguiitem.h>
64 #include <kxmlguiclient.h>
65 #include <tdetoolbar.h>
66 #include <libtdepim/addresseeview.h>
67 #include <libtdepim/categoryeditdialog.h>
68 #include <libtdepim/categoryselectdialog.h>
69 #include <libtdepim/resourceabc.h>
70 #include "distributionlisteditor.h"
71 
72 #include "addresseeutil.h"
73 #include "addresseeeditordialog.h"
74 #include "distributionlistentryview.h"
75 #include "extensionmanager.h"
76 #include "filterselectionwidget.h"
77 #include "incsearchwidget.h"
78 #include "jumpbuttonbar.h"
79 #include "kablock.h"
80 #include "kabprefs.h"
81 #include "kabtools.h"
82 #include "kaddressbookservice.h"
83 #include "kaddressbookiface.h"
84 #include "ldapsearchdialog.h"
85 #include "locationmap.h"
86 #include "printing/printingwizard.h"
87 #include "searchmanager.h"
88 #include "undocmds.h"
89 #include "viewmanager.h"
90 #include "xxportmanager.h"
91 
92 #include "kabcore.h"
93 
94 KABCore::KABCore( KXMLGUIClient *client, bool readWrite, TQWidget *parent,
95  const TQString &file, const char *name )
96  : KAB::Core( client, parent, name ), mStatusBar( 0 ), mViewManager( 0 ),
97  mExtensionManager( 0 ), mJumpButtonBar( 0 ), mCategorySelectDialog( 0 ),
98  mCategoryEditDialog( 0 ), mLdapSearchDialog( 0 ), mReadWrite( readWrite ),
99  mModified( false )
100 {
101  mWidget = new TQWidget( parent, name );
102 
103  mIsPart = !parent->isA( "KAddressBookMain" );
104 
105  mAddressBookChangedTimer = new TQTimer( this );
106  connect( mAddressBookChangedTimer, TQ_SIGNAL( timeout() ),
107  this, TQ_SLOT( addressBookChanged() ) );
108 
109  if ( file.isEmpty() ) {
110  mAddressBook = TDEABC::StdAddressBook::self( true );
111  } else {
112  kdDebug(5720) << "KABCore(): document '" << file << "'" << endl;
113  mAddressBook = new TDEABC::AddressBook;
114  mAddressBook->addResource( new TDEABC::ResourceFile( file ) );
115  if ( !mAddressBook->load() ) {
116  KMessageBox::error( parent, i18n("Unable to load '%1'.").arg( file ) );
117  }
118  }
119  mAddressBook->setErrorHandler( new TDEABC::GuiErrorHandler( mWidget ) );
120 
121  mAddressBook->addCustomField( i18n( "Profession" ), TDEABC::Field::Organization,
122  "X-Profession", "KADDRESSBOOK" );
123  mAddressBook->addCustomField( i18n( "Assistant's Name" ), TDEABC::Field::Organization,
124  "X-AssistantsName", "KADDRESSBOOK" );
125  mAddressBook->addCustomField( i18n( "Manager's Name" ), TDEABC::Field::Organization,
126  "X-ManagersName", "KADDRESSBOOK" );
127  mAddressBook->addCustomField( i18n( "Partner's Name" ), TDEABC::Field::Personal,
128  "X-SpousesName", "KADDRESSBOOK" );
129  mAddressBook->addCustomField( i18n( "Office" ), TDEABC::Field::Personal,
130  "X-Office", "KADDRESSBOOK" );
131  mAddressBook->addCustomField( i18n( "IM Address" ), TDEABC::Field::Personal,
132  "X-IMAddress", "KADDRESSBOOK" );
133  mAddressBook->addCustomField( i18n( "Anniversary" ), TDEABC::Field::Personal,
134  "X-Anniversary", "KADDRESSBOOK" );
135  mAddressBook->addCustomField( i18n( "Blog" ), TDEABC::Field::Personal,
136  "BlogFeed", "KADDRESSBOOK" );
137 
138  mSearchManager = new KAB::SearchManager( mAddressBook, parent );
139 
140  connect( mSearchManager, TQ_SIGNAL( contactsUpdated() ),
141  this, TQ_SLOT( slotContactsUpdated() ) );
142 
143  initGUI();
144 
145  connect( mAddressBook, TQ_SIGNAL( addressBookChanged( AddressBook* ) ),
146  TQ_SLOT( delayedAddressBookChanged() ) );
147  connect( mAddressBook, TQ_SIGNAL( loadingFinished( Resource* ) ),
148  TQ_SLOT( delayedAddressBookChanged() ) );
149 
150  mIncSearchWidget->setFocus();
151 
152  connect( mViewManager, TQ_SIGNAL( selected( const TQString& ) ),
153  TQ_SLOT( setContactSelected( const TQString& ) ) );
154  connect( mViewManager, TQ_SIGNAL( executed( const TQString& ) ),
155  TQ_SLOT( editContact( const TQString& ) ) );
156  connect( mViewManager, TQ_SIGNAL( modified() ),
157  TQ_SLOT( setModified() ) );
158  connect( mViewManager, TQ_SIGNAL( urlDropped( const KURL& ) ),
159  mXXPortManager, TQ_SLOT( importVCard( const KURL& ) ) );
160  connect( mViewManager, TQ_SIGNAL( viewFieldsChanged() ),
161  TQ_SLOT( updateIncSearchWidget() ) );
162  connect( mExtensionManager, TQ_SIGNAL( modified( const TDEABC::Addressee::List& ) ),
163  this, TQ_SLOT( extensionModified( const TDEABC::Addressee::List& ) ) );
164  connect( mExtensionManager, TQ_SIGNAL( deleted( const TQStringList& ) ),
165  this, TQ_SLOT( extensionDeleted( const TQStringList& ) ) );
166 
167  connect( mXXPortManager, TQ_SIGNAL( modified() ),
168  TQ_SLOT( setModified() ) );
169 
170  connect( mDetailsViewer, TQ_SIGNAL( highlightedMessage( const TQString& ) ),
171  TQ_SLOT( detailsHighlighted( const TQString& ) ) );
172 
173  connect( mIncSearchWidget, TQ_SIGNAL( scrollUp() ),
174  mViewManager, TQ_SLOT( scrollUp() ) );
175  connect( mIncSearchWidget, TQ_SIGNAL( scrollDown() ),
176  mViewManager, TQ_SLOT( scrollDown() ) );
177 
178  mAddressBookService = new KAddressBookService( this );
179 
180  mCommandHistory = new KCommandHistory( actionCollection(), true );
181  connect( mCommandHistory, TQ_SIGNAL( commandExecuted() ),
182  mSearchManager, TQ_SLOT( reload() ) );
183 
184  mSearchManager->reload();
185 
186  setModified( false );
187 
188  TDEAcceleratorManager::manage( mWidget );
189 
190  mKIMProxy = ::KIMProxy::instance( kapp->dcopClient() );
191 }
192 
193 KABCore::~KABCore()
194 {
195  mAddressBook->disconnect();
196 
197  mAddressBook = 0;
198  TDEABC::StdAddressBook::close();
199  mKIMProxy = 0;
200 }
201 
202 void KABCore::restoreSettings()
203 {
204  bool state = KABPrefs::instance()->jumpButtonBarVisible();
205  mActionJumpBar->setChecked( state );
206  setJumpButtonBarVisible( state );
207 
208  state = KABPrefs::instance()->detailsPageVisible();
209  mActionDetails->setChecked( state );
210  setDetailsVisible( state );
211 
212  mViewManager->restoreSettings();
213  mExtensionManager->restoreSettings();
214 
215  updateIncSearchWidget();
216  mIncSearchWidget->setCurrentItem( KABPrefs::instance()->currentIncSearchField() );
217 
218  TQValueList<int> splitterSize = KABPrefs::instance()->detailsSplitter();
219  if ( splitterSize.count() == 0 ) {
220  splitterSize.append( 360 );
221  splitterSize.append( 260 );
222  }
223  mDetailsSplitter->setSizes( splitterSize );
224 
225  const TQValueList<int> leftSplitterSizes = KABPrefs::instance()->leftSplitter();
226  if ( !leftSplitterSizes.isEmpty() )
227  mLeftSplitter->setSizes( leftSplitterSizes );
228 }
229 
230 void KABCore::saveSettings()
231 {
232  KABPrefs::instance()->setJumpButtonBarVisible( mActionJumpBar->isChecked() );
233  KABPrefs::instance()->setDetailsPageVisible( mActionDetails->isChecked() );
234  KABPrefs::instance()->setDetailsSplitter( mDetailsSplitter->sizes() );
235  KABPrefs::instance()->setLeftSplitter( mLeftSplitter->sizes() );
236 
237  mExtensionManager->saveSettings();
238  mViewManager->saveSettings();
239 
240  KABPrefs::instance()->setCurrentIncSearchField( mIncSearchWidget->currentItem() );
241 }
242 
243 TDEABC::AddressBook *KABCore::addressBook() const
244 {
245  return mAddressBook;
246 }
247 
248 TDEConfig *KABCore::config() const
249 {
250  return KABPrefs::instance()->config();
251 }
252 
253 TDEActionCollection *KABCore::actionCollection() const
254 {
255  return guiClient()->actionCollection();
256 }
257 
258 TDEABC::Field *KABCore::currentSortField() const
259 {
260  return mViewManager->currentSortField();
261 }
262 
263 TQStringList KABCore::selectedUIDs() const
264 {
265  return mViewManager->selectedUids();
266 }
267 
268 TDEABC::Resource *KABCore::requestResource( TQWidget *parent )
269 {
270  TQPtrList<TDEABC::Resource> tdeabcResources = addressBook()->resources();
271 
272  TQPtrList<KRES::Resource> kresResources;
273  TQPtrListIterator<TDEABC::Resource> resIt( tdeabcResources );
274  TDEABC::Resource *resource;
275  while ( ( resource = resIt.current() ) != 0 ) {
276  ++resIt;
277  bool writable = false;
278  if ( resource->inherits( "KPIM::ResourceABC" ) ) {
279  KPIM::ResourceABC *resAbc = static_cast<KPIM::ResourceABC *>( resource );
280  const TQStringList subresources = resAbc->subresources();
281  for ( TQStringList::ConstIterator it = subresources.begin(); it != subresources.end(); ++it ) {
282  if ( resAbc->subresourceActive(*it) && resAbc->subresourceWritable(*it) ) {
283  writable = true;
284  break;
285  }
286  }
287  } else {
288  if ( !resource->readOnly() ) {
289  writable = true;
290  }
291  }
292 
293  if ( writable ) {
294  KRES::Resource *res = resource; // downcast
295  kresResources.append( res );
296  }
297  }
298 
299  KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent );
300  return static_cast<TDEABC::Resource*>( res ); // upcast
301 }
302 
303 TQWidget *KABCore::widget() const
304 {
305  return mWidget;
306 }
307 
308 TDEAboutData *KABCore::createAboutData()
309 {
310  TDEAboutData *about = new TDEAboutData( "kaddressbook", I18N_NOOP( "KAddressBook" ),
311  "3.5.13", I18N_NOOP( "The TDE Address Book" ),
312  TDEAboutData::License_GPL_V2,
313  I18N_NOOP( "(c) 2008-2010, The Trinity Team\n(c) 1997-2005, The KDE PIM Team" ) );
314  about->addAuthor( "Timothy Pearson", I18N_NOOP( "Current maintainer" ), "kb9vqf@pearsoncomputing.net" );
315  about->addAuthor( "Tobias Koenig", I18N_NOOP( "Previous maintainer" ), "tokoe@kde.org" );
316  about->addAuthor( "Don Sanders", I18N_NOOP( "Original author" ) );
317  about->addAuthor( "Cornelius Schumacher",
318  I18N_NOOP( "Co-maintainer, libtdeabc port, CSV import/export" ),
319  "schumacher@kde.org" );
320  about->addAuthor( "Mike Pilone", I18N_NOOP( "GUI and framework redesign" ),
321  "mpilone@slac.com" );
322  about->addAuthor( "Greg Stern", I18N_NOOP( "DCOP interface" ) );
323  about->addAuthor( "Mark Westcott", I18N_NOOP( "Contact pinning" ) );
324  about->addAuthor( "Mischel Boyer de la Giroday", I18N_NOOP( "LDAP Lookup" ),
325  "michel@klaralvdalens-datakonsult.se" );
326  about->addAuthor( "Steffen Hansen", I18N_NOOP( "LDAP Lookup" ),
327  "hansen@kde.org" );
328 
329  return about;
330 }
331 
332 void KABCore::setStatusBar( KStatusBar *statusBar )
333 {
334  mStatusBar = statusBar;
335 }
336 
337 KStatusBar *KABCore::statusBar() const
338 {
339  return mStatusBar;
340 }
341 
342 void KABCore::setContactSelected( const TQString &uid )
343 {
344  // Avoid crash on exit
345  if ( !mAddressBook ) {
346  return;
347  }
348 
349  TDEABC::Addressee addr = mAddressBook->findByUid( uid );
350  if ( !mDetailsViewer->isHidden() )
351  mDetailsViewer->setAddressee( addr );
352 #ifdef TDEPIM_NEW_DISTRLISTS
353  if ( !mSelectedDistributionList.isNull() && mDistListEntryView->isShown() ) {
354  showDistributionListEntry( uid );
355  }
356 #endif
357  mExtensionManager->setSelectionChanged();
358 
359  TDEABC::Addressee::List list = mViewManager->selectedAddressees();
360  const bool someSelected = list.size() > 0;
361  const bool singleSelected = list.size() == 1;
362  bool writable = mReadWrite;
363 
364  if ( writable ) {
365  //check if every single (sub)resource is writable
366  //### We have a performance problem here - everytime *one* item is added or
367  // removed we re-check *all* items. If this turns out to be a bottleneck
368  // we need to keep some state and check new items only.
369  TDEABC::Addressee::List::ConstIterator addrIt = list.constBegin();
370  for ( ; addrIt != list.constEnd(); ++addrIt ) {
371  TDEABC::Resource *res = ( *addrIt ).resource();
372  if ( !res ) {
373  kdDebug() << "KABCore::setContactSelected: this addressee has no resource!" << endl;
374  writable = false;
375  break;
376  }
377  if ( res->readOnly() ) {
378  writable = false;
379  break;
380  }
381  //HACK: manual polymorphism
382  if ( res->inherits( "KPIM::ResourceABC" ) ) {
383  KPIM::ResourceABC *resAbc = static_cast<KPIM::ResourceABC *>( res );
384 
385  TQString subresource = resAbc->uidToResourceMap()[ ( *addrIt ).uid() ];
386  if ( !subresource.isEmpty() && !resAbc->subresourceWritable( subresource ) ) {
387  writable = false;
388  break;
389  }
390  }
391  }
392  }
393 
394  bool moreThanOneResource = mAddressBook->resources().count() > 1;
395  if ( !moreThanOneResource && !mAddressBook->resources().isEmpty() ) {
396  TDEABC::Resource *res = mAddressBook->resources().first();
397  if ( res->inherits( "KPIM::ResourceABC" ) ) {
398  KPIM::ResourceABC *resAbc = static_cast<KPIM::ResourceABC *>( res );
399  const TQStringList subresources = resAbc->subresources();
400  int writeables = 0;
401  for ( TQStringList::ConstIterator it = subresources.begin(); it != subresources.end(); ++it ) {
402  if ( resAbc->subresourceActive(*it) && resAbc->subresourceWritable(*it) ) {
403  writeables++;
404  }
405  }
406  moreThanOneResource = ( writeables >= 2 );
407  }
408  }
409 
410  // update the actions
411 
412  mActionCopy->setEnabled( someSelected );
413  mActionCut->setEnabled( someSelected && writable );
414  mActionDelete->setEnabled( someSelected && writable );
415  // the "edit" dialog doubles as the details dialog and it knows when the addressee is read-only
416  // (### this does not make much sense from the user perspective!)
417  mActionEditAddressee->setEnabled( singleSelected && !mExtensionManager->isQuickEditVisible());
418  mActionCopyAddresseeTo->setEnabled( someSelected && moreThanOneResource );
419  mActionMoveAddresseeTo->setEnabled( someSelected && moreThanOneResource && writable );
420  mActionMail->setEnabled( someSelected );
421  mActionMailVCard->setEnabled( someSelected );
422  mActionChat->setEnabled( singleSelected && mKIMProxy && mKIMProxy->initialize() );
423  mActionWhoAmI->setEnabled( singleSelected );
424  mActionCategories->setEnabled( someSelected && writable );
425  mActionMerge->setEnabled( ( list.size() == 2 ) && writable );
426 
427  if ( mReadWrite ) {
428  TQClipboard *cb = TQApplication::clipboard();
429 #if defined(KABC_VCARD_ENCODING_FIX)
430  const TQMimeSource *data = cb->data( TQClipboard::Clipboard );
431  list = AddresseeUtil::clipboardToAddressees( data->encodedData( "text/x-vcard" ) );
432 #else
433  list = AddresseeUtil::clipboardToAddressees( cb->text() );
434 #endif
435  mActionPaste->setEnabled( !list.isEmpty() );
436  }
437 #ifdef TDEPIM_NEW_DISTRLISTS
438  mAddDistListButton->setEnabled( writable );
439  mRemoveDistListButton->setEnabled( someSelected && writable );
440 #endif
441 }
442 
443 void KABCore::sendMail()
444 {
445  //FIXME: breaks with email addresses containing ","
446  sendMail( mViewManager->selectedEmails().join( ", " ) );
447 }
448 
449 void KABCore::sendMail( const TQString& email )
450 {
451  kapp->invokeMailer( email, "" );
452 }
453 
454 void KABCore::mailVCard()
455 {
456  TQStringList uids = mViewManager->selectedUids();
457  if ( !uids.isEmpty() )
458  mailVCard( uids );
459 }
460 
461 void KABCore::mailVCard( const TQStringList &uids )
462 {
463  KABTools::mailVCards( uids, mAddressBook );
464 }
465 
466 void KABCore::startChat()
467 {
468  TQStringList uids = mViewManager->selectedUids();
469  if ( !uids.isEmpty() )
470  mKIMProxy->chatWithContact( uids.first() );
471 }
472 
473 void KABCore::browse( const TQString& url )
474 {
475  kapp->invokeBrowser( url );
476 }
477 
478 void KABCore::selectAllContacts()
479 {
480  mViewManager->setSelected( TQString(), true );
481 }
482 
483 void KABCore::deleteContacts()
484 {
485  TQStringList uidList = mViewManager->selectedUids();
486 
487  deleteContacts( uidList );
488 }
489 
490 void KABCore::deleteDistributionLists( const TQStringList & names )
491 {
492  if ( names.isEmpty() )
493  return;
494  if ( KMessageBox::warningContinueCancelList( mWidget, i18n( "Do you really want to delete this distribution list?",
495  "Do you really want to delete these %n distribution lists?", names.count() ),
496  names, TQString(), KStdGuiItem::del() ) == KMessageBox::Cancel )
497  return;
498 
499  TQStringList uids;
500  for ( TQStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) {
501  uids.append( KPIM::DistributionList::findByName( mAddressBook, *it ).uid() );
502  }
503  DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
504  mCommandHistory->addCommand( command );
505  setModified( true );
506 }
507 
508 void KABCore::deleteContacts( const TQStringList &uids )
509 {
510  if ( uids.count() > 0 ) {
511  TQStringList names;
512  TQStringList::ConstIterator it = uids.begin();
513  const TQStringList::ConstIterator endIt( uids.end() );
514  while ( it != endIt ) {
515  TDEABC::Addressee addr = mAddressBook->findByUid( *it );
516  names.append( addr.realName().isEmpty() ? addr.preferredEmail() : addr.realName() );
517  ++it;
518  }
519 
520  if ( KMessageBox::warningContinueCancelList(
521  mWidget,
522  i18n( "<qt>"
523  "Do you really want to delete this contact from your addressbook?<br>"
524  "<b>Note:</b>The contact will be also removed from all distribution lists."
525  "</qt>",
526  "<qt>"
527  "Do you really want to delete these %n contacts from your addressbook?<br>"
528  "<b>Note:</b>The contacts will be also removed from all distribution lists."
529  "</qt>",
530  uids.count() ),
531  names, TQString(), KStdGuiItem::del() ) == KMessageBox::Cancel ) {
532  return;
533  }
534 
535  DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
536  mCommandHistory->addCommand( command );
537 
538  // now if we deleted anything, refresh
539  setContactSelected( TQString() );
540  setModified( true );
541  }
542 }
543 
544 void KABCore::copyContacts()
545 {
546  TDEABC::Addressee::List addrList = mViewManager->selectedAddressees();
547 
548 #if defined(KABC_VCARD_ENCODING_FIX)
549  TQByteArray clipText = AddresseeUtil::addresseesToClipboard( addrList );
550  TQClipboard *cb = TQApplication::clipboard();
551  cb->setText( TQString::fromUtf8( clipText.data() ) );
552 #else
553  TQString clipText = AddresseeUtil::addresseesToClipboard( addrList );
554  TQClipboard *cb = TQApplication::clipboard();
555  cb->setText( clipText );
556 #endif
557 }
558 
559 void KABCore::cutContacts()
560 {
561  TQStringList uidList = mViewManager->selectedUids();
562 
563  if ( uidList.size() > 0 ) {
564  CutCommand *command = new CutCommand( mAddressBook, uidList );
565  mCommandHistory->addCommand( command );
566 
567  setModified( true );
568  }
569 }
570 
571 void KABCore::pasteContacts()
572 {
573  TQClipboard *cb = TQApplication::clipboard();
574 #if defined(KABC_VCARD_ENCODING_FIX)
575  const TQMimeSource *data = cb->data( TQClipboard::Clipboard );
576  TDEABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( data->encodedData( "text/x-vcard" ) );
577 #else
578  TDEABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
579 #endif
580  pasteContacts( list );
581 }
582 
583 void KABCore::pasteContacts( TDEABC::Addressee::List &list )
584 {
585  TDEABC::Resource *resource = requestResource( mWidget );
586  if ( !resource )
587  return;
588 
589  TDEABC::Addressee::List::Iterator it;
590  const TDEABC::Addressee::List::Iterator endIt( list.end() );
591  for ( it = list.begin(); it != endIt; ++it )
592  (*it).setResource( resource );
593 
594  PasteCommand *command = new PasteCommand( this, list );
595  mCommandHistory->addCommand( command );
596 
597  setModified( true );
598 }
599 
600 void KABCore::mergeContacts()
601 {
602  TDEABC::Addressee::List list = mViewManager->selectedAddressees();
603  if ( list.count() < 2 )
604  return;
605 
606  TDEABC::Addressee addr = KABTools::mergeContacts( list );
607 
608  TDEABC::Addressee::List::Iterator it = list.begin();
609  const TDEABC::Addressee::List::Iterator endIt( list.end() );
610  TDEABC::Addressee origAddr = *it;
611  TQStringList uids;
612  ++it;
613  while ( it != endIt ) {
614  uids.append( (*it).uid() );
615  ++it;
616  }
617 
618  DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
619  mCommandHistory->addCommand( command );
620 
621  EditCommand *editCommand = new EditCommand( mAddressBook, origAddr, addr );
622  mCommandHistory->addCommand( editCommand );
623 
624  mSearchManager->reload();
625 }
626 
627 void KABCore::setWhoAmI()
628 {
629  TDEABC::Addressee::List addrList = mViewManager->selectedAddressees();
630 
631  if ( addrList.count() > 1 ) {
632  // can probably be removed because we now check the selection in setContactSelected().
633  KMessageBox::sorry( mWidget, i18n( "Please select only one contact." ) );
634  return;
635  }
636 
637  TQString text( i18n( "<qt>Do you really want to use <b>%1</b> as your new personal contact?</qt>" ) );
638  if ( KMessageBox::questionYesNo( mWidget, text.arg( addrList[ 0 ].assembledName() ), TQString(), i18n("Use"), i18n("Do Not Use") ) == KMessageBox::Yes )
639  static_cast<TDEABC::StdAddressBook*>( TDEABC::StdAddressBook::self( true ) )->setWhoAmI( addrList[ 0 ] );
640 }
641 
642 void KABCore::incrementalTextSearch( const TQString& text )
643 {
644  setContactSelected( TQString() );
645  mSearchManager->search( text, mIncSearchWidget->currentFields() );
646 }
647 
648 void KABCore::incrementalJumpButtonSearch( const TQString& character )
649 {
650  mViewManager->setSelected( TQString(), false );
651 
652  TDEABC::AddresseeList list = mSearchManager->contacts();
653  TDEABC::Field *field = mViewManager->currentSortField();
654  if ( field ) {
655  list.sortByField( field );
656  TDEABC::AddresseeList::ConstIterator it;
657  const TDEABC::AddresseeList::ConstIterator endIt( list.end() );
658  for ( it = list.begin(); it != endIt; ++it ) {
659  if ( field->value( *it ).startsWith( character, false ) ) {
660  mViewManager->setSelected( (*it).uid(), true );
661  return;
662  }
663  }
664  }
665 }
666 
667 void KABCore::setModified()
668 {
669  setModified( true );
670 }
671 
672 void KABCore::setModified( bool modified )
673 {
674  mModified = modified;
675  mActionSave->setEnabled( mModified );
676 
677  mSearchManager->reload();
678 }
679 
680 bool KABCore::modified() const
681 {
682  return mModified;
683 }
684 
685 void KABCore::contactModified( const TDEABC::Addressee &addr )
686 {
687  Command *command = 0;
688 
689  // check if it exists already
690  TDEABC::Addressee origAddr = mAddressBook->findByUid( addr.uid() );
691  if ( origAddr.isEmpty() ) {
692  TDEABC::Addressee::List addressees;
693  addressees.append( addr );
694  command = new NewCommand( mAddressBook, addressees );
695  } else {
696  command = new EditCommand( mAddressBook, origAddr, addr );
697  }
698 
699  mCommandHistory->addCommand( command );
700 
701  setContactSelected( addr.uid() );
702  setModified( true );
703 }
704 
705 void KABCore::newDistributionList()
706 {
707 #ifdef TDEPIM_NEW_DISTRLISTS
708  TDEABC::Resource *resource = requestResource( mWidget );
709  if ( !resource )
710  return;
711 
712  TQString name = i18n( "New Distribution List" );
713  const KPIM::DistributionList distList = KPIM::DistributionList::findByName( addressBook(), name );
714  if ( !distList.isEmpty() ) {
715  bool foundUnused = false;
716  int i = 1;
717  while ( !foundUnused ) {
718  name = i18n( "New Distribution List (%1)" ).arg( i++ );
719  foundUnused = KPIM::DistributionList::findByName( addressBook(), name ).isEmpty();
720  }
721  }
722  KPIM::DistributionList list;
723  list.setUid( TDEApplication::randomString( 10 ) );
724  list.setName( name );
725  list.setResource( resource );
726  editDistributionList( list );
727 #endif
728 }
729 
730 void KABCore::newContact()
731 {
732  AddresseeEditorDialog *dialog = 0;
733 
734  TDEABC::Resource* resource = requestResource( mWidget );
735 
736  if ( resource ) {
737  TDEABC::Addressee addr;
738  addr.setResource( resource );
739 
740  if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) )
741  return;
742 
743  dialog = createAddresseeEditorDialog( mWidget );
744  dialog->setAddressee( addr );
745  } else
746  return;
747 
748  mEditorDict.insert( dialog->addressee().uid(), dialog );
749 
750  dialog->show();
751 }
752 
753 void KABCore::addEmail( const TQString &aStr )
754 {
755  TQString fullName, email;
756 
757  TDEABC::Addressee::parseEmailAddress( aStr, fullName, email );
758 
759  // This ugly hack will be removed in 4.0
760  // addressbook may not be reloaded yet, as done asynchronously sometimes, so wait
761  while ( !mAddressBook->loadingHasFinished() ) {
762  TQApplication::eventLoop()->processEvents( TQEventLoop::ExcludeUserInput );
763  // use sleep here to reduce cpu usage
764  usleep( 100 );
765  }
766  // End of ugly hack
767 
768  // Try to lookup the addressee matching the email address
769  bool found = false;
770  TQStringList emailList;
771  TDEABC::AddressBook::Iterator it;
772  const TDEABC::AddressBook::Iterator endIt( mAddressBook->end() );
773  for ( it = mAddressBook->begin(); !found && (it != endIt); ++it ) {
774  emailList = (*it).emails();
775  if ( emailList.contains( email ) > 0 ) {
776  found = true;
777  (*it).setNameFromString( fullName );
778  editContact( (*it).uid() );
779  }
780  }
781 
782  if ( !found ) {
783  TDEABC::Addressee addr;
784  addr.setNameFromString( fullName );
785  addr.insertEmail( email, true );
786 
787  mAddressBook->insertAddressee( addr );
788  mViewManager->refreshView( addr.uid() );
789  editContact( addr.uid() );
790  }
791 }
792 
793 void KABCore::importVCard( const KURL &url )
794 {
795  mXXPortManager->importVCard( url );
796 }
797 
798 void KABCore::importVCardFromData( const TQString &vCard )
799 {
800  mXXPortManager->importVCardFromData( vCard );
801 }
802 
803 void KABCore::editContact( const TQString &uid )
804 {
805  if ( mExtensionManager->isQuickEditVisible() )
806  return;
807 
808  // First, locate the contact entry
809  TQString localUID = uid;
810  if ( localUID.isNull() ) {
811  TQStringList uidList = mViewManager->selectedUids();
812  if ( uidList.count() > 0 )
813  localUID = *( uidList.at( 0 ) );
814  }
815  // This ugly hack will be removed in 4.0
816  // for calls with given uid, as done from commandline and DCOP
817  // addressbook may not be reloaded yet, as done asynchronously, so wait
818  else while ( !mAddressBook->loadingHasFinished() ) {
819  TQApplication::eventLoop()->processEvents( TQEventLoop::ExcludeUserInput );
820  // use sleep here to reduce cpu usage
821  usleep( 100 );
822  }
823  // End of ugly hack
824 
825  TDEABC::Addressee addr = mAddressBook->findByUid( localUID );
826  if ( !addr.isEmpty() ) {
827  AddresseeEditorDialog *dialog = mEditorDict.find( addr.uid() );
828  if ( !dialog ) {
829 
830  if ( !addr.resource()->readOnly() )
831  if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) ) {
832  return;
833  }
834 
835  dialog = createAddresseeEditorDialog( mWidget );
836 
837  mEditorDict.insert( addr.uid(), dialog );
838 
839  dialog->setAddressee( addr );
840  }
841 
842  dialog->raise();
843  dialog->show();
844  }
845 }
846 
847 
848 void KABCore::copySelectedContactToResource()
849 {
850  storeContactIn( TQString(), true /*copy*/);
851 }
852 
853 void KABCore::moveSelectedContactToResource()
854 {
855  storeContactIn( TQString(), false /*copy*/);
856 }
857 
858 void KABCore::storeContactIn( const TQString &uid, bool copy /*false*/ )
859 {
860  // First, locate the contact entry
861  TQStringList uidList;
862  if ( uid.isNull() ) {
863  uidList = mViewManager->selectedUids();
864  } else {
865  uidList << uid;
866  }
867  TDEABC::Resource *resource = requestResource( mWidget );
868  if ( !resource )
869  return;
870 
871  if ( copy ) {
872  CopyToCommand *command = new CopyToCommand( mAddressBook, uidList, resource );
873  mCommandHistory->addCommand( command );
874  }
875  else {
876  MoveToCommand *command = new MoveToCommand( this, uidList, resource );
877  mCommandHistory->addCommand( command );
878  }
879 
880  addressBookChanged();
881  setModified( true );
882 }
883 
884 void KABCore::save()
885 {
886  TQPtrList<TDEABC::Resource> resources = mAddressBook->resources();
887  TQPtrListIterator<TDEABC::Resource> it( resources );
888  while ( it.current() && !it.current()->readOnly() ) {
889  TDEABC::Ticket *ticket = mAddressBook->requestSaveTicket( it.current() );
890  if ( ticket ) {
891  if ( !mAddressBook->save( ticket ) ) {
892  KMessageBox::error( mWidget,
893  i18n( "<qt>Unable to save address book <b>%1</b>.</qt>" ).arg( it.current()->resourceName() ) );
894  mAddressBook->releaseSaveTicket( ticket );
895  } else {
896  setModified( false );
897  }
898  } else {
899  KMessageBox::error( mWidget,
900  i18n( "<qt>Unable to get access for saving the address book <b>%1</b>.</qt>" )
901  .arg( it.current()->resourceName() ) );
902  }
903 
904  ++it;
905  }
906 }
907 
908 void KABCore::load()
909 {
910  TQPtrList<TDEABC::Resource> resources = mAddressBook->resources();
911  TQPtrListIterator<TDEABC::Resource> it( resources );
912  while ( it.current() ) {
913  mAddressBook->load();
914  ++it;
915  }
916 }
917 
918 void KABCore::setJumpButtonBarVisible( bool visible )
919 {
920  if ( visible ) {
921  if ( !mJumpButtonBar )
922  createJumpButtonBar();
923  mJumpButtonBar->show();
924  } else
925  if ( mJumpButtonBar )
926  mJumpButtonBar->hide();
927 }
928 
929 void KABCore::setDetailsVisible( bool visible )
930 {
931  if ( visible )
932  mDetailsPage->show();
933  else
934  mDetailsPage->hide();
935 }
936 
937 void KABCore::extensionModified( const TDEABC::Addressee::List &list )
938 {
939  if ( list.count() != 0 ) {
940  TDEABC::Addressee::List::ConstIterator it;
941  const TDEABC::Addressee::List::ConstIterator endIt( list.end() );
942  for ( it = list.begin(); it != endIt; ++it ) {
943  Command *command = 0;
944 
945  // check if it exists already
946  TDEABC::Addressee origAddr = mAddressBook->findByUid( (*it).uid() );
947  if ( origAddr.isEmpty() ) {
948  TDEABC::Addressee::List addressees;
949  addressees.append( *it );
950  command = new NewCommand( mAddressBook, addressees );
951  } else
952  command = new EditCommand( mAddressBook, origAddr, *it );
953 
954  mCommandHistory->blockSignals( true );
955  mCommandHistory->addCommand( command );
956  mCommandHistory->blockSignals( false );
957  }
958 
959  setModified(true);
960  }
961 }
962 
963 void KABCore::extensionDeleted( const TQStringList &uidList )
964 {
965  DeleteCommand *command = new DeleteCommand( mAddressBook, uidList );
966  mCommandHistory->addCommand( command );
967 
968  // now if we deleted anything, refresh
969  setContactSelected( TQString() );
970  setModified( true );
971 }
972 
973 TQString KABCore::getNameByPhone( const TQString &phone )
974 {
975  // This ugly hack will be removed in 4.0
976  // addressbook may not be reloaded yet, as done asynchronously, so wait
977  while ( !mAddressBook->loadingHasFinished() ) {
978  TQApplication::eventLoop()->processEvents( TQEventLoop::ExcludeUserInput );
979  // use sleep here to reduce cpu usage
980  usleep( 100 );
981  }
982  // End of ugly hack
983 
984  TQRegExp r( "[/*/-/ ]" );
985  TQString localPhone( phone );
986 
987  bool found = false;
988  TQString ownerName = "";
989  TDEABC::PhoneNumber::List phoneList;
990 
991  TDEABC::AddressBook::ConstIterator iter;
992  const TDEABC::AddressBook::ConstIterator endIter( mAddressBook->end() );
993 
994  for ( iter = mAddressBook->begin(); !found && ( iter != endIter ); ++iter ) {
995  phoneList = (*iter).phoneNumbers();
996  TDEABC::PhoneNumber::List::Iterator phoneIter( phoneList.begin() );
997  const TDEABC::PhoneNumber::List::Iterator phoneEndIter( phoneList.end() );
998  for ( ; !found && ( phoneIter != phoneEndIter ); ++phoneIter) {
999  // Get rid of separator chars so just the numbers are compared.
1000  if ( (*phoneIter).number().replace( r, "" ) == localPhone.replace( r, "" ) ) {
1001  ownerName = (*iter).realName();
1002  found = true;
1003  }
1004  }
1005  }
1006 
1007  return ownerName;
1008 }
1009 
1010 void KABCore::openLDAPDialog()
1011 {
1012  if ( !KProtocolInfo::isKnownProtocol( KURL( "ldap://localhost" ) ) ) {
1013  KMessageBox::error( mWidget, i18n( "Your TDE installation is missing LDAP "
1014  "support, please ask your administrator or distributor for more information." ),
1015  i18n( "No LDAP IO Slave Available" ) );
1016  return;
1017  }
1018 
1019  if ( !mLdapSearchDialog ) {
1020  mLdapSearchDialog = new LDAPSearchDialog( mAddressBook, this, mWidget );
1021  connect( mLdapSearchDialog, TQ_SIGNAL( addresseesAdded() ),
1022  TQ_SLOT( addressBookChanged() ) );
1023  connect( mLdapSearchDialog, TQ_SIGNAL( addresseesAdded() ),
1024  TQ_SLOT( setModified() ) );
1025  } else
1026  mLdapSearchDialog->restoreSettings();
1027 
1028  if ( mLdapSearchDialog->isOK() )
1029  mLdapSearchDialog->exec();
1030 }
1031 
1032 void KABCore::configure()
1033 {
1034  // Save the current config so we do not loose anything if the user accepts
1035  saveSettings();
1036 
1037  KCMultiDialog dlg( mWidget, "", true );
1038  connect( &dlg, TQ_SIGNAL( configCommitted() ),
1039  this, TQ_SLOT( configurationChanged() ) );
1040 
1041  dlg.addModule( "kabconfig.desktop" );
1042  dlg.addModule( "kabldapconfig.desktop" );
1043  dlg.addModule( "kabcustomfields.desktop" );
1044 
1045  dlg.exec();
1046 }
1047 
1048 void KABCore::print()
1049 {
1050  KPrinter printer;
1051  printer.setDocName( i18n( "Address Book" ) );
1052  printer.setDocFileName( "addressbook" );
1053 
1054  if ( !printer.setup( mWidget, i18n("Print Addresses") ) )
1055  return;
1056 
1057  KABPrinting::PrintingWizard wizard( &printer, mAddressBook,
1058  mViewManager->selectedUids(), mWidget );
1059 
1060  wizard.exec();
1061 }
1062 
1063 void KABCore::detailsHighlighted( const TQString &msg )
1064 {
1065  if ( mStatusBar ) {
1066  if ( !mStatusBar->hasItem( 2 ) )
1067  mStatusBar->insertItem( msg, 2 );
1068  else
1069  mStatusBar->changeItem( msg, 2 );
1070  }
1071 }
1072 
1073 void KABCore::showContactsAddress( const TQString &addrUid )
1074 {
1075  TQStringList uidList = mViewManager->selectedUids();
1076  if ( uidList.isEmpty() )
1077  return;
1078 
1079  TDEABC::Addressee addr = mAddressBook->findByUid( uidList.first() );
1080  if ( addr.isEmpty() )
1081  return;
1082 
1083  const TDEABC::Address::List list = addr.addresses();
1084  TDEABC::Address::List::ConstIterator it;
1085  const TDEABC::Address::List::ConstIterator endIt( list.end() );
1086  for ( it = list.begin(); it != endIt; ++it )
1087  if ( (*it).id() == addrUid ) {
1088  LocationMap::instance()->showAddress( *it );
1089  break;
1090  }
1091 }
1092 
1093 void KABCore::configurationChanged()
1094 {
1095  mExtensionManager->reconfigure();
1096  mViewManager->refreshView();
1097 }
1098 
1099 bool KABCore::queryClose()
1100 {
1101  saveSettings();
1102  KABPrefs::instance()->writeConfig();
1103 
1104  TQPtrList<TDEABC::Resource> resources = mAddressBook->resources();
1105  TQPtrListIterator<TDEABC::Resource> it( resources );
1106  while ( it.current() ) {
1107  it.current()->close();
1108  ++it;
1109  }
1110 
1111  return true;
1112 }
1113 
1114 void KABCore::reinitXMLGUI()
1115 {
1116  mExtensionManager->createActions();
1117 }
1118 void KABCore::delayedAddressBookChanged()
1119 {
1120  mAddressBookChangedTimer->start( 1000 );
1121 }
1122 
1123 void KABCore::addressBookChanged()
1124 {
1125  const TQStringList selectedUids = mViewManager->selectedUids();
1126 
1127  mAddressBookChangedTimer->stop();
1128 
1129  if ( mJumpButtonBar )
1130  mJumpButtonBar->updateButtons();
1131 
1132  mSearchManager->reload();
1133 
1134  mViewManager->setSelected( TQString(), false );
1135 
1136  TQString uid = TQString();
1137  if ( !selectedUids.isEmpty() ) {
1138  uid = selectedUids.first();
1139  mViewManager->setSelected( uid, true );
1140  }
1141 
1142  setContactSelected( uid );
1143 
1144  updateCategories();
1145 }
1146 
1147 AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( TQWidget *parent,
1148  const char *name )
1149 {
1150  AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent,
1151  name ? name : "editorDialog" );
1152  connect( dialog, TQ_SIGNAL( contactModified( const TDEABC::Addressee& ) ),
1153  TQ_SLOT( contactModified( const TDEABC::Addressee& ) ) );
1154  connect( dialog, TQ_SIGNAL( editorDestroyed( const TQString& ) ),
1155  TQ_SLOT( slotEditorDestroyed( const TQString& ) ) );
1156 
1157  return dialog;
1158 }
1159 
1160 void KABCore::activateDetailsWidget( TQWidget *widget )
1161 {
1162  if ( mDetailsStack->visibleWidget() == widget )
1163  return;
1164  mDetailsStack->raiseWidget( widget );
1165 }
1166 
1167 void KABCore::deactivateDetailsWidget( TQWidget *widget )
1168 {
1169  if ( mDetailsStack->visibleWidget() != widget )
1170  return;
1171  mDetailsStack->raiseWidget( mDetailsWidget );
1172 }
1173 
1174 void KABCore::slotEditorDestroyed( const TQString &uid )
1175 {
1176  AddresseeEditorDialog *dialog = mEditorDict.take( uid );
1177 
1178  TDEABC::Addressee addr = dialog->addressee();
1179 
1180  if ( !addr.resource()->readOnly() ) {
1181  TQApplication::setOverrideCursor( TQt::waitCursor );
1182  KABLock::self( mAddressBook )->unlock( addr.resource() );
1183  TQApplication::restoreOverrideCursor();
1184  }
1185 }
1186 
1187 void KABCore::initGUI()
1188 {
1189  TQVBoxLayout *topLayout = new TQVBoxLayout( mWidget, 0, 0 );
1190  TDEToolBar* searchTB = new TDEToolBar( mWidget, "search toolbar");
1191  searchTB->boxLayout()->setSpacing( KDialog::spacingHint() );
1192  mIncSearchWidget = new IncSearchWidget( searchTB, "tde toolbar widget");
1193  searchTB->setStretchableWidget( mIncSearchWidget );
1194  connect( mIncSearchWidget, TQ_SIGNAL( doSearch( const TQString& ) ),
1195  TQ_SLOT( incrementalTextSearch( const TQString& ) ) );
1196 
1197  mDetailsSplitter = new TQSplitter( mWidget );
1198 
1199  mLeftSplitter = new TQSplitter( mDetailsSplitter );
1200  mLeftSplitter->setOrientation( KABPrefs::instance()->contactListAboveExtensions() ? TQt::Vertical : TQt::Horizontal );
1201 
1202  topLayout->addWidget( searchTB );
1203  topLayout->addWidget( mDetailsSplitter );
1204 
1205  mDetailsStack = new TQWidgetStack( mDetailsSplitter );
1206  mExtensionManager = new ExtensionManager( new TQWidget( mLeftSplitter ), mDetailsStack, this, this );
1207  connect( mExtensionManager, TQ_SIGNAL( detailsWidgetDeactivated( TQWidget* ) ),
1208  this, TQ_SLOT( deactivateDetailsWidget( TQWidget* ) ) );
1209  connect( mExtensionManager, TQ_SIGNAL( detailsWidgetActivated( TQWidget* ) ),
1210  this, TQ_SLOT( activateDetailsWidget( TQWidget* ) ) );
1211 
1212  TQWidget *viewWidget = new TQWidget( mLeftSplitter );
1213  if ( KABPrefs::instance()->contactListAboveExtensions() )
1214  mLeftSplitter->moveToFirst( viewWidget );
1215  TQVBoxLayout *viewLayout = new TQVBoxLayout( viewWidget );
1216  viewLayout->setSpacing( KDialog::spacingHint() );
1217 
1218  mViewHeaderLabel = new TQLabel( viewWidget );
1219 // mViewHeaderLabel->setSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Fixed );
1220  mViewHeaderLabel->setText( i18n( "Contacts" ) );
1221  viewLayout->addWidget( mViewHeaderLabel );
1222  mViewManager = new ViewManager( this, viewWidget );
1223  viewLayout->addWidget( mViewManager, 1 );
1224 
1225 #ifdef TDEPIM_NEW_DISTRLISTS
1226  mDistListButtonWidget = new TQWidget( viewWidget );
1227  TQHBoxLayout *buttonLayout = new TQHBoxLayout( mDistListButtonWidget );
1228  buttonLayout->setSpacing( KDialog::spacingHint() );
1229  buttonLayout->addStretch( 1 );
1230 
1231  mAddDistListButton = new KPushButton( mDistListButtonWidget );
1232  mAddDistListButton->setEnabled( false );
1233  mAddDistListButton->setText( i18n( "Add" ) );
1234  TQToolTip::add( mAddDistListButton, i18n( "Add contacts to the distribution list" ) );
1235  TQWhatsThis::add( mAddDistListButton,
1236  i18n( "Click this button if you want to add more contacts to "
1237  "the current distribution list. You will be shown a dialog that allows "
1238  "to enter a list of existing contacts to this distribution list." ) );
1239  connect( mAddDistListButton, TQ_SIGNAL( clicked() ),
1240  this, TQ_SLOT( editSelectedDistributionList() ) );
1241  buttonLayout->addWidget( mAddDistListButton );
1242  mDistListButtonWidget->setShown( false );
1243  viewLayout->addWidget( mDistListButtonWidget );
1244 
1245  mRemoveDistListButton = new KPushButton( mDistListButtonWidget );
1246  mRemoveDistListButton->setEnabled( false );
1247  mRemoveDistListButton->setText( i18n( "Remove" ) );
1248  TQToolTip::add( mRemoveDistListButton, i18n( "Remove contacts from the distribution list" ) );
1249  TQWhatsThis::add( mRemoveDistListButton,
1250  i18n( "Click this button if you want to remove the selected contacts from "
1251  "the current distribution list." ) );
1252  connect( mRemoveDistListButton, TQ_SIGNAL( clicked() ),
1253  this, TQ_SLOT( removeSelectedContactsFromDistList() ) );
1254  buttonLayout->addWidget( mRemoveDistListButton );
1255 #endif
1256 
1257  mFilterSelectionWidget = new FilterSelectionWidget( searchTB , "tde toolbar widget" );
1258  mViewManager->setFilterSelectionWidget( mFilterSelectionWidget );
1259 
1260  connect( mFilterSelectionWidget, TQ_SIGNAL( filterActivated( int ) ),
1261  mViewManager, TQ_SLOT( setActiveFilter( int ) ) );
1262 
1263  mDetailsWidget = new TQWidget( mDetailsSplitter );
1264  mDetailsLayout = new TQHBoxLayout( mDetailsWidget );
1265 
1266  mDetailsPage = new TQWidget( mDetailsWidget );
1267  mDetailsLayout->addWidget( mDetailsPage );
1268 
1269  TQHBoxLayout *detailsPageLayout = new TQHBoxLayout( mDetailsPage, 0, 0 );
1270  mDetailsViewer = new KPIM::AddresseeView( mDetailsPage );
1271  mDetailsViewer->setVScrollBarMode( TQScrollView::Auto );
1272  detailsPageLayout->addWidget( mDetailsViewer );
1273 
1274  mDistListEntryView = new KAB::DistributionListEntryView( this, mWidget );
1275  connect( mDistListEntryView, TQ_SIGNAL( distributionListClicked( const TQString& ) ),
1276  this, TQ_SLOT( sendMailToDistributionList( const TQString& ) ) );
1277  mDetailsStack->addWidget( mDistListEntryView );
1278  mDetailsStack->addWidget( mDetailsWidget );
1279  mDetailsStack->raiseWidget( mDetailsWidget );
1280  mDetailsSplitter->moveToLast( mDetailsStack );
1281 
1282  connect( mDetailsViewer, TQ_SIGNAL( addressClicked( const TQString&) ),
1283  this, TQ_SLOT( showContactsAddress( const TQString& ) ) );
1284 
1285  topLayout->setStretchFactor( mDetailsSplitter, 1 );
1286 
1287  mXXPortManager = new XXPortManager( this, mWidget );
1288 
1289  initActions();
1290 }
1291 
1292 void KABCore::createJumpButtonBar()
1293 {
1294  mJumpButtonBar = new JumpButtonBar( this, mDetailsWidget );
1295  mDetailsLayout->addWidget( mJumpButtonBar );
1296  mDetailsLayout->setStretchFactor( mJumpButtonBar, 1 );
1297 
1298  connect( mJumpButtonBar, TQ_SIGNAL( jumpToLetter( const TQString& ) ),
1299  TQ_SLOT( incrementalJumpButtonSearch( const TQString& ) ) );
1300  connect( mViewManager, TQ_SIGNAL( sortFieldChanged() ),
1301  mJumpButtonBar, TQ_SLOT( updateButtons() ) );
1302 }
1303 
1304 void KABCore::initActions()
1305 {
1306  connect( TQApplication::clipboard(), TQ_SIGNAL( dataChanged() ),
1307  TQ_SLOT( clipboardDataChanged() ) );
1308 
1309  TDEAction *action;
1310 
1311  // file menu
1312  mActionMail = new TDEAction( i18n( "&Send Email to Contact..." ), "mail-send", 0,
1313  this, TQ_SLOT( sendMail() ), actionCollection(), "file_mail" );
1314  action = KStdAction::print( this, TQ_SLOT( print() ), actionCollection() );
1315  mActionMail->setWhatsThis( i18n( "Send a mail to all selected contacts." ) );
1316  action->setWhatsThis( i18n( "Print a special number of contacts." ) );
1317 
1318  mActionSave = KStdAction::save( this,
1319  TQ_SLOT( save() ), actionCollection(), "file_sync" );
1320  mActionSave->setWhatsThis( i18n( "Save all changes of the address book to the storage backend." ) );
1321 
1322  action = new TDEAction( i18n( "&New Contact..." ), "identity", CTRL+Key_N, this,
1323  TQ_SLOT( newContact() ), actionCollection(), "file_new_contact" );
1324  action->setWhatsThis( i18n( "Create a new contact<p>You will be presented with a dialog where you can add all data about a person, including addresses and phone numbers." ) );
1325 
1326  action = new TDEAction( i18n( "&New Distribution List..." ), "kontact_contacts", 0, this,
1327  TQ_SLOT( newDistributionList() ), actionCollection(), "file_new_distributionlist" );
1328  action->setWhatsThis( i18n( "Create a new distribution list<p>You will be presented with a dialog where you can create a new distribution list." ) );
1329 
1330  mActionMailVCard = new TDEAction( i18n("Send &Contact..."), "mail_post_to", 0,
1331  this, TQ_SLOT( mailVCard() ),
1332  actionCollection(), "file_mail_vcard" );
1333  mActionMailVCard->setWhatsThis( i18n( "Send a mail with the selected contact as attachment." ) );
1334 
1335  mActionChat = new TDEAction( i18n("Chat &With..."), 0,
1336  this, TQ_SLOT( startChat() ),
1337  actionCollection(), "file_chat" );
1338  mActionChat->setWhatsThis( i18n( "Start a chat with the selected contact." ) );
1339 
1340  mActionEditAddressee = new TDEAction( i18n( "&Edit Contact..." ), "edit", 0,
1341  this, TQ_SLOT( editContact() ),
1342  actionCollection(), "file_properties" );
1343  mActionEditAddressee->setWhatsThis( i18n( "Edit a contact<p>You will be presented with a dialog where you can change all data about a person, including addresses and phone numbers." ) );
1344 
1345  mActionMerge = new TDEAction( i18n( "&Merge Contacts" ), "", 0,
1346  this, TQ_SLOT( mergeContacts() ),
1347  actionCollection(), "edit_merge" );
1348 
1349  // edit menu
1350  mActionCopy = KStdAction::copy( this, TQ_SLOT( copyContacts() ), actionCollection() );
1351  mActionCut = KStdAction::cut( this, TQ_SLOT( cutContacts() ), actionCollection() );
1352  mActionPaste = KStdAction::paste( this, TQ_SLOT( pasteContacts() ), actionCollection() );
1353  action = KStdAction::selectAll( this, TQ_SLOT( selectAllContacts() ), actionCollection() );
1354  mActionCopy->setWhatsThis( i18n( "Copy the currently selected contact(s) to system clipboard in vCard format." ) );
1355  mActionCut->setWhatsThis( i18n( "Cuts the currently selected contact(s) to system clipboard in vCard format." ) );
1356  mActionPaste->setWhatsThis( i18n( "Paste the previously cut or copied contacts from clipboard." ) );
1357  action->setWhatsThis( i18n( "Selects all visible contacts from current view." ) );
1358 // mActionUndo->setWhatsThis( i18n( "Undoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
1359 // mActionRedo->setWhatsThis( i18n( "Redoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
1360 
1361  mActionDelete = new TDEAction( i18n( "&Delete Contact" ), "edit-delete",
1362  Key_Delete, this, TQ_SLOT( deleteContacts() ),
1363  actionCollection(), "edit_delete" );
1364  mActionDelete->setWhatsThis( i18n( "Delete all selected contacts." ) );
1365 
1366 
1367  mActionCopyAddresseeTo = new TDEAction( i18n( "&Copy Contact To..." ), "", 0,
1368  this, TQ_SLOT( copySelectedContactToResource() ),
1369  actionCollection(), "copy_contact_to" );
1370  const TQString copyMoveWhatsThis = i18n( "Store a contact in a different Addressbook<p>You will be presented with a dialog where you can select a new storage place for this contact." );
1371  mActionCopyAddresseeTo->setWhatsThis( copyMoveWhatsThis );
1372 
1373  mActionMoveAddresseeTo = new TDEAction( i18n( "M&ove Contact To..." ), "", 0,
1374  this, TQ_SLOT( moveSelectedContactToResource() ),
1375  actionCollection(), "move_contact_to" );
1376  mActionMoveAddresseeTo->setWhatsThis( copyMoveWhatsThis );
1377 
1378  // settings menu
1379  mActionJumpBar = new TDEToggleAction( i18n( "Show Jump Bar" ), "next", 0,
1380  actionCollection(), "options_show_jump_bar" );
1381  mActionJumpBar->setWhatsThis( i18n( "Toggle whether the jump button bar shall be visible." ) );
1382  mActionJumpBar->setCheckedState( i18n( "Hide Jump Bar") );
1383  connect( mActionJumpBar, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( setJumpButtonBarVisible( bool ) ) );
1384 
1385  mActionDetails = new TDEToggleAction( i18n( "Show Details" ), 0, 0,
1386  actionCollection(), "options_show_details" );
1387  mActionDetails->setWhatsThis( i18n( "Toggle whether the details page shall be visible." ) );
1388  mActionDetails->setCheckedState( i18n( "Hide Details") );
1389  connect( mActionDetails, TQ_SIGNAL( toggled( bool ) ), TQ_SLOT( setDetailsVisible( bool ) ) );
1390 
1391  if ( mIsPart )
1392  action = new TDEAction( i18n( "&Configure Address Book..." ), "configure", 0,
1393  this, TQ_SLOT( configure() ), actionCollection(),
1394  "kaddressbook_configure" );
1395  else
1396  action = KStdAction::preferences( this, TQ_SLOT( configure() ), actionCollection() );
1397 
1398  action->setWhatsThis( i18n( "You will be presented with a dialog, that offers you all possibilities to configure KAddressBook." ) );
1399 
1400  // misc
1401  action = new TDEAction( i18n( "&Lookup Addresses in LDAP Directory..." ), "edit-find", 0,
1402  this, TQ_SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" );
1403  action->setWhatsThis( i18n( "Search for contacts on a LDAP server<p>You will be presented with a dialog, where you can search for contacts and select the ones you want to add to your local address book." ) );
1404 
1405  mActionWhoAmI = new TDEAction( i18n( "Set as Personal Contact Data" ), "preferences-desktop-personal", 0, this,
1406  TQ_SLOT( setWhoAmI() ), actionCollection(),
1407  "edit_set_personal" );
1408  mActionWhoAmI->setWhatsThis( i18n( "Set the personal contact<p>The data of this contact will be used in many other TDE applications, so you do not have to input your personal data several times." ) );
1409 
1410  mActionCategories = new TDEAction( i18n( "Select Categories..." ), 0, this,
1411  TQ_SLOT( setCategories() ), actionCollection(),
1412  "edit_set_categories" );
1413  mActionCategories->setWhatsThis( i18n( "Set the categories for all selected contacts." ) );
1414 
1415  TDEAction *clearLocation = new TDEAction( i18n( "Clear Search Bar" ),
1416  TQApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
1417  CTRL+Key_L, this, TQ_SLOT( slotClearSearchBar() ), actionCollection(), "clear_search" );
1418  clearLocation->setWhatsThis( i18n( "Clear Search Bar<p>"
1419  "Clears the content of the quick search bar." ) );
1420 
1421  clipboardDataChanged();
1422 }
1423 
1424 void KABCore::clipboardDataChanged()
1425 {
1426  if ( mReadWrite )
1427  mActionPaste->setEnabled( !TQApplication::clipboard()->text().isEmpty() );
1428 }
1429 
1430 void KABCore::updateIncSearchWidget()
1431 {
1432  mIncSearchWidget->setViewFields( mViewManager->viewFields() );
1433 }
1434 
1435 void KABCore::updateCategories()
1436 {
1437  TQStringList categories( allCategories() );
1438  categories.sort();
1439 
1440  const TQStringList customCategories( KABPrefs::instance()->customCategories() );
1441  TQStringList::ConstIterator it;
1442  const TQStringList::ConstIterator endIt( customCategories.end() );
1443  for ( it = customCategories.begin(); it != endIt; ++it ) {
1444  if ( categories.find( *it ) == categories.end() ) {
1445  categories.append( *it );
1446  }
1447  }
1448 
1449  KABPrefs::instance()->mCustomCategories = categories;
1450  KABPrefs::instance()->writeConfig();
1451 
1452  if ( mCategoryEditDialog )
1453  mCategoryEditDialog->reload();
1454 }
1455 
1456 TQStringList KABCore::allCategories() const
1457 {
1458  TQStringList categories, allCategories;
1459  TQStringList::ConstIterator catIt;
1460 
1461  // Avoid crash on exit
1462  if ( !mAddressBook ) {
1463  return allCategories;
1464  }
1465 
1466  TDEABC::AddressBook::ConstIterator it;
1467  const TDEABC::AddressBook::ConstIterator endIt( mAddressBook->end() );
1468  for ( it = mAddressBook->begin(); it != endIt; ++it ) {
1469  categories = (*it).categories();
1470  const TQStringList::ConstIterator catEndIt( categories.end() );
1471  for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
1472  if ( !allCategories.contains( *catIt ) )
1473  allCategories.append( *catIt );
1474  }
1475  }
1476 
1477  return allCategories;
1478 }
1479 
1480 void KABCore::setCategories()
1481 {
1482  // Show the category dialog
1483  if ( mCategorySelectDialog == 0 ) {
1484  mCategorySelectDialog = new KPIM::CategorySelectDialog( KABPrefs::instance(), mWidget );
1485  connect( mCategorySelectDialog, TQ_SIGNAL( categoriesSelected( const TQStringList& ) ),
1486  TQ_SLOT( categoriesSelected( const TQStringList& ) ) );
1487  connect( mCategorySelectDialog, TQ_SIGNAL( editCategories() ), TQ_SLOT( editCategories() ) );
1488  }
1489 
1490  mCategorySelectDialog->show();
1491  mCategorySelectDialog->raise();
1492 }
1493 
1494 void KABCore::categoriesSelected( const TQStringList &categories )
1495 {
1496  bool merge = false;
1497  TQString msg = i18n( "Merge with existing categories?" );
1498  if ( KMessageBox::questionYesNo( mWidget, msg, TQString(), i18n( "Merge" ), i18n( "Do Not Merge" ) ) == KMessageBox::Yes )
1499  merge = true;
1500 
1501  TQStringList uids = mViewManager->selectedUids();
1502  TQStringList::ConstIterator it;
1503  const TQStringList::ConstIterator endIt( uids.end() );
1504  for ( it = uids.begin(); it != endIt; ++it ) {
1505  TDEABC::Addressee addr = mAddressBook->findByUid( *it );
1506  if ( !addr.isEmpty() ) {
1507  if ( !merge )
1508  addr.setCategories( categories );
1509  else {
1510  TQStringList addrCategories = addr.categories();
1511  TQStringList::ConstIterator catIt;
1512  const TQStringList::ConstIterator catEndIt( categories.end() );
1513  for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
1514  if ( !addrCategories.contains( *catIt ) )
1515  addrCategories.append( *catIt );
1516  }
1517  addr.setCategories( addrCategories );
1518  }
1519 
1520  mAddressBook->insertAddressee( addr );
1521  }
1522  }
1523 
1524  if ( uids.count() > 0 )
1525  setModified( true );
1526 }
1527 
1528 void KABCore::editCategories()
1529 {
1530  if ( mCategoryEditDialog == 0 ) {
1531  mCategoryEditDialog = new KPIM::CategoryEditDialog( KABPrefs::instance(), mWidget );
1532  connect( mCategoryEditDialog, TQ_SIGNAL( categoryConfigChanged() ),
1533  mCategorySelectDialog, TQ_SLOT( updateCategoryConfig() ) );
1534  }
1535 
1536  mCategoryEditDialog->show();
1537  mCategoryEditDialog->raise();
1538 }
1539 
1540 void KABCore::slotClearSearchBar()
1541 {
1542  mIncSearchWidget->clear();
1543  mIncSearchWidget->setFocus();
1544 }
1545 
1546 void KABCore::slotContactsUpdated()
1547 {
1548  if ( mStatusBar ) {
1549  TQString msg( i18n( "%n contact matches", "%n contacts matching", mSearchManager->contacts().count() ) );
1550  if ( !mStatusBar->hasItem( 1 ) )
1551  mStatusBar->insertItem( msg, 1 );
1552  else
1553  mStatusBar->changeItem( msg, 1 );
1554  }
1555 
1556  emit contactsUpdated();
1557 }
1558 
1559 bool KABCore::handleCommandLine( KAddressBookIface* iface )
1560 {
1561  TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs();
1562  TQCString addrStr = args->getOption( "addr" );
1563  TQCString uidStr = args->getOption( "uid" );
1564 
1565  TQString addr, uid, vcard;
1566  if ( !addrStr.isEmpty() )
1567  addr = TQString::fromLocal8Bit( addrStr );
1568  if ( !uidStr.isEmpty() )
1569  uid = TQString::fromLocal8Bit( uidStr );
1570 
1571  bool doneSomething = false;
1572 
1573  // Can not see why anyone would pass both a uid and an email address, so I'll leave it that two contact editors will show if they do
1574  if ( !addr.isEmpty() ) {
1575  iface->addEmail( addr );
1576  doneSomething = true;
1577  }
1578 
1579  if ( !uid.isEmpty() ) {
1580  iface->showContactEditor( uid );
1581  doneSomething = true;
1582  }
1583 
1584  if ( args->isSet( "new-contact" ) ) {
1585  iface->newContact();
1586  doneSomething = true;
1587  }
1588 
1589  if ( args->count() >= 1 ) {
1590  for ( int i = 0; i < args->count(); ++i )
1591  iface->importVCard( args->url( i ).url() );
1592  doneSomething = true;
1593  }
1594  return doneSomething;
1595 }
1596 
1597 void KABCore::removeSelectedContactsFromDistList()
1598 {
1599 #ifdef TDEPIM_NEW_DISTRLISTS
1600 
1601  KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList );
1602  if ( dist.isEmpty() )
1603  return;
1604  const TQStringList uids = selectedUIDs();
1605  if ( uids.isEmpty() )
1606  return;
1607 
1608  TQStringList names;
1609  TQStringList::ConstIterator it = uids.begin();
1610  const TQStringList::ConstIterator endIt( uids.end() );
1611  while ( it != endIt ) {
1612  TDEABC::Addressee addr = mAddressBook->findByUid( *it );
1613  names.append( addr.realName().isEmpty() ? addr.preferredEmail() : addr.realName() );
1614  ++it;
1615  }
1616 
1617  if ( KMessageBox::warningContinueCancelList(
1618  mWidget,
1619  i18n( "<qt>"
1620  "Do you really want to remove this contact from the %1 distribution list?<br>"
1621  "<b>Note:</b>The contact will be not be removed from your addressbook nor from "
1622  "any other distribution list."
1623  "</qt>",
1624  "<qt>"
1625  "Do you really want to remove these %n contacts from the %1 distribution list?<br>"
1626  "<b>Note:</b>The contacts will be not be removed from your addressbook nor from "
1627  "any other distribution list."
1628  "</qt>",
1629  uids.count() ).arg( mSelectedDistributionList ),
1630  names, TQString(), KStdGuiItem::del() ) == KMessageBox::Cancel ) {
1631  return;
1632  }
1633 
1634  for ( TQStringList::ConstIterator uidIt = uids.begin(); uidIt != uids.end(); ++uidIt ) {
1635  typedef KPIM::DistributionList::Entry::List EntryList;
1636  const EntryList entries = dist.entries( addressBook() );
1637  for ( EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it ) {
1638  if ( (*it).addressee.uid() == (*uidIt) ) {
1639  dist.removeEntry( (*it).addressee, (*it).email );
1640  break;
1641  }
1642  }
1643  }
1644  addressBook()->insertAddressee( dist );
1645  setModified();
1646 #endif
1647 }
1648 
1649 void KABCore::sendMailToDistributionList( const TQString &name )
1650 {
1651 #ifdef TDEPIM_NEW_DISTRLISTS
1652  KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), name );
1653  if ( dist.isEmpty() )
1654  return;
1655  typedef KPIM::DistributionList::Entry::List EntryList;
1656  TQStringList mails;
1657  const EntryList entries = dist.entries( addressBook() );
1658  for ( EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it )
1659  mails += (*it).addressee.fullEmail( (*it).email );
1660  sendMail( mails.join( ", " ) );
1661 #endif
1662 }
1663 
1664 void KABCore::editSelectedDistributionList()
1665 {
1666 #ifdef TDEPIM_NEW_DISTRLISTS
1667  editDistributionList( KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList ) );
1668 #endif
1669 }
1670 
1671 
1672 void KABCore::editDistributionList( const TQString &name )
1673 {
1674 #ifdef TDEPIM_NEW_DISTRLISTS
1675  editDistributionList( KPIM::DistributionList::findByName( addressBook(), name ) );
1676 #endif
1677 }
1678 
1679 #ifdef TDEPIM_NEW_DISTRLISTS
1680 
1681 void KABCore::showDistributionListEntry( const TQString& uid )
1682 {
1683  KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList );
1684  if ( !dist.isEmpty() ) {
1685  mDistListEntryView->clear();
1686  typedef KPIM::DistributionList::Entry::List EntryList;
1687  const EntryList entries = dist.entries( addressBook() );
1688  for (EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it ) {
1689  if ( (*it).addressee.uid() == uid ) {
1690  mDistListEntryView->setEntry( dist, *it );
1691  break;
1692  }
1693  }
1694  }
1695 }
1696 
1697 void KABCore::editDistributionList( const KPIM::DistributionList &dist )
1698 {
1699  if ( dist.isEmpty() )
1700  return;
1701  TQGuardedPtr<KPIM::DistributionListEditor::EditorWidget> dlg = new KPIM::DistributionListEditor::EditorWidget( addressBook(), widget() );
1702  dlg->setDistributionList( dist );
1703  if ( dlg->exec() == TQDialog::Accepted && dlg ) {
1704  const KPIM::DistributionList newDist = dlg->distributionList();
1705  if ( newDist != dist ) {
1706  setModified();
1707  }
1708  }
1709  delete dlg;
1710 }
1711 
1712 
1713 KPIM::DistributionList::List KABCore::distributionLists() const
1714 {
1715  return mSearchManager->distributionLists();
1716 }
1717 
1718 void KABCore::setSelectedDistributionList( const TQString &name )
1719 {
1720  mSelectedDistributionList = name;
1721  mSearchManager->setSelectedDistributionList( name );
1722  mViewHeaderLabel->setText( name.isNull() ?
1723  i18n( "Contacts" ) :
1724  i18n( "Distribution List: %1" ).arg( name ) );
1725  mDistListButtonWidget->setShown( !mSelectedDistributionList.isNull() );
1726  if ( !name.isNull() ) {
1727  mDetailsStack->raiseWidget( mDistListEntryView );
1728  if ( selectedUIDs().isEmpty() ) {
1729  mViewManager->setFirstSelected( true );
1730  }
1731  const TQStringList selectedUids = selectedUIDs();
1732  showDistributionListEntry( selectedUids.isEmpty() ? TQString() : selectedUids.first() );
1733  } else {
1734  mDetailsStack->raiseWidget( mExtensionManager->activeDetailsWidget() ?
1735  mExtensionManager->activeDetailsWidget() : mDetailsWidget );
1736  }
1737 }
1738 
1739 TQStringList KABCore::distributionListNames() const
1740 {
1741  return mSearchManager->distributionListNames();
1742 }
1743 #endif
1744 
1745 #include "kabcore.moc"
static TDEABC::Addressee::List clipboardToAddressees(const TQString &clipboard)
Convert a string from the clipboard into a list of addressee objects.
static TQString addresseesToClipboard(const TDEABC::Addressee::List &addrList)
Same as above function, except that an entire list of TDEABC::Addressee objects will be converted to ...
A simple widget which consists of a label and a combo box in a horizontal line.
Used to draw the jump button bar on the right of the view.
Definition: jumpbuttonbar.h:48
The PrintingWizard combines pages common for all print styles and those provided by the respective st...
The view manager manages the views and everything related to them.
Definition: viewmanager.h:51