00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdio.h>
00021
00022 #ifdef KDE_USE_FINAL
00023 #undef Always
00024 #include <qdir.h>
00025 #endif
00026 #include <qtable.h>
00027 #include <qpair.h>
00028 #include <qguardedptr.h>
00029
00030 #include <klibloader.h>
00031 #include <kaboutdata.h>
00032 #include <kstaticdeleter.h>
00033 #include <klocale.h>
00034 #include <kapplication.h>
00035 #include <kdebug.h>
00036 #include <kconfig.h>
00037 #include <kio/authinfo.h>
00038 #include <dcopclient.h>
00039
00040 #include "kjavaappletwidget.h"
00041 #include "kjavaappletviewer.h"
00042 #include "kjavaappletserver.h"
00043
00044
00045 K_EXPORT_COMPONENT_FACTORY (kjavaappletviewer, KJavaAppletViewerFactory)
00046
00047 KInstance *KJavaAppletViewerFactory::s_instance = 0;
00048
00049 KJavaAppletViewerFactory::KJavaAppletViewerFactory () {
00050 s_instance = new KInstance ("KJavaAppletViewer");
00051 }
00052
00053 KJavaAppletViewerFactory::~KJavaAppletViewerFactory () {
00054 delete s_instance;
00055 }
00056
00057 KParts::Part *KJavaAppletViewerFactory::createPartObject
00058 (QWidget *wparent, const char *wname,
00059 QObject *parent, const char * name, const char *, const QStringList & args) {
00060 return new KJavaAppletViewer (wparent, wname, parent, name, args);
00061 }
00062
00063
00064
00065 class KJavaServerMaintainer;
00066 static KJavaServerMaintainer * serverMaintainer = 0;
00067
00068 class KJavaServerMaintainer {
00069 public:
00070 KJavaServerMaintainer () { }
00071 ~KJavaServerMaintainer ();
00072
00073 KJavaAppletContext * getContext (QObject*, const QString &);
00074 void releaseContext (QObject*, const QString &);
00075 void setServer (KJavaAppletServer * s);
00076 private:
00077 typedef QMap <QPair <QObject*, QString>, QPair <KJavaAppletContext*, int> >
00078 ContextMap;
00079 ContextMap m_contextmap;
00080 QGuardedPtr <KJavaAppletServer> server;
00081 };
00082
00083 KJavaServerMaintainer::~KJavaServerMaintainer () {
00084 delete server;
00085 }
00086
00087 KJavaAppletContext * KJavaServerMaintainer::getContext (QObject * w, const QString & doc) {
00088 ContextMap::key_type key = qMakePair (w, doc);
00089 ContextMap::iterator it = m_contextmap.find (key);
00090 if (it != m_contextmap.end ()) {
00091 (*it).second++;
00092 return (*it).first;
00093 }
00094 KJavaAppletContext * context = new KJavaAppletContext ();
00095 m_contextmap.insert (key, qMakePair(context, 1));
00096 return context;
00097 }
00098
00099 void KJavaServerMaintainer::releaseContext (QObject * w, const QString & doc) {
00100 ContextMap::iterator it = m_contextmap.find (qMakePair (w, doc));
00101 if (it != m_contextmap.end () && --(*it).second <= 0) {
00102 kdDebug(6100) << "KJavaServerMaintainer::releaseContext" << endl;
00103 (*it).first->deleteLater ();
00104 m_contextmap.remove (it);
00105 }
00106 }
00107
00108 inline void KJavaServerMaintainer::setServer (KJavaAppletServer * s) {
00109 if (!server)
00110 server = s;
00111 }
00112
00113 static KStaticDeleter <KJavaServerMaintainer> serverMaintainerDeleter;
00114
00115
00116
00117 AppletParameterDialog::AppletParameterDialog (KJavaAppletWidget * parent)
00118 : KDialogBase (parent, "paramdialog", true, i18n ("Applet Parameters"),
00119 KDialogBase::Close, KDialogBase::Close, true),
00120 m_appletWidget (parent) {
00121 KJavaApplet * applet = parent->applet ();
00122 table = new QTable (30, 2, this);
00123 table->setMinimumSize (QSize (600, 400));
00124 table->setColumnWidth (0, 200);
00125 table->setColumnWidth (1, 340);
00126 QHeader *header = table->horizontalHeader();
00127 header->setLabel (0, i18n ("Parameter"));
00128 header->setLabel (1, i18n ("Value"));
00129 QTableItem * tit = new QTableItem (table, QTableItem::Never, i18n("Class"));
00130 table->setItem (0, 0, tit);
00131 tit = new QTableItem(table, QTableItem::Always, applet->appletClass());
00132 table->setItem (0, 1, tit);
00133 tit = new QTableItem (table, QTableItem::Never, i18n ("Base URL"));
00134 table->setItem (1, 0, tit);
00135 tit = new QTableItem(table, QTableItem::Always, applet->baseURL());
00136 table->setItem (1, 1, tit);
00137 tit = new QTableItem (table, QTableItem::Never, i18n ("Archives"));
00138 table->setItem (2, 0, tit);
00139 tit = new QTableItem(table, QTableItem::Always, applet->archives());
00140 table->setItem (2, 1, tit);
00141 QMap<QString,QString>::iterator it = applet->getParams().begin ();
00142 for (int count = 2; it != applet->getParams().end (); ++it) {
00143 tit = new QTableItem (table, QTableItem::Always, it.key ());
00144 table->setItem (++count, 0, tit);
00145 tit = new QTableItem(table, QTableItem::Always, it.data ());
00146 table->setItem (count, 1, tit);
00147 }
00148 setMainWidget (table);
00149 }
00150
00151 void AppletParameterDialog::slotClose () {
00152 table->selectCells (0, 0, 0, 0);
00153 KJavaApplet * applet = m_appletWidget->applet ();
00154 applet->setAppletClass (table->item (0, 1)->text ());
00155 applet->setBaseURL (table->item (1, 1)->text ());
00156 applet->setArchives (table->item (2, 1)->text ());
00157 for (int i = 3; i < table->numRows (); ++i) {
00158 if (table->item (i, 0) && table->item (i, 1) && !table->item (i, 0)->text ().isEmpty ())
00159 applet->setParameter (table->item (i, 0)->text (),
00160 table->item (i, 1)->text ());
00161 }
00162 hide ();
00163 }
00164
00165
00166 class CoverWidget : public QWidget {
00167 KJavaAppletWidget * m_appletwidget;
00168 public:
00169 CoverWidget (QWidget *);
00170 ~CoverWidget () {}
00171 KJavaAppletWidget * appletWidget () const;
00172 protected:
00173 void resizeEvent (QResizeEvent * e);
00174 };
00175
00176 inline CoverWidget::CoverWidget (QWidget * parent) : QWidget (parent) {
00177 m_appletwidget = new KJavaAppletWidget (this);
00178 setFocusProxy (m_appletwidget);
00179 hide ();
00180 }
00181
00182 inline KJavaAppletWidget * CoverWidget::appletWidget () const {
00183 return m_appletwidget;
00184 }
00185
00186 void CoverWidget::resizeEvent (QResizeEvent * e) {
00187 m_appletwidget->resize (e->size().width(), e->size().height());
00188 }
00189
00190
00191
00192 KJavaAppletViewer::KJavaAppletViewer (QWidget * wparent, const char *,
00193 QObject * parent, const char * name, const QStringList & args)
00194 : KParts::ReadOnlyPart (parent, name),
00195 m_browserextension (new KJavaAppletViewerBrowserExtension (this)),
00196 m_liveconnect (new KJavaAppletViewerLiveConnectExtension (this)),
00197 m_closed (true)
00198 {
00199 if (!serverMaintainer) {
00200 serverMaintainerDeleter.setObject (serverMaintainer,
00201 new KJavaServerMaintainer);
00202 }
00203 m_view = new CoverWidget (wparent);
00204 QString classname, classid, codebase, khtml_codebase;
00205 int width = -1;
00206 int height = -1;
00207 KJavaApplet * applet = m_view->appletWidget()->applet ();
00208 QStringList::const_iterator it = args.begin ();
00209 for ( ; it != args.end (); ++it) {
00210 int equalPos = (*it).find("=");
00211 if (equalPos > 0) {
00212 QString name = (*it).left (equalPos).upper ();
00213 QString value = (*it).right ((*it).length () - equalPos - 1);
00214 if (value.at(0)=='\"')
00215 value = value.right (value.length () - 1);
00216 if (value.at (value.length () - 1) == '\"')
00217 value.truncate (value.length () - 1);
00218 kdDebug(6100) << "name=" << name << " value=" << value << endl;
00219 if (!name.isEmpty()) {
00220 QString name_lower = name.lower ();
00221 if (name == "__KHTML__PLUGINBASEURL") {
00222 KURL url (value);
00223 QString fn = url.fileName (false);
00224 baseurl = fn.isEmpty () ?
00225 value : value.left (value.length ()-fn.length ());
00226 } else if (name == "__KHTML__CODEBASE")
00227 khtml_codebase = value;
00228 else if (name_lower == QString::fromLatin1("codebase") ||
00229 name_lower == QString::fromLatin1("java_codebase")) {
00230 if (!value.isEmpty ())
00231 codebase = value;
00232 } else if (name == "__KHTML__CLASSID")
00233
00234 classid = value;
00235 else if (name_lower == QString::fromLatin1("code") ||
00236 name_lower == QString::fromLatin1("java_code") ||
00237 name_lower == QString::fromLatin1("src"))
00238 classname = value;
00239 else if (name_lower == QString::fromLatin1("archive") ||
00240 name_lower == QString::fromLatin1("java_archive") ||
00241 name_lower.startsWith ("cache_archive"))
00242 applet->setArchives (value);
00243 else if (name_lower == QString::fromLatin1("name"))
00244 applet->setAppletName (value);
00245 else if (name_lower == QString::fromLatin1("width"))
00246 width = value.toInt();
00247 else if (name_lower == QString::fromLatin1("height"))
00248 height = value.toInt();
00249 else {
00250 applet->setParameter (name, value);
00251 }
00252 }
00253 }
00254 }
00255 if (!classid.isEmpty ()) {
00256 applet->setParameter ("CLSID", classid);
00257 kdDebug(6100) << "classid=" << classid << classid.startsWith("clsid:")<< endl;
00258 if (classid.startsWith ("clsid:"))
00259
00260 khtml_codebase = baseurl;
00261 else if (classname.isEmpty () && classid.startsWith ("java:"))
00262 classname = classid.mid(5);
00263 }
00264 if (codebase.isEmpty ())
00265 codebase = khtml_codebase;
00266
00267 if (width > 0 && height > 0)
00268 m_view->resize (width, height);
00269 applet->setBaseURL (baseurl);
00270
00271 KURL kbaseURL( baseurl );
00272 KURL newURL(kbaseURL, codebase);
00273 if (kapp->authorizeURLAction("redirect", KURL(baseurl), newURL))
00274 applet->setCodeBase (newURL.url());
00275 applet->setAppletClass (classname);
00276 KJavaAppletContext * cxt = serverMaintainer->getContext (parent, baseurl);
00277 applet->setAppletContext (cxt);
00278
00279 KJavaAppletServer * server = cxt->getServer ();
00280
00281 serverMaintainer->setServer (server);
00282
00283 if (!server->usingKIO ()) {
00284
00285 KIO::AuthInfo info;
00286 QString errorMsg;
00287 QCString replyType;
00288 QByteArray params;
00289 QByteArray reply;
00290 KIO::AuthInfo authResult;
00291
00292
00293 info.url = baseurl;
00294 info.verifyPath = true;
00295
00296 QDataStream stream(params, IO_WriteOnly);
00297 stream << info << m_view->topLevelWidget()->winId();
00298
00299 if (!kapp->dcopClient ()->call( "kded", "kpasswdserver", "checkAuthInfo(KIO::AuthInfo, long int)", params, replyType, reply ) ) {
00300 kdWarning() << "Can't communicate with kded_kpasswdserver!" << endl;
00301 } else if ( replyType == "KIO::AuthInfo" ) {
00302 QDataStream stream2( reply, IO_ReadOnly );
00303 stream2 >> authResult;
00304 applet->setUser (authResult.username);
00305 applet->setPassword (authResult.password);
00306 applet->setAuthName (authResult.realmValue);
00307 }
00308 }
00309
00310
00311 if (wparent)
00312 wparent->topLevelWidget ()->installEventFilter (this);
00313
00314 setInstance (KJavaAppletViewerFactory::instance ());
00315 KParts::Part::setWidget (m_view);
00316
00317 connect (applet->getContext(), SIGNAL(appletLoaded()), this, SLOT(appletLoaded()));
00318 connect (applet->getContext(), SIGNAL(showDocument(const QString&, const QString&)), m_browserextension, SLOT(showDocument(const QString&, const QString&)));
00319 connect (applet->getContext(), SIGNAL(showStatus(const QString &)), this, SLOT(infoMessage(const QString &)));
00320 connect (applet, SIGNAL(jsEvent (const QStringList &)), m_liveconnect, SLOT(jsEvent (const QStringList &)));
00321 }
00322
00323 bool KJavaAppletViewer::eventFilter (QObject *o, QEvent *e) {
00324 if (m_liveconnect->jsSessions () > 0) {
00325 switch (e->type()) {
00326 case QEvent::Destroy:
00327 case QEvent::Close:
00328 case QEvent::Quit:
00329 return true;
00330 default:
00331 break;
00332 }
00333 }
00334 return KParts::ReadOnlyPart::eventFilter(o,e);
00335 }
00336
00337 KJavaAppletViewer::~KJavaAppletViewer () {
00338 m_view = 0L;
00339 serverMaintainer->releaseContext (parent(), baseurl);
00340 }
00341
00342 bool KJavaAppletViewer::openURL (const KURL & url) {
00343 if (!m_view) return false;
00344 m_closed = false;
00345 KJavaAppletWidget * w = m_view->appletWidget ();
00346 KJavaApplet * applet = w->applet ();
00347 if (applet->isCreated ())
00348 applet->stop ();
00349 if (applet->appletClass ().isEmpty ()) {
00350
00351 if (applet->baseURL ().isEmpty ()) {
00352 applet->setAppletClass (url.fileName ());
00353 applet->setBaseURL (url.upURL ().url ());
00354 } else
00355 applet->setAppletClass (url.url ());
00356 AppletParameterDialog (w).exec ();
00357 applet->setSize (w->sizeHint());
00358 }
00359
00360 if (applet->size().width() > 0 || m_view->isVisible())
00361 w->showApplet ();
00362 if (!applet->failed ())
00363 emit started (0L);
00364 return url.isValid ();
00365 }
00366
00367 bool KJavaAppletViewer::closeURL () {
00368 kdDebug(6100) << "closeURL" << endl;
00369 m_closed = true;
00370 KJavaApplet * applet = m_view->appletWidget ()->applet ();
00371 if (applet->isCreated ())
00372 applet->stop ();
00373 applet->getContext()->getServer()->endWaitForReturnData();
00374 return true;
00375 }
00376
00377 bool KJavaAppletViewer::appletAlive () const {
00378 return !m_closed && m_view &&
00379 m_view->appletWidget ()->applet () &&
00380 m_view->appletWidget ()->applet ()->isAlive ();
00381 }
00382
00383 bool KJavaAppletViewer::openFile () {
00384 return false;
00385 }
00386
00387 void KJavaAppletViewer::appletLoaded () {
00388 if (!m_view) return;
00389 KJavaApplet * applet = m_view->appletWidget ()->applet ();
00390 if (applet->isAlive() || applet->failed())
00391 emit completed();
00392 }
00393
00394 void KJavaAppletViewer::infoMessage (const QString & msg) {
00395 m_browserextension->infoMessage(msg);
00396 }
00397
00398 KAboutData* KJavaAppletViewer::createAboutData () {
00399 return new KAboutData("KJavaAppletViewer", I18N_NOOP("KDE Java Applet Plugin"), "1.0");
00400 }
00401
00402
00403
00404 KJavaAppletViewerBrowserExtension::KJavaAppletViewerBrowserExtension (KJavaAppletViewer * parent)
00405 : KParts::BrowserExtension (parent, "KJavaAppletViewer Browser Extension") {
00406 }
00407
00408 void KJavaAppletViewerBrowserExtension::urlChanged (const QString & url) {
00409 emit setLocationBarURL (url);
00410 }
00411
00412 void KJavaAppletViewerBrowserExtension::setLoadingProgress (int percentage) {
00413 emit loadingProgress (percentage);
00414 }
00415
00416 void KJavaAppletViewerBrowserExtension::setURLArgs (const KParts::URLArgs & ) {
00417 }
00418
00419 void KJavaAppletViewerBrowserExtension::saveState (QDataStream & stream) {
00420 KJavaApplet * applet = static_cast<KJavaAppletViewer*>(parent())->view()->appletWidget ()->applet ();
00421 stream << applet->appletClass();
00422 stream << applet->baseURL();
00423 stream << applet->archives();
00424 stream << applet->getParams().size ();
00425 QMap<QString,QString>::iterator it = applet->getParams().begin ();
00426 for ( ; it != applet->getParams().end (); ++it) {
00427 stream << it.key ();
00428 stream << it.data ();
00429 }
00430 }
00431
00432 void KJavaAppletViewerBrowserExtension::restoreState (QDataStream & stream) {
00433 KJavaAppletWidget * w = static_cast<KJavaAppletViewer*>(parent())->view()->appletWidget();
00434 KJavaApplet * applet = w->applet ();
00435 QString key, val;
00436 int paramcount;
00437 stream >> val;
00438 applet->setAppletClass (val);
00439 stream >> val;
00440 applet->setBaseURL (val);
00441 stream >> val;
00442 applet->setArchives (val);
00443 stream >> paramcount;
00444 for (int i = 0; i < paramcount; ++i) {
00445 stream >> key;
00446 stream >> val;
00447 applet->setParameter (key, val);
00448 kdDebug(6100) << "restoreState key:" << key << " val:" << val << endl;
00449 }
00450 applet->setSize (w->sizeHint ());
00451 if (w->isVisible())
00452 w->showApplet ();
00453 }
00454
00455 void KJavaAppletViewerBrowserExtension::showDocument (const QString & doc,
00456 const QString & frame) {
00457 KURL url (doc);
00458 KParts::URLArgs args;
00459 args.frameName = frame;
00460 emit openURLRequest (url, args);
00461 }
00462
00463
00464
00465 KJavaAppletViewerLiveConnectExtension::KJavaAppletViewerLiveConnectExtension(KJavaAppletViewer * parent)
00466 : KParts::LiveConnectExtension (parent), m_viewer (parent) {
00467 }
00468
00469 bool KJavaAppletViewerLiveConnectExtension::get (
00470 const unsigned long objid, const QString & name,
00471 KParts::LiveConnectExtension::Type & type,
00472 unsigned long & rid, QString & value)
00473 {
00474 if (!m_viewer->appletAlive ())
00475 return false;
00476 QStringList args, ret_args;
00477 KJavaApplet * applet = m_viewer->view ()->appletWidget ()->applet ();
00478 args.append (QString::number (applet->appletId ()));
00479 args.append (QString::number ((int) objid));
00480 args.append (name);
00481 m_jssessions++;
00482 bool ret = applet->getContext()->getMember (args, ret_args);
00483 m_jssessions--;
00484 if (!ret || ret_args.count() != 3) return false;
00485 bool ok;
00486 int itype = ret_args[0].toInt (&ok);
00487 if (!ok || itype < 0) return false;
00488 type = (KParts::LiveConnectExtension::Type) itype;
00489 rid = ret_args[1].toInt (&ok);
00490 if (!ok) return false;
00491 value = ret_args[2];
00492 return true;
00493 }
00494
00495 bool KJavaAppletViewerLiveConnectExtension::put(const unsigned long objid, const QString & name, const QString & value)
00496 {
00497 if (!m_viewer->appletAlive ())
00498 return false;
00499 QStringList args;
00500 KJavaApplet * applet = m_viewer->view ()->appletWidget ()->applet ();
00501 args.append (QString::number (applet->appletId ()));
00502 args.append (QString::number ((int) objid));
00503 args.append (name);
00504 args.append (value);
00505 m_jssessions++;
00506 bool ret = applet->getContext()->putMember (args);
00507 m_jssessions--;
00508 return ret;
00509 }
00510
00511 bool KJavaAppletViewerLiveConnectExtension::call( const unsigned long objid, const QString & func, const QStringList & fargs, KParts::LiveConnectExtension::Type & type, unsigned long & retobjid, QString & value )
00512 {
00513 if (!m_viewer->appletAlive ())
00514 return false;
00515 KJavaApplet * applet = m_viewer->view ()->appletWidget ()->applet ();
00516 QStringList args, ret_args;
00517 args.append (QString::number (applet->appletId ()));
00518 args.append (QString::number ((int) objid));
00519 args.append (func);
00520 for (QStringList::const_iterator it=fargs.begin(); it != fargs.end(); ++it)
00521 args.append(*it);
00522 m_jssessions++;
00523 bool ret = applet->getContext()->callMember (args, ret_args);
00524 m_jssessions--;
00525 if (!ret || ret_args.count () != 3) return false;
00526 bool ok;
00527 int itype = ret_args[0].toInt (&ok);
00528 if (!ok || itype < 0) return false;
00529 type = (KParts::LiveConnectExtension::Type) itype;
00530 retobjid = ret_args[1].toInt (&ok);
00531 if (!ok) return false;
00532 value = ret_args[2];
00533 return true;
00534 }
00535
00536 void KJavaAppletViewerLiveConnectExtension::unregister(const unsigned long objid)
00537 {
00538 if (!m_viewer->view () || !m_viewer->view ())
00539 return;
00540 KJavaApplet * applet = m_viewer->view ()->appletWidget ()->applet ();
00541 if (!applet || objid == 0) {
00542
00543
00544 return;
00545 }
00546 QStringList args;
00547 args.append (QString::number (applet->appletId ()));
00548 args.append (QString::number ((int) objid));
00549 applet->getContext()->derefObject (args);
00550 }
00551
00552 void KJavaAppletViewerLiveConnectExtension::jsEvent (const QStringList & args) {
00553 if (args.count () < 2 || !m_viewer->appletAlive ())
00554 return;
00555 bool ok;
00556 unsigned long objid = args[0].toInt(&ok);
00557 QString event = args[1];
00558 KParts::LiveConnectExtension::ArgList arglist;
00559 for (unsigned i = 2; i < args.count(); i += 2)
00560
00561 arglist.push_back(KParts::LiveConnectExtension::ArgList::value_type((KParts::LiveConnectExtension::Type) args[i].toInt(), args[i+1]));
00562 emit partEvent (objid, event, arglist);
00563 }
00564
00565 int KJavaAppletViewerLiveConnectExtension::m_jssessions = 0;
00566
00567
00568
00569 #include "kjavaappletviewer.moc"