configpage.cpp

00001 /*
00002     This file is part of libkresources.
00003 
00004     Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
00005     Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org>
00006     Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
00007 
00008     This library is free software; you can redistribute it and/or
00009     modify it under the terms of the GNU Library General Public
00010     License as published by the Free Software Foundation; either
00011     version 2 of the License, or (at your option) any later version.
00012 
00013     This library is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016     Library General Public License for more details.
00017 
00018     You should have received a copy of the GNU Library General Public License
00019     along with this library; see the file COPYING.LIB.  If not, write to
00020     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021     Boston, MA 02110-1301, USA.
00022 */
00023 
00024 #include <qgroupbox.h>
00025 #include <qlabel.h>
00026 #include <qlayout.h>
00027 
00028 #include <kapplication.h>
00029 #include <kcombobox.h>
00030 #include <kdebug.h>
00031 #include <klocale.h>
00032 #include <kmessagebox.h>
00033 #include <ksimpleconfig.h>
00034 #include <kstandarddirs.h>
00035 #include <kurlrequester.h>
00036 #include <klistview.h>
00037 #include <kbuttonbox.h>
00038 #include <ktrader.h>
00039 #include <kinputdialog.h>
00040 
00041 #include "resource.h"
00042 #include "configdialog.h"
00043 
00044 #include "configpage.h"
00045 
00046 namespace KRES {
00047 
00048 ResourcePageInfo::ResourcePageInfo() : KShared() {
00049   mManager = 0L;
00050   mConfig = 0L;
00051 }
00052 
00053 ResourcePageInfo::~ResourcePageInfo() {
00054   //delete mManager;
00055   mManager = 0L;
00056   //delete mConfig;
00057   mConfig = 0L;
00058 }
00059 
00060 
00061 class ConfigViewItem : public QCheckListItem
00062 {
00063   public:
00064     ConfigViewItem( QListView *parent, Resource* resource ) :
00065       QCheckListItem( parent, resource->resourceName(), CheckBox ),
00066       mResource( resource ),
00067       mIsStandard( false )
00068     {
00069       setText( 1, mResource->type() );
00070       setOn( mResource->isActive() );
00071     }
00072 
00073     void setStandard( bool value )
00074     {
00075       setText( 2, ( value ? i18n( "Yes" ) : QString::null ) );
00076       mIsStandard = value;
00077     }
00078 
00079     bool standard() const { return mIsStandard; }
00080     bool readOnly() const { return mResource->readOnly(); }
00081 
00082     Resource *resource() { return mResource; }
00083 
00084     void updateItem()
00085     {
00086       setOn( mResource->isActive() );
00087       setText( 0, mResource->resourceName() );
00088       setText( 1, mResource->type() );
00089       setText( 2, mIsStandard ? i18n( "Yes" ) : QString::null );
00090     }
00091 
00092   private:
00093     Resource* mResource;
00094 
00095     bool mIsStandard;
00096 };
00097 
00098 ConfigPage::ConfigPage( QWidget *parent, const char *name )
00099   : QWidget( parent, name ),
00100     mCurrentManager( 0 ),
00101     mCurrentConfig( 0 )
00102 {
00103   setCaption( i18n( "Resource Configuration" ) );
00104 
00105   QVBoxLayout *mainLayout = new QVBoxLayout( this );
00106 
00107   QGroupBox *groupBox = new QGroupBox( i18n( "Resources" ), this );
00108   groupBox->setColumnLayout(0, Qt::Vertical );
00109   groupBox->layout()->setSpacing( 6 );
00110   groupBox->layout()->setMargin( 11 );
00111   QGridLayout *groupBoxLayout = new QGridLayout( groupBox->layout(), 2, 2 );
00112 
00113   mFamilyCombo = new KComboBox( false, groupBox );
00114   groupBoxLayout->addMultiCellWidget( mFamilyCombo, 0, 0, 0, 1 );
00115 
00116   mListView = new KListView( groupBox );
00117   mListView->setAllColumnsShowFocus( true );
00118   mListView->setFullWidth( true );
00119   mListView->addColumn( i18n( "Name" ) );
00120   mListView->addColumn( i18n( "Type" ) );
00121   mListView->addColumn( i18n( "Standard" ) );
00122 
00123   groupBoxLayout->addWidget( mListView, 1, 0 );
00124   connect(  mListView, SIGNAL( doubleClicked( QListViewItem *, const QPoint &, int ) ), this, SLOT( slotEdit() ) );
00125   KButtonBox *buttonBox = new KButtonBox( groupBox, Vertical );
00126   mAddButton = buttonBox->addButton( i18n( "&Add..." ), this, SLOT(slotAdd()) );
00127   mRemoveButton = buttonBox->addButton( i18n( "&Remove" ), this, SLOT(slotRemove()) );
00128   mRemoveButton->setEnabled( false );
00129   mEditButton = buttonBox->addButton( i18n( "&Edit..." ), this, SLOT(slotEdit()) );
00130   mEditButton->setEnabled( false );
00131   mStandardButton = buttonBox->addButton( i18n( "&Use as Standard" ), this, SLOT(slotStandard()) );
00132   mStandardButton->setEnabled( false );
00133   buttonBox->layout();
00134 
00135   groupBoxLayout->addWidget( buttonBox, 1, 1 );
00136 
00137   mainLayout->addWidget( groupBox );
00138 
00139   connect( mFamilyCombo, SIGNAL( activated( int ) ),
00140            SLOT( slotFamilyChanged( int ) ) );
00141   connect( mListView, SIGNAL( selectionChanged() ),
00142            SLOT( slotSelectionChanged() ) );
00143   connect( mListView, SIGNAL( clicked( QListViewItem * ) ),
00144            SLOT( slotItemClicked( QListViewItem * ) ) );
00145 
00146   mLastItem = 0;
00147 
00148   mConfig = new KConfig( "kcmkresourcesrc" );
00149   mConfig->setGroup( "General" );
00150 
00151   load();
00152 }
00153 
00154 ConfigPage::~ConfigPage()
00155 {
00156   QValueList<KSharedPtr<ResourcePageInfo> >::Iterator it;
00157   for ( it = mInfoMap.begin(); it != mInfoMap.end(); ++it ) {
00158     (*it)->mManager->removeObserver( this );
00159   }
00160 
00161   mConfig->writeEntry( "CurrentFamily", mFamilyCombo->currentItem() );
00162   delete mConfig;
00163   mConfig = 0;
00164 }
00165 
00166 void ConfigPage::load()
00167 {
00168   kdDebug(5650) << "ConfigPage::load()" << endl;
00169 
00170   mListView->clear();
00171   mFamilyMap.clear();
00172   mInfoMap.clear();
00173   QStringList familyDisplayNames;
00174 
00175   // KDE-3.3 compatibility code: get families from the plugins
00176   QStringList compatFamilyNames;
00177   const KTrader::OfferList plugins = KTrader::self()->query( "KResources/Plugin" );
00178   KTrader::OfferList::ConstIterator it = plugins.begin();
00179   KTrader::OfferList::ConstIterator end = plugins.end();
00180   for ( ; it != end; ++it ) {
00181     const QString family = (*it)->property( "X-KDE-ResourceFamily" ).toString();
00182     if ( compatFamilyNames.find( family ) == compatFamilyNames.end() )
00183         compatFamilyNames.append( family );
00184   }
00185 
00186   const KTrader::OfferList managers = KTrader::self()->query( "KResources/Manager" );
00187   KTrader::OfferList::ConstIterator m_it;
00188   for( m_it = managers.begin(); m_it != managers.end(); ++m_it ) {
00189     QString displayName = (*m_it)->property( "Name" ).toString();
00190     familyDisplayNames.append( displayName );
00191     QString family = (*m_it)->property( "X-KDE-ResourceFamily" ).toString();
00192     if ( !family.isEmpty() ) {
00193       compatFamilyNames.remove( family );
00194       mFamilyMap.append( family );
00195       loadManager( family );
00196     }
00197   }
00198 
00199   // Rest of the kde-3.3 compat code
00200   QStringList::ConstIterator cfit = compatFamilyNames.begin();
00201   for ( ; cfit != compatFamilyNames.end(); ++cfit ) {
00202       mFamilyMap.append( *cfit );
00203       familyDisplayNames.append( *cfit );
00204       loadManager( *cfit );
00205   }
00206 
00207   mCurrentManager = 0;
00208 
00209   mFamilyCombo->clear();
00210   mFamilyCombo->insertStringList( familyDisplayNames );
00211 
00212   int currentFamily = mConfig->readNumEntry( "CurrentFamily", 0 );
00213   mFamilyCombo->setCurrentItem( currentFamily );
00214   slotFamilyChanged( currentFamily );
00215   emit changed( false );
00216 }
00217 
00218 void ConfigPage::loadManager( const QString& family )
00219 {
00220   mCurrentManager = new Manager<Resource>( family );
00221   if ( mCurrentManager ) {
00222       mCurrentManager->addObserver( this );
00223 
00224       ResourcePageInfo *info = new ResourcePageInfo;
00225       info->mManager = mCurrentManager;
00226       info->mConfig = new KConfig( KRES::ManagerImpl::defaultConfigFile( family ) );
00227       info->mManager->readConfig( info->mConfig );
00228 
00229       mInfoMap.append( KSharedPtr<ResourcePageInfo>(info) );
00230   }
00231 }
00232 
00233 void ConfigPage::save()
00234 {
00235   saveResourceSettings();
00236 
00237   QValueList<KSharedPtr<ResourcePageInfo> >::Iterator it;
00238   for ( it = mInfoMap.begin(); it != mInfoMap.end(); ++it )
00239     (*it)->mManager->writeConfig( (*it)->mConfig );
00240 
00241   emit changed( false );
00242 }
00243 
00244 void ConfigPage::defaults()
00245 {
00246 }
00247 
00248 void ConfigPage::slotFamilyChanged( int pos )
00249 {
00250   if ( pos < 0 || pos >= (int)mFamilyMap.count() )
00251     return;
00252 
00253   saveResourceSettings();
00254 
00255   mFamily = mFamilyMap[ pos ];
00256 
00257   mCurrentManager = mInfoMap[ pos ]->mManager;
00258   mCurrentConfig = mInfoMap[ pos ]->mConfig;
00259 
00260   if ( !mCurrentManager )
00261     kdDebug(5650) << "ERROR: cannot create ResourceManager<Resource>( mFamily )" << endl;
00262 
00263   mListView->clear();
00264 
00265   if ( mCurrentManager->isEmpty() )
00266     defaults();
00267 
00268   Resource *standardResource = mCurrentManager->standardResource();
00269 
00270   Manager<Resource>::Iterator it;
00271   for ( it = mCurrentManager->begin(); it != mCurrentManager->end(); ++it ) {
00272     ConfigViewItem *item = new ConfigViewItem( mListView, *it );
00273     if ( *it == standardResource )
00274       item->setStandard( true );
00275   }
00276 
00277   if ( mListView->childCount() == 0 ) {
00278     defaults();
00279     emit changed( true );
00280     mCurrentManager->writeConfig( mCurrentConfig );
00281   } else {
00282     if ( !standardResource )
00283       KMessageBox::sorry( this, i18n( "There is no standard resource! Please select one." ) );
00284 
00285     emit changed( false );
00286   }
00287 }
00288 
00289 void ConfigPage::slotAdd()
00290 {
00291   if ( !mCurrentManager )
00292     return;
00293 
00294   QStringList types = mCurrentManager->resourceTypeNames();
00295   QStringList descs = mCurrentManager->resourceTypeDescriptions();
00296   bool ok = false;
00297   QString desc = KInputDialog::getItem( i18n( "Resource Configuration" ),
00298                     i18n( "Please select type of the new resource:" ), descs,
00299                     0, false, &ok, this );
00300   if ( !ok )
00301     return;
00302 
00303   QString type = types[ descs.findIndex( desc ) ];
00304 
00305   // Create new resource
00306   Resource *resource = mCurrentManager->createResource( type );
00307   if ( !resource ) {
00308     KMessageBox::error( this, i18n("Unable to create resource of type '%1'.")
00309                               .arg( type ) );
00310     return;
00311   }
00312 
00313   resource->setResourceName( type + "-resource" );
00314 
00315   ConfigDialog dlg( this, mFamily, resource, "KRES::ConfigDialog" );
00316 
00317   if ( dlg.exec() ) {
00318     mCurrentManager->add( resource );
00319 
00320     ConfigViewItem *item = new ConfigViewItem( mListView, resource );
00321 
00322     mLastItem = item;
00323 
00324     // if there are only read-only resources we'll set this resource
00325     // as standard resource
00326     if ( !resource->readOnly() ) {
00327       bool onlyReadOnly = true;
00328       QListViewItem *it = mListView->firstChild();
00329       while ( it != 0 ) {
00330         ConfigViewItem *confIt = static_cast<ConfigViewItem*>( it );
00331         if ( !confIt->readOnly() && confIt != item )
00332           onlyReadOnly = false;
00333 
00334         it = it->itemBelow();
00335       }
00336 
00337       if ( onlyReadOnly )
00338         item->setStandard( true );
00339     }
00340 
00341     emit changed( true );
00342   } else {
00343     delete resource;
00344     resource = 0;
00345   }
00346 }
00347 
00348 void ConfigPage::slotRemove()
00349 {
00350   if ( !mCurrentManager )
00351     return;
00352 
00353   QListViewItem *item = mListView->currentItem();
00354   ConfigViewItem *confItem = static_cast<ConfigViewItem*>( item );
00355 
00356   if ( !confItem )
00357     return;
00358 
00359   if ( confItem->standard() ) {
00360     KMessageBox::sorry( this, i18n( "You cannot remove your standard resource! Please select a new standard resource first." ) );
00361     return;
00362   }
00363 
00364   mCurrentManager->remove( confItem->resource() );
00365 
00366   if ( item == mLastItem )
00367     mLastItem = 0;
00368 
00369   mListView->takeItem( item );
00370   delete item;
00371 
00372   emit changed( true );
00373 }
00374 
00375 void ConfigPage::slotEdit()
00376 {
00377   if ( !mCurrentManager )
00378     return;
00379 
00380   QListViewItem *item = mListView->currentItem();
00381   ConfigViewItem *configItem = static_cast<ConfigViewItem*>( item );
00382   if ( !configItem )
00383     return;
00384 
00385   Resource *resource = configItem->resource();
00386 
00387   ConfigDialog dlg( this, mFamily, resource, "KRES::ConfigDialog" );
00388 
00389   if ( dlg.exec() ) {
00390     configItem->setText( 0, resource->resourceName() );
00391     configItem->setText( 1, resource->type() );
00392 
00393     if ( configItem->standard() && configItem->readOnly() ) {
00394       KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard!" ) );
00395       configItem->setStandard( false );
00396     }
00397 
00398     mCurrentManager->change( resource );
00399     emit changed( true );
00400   }
00401 }
00402 
00403 void ConfigPage::slotStandard()
00404 {
00405   if ( !mCurrentManager )
00406     return;
00407 
00408   ConfigViewItem *item = static_cast<ConfigViewItem*>( mListView->currentItem() );
00409   if ( !item )
00410     return;
00411 
00412   if ( item->readOnly() ) {
00413     KMessageBox::sorry( this, i18n( "You cannot use a read-only resource as standard!" ) );
00414     return;
00415   }
00416 
00417   if ( !item->isOn() ) {
00418     KMessageBox::sorry( this, i18n( "You cannot use an inactive resource as standard!" ) );
00419     return;
00420   }
00421 
00422   QListViewItem *it = mListView->firstChild();
00423   while ( it != 0 ) {
00424     ConfigViewItem *configItem = static_cast<ConfigViewItem*>( it );
00425     if ( configItem->standard() )
00426       configItem->setStandard( false );
00427     it = it->itemBelow();
00428   }
00429 
00430   item->setStandard( true );
00431   mCurrentManager->setStandardResource( item->resource() );
00432 
00433   emit changed( true );
00434 }
00435 
00436 void ConfigPage::slotSelectionChanged()
00437 {
00438   bool state = ( mListView->currentItem() != 0 );
00439 
00440   mRemoveButton->setEnabled( state );
00441   mEditButton->setEnabled( state );
00442   mStandardButton->setEnabled( state );
00443 }
00444 
00445 void ConfigPage::resourceAdded( Resource *resource )
00446 {
00447   kdDebug(5650) << "ConfigPage::resourceAdded( " << resource->resourceName()
00448                 << " )" << endl;
00449 
00450   ConfigViewItem *item = new ConfigViewItem( mListView, resource );
00451 
00452   item->setOn( resource->isActive() );
00453 
00454   mLastItem = item;
00455 
00456   emit changed( true );
00457 }
00458 
00459 void ConfigPage::resourceModified( Resource *resource )
00460 {
00461   kdDebug(5650) << "ConfigPage::resourceModified( " << resource->resourceName()
00462                 << " )" << endl;
00463   ConfigViewItem *item = findItem( resource );
00464   if ( !item ) return;
00465 
00466   // TODO: Reread resource config. Otherwise we won't see the modification.
00467 
00468   item->updateItem();
00469 }
00470 
00471 void ConfigPage::resourceDeleted( Resource *resource )
00472 {
00473   kdDebug(5650) << "ConfigPage::resourceDeleted( " << resource->resourceName()
00474                 << " )" << endl;
00475 
00476   ConfigViewItem *item = findItem( resource );
00477   if ( !item ) return;
00478 
00479   delete item;
00480 }
00481 
00482 ConfigViewItem *ConfigPage::findItem( Resource *resource )
00483 {
00484   QListViewItem *i;
00485   for( i = mListView->firstChild(); i; i = i->nextSibling() ) {
00486     ConfigViewItem *item = static_cast<ConfigViewItem *>( i );
00487     if ( item->resource() == resource ) return item;
00488   }
00489   return 0;
00490 }
00491 
00492 void ConfigPage::slotItemClicked( QListViewItem *item )
00493 {
00494   ConfigViewItem *configItem = static_cast<ConfigViewItem *>( item );
00495   if ( !configItem ) return;
00496 
00497   if ( configItem->standard() && !configItem->isOn() ) {
00498     KMessageBox::sorry( this, i18n( "You cannot deactivate the standard resource. Choose another standard resource first." ) );
00499     configItem->setOn( true );
00500     return;
00501   }
00502 
00503   if ( configItem->isOn() != configItem->resource()->isActive() ) {
00504     emit changed( true );
00505   }
00506 }
00507 
00508 void ConfigPage::saveResourceSettings()
00509 {
00510   if ( mCurrentManager ) {
00511     QListViewItem *item = mListView->firstChild();
00512     while ( item ) {
00513       ConfigViewItem *configItem = static_cast<ConfigViewItem *>( item );
00514 
00515       // check if standard resource
00516       if ( configItem->standard() && !configItem->readOnly() &&
00517            configItem->isOn() )
00518         mCurrentManager->setStandardResource( configItem->resource() );
00519 
00520       // check if active or passive resource
00521       configItem->resource()->setActive( configItem->isOn() );
00522 
00523       item = item->nextSibling();
00524     }
00525     mCurrentManager->writeConfig( mCurrentConfig );
00526 
00527     if ( !mCurrentManager->standardResource() )
00528       KMessageBox::sorry( this, i18n( "There is no valid standard resource! Please select one which is neither read-only nor inactive." ) );
00529   }
00530 }
00531 
00532 }
00533 
00534 #include "configpage.moc"
00535 
KDE Home | KDE Accessibility Home | Description of Access Keys