00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00036 #include "configpage.h"
00037
00038 #include <QtGui/QGroupBox>
00039 #include <QtGui/QLabel>
00040 #include <QtGui/QLayout>
00041 #include <QtGui/QTreeWidget>
00042 #include <QtGui/QTreeWidgetItem>
00043
00044 #include <kcombobox.h>
00045 #include <kdebug.h>
00046 #include <klocale.h>
00047 #include <kmessagebox.h>
00048 #include <kconfig.h>
00049 #include <kstandarddirs.h>
00050 #include <kurlrequester.h>
00051 #include <kdialogbuttonbox.h>
00052 #include <kservicetypetrader.h>
00053 #include <kinputdialog.h>
00054 #include <QtCore/QList>
00055
00056 #include "resource.h"
00057 #include "configdialog.h"
00058
00059 namespace KRES {
00060
00061 class ResourcePageInfo::Private
00062 {
00063 };
00064
00065 ResourcePageInfo::ResourcePageInfo() : d( new KRES::ResourcePageInfo::Private )
00066 {
00067 mManager = 0;
00068 mConfig = 0;
00069 }
00070
00071 ResourcePageInfo::~ResourcePageInfo()
00072 {
00073
00074 mManager = 0;
00075
00076 mConfig = 0;
00077 delete d;
00078 }
00079
00080 class ConfigViewItem : public QTreeWidgetItem
00081 {
00082 public:
00083 ConfigViewItem( QTreeWidget *parent, Resource *resource ) :
00084 QTreeWidgetItem( parent ), mResource( resource ), mIsStandard( false )
00085 {
00086 updateItem();
00087 }
00088
00089 void setStandard( bool value )
00090 {
00091 setText( 2, ( value ? i18nc( "yes, a standard resource", "Yes" ) : QString() ) );
00092 mIsStandard = value;
00093 }
00094
00095 bool standard() const { return mIsStandard; }
00096 bool readOnly() const { return mResource->readOnly(); }
00097
00098 Resource *resource() { return mResource; }
00099
00100 void updateItem()
00101 {
00102 setCheckState( 0, mResource->isActive() ? Qt::Checked : Qt::Unchecked );
00103 setText( 0, mResource->resourceName() );
00104 setText( 1, mResource->type() );
00105 setText( 2, mIsStandard ? i18nc( "yes, a standard resource", "Yes" ) : QString() );
00106 }
00107
00108 bool isOn()
00109 {
00110 return checkState( 0 ) == Qt::Checked;
00111 }
00112
00113 private:
00114 Resource *mResource;
00115 bool mIsStandard;
00116 };
00117
00118 class ConfigPage::Private
00119 {
00120 public:
00121 void loadManager( const QString &family, ConfigPage *page );
00122 void saveResourceSettings( ConfigPage *page );
00123
00124 Manager<Resource> *mCurrentManager;
00125 KConfig *mCurrentConfig;
00126 KConfigGroup *mConfigGroup;
00127 QString mFamily;
00128 QStringList mFamilyMap;
00129 QList<KSharedPtr<ResourcePageInfo> > mInfoMap;
00130
00131 KComboBox *mFamilyCombo;
00132 QTreeWidget *mListView;
00133 QPushButton *mAddButton;
00134 QPushButton *mRemoveButton;
00135 QPushButton *mEditButton;
00136 QPushButton *mStandardButton;
00137
00138 QTreeWidgetItem *mLastItem;
00139 };
00140
00141 ConfigPage::ConfigPage( QWidget *parent )
00142 : QWidget( parent ), d( new KRES::ConfigPage::Private )
00143 {
00144 setWindowTitle( i18n( "Resource Configuration" ) );
00145
00146 QVBoxLayout *mainLayout = new QVBoxLayout( this );
00147 mainLayout->setMargin( 0 );
00148
00149 QGroupBox *groupBox = new QGroupBox( i18n( "Resources" ), this );
00150 QGridLayout *groupBoxLayout = new QGridLayout();
00151 groupBox->setLayout( groupBoxLayout );
00152
00153 d->mFamilyCombo = new KComboBox( false, groupBox );
00154 groupBoxLayout->addWidget( d->mFamilyCombo, 0, 0, 1, 2 );
00155
00156 d->mCurrentManager = 0;
00157 d->mCurrentConfig = 0;
00158 d->mListView = new QTreeWidget( groupBox );
00159 d->mListView->setColumnCount( 3 );
00160 QStringList headerLabels;
00161 headerLabels << i18nc( "@title:column resource name", "Name" )
00162 << i18nc( "@title:column resource type", "Type" )
00163 << i18nc( "@title:column a standard resource?", "Standard" );
00164 d->mListView->setHeaderItem( new QTreeWidgetItem( headerLabels ) );
00165
00166 groupBoxLayout->addWidget( d->mListView, 1, 0 );
00167 connect( d->mListView, SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ),
00168 this, SLOT( slotEdit() ) );
00169
00170 KDialogButtonBox *buttonBox = new KDialogButtonBox( groupBox, Qt::Vertical );
00171 d->mAddButton = buttonBox->addButton( i18n( "&Add..." ),
00172 KDialogButtonBox::ActionRole,
00173 this, SLOT(slotAdd()) );
00174
00175 d->mRemoveButton = buttonBox->addButton( i18n( "&Remove" ),
00176 KDialogButtonBox::ActionRole,
00177 this, SLOT(slotRemove()) );
00178 d->mRemoveButton->setEnabled( false );
00179
00180 d->mEditButton = buttonBox->addButton( i18n( "&Edit..." ),
00181 KDialogButtonBox::ActionRole,
00182 this, SLOT(slotEdit()) );
00183 d->mEditButton->setEnabled( false );
00184
00185 d->mStandardButton = buttonBox->addButton( i18n( "&Use as Standard" ),
00186 KDialogButtonBox::ActionRole,
00187 this, SLOT(slotStandard()) );
00188 d->mStandardButton->setEnabled( false );
00189
00190 buttonBox->layout();
00191 groupBoxLayout->addWidget( buttonBox, 1, 1 );
00192
00193 mainLayout->addWidget( groupBox );
00194
00195 connect( d->mFamilyCombo, SIGNAL( activated( int ) ),
00196 SLOT( slotFamilyChanged( int ) ) );
00197 connect( d->mListView, SIGNAL( itemSelectionChanged() ),
00198 SLOT( slotSelectionChanged() ) );
00199 connect( d->mListView, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ),
00200 SLOT( slotItemClicked( QTreeWidgetItem * ) ) );
00201
00202 d->mLastItem = 0;
00203
00204 d->mConfigGroup = new KConfigGroup( new KConfig( "kcmkresourcesrc" ), "General" );
00205
00206 load();
00207 }
00208
00209 ConfigPage::~ConfigPage()
00210 {
00211 QList<KSharedPtr<ResourcePageInfo> >::Iterator it;
00212 for ( it = d->mInfoMap.begin(); it != d->mInfoMap.end(); ++it ) {
00213 (*it)->mManager->removeObserver( this );
00214 }
00215
00216 d->mConfigGroup->writeEntry( "CurrentFamily", d->mFamilyCombo->currentIndex() );
00217 delete d->mConfigGroup->config();
00218 delete d->mConfigGroup;
00219 d->mConfigGroup = 0;
00220 delete d;
00221 }
00222
00223 void ConfigPage::load()
00224 {
00225 kDebug();
00226
00227 d->mListView->clear();
00228 d->mFamilyMap.clear();
00229 d->mInfoMap.clear();
00230 QStringList familyDisplayNames;
00231
00232
00233 QStringList compatFamilyNames;
00234 const KService::List plugins = KServiceTypeTrader::self()->query( "KResources/Plugin" );
00235 KService::List::ConstIterator it = plugins.begin();
00236 KService::List::ConstIterator end = plugins.end();
00237 for ( ; it != end; ++it ) {
00238 const QString family = (*it)->property( "X-KDE-ResourceFamily" ).toString();
00239 if ( compatFamilyNames.indexOf( family ) == -1 ) {
00240 compatFamilyNames.append( family );
00241 }
00242 }
00243
00244 const KService::List managers = KServiceTypeTrader::self()->query( "KResources/Manager" );
00245 KService::List::ConstIterator m_it;
00246 for ( m_it = managers.begin(); m_it != managers.end(); ++m_it ) {
00247 QString displayName = (*m_it)->property( "Name" ).toString();
00248 familyDisplayNames.append( displayName );
00249 QString family = (*m_it)->property( "X-KDE-ResourceFamily" ).toString();
00250 if ( !family.isEmpty() ) {
00251 compatFamilyNames.removeAll( family );
00252 d->mFamilyMap.append( family );
00253 kDebug() << "Loading manager for family " << family;
00254 d->loadManager( family, this );
00255 kDebug() << "Manager for family " << family << " loaded.";
00256 }
00257 }
00258
00259
00260 QStringList::ConstIterator cfit = compatFamilyNames.constBegin();
00261 for ( ; cfit != compatFamilyNames.constEnd(); ++cfit ) {
00262 d->mFamilyMap.append( *cfit );
00263 familyDisplayNames.append( *cfit );
00264 d->loadManager( *cfit, this );
00265 }
00266
00267 d->mCurrentManager = 0;
00268
00269 d->mFamilyCombo->clear();
00270 d->mFamilyCombo->insertItems( 0, familyDisplayNames );
00271
00272 int currentFamily = d->mConfigGroup->readEntry( "CurrentFamily", 0 );
00273 d->mFamilyCombo->setCurrentIndex( currentFamily );
00274 slotFamilyChanged( currentFamily );
00275 emit changed( false );
00276 }
00277
00278 void ConfigPage::Private::loadManager( const QString &family, ConfigPage *page )
00279 {
00280 mCurrentManager = new Manager<Resource>( family );
00281 if ( mCurrentManager ) {
00282 mCurrentManager->addObserver( page );
00283
00284 ResourcePageInfo *info = new ResourcePageInfo;
00285 info->mManager = mCurrentManager;
00286 info->mConfig = new KConfig( KRES::ManagerImpl::defaultConfigFile( family ) );
00287 info->mManager->readConfig( info->mConfig );
00288
00289 mInfoMap.append( KSharedPtr<ResourcePageInfo>( info ) );
00290 }
00291 }
00292
00293 void ConfigPage::save()
00294 {
00295 d->saveResourceSettings( this );
00296
00297 QList<KSharedPtr<ResourcePageInfo> >::Iterator it;
00298 for ( it = d->mInfoMap.begin(); it != d->mInfoMap.end(); ++it ) {
00299 (*it)->mManager->writeConfig( (*it)->mConfig );
00300 }
00301
00302 emit changed( false );
00303 }
00304
00305 void ConfigPage::defaults()
00306 {
00307 }
00308
00309 void ConfigPage::slotFamilyChanged( int pos )
00310 {
00311 if ( pos < 0 || pos >= (int)d->mFamilyMap.count() ) {
00312 return;
00313 }
00314
00315 d->saveResourceSettings( this );
00316
00317 d->mFamily = d->mFamilyMap[ pos ];
00318
00319 d->mCurrentManager = d->mInfoMap[ pos ]->mManager;
00320 d->mCurrentConfig = d->mInfoMap[ pos ]->mConfig;
00321
00322 if ( !d->mCurrentManager ) {
00323 kDebug() << "ERROR: cannot create ResourceManager<Resource>( mFamily )";
00324 }
00325
00326 d->mListView->clear();
00327
00328 if ( d->mCurrentManager->isEmpty() ) {
00329 defaults();
00330 }
00331
00332 Resource *standardResource = d->mCurrentManager->standardResource();
00333
00334 Manager<Resource>::Iterator it;
00335 for ( it = d->mCurrentManager->begin(); it != d->mCurrentManager->end(); ++it ) {
00336 ConfigViewItem *item = new ConfigViewItem( d->mListView, *it );
00337 if ( *it == standardResource ) {
00338 item->setStandard( true );
00339 }
00340 }
00341
00342 if ( d->mListView->topLevelItemCount() == 0 ) {
00343 defaults();
00344 emit changed( true );
00345 d->mCurrentManager->writeConfig( d->mCurrentConfig );
00346 } else {
00347 if ( !standardResource ) {
00348 KMessageBox::sorry( this, i18n( "There is no standard resource. Please select one." ) );
00349 }
00350
00351 emit changed( false );
00352 }
00353 }
00354
00355 void ConfigPage::slotAdd()
00356 {
00357 if ( !d->mCurrentManager ) {
00358 return;
00359 }
00360
00361 QStringList types = d->mCurrentManager->resourceTypeNames();
00362 QStringList descs = d->mCurrentManager->resourceTypeDescriptions();
00363 bool ok = false;
00364 QString desc = KInputDialog::getItem( i18n( "Resource Configuration" ),
00365 i18n( "Please select type of the new resource:" ), descs,
00366 0, false, &ok, this );
00367 if ( !ok ) {
00368 return;
00369 }
00370
00371 QString type = types[ descs.indexOf( desc ) ];
00372
00373
00374 Resource *resource = d->mCurrentManager->createResource( type );
00375 if ( !resource ) {
00376 KMessageBox::error(
00377 this, i18n( "Unable to create resource of type '%1'.", type ) );
00378 return;
00379 }
00380
00381 resource->setResourceName( type + "-resource" );
00382
00383 ConfigDialog dlg( this, d->mFamily, resource );
00384
00385 if ( dlg.exec() ) {
00386 d->mCurrentManager->add( resource );
00387
00388 ConfigViewItem *item = new ConfigViewItem( d->mListView, resource );
00389
00390 d->mLastItem = item;
00391
00392
00393
00394 if ( !resource->readOnly() ) {
00395 bool onlyReadOnly = true;
00396 for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
00397 ConfigViewItem *confIt = static_cast<ConfigViewItem*>( d->mListView->topLevelItem( i ) );
00398 if ( !confIt->readOnly() && confIt != item ) {
00399 onlyReadOnly = false;
00400 }
00401 }
00402
00403 if ( onlyReadOnly ) {
00404 item->setStandard( true );
00405 }
00406 }
00407
00408 emit changed( true );
00409 } else {
00410 delete resource;
00411 resource = 0;
00412 }
00413 }
00414
00415 void ConfigPage::slotRemove()
00416 {
00417 if ( !d->mCurrentManager ) {
00418 return;
00419 }
00420
00421 QTreeWidgetItem *item = d->mListView->currentItem();
00422 ConfigViewItem *confItem = static_cast<ConfigViewItem*>( item );
00423
00424 if ( !confItem ) {
00425 return;
00426 }
00427
00428 if ( confItem->standard() ) {
00429 KMessageBox::sorry( this,
00430 i18n( "You cannot remove your standard resource. "
00431 "Please select a new standard resource first." ) );
00432 return;
00433 }
00434
00435 d->mCurrentManager->remove( confItem->resource() );
00436
00437 if ( item == d->mLastItem ) {
00438 d->mLastItem = 0;
00439 }
00440
00441 d->mListView->takeTopLevelItem( d->mListView->indexOfTopLevelItem( item ) );
00442 delete item;
00443
00444 emit changed( true );
00445 }
00446
00447 void ConfigPage::slotEdit()
00448 {
00449 if ( !d->mCurrentManager ) {
00450 return;
00451 }
00452
00453 QTreeWidgetItem *item = d->mListView->currentItem();
00454 ConfigViewItem *configItem = static_cast<ConfigViewItem*>( item );
00455 if ( !configItem ) {
00456 return;
00457 }
00458
00459 Resource *resource = configItem->resource();
00460
00461 ConfigDialog dlg( this, d->mFamily, resource );
00462
00463 if ( dlg.exec() ) {
00464 configItem->setText( 0, resource->resourceName() );
00465 configItem->setText( 1, resource->type() );
00466
00467 if ( configItem->standard() && configItem->readOnly() ) {
00468 KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard." ) );
00469 configItem->setStandard( false );
00470 }
00471
00472 d->mCurrentManager->change( resource );
00473 emit changed( true );
00474 }
00475 }
00476
00477 void ConfigPage::slotStandard()
00478 {
00479 if ( !d->mCurrentManager ) {
00480 return;
00481 }
00482
00483 ConfigViewItem *item = static_cast<ConfigViewItem*>( d->mListView->currentItem() );
00484 if ( !item ) {
00485 return;
00486 }
00487
00488 if ( item->readOnly() ) {
00489 KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard." ) );
00490 return;
00491 }
00492
00493 if ( !item->isOn() ) {
00494 KMessageBox::sorry( this, i18n( "You cannot use an inactive resource as standard." ) );
00495 return;
00496 }
00497
00498 for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
00499 ConfigViewItem *configItem = static_cast<ConfigViewItem*>( d->mListView->topLevelItem( i ) );
00500 if ( configItem->standard() ) {
00501 configItem->setStandard( false );
00502 }
00503 }
00504
00505 item->setStandard( true );
00506 d->mCurrentManager->setStandardResource( item->resource() );
00507
00508 emit changed( true );
00509 }
00510
00511 void ConfigPage::slotSelectionChanged()
00512 {
00513 bool state = ( d->mListView->currentItem() != 0 );
00514
00515 d->mRemoveButton->setEnabled( state );
00516 d->mEditButton->setEnabled( state );
00517 d->mStandardButton->setEnabled( state );
00518 }
00519
00520 void ConfigPage::resourceAdded( Resource *resource )
00521 {
00522 kDebug() << resource->resourceName();
00523
00524 ConfigViewItem *item = new ConfigViewItem( d->mListView, resource );
00525
00526 item->setCheckState( 0, resource->isActive()? Qt::Checked : Qt::Unchecked );
00527
00528 d->mLastItem = item;
00529
00530 emit changed( true );
00531 }
00532
00533 void ConfigPage::resourceModified( Resource *resource )
00534 {
00535 kDebug() << resource->resourceName();
00536 ConfigViewItem *item = findItem( resource );
00537 if ( !item ) {
00538 return;
00539 }
00540
00541
00542
00543 item->updateItem();
00544 }
00545
00546 void ConfigPage::resourceDeleted( Resource *resource )
00547 {
00548 kDebug() << resource->resourceName();
00549
00550 ConfigViewItem *item = findItem( resource );
00551 if ( !item ) {
00552 return;
00553 }
00554
00555 delete item;
00556 }
00557
00558 ConfigViewItem *ConfigPage::findItem( Resource *resource )
00559 {
00560 for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
00561 ConfigViewItem *item = static_cast<ConfigViewItem *>( d->mListView->topLevelItem( i ) );
00562 if ( item->resource() == resource ) {
00563 return item;
00564 }
00565 }
00566 return 0;
00567 }
00568
00569 void ConfigPage::slotItemClicked( QTreeWidgetItem *item )
00570 {
00571 ConfigViewItem *configItem = static_cast<ConfigViewItem *>( item );
00572 if ( !configItem ) {
00573 return;
00574 }
00575
00576 if ( configItem->standard() && !configItem->isOn() ) {
00577 KMessageBox::sorry( this,
00578 i18n( "You cannot deactivate the standard resource. "
00579 "Choose another standard resource first." ) );
00580 configItem->setCheckState( 0, Qt::Checked );
00581 return;
00582 }
00583
00584 if ( configItem->isOn() != configItem->resource()->isActive() ) {
00585 emit changed( true );
00586 }
00587 }
00588
00589 void ConfigPage::Private::saveResourceSettings( ConfigPage *page )
00590 {
00591 if ( mCurrentManager ) {
00592 for ( int i = 0; i < mListView->topLevelItemCount(); ++i ) {
00593 ConfigViewItem *configItem = static_cast<ConfigViewItem *>( mListView->topLevelItem( i ) );
00594
00595 if ( configItem->standard() && !configItem->readOnly() &&
00596 configItem->isOn() ) {
00597 mCurrentManager->setStandardResource( configItem->resource() );
00598 }
00599
00600
00601 configItem->resource()->setActive( configItem->isOn() );
00602 }
00603 mCurrentManager->writeConfig( mCurrentConfig );
00604
00605 if ( !mCurrentManager->standardResource() ) {
00606 KMessageBox::sorry( page,
00607 i18n( "There is no valid standard resource. "
00608 "Please select one which is neither read-only nor inactive." ) );
00609 }
00610 }
00611 }
00612
00613 }
00614
00615 #include "configpage.moc"
00616