kpluginselector.cpp
00001 /* This file is part of the KDE project 00002 Copyright (C) 2002-2003 Matthias Kretz <kretz@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License version 2 as published by the Free Software Foundation. 00007 00008 This library is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 Library General Public License for more details. 00012 00013 You should have received a copy of the GNU Library General Public License 00014 along with this library; see the file COPYING.LIB. If not, write to 00015 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00016 Boston, MA 02110-1301, USA. 00017 00018 */ 00019 00020 #include "kpluginselector.h" 00021 #include "kpluginselector_p.h" 00022 00023 #include <tqtooltip.h> 00024 #include <tqvbox.h> 00025 #include <tqlabel.h> 00026 #include <tqstrlist.h> 00027 #include <tqfile.h> 00028 #include <tqstring.h> 00029 #include <tqlayout.h> 00030 #include <tqptrlist.h> 00031 #include <tqwidgetstack.h> 00032 #include <tqcursor.h> 00033 #include <tqapplication.h> 00034 #include <tqobjectlist.h> 00035 #include <tqcstring.h> 00036 00037 #include <kdebug.h> 00038 #include <tdelocale.h> 00039 #include <tdelistview.h> 00040 #include <ksimpleconfig.h> 00041 #include <kdialog.h> 00042 #include <tdeglobal.h> 00043 #include <tdeglobalsettings.h> 00044 #include <kstandarddirs.h> 00045 #include <ktabctl.h> 00046 #include <tdecmoduleinfo.h> 00047 #include <tqvaluelist.h> 00048 #include <kservice.h> 00049 #include <ktrader.h> 00050 #include <ktabwidget.h> 00051 #include <kiconloader.h> 00052 #include <tdecmodule.h> 00053 #include "tdecmoduleinfo.h" 00054 #include "tdecmoduleloader.h" 00055 #include <tqsplitter.h> 00056 #include <tqframe.h> 00057 #include "kplugininfo.h" 00058 #include <kinstance.h> 00059 #include <tqptrdict.h> 00060 #include <tqstringlist.h> 00061 #include "tdecmoduleproxy.h" 00062 00063 /* 00064 QCheckListViewItem that holds a pointer to the KPluginInfo object. 00065 Used in the tooltip code to access additional fields 00066 */ 00067 class KPluginInfoLVI : public TQCheckListItem 00068 { 00069 public: 00070 KPluginInfoLVI( KPluginInfo *pluginInfo, TDEListView *parent ) 00071 : TQCheckListItem( parent, pluginInfo->name(), TQCheckListItem::CheckBox ), m_pluginInfo( pluginInfo ) 00072 { 00073 } 00074 00075 KPluginInfo * pluginInfo() { return m_pluginInfo; } 00076 00077 private: 00078 KPluginInfo *m_pluginInfo; 00079 }; 00080 00081 /* 00082 Custom TQToolTip for the list view. 00083 The decision whether or not to show tooltips is taken in 00084 maybeTip(). See also the TQListView sources from Qt itself. 00085 */ 00086 class KPluginListViewToolTip : public TQToolTip 00087 { 00088 public: 00089 KPluginListViewToolTip( TQWidget *parent, TDEListView *lv ); 00090 00091 void maybeTip( const TQPoint &pos ); 00092 00093 private: 00094 TDEListView *m_listView; 00095 }; 00096 00097 KPluginListViewToolTip::KPluginListViewToolTip( TQWidget *parent, TDEListView *lv ) 00098 : TQToolTip( parent ), m_listView( lv ) 00099 { 00100 } 00101 00102 void KPluginListViewToolTip::maybeTip( const TQPoint &pos ) 00103 { 00104 if ( !parentWidget() || !m_listView ) 00105 return; 00106 00107 KPluginInfoLVI *item = dynamic_cast<KPluginInfoLVI *>( m_listView->itemAt( pos ) ); 00108 if ( !item ) 00109 return; 00110 00111 TQString toolTip = i18n( "<qt><table>" 00112 "<tr><td><b>Description:</b></td><td>%1</td></tr>" 00113 "<tr><td><b>Author:</b></td><td>%2</td></tr>" 00114 "<tr><td><b>Version:</b></td><td>%3</td></tr>" 00115 "<tr><td><b>License:</b></td><td>%4</td></tr></table></qt>" ).arg( item->pluginInfo()->comment(), 00116 item->pluginInfo()->author(), item->pluginInfo()->version(), item->pluginInfo()->license() ); 00117 00118 //kdDebug( 702 ) << k_funcinfo << "Adding tooltip: itemRect: " << itemRect << ", tooltip: " << toolTip << endl; 00119 tip( m_listView->itemRect( item ), toolTip ); 00120 } 00121 00122 struct KPluginSelectionWidget::KPluginSelectionWidgetPrivate 00123 { 00124 KPluginSelectionWidgetPrivate( KPluginSelector * _kps, 00125 const TQString & _cat, 00126 TDEConfigGroup * _config ) 00127 : widgetstack( 0 ) 00128 , kps( _kps ) 00129 , config( _config ) 00130 , tooltip( 0 ) 00131 , catname( _cat ) 00132 , currentplugininfo( 0 ) 00133 , visible( true ) 00134 , currentchecked( false ) 00135 , changed( 0 ) 00136 { 00137 moduleParentComponents.setAutoDelete( true ); 00138 } 00139 00140 ~KPluginSelectionWidgetPrivate() 00141 { 00142 delete config; 00143 } 00144 00145 TQMap<TQCheckListItem*, KPluginInfo*> pluginInfoMap; 00146 00147 TQWidgetStack * widgetstack; 00148 KPluginSelector * kps; 00149 TDEConfigGroup * config; 00150 KPluginListViewToolTip *tooltip; 00151 00152 TQDict<TDECModuleInfo> pluginconfigmodules; 00153 TQMap<TQString, int> widgetIDs; 00154 TQMap<KPluginInfo*, bool> plugincheckedchanged; 00155 TQString catname; 00156 TQValueList<TDECModuleProxy*> modulelist; 00157 TQPtrDict<TQStringList> moduleParentComponents; 00158 00159 KPluginInfo * currentplugininfo; 00160 bool visible; 00161 bool currentchecked; 00162 int changed; 00163 }; 00164 00165 KPluginSelectionWidget::KPluginSelectionWidget( 00166 const TQValueList<KPluginInfo*> & plugininfos, KPluginSelector * kps, 00167 TQWidget * parent, const TQString & catname, const TQString & category, 00168 TDEConfigGroup * config, const char * name ) 00169 : TQWidget( parent, name ) 00170 , d( new KPluginSelectionWidgetPrivate( kps, catname, config ) ) 00171 { 00172 init( plugininfos, category ); 00173 } 00174 00175 inline TQString KPluginSelectionWidget::catName() const 00176 { 00177 return d->catname; 00178 } 00179 00180 void KPluginSelectionWidget::init( const TQValueList<KPluginInfo*> & plugininfos, 00181 const TQString & category ) 00182 { 00183 // setup Widgets 00184 ( new TQVBoxLayout( this, 0, KDialog::spacingHint() ) )->setAutoAdd( true ); 00185 TDEListView * listview = new TDEListView( this ); 00186 d->tooltip = new KPluginListViewToolTip( listview->viewport(), listview ); 00187 connect( listview, TQT_SIGNAL( pressed( TQListViewItem * ) ), this, 00188 TQT_SLOT( executed( TQListViewItem * ) ) ); 00189 connect( listview, TQT_SIGNAL( spacePressed( TQListViewItem * ) ), this, 00190 TQT_SLOT( executed( TQListViewItem * ) ) ); 00191 connect( listview, TQT_SIGNAL( returnPressed( TQListViewItem * ) ), this, 00192 TQT_SLOT( executed( TQListViewItem * ) ) ); 00193 connect( listview, TQT_SIGNAL( selectionChanged( TQListViewItem * ) ), this, 00194 TQT_SLOT( executed( TQListViewItem * ) ) ); 00195 listview->setSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Preferred ); 00196 listview->setAcceptDrops( false ); 00197 listview->setFullWidth( true ); 00198 listview->setSelectionModeExt( TDEListView::Single ); 00199 listview->setAllColumnsShowFocus( true ); 00200 listview->addColumn( i18n( "Name" ) ); 00201 for( TQValueList<KPluginInfo*>::ConstIterator it = plugininfos.begin(); 00202 it != plugininfos.end(); ++it ) 00203 { 00204 d->plugincheckedchanged[ *it ] = false; 00205 if( !( *it )->isHidden() && 00206 ( category.isNull() || ( *it )->category() == category ) ) 00207 { 00208 TQCheckListItem * item = new KPluginInfoLVI( *it, listview ); 00209 if( ! ( *it )->icon().isEmpty() ) 00210 item->setPixmap( 0, SmallIcon( ( *it )->icon(), IconSize( TDEIcon::Small ) ) ); 00211 item->setOn( ( *it )->isPluginEnabled() ); 00212 d->pluginInfoMap.insert( item, *it ); 00213 } 00214 } 00215 00216 // widgetstack 00217 d->widgetstack = d->kps->widgetStack(); 00218 load(); 00219 // select and highlight the first item in the plugin list 00220 if( listview->firstChild() ) 00221 listview->setSelected( listview->firstChild(), true ); 00222 } 00223 00224 KPluginSelectionWidget::~KPluginSelectionWidget() 00225 { 00226 delete d->tooltip; 00227 delete d; 00228 } 00229 00230 bool KPluginSelectionWidget::pluginIsLoaded( const TQString & pluginName ) const 00231 { 00232 for( TQMap<TQCheckListItem*, KPluginInfo*>::ConstIterator it = 00233 d->pluginInfoMap.begin(); it != d->pluginInfoMap.end(); ++it ) 00234 if( it.data()->pluginName() == pluginName ) 00235 return it.data()->isPluginEnabled(); 00236 return false; 00237 } 00238 00239 00240 TQWidget * KPluginSelectionWidget::insertKCM( TQWidget * parent, 00241 const TDECModuleInfo & moduleinfo ) 00242 { 00243 TDECModuleProxy * module = new TDECModuleProxy( moduleinfo, false, 00244 parent ); 00245 if( !module->realModule() ) 00246 { 00247 //FIXME: not very verbose 00248 TQLabel * label = new TQLabel( i18n( "Error" ), parent ); 00249 label->setAlignment( Qt::AlignCenter ); 00250 00251 return label; 00252 } 00253 // add the KCM to the list so that we can call load/save/defaults on it 00254 d->modulelist.append( module ); 00255 TQStringList * parentComponents = new TQStringList( 00256 moduleinfo.service()->property( 00257 "X-TDE-ParentComponents" ).toStringList() ); 00258 d->moduleParentComponents.insert( module, parentComponents ); 00259 connect( module, TQT_SIGNAL( changed( bool ) ), TQT_SLOT( clientChanged( bool ) ) ); 00260 return module; 00261 } 00262 00263 void KPluginSelectionWidget::embeddPluginKCMs( KPluginInfo * plugininfo, bool checked ) 00264 { 00265 //if we have Services for the plugin we should be able to 00266 //create KCM(s) 00267 TQApplication::setOverrideCursor( Qt::WaitCursor ); 00268 if( plugininfo->kcmServices().size() > 1 ) 00269 { 00270 // we need a tabwidget 00271 KTabWidget * tabwidget = new KTabWidget( d->widgetstack ); 00272 tabwidget->setEnabled( checked ); 00273 00274 int id = d->widgetstack->addWidget( tabwidget ); 00275 d->kps->configPage( id ); 00276 d->widgetIDs[ plugininfo->pluginName() ] = id; 00277 00278 for( TQValueList<KService::Ptr>::ConstIterator it = 00279 plugininfo->kcmServices().begin(); 00280 it != plugininfo->kcmServices().end(); ++it ) 00281 { 00282 if( !( *it )->noDisplay() ) 00283 { 00284 TDECModuleInfo moduleinfo( *it ); 00285 TQWidget * module = insertKCM( tabwidget, moduleinfo ); 00286 tabwidget->addTab( module, moduleinfo.moduleName() ); 00287 } 00288 } 00289 } 00290 else 00291 { 00292 if( !plugininfo->kcmServices().front()->noDisplay() ) 00293 { 00294 TDECModuleInfo moduleinfo( 00295 plugininfo->kcmServices().front() ); 00296 TQWidget * module = insertKCM( d->widgetstack, moduleinfo ); 00297 module->setEnabled( checked ); 00298 00299 int id = d->widgetstack->addWidget( module ); 00300 d->kps->configPage( id ); 00301 d->widgetIDs[ plugininfo->pluginName() ] = id; 00302 } 00303 } 00304 TQApplication::restoreOverrideCursor(); 00305 } 00306 00307 inline void KPluginSelectionWidget::updateConfigPage() 00308 { 00309 updateConfigPage( d->currentplugininfo, d->currentchecked ); 00310 } 00311 00312 void KPluginSelectionWidget::updateConfigPage( KPluginInfo * plugininfo, 00313 bool checked ) 00314 { 00315 //kdDebug( 702 ) << k_funcinfo << endl; 00316 d->currentplugininfo = plugininfo; 00317 d->currentchecked = checked; 00318 00319 // if this widget is not currently visible (meaning that it's in a tabwidget 00320 // and another tab is currently opened) it's not allowed to change the 00321 // widgetstack 00322 if( ! d->visible ) 00323 return; 00324 00325 if( 0 == plugininfo ) 00326 { 00327 d->kps->configPage( 1 ); 00328 return; 00329 } 00330 00331 if( plugininfo->kcmServices().empty() ) 00332 d->kps->configPage( 1 ); 00333 else 00334 { 00335 if( !d->widgetIDs.contains( plugininfo->pluginName() ) ) 00336 // if no widget exists for the plugin create it 00337 embeddPluginKCMs( plugininfo, checked ); 00338 else 00339 { 00340 // the page already exists 00341 int id = d->widgetIDs[ plugininfo->pluginName() ]; 00342 d->kps->configPage( id ); 00343 d->widgetstack->widget( id )->setEnabled( checked ); 00344 } 00345 } 00346 } 00347 00348 void KPluginSelectionWidget::clientChanged( bool didchange ) 00349 { 00350 kdDebug( 702 ) << k_funcinfo << endl; 00351 d->changed += didchange ? 1 : -1; 00352 if( d->changed == 1 ) 00353 emit changed( true ); 00354 else if( d->changed == 0 ) 00355 emit changed( false ); 00356 else if( d->changed < 0 ) 00357 kdError( 702 ) << "negative changed value: " << d->changed << endl; 00358 } 00359 00360 void KPluginSelectionWidget::tabWidgetChanged( TQWidget * widget ) 00361 { 00362 if( widget == this ) 00363 { 00364 d->visible = true; 00365 updateConfigPage(); 00366 } 00367 else 00368 d->visible = false; 00369 } 00370 00371 void KPluginSelectionWidget::executed( TQListViewItem * item ) 00372 { 00373 kdDebug( 702 ) << k_funcinfo << endl; 00374 if( item == 0 ) 00375 return; 00376 00377 // Why not a dynamic_cast? - Martijn 00378 // because this is what the Qt API suggests; and since gcc 3.x I don't 00379 // trust dynamic_cast anymore - mkretz 00380 if( item->rtti() != 1 ) //check for a QCheckListItem 00381 return; 00382 00383 TQCheckListItem * citem = static_cast<TQCheckListItem *>( item ); 00384 bool checked = citem->isOn(); 00385 //kdDebug( 702 ) << "it's a " << ( checked ? "checked" : "unchecked" ) 00386 // << " TQCheckListItem" << endl; 00387 00388 KPluginInfo * info = d->pluginInfoMap[ citem ]; 00389 Q_ASSERT( !info->isHidden() ); 00390 00391 if ( info->isPluginEnabled() != checked ) 00392 { 00393 kdDebug( 702 ) << "Item changed state, emitting changed()" << endl; 00394 00395 if( ! d->plugincheckedchanged[ info ] ) 00396 { 00397 ++d->changed; 00398 if ( d->changed == 1 ) 00399 emit changed( true ); 00400 } 00401 d->plugincheckedchanged[ info ] = true; 00402 00403 checkDependencies( info ); 00404 } 00405 else 00406 { 00407 if( d->plugincheckedchanged[ info ] ) 00408 { 00409 --d->changed; 00410 if ( d->changed == 0 ) 00411 emit changed( false ); 00412 } 00413 d->plugincheckedchanged[ info ] = false; 00414 // FIXME: plugins that depend on this plugin need to be disabled, too 00415 } 00416 00417 updateConfigPage( info, checked ); 00418 } 00419 00420 void KPluginSelectionWidget::load() 00421 { 00422 //kdDebug( 702 ) << k_funcinfo << endl; 00423 00424 for( TQMap<TQCheckListItem*, KPluginInfo*>::Iterator it = 00425 d->pluginInfoMap.begin(); it != d->pluginInfoMap.end(); ++it ) 00426 { 00427 KPluginInfo * info = it.data(); 00428 info->load( d->config ); 00429 it.key()->setOn( info->isPluginEnabled() ); 00430 if( d->visible && info == d->currentplugininfo ) 00431 d->currentchecked = info->isPluginEnabled(); 00432 } 00433 00434 for( TQValueList<TDECModuleProxy*>::Iterator it = d->modulelist.begin(); 00435 it != d->modulelist.end(); ++it ) 00436 if( ( *it )->changed() ) 00437 ( *it )->load(); 00438 00439 updateConfigPage(); 00440 // TODO: update changed state 00441 } 00442 00443 void KPluginSelectionWidget::save() 00444 { 00445 kdDebug( 702 ) << k_funcinfo << endl; 00446 00447 for( TQMap<TQCheckListItem*, KPluginInfo*>::Iterator it = 00448 d->pluginInfoMap.begin(); it != d->pluginInfoMap.end(); ++it ) 00449 { 00450 KPluginInfo * info = it.data(); 00451 bool checked = it.key()->isOn(); 00452 info->setPluginEnabled( checked ); 00453 info->save( d->config ); 00454 d->plugincheckedchanged[ info ] = false; 00455 } 00456 TQStringList updatedModules; 00457 for( TQValueList<TDECModuleProxy*>::Iterator it = d->modulelist.begin(); 00458 it != d->modulelist.end(); ++it ) 00459 if( ( *it )->changed() ) 00460 { 00461 ( *it )->save(); 00462 TQStringList * names = d->moduleParentComponents[ *it ]; 00463 if( names->size() == 0 ) 00464 names->append( TQString::null ); 00465 for( TQStringList::ConstIterator nameit = names->begin(); 00466 nameit != names->end(); ++nameit ) 00467 if( updatedModules.find( *nameit ) == updatedModules.end() ) 00468 updatedModules.append( *nameit ); 00469 } 00470 for( TQStringList::ConstIterator it = updatedModules.begin(); it != updatedModules.end(); ++it ) 00471 emit configCommitted( ( *it ).latin1() ); 00472 00473 updateConfigPage(); 00474 kdDebug( 702 ) << "syncing config file" << endl; 00475 d->config->sync(); 00476 d->changed = 0; 00477 emit changed( false ); 00478 } 00479 00480 void KPluginSelectionWidget::checkDependencies( const KPluginInfo * info ) 00481 { 00482 if( info->dependencies().isEmpty() ) 00483 return; 00484 00485 for( TQStringList::ConstIterator it = info->dependencies().begin(); 00486 it != info->dependencies().end(); ++it ) 00487 for( TQMap<TQCheckListItem*, 00488 KPluginInfo*>::Iterator infoIt = d->pluginInfoMap.begin(); 00489 infoIt != d->pluginInfoMap.end(); ++infoIt ) 00490 if( infoIt.data()->pluginName() == *it ) 00491 { 00492 if( !infoIt.key()->isOn() ) 00493 { 00494 infoIt.key()->setOn( true ); 00495 checkDependencies( infoIt.data() ); 00496 } 00497 continue; 00498 } 00499 } 00500 00501 class KPluginSelector::KPluginSelectorPrivate 00502 { 00503 public: 00504 KPluginSelectorPrivate() 00505 : frame( 0 ) 00506 , tabwidget( 0 ) 00507 , widgetstack( 0 ) 00508 , hideconfigpage( false ) 00509 { 00510 } 00511 00512 TQFrame * frame; 00513 KTabWidget * tabwidget; 00514 TQWidgetStack * widgetstack; 00515 TQValueList<KPluginSelectionWidget *> pswidgets; 00516 bool hideconfigpage; 00517 }; 00518 00519 KPluginSelector::KPluginSelector( TQWidget * parent, const char * name ) 00520 : TQWidget( parent, name ) 00521 , d( new KPluginSelectorPrivate ) 00522 { 00523 TQBoxLayout * hbox = new TQHBoxLayout( this, 0, KDialog::spacingHint() ); 00524 hbox->setAutoAdd( true ); 00525 00526 TQSplitter* splitter = new TQSplitter( Qt::Horizontal, this ); 00527 d->frame = new TQFrame( splitter, "KPluginSelector left frame" ); 00528 d->frame->setFrameStyle( TQFrame::NoFrame ); 00529 ( new TQVBoxLayout( d->frame, 0, KDialog::spacingHint() ) )->setAutoAdd( true ); 00530 00531 // widgetstack 00532 d->widgetstack = new TQWidgetStack( splitter, "KPluginSelector Config Pages" ); 00533 d->widgetstack->setFrameStyle( TQFrame::Panel | TQFrame::Sunken ); 00534 d->widgetstack->setMinimumSize( 200, 200 ); 00535 00536 TQLabel * label = new TQLabel( i18n( "(This plugin is not configurable)" ), 00537 d->widgetstack ); 00538 ( new TQVBoxLayout( label, 0, KDialog::spacingHint() ) )->setAutoAdd( true ); 00539 label->setAlignment( Qt::AlignCenter ); 00540 label->setMinimumSize( 200, 200 ); 00541 00542 d->widgetstack->addWidget( label, 1 ); 00543 00544 configPage( 1 ); 00545 } 00546 00547 KPluginSelector::~KPluginSelector() 00548 { 00549 delete d; 00550 } 00551 00552 void KPluginSelector::checkNeedForTabWidget() 00553 { 00554 kdDebug( 702 ) << k_funcinfo << endl; 00555 if( ! d->tabwidget && d->pswidgets.size() == 1 ) 00556 { 00557 kdDebug( 702 ) << "no TabWidget and one KPluginSelectionWidget" << endl; 00558 // there's only one KPluginSelectionWidget yet, we need a TabWidget 00559 KPluginSelectionWidget * w = d->pswidgets.first(); 00560 if( w ) 00561 { 00562 kdDebug( 702 ) << "create TabWidget" << endl; 00563 d->tabwidget = new KTabWidget( d->frame, 00564 "KPluginSelector TabWidget" ); 00565 w->reparent( d->tabwidget, TQPoint( 0, 0 ) ); 00566 d->tabwidget->addTab( w, w->catName() ); 00567 connect( d->tabwidget, TQT_SIGNAL( currentChanged( TQWidget * ) ), w, 00568 TQT_SLOT( tabWidgetChanged( TQWidget * ) ) ); 00569 } 00570 } 00571 } 00572 00573 static TQValueList<KPluginInfo*> tdepartsPluginInfos( const TQString& instanceName ) 00574 { 00575 if( instanceName.isNull() ) 00576 return TQValueList<KPluginInfo*>(); //nothing 00577 00578 const TQStringList desktopfilenames = TDEGlobal::dirs()->findAllResources( "data", 00579 instanceName + "/kpartplugins/*.desktop", true, false ); 00580 return KPluginInfo::fromFiles( desktopfilenames ); 00581 } 00582 00583 void KPluginSelector::addPlugins( const TQString & instanceName, 00584 const TQString & catname, const TQString & category, TDEConfig * config ) 00585 { 00586 const TQValueList<KPluginInfo*> plugininfos = tdepartsPluginInfos( instanceName ); 00587 if ( plugininfos.isEmpty() ) 00588 return; 00589 checkNeedForTabWidget(); 00590 Q_ASSERT( config ); // please set config, or use addPlugins( instance, ... ) which takes care of it 00591 if ( !config ) // KDE4: ensure that config is always set; make it second in the arg list? 00592 config = new KSimpleConfig( instanceName ); // memleak! 00593 TDEConfigGroup * cfgGroup = new TDEConfigGroup( config, "KParts Plugins" ); 00594 kdDebug( 702 ) << k_funcinfo << "cfgGroup = " << cfgGroup << endl; 00595 addPluginsInternal( plugininfos, catname, category, cfgGroup ); 00596 } 00597 00598 void KPluginSelector::addPluginsInternal( const TQValueList<KPluginInfo*> plugininfos, 00599 const TQString & catname, const TQString & category, 00600 TDEConfigGroup* cfgGroup ) 00601 { 00602 KPluginSelectionWidget * w; 00603 if( d->tabwidget ) 00604 { 00605 w = new KPluginSelectionWidget( plugininfos, this, 00606 d->tabwidget, catname, category, cfgGroup ); 00607 d->tabwidget->addTab( w, catname ); 00608 connect( d->tabwidget, TQT_SIGNAL( currentChanged( TQWidget * ) ), w, 00609 TQT_SLOT( tabWidgetChanged( TQWidget * ) ) ); 00610 } 00611 else 00612 w = new KPluginSelectionWidget( plugininfos, this, d->frame, 00613 catname, category, cfgGroup ); 00614 w->setMinimumSize( 200, 200 ); 00615 connect( w, TQT_SIGNAL( changed( bool ) ), this, TQT_SIGNAL( changed( bool ) ) ); 00616 connect( w, TQT_SIGNAL( configCommitted( const TQCString & ) ), this, 00617 TQT_SIGNAL( configCommitted( const TQCString & ) ) ); 00618 d->pswidgets += w; 00619 } 00620 00621 void KPluginSelector::addPlugins( const TDEInstance * instance, const TQString & 00622 catname, const TQString & category, TDEConfig * config ) 00623 { 00624 if ( !config ) 00625 config = instance->config(); 00626 addPlugins( instance->instanceName(), catname, category, config ); 00627 } 00628 00629 void KPluginSelector::addPlugins( const TQValueList<KPluginInfo*> & plugininfos, 00630 const TQString & catname, const TQString & category, TDEConfig * config ) 00631 { 00632 checkNeedForTabWidget(); 00633 // the TDEConfigGroup becomes owned by KPluginSelectionWidget 00634 TDEConfigGroup * cfgGroup = new TDEConfigGroup( config ? config : TDEGlobal::config(), "Plugins" ); 00635 kdDebug( 702 ) << k_funcinfo << "cfgGroup = " << cfgGroup << endl; 00636 addPluginsInternal( plugininfos, catname, category, cfgGroup ); 00637 } 00638 00639 TQWidgetStack * KPluginSelector::widgetStack() 00640 { 00641 return d->widgetstack; 00642 } 00643 00644 inline void KPluginSelector::configPage( int id ) 00645 { 00646 if( id == 1 ) 00647 { 00648 // no config page 00649 if( d->hideconfigpage ) 00650 { 00651 d->widgetstack->hide(); 00652 return; 00653 } 00654 } 00655 else 00656 d->widgetstack->show(); 00657 00658 d->widgetstack->raiseWidget( id ); 00659 } 00660 00661 void KPluginSelector::setShowEmptyConfigPage( bool show ) 00662 { 00663 d->hideconfigpage = !show; 00664 if( d->hideconfigpage ) 00665 if( d->widgetstack->id( d->widgetstack->visibleWidget() ) == 1 ) 00666 d->widgetstack->hide(); 00667 } 00668 00669 void KPluginSelector::load() 00670 { 00671 for( TQValueList<KPluginSelectionWidget *>::Iterator it = 00672 d->pswidgets.begin(); it != d->pswidgets.end(); ++it ) 00673 { 00674 ( *it )->load(); 00675 } 00676 } 00677 00678 void KPluginSelector::save() 00679 { 00680 for( TQValueList<KPluginSelectionWidget *>::Iterator it = 00681 d->pswidgets.begin(); it != d->pswidgets.end(); ++it ) 00682 { 00683 ( *it )->save(); 00684 } 00685 } 00686 00687 void KPluginSelector::defaults() 00688 { 00689 kdDebug( 702 ) << k_funcinfo << endl; 00690 00691 // what should defaults do? here's what I think: 00692 // Pressing a button in the dialog should not change any widgets that are 00693 // not visible for the user. Therefor we may only change the currently 00694 // visible plugin's KCM. Restoring the default plugin selections is therefor 00695 // not possible. (if the plugin has multiple KCMs they will be shown in a 00696 // tabwidget - defaults() will be called for all of them) 00697 00698 TQWidget * pluginconfig = d->widgetstack->visibleWidget(); 00699 TDECModuleProxy * kcm = ::tqqt_cast<TDECModuleProxy*>(pluginconfig); 00700 if( kcm ) 00701 { 00702 kdDebug( 702 ) << "call TDECModule::defaults() for the plugins KCM" 00703 << endl; 00704 kcm->defaults(); 00705 return; 00706 } 00707 00708 // if we get here the visible Widget must be a tabwidget holding more than 00709 // one KCM 00710 TQObjectList * kcms = pluginconfig->queryList( "TDECModuleProxy", 00711 0, false, false ); 00712 TQObjectListIt it( *kcms ); 00713 TQObject * obj; 00714 while( ( obj = it.current() ) != 0 ) 00715 { 00716 ++it; 00717 ( ( TDECModule* )obj )->defaults(); 00718 } 00719 delete kcms; 00720 // FIXME: update changed state 00721 } 00722 00723 // vim: sw=4 sts=4 et 00724 00725 #include "kpluginselector.moc" 00726 #include "kpluginselector_p.moc"