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 <tdestandarddirs.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
94KABCore::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( tdeApp->dcopClient() );
191}
192
193KABCore::~KABCore()
194{
195 mAddressBook->disconnect();
196
197 mAddressBook = 0;
198 TDEABC::StdAddressBook::close();
199 mKIMProxy = 0;
200}
201
202void 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
230void 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
243TDEABC::AddressBook *KABCore::addressBook() const
244{
245 return mAddressBook;
246}
247
248TDEConfig *KABCore::config() const
249{
250 return KABPrefs::instance()->config();
251}
252
253TDEActionCollection *KABCore::actionCollection() const
254{
255 return guiClient()->actionCollection();
256}
257
258TDEABC::Field *KABCore::currentSortField() const
259{
260 return mViewManager->currentSortField();
261}
262
263TQStringList KABCore::selectedUIDs() const
264{
265 return mViewManager->selectedUids();
266}
267
268TDEABC::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
303TQWidget *KABCore::widget() const
304{
305 return mWidget;
306}
307
308TDEAboutData *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
332void KABCore::setStatusBar( KStatusBar *statusBar )
333{
334 mStatusBar = statusBar;
335}
336
337KStatusBar *KABCore::statusBar() const
338{
339 return mStatusBar;
340}
341
342void 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
443void KABCore::sendMail()
444{
445 //FIXME: breaks with email addresses containing ","
446 sendMail( mViewManager->selectedEmails().join( ", " ) );
447}
448
449void KABCore::sendMail( const TQString& email )
450{
451 tdeApp->invokeMailer( email, "" );
452}
453
454void KABCore::mailVCard()
455{
456 TQStringList uids = mViewManager->selectedUids();
457 if ( !uids.isEmpty() )
458 mailVCard( uids );
459}
460
461void KABCore::mailVCard( const TQStringList &uids )
462{
463 KABTools::mailVCards( uids, mAddressBook );
464}
465
466void KABCore::startChat()
467{
468 TQStringList uids = mViewManager->selectedUids();
469 if ( !uids.isEmpty() )
470 mKIMProxy->chatWithContact( uids.first() );
471}
472
473void KABCore::browse( const TQString& url )
474{
475 tdeApp->invokeBrowser( url );
476}
477
478void KABCore::selectAllContacts()
479{
480 mViewManager->setSelected( TQString(), true );
481}
482
483void KABCore::deleteContacts()
484{
485 TQStringList uidList = mViewManager->selectedUids();
486
487 deleteContacts( uidList );
488}
489
490void 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
508void 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
544void 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
559void 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
571void 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
583void 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
600void 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
627void 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
642void KABCore::incrementalTextSearch( const TQString& text )
643{
644 setContactSelected( TQString() );
645 mSearchManager->search( text, mIncSearchWidget->currentFields() );
646}
647
648void 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
667void KABCore::setModified()
668{
669 setModified( true );
670}
671
672void KABCore::setModified( bool modified )
673{
674 mModified = modified;
675 mActionSave->setEnabled( mModified );
676
677 mSearchManager->reload();
678}
679
680bool KABCore::modified() const
681{
682 return mModified;
683}
684
685void 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
705void 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
730void 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
753void 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
793void KABCore::importVCard( const KURL &url )
794{
795 mXXPortManager->importVCard( url );
796}
797
798void KABCore::importVCardFromData( const TQString &vCard )
799{
800 mXXPortManager->importVCardFromData( vCard );
801}
802
803void 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
848void KABCore::copySelectedContactToResource()
849{
850 storeContactIn( TQString(), true /*copy*/);
851}
852
853void KABCore::moveSelectedContactToResource()
854{
855 storeContactIn( TQString(), false /*copy*/);
856}
857
858void 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
884void 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
908void 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
918void 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
929void KABCore::setDetailsVisible( bool visible )
930{
931 if ( visible )
932 mDetailsPage->show();
933 else
934 mDetailsPage->hide();
935}
936
937void 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
963void 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
973TQString 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
1010void 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
1032void 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
1048void 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
1063void 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
1073void 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
1093void KABCore::configurationChanged()
1094{
1095 mExtensionManager->reconfigure();
1096 mViewManager->refreshView();
1097}
1098
1099bool 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
1114void KABCore::reinitXMLGUI()
1115{
1116 mExtensionManager->createActions();
1117}
1118void KABCore::delayedAddressBookChanged()
1119{
1120 mAddressBookChangedTimer->start( 1000 );
1121}
1122
1123void 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
1147AddresseeEditorDialog *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
1160void KABCore::activateDetailsWidget( TQWidget *widget )
1161{
1162 if ( mDetailsStack->visibleWidget() == widget )
1163 return;
1164 mDetailsStack->raiseWidget( widget );
1165}
1166
1167void KABCore::deactivateDetailsWidget( TQWidget *widget )
1168{
1169 if ( mDetailsStack->visibleWidget() != widget )
1170 return;
1171 mDetailsStack->raiseWidget( mDetailsWidget );
1172}
1173
1174void 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
1187void 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
1292void 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
1304void 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
1424void KABCore::clipboardDataChanged()
1425{
1426 if ( mReadWrite )
1427 mActionPaste->setEnabled( !TQApplication::clipboard()->text().isEmpty() );
1428}
1429
1430void KABCore::updateIncSearchWidget()
1431{
1432 mIncSearchWidget->setViewFields( mViewManager->viewFields() );
1433}
1434
1435void 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
1456TQStringList 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
1480void 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
1494void 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
1528void 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
1540void KABCore::slotClearSearchBar()
1541{
1542 mIncSearchWidget->clear();
1543 mIncSearchWidget->setFocus();
1544}
1545
1546void 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
1559bool 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
1597void 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
1649void 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
1664void KABCore::editSelectedDistributionList()
1665{
1666#ifdef TDEPIM_NEW_DISTRLISTS
1667 editDistributionList( KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList ) );
1668#endif
1669}
1670
1671
1672void 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
1681void 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
1697void 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
1713KPIM::DistributionList::List KABCore::distributionLists() const
1714{
1715 return mSearchManager->distributionLists();
1716}
1717
1718void 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
1739TQStringList 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