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 ? i18n( "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 ? i18n( "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
00148 QGroupBox *groupBox = new QGroupBox( i18n( "Resources" ), this );
00149 QGridLayout *groupBoxLayout = new QGridLayout();
00150 groupBox->setLayout( groupBoxLayout );
00151 groupBoxLayout->setSpacing( 6 );
00152 groupBoxLayout->setMargin( 11 );
00153
00154 d->mFamilyCombo = new KComboBox( false, groupBox );
00155 groupBoxLayout->addWidget( d->mFamilyCombo, 0, 0, 1, 2 );
00156
00157 d->mCurrentManager = 0;
00158 d->mCurrentConfig = 0;
00159 d->mListView = new QTreeWidget( groupBox );
00160 d->mListView->setColumnCount( 3 );
00161 QStringList headerLabels;
00162 headerLabels << i18n( "Name" ) << i18n( "Type" ) << i18n( "Standard" );
00163 d->mListView->setHeaderItem( new QTreeWidgetItem( headerLabels ) );
00164
00165 groupBoxLayout->addWidget( d->mListView, 1, 0 );
00166 connect( d->mListView, SIGNAL( itemDoubleClicked( QTreeWidgetItem *, int ) ),
00167 this, SLOT( slotEdit() ) );
00168
00169 KDialogButtonBox *buttonBox = new KDialogButtonBox( groupBox, Qt::Vertical );
00170 d->mAddButton = buttonBox->addButton( i18n( "&Add..." ),
00171 KDialogButtonBox::ActionRole,
00172 this, SLOT(slotAdd()) );
00173
00174 d->mRemoveButton = buttonBox->addButton( i18n( "&Remove" ),
00175 KDialogButtonBox::ActionRole,
00176 this, SLOT(slotRemove()) );
00177 d->mRemoveButton->setEnabled( false );
00178
00179 d->mEditButton = buttonBox->addButton( i18n( "&Edit..." ),
00180 KDialogButtonBox::ActionRole,
00181 this, SLOT(slotEdit()) );
00182 d->mEditButton->setEnabled( false );
00183
00184 d->mStandardButton = buttonBox->addButton( i18n( "&Use as Standard" ),
00185 KDialogButtonBox::ActionRole,
00186 this, SLOT(slotStandard()) );
00187 d->mStandardButton->setEnabled( false );
00188
00189 buttonBox->layout();
00190 groupBoxLayout->addWidget( buttonBox, 1, 1 );
00191
00192 mainLayout->addWidget( groupBox );
00193
00194 connect( d->mFamilyCombo, SIGNAL( activated( int ) ),
00195 SLOT( slotFamilyChanged( int ) ) );
00196 connect( d->mListView, SIGNAL( itemSelectionChanged() ),
00197 SLOT( slotSelectionChanged() ) );
00198 connect( d->mListView, SIGNAL( itemClicked( QTreeWidgetItem *, int ) ),
00199 SLOT( slotItemClicked( QTreeWidgetItem * ) ) );
00200
00201 d->mLastItem = 0;
00202
00203 d->mConfigGroup = new KConfigGroup( new KConfig( "kcmkresourcesrc" ), "General" );
00204
00205 load();
00206 }
00207
00208 ConfigPage::~ConfigPage()
00209 {
00210 QList<KSharedPtr<ResourcePageInfo> >::Iterator it;
00211 for ( it = d->mInfoMap.begin(); it != d->mInfoMap.end(); ++it ) {
00212 (*it)->mManager->removeObserver( this );
00213 }
00214
00215 d->mConfigGroup->writeEntry( "CurrentFamily", d->mFamilyCombo->currentIndex() );
00216 delete d->mConfigGroup->config();
00217 delete d->mConfigGroup;
00218 d->mConfigGroup = 0;
00219 delete d;
00220 }
00221
00222 void ConfigPage::load()
00223 {
00224 kDebug(5650) << "ConfigPage::load()";
00225
00226 d->mListView->clear();
00227 d->mFamilyMap.clear();
00228 d->mInfoMap.clear();
00229 QStringList familyDisplayNames;
00230
00231
00232 QStringList compatFamilyNames;
00233 const KService::List plugins = KServiceTypeTrader::self()->query( "KResources/Plugin" );
00234 KService::List::ConstIterator it = plugins.begin();
00235 KService::List::ConstIterator end = plugins.end();
00236 for ( ; it != end; ++it ) {
00237 const QString family = (*it)->property( "X-KDE-ResourceFamily" ).toString();
00238 if ( compatFamilyNames.indexOf( family ) == -1 ) {
00239 compatFamilyNames.append( family );
00240 }
00241 }
00242
00243 const KService::List managers = KServiceTypeTrader::self()->query( "KResources/Manager" );
00244 KService::List::ConstIterator m_it;
00245 for ( m_it = managers.begin(); m_it != managers.end(); ++m_it ) {
00246 QString displayName = (*m_it)->property( "Name" ).toString();
00247 familyDisplayNames.append( displayName );
00248 QString family = (*m_it)->property( "X-KDE-ResourceFamily" ).toString();
00249 if ( !family.isEmpty() ) {
00250 compatFamilyNames.removeAll( family );
00251 d->mFamilyMap.append( family );
00252 d->loadManager( family, this );
00253 }
00254 }
00255
00256
00257 QStringList::ConstIterator cfit = compatFamilyNames.begin();
00258 for ( ; cfit != compatFamilyNames.end(); ++cfit ) {
00259 d->mFamilyMap.append( *cfit );
00260 familyDisplayNames.append( *cfit );
00261 d->loadManager( *cfit, this );
00262 }
00263
00264 d->mCurrentManager = 0;
00265
00266 d->mFamilyCombo->clear();
00267 d->mFamilyCombo->insertItems( 0, familyDisplayNames );
00268
00269 int currentFamily = d->mConfigGroup->readEntry( "CurrentFamily", 0 );
00270 d->mFamilyCombo->setCurrentIndex( currentFamily );
00271 slotFamilyChanged( currentFamily );
00272 emit changed( false );
00273 }
00274
00275 void ConfigPage::Private::loadManager( const QString &family, ConfigPage *page )
00276 {
00277 mCurrentManager = new Manager<Resource>( family );
00278 if ( mCurrentManager ) {
00279 mCurrentManager->addObserver( page );
00280
00281 ResourcePageInfo *info = new ResourcePageInfo;
00282 info->mManager = mCurrentManager;
00283 info->mConfig = new KConfig( KRES::ManagerImpl::defaultConfigFile( family ) );
00284 info->mManager->readConfig( info->mConfig );
00285
00286 mInfoMap.append( KSharedPtr<ResourcePageInfo>( info ) );
00287 }
00288 }
00289
00290 void ConfigPage::save()
00291 {
00292 d->saveResourceSettings( this );
00293
00294 QList<KSharedPtr<ResourcePageInfo> >::Iterator it;
00295 for ( it = d->mInfoMap.begin(); it != d->mInfoMap.end(); ++it ) {
00296 (*it)->mManager->writeConfig( (*it)->mConfig );
00297 }
00298
00299 emit changed( false );
00300 }
00301
00302 void ConfigPage::defaults()
00303 {
00304 }
00305
00306 void ConfigPage::slotFamilyChanged( int pos )
00307 {
00308 if ( pos < 0 || pos >= (int)d->mFamilyMap.count() ) {
00309 return;
00310 }
00311
00312 d->saveResourceSettings( this );
00313
00314 d->mFamily = d->mFamilyMap[ pos ];
00315
00316 d->mCurrentManager = d->mInfoMap[ pos ]->mManager;
00317 d->mCurrentConfig = d->mInfoMap[ pos ]->mConfig;
00318
00319 if ( !d->mCurrentManager ) {
00320 kDebug(5650) << "ERROR: cannot create ResourceManager<Resource>( mFamily )";
00321 }
00322
00323 d->mListView->clear();
00324
00325 if ( d->mCurrentManager->isEmpty() ) {
00326 defaults();
00327 }
00328
00329 Resource *standardResource = d->mCurrentManager->standardResource();
00330
00331 Manager<Resource>::Iterator it;
00332 for ( it = d->mCurrentManager->begin(); it != d->mCurrentManager->end(); ++it ) {
00333 ConfigViewItem *item = new ConfigViewItem( d->mListView, *it );
00334 if ( *it == standardResource ) {
00335 item->setStandard( true );
00336 }
00337 }
00338
00339 if ( d->mListView->topLevelItemCount() == 0 ) {
00340 defaults();
00341 emit changed( true );
00342 d->mCurrentManager->writeConfig( d->mCurrentConfig );
00343 } else {
00344 if ( !standardResource ) {
00345 KMessageBox::sorry( this, i18n( "There is no standard resource. Please select one." ) );
00346 }
00347
00348 emit changed( false );
00349 }
00350 }
00351
00352 void ConfigPage::slotAdd()
00353 {
00354 if ( !d->mCurrentManager ) {
00355 return;
00356 }
00357
00358 QStringList types = d->mCurrentManager->resourceTypeNames();
00359 QStringList descs = d->mCurrentManager->resourceTypeDescriptions();
00360 bool ok = false;
00361 QString desc = KInputDialog::getItem( i18n( "Resource Configuration" ),
00362 i18n( "Please select type of the new resource:" ), descs,
00363 0, false, &ok, this );
00364 if ( !ok ) {
00365 return;
00366 }
00367
00368 QString type = types[ descs.indexOf( desc ) ];
00369
00370
00371 Resource *resource = d->mCurrentManager->createResource( type );
00372 if ( !resource ) {
00373 KMessageBox::error(
00374 this, i18n( "Unable to create resource of type '%1'.", type ) );
00375 return;
00376 }
00377
00378 resource->setResourceName( type + "-resource" );
00379
00380 ConfigDialog dlg( this, d->mFamily, resource );
00381
00382 if ( dlg.exec() ) {
00383 d->mCurrentManager->add( resource );
00384
00385 ConfigViewItem *item = new ConfigViewItem( d->mListView, resource );
00386
00387 d->mLastItem = item;
00388
00389
00390
00391 if ( !resource->readOnly() ) {
00392 bool onlyReadOnly = true;
00393 for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
00394 ConfigViewItem *confIt = static_cast<ConfigViewItem*>( d->mListView->topLevelItem( i ) );
00395 if ( !confIt->readOnly() && confIt != item ) {
00396 onlyReadOnly = false;
00397 }
00398 }
00399
00400 if ( onlyReadOnly ) {
00401 item->setStandard( true );
00402 }
00403 }
00404
00405 emit changed( true );
00406 } else {
00407 delete resource;
00408 resource = 0;
00409 }
00410 }
00411
00412 void ConfigPage::slotRemove()
00413 {
00414 if ( !d->mCurrentManager ) {
00415 return;
00416 }
00417
00418 QTreeWidgetItem *item = d->mListView->currentItem();
00419 ConfigViewItem *confItem = static_cast<ConfigViewItem*>( item );
00420
00421 if ( !confItem ) {
00422 return;
00423 }
00424
00425 if ( confItem->standard() ) {
00426 KMessageBox::sorry( this,
00427 i18n( "You cannot remove your standard resource. "
00428 "Please select a new standard resource first." ) );
00429 return;
00430 }
00431
00432 d->mCurrentManager->remove( confItem->resource() );
00433
00434 if ( item == d->mLastItem ) {
00435 d->mLastItem = 0;
00436 }
00437
00438 d->mListView->takeTopLevelItem( d->mListView->indexOfTopLevelItem( item ) );
00439 delete item;
00440
00441 emit changed( true );
00442 }
00443
00444 void ConfigPage::slotEdit()
00445 {
00446 if ( !d->mCurrentManager ) {
00447 return;
00448 }
00449
00450 QTreeWidgetItem *item = d->mListView->currentItem();
00451 ConfigViewItem *configItem = static_cast<ConfigViewItem*>( item );
00452 if ( !configItem ) {
00453 return;
00454 }
00455
00456 Resource *resource = configItem->resource();
00457
00458 ConfigDialog dlg( this, d->mFamily, resource );
00459
00460 if ( dlg.exec() ) {
00461 configItem->setText( 0, resource->resourceName() );
00462 configItem->setText( 1, resource->type() );
00463
00464 if ( configItem->standard() && configItem->readOnly() ) {
00465 KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard." ) );
00466 configItem->setStandard( false );
00467 }
00468
00469 d->mCurrentManager->change( resource );
00470 emit changed( true );
00471 }
00472 }
00473
00474 void ConfigPage::slotStandard()
00475 {
00476 if ( !d->mCurrentManager ) {
00477 return;
00478 }
00479
00480 ConfigViewItem *item = static_cast<ConfigViewItem*>( d->mListView->currentItem() );
00481 if ( !item ) {
00482 return;
00483 }
00484
00485 if ( item->readOnly() ) {
00486 KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard." ) );
00487 return;
00488 }
00489
00490 if ( !item->isOn() ) {
00491 KMessageBox::sorry( this, i18n( "You cannot use an inactive resource as standard." ) );
00492 return;
00493 }
00494
00495 for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
00496 ConfigViewItem *configItem = static_cast<ConfigViewItem*>( d->mListView->topLevelItem( i ) );
00497 if ( configItem->standard() ) {
00498 configItem->setStandard( false );
00499 }
00500 }
00501
00502 item->setStandard( true );
00503 d->mCurrentManager->setStandardResource( item->resource() );
00504
00505 emit changed( true );
00506 }
00507
00508 void ConfigPage::slotSelectionChanged()
00509 {
00510 bool state = ( d->mListView->currentItem() != 0 );
00511
00512 d->mRemoveButton->setEnabled( state );
00513 d->mEditButton->setEnabled( state );
00514 d->mStandardButton->setEnabled( state );
00515 }
00516
00517 void ConfigPage::resourceAdded( Resource *resource )
00518 {
00519 kDebug(5650) << "ConfigPage::resourceAdded(" << resource->resourceName() << ")";
00520
00521 ConfigViewItem *item = new ConfigViewItem( d->mListView, resource );
00522
00523 item->setCheckState( 0, resource->isActive()? Qt::Checked : Qt::Unchecked );
00524
00525 d->mLastItem = item;
00526
00527 emit changed( true );
00528 }
00529
00530 void ConfigPage::resourceModified( Resource *resource )
00531 {
00532 kDebug(5650) << "ConfigPage::resourceModified(" << resource->resourceName() << ")";
00533 ConfigViewItem *item = findItem( resource );
00534 if ( !item ) {
00535 return;
00536 }
00537
00538
00539
00540 item->updateItem();
00541 }
00542
00543 void ConfigPage::resourceDeleted( Resource *resource )
00544 {
00545 kDebug(5650) << "ConfigPage::resourceDeleted(" << resource->resourceName() << ")";
00546
00547 ConfigViewItem *item = findItem( resource );
00548 if ( !item ) {
00549 return;
00550 }
00551
00552 delete item;
00553 }
00554
00555 ConfigViewItem *ConfigPage::findItem( Resource *resource )
00556 {
00557 for ( int i = 0; i < d->mListView->topLevelItemCount(); ++i ) {
00558 ConfigViewItem *item = static_cast<ConfigViewItem *>( d->mListView->topLevelItem( i ) );
00559 if ( item->resource() == resource ) {
00560 return item;
00561 }
00562 }
00563 return 0;
00564 }
00565
00566 void ConfigPage::slotItemClicked( QTreeWidgetItem *item )
00567 {
00568 ConfigViewItem *configItem = static_cast<ConfigViewItem *>( item );
00569 if ( !configItem ) {
00570 return;
00571 }
00572
00573 if ( configItem->standard() && !configItem->isOn() ) {
00574 KMessageBox::sorry( this,
00575 i18n( "You cannot deactivate the standard resource. "
00576 "Choose another standard resource first." ) );
00577 configItem->setCheckState( 0, Qt::Checked );
00578 return;
00579 }
00580
00581 if ( configItem->isOn() != configItem->resource()->isActive() ) {
00582 emit changed( true );
00583 }
00584 }
00585
00586 void ConfigPage::Private::saveResourceSettings( ConfigPage *page )
00587 {
00588 if ( mCurrentManager ) {
00589 for ( int i = 0; i < mListView->topLevelItemCount(); ++i ) {
00590 ConfigViewItem *configItem = static_cast<ConfigViewItem *>( mListView->topLevelItem( i ) );
00591
00592 if ( configItem->standard() && !configItem->readOnly() &&
00593 configItem->isOn() ) {
00594 mCurrentManager->setStandardResource( configItem->resource() );
00595 }
00596
00597
00598 configItem->resource()->setActive( configItem->isOn() );
00599 }
00600 mCurrentManager->writeConfig( mCurrentConfig );
00601
00602 if ( !mCurrentManager->standardResource() ) {
00603 KMessageBox::sorry( page,
00604 i18n( "There is no valid standard resource. "
00605 "Please select one which is neither read-only nor inactive." ) );
00606 }
00607 }
00608 }
00609
00610 }
00611
00612 #include "configpage.moc"
00613