00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qlayout.h>
00025 #include <qpushbutton.h>
00026 #include <qtimer.h>
00027
00028 #include <kabc/resource.h>
00029 #include <kdialog.h>
00030 #include <kinputdialog.h>
00031 #include <klocale.h>
00032 #include <kmessagebox.h>
00033 #include <kresources/configdialog.h>
00034
00035 #include "core.h"
00036
00037 #include "resourceselection.h"
00038 #include <libkdepim/resourceabc.h>
00039
00040 class AddressBookWrapper : public KABC::AddressBook
00041 {
00042 public:
00043 AddressBookWrapper( KABC::AddressBook* );
00044
00045 KRES::Manager<KABC::Resource>* getResourceManager()
00046 {
00047 return resourceManager();
00048 }
00049 };
00050
00051 class ResourceItem : public QCheckListItem
00052 {
00053 public:
00054 ResourceItem( KListView *parent, KABC::Resource *resource )
00055 : QCheckListItem( parent, resource->resourceName(), CheckBox ),
00056 mResource( resource ), mChecked( false ),
00057 mIsSubresource( false ), mSubItemsCreated( false ),
00058 mResourceIdentifier()
00059 {
00060 setOn( resource->isActive() );
00061 mChecked = isOn();
00062 }
00063
00064 ResourceItem( KPIM::ResourceABC *resourceABC, ResourceItem* parent,
00065 const QString& resourceIdent )
00066 : QCheckListItem( parent, resourceABC->subresourceLabel( resourceIdent ), CheckBox ),
00067 mResource( resourceABC ), mChecked( false ),
00068 mIsSubresource( true ), mSubItemsCreated( false ),
00069 mResourceIdentifier( resourceIdent )
00070 {
00071 KPIM::ResourceABC* res = dynamic_cast<KPIM::ResourceABC *>( mResource );
00072 setOn( res->subresourceActive( mResourceIdentifier ) );
00073 mChecked = isOn();
00074 }
00075
00076 void createSubresourceItems();
00077
00078 void setChecked( bool state ) { mChecked = state; }
00079 bool checked() const { return mChecked; }
00080 KABC::Resource *resource() const { return mResource; }
00081 QString resourceIdentifier() const { return mResourceIdentifier; }
00082 bool isSubResource() const { return mIsSubresource; }
00083
00084 virtual void stateChange( bool active );
00085
00086 private:
00087 KABC::Resource * const mResource;
00088 bool mChecked;
00089 const bool mIsSubresource;
00090 bool mSubItemsCreated;
00091 const QString mResourceIdentifier;
00092 };
00093
00094
00095 void ResourceItem::createSubresourceItems()
00096 {
00097 KPIM::ResourceABC* res = dynamic_cast<KPIM::ResourceABC *>( mResource );
00098 QStringList subresources;
00099 if ( res )
00100 subresources = res->subresources();
00101 if ( !subresources.isEmpty() ) {
00102 setOpen( true );
00103 setExpandable( true );
00104
00105 QStringList::ConstIterator it;
00106 for ( it = subresources.begin(); it != subresources.end(); ++it ) {
00107 (void)new ResourceItem( res, this, *it );
00108 }
00109 }
00110 mSubItemsCreated = true;
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 void ResourceItem::stateChange( bool active )
00123 {
00124
00125 if ( active && !mIsSubresource ) {
00126 if ( !mSubItemsCreated )
00127 createSubresourceItems();
00128 }
00129
00130 setOpen( active && childCount() > 0 );
00131 }
00132
00134
00135 ResourceSelection::ResourceSelection( KAB::Core *core, QWidget *parent, const char *name )
00136 : KAB::ExtensionWidget( core, parent, name ), mManager( 0 )
00137 {
00138 initGUI();
00139
00140 AddressBookWrapper *wrapper = static_cast<AddressBookWrapper*>( core->addressBook() );
00141 mManager = wrapper->getResourceManager();
00142
00143 connect( mAddButton, SIGNAL( clicked() ), SLOT( add() ) );
00144 connect( mEditButton, SIGNAL( clicked() ), SLOT( edit() ) );
00145 connect( mRemoveButton, SIGNAL( clicked() ), SLOT( remove() ) );
00146
00147 connect( mListView, SIGNAL( clicked( QListViewItem* ) ),
00148 SLOT( currentChanged( QListViewItem* ) ) );
00149
00150 QTimer::singleShot( 0, this, SLOT( updateView() ) );
00151 }
00152
00153 ResourceSelection::~ResourceSelection()
00154 {
00155 }
00156
00157 QString ResourceSelection::title() const
00158 {
00159 return i18n( "Address Books" );
00160 }
00161
00162 QString ResourceSelection::identifier() const
00163 {
00164 return "resourceselection";
00165 }
00166
00167 void ResourceSelection::add()
00168 {
00169 QStringList types = mManager->resourceTypeNames();
00170 QStringList descs = mManager->resourceTypeDescriptions();
00171
00172 bool ok = false;
00173
00174 ResourceItem *i = selectedItem();
00175 if ( i ) {
00176 KPIM::ResourceABC *res = dynamic_cast<KPIM::ResourceABC *>( i->resource() );
00177 if ( i->isSubResource() || ( res && res->canHaveSubresources() ) ) {
00178 const QString folderName = KInputDialog::getText( i18n( "Add Subresource" ),
00179 i18n( "Please enter a name for the new subresource" ), QString::null,
00180 &ok, this );
00181 if ( !ok )
00182 return;
00183 const QString parentId = i->isSubResource() ? i->resourceIdentifier() : QString:: null;
00184 if ( !res->addSubresource( folderName, parentId ) ) {
00185 KMessageBox::error( this, i18n("<qt>Unable to create subresource <b>%1</b>.</qt>")
00186 .arg( folderName ) );
00187 }
00188 return;
00189 }
00190 }
00191
00192 QString desc = KInputDialog::getItem( i18n( "Add Address Book" ),
00193 i18n( "Please select type of the new address book:" ),
00194 descs, 0, false, &ok, this );
00195 if ( !ok )
00196 return;
00197
00198 QString type = types[ descs.findIndex( desc ) ];
00199
00200
00201 KABC::Resource *resource = mManager->createResource( type );
00202 if( !resource ) {
00203 KMessageBox::error( this, i18n("<qt>Unable to create an address book of type <b>%1</b>.</qt>")
00204 .arg( type ) );
00205 return;
00206 }
00207
00208 resource->setResourceName( i18n( "%1 address book" ).arg( type ) );
00209
00210 KRES::ConfigDialog dlg( this, QString( "contact" ), resource );
00211
00212 if ( dlg.exec() ) {
00213 core()->addressBook()->addResource( resource );
00214 resource->asyncLoad();
00215
00216 mLastResource = resource->identifier();
00217 updateView();
00218 } else {
00219 delete resource;
00220 resource = 0;
00221 }
00222 }
00223
00224 void ResourceSelection::edit()
00225 {
00226 ResourceItem *item = selectedItem();
00227 if ( !item )
00228 return;
00229
00230 KRES::ConfigDialog dlg( this, QString( "contact" ), item->resource() );
00231
00232 if ( dlg.exec() ) {
00233 mManager->change( item->resource() );
00234 item->resource()->asyncLoad();
00235
00236 mLastResource = item->resource()->identifier();
00237 updateView();
00238 }
00239 }
00240
00241 void ResourceSelection::remove()
00242 {
00243 ResourceItem *item = selectedItem();
00244 if ( !item )
00245 return;
00246
00247 const QString msg = item->isSubResource() ?
00248 i18n("<qt>Do you really want to remove the subresource <b>%1</b>? "
00249 "It will be completely removed, along with its contents. This "
00250 "operation can not be undone.</qt>").arg( item->text() )
00251 : i18n("<qt>Do you really want to remove the address book <b>%1</b>?</qt>")
00252 .arg( item->resource()->resourceName() );
00253 int result = KMessageBox::warningContinueCancel( this, msg, "",
00254 KGuiItem( i18n( "&Remove" ), "editdelete" ) );
00255 if ( result == KMessageBox::Cancel )
00256 return;
00257
00258 if ( item->isSubResource() ) {
00259 KPIM::ResourceABC *res = dynamic_cast<KPIM::ResourceABC *>( item->resource() );
00260 if ( !res->removeSubresource( item->resourceIdentifier() ) ) {
00261 KMessageBox::sorry( this,
00262 i18n ("<qt>Failed to remove the subresource <b>%1</b>. The "
00263 "reason could be that it is a built-in one which cannot "
00264 "be removed, or that the removal of the underlying storage "
00265 "folder failed.</qt>").arg( item->text() ) );
00266
00267 return;
00268 }
00269 } else {
00270 mLastResource = item->resource()->identifier();
00271 core()->addressBook()->removeResource( item->resource() );
00272 }
00273 core()->addressBook()->emitAddressBookChanged();
00274
00275 updateView();
00276 }
00277
00278 void ResourceSelection::currentChanged( QListViewItem *item )
00279 {
00280 ResourceItem *resItem = static_cast<ResourceItem*>( item );
00281 bool state = (resItem && !resItem->isSubResource() );
00282 mEditButton->setEnabled( state );
00283
00284 if ( !resItem )
00285 return;
00286
00287
00288 KABC::Resource *resource = resItem->resource();
00289
00290 if ( resItem->checked() != resItem->isOn() ) {
00291 resItem->setChecked( resItem->isOn() );
00292 kdDebug() << "checked=" << resItem->checked() << " isSubResource=" << resItem->isSubResource() << endl;
00293 if ( resItem->isSubResource() ) {
00294 KPIM::ResourceABC *res = dynamic_cast<KPIM::ResourceABC *>( resource );
00295 res->setSubresourceActive( resItem->resourceIdentifier(), resItem->isOn() );
00296 mManager->change( resource );
00297 } else {
00298 resource->setActive( resItem->isOn() );
00299 mManager->change( resource );
00300
00301 if ( resItem->checked() ) {
00302 if ( !resource->addressBook() )
00303 resource->setAddressBook( core()->addressBook() );
00304
00305 if ( !resource->isOpen() )
00306 resource->open();
00307
00308 resource->asyncLoad();
00309 } else {
00310 resource->close();
00311 }
00312 }
00313
00314 mLastResource = resource->identifier();
00315 core()->addressBook()->emitAddressBookChanged();
00316
00317 }
00318 }
00319
00320 void ResourceSelection::updateView()
00321 {
00322 if ( !mManager )
00323 return;
00324
00325 mListView->clear();
00326
00327 KRES::Manager<KABC::Resource>::Iterator it;
00328 for ( it = mManager->begin(); it != mManager->end(); ++it ) {
00329
00330 new ResourceItem( mListView, *it );
00331 KPIM::ResourceABC* resource = dynamic_cast<KPIM::ResourceABC *>( *it );
00332 if ( resource ) {
00333 disconnect( resource, 0, this, 0 );
00334 connect( resource, SIGNAL( signalSubresourceAdded( KPIM::ResourceABC *,
00335 const QString &, const QString & ) ),
00336 SLOT( slotSubresourceAdded( KPIM::ResourceABC *,
00337 const QString &, const QString & ) ) );
00338
00339 connect( resource, SIGNAL( signalSubresourceRemoved( KPIM::ResourceABC *,
00340 const QString &, const QString & ) ),
00341 SLOT( slotSubresourceRemoved( KPIM::ResourceABC *,
00342 const QString &, const QString & ) ) );
00343
00344
00345 }
00346 }
00347
00348 QListViewItemIterator itemIt( mListView );
00349 while ( itemIt.current() ) {
00350 ResourceItem *item = static_cast<ResourceItem*>( itemIt.current() );
00351 if ( item->resource()->identifier() == mLastResource ) {
00352 mListView->setSelected( item, true );
00353 mListView->ensureItemVisible( item );
00354 break;
00355 }
00356 ++itemIt;
00357 }
00358
00359 core()->addressBook()->emitAddressBookChanged();
00360 }
00361
00362
00363
00364 void ResourceSelection::slotSubresourceAdded( KPIM::ResourceABC *resource,
00365 const QString& type,
00366 const QString& subResource )
00367 {
00368 if ( type != "Contact" )
00369 return;
00370 QListViewItem *i = mListView->findItem( resource->resourceName(), 0 );
00371 if ( !i )
00372
00373 return;
00374
00375 ResourceItem *item = static_cast<ResourceItem *>( i );
00376 (void)new ResourceItem( resource, item, subResource );
00377
00378 core()->addressBook()->emitAddressBookChanged();
00379 }
00380
00381 ResourceItem *ResourceSelection::findItemByIdentifier( const QString& id )
00382 {
00383 QListViewItem *item;
00384 ResourceItem *i = 0;
00385 for( item = mListView->firstChild(); item; item = item->itemBelow() ) {
00386 i = static_cast<ResourceItem *>( item );
00387 if ( i->resourceIdentifier() == id )
00388 return i;
00389 }
00390 return 0;
00391 }
00392
00393
00394 void ResourceSelection::slotSubresourceRemoved( KPIM::ResourceABC* ,
00395 const QString& type,
00396 const QString& subResource )
00397 {
00398 if ( type != "Contact" )
00399 return;
00400 delete findItemByIdentifier( subResource );
00401 core()->addressBook()->emitAddressBookChanged();
00402 }
00403
00404 ResourceItem* ResourceSelection::selectedItem() const
00405 {
00406 return static_cast<ResourceItem*>( mListView->selectedItem() );
00407 }
00408
00409 void ResourceSelection::initGUI()
00410 {
00411 QGridLayout *layout = new QGridLayout( this, 2, 3, KDialog::marginHint(),
00412 KDialog::spacingHint() );
00413
00414 mListView = new KListView( this );
00415 mListView->addColumn( i18n( "Address Books" ) );
00416 mListView->setFullWidth( true );
00417 layout->addMultiCellWidget( mListView, 0, 0, 0, 2 );
00418
00419 mAddButton = new QPushButton( i18n( "Add..." ), this );
00420 mEditButton = new QPushButton( i18n( "Edit..." ), this );
00421 mEditButton->setEnabled( false );
00422 mRemoveButton = new QPushButton( i18n( "Remove" ), this );
00423
00424 layout->addWidget( mAddButton, 1, 0 );
00425 layout->addWidget( mEditButton, 1, 1 );
00426 layout->addWidget( mRemoveButton, 1, 2 );
00427 }
00428
00429 class ResourceSelectionFactory : public KAB::ExtensionFactory
00430 {
00431 public:
00432 KAB::ExtensionWidget *extension( KAB::Core *core, QWidget *parent, const char *name )
00433 {
00434 return new ResourceSelection( core, parent, name );
00435 }
00436
00437 QString identifier() const
00438 {
00439 return "resourceselection";
00440 }
00441 };
00442
00443 extern "C" {
00444 void *init_libkaddrbk_resourceselection()
00445 {
00446 return ( new ResourceSelectionFactory );
00447 }
00448 }
00449
00450 #include "resourceselection.moc"