Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / nsplugins / plugin_part.cpp
blob7cd43163b3761181d2827127087f87b8c3ee7fa9
1 /*
2 Netscape Plugin Loader KPart
4 Copyright (c) 2000 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
5 Stefan Schimanski <1Stein@gmx.de>
6 Copyright (c) 2002-2005 George Staikos <staikos@kde.org>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 #include "plugin_part.h"
24 #include "nspluginloader.h"
25 #include "callbackadaptor.h"
27 #include <kaboutdata.h>
28 #include <kaction.h>
29 #include <kactioncollection.h>
30 #include <kapplication.h>
31 #include <kdebug.h>
32 #include <kfiledialog.h>
33 #include <kio/netaccess.h>
34 #include <klocale.h>
35 #include <kparts/browserinterface.h>
36 #include <kparts/browserextension.h>
38 #include <QLabel>
41 class PluginBrowserExtension : public KParts::BrowserExtension
43 friend class PluginPart;
44 public:
45 PluginBrowserExtension( KParts::ReadOnlyPart *parent )
46 : KParts::BrowserExtension( parent ) {}
47 ~PluginBrowserExtension() {}
49 // ATTENTION: you -CANNOT- add data members here
53 PluginLiveConnectExtension::PluginLiveConnectExtension(PluginPart* part)
54 : KParts::LiveConnectExtension(part), _part(part), _retval(0L) {
57 PluginLiveConnectExtension::~PluginLiveConnectExtension() {
60 bool PluginLiveConnectExtension::get(const unsigned long, const QString &field, Type &type, unsigned long &retobj, QString &value) {
61 Q_UNUSED(type);
62 Q_UNUSED(retobj);
63 Q_UNUSED(value);
64 kDebug(1432) << "PLUGIN:LiveConnect::get " << field;
65 return false;
68 bool PluginLiveConnectExtension::call(const unsigned long, const QString &func, const QStringList &args, Type &type, unsigned long &retobjid, QString &value) {
69 Q_UNUSED(type);
70 Q_UNUSED(retobjid);
71 Q_UNUSED(value);
72 kDebug(1432) << "PLUGIN:LiveConnect::call " << func << " args: " << args;
73 return false;
76 bool PluginLiveConnectExtension::put( const unsigned long, const QString &field, const QString &value) {
77 kDebug(1432) << "PLUGIN:LiveConnect::put " << field << " " << value;
78 if (_retval && field == "__nsplugin") {
79 *_retval = value;
80 return true;
81 } else if (field.toLower() == "src") {
82 _part->changeSrc(value);
83 return true;
85 return false;
88 QString PluginLiveConnectExtension::evalJavaScript( const QString & script )
90 kDebug(1432) << "PLUGIN:LiveConnect::evalJavaScript " << script;
91 ArgList args;
92 QString jscode;
93 jscode.sprintf("this.__nsplugin=eval(\"%s\")", qPrintable( QString(script).replace('\\', "\\\\").replace('"', "\\\"")));
94 //kDebug(1432) << "String is [" << jscode << "]";
95 args.push_back(qMakePair(KParts::LiveConnectExtension::TypeString, jscode));
96 QString nsplugin("Undefined");
97 _retval = &nsplugin;
98 emit partEvent(0, "eval", args);
99 _retval = 0L;
100 return nsplugin;
103 K_EXPORT_PLUGIN(PluginFactory)
106 * We need one static instance of the factory for our C 'main'
107 * function
109 KComponentData *PluginFactory::s_instance = 0L;
112 PluginFactory::PluginFactory()
114 kDebug(1432) << "PluginFactory::PluginFactory";
115 s_instance = 0;
117 // preload plugin loader
118 _loader = NSPluginLoader::instance();
122 PluginFactory::~PluginFactory()
124 kDebug(1432) << "PluginFactory::~PluginFactory";
126 _loader->release();
128 if (s_instance) {
129 delete s_instance;
130 s_instance = 0;
134 KParts::Part * PluginFactory::createPartObject(QWidget *parentWidget, QObject *parent,
135 const char *classname, const QStringList &args)
137 Q_UNUSED(classname)
138 kDebug(1432) << "PluginFactory::create";
139 KParts::Part *obj = new PluginPart(parentWidget, parent, args);
140 return obj;
144 const KComponentData &PluginFactory::componentData()
146 kDebug(1432) << "PluginFactory::instance";
148 if (!s_instance) {
149 KAboutData about("plugin", 0, ki18n("plugin"), "1.99");
150 s_instance = new KComponentData(about);
152 return *s_instance;
156 /**************************************************************************/
158 static int s_callBackObjectCounter;
160 PluginPart::PluginPart(QWidget *parentWidget, QObject *parent, const QStringList &args)
161 : KParts::ReadOnlyPart(parent), _widget(0), _args(args),
162 _destructed(0L)
164 callbackPath = QString::fromLatin1("/Callback") + QString::number(s_callBackObjectCounter);
165 ++s_callBackObjectCounter;
166 (void) new CallBackAdaptor( this );
167 QDBusConnection::sessionBus().registerObject( callbackPath, this );
169 setComponentData(PluginFactory::componentData());
170 kDebug(1432) << "PluginPart::PluginPart";
172 // we have to keep the class name of KParts::PluginBrowserExtension
173 // to let khtml find it
174 _extension = static_cast<PluginBrowserExtension*>(new KParts::BrowserExtension(this));
175 _liveconnect = new PluginLiveConnectExtension(this);
177 // Only create this if we have no parent since the parent part is
178 // responsible for "Save As" then
179 if (!parent || !parent->inherits("Part")) {
180 KAction *action = actionCollection()->addAction("saveDocument");
181 action->setText(i18n("&Save As..."));
182 connect(action, SIGNAL(triggered(bool) ), SLOT(saveAs()));
183 action->setShortcut(Qt::CTRL+Qt::Key_S);
184 setXMLFile("nspluginpart.rc");
187 // create
188 _loader = NSPluginLoader::instance();
190 // create a canvas to insert our widget
191 _canvas = new PluginCanvasWidget( parentWidget );
192 //_canvas->setFocusPolicy( QWidget::ClickFocus );
193 _canvas->setFocusPolicy( Qt::WheelFocus );
194 setWidget(_canvas);
195 _canvas->show();
196 QObject::connect( _canvas, SIGNAL(resized(int,int)),
197 this, SLOT(pluginResized(int,int)) );
201 PluginPart::~PluginPart()
203 kDebug(1432) << "PluginPart::~PluginPart";
205 _loader->release();
206 if (_destructed)
207 *_destructed = true;
211 bool PluginPart::openUrl(const KUrl &url)
213 closeUrl();
214 kDebug(1432) << "-> PluginPart::openUrl";
216 setUrl(url);
217 QString surl = url.url();
218 QString smime = arguments().mimeType();
219 bool reload = arguments().reload();
220 bool embed = false;
222 // handle arguments
223 QStringList argn, argv;
225 QStringList::const_iterator it = _args.constBegin();
226 for ( ; it != _args.constEnd(); ) {
228 int equalPos = (*it).indexOf("=");
229 if (equalPos>0) {
231 QString name = (*it).left(equalPos).toUpper();
232 QString value = (*it).mid(equalPos+1);
233 if (value[0] == '"' && value[value.length()-1] == '"')
234 value = value.mid(1, value.length()-2);
236 kDebug(1432) << "name=" << name << " value=" << value;
238 if (!name.isEmpty()) {
239 // hack to pass view mode from khtml
240 if ( name=="__KHTML__PLUGINEMBED" ) {
241 embed = true;
242 kDebug(1432) << "__KHTML__PLUGINEMBED found";
243 } else {
244 argn << name;
245 argv << value;
250 it++;
253 if (surl.isEmpty()) {
254 kDebug(1432) << "<- PluginPart::openUrl - false (no url passed to nsplugin)";
255 return false;
258 // status messages
259 emit setWindowCaption( url.prettyUrl() );
260 emit setStatusBarText( i18n("Loading Netscape plugin for %1", url.prettyUrl()) );
262 // create plugin widget
263 NSPluginInstance *inst = _loader->newInstance( _canvas, surl, smime, embed,
264 argn, argv,
265 QDBusConnection::sessionBus().baseService(),
266 callbackPath, reload);
268 if ( inst ) {
269 _widget = inst;
270 _nspWidget = inst;
271 } else {
272 QLabel *label = new QLabel( i18n("Unable to load Netscape plugin for %1", url.url()), _canvas );
273 label->setAlignment( Qt::AlignCenter );
274 label->setWordWrap( true );
275 _widget = label;
278 _widget->resize(_canvas->width(), _canvas->height());
279 _widget->show();
281 kDebug(1432) << "<- PluginPart::openUrl = " << (inst!=0);
282 return inst != 0L;
286 bool PluginPart::closeUrl()
288 kDebug(1432) << "PluginPart::closeUrl";
289 delete _widget;
290 _widget = 0;
291 return true;
295 void PluginPart::reloadPage()
297 kDebug(1432) << "PluginPart::reloadPage()";
298 _extension->browserInterface()->callMethod("goHistory", 0);
301 void PluginPart::postURL(const QString& url, const QString& target, const QByteArray& data, const QString& mime)
303 kDebug(1432) << "PluginPart::postURL( url=" << url
304 << ", target=" << target << endl;
306 KUrl new_url(this->url(), url);
307 KParts::OpenUrlArguments arguments;
308 KParts::BrowserArguments browserArguments;
309 browserArguments.setDoPost(true);
310 browserArguments.frameName = target;
311 browserArguments.postData = data;
312 browserArguments.setContentType(mime);
314 emit _extension->openUrlRequest(new_url, arguments, browserArguments);
317 void PluginPart::requestURL(const QString& url, const QString& target)
319 kDebug(1432) << "PluginPart::requestURL( url=" << url
320 << ", target=" << target << endl;
322 KUrl new_url(this->url(), url);
323 KParts::OpenUrlArguments arguments;
324 KParts::BrowserArguments browserArguments;
325 browserArguments.frameName = target;
326 browserArguments.setDoPost(false);
328 emit _extension->openUrlRequest(new_url, arguments, browserArguments);
331 void PluginPart::evalJavaScript(int id, const QString & script)
333 kDebug(1432) <<"evalJavascript: before widget check";
334 if (_widget) {
335 bool destructed = false;
336 _destructed = &destructed;
337 kDebug(1432) <<"evalJavascript: there is a widget:";
338 QString rc = _liveconnect->evalJavaScript(script);
339 if (destructed)
340 return;
341 _destructed = 0L;
342 kDebug(1432) << "Liveconnect: script [" << script << "] evaluated to [" << rc << "]";
343 NSPluginInstance *ni = dynamic_cast<NSPluginInstance*>(_widget.operator->());
344 if (ni)
345 ni->javascriptResult(id, rc);
349 void PluginPart::statusMessage(const QString &msg)
351 kDebug(1422) << "PluginPart::statusMessage " << msg;
352 emit setStatusBarText(msg);
356 void PluginPart::pluginResized(int w, int h)
358 if (_nspWidget)
359 _nspWidget->pluginResized(w, h);
361 if (_widget) {
362 _widget->resize(w, h);
367 void PluginPart::changeSrc(const QString& url) {
368 closeUrl();
369 openUrl(KUrl( url ));
373 void PluginPart::saveAs() {
374 KUrl savefile = KFileDialog::getSaveUrl(QString(), QString(), _widget);
375 KIO::NetAccess::file_copy(url(), savefile, _widget);
379 void PluginCanvasWidget::resizeEvent(QResizeEvent *ev)
381 QWidget::resizeEvent(ev);
382 emit resized(width(), height());
386 #include "plugin_part.moc"