/* This file is part of KAddressBook. Copyright (c) 2004 Tobias Koenig This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. As a special exception, permission is given to link this program with any edition of Qt, and distribute the resulting executable, without including the source code for Qt in the source distribution. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "core.h" #include "resourceselection.h" #include class AddressBookWrapper : public KABC::AddressBook { public: AddressBookWrapper( KABC::AddressBook* ); KRES::Manager* getResourceManager() { return resourceManager(); } }; class ResourceItem : public QCheckListItem { public: ResourceItem( KListView *parent, KABC::Resource *resource ) : QCheckListItem( parent, resource->resourceName(), CheckBox ), mResource( resource ), mChecked( false ), mIsSubresource( false ), mSubItemsCreated( false ), mResourceIdentifier() { setOn( resource->isActive() ); setPixmap( 0, KGlobal::iconLoader()->loadIcon( "contents", KIcon::Small ) ); mChecked = isOn(); } ResourceItem( KPIM::ResourceABC *resourceABC, ResourceItem* parent, const QString& resourceIdent ) : QCheckListItem( parent, resourceABC->subresourceLabel( resourceIdent ), CheckBox ), mResource( resourceABC ), mChecked( false ), mIsSubresource( true ), mSubItemsCreated( false ), mResourceIdentifier( resourceIdent ) { KPIM::ResourceABC* res = dynamic_cast( mResource ); setOn( res->subresourceActive( mResourceIdentifier ) ); setPixmap( 0, KGlobal::iconLoader()->loadIcon( "contents", KIcon::Small ) ); mChecked = isOn(); } void createSubresourceItems(); void setChecked( bool state ) { mChecked = state; setOn(state); } bool checked() const { return mChecked; } KABC::Resource *resource() const { return mResource; } QString resourceIdentifier() const { return mResourceIdentifier; } bool isSubResource() const { return mIsSubresource; } virtual void stateChange( bool active ); private: KABC::Resource * const mResource; bool mChecked; const bool mIsSubresource; bool mSubItemsCreated; const QString mResourceIdentifier; }; // Comes from korganizer/resourceview.cpp void ResourceItem::createSubresourceItems() { KPIM::ResourceABC* res = dynamic_cast( mResource ); QStringList subresources; if ( res ) subresources = res->subresources(); if ( !subresources.isEmpty() ) { setOpen( true ); setExpandable( true ); // This resource has subresources QStringList::ConstIterator it; for ( it = subresources.begin(); it != subresources.end(); ++it ) { (void)new ResourceItem( res, this, *it ); } } mSubItemsCreated = true; } void ResourceItem::stateChange( bool active ) { //kdDebug(5720) << k_funcinfo << this << " " << text( 0 ) << " active=" << active << endl; if ( active && !mIsSubresource ) { if ( !mSubItemsCreated ) createSubresourceItems(); } setOpen( active && childCount() > 0 ); } //// ResourceSelection::ResourceSelection( KAB::Core *core, QWidget *parent, const char *name ) : KAB::ExtensionWidget( core, parent, name ), mManager( 0 ) { initGUI(); AddressBookWrapper *wrapper = static_cast( core->addressBook() ); mManager = wrapper->getResourceManager(); connect( mAddButton, SIGNAL( clicked() ), SLOT( add() ) ); connect( mEditButton, SIGNAL( clicked() ), SLOT( edit() ) ); connect( mRemoveButton, SIGNAL( clicked() ), SLOT( remove() ) ); connect( mListView, SIGNAL( clicked( QListViewItem* ) ), SLOT( currentChanged( QListViewItem* ) ) ); QTimer::singleShot( 0, this, SLOT( updateView() ) ); } ResourceSelection::~ResourceSelection() { } QString ResourceSelection::title() const { return i18n( "Address Books" ); } QString ResourceSelection::identifier() const { return "resourceselection"; } void ResourceSelection::add() { QStringList types = mManager->resourceTypeNames(); QStringList descs = mManager->resourceTypeDescriptions(); bool ok = false; QString desc = KInputDialog::getItem( i18n( "Add Address Book" ), i18n( "Please select type of the new address book:" ), descs, 0, false, &ok, this ); if ( !ok ) return; QString type = types[ descs.findIndex( desc ) ]; // Create new resource KABC::Resource *resource = mManager->createResource( type ); if ( !resource ) { KMessageBox::error( this, i18n("Unable to create an address book of type %1.") .arg( type ) ); return; } resource->setResourceName( i18n( "%1 address book" ).arg( type ) ); resource->setAddressBook(core()->addressBook()); KRES::ConfigDialog dlg( this, QString( "contact" ), resource ); if ( dlg.exec() ) { core()->addressBook()->addResource( resource ); resource->asyncLoad(); mLastResource = resource->identifier(); updateView(); } else { delete resource; resource = 0; } } void ResourceSelection::edit() { ResourceItem *item = selectedItem(); if ( !item ) return; // view items can change during "edit", e.g. sub resources being removed -> // sub resource item removed // thus keep their data rather than their pointer KABC::Resource *resource = item->resource(); KRES::ConfigDialog dlg( this, QString( "contact" ), resource ); if ( dlg.exec() ) { mManager->change( resource ); resource->asyncLoad(); mLastResource = resource->identifier(); updateView(); } } void ResourceSelection::remove() { ResourceItem *item = selectedItem(); if ( !item ) return; int result = KMessageBox::warningContinueCancel( this, i18n( "Do you really want to remove the address book %1?" ) .arg( item->resource()->resourceName() ), "", KGuiItem( i18n( "&Remove" ), "editdelete" ) ); if ( result == KMessageBox::Cancel ) return; mLastResource = item->resource()->identifier(); core()->addressBook()->removeResource( item->resource() ); core()->addressBook()->emitAddressBookChanged(); updateView(); } void ResourceSelection::currentChanged( QListViewItem *item ) { ResourceItem *resItem = static_cast( item ); bool state = (resItem && !resItem->isSubResource() ); mEditButton->setEnabled( state ); mRemoveButton->setEnabled( state ); if ( !resItem ) return; KABC::Resource *resource = resItem->resource(); if ( resItem->checked() != resItem->isOn() ) { resItem->setChecked( resItem->isOn() ); if ( resItem->isSubResource() ) { KPIM::ResourceABC *res = dynamic_cast( resource ); res->setSubresourceActive( resItem->resourceIdentifier(), resItem->isOn() ); mManager->change( resource ); } else { resource->setActive( resItem->isOn() ); mManager->change( resource ); if ( resItem->checked() ) { if ( !resource->addressBook() ) resource->setAddressBook( core()->addressBook() ); if ( !resource->isOpen() ) resource->open(); resource->asyncLoad(); } else { resource->close(); } } mLastResource = resource->identifier(); core()->addressBook()->emitAddressBookChanged(); //updateView(); } } void ResourceSelection::updateView() { if ( !mManager ) return; mListView->clear(); KRES::Manager::Iterator it; for ( it = mManager->begin(); it != mManager->end(); ++it ) { ResourceItem *item = new ResourceItem( mListView, *it ); KPIM::ResourceABC* resource = dynamic_cast( *it ); if ( resource ) { disconnect( resource, 0, this, 0 ); connect( resource, SIGNAL( signalSubresourceAdded( KPIM::ResourceABC *, const QString &, const QString & ) ), SLOT( slotSubresourceAdded( KPIM::ResourceABC *, const QString &, const QString & ) ) ); connect( resource, SIGNAL( signalSubresourceRemoved( KPIM::ResourceABC *, const QString &, const QString & ) ), SLOT( slotSubresourceRemoved( KPIM::ResourceABC *, const QString &, const QString & ) ) ); connect( resource, SIGNAL( signalSubresourceChanged( KPIM::ResourceABC *, const QString &, const QString & ) ), SLOT( slotSubresourceChanged( KPIM::ResourceABC *, const QString &, const QString & ) ) ); //connect( resource, SIGNAL( resourceSaved( KPIM::ResourceABC * ) ), // SLOT( closeResource( KPIM::ResourceABC * ) ) ); item->createSubresourceItems(); } } QListViewItemIterator itemIt( mListView ); while ( itemIt.current() ) { ResourceItem *item = static_cast( itemIt.current() ); if ( item->resource()->identifier() == mLastResource ) { mListView->setSelected( item, true ); mListView->ensureItemVisible( item ); break; } ++itemIt; } core()->addressBook()->emitAddressBookChanged(); } // Add a new entry void ResourceSelection::slotSubresourceAdded( KPIM::ResourceABC *resource, const QString& /*type*/, const QString& subResource ) { kdDebug(5720) << k_funcinfo << resource->resourceName() << " " << subResource << endl; QListViewItem *i = mListView->findItem( resource->resourceName(), 0 ); if ( !i ) // Not found return; ResourceItem *item = static_cast( i ); // Make sure all other sub items have already been created item->createSubresourceItems(); // check if we already have an item for it if ( !findSubResourceItem( resource, subResource ) ) { (void)new ResourceItem( resource, item, subResource ); } } // Remove an entry void ResourceSelection::slotSubresourceRemoved( KPIM::ResourceABC* resource, const QString& /*type*/, const QString& subResource ) { ResourceItem *item = findSubResourceItem( resource, subResource ); delete item; core()->addressBook()->emitAddressBookChanged(); updateView(); } // change an entry void ResourceSelection::slotSubresourceChanged( KPIM::ResourceABC* resource, const QString& type, const QString& subResource ) { kdDebug(5720) << resource->resourceName() << subResource; ResourceItem *item = findSubResourceItem( resource, subResource ); if ( item == 0 ) { kdWarning(5720) << "Changed before it was added?"; slotSubresourceAdded( resource, type, subResource ); return; } item->setText( 0, resource->subresourceLabel( subResource ) ); item->setChecked( resource->subresourceActive( subResource ) ? true : false ); // TODO //emitResourcesChanged(); core()->addressBook()->emitAddressBookChanged(); updateView(); } ResourceItem* ResourceSelection::selectedItem() const { return static_cast( mListView->selectedItem() ); } ResourceItem* ResourceSelection::findSubResourceItem( KPIM::ResourceABC *resource, const QString &subResource ) { QListViewItemIterator parentIt( mListView ); for ( ; *parentIt; ++parentIt ) { if ( static_cast(*parentIt)->resource() != resource ) continue; QListViewItemIterator childIt( *parentIt ); for ( ; *childIt; ++childIt ) { ResourceItem *item = static_cast(*childIt); if ( item->resourceIdentifier() == subResource ) return item; } } return 0; } void ResourceSelection::initGUI() { QBoxLayout *topLayout = new QVBoxLayout( this ); topLayout->setSpacing( KDialog::spacingHint() ); QBoxLayout *buttonLayout = new QHBoxLayout(); buttonLayout->setSpacing( KDialog::spacingHint() ); topLayout->addLayout( buttonLayout ); QLabel *abLabel = new QLabel( i18n( "Address Books" ), this ); buttonLayout->addWidget( abLabel ); buttonLayout->addStretch( 1 ); mAddButton = new QPushButton( this ); mAddButton->setIconSet( SmallIconSet( "add" ) ); QToolTip::add( mAddButton, i18n( "Add addressbook" ) ); buttonLayout->addWidget( mAddButton ); mEditButton = new QPushButton( this ); mEditButton->setIconSet( SmallIconSet( "edit" ) ); mEditButton->setEnabled( false ); QToolTip::add( mEditButton, i18n( "Edit addressbook settings" ) ); buttonLayout->addWidget( mEditButton ); mRemoveButton = new QPushButton( this ); mRemoveButton->setIconSet( SmallIconSet( "remove" ) ); mRemoveButton->setEnabled( false ); QToolTip::add( mRemoveButton, i18n( "Remove addressbook" ) ); buttonLayout->addWidget( mRemoveButton ); mListView = new KListView( this ); mListView->header()->hide(); mListView->addColumn( i18n( "Address Books" ) ); mListView->setFullWidth( true ); topLayout->addWidget( mListView ); } class ResourceSelectionFactory : public KAB::ExtensionFactory { public: KAB::ExtensionWidget *extension( KAB::Core *core, QWidget *parent, const char *name ) { return new ResourceSelection( core, parent, name ); } QString identifier() const { return "resourceselection"; } }; extern "C" { void *init_libkaddrbk_resourceselection() { return ( new ResourceSelectionFactory ); } } #include "resourceselection.moc"