khtml Library API Documentation

kjavaappletviewer.cpp

00001 /* This file is part of the KDE project 00002 * 00003 * Copyright (C) 2003 Koos Vriezen <koos.vriezen@xs4all.nl> 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Library General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Library General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Library General Public License 00016 * along with this library; see the file COPYING.LIB. If not, write to 00017 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 * Boston, MA 02111-1307, USA. 00019 */ 00020 #include <stdio.h> 00021 00022 #ifdef KDE_USE_FINAL 00023 #undef Always 00024 #endif 00025 #include <qdir.h> 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) 00177 : QWidget (parent, "KJavaAppletViewer Widget") 00178 { 00179 m_appletwidget = new KJavaAppletWidget (this); 00180 setFocusProxy (m_appletwidget); 00181 } 00182 00183 inline KJavaAppletWidget * CoverWidget::appletWidget () const { 00184 return m_appletwidget; 00185 } 00186 00187 void CoverWidget::resizeEvent (QResizeEvent * e) { 00188 m_appletwidget->resize (e->size().width(), e->size().height()); 00189 } 00190 00191 //----------------------------------------------------------------------------- 00192 00193 KJavaAppletViewer::KJavaAppletViewer (QWidget * wparent, const char *, 00194 QObject * parent, const char * name, const QStringList & args) 00195 : KParts::ReadOnlyPart (parent, name), 00196 m_browserextension (new KJavaAppletViewerBrowserExtension (this)), 00197 m_liveconnect (new KJavaAppletViewerLiveConnectExtension (this)), 00198 m_closed (true) 00199 { 00200 if (!serverMaintainer) { 00201 serverMaintainerDeleter.setObject (serverMaintainer, 00202 new KJavaServerMaintainer); 00203 } 00204 m_view = new CoverWidget (wparent); 00205 QString classname, classid, codebase, khtml_codebase; 00206 int width = -1; 00207 int height = -1; 00208 KJavaApplet * applet = m_view->appletWidget()->applet (); 00209 QStringList::const_iterator it = args.begin (); 00210 for ( ; it != args.end (); ++it) { 00211 int equalPos = (*it).find("="); 00212 if (equalPos > 0) { 00213 QString name = (*it).left (equalPos).upper (); 00214 QString value = (*it).right ((*it).length () - equalPos - 1); 00215 if (value.at(0)=='\"') 00216 value = value.right (value.length () - 1); 00217 if (value.at (value.length () - 1) == '\"') 00218 value.truncate (value.length () - 1); 00219 kdDebug(6100) << "name=" << name << " value=" << value << endl; 00220 if (!name.isEmpty()) { 00221 QString name_lower = name.lower (); 00222 if (name == "__KHTML__PLUGINBASEURL") { 00223 baseurl = KURL (KURL (value), QString (".")).url (); 00224 } else if (name == "__KHTML__CODEBASE") 00225 khtml_codebase = value; 00226 else if (name_lower == QString::fromLatin1("codebase") || 00227 name_lower == QString::fromLatin1("java_codebase")) { 00228 if (!value.isEmpty ()) 00229 codebase = value; 00230 } else if (name == "__KHTML__CLASSID") 00231 //else if (name.lower()==QString::fromLatin1("classid")) 00232 classid = value; 00233 else if (name_lower == QString::fromLatin1("code") || 00234 name_lower == QString::fromLatin1("java_code") || 00235 name_lower == QString::fromLatin1("src")) 00236 classname = value; 00237 else if (name_lower == QString::fromLatin1("archive") || 00238 name_lower == QString::fromLatin1("java_archive") || 00239 name_lower.startsWith ("cache_archive")) 00240 applet->setArchives (value); 00241 else if (name_lower == QString::fromLatin1("name")) 00242 applet->setAppletName (value); 00243 else if (name_lower == QString::fromLatin1("width")) 00244 width = value.toInt(); 00245 else if (name_lower == QString::fromLatin1("height")) 00246 height = value.toInt(); 00247 else { 00248 applet->setParameter (name, value); 00249 } 00250 } 00251 } 00252 } 00253 if (!classid.isEmpty ()) { 00254 applet->setParameter ("CLSID", classid); 00255 kdDebug(6100) << "classid=" << classid << classid.startsWith("clsid:")<< endl; 00256 if (classid.startsWith ("clsid:")) 00257 // codeBase contains the URL to the plugin page 00258 khtml_codebase = baseurl; 00259 else if (classname.isEmpty () && classid.startsWith ("java:")) 00260 classname = classid.mid(5); 00261 } 00262 if (codebase.isEmpty ()) 00263 codebase = khtml_codebase; 00264 if (baseurl.isEmpty ()) { 00265 // not embeded in khtml 00266 QString pwd = QDir().absPath (); 00267 if (!pwd.endsWith (QChar (QDir::separator ()))) 00268 pwd += QDir::separator (); 00269 baseurl = KURL (KURL (pwd), codebase).url (); 00270 } 00271 if (width > 0 && height > 0) { 00272 m_view->resize (width, height); 00273 applet->setSize( QSize( width, height ) ); 00274 } 00275 applet->setBaseURL (baseurl); 00276 // check codebase first 00277 KURL kbaseURL( baseurl ); 00278 KURL newURL(kbaseURL, codebase); 00279 if (kapp->authorizeURLAction("redirect", KURL(baseurl), newURL)) 00280 applet->setCodeBase (newURL.url()); 00281 applet->setAppletClass (classname); 00282 KJavaAppletContext * cxt = serverMaintainer->getContext (parent, baseurl); 00283 applet->setAppletContext (cxt); 00284 00285 KJavaAppletServer * server = cxt->getServer (); 00286 00287 serverMaintainer->setServer (server); 00288 00289 if (!server->usingKIO ()) { 00290 /* if this page needs authentication */ 00291 KIO::AuthInfo info; 00292 QString errorMsg; 00293 QCString replyType; 00294 QByteArray params; 00295 QByteArray reply; 00296 KIO::AuthInfo authResult; 00297 00298 //(void) dcopClient(); // Make sure to have a dcop client. 00299 info.url = baseurl; 00300 info.verifyPath = true; 00301 00302 QDataStream stream(params, IO_WriteOnly); 00303 stream << info << m_view->topLevelWidget()->winId(); 00304 00305 if (!kapp->dcopClient ()->call( "kded", "kpasswdserver", "checkAuthInfo(KIO::AuthInfo, long int)", params, replyType, reply ) ) { 00306 kdWarning() << "Can't communicate with kded_kpasswdserver!" << endl; 00307 } else if ( replyType == "KIO::AuthInfo" ) { 00308 QDataStream stream2( reply, IO_ReadOnly ); 00309 stream2 >> authResult; 00310 applet->setUser (authResult.username); 00311 applet->setPassword (authResult.password); 00312 applet->setAuthName (authResult.realmValue); 00313 } 00314 } 00315 00316 /* install event filter for close events */ 00317 if (wparent) 00318 wparent->topLevelWidget ()->installEventFilter (this); 00319 00320 setInstance (KJavaAppletViewerFactory::instance ()); 00321 KParts::Part::setWidget (m_view); 00322 00323 connect (applet->getContext(), SIGNAL(appletLoaded()), this, SLOT(appletLoaded())); 00324 connect (applet->getContext(), SIGNAL(showDocument(const QString&, const QString&)), m_browserextension, SLOT(showDocument(const QString&, const QString&))); 00325 connect (applet->getContext(), SIGNAL(showStatus(const QString &)), this, SLOT(infoMessage(const QString &))); 00326 connect (applet, SIGNAL(jsEvent (const QStringList &)), m_liveconnect, SLOT(jsEvent (const QStringList &))); 00327 } 00328 00329 bool KJavaAppletViewer::eventFilter (QObject *o, QEvent *e) { 00330 if (m_liveconnect->jsSessions () > 0) { 00331 switch (e->type()) { 00332 case QEvent::Destroy: 00333 case QEvent::Close: 00334 case QEvent::Quit: 00335 return true; 00336 default: 00337 break; 00338 } 00339 } 00340 return KParts::ReadOnlyPart::eventFilter(o,e); 00341 } 00342 00343 KJavaAppletViewer::~KJavaAppletViewer () { 00344 m_view = 0L; 00345 serverMaintainer->releaseContext (parent(), baseurl); 00346 } 00347 00348 bool KJavaAppletViewer::openURL (const KURL & url) { 00349 if (!m_view) return false; 00350 m_closed = false; 00351 KJavaAppletWidget * w = m_view->appletWidget (); 00352 KJavaApplet * applet = w->applet (); 00353 if (applet->isCreated ()) 00354 applet->stop (); 00355 if (applet->appletClass ().isEmpty ()) { 00356 // preview without setting a class? 00357 if (applet->baseURL ().isEmpty ()) { 00358 applet->setAppletClass (url.fileName ()); 00359 applet->setBaseURL (url.upURL ().url ()); 00360 } else 00361 applet->setAppletClass (url.url ()); 00362 AppletParameterDialog (w).exec (); 00363 applet->setSize (w->sizeHint()); 00364 } 00365 // delay showApplet if size is unknown and m_view not shown 00366 if (applet->size().width() > 0 || m_view->isVisible()) 00367 w->showApplet (); 00368 if (!applet->failed ()) 00369 emit started (0L); 00370 return url.isValid (); 00371 } 00372 00373 bool KJavaAppletViewer::closeURL () { 00374 kdDebug(6100) << "closeURL" << endl; 00375 m_closed = true; 00376 KJavaApplet * applet = m_view->appletWidget ()->applet (); 00377 if (applet->isCreated ()) 00378 applet->stop (); 00379 applet->getContext()->getServer()->endWaitForReturnData(); 00380 return true; 00381 } 00382 00383 bool KJavaAppletViewer::appletAlive () const { 00384 return !m_closed && m_view && 00385 m_view->appletWidget ()->applet () && 00386 m_view->appletWidget ()->applet ()->isAlive (); 00387 } 00388 00389 bool KJavaAppletViewer::openFile () { 00390 return false; 00391 } 00392 00393 void KJavaAppletViewer::appletLoaded () { 00394 if (!m_view) return; 00395 KJavaApplet * applet = m_view->appletWidget ()->applet (); 00396 if (applet->isAlive() || applet->failed()) 00397 emit completed(); 00398 } 00399 00400 void KJavaAppletViewer::infoMessage (const QString & msg) { 00401 m_browserextension->infoMessage(msg); 00402 } 00403 00404 KAboutData* KJavaAppletViewer::createAboutData () { 00405 return new KAboutData("KJavaAppletViewer", I18N_NOOP("KDE Java Applet Plugin"), "1.0"); 00406 } 00407 00408 //--------------------------------------------------------------------- 00409 00410 KJavaAppletViewerBrowserExtension::KJavaAppletViewerBrowserExtension (KJavaAppletViewer * parent) 00411 : KParts::BrowserExtension (parent, "KJavaAppletViewer Browser Extension") { 00412 } 00413 00414 void KJavaAppletViewerBrowserExtension::urlChanged (const QString & url) { 00415 emit setLocationBarURL (url); 00416 } 00417 00418 void KJavaAppletViewerBrowserExtension::setLoadingProgress (int percentage) { 00419 emit loadingProgress (percentage); 00420 } 00421 00422 void KJavaAppletViewerBrowserExtension::setURLArgs (const KParts::URLArgs & /*args*/) { 00423 } 00424 00425 void KJavaAppletViewerBrowserExtension::saveState (QDataStream & stream) { 00426 KJavaApplet * applet = static_cast<KJavaAppletViewer*>(parent())->view()->appletWidget ()->applet (); 00427 stream << applet->appletClass(); 00428 stream << applet->baseURL(); 00429 stream << applet->archives(); 00430 stream << applet->getParams().size (); 00431 QMap<QString,QString>::iterator it = applet->getParams().begin (); 00432 for ( ; it != applet->getParams().end (); ++it) { 00433 stream << it.key (); 00434 stream << it.data (); 00435 } 00436 } 00437 00438 void KJavaAppletViewerBrowserExtension::restoreState (QDataStream & stream) { 00439 KJavaAppletWidget * w = static_cast<KJavaAppletViewer*>(parent())->view()->appletWidget(); 00440 KJavaApplet * applet = w->applet (); 00441 QString key, val; 00442 int paramcount; 00443 stream >> val; 00444 applet->setAppletClass (val); 00445 stream >> val; 00446 applet->setBaseURL (val); 00447 stream >> val; 00448 applet->setArchives (val); 00449 stream >> paramcount; 00450 for (int i = 0; i < paramcount; ++i) { 00451 stream >> key; 00452 stream >> val; 00453 applet->setParameter (key, val); 00454 kdDebug(6100) << "restoreState key:" << key << " val:" << val << endl; 00455 } 00456 applet->setSize (w->sizeHint ()); 00457 if (w->isVisible()) 00458 w->showApplet (); 00459 } 00460 00461 void KJavaAppletViewerBrowserExtension::showDocument (const QString & doc, 00462 const QString & frame) { 00463 KURL url (doc); 00464 KParts::URLArgs args; 00465 args.frameName = frame; 00466 emit openURLRequest (url, args); 00467 } 00468 00469 //----------------------------------------------------------------------------- 00470 00471 KJavaAppletViewerLiveConnectExtension::KJavaAppletViewerLiveConnectExtension(KJavaAppletViewer * parent) 00472 : KParts::LiveConnectExtension (parent, "KJavaAppletViewer LiveConnect Extension"), m_viewer (parent) { 00473 } 00474 00475 bool KJavaAppletViewerLiveConnectExtension::get ( 00476 const unsigned long objid, const QString & name, 00477 KParts::LiveConnectExtension::Type & type, 00478 unsigned long & rid, QString & value) 00479 { 00480 if (!m_viewer->appletAlive ()) 00481 return false; 00482 QStringList args, ret_args; 00483 KJavaApplet * applet = m_viewer->view ()->appletWidget ()->applet (); 00484 args.append (QString::number (applet->appletId ())); 00485 args.append (QString::number ((int) objid)); 00486 args.append (name); 00487 m_jssessions++; 00488 bool ret = applet->getContext()->getMember (args, ret_args); 00489 m_jssessions--; 00490 if (!ret || ret_args.count() != 3) return false; 00491 bool ok; 00492 int itype = ret_args[0].toInt (&ok); 00493 if (!ok || itype < 0) return false; 00494 type = (KParts::LiveConnectExtension::Type) itype; 00495 rid = ret_args[1].toInt (&ok); 00496 if (!ok) return false; 00497 value = ret_args[2]; 00498 return true; 00499 } 00500 00501 bool KJavaAppletViewerLiveConnectExtension::put(const unsigned long objid, const QString & name, const QString & value) 00502 { 00503 if (!m_viewer->appletAlive ()) 00504 return false; 00505 QStringList args; 00506 KJavaApplet * applet = m_viewer->view ()->appletWidget ()->applet (); 00507 args.append (QString::number (applet->appletId ())); 00508 args.append (QString::number ((int) objid)); 00509 args.append (name); 00510 args.append (value); 00511 m_jssessions++; 00512 bool ret = applet->getContext()->putMember (args); 00513 m_jssessions--; 00514 return ret; 00515 } 00516 00517 bool KJavaAppletViewerLiveConnectExtension::call( const unsigned long objid, const QString & func, const QStringList & fargs, KParts::LiveConnectExtension::Type & type, unsigned long & retobjid, QString & value ) 00518 { 00519 if (!m_viewer->appletAlive ()) 00520 return false; 00521 KJavaApplet * applet = m_viewer->view ()->appletWidget ()->applet (); 00522 QStringList args, ret_args; 00523 args.append (QString::number (applet->appletId ())); 00524 args.append (QString::number ((int) objid)); 00525 args.append (func); 00526 for (QStringList::const_iterator it=fargs.begin(); it != fargs.end(); ++it) 00527 args.append(*it); 00528 m_jssessions++; 00529 bool ret = applet->getContext()->callMember (args, ret_args); 00530 m_jssessions--; 00531 if (!ret || ret_args.count () != 3) return false; 00532 bool ok; 00533 int itype = ret_args[0].toInt (&ok); 00534 if (!ok || itype < 0) return false; 00535 type = (KParts::LiveConnectExtension::Type) itype; 00536 retobjid = ret_args[1].toInt (&ok); 00537 if (!ok) return false; 00538 value = ret_args[2]; 00539 return true; 00540 } 00541 00542 void KJavaAppletViewerLiveConnectExtension::unregister(const unsigned long objid) 00543 { 00544 if (!m_viewer->view () || !m_viewer->view ()) 00545 return; 00546 KJavaApplet * applet = m_viewer->view ()->appletWidget ()->applet (); 00547 if (!applet || objid == 0) { 00548 // typically a gc after a function call on the applet, 00549 // no need to send to the jvm 00550 return; 00551 } 00552 QStringList args; 00553 args.append (QString::number (applet->appletId ())); 00554 args.append (QString::number ((int) objid)); 00555 applet->getContext()->derefObject (args); 00556 } 00557 00558 void KJavaAppletViewerLiveConnectExtension::jsEvent (const QStringList & args) { 00559 if (args.count () < 2 || !m_viewer->appletAlive ()) 00560 return; 00561 bool ok; 00562 unsigned long objid = args[0].toInt(&ok); 00563 QString event = args[1]; 00564 KParts::LiveConnectExtension::ArgList arglist; 00565 for (unsigned i = 2; i < args.count(); i += 2) 00566 // take a deep breath here 00567 arglist.push_back(KParts::LiveConnectExtension::ArgList::value_type((KParts::LiveConnectExtension::Type) args[i].toInt(), args[i+1])); 00568 emit partEvent (objid, event, arglist); 00569 } 00570 00571 int KJavaAppletViewerLiveConnectExtension::m_jssessions = 0; 00572 00573 //----------------------------------------------------------------------------- 00574 00575 #include "kjavaappletviewer.moc"
KDE Logo
This file is part of the documentation for khtml Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Sep 29 09:42:28 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003