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.

resourceselection.cpp 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /*
  2. This file is part of KAddressBook.
  3. Copyright (c) 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. #include <tqlayout.h>
  20. #include <tqpopupmenu.h>
  21. #include <tqpushbutton.h>
  22. #include <tqtimer.h>
  23. #include <tqlabel.h>
  24. #include <tqheader.h>
  25. #include <tqtooltip.h>
  26. #include <kabc/resource.h>
  27. #include <kdialog.h>
  28. #include <kglobal.h>
  29. #include <kiconloader.h>
  30. #include <kinputdialog.h>
  31. #include <klocale.h>
  32. #include <kmessagebox.h>
  33. #include <kresources/configdialog.h>
  34. #include "core.h"
  35. #include "resourceselection.h"
  36. #include <libtdepim/resourceabc.h>
  37. class AddressBookWrapper : public KABC::AddressBook
  38. {
  39. public:
  40. AddressBookWrapper( KABC::AddressBook* );
  41. KRES::Manager<KABC::Resource>* getResourceManager()
  42. {
  43. return resourceManager();
  44. }
  45. };
  46. class ResourceItem : public TQCheckListItem
  47. {
  48. public:
  49. ResourceItem( KListView *parent, KABC::Resource *resource )
  50. : TQCheckListItem( parent, resource->resourceName(), CheckBox ),
  51. mResource( resource ), mChecked( false ),
  52. mIsSubresource( false ), mSubItemsCreated( false ),
  53. mResourceIdentifier()
  54. {
  55. setOn( resource->isActive() );
  56. setPixmap( 0, KGlobal::iconLoader()->loadIcon( "contents", KIcon::Small ) );
  57. mChecked = isOn();
  58. }
  59. ResourceItem( KPIM::ResourceABC *resourceABC, ResourceItem* parent,
  60. const TQString& resourceIdent )
  61. : TQCheckListItem( parent, resourceABC->subresourceLabel( resourceIdent ), CheckBox ),
  62. mResource( resourceABC ), mChecked( false ),
  63. mIsSubresource( true ), mSubItemsCreated( false ),
  64. mResourceIdentifier( resourceIdent )
  65. {
  66. KPIM::ResourceABC* res = dynamic_cast<KPIM::ResourceABC *>( mResource );
  67. setOn( res->subresourceActive( mResourceIdentifier ) );
  68. setPixmap( 0, KGlobal::iconLoader()->loadIcon( "contents", KIcon::Small ) );
  69. mChecked = isOn();
  70. }
  71. void createSubresourceItems();
  72. void setChecked( bool state ) {
  73. mChecked = state;
  74. setOn(state);
  75. }
  76. bool checked() const { return mChecked; }
  77. KABC::Resource *resource() const { return mResource; }
  78. TQString resourceIdentifier() const { return mResourceIdentifier; }
  79. bool isSubResource() const { return mIsSubresource; }
  80. virtual void stateChange( bool active );
  81. private:
  82. KABC::Resource * const mResource;
  83. bool mChecked;
  84. const bool mIsSubresource;
  85. bool mSubItemsCreated;
  86. const TQString mResourceIdentifier;
  87. };
  88. // Comes from korganizer/resourceview.cpp
  89. void ResourceItem::createSubresourceItems()
  90. {
  91. KPIM::ResourceABC* res = dynamic_cast<KPIM::ResourceABC *>( mResource );
  92. TQStringList subresources;
  93. if ( res )
  94. subresources = res->subresources();
  95. if ( !subresources.isEmpty() ) {
  96. setOpen( true );
  97. setExpandable( true );
  98. // This resource has subresources
  99. TQStringList::ConstIterator it;
  100. for ( it = subresources.begin(); it != subresources.end(); ++it ) {
  101. (void)new ResourceItem( res, this, *it );
  102. }
  103. }
  104. mSubItemsCreated = true;
  105. }
  106. void ResourceItem::stateChange( bool active )
  107. {
  108. //kdDebug(5720) << k_funcinfo << this << " " << text( 0 ) << " active=" << active << endl;
  109. if ( active && !mIsSubresource ) {
  110. if ( !mSubItemsCreated )
  111. createSubresourceItems();
  112. }
  113. setOpen( active && childCount() > 0 );
  114. }
  115. ////
  116. ResourceSelection::ResourceSelection( KAB::Core *core, TQWidget *parent, const char *name )
  117. : KAB::ExtensionWidget( core, parent, name ), mManager( 0 )
  118. {
  119. initGUI();
  120. AddressBookWrapper *wrapper = static_cast<AddressBookWrapper*>( core->addressBook() );
  121. mManager = wrapper->getResourceManager();
  122. connect( mAddButton, TQT_SIGNAL( clicked() ), TQT_SLOT( add() ) );
  123. connect( mEditButton, TQT_SIGNAL( clicked() ), TQT_SLOT( edit() ) );
  124. connect( mRemoveButton, TQT_SIGNAL( clicked() ), TQT_SLOT( remove() ) );
  125. connect( mListView, TQT_SIGNAL( clicked( TQListViewItem* ) ),
  126. TQT_SLOT( currentChanged( TQListViewItem* ) ) );
  127. connect( mListView, TQT_SIGNAL( contextMenuRequested ( TQListViewItem *,
  128. const TQPoint &, int ) ),
  129. TQT_SLOT( contextMenuRequested( TQListViewItem *, const TQPoint &,
  130. int ) ) );
  131. TQTimer::singleShot( 0, this, TQT_SLOT( updateView() ) );
  132. }
  133. ResourceSelection::~ResourceSelection()
  134. {
  135. }
  136. void ResourceSelection::contextMenuRequested ( TQListViewItem *i,
  137. const TQPoint &pos, int )
  138. {
  139. ResourceItem *item = static_cast<ResourceItem *>( i );
  140. TQPopupMenu *menu = new TQPopupMenu( this );
  141. connect( menu, TQT_SIGNAL( aboutToHide() ), menu, TQT_SLOT( deleteLater() ) );
  142. if ( item ) {
  143. int reloadId = menu->insertItem( i18n("Re&load"), this,
  144. TQT_SLOT( reloadResource() ) );
  145. menu->setItemEnabled( reloadId, item->resource()->isActive() );
  146. int saveId = menu->insertItem( i18n("&Save"), this,
  147. TQT_SLOT( saveResource() ) );
  148. menu->setItemEnabled( saveId, item->resource()->isActive() );
  149. menu->insertSeparator();
  150. // menu->insertItem( i18n("Show &Info"), this, TQT_SLOT( showInfo() ) );
  151. menu->insertItem( i18n("&Edit..."), this, TQT_SLOT( edit() ) );
  152. menu->insertItem( i18n("&Remove"), this, TQT_SLOT( remove() ) );
  153. menu->insertSeparator();
  154. }
  155. menu->insertItem( i18n("&Add..."), this, TQT_SLOT( add() ) );
  156. menu->popup( pos );
  157. }
  158. void ResourceSelection::reloadResource()
  159. {
  160. ResourceItem *item = selectedItem();
  161. if ( !item ) return;
  162. KABC::Resource *r = item->resource();
  163. r->load();
  164. }
  165. void ResourceSelection::saveResource()
  166. {
  167. ResourceItem *item = selectedItem();
  168. if ( !item ) return;
  169. KABC::Resource *r = item->resource();
  170. KABC::Ticket *ticket = core()->addressBook()->requestSaveTicket( r );
  171. if ( ticket ) {
  172. r->save( ticket );
  173. }
  174. }
  175. void ResourceSelection::showInfo()
  176. {
  177. ResourceItem *item = selectedItem();
  178. if ( !item ) return;
  179. // TQString txt = "<qt>" + item->resource()->infoText() + "</qt>";
  180. // KMessageBox::information( this, txt );
  181. }
  182. TQString ResourceSelection::title() const
  183. {
  184. return i18n( "Address Books" );
  185. }
  186. TQString ResourceSelection::identifier() const
  187. {
  188. return "resourceselection";
  189. }
  190. void ResourceSelection::add()
  191. {
  192. TQStringList types = mManager->resourceTypeNames();
  193. TQStringList descs = mManager->resourceTypeDescriptions();
  194. bool ok = false;
  195. TQString desc = KInputDialog::getItem( i18n( "Add Address Book" ),
  196. i18n( "Please select type of the new address book:" ),
  197. descs, 0, false, &ok, this );
  198. if ( !ok )
  199. return;
  200. TQString type = types[ descs.findIndex( desc ) ];
  201. // Create new resource
  202. KABC::Resource *resource = mManager->createResource( type );
  203. if ( !resource ) {
  204. KMessageBox::error( this, i18n("<qt>Unable to create an address book of type <b>%1</b>.</qt>")
  205. .tqarg( type ) );
  206. return;
  207. }
  208. resource->setAddressBook(core()->addressBook());
  209. KRES::ConfigDialog dlg( this, TQString( "contact" ), resource );
  210. if ( dlg.exec() ) {
  211. core()->addressBook()->addResource( resource );
  212. resource->asyncLoad();
  213. mLastResource = resource->identifier();
  214. updateView();
  215. currentChanged(mListView->currentItem() );
  216. } else {
  217. delete resource;
  218. resource = 0;
  219. }
  220. }
  221. void ResourceSelection::edit()
  222. {
  223. ResourceItem *item = selectedItem();
  224. if ( !item )
  225. return;
  226. // view items can change during "edit", e.g. sub resources being removed ->
  227. // sub resource item removed
  228. // thus keep their data rather than their pointer
  229. KABC::Resource *resource = item->resource();
  230. KRES::ConfigDialog dlg( this, TQString( "contact" ), resource );
  231. if ( dlg.exec() ) {
  232. mManager->change( resource );
  233. resource->asyncLoad();
  234. mLastResource = resource->identifier();
  235. updateView();
  236. }
  237. }
  238. void ResourceSelection::remove()
  239. {
  240. ResourceItem *item = selectedItem();
  241. if ( !item )
  242. return;
  243. int result = KMessageBox::warningContinueCancel( this,
  244. i18n( "<qt>Do you really want to remove the address book <b>%1</b>?</qt>" )
  245. .tqarg( item->resource()->resourceName() ), "",
  246. KGuiItem( i18n( "&Remove" ), "editdelete" ) );
  247. if ( result == KMessageBox::Cancel )
  248. return;
  249. mLastResource = item->resource()->identifier();
  250. core()->addressBook()->removeResource( item->resource() );
  251. core()->addressBook()->emitAddressBookChanged();
  252. updateView();
  253. currentChanged(mListView->currentItem() );
  254. }
  255. void ResourceSelection::currentChanged( TQListViewItem *item )
  256. {
  257. ResourceItem *resItem = static_cast<ResourceItem*>( item );
  258. bool state = (resItem && !resItem->isSubResource() );
  259. mEditButton->setEnabled( state );
  260. mRemoveButton->setEnabled( state );
  261. if ( !resItem )
  262. return;
  263. KABC::Resource *resource = resItem->resource();
  264. if ( resItem->checked() != resItem->isOn() ) {
  265. resItem->setChecked( resItem->isOn() );
  266. if ( resItem->isSubResource() ) {
  267. KPIM::ResourceABC *res = dynamic_cast<KPIM::ResourceABC *>( resource );
  268. res->setSubresourceActive( resItem->resourceIdentifier(), resItem->isOn() );
  269. mManager->change( resource );
  270. } else {
  271. resource->setActive( resItem->isOn() );
  272. mManager->change( resource );
  273. if ( resItem->checked() ) {
  274. if ( !resource->addressBook() )
  275. resource->setAddressBook( core()->addressBook() );
  276. if ( !resource->isOpen() )
  277. resource->open();
  278. resource->asyncLoad();
  279. } else {
  280. resource->close();
  281. }
  282. }
  283. mLastResource = resource->identifier();
  284. core()->addressBook()->emitAddressBookChanged();
  285. //updateView();
  286. }
  287. }
  288. void ResourceSelection::updateView()
  289. {
  290. if ( !mManager )
  291. return;
  292. mListView->clear();
  293. KRES::Manager<KABC::Resource>::Iterator it;
  294. for ( it = mManager->begin(); it != mManager->end(); ++it ) {
  295. ResourceItem *item = new ResourceItem( mListView, *it );
  296. KPIM::ResourceABC* resource = dynamic_cast<KPIM::ResourceABC *>( *it );
  297. if ( resource ) {
  298. disconnect( resource, 0, this, 0 );
  299. connect( resource, TQT_SIGNAL( signalSubresourceAdded( KPIM::ResourceABC *,
  300. const TQString &, const TQString & ) ),
  301. TQT_SLOT( slotSubresourceAdded( KPIM::ResourceABC *,
  302. const TQString &, const TQString & ) ) );
  303. connect( resource, TQT_SIGNAL( signalSubresourceRemoved( KPIM::ResourceABC *,
  304. const TQString &, const TQString & ) ),
  305. TQT_SLOT( slotSubresourceRemoved( KPIM::ResourceABC *,
  306. const TQString &, const TQString & ) ) );
  307. connect( resource, TQT_SIGNAL( signalSubresourceChanged( KPIM::ResourceABC *,
  308. const TQString &, const TQString & ) ),
  309. TQT_SLOT( slotSubresourceChanged( KPIM::ResourceABC *,
  310. const TQString &, const TQString & ) ) );
  311. //connect( resource, TQT_SIGNAL( resourceSaved( KPIM::ResourceABC * ) ),
  312. // TQT_SLOT( closeResource( KPIM::ResourceABC * ) ) );
  313. item->createSubresourceItems();
  314. }
  315. }
  316. TQListViewItemIterator itemIt( mListView );
  317. while ( itemIt.current() ) {
  318. ResourceItem *item = static_cast<ResourceItem*>( itemIt.current() );
  319. if ( item->resource()->identifier() == mLastResource ) {
  320. mListView->setSelected( item, true );
  321. mListView->ensureItemVisible( item );
  322. break;
  323. }
  324. ++itemIt;
  325. }
  326. core()->addressBook()->emitAddressBookChanged();
  327. }
  328. // Add a new entry
  329. void ResourceSelection::slotSubresourceAdded( KPIM::ResourceABC *resource,
  330. const TQString& /*type*/,
  331. const TQString& subResource )
  332. {
  333. kdDebug(5720) << k_funcinfo << resource->resourceName() << " " << subResource << endl;
  334. TQListViewItem *i = mListView->findItem( resource->resourceName(), 0 );
  335. if ( !i )
  336. // Not found
  337. return;
  338. ResourceItem *item = static_cast<ResourceItem *>( i );
  339. // Make sure all other sub items have already been created
  340. item->createSubresourceItems();
  341. // check if we already have an item for it
  342. if ( !findSubResourceItem( resource, subResource ) ) {
  343. (void)new ResourceItem( resource, item, subResource );
  344. }
  345. }
  346. // Remove an entry
  347. void ResourceSelection::slotSubresourceRemoved( KPIM::ResourceABC* resource,
  348. const TQString& /*type*/,
  349. const TQString& subResource )
  350. {
  351. ResourceItem *item = findSubResourceItem( resource, subResource );
  352. delete item;
  353. core()->addressBook()->emitAddressBookChanged();
  354. updateView();
  355. }
  356. // change an entry
  357. void ResourceSelection::slotSubresourceChanged( KPIM::ResourceABC* resource,
  358. const TQString& type,
  359. const TQString& subResource )
  360. {
  361. kdDebug(5720) << resource->resourceName() << subResource;
  362. ResourceItem *item = findSubResourceItem( resource, subResource );
  363. if ( item == 0 ) {
  364. kdWarning(5720) << "Changed before it was added?";
  365. slotSubresourceAdded( resource, type, subResource );
  366. return;
  367. }
  368. item->setText( 0, resource->subresourceLabel( subResource ) );
  369. item->setChecked( resource->subresourceActive( subResource ) ? true : false );
  370. // TODO
  371. //emitResourcesChanged();
  372. core()->addressBook()->emitAddressBookChanged();
  373. updateView();
  374. }
  375. ResourceItem* ResourceSelection::selectedItem() const
  376. {
  377. return static_cast<ResourceItem*>( mListView->selectedItem() );
  378. }
  379. ResourceItem* ResourceSelection::findSubResourceItem( KPIM::ResourceABC *resource,
  380. const TQString &subResource )
  381. {
  382. TQListViewItemIterator parentIt( mListView );
  383. for ( ; *parentIt; ++parentIt ) {
  384. if ( static_cast<ResourceItem*>(*parentIt)->resource() != resource )
  385. continue;
  386. TQListViewItemIterator childIt( *parentIt );
  387. for ( ; *childIt; ++childIt ) {
  388. ResourceItem *item = static_cast<ResourceItem*>(*childIt);
  389. if ( item->resourceIdentifier() == subResource )
  390. return item;
  391. }
  392. }
  393. return 0;
  394. }
  395. void ResourceSelection::initGUI()
  396. {
  397. TQBoxLayout *topLayout = new TQVBoxLayout( this );
  398. topLayout->setSpacing( KDialog::spacingHint() );
  399. TQBoxLayout *buttonLayout = new TQHBoxLayout();
  400. buttonLayout->setSpacing( KDialog::spacingHint() );
  401. topLayout->addLayout( buttonLayout );
  402. TQLabel *abLabel = new TQLabel( i18n( "Address Books" ), this );
  403. buttonLayout->addWidget( abLabel );
  404. buttonLayout->addStretch( 1 );
  405. mAddButton = new TQPushButton( this );
  406. mAddButton->setIconSet( SmallIconSet( "add" ) );
  407. TQToolTip::add( mAddButton, i18n( "Add addressbook" ) );
  408. buttonLayout->addWidget( mAddButton );
  409. mEditButton = new TQPushButton( this );
  410. mEditButton->setIconSet( SmallIconSet( "edit" ) );
  411. mEditButton->setEnabled( false );
  412. TQToolTip::add( mEditButton, i18n( "Edit addressbook settings" ) );
  413. buttonLayout->addWidget( mEditButton );
  414. mRemoveButton = new TQPushButton( this );
  415. mRemoveButton->setIconSet( SmallIconSet( "remove" ) );
  416. mRemoveButton->setEnabled( false );
  417. TQToolTip::add( mRemoveButton, i18n( "Remove addressbook" ) );
  418. buttonLayout->addWidget( mRemoveButton );
  419. mListView = new KListView( this );
  420. mListView->header()->hide();
  421. mListView->addColumn( i18n( "Address Books" ) );
  422. mListView->setFullWidth( true );
  423. topLayout->addWidget( mListView );
  424. }
  425. class ResourceSelectionFactory : public KAB::ExtensionFactory
  426. {
  427. public:
  428. KAB::ExtensionWidget *extension( KAB::Core *core, TQWidget *parent, const char *name )
  429. {
  430. return new ResourceSelection( core, parent, name );
  431. }
  432. TQString identifier() const
  433. {
  434. return "resourceselection";
  435. }
  436. };
  437. extern "C" {
  438. void *init_libkaddrbk_resourceselection()
  439. {
  440. return ( new ResourceSelectionFactory );
  441. }
  442. }
  443. #include "resourceselection.moc"