2 * Copyright (C) 2002-2003 Leo Savernik
4 * Copyright (C) 2001, Daniel Naber
5 * based on javaopts.cpp
6 * Copyright (C) 2000 Stefan Schimanski <1Stein@gmx.de>
12 #include "pluginopts.h"
20 #include <QtCore/QRegExp>
21 #include <QtCore/QTextStream>
22 #include <QtDBus/QDBusConnection>
23 #include <QtDBus/QDBusMessage>
24 #include <QtGui/QLabel>
25 #include <QtGui/QLayout>
26 #include <QtGui/QSlider>
27 #include <QtGui/QTreeWidget>
31 #include <kapplication.h>
33 #include <kfiledialog.h>
34 #include <kiconloader.h>
36 #include <kmessagebox.h>
37 #include <kstandarddirs.h>
38 #include <kurlrequester.h>
39 #include <KPluginFactory>
40 #include <KPluginLoader>
41 #include <KProgressDialog>
45 #include "ui_nsconfigwidget.h"
46 #include "policydlg.h"
48 // == class PluginPolicies =====
50 PluginPolicies::PluginPolicies(KSharedConfig::Ptr config
, const QString
&group
, bool global
,
51 const QString
&domain
) :
52 Policies(config
,group
,global
,domain
,"plugins.","EnablePlugins") {
55 PluginPolicies::~PluginPolicies() {
58 // == class KPluginOptions =====
60 K_PLUGIN_FACTORY_DECLARATION(KcmKonqHtmlFactory
)
62 KPluginOptions::KPluginOptions( QWidget
*parent
, const QVariantList
& )
63 : KCModule( KcmKonqHtmlFactory::componentData(), parent
),
64 m_pConfig( KSharedConfig::openConfig("konquerorrc", KConfig::NoGlobals
) ),
65 m_groupname( "Java/JavaScript Settings" ),
66 global_policies(m_pConfig
,m_groupname
,true)
68 QVBoxLayout
* toplevel
= new QVBoxLayout( this );
70 QTabWidget
* topleveltab
= new QTabWidget( this );
71 toplevel
->addWidget( topleveltab
);
73 QWidget
* globalGB
= new QWidget( topleveltab
);
74 topleveltab
->addTab( globalGB
, i18n( "Global Settings" ) );
76 /**************************************************************************
77 ******************** Global Settings *************************************
78 *************************************************************************/
79 enablePluginsGloballyCB
= new QCheckBox( i18n( "&Enable plugins globally" ), globalGB
);
80 enableHTTPOnly
= new QCheckBox( i18n( "Only allow &HTTP and HTTPS URLs for plugins" ), globalGB
);
81 enableUserDemand
= new QCheckBox( i18n( "&Load plugins on demand only" ), globalGB
);
82 priorityLabel
= new QLabel(i18n("CPU priority for plugins: %1", QString()), globalGB
);
83 //priority = new QSlider(5, 100, 5, 100, Qt::Horizontal, globalGB);
84 priority
= new QSlider(Qt::Horizontal
, globalGB
);
85 priority
->setMinimum(5);
86 priority
->setMaximum(100);
87 priority
->setPageStep(5);
89 QVBoxLayout
*vbox
= new QVBoxLayout
;
90 vbox
->addWidget(enablePluginsGloballyCB
);
91 vbox
->addWidget(enableHTTPOnly
);
92 vbox
->addWidget(enableUserDemand
);
93 vbox
->addWidget(priorityLabel
);
94 vbox
->addWidget(priority
);
96 connect( enablePluginsGloballyCB
, SIGNAL( clicked() ), this, SLOT( slotChanged() ) );
97 connect( enablePluginsGloballyCB
, SIGNAL( clicked() ), this, SLOT( slotTogglePluginsEnabled() ) );
98 connect( enableHTTPOnly
, SIGNAL( clicked() ), this, SLOT( slotChanged() ) );
99 connect( enableUserDemand
, SIGNAL( clicked() ), this, SLOT( slotChanged() ) );
100 connect( priority
, SIGNAL( valueChanged(int) ), this, SLOT( slotChanged() ) );
101 connect( priority
, SIGNAL( valueChanged(int) ), this, SLOT( updatePLabel(int) ) );
103 QFrame
*hrule
= new QFrame(globalGB
);
104 hrule
->setFrameStyle(QFrame::HLine
| QFrame::Sunken
);
105 hrule
->setSizePolicy(QSizePolicy::MinimumExpanding
,QSizePolicy::Fixed
);
107 /**************************************************************************
108 ********************* Domain-specific Settings ***************************
109 *************************************************************************/
110 QPushButton
*domainSpecPB
= new QPushButton(i18n("Domain-Specific Settin&gs"),
112 domainSpecPB
->setSizePolicy(QSizePolicy::Fixed
,QSizePolicy::Fixed
);
113 connect(domainSpecPB
,SIGNAL(clicked()),SLOT(slotShowDomainDlg()));
115 vbox
->addWidget(hrule
);
116 vbox
->addWidget(domainSpecPB
);
118 globalGB
->setLayout(vbox
);
120 vbox
->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum
, QSizePolicy::MinimumExpanding
));
122 domainSpecificDlg
= new KDialog( this );
123 domainSpecificDlg
->setCaption( i18n("Domain-Specific Policies") );
124 domainSpecificDlg
->setButtons( KDialog::Close
);
125 domainSpecificDlg
->setDefaultButton( KDialog::Close
);
126 domainSpecificDlg
->setObjectName( "domainSpecificDlg" );
127 domainSpecificDlg
->setModal( true );
129 domainSpecific
= new PluginDomainListView(m_pConfig
,m_groupname
,this,domainSpecificDlg
);
130 domainSpecific
->setMinimumSize(320,200);
131 connect(domainSpecific
,SIGNAL(changed(bool)),SLOT(slotChanged()));
133 domainSpecificDlg
->setMainWidget(domainSpecific
);
135 /**************************************************************************
136 ********************** WhatsThis? items **********************************
137 *************************************************************************/
138 enablePluginsGloballyCB
->setWhatsThis( i18n("Enables the execution of plugins "
139 "that can be contained in HTML pages, e.g. Macromedia Flash. "
140 "Note that, as with any browser, enabling active contents can be a security problem.") );
142 QString wtstr
= i18n("<p>This box contains the domains and hosts you have set "
143 "a specific plugin policy for. This policy will be used "
144 "instead of the default policy for enabling or disabling plugins on pages sent by these "
145 "domains or hosts.</p><p>Select a policy and use the controls on "
146 "the right to modify it.</p>");
147 domainSpecific
->listView()->setWhatsThis( wtstr
);
148 domainSpecific
->importButton()->setWhatsThis( i18n("Click this button to choose the file that contains "
149 "the plugin policies. These policies will be merged "
150 "with the existing ones. Duplicate entries are ignored.") );
151 domainSpecific
->exportButton()->setWhatsThis( i18n("Click this button to save the plugin policy to a zipped "
152 "file. The file, named <b>plugin_policy.tgz</b>, will be "
153 "saved to a location of your choice." ) );
154 domainSpecific
->setWhatsThis( i18n("Here you can set specific plugin policies for any particular "
155 "host or domain. To add a new policy, simply click the <i>New...</i> "
156 "button and supply the necessary information requested by the "
157 "dialog box. To change an existing policy, click on the <i>Change...</i> "
158 "button and choose the new policy from the policy dialog box. Clicking "
159 "on the <i>Delete</i> button will remove the selected policy causing the default "
160 "policy setting to be used for that domain.") );
162 "The <i>Import</i> and <i>Export</i> "
163 "button allows you to easily share your policies with other people by allowing "
164 "you to save and retrieve them from a zipped file.") );
167 /*****************************************************************************/
169 QWidget
* pluginsSettingsContainer
= new QWidget( topleveltab
);
170 topleveltab
->addTab( pluginsSettingsContainer
, i18n( "Plugins" ) );
172 // create Designer made widget
173 m_widget
= new Ui::NSConfigWidget();
174 m_widget
->setupUi( pluginsSettingsContainer
);
175 pluginsSettingsContainer
->setObjectName( "configwidget" );
176 m_widget
->dirEdit
->setMode(KFile::ExistingOnly
| KFile::LocalOnly
| KFile::Directory
);
179 connect( m_widget
->scanButton
, SIGNAL(clicked()), SLOT(scan()) );
188 void KPluginOptions::updatePLabel(int p
) {
192 level
= i18nc("lowest priority", "lowest");
194 level
= i18nc("low priority", "low");
196 level
= i18nc("medium priority", "medium");
198 level
= i18nc("high priority", "high");
200 level
= i18nc("highest priority", "highest");
203 priorityLabel
->setText(i18n("CPU priority for plugins: %1", level
));
207 void KPluginOptions::load()
210 global_policies
.load();
211 bool bPluginGlobal
= global_policies
.isFeatureEnabled();
213 // *** apply to GUI ***
214 enablePluginsGloballyCB
->setChecked( bPluginGlobal
);
216 domainSpecific
->initialize(m_pConfig
->group(m_groupname
).readEntry("PluginDomains", QStringList() ));
218 /****************************************************************************/
220 KSharedConfig::Ptr config
= KSharedConfig::openConfig("kcmnspluginrc");
221 KConfigGroup
cg(config
, "Misc");
223 m_widget
->dirEdit
->setUrl(KUrl());
224 m_widget
->dirEdit
->setEnabled( false );
225 m_widget
->dirRemove
->setEnabled( false );
226 m_widget
->dirUp
->setEnabled( false );
227 m_widget
->dirDown
->setEnabled( false );
228 enableHTTPOnly
->setChecked( cg
.readEntry("HTTP URLs Only", false) );
229 enableUserDemand
->setChecked( cg
.readEntry("demandLoad", false) );
230 priority
->setValue(100 - qBound(0, cg
.readEntry("Nice Level", 0), 19) * 5);
231 updatePLabel(priority
->value());
234 pluginLoad( config
);
239 void KPluginOptions::defaults()
241 global_policies
.defaults();
242 enablePluginsGloballyCB
->setChecked( global_policies
.isFeatureEnabled() );
243 enableHTTPOnly
->setChecked(false);
244 enableUserDemand
->setChecked(false);
245 priority
->setValue(100);
247 /*****************************************************************************/
249 KSharedConfig::Ptr config
= KSharedConfig::openConfig( QString(), KConfig::NoGlobals
);
251 m_widget
->dirEdit
->setUrl(KUrl());
252 m_widget
->dirEdit
->setEnabled( false );
253 m_widget
->dirRemove
->setEnabled( false );
255 dirLoad( config
, true );
256 pluginLoad( config
);
261 void KPluginOptions::save()
263 global_policies
.save();
265 domainSpecific
->save(m_groupname
,"PluginDomains");
267 m_pConfig
->sync(); // I need a sync here, otherwise "apply" won't work
269 // Send signal to all konqueror instances
270 QDBusMessage message
=
271 QDBusMessage::createSignal("/KonqMain", "org.kde.Konqueror.Main", "reparseConfiguration");
272 QDBusConnection::sessionBus().send(message
);
274 /*****************************************************************************/
276 KSharedConfig::Ptr config
= KSharedConfig::openConfig("kcmnspluginrc");
279 pluginSave( config
);
281 KConfigGroup
cg(config
, "Misc");
282 cg
.writeEntry( "HTTP URLs Only", enableHTTPOnly
->isChecked() );
283 cg
.writeEntry( "demandLoad", enableUserDemand
->isChecked() );
284 cg
.writeEntry("Nice Level", (int)(100 - priority
->value()) / 5);
290 QString
KPluginOptions::quickHelp() const
292 return i18n("<h1>Konqueror Plugins</h1> The Konqueror web browser can use Netscape"
293 " plugins to show special content, just like the Navigator does. Please note that"
294 " the way you have to install Netscape plugins may depend on your distribution. A typical"
295 " place to install them is, for example, '/opt/netscape/plugins'.");
298 void KPluginOptions::slotChanged()
303 void KPluginOptions::slotTogglePluginsEnabled() {
304 global_policies
.setFeatureEnabled(enablePluginsGloballyCB
->isChecked());
307 void KPluginOptions::slotShowDomainDlg() {
308 domainSpecificDlg
->show();
311 /***********************************************************************************/
313 void KPluginOptions::scan()
315 m_widget
->scanButton
->setEnabled(false);
317 int ret
= KMessageBox::warningYesNoCancel( this,
318 i18n("Do you want to apply your changes "
319 "before the scan? Otherwise the "
320 "changes will be lost."), QString(), KStandardGuiItem::save(), KStandardGuiItem::discard() );
321 if ( ret
==KMessageBox::Cancel
) {
322 m_widget
->scanButton
->setEnabled(true);
325 if ( ret
==KMessageBox::Yes
)
329 nspluginscan
= new KProcess(this);
330 nspluginscan
->setOutputChannelMode(KProcess::SeparateChannels
);
331 QString scanExe
= KGlobal::dirs()->findExe("nspluginscan");
332 if (scanExe
.isEmpty()) {
333 kDebug() << "can't find nspluginviewer";
335 KMessageBox::sorry ( this,
336 i18n("The nspluginscan executable cannot be found. "
337 "Netscape plugins will not be scanned.") );
338 m_widget
->scanButton
->setEnabled(true);
342 // find nspluginscan executable
343 m_progress
= new KProgressDialog( this, QString(), i18n("Scanning for plugins") );
344 m_progress
->progressBar()->setValue( 5 );
346 // start nspluginscan
347 *nspluginscan
<< scanExe
<< "--verbose";
348 kDebug() << "Running nspluginscan";
349 connect(nspluginscan
, SIGNAL(readyReadStandardOutput()),
350 this, SLOT(progress()));
351 connect(nspluginscan
, SIGNAL(finished(int, QProcess::ExitStatus
)),
352 this, SLOT(scanDone()));
353 connect(m_progress
, SIGNAL(cancelClicked()), this, SLOT(scanDone()));
355 nspluginscan
->start();
358 void KPluginOptions::progress()
360 // we do not know if the output array ends in the middle of an utf-8 sequence
361 m_output
+= nspluginscan
->readAllStandardOutput();
364 while ((pos
= m_output
.indexOf('\n')) != -1) {
365 line
= QString::fromLocal8Bit(m_output
, pos
+ 1);
366 m_output
.remove(0, pos
+ 1);
368 m_progress
->progressBar()->setValue(line
.trimmed().toInt());
371 void KPluginOptions::scanDone()
375 m_progress
->progressBar()->setValue(100);
377 m_progress
->deleteLater();
380 m_widget
->scanButton
->setEnabled(true);
383 /***********************************************************************************/
386 void KPluginOptions::dirInit()
388 m_widget
->dirEdit
->setWindowTitle(i18n("Select Plugin Scan Folder"));
389 connect( m_widget
->dirNew
, SIGNAL(clicked()), SLOT(dirNew()));
390 connect( m_widget
->dirRemove
, SIGNAL(clicked()), SLOT(dirRemove()));
391 connect( m_widget
->dirUp
, SIGNAL(clicked()), SLOT(dirUp()));
392 connect( m_widget
->dirDown
, SIGNAL(clicked()), SLOT(dirDown()) );
393 connect( m_widget
->dirEdit
,
394 SIGNAL(textChanged(const QString
&)),
395 SLOT(dirEdited(const QString
&)) );
397 connect( m_widget
->dirList
,
398 SIGNAL(executed(QListWidgetItem
*)),
399 SLOT(dirSelect(QListWidgetItem
*)) );
401 connect( m_widget
->dirList
,
402 SIGNAL(itemChanged(QListWidgetItem
*)),
403 SLOT(dirSelect(QListWidgetItem
*)) );
407 void KPluginOptions::dirLoad( KSharedConfig::Ptr config
, bool useDefault
)
413 KConfigGroup
cg(config
, "Misc");
414 if ( cg
.hasKey( "scanPaths" ) && !useDefault
)
415 paths
= cg
.readEntry( "scanPaths" , QStringList() );
416 else {//keep sync with kdebase/apps/nsplugins
417 paths
.append("$HOME/.mozilla/plugins");
418 paths
.append("$HOME/.netscape/plugins");
419 paths
.append("/usr/lib/firefox/plugins");
420 paths
.append("/usr/lib64/browser-plugins");
421 paths
.append("/usr/lib/browser-plugins");
422 paths
.append("/usr/local/netscape/plugins");
423 paths
.append("/opt/mozilla/plugins");
424 paths
.append("/opt/mozilla/lib/plugins");
425 paths
.append("/opt/netscape/plugins");
426 paths
.append("/opt/netscape/communicator/plugins");
427 paths
.append("/usr/lib/netscape/plugins");
428 paths
.append("/usr/lib/netscape/plugins-libc5");
429 paths
.append("/usr/lib/netscape/plugins-libc6");
430 paths
.append("/usr/lib/mozilla/plugins");
431 paths
.append("/usr/lib64/netscape/plugins");
432 paths
.append("/usr/lib64/mozilla/plugins");
433 paths
.append("$MOZILLA_HOME/plugins");
437 m_widget
->dirList
->clear();
438 m_widget
->dirList
->addItems( paths
);
443 void KPluginOptions::dirSave( KSharedConfig::Ptr config
)
448 for ( int rowIndex
= 0 ; rowIndex
< m_widget
->dirList
->count() ; rowIndex
++ ) {
449 if ( !m_widget
->dirList
->item(rowIndex
)->text().isEmpty() )
450 paths
<< m_widget
->dirList
->item(rowIndex
)->text();
454 KConfigGroup
cg(config
, "Misc");
455 cg
.writeEntry( "scanPaths", paths
);
459 void KPluginOptions::dirSelect( QListWidgetItem
*item
)
461 m_widget
->dirEdit
->setEnabled( item
!=0 );
462 m_widget
->dirRemove
->setEnabled( item
!=0 );
464 int cur
= m_widget
->dirList
->currentRow();
465 m_widget
->dirDown
->setEnabled( item
!=0 && cur
<m_widget
->dirList
->count()-1 );
466 m_widget
->dirUp
->setEnabled( item
!=0 && cur
>0 );
467 m_widget
->dirEdit
->setUrl( item
!=0 ? item
->text() : QString() );
471 void KPluginOptions::dirNew()
473 m_widget
->dirList
->insertItem( 0 , QString() );
474 m_widget
->dirList
->setCurrentRow( 0 );
475 dirSelect( m_widget
->dirList
->currentItem() );
476 m_widget
->dirEdit
->setUrl(QString());
477 m_widget
->dirEdit
->setFocus();
482 void KPluginOptions::dirRemove()
484 m_widget
->dirEdit
->setUrl(QString());
485 delete m_widget
->dirList
->currentItem();
486 m_widget
->dirRemove
->setEnabled( false );
487 m_widget
->dirUp
->setEnabled( false );
488 m_widget
->dirDown
->setEnabled( false );
489 m_widget
->dirEdit
->setEnabled( false );
494 void KPluginOptions::dirUp()
496 int cur
= m_widget
->dirList
->currentRow();
498 QString txt
= m_widget
->dirList
->item(cur
-1)->text();
499 delete m_widget
->dirList
->takeItem( cur
-1 );
500 m_widget
->dirList
->insertItem( cur
, txt
);
502 m_widget
->dirUp
->setEnabled( cur
-1>0 );
503 m_widget
->dirDown
->setEnabled( true );
509 void KPluginOptions::dirDown()
511 int cur
= m_widget
->dirList
->currentRow();
512 if ( cur
< m_widget
->dirList
->count()-1 ) {
513 QString txt
= m_widget
->dirList
->item(cur
+1)->text();
514 delete m_widget
->dirList
->takeItem( cur
+1 );
515 m_widget
->dirList
->insertItem( cur
, txt
);
517 m_widget
->dirUp
->setEnabled( true );
518 m_widget
->dirDown
->setEnabled( cur
+1<m_widget
->dirList
->count()-1 );
524 void KPluginOptions::dirEdited(const QString
&txt
)
526 if ( m_widget
->dirList
->currentItem()->text() != txt
) {
527 m_widget
->dirList
->blockSignals(true);
528 m_widget
->dirList
->currentItem()->setText(txt
);
529 m_widget
->dirList
->blockSignals(false);
535 /***********************************************************************************/
538 void KPluginOptions::pluginInit()
543 void KPluginOptions::pluginLoad( KSharedConfig::Ptr
/*config*/ )
545 m_widget
->pluginList
->setRootIsDecorated(false);
546 m_widget
->pluginList
->setColumnWidth( 0, 200 );
547 kDebug() << "-> KPluginOptions::fillPluginList";
548 m_widget
->pluginList
->clear();
549 QRegExp
version(";version=[^:]*:");
551 // open the cache file
552 QFile
cachef( KStandardDirs::locate("data", "nsplugins/cache") );
553 if ( !cachef
.exists() || !cachef
.open(QIODevice::ReadOnly
) ) {
554 kDebug() << "Could not load plugin cache file!";
558 QTextStream
cache(&cachef
);
561 QTreeWidgetItem
*root
= new QTreeWidgetItem( m_widget
->pluginList
, QStringList() << i18n("Netscape Plugins") );
562 root
->setFlags( Qt::ItemIsEnabled
);
563 root
->setExpanded( true );
564 root
->setIcon(0, KIcon("netscape"));
567 QString line
, plugin
;
568 QTreeWidgetItem
*next
= 0;
569 QTreeWidgetItem
*lastMIME
= 0;
570 while ( !cache
.atEnd() ) {
572 line
= cache
.readLine();
574 if (line
.isEmpty() || (line
.left(1) == "#"))
577 if (line
.left(1) == "[") {
579 plugin
= line
.mid(1,line
.length()-2);
580 //kDebug() << "plugin=" << plugin;
582 // add plugin root item
583 next
= new QTreeWidgetItem( root
, QStringList() << i18n("Plugin") << plugin
);
584 next
->setFlags( Qt::ItemIsEnabled
);
591 const QStringList desc
= line
.split(':');
592 // avoid crash on broken lines
596 QString mime
= desc
[0].trimmed();
599 if (desc
.count() > 2)
601 if (desc
.count() > 1)
604 if (!mime
.isEmpty() && next
) {
605 //kDebug() << "mime=" << mime << " desc=" << name << " suffix=" << suffixes;
606 lastMIME
= new QTreeWidgetItem( next
, QStringList() << i18n("MIME type") << mime
);
607 lastMIME
->setFlags( Qt::ItemIsEnabled
);
609 QTreeWidgetItem
*last
= new QTreeWidgetItem( lastMIME
, QStringList() << i18n("Description") << name
);
610 last
->setFlags( Qt::ItemIsEnabled
);
612 last
= new QTreeWidgetItem( lastMIME
, QStringList() << i18n("Suffixes") << suffixes
);
613 last
->setFlags( Qt::ItemIsEnabled
);
617 //kDebug() << "<- KPluginOptions::fillPluginList";
621 void KPluginOptions::pluginSave( KSharedConfig::Ptr
/*config*/ )
626 // == class PluginDomainDialog =====
628 PluginDomainDialog::PluginDomainDialog(QWidget
*parent
) :
631 setObjectName("PluginDomainDialog");
632 setWindowTitle(i18n("Domain-Specific Policies"));
634 thisLayout
= new QVBoxLayout(this);
635 thisLayout
->addSpacing(6);
636 QFrame
*hrule
= new QFrame(this);
637 hrule
->setFrameStyle(QFrame::HLine
| QFrame::Sunken
);
638 thisLayout
->addWidget(hrule
);
639 thisLayout
->addSpacing(6);
641 QBoxLayout
*hl
= new QHBoxLayout(this);
646 QPushButton
*closePB
= new KPushButton(KStandardGuiItem::close(),this);
647 connect(closePB
,SIGNAL(clicked()),SLOT(slotClose()));
648 hl
->addWidget(closePB
);
649 thisLayout
->addLayout(hl
);
652 PluginDomainDialog::~PluginDomainDialog() {
655 void PluginDomainDialog::setMainWidget(QWidget
*widget
) {
656 thisLayout
->insertWidget(0,widget
);
659 void PluginDomainDialog::slotClose() {
663 // == class PluginDomainListView =====
665 PluginDomainListView::PluginDomainListView(KSharedConfig::Ptr config
,const QString
&group
,
666 KPluginOptions
*options
,QWidget
*parent
)
667 : DomainListView(config
,i18n( "Doma&in-Specific" ), parent
),
668 group(group
), options(options
) {
671 PluginDomainListView::~PluginDomainListView() {
674 void PluginDomainListView::setupPolicyDlg(PushButton trigger
,PolicyDialog
&pDlg
,
679 caption
= i18n( "New Plugin Policy" );
680 pol
->setFeatureEnabled(!options
->enablePluginsGloballyCB
->isChecked());
682 case ChangeButton
: caption
= i18n( "Change Plugin Policy" ); break;
683 default: ; // inhibit gcc warning
685 pDlg
.setWindowTitle(caption
);
686 pDlg
.setFeatureEnabledLabel(i18n("&Plugin policy:"));
687 pDlg
.setFeatureEnabledWhatsThis(i18n("Select a plugin policy for "
688 "the above host or domain."));
692 PluginPolicies
*PluginDomainListView::createPolicies() {
693 return new PluginPolicies(config
,group
,false);
696 PluginPolicies
*PluginDomainListView::copyPolicies(Policies
*pol
) {
697 return new PluginPolicies(*static_cast<PluginPolicies
*>(pol
));
700 #include "pluginopts.moc"