20 #include "kpluginselector.h"
21 #include "kpluginselector_p.h"
23 #include <tqtooltip.h>
26 #include <tqstrlist.h>
30 #include <tqptrlist.h>
31 #include <tqwidgetstack.h>
33 #include <tqapplication.h>
34 #include <tqobjectlist.h>
35 #include <tqcstring.h>
39 #include <tdelistview.h>
40 #include <ksimpleconfig.h>
42 #include <tdeglobal.h>
43 #include <tdeglobalsettings.h>
44 #include <kstandarddirs.h>
46 #include <tdecmoduleinfo.h>
47 #include <tqvaluelist.h>
50 #include <ktabwidget.h>
51 #include <kiconloader.h>
52 #include <tdecmodule.h>
53 #include "tdecmoduleinfo.h"
54 #include "tdecmoduleloader.h"
55 #include <tqsplitter.h>
57 #include "kplugininfo.h"
58 #include <kinstance.h>
59 #include <tqptrdict.h>
60 #include <tqstringlist.h>
61 #include "tdecmoduleproxy.h"
67 class KPluginInfoLVI :
public TQCheckListItem
71 : TQCheckListItem( parent, pluginInfo->
name(), TQCheckListItem::CheckBox ), m_pluginInfo( pluginInfo )
86 class KPluginListViewToolTip :
public TQToolTip
89 KPluginListViewToolTip( TQWidget *parent,
TDEListView *lv );
91 void maybeTip(
const TQPoint &pos );
97 KPluginListViewToolTip::KPluginListViewToolTip( TQWidget *parent,
TDEListView *lv )
98 : TQToolTip( parent ), m_listView( lv )
102 void KPluginListViewToolTip::maybeTip(
const TQPoint &pos )
104 if ( !parentWidget() || !m_listView )
107 KPluginInfoLVI *item =
dynamic_cast<KPluginInfoLVI *
>( m_listView->itemAt( pos ) );
111 TQString toolTip = i18n(
"<qt><table>"
112 "<tr><td><b>Description:</b></td><td>%1</td></tr>"
113 "<tr><td><b>Author:</b></td><td>%2</td></tr>"
114 "<tr><td><b>Version:</b></td><td>%3</td></tr>"
115 "<tr><td><b>License:</b></td><td>%4</td></tr></table></qt>" ).arg( item->pluginInfo()->comment(),
116 item->pluginInfo()->author(), item->pluginInfo()->version(), item->pluginInfo()->license() );
119 tip( m_listView->itemRect( item ), toolTip );
122 struct KPluginSelectionWidget::KPluginSelectionWidgetPrivate
125 const TQString & _cat,
132 , currentplugininfo( 0 )
134 , currentchecked( false )
137 moduleParentComponents.setAutoDelete(
true );
140 ~KPluginSelectionWidgetPrivate()
145 TQMap<TQCheckListItem*, KPluginInfo*> pluginInfoMap;
147 TQWidgetStack * widgetstack;
150 KPluginListViewToolTip *tooltip;
152 TQDict<TDECModuleInfo> pluginconfigmodules;
153 TQMap<TQString, int> widgetIDs;
154 TQMap<KPluginInfo*, bool> plugincheckedchanged;
156 TQValueList<TDECModuleProxy*> modulelist;
157 TQPtrDict<TQStringList> moduleParentComponents;
165 KPluginSelectionWidget::KPluginSelectionWidget(
167 TQWidget * parent,
const TQString & catname,
const TQString & category,
169 : TQWidget( parent, name )
170 , d( new KPluginSelectionWidgetPrivate( kps, catname, config ) )
172 init( plugininfos, category );
175 inline TQString KPluginSelectionWidget::catName()
const
180 void KPluginSelectionWidget::init(
const TQValueList<KPluginInfo*> & plugininfos,
181 const TQString & category )
186 d->tooltip =
new KPluginListViewToolTip( listview->viewport(), listview );
187 connect( listview, TQT_SIGNAL( pressed( TQListViewItem * ) ),
this,
188 TQT_SLOT( executed( TQListViewItem * ) ) );
189 connect( listview, TQT_SIGNAL( spacePressed( TQListViewItem * ) ),
this,
190 TQT_SLOT( executed( TQListViewItem * ) ) );
191 connect( listview, TQT_SIGNAL( returnPressed( TQListViewItem * ) ),
this,
192 TQT_SLOT( executed( TQListViewItem * ) ) );
193 connect( listview, TQT_SIGNAL( selectionChanged( TQListViewItem * ) ),
this,
194 TQT_SLOT( executed( TQListViewItem * ) ) );
195 listview->setSizePolicy( TQSizePolicy::Minimum, TQSizePolicy::Preferred );
199 listview->setAllColumnsShowFocus(
true );
201 for( TQValueList<KPluginInfo*>::ConstIterator it = plugininfos.begin();
202 it != plugininfos.end(); ++it )
204 d->plugincheckedchanged[ *it ] =
false;
205 if( !( *it )->isHidden() &&
206 ( category.isNull() || ( *it )->category() == category ) )
208 TQCheckListItem * item =
new KPluginInfoLVI( *it, listview );
209 if( ! ( *it )->icon().isEmpty() )
210 item->setPixmap( 0, SmallIcon( ( *it )->icon(), IconSize(
TDEIcon::Small ) ) );
211 item->setOn( ( *it )->isPluginEnabled() );
212 d->pluginInfoMap.insert( item, *it );
217 d->widgetstack = d->kps->widgetStack();
220 if( listview->firstChild() )
221 listview->setSelected( listview->firstChild(), true );
224 KPluginSelectionWidget::~KPluginSelectionWidget()
230 bool KPluginSelectionWidget::pluginIsLoaded(
const TQString & pluginName )
const
232 for( TQMap<TQCheckListItem*, KPluginInfo*>::ConstIterator it =
233 d->pluginInfoMap.begin(); it != d->pluginInfoMap.end(); ++it )
234 if( it.data()->pluginName() == pluginName )
235 return it.data()->isPluginEnabled();
240 TQWidget * KPluginSelectionWidget::insertKCM( TQWidget * parent,
248 TQLabel *
label =
new TQLabel( i18n(
"Error" ), parent );
249 label->setAlignment( Qt::AlignCenter );
254 d->modulelist.append( module );
255 TQStringList * parentComponents =
new TQStringList(
256 moduleinfo.
service()->property(
257 "X-TDE-ParentComponents" ).toStringList() );
258 d->moduleParentComponents.insert( module, parentComponents );
259 connect( module, TQT_SIGNAL( changed(
bool ) ), TQT_SLOT( clientChanged(
bool ) ) );
263 void KPluginSelectionWidget::embeddPluginKCMs(
KPluginInfo * plugininfo,
bool checked )
267 TQApplication::setOverrideCursor( Qt::WaitCursor );
272 tabwidget->setEnabled( checked );
274 int id = d->widgetstack->addWidget( tabwidget );
275 d->kps->configPage(
id );
276 d->widgetIDs[ plugininfo->
pluginName() ] = id;
278 for( TQValueList<KService::Ptr>::ConstIterator it =
282 if( !( *it )->noDisplay() )
285 TQWidget * module = insertKCM( tabwidget, moduleinfo );
286 tabwidget->addTab( module, moduleinfo.
moduleName() );
292 if( !plugininfo->
kcmServices().front()->noDisplay() )
296 TQWidget * module = insertKCM( d->widgetstack, moduleinfo );
297 module->setEnabled( checked );
299 int id = d->widgetstack->addWidget( module );
300 d->kps->configPage(
id );
301 d->widgetIDs[ plugininfo->
pluginName() ] = id;
304 TQApplication::restoreOverrideCursor();
307 inline void KPluginSelectionWidget::updateConfigPage()
309 updateConfigPage( d->currentplugininfo, d->currentchecked );
312 void KPluginSelectionWidget::updateConfigPage(
KPluginInfo * plugininfo,
316 d->currentplugininfo = plugininfo;
317 d->currentchecked = checked;
325 if( 0 == plugininfo )
327 d->kps->configPage( 1 );
332 d->kps->configPage( 1 );
335 if( !d->widgetIDs.contains( plugininfo->
pluginName() ) )
337 embeddPluginKCMs( plugininfo, checked );
341 int id = d->widgetIDs[ plugininfo->
pluginName() ];
342 d->kps->configPage(
id );
343 d->widgetstack->widget(
id )->setEnabled( checked );
348 void KPluginSelectionWidget::clientChanged(
bool didchange )
351 d->changed += didchange ? 1 : -1;
352 if( d->changed == 1 )
353 emit changed(
true );
354 else if( d->changed == 0 )
355 emit changed(
false );
356 else if( d->changed < 0 )
357 kdError( 702 ) <<
"negative changed value: " << d->changed <<
endl;
360 void KPluginSelectionWidget::tabWidgetChanged( TQWidget * widget )
371 void KPluginSelectionWidget::executed( TQListViewItem * item )
380 if( item->rtti() != 1 )
383 TQCheckListItem * citem =
static_cast<TQCheckListItem *
>( item );
384 bool checked = citem->isOn();
393 kdDebug( 702 ) <<
"Item changed state, emitting changed()" <<
endl;
395 if( ! d->plugincheckedchanged[ info ] )
398 if ( d->changed == 1 )
399 emit changed(
true );
401 d->plugincheckedchanged[ info ] =
true;
403 checkDependencies( info );
407 if( d->plugincheckedchanged[ info ] )
410 if ( d->changed == 0 )
411 emit changed(
false );
413 d->plugincheckedchanged[ info ] =
false;
417 updateConfigPage( info, checked );
420 void KPluginSelectionWidget::load()
424 for( TQMap<TQCheckListItem*, KPluginInfo*>::Iterator it =
425 d->pluginInfoMap.begin(); it != d->pluginInfoMap.end(); ++it )
428 info->
load( d->config );
430 if( d->visible && info == d->currentplugininfo )
434 for( TQValueList<TDECModuleProxy*>::Iterator it = d->modulelist.begin();
435 it != d->modulelist.end(); ++it )
436 if( ( *it )->changed() )
443 void KPluginSelectionWidget::save()
447 for( TQMap<TQCheckListItem*, KPluginInfo*>::Iterator it =
448 d->pluginInfoMap.begin(); it != d->pluginInfoMap.end(); ++it )
451 bool checked = it.key()->isOn();
453 info->
save( d->config );
454 d->plugincheckedchanged[ info ] =
false;
456 TQStringList updatedModules;
457 for( TQValueList<TDECModuleProxy*>::Iterator it = d->modulelist.begin();
458 it != d->modulelist.end(); ++it )
459 if( ( *it )->changed() )
462 TQStringList * names = d->moduleParentComponents[ *it ];
463 if( names->size() == 0 )
464 names->append( TQString::null );
465 for( TQStringList::ConstIterator nameit = names->begin();
466 nameit != names->end(); ++nameit )
467 if( updatedModules.find( *nameit ) == updatedModules.end() )
468 updatedModules.append( *nameit );
470 for( TQStringList::ConstIterator it = updatedModules.begin(); it != updatedModules.end(); ++it )
471 emit configCommitted( ( *it ).latin1() );
477 emit changed(
false );
480 void KPluginSelectionWidget::checkDependencies(
const KPluginInfo * info )
485 for( TQStringList::ConstIterator it = info->
dependencies().begin();
487 for( TQMap<TQCheckListItem*,
488 KPluginInfo*>::Iterator infoIt = d->pluginInfoMap.begin();
489 infoIt != d->pluginInfoMap.end(); ++infoIt )
490 if( infoIt.data()->pluginName() == *it )
492 if( !infoIt.key()->isOn() )
494 infoIt.key()->setOn(
true );
495 checkDependencies( infoIt.data() );
501 class KPluginSelector::KPluginSelectorPrivate
504 KPluginSelectorPrivate()
508 , hideconfigpage( false )
514 TQWidgetStack * widgetstack;
515 TQValueList<KPluginSelectionWidget *> pswidgets;
520 : TQWidget( parent, name )
521 , d( new KPluginSelectorPrivate )
524 hbox->setAutoAdd(
true );
526 TQSplitter* splitter =
new TQSplitter( Qt::Horizontal,
this );
527 d->frame =
new TQFrame( splitter,
"KPluginSelector left frame" );
528 d->frame->setFrameStyle( TQFrame::NoFrame );
532 d->widgetstack =
new TQWidgetStack( splitter,
"KPluginSelector Config Pages" );
533 d->widgetstack->setFrameStyle( TQFrame::Panel | TQFrame::Sunken );
534 d->widgetstack->setMinimumSize( 200, 200 );
536 TQLabel * label =
new TQLabel( i18n(
"(This plugin is not configurable)" ),
539 label->setAlignment( Qt::AlignCenter );
540 label->setMinimumSize( 200, 200 );
542 d->widgetstack->addWidget( label, 1 );
547 KPluginSelector::~KPluginSelector()
552 void KPluginSelector::checkNeedForTabWidget()
555 if( ! d->tabwidget && d->pswidgets.size() == 1 )
557 kdDebug( 702 ) <<
"no TabWidget and one KPluginSelectionWidget" <<
endl;
559 KPluginSelectionWidget * w = d->pswidgets.first();
564 "KPluginSelector TabWidget" );
565 w->reparent( d->tabwidget, TQPoint( 0, 0 ) );
566 d->tabwidget->addTab( w, w->catName() );
567 connect( d->tabwidget, TQT_SIGNAL( currentChanged( TQWidget * ) ), w,
568 TQT_SLOT( tabWidgetChanged( TQWidget * ) ) );
573 static TQValueList<KPluginInfo*> tdepartsPluginInfos(
const TQString& instanceName )
575 if( instanceName.isNull() )
576 return TQValueList<KPluginInfo*>();
579 instanceName +
"/kpartplugins/*.desktop",
true,
false );
584 const TQString & catname,
const TQString & category,
TDEConfig * config )
586 const TQValueList<KPluginInfo*> plugininfos = tdepartsPluginInfos( instanceName );
587 if ( plugininfos.isEmpty() )
589 checkNeedForTabWidget();
595 addPluginsInternal( plugininfos, catname, category, cfgGroup );
598 void KPluginSelector::addPluginsInternal(
const TQValueList<KPluginInfo*> plugininfos,
599 const TQString & catname,
const TQString & category,
602 KPluginSelectionWidget * w;
605 w =
new KPluginSelectionWidget( plugininfos,
this,
606 d->tabwidget, catname, category, cfgGroup );
607 d->tabwidget->addTab( w, catname );
608 connect( d->tabwidget, TQT_SIGNAL( currentChanged( TQWidget * ) ), w,
609 TQT_SLOT( tabWidgetChanged( TQWidget * ) ) );
612 w =
new KPluginSelectionWidget( plugininfos,
this, d->frame,
613 catname, category, cfgGroup );
614 w->setMinimumSize( 200, 200 );
615 connect( w, TQT_SIGNAL(
changed(
bool ) ),
this, TQT_SIGNAL(
changed(
bool ) ) );
622 catname,
const TQString & category,
TDEConfig * config )
625 config = instance->
config();
630 const TQString & catname,
const TQString & category,
TDEConfig * config )
632 checkNeedForTabWidget();
636 addPluginsInternal( plugininfos, catname, category, cfgGroup );
639 TQWidgetStack * KPluginSelector::widgetStack()
641 return d->widgetstack;
644 inline void KPluginSelector::configPage(
int id )
649 if( d->hideconfigpage )
651 d->widgetstack->hide();
656 d->widgetstack->show();
658 d->widgetstack->raiseWidget(
id );
663 d->hideconfigpage = !show;
664 if( d->hideconfigpage )
665 if( d->widgetstack->id( d->widgetstack->visibleWidget() ) == 1 )
666 d->widgetstack->hide();
671 for( TQValueList<KPluginSelectionWidget *>::Iterator it =
672 d->pswidgets.begin(); it != d->pswidgets.end(); ++it )
680 for( TQValueList<KPluginSelectionWidget *>::Iterator it =
681 d->pswidgets.begin(); it != d->pswidgets.end(); ++it )
698 TQWidget * pluginconfig = d->widgetstack->visibleWidget();
702 kdDebug( 702 ) <<
"call TDECModule::defaults() for the plugins KCM"
710 TQObjectList * kcms = pluginconfig->queryList(
"TDECModuleProxy",
712 TQObjectListIt it( *kcms );
714 while( ( obj = it.current() ) != 0 )
722 #include "kpluginselector.moc"
723 #include "kpluginselector_p.moc"