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