TDE personal information management applications
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1754 lines
59KB

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