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