kparts Library API Documentation

browserextension.cpp

00001  /* This file is part of the KDE project
00002    Copyright (C) 1999 Simon Hausmann <hausmann@kde.org>
00003              (C) 1999 David Faure <faure@kde.org>
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 "browserextension.h"
00021 
00022 #include <qapplication.h>
00023 #include <qclipboard.h>
00024 #include <qtimer.h>
00025 #include <qobjectlist.h>
00026 #include <qmetaobject.h>
00027 #include <qregexp.h>
00028 #include <qstrlist.h>
00029 #include <qstylesheet.h>
00030 
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <kmessagebox.h>
00034 #include <kstaticdeleter.h>
00035 #include <kurifilter.h>
00036 #include <assert.h>
00037 
00038 using namespace KParts;
00039 
00040 const char *OpenURLEvent::s_strOpenURLEvent = "KParts/BrowserExtension/OpenURLevent";
00041 
00042 class OpenURLEvent::OpenURLEventPrivate
00043 {
00044 public:
00045   OpenURLEventPrivate()
00046   {
00047   }
00048   ~OpenURLEventPrivate()
00049   {
00050   }
00051 };
00052 
00053 OpenURLEvent::OpenURLEvent( ReadOnlyPart *part, const KURL &url, const URLArgs &args )
00054 : Event( s_strOpenURLEvent ), m_part( part ), m_url( url ), m_args( args )
00055 {
00056 //  d = new OpenURLEventPrivate();
00057 }
00058 
00059 OpenURLEvent::~OpenURLEvent()
00060 {
00061 //  delete d;
00062 }
00063 
00064 namespace KParts
00065 {
00066 
00067 struct URLArgsPrivate
00068 {
00069     URLArgsPrivate() {
00070       doPost = false;
00071       redirectedRequest = false;
00072       lockHistory = false;
00073       newTab = false;
00074       forcesNewWindow = false;
00075     }
00076     QString contentType; // for POST
00077     QMap<QString, QString> metaData;
00078     bool doPost;
00079     bool redirectedRequest;
00080     bool lockHistory;
00081     bool newTab;
00082     bool forcesNewWindow;
00083 };
00084 
00085 }
00086 
00087 URLArgs::URLArgs()
00088 {
00089   reload = false;
00090   xOffset = 0;
00091   yOffset = 0;
00092   trustedSource = false;
00093   d = 0L; // Let's build it on demand for now
00094 }
00095 
00096 
00097 URLArgs::URLArgs( bool _reload, int _xOffset, int _yOffset, const QString &_serviceType )
00098 {
00099   reload = _reload;
00100   xOffset = _xOffset;
00101   yOffset = _yOffset;
00102   serviceType = _serviceType;
00103   d = 0L; // Let's build it on demand for now
00104 }
00105 
00106 URLArgs::URLArgs( const URLArgs &args )
00107 {
00108   d = 0L;
00109   (*this) = args;
00110 }
00111 
00112 URLArgs &URLArgs::operator=(const URLArgs &args)
00113 {
00114   if (this == &args) return *this;
00115 
00116   delete d; d= 0;
00117 
00118   reload = args.reload;
00119   xOffset = args.xOffset;
00120   yOffset = args.yOffset;
00121   serviceType = args.serviceType;
00122   postData = args.postData;
00123   frameName = args.frameName;
00124   docState = args.docState;
00125   trustedSource = args.trustedSource;
00126 
00127   if ( args.d )
00128      d = new URLArgsPrivate( * args.d );
00129 
00130   return *this;
00131 }
00132 
00133 URLArgs::~URLArgs()
00134 {
00135   delete d;
00136   d = 0;
00137 }
00138 
00139 void URLArgs::setContentType( const QString & contentType )
00140 {
00141   if (!d)
00142     d = new URLArgsPrivate;
00143   d->contentType = contentType;
00144 }
00145 
00146 void URLArgs::setRedirectedRequest( bool redirected )
00147 {
00148   if (!d)
00149      d = new URLArgsPrivate;
00150   d->redirectedRequest = redirected;
00151 }
00152 
00153 bool URLArgs::redirectedRequest () const
00154 {
00155   return d ? d->redirectedRequest : false;
00156 }
00157 
00158 QString URLArgs::contentType() const
00159 {
00160   return d ? d->contentType : QString::null;
00161 }
00162 
00163 QMap<QString, QString> &URLArgs::metaData()
00164 {
00165   if (!d)
00166      d = new URLArgsPrivate;
00167   return d->metaData;
00168 }
00169 
00170 void URLArgs::setDoPost( bool enable )
00171 {
00172     if ( !d )
00173         d = new URLArgsPrivate;
00174     d->doPost = enable;
00175 }
00176 
00177 bool URLArgs::doPost() const
00178 {
00179     return d ? d->doPost : false;
00180 }
00181 
00182 void URLArgs::setLockHistory( bool lock )
00183 {
00184   if (!d)
00185      d = new URLArgsPrivate;
00186   d->lockHistory = lock;
00187 }
00188 
00189 bool URLArgs::lockHistory() const
00190 {
00191     return d ? d->lockHistory : false;
00192 }
00193 
00194 void URLArgs::setNewTab( bool newTab )
00195 {
00196   if (!d)
00197      d = new URLArgsPrivate;
00198   d->newTab = newTab;
00199 }
00200 
00201 bool URLArgs::newTab() const
00202 {
00203     return d ? d->newTab : false;
00204 }
00205 
00206 void URLArgs::setForcesNewWindow( bool forcesNewWindow )
00207 {
00208   if (!d)
00209      d = new URLArgsPrivate;
00210   d->forcesNewWindow = forcesNewWindow;
00211 }
00212 
00213 bool URLArgs::forcesNewWindow() const
00214 {
00215     return d ? d->forcesNewWindow : false;
00216 }
00217 
00218 namespace KParts
00219 {
00220 
00221 struct WindowArgsPrivate
00222 {
00223 };
00224 
00225 }
00226 
00227 WindowArgs::WindowArgs()
00228 {
00229     x = y = width = height = -1;
00230     fullscreen = false;
00231     menuBarVisible = true;
00232     toolBarsVisible = true;
00233     statusBarVisible = true;
00234     resizable = true;
00235     lowerWindow = false;
00236     d = 0;
00237 }
00238 
00239 WindowArgs::WindowArgs( const WindowArgs &args )
00240 {
00241     d = 0;
00242     (*this) = args;
00243 }
00244 
00245 WindowArgs &WindowArgs::operator=( const WindowArgs &args )
00246 {
00247     if ( this == &args ) return *this;
00248 
00249     delete d; d = 0;
00250 
00251     x = args.x;
00252     y = args.y;
00253     width = args.width;
00254     height = args.height;
00255     fullscreen = args.fullscreen;
00256     menuBarVisible = args.menuBarVisible;
00257     toolBarsVisible = args.toolBarsVisible;
00258     statusBarVisible = args.statusBarVisible;
00259     resizable = args.resizable;
00260     lowerWindow = args.lowerWindow;
00261 
00262     /*
00263     if ( args.d )
00264     {
00265       [ ... ]
00266     }
00267     */
00268 
00269     return *this;
00270 }
00271 
00272 WindowArgs::WindowArgs( const QRect &_geometry, bool _fullscreen, bool _menuBarVisible,
00273                         bool _toolBarsVisible, bool _statusBarVisible, bool _resizable )
00274 {
00275     d = 0;
00276     x = _geometry.x();
00277     y = _geometry.y();
00278     width = _geometry.width();
00279     height = _geometry.height();
00280     fullscreen = _fullscreen;
00281     menuBarVisible = _menuBarVisible;
00282     toolBarsVisible = _toolBarsVisible;
00283     statusBarVisible = _statusBarVisible;
00284     resizable = _resizable;
00285     lowerWindow = false;
00286 }
00287 
00288 WindowArgs::WindowArgs( int _x, int _y, int _width, int _height, bool _fullscreen,
00289                         bool _menuBarVisible, bool _toolBarsVisible,
00290                         bool _statusBarVisible, bool _resizable )
00291 {
00292     d = 0;
00293     x = _x;
00294     y = _y;
00295     width = _width;
00296     height = _height;
00297     fullscreen = _fullscreen;
00298     menuBarVisible = _menuBarVisible;
00299     toolBarsVisible = _toolBarsVisible;
00300     statusBarVisible = _statusBarVisible;
00301     resizable = _resizable;
00302     lowerWindow = false;
00303 }
00304 
00305 namespace KParts
00306 {
00307 
00308 // Internal class, use to store the status of the actions
00309 class KBitArray
00310 {
00311 public:
00312     int val;
00313     KBitArray() { val = 0; }
00314     bool operator [](int index) { return (val & (1 << index)) ? true : false; }
00315     void setBit(int index, bool value) {
00316         if (value) val = val | (1 << index);
00317         else val = val & ~(1 << index);
00318     }
00319 };
00320 
00321 class BrowserExtensionPrivate
00322 {
00323 public:
00324   BrowserExtensionPrivate()
00325   {
00326       m_browserInterface = 0;
00327   }
00328   ~BrowserExtensionPrivate()
00329   {
00330   }
00331 
00332   struct DelayedRequest {
00333     KURL m_delayedURL;
00334     KParts::URLArgs m_delayedArgs;
00335   };
00336   QValueList<DelayedRequest> m_requests;
00337   bool m_urlDropHandlingEnabled;
00338   KBitArray m_actionStatus;
00339   BrowserInterface *m_browserInterface;
00340 };
00341 
00342 }
00343 
00344 BrowserExtension::ActionSlotMap * BrowserExtension::s_actionSlotMap = 0L;
00345 static KStaticDeleter<BrowserExtension::ActionSlotMap> actionSlotMapsd;
00346 BrowserExtension::ActionNumberMap * BrowserExtension::s_actionNumberMap = 0L;
00347 static KStaticDeleter<BrowserExtension::ActionNumberMap> actionNumberMapsd;
00348 
00349 BrowserExtension::BrowserExtension( KParts::ReadOnlyPart *parent,
00350                                     const char *name )
00351 : QObject( parent, name), m_part( parent )
00352 {
00353   //kdDebug() << "BrowserExtension::BrowserExtension() " << this << endl;
00354   d = new BrowserExtensionPrivate;
00355   d->m_urlDropHandlingEnabled = false;
00356 
00357   if ( !s_actionSlotMap )
00358       // Create the action-slot map
00359       createActionSlotMap();
00360 
00361   // Set the initial status of the actions depending on whether
00362   // they're supported or not
00363   ActionSlotMap::ConstIterator it = s_actionSlotMap->begin();
00364   ActionSlotMap::ConstIterator itEnd = s_actionSlotMap->end();
00365   QStrList slotNames = metaObject()->slotNames();
00366   for ( int i=0 ; it != itEnd ; ++it, ++i )
00367   {
00368       // Does the extension have a slot with the name of this action ?
00369       d->m_actionStatus.setBit( i, slotNames.contains( it.key()+"()" ) );
00370   }
00371 
00372   connect( m_part, SIGNAL( completed() ),
00373            this, SLOT( slotCompleted() ) );
00374   connect( this, SIGNAL( openURLRequest( const KURL &, const KParts::URLArgs & ) ),
00375            this, SLOT( slotOpenURLRequest( const KURL &, const KParts::URLArgs & ) ) );
00376   connect( this, SIGNAL( enableAction( const char *, bool ) ),
00377            this, SLOT( slotEnableAction( const char *, bool ) ) );
00378 }
00379 
00380 BrowserExtension::~BrowserExtension()
00381 {
00382   //kdDebug() << "BrowserExtension::~BrowserExtension() " << this << endl;
00383   delete d;
00384 }
00385 
00386 void BrowserExtension::setURLArgs( const URLArgs &args )
00387 {
00388   m_args = args;
00389 }
00390 
00391 URLArgs BrowserExtension::urlArgs() const
00392 {
00393   return m_args;
00394 }
00395 
00396 int BrowserExtension::xOffset()
00397 {
00398   return 0;
00399 }
00400 
00401 int BrowserExtension::yOffset()
00402 {
00403   return 0;
00404 }
00405 
00406 void BrowserExtension::saveState( QDataStream &stream )
00407 {
00408   stream << m_part->url() << (Q_INT32)xOffset() << (Q_INT32)yOffset();
00409 }
00410 
00411 void BrowserExtension::restoreState( QDataStream &stream )
00412 {
00413   KURL u;
00414   Q_INT32 xOfs, yOfs;
00415   stream >> u >> xOfs >> yOfs;
00416 
00417   URLArgs args( urlArgs() );
00418   args.xOffset = xOfs;
00419   args.yOffset = yOfs;
00420 
00421   setURLArgs( args );
00422 
00423   m_part->openURL( u );
00424 }
00425 
00426 bool BrowserExtension::isURLDropHandlingEnabled() const
00427 {
00428     return d->m_urlDropHandlingEnabled;
00429 }
00430 
00431 void BrowserExtension::setURLDropHandlingEnabled( bool enable )
00432 {
00433     d->m_urlDropHandlingEnabled = enable;
00434 }
00435 
00436 void BrowserExtension::slotCompleted()
00437 {
00438   //empty the argument stuff, to avoid bogus/invalid values when opening a new url
00439   setURLArgs( URLArgs() );
00440 }
00441 
00442 void BrowserExtension::pasteRequest()
00443 {
00444     QCString plain("plain");
00445     QString url = QApplication::clipboard()->text(plain, QClipboard::Selection).stripWhiteSpace();
00446     // Remove linefeeds and any whitespace surrounding it.
00447     url.replace(QRegExp("[\\ ]*\\n+[\\ ]*"),"");
00448 
00449     // Check if it's a URL
00450     QStringList filters = KURIFilter::self()->pluginNames();
00451     filters.remove( "kuriikwsfilter" );
00452     filters.remove( "localdomainurifilter" );
00453     KURIFilterData filterData;
00454     filterData.setData( url );
00455     filterData.setCheckForExecutables( false );
00456     if ( KURIFilter::self()->filterURI( filterData, filters ) )
00457     {
00458         switch ( filterData.uriType() )
00459     {
00460         case KURIFilterData::LOCAL_FILE:
00461         case KURIFilterData::LOCAL_DIR:
00462         case KURIFilterData::NET_PROTOCOL:
00463             slotOpenURLRequest( filterData.uri(), KParts::URLArgs() );
00464         break;
00465         case KURIFilterData::ERROR:
00466         KMessageBox::sorry( m_part->widget(), filterData.errorMsg() );
00467         break;
00468         default:
00469         break;
00470     }
00471     }
00472     else if ( KURIFilter::self()->filterURI( filterData, "kuriikwsfilter" ) && url.length() < 250 )
00473     {
00474         if ( KMessageBox::questionYesNo( m_part->widget(),
00475             i18n( "<qt>Do you want to search the Internet for <b>%1</b>?" ).arg( QStyleSheet::escape(url) ),
00476             i18n( "Internet Search" ), KGuiItem( i18n( "&Search" ), "find"),
00477             KStdGuiItem::cancel(), "MiddleClickSearch" ) == KMessageBox::Yes)
00478           slotOpenURLRequest( filterData.uri(), KParts::URLArgs() );
00479     }
00480 }
00481 
00482 void BrowserExtension::slotOpenURLRequest( const KURL &url, const KParts::URLArgs &args )
00483 {
00484     //kdDebug() << this << " BrowserExtension::slotOpenURLRequest(): url=" << url.url() << endl;
00485     BrowserExtensionPrivate::DelayedRequest req;
00486     req.m_delayedURL = url;
00487     req.m_delayedArgs = args;
00488     d->m_requests.append( req );
00489     QTimer::singleShot( 0, this, SLOT( slotEmitOpenURLRequestDelayed() ) );
00490 }
00491 
00492 void BrowserExtension::slotEmitOpenURLRequestDelayed()
00493 {
00494     if (d->m_requests.isEmpty()) return;
00495     BrowserExtensionPrivate::DelayedRequest req = d->m_requests.front();
00496     d->m_requests.pop_front();
00497     emit openURLRequestDelayed( req.m_delayedURL, req.m_delayedArgs );
00498     // tricky: do not do anything here! (no access to member variables, etc.)
00499 }
00500 
00501 void BrowserExtension::setBrowserInterface( BrowserInterface *impl )
00502 {
00503     d->m_browserInterface = impl;
00504 }
00505 
00506 BrowserInterface *BrowserExtension::browserInterface() const
00507 {
00508     return d->m_browserInterface;
00509 }
00510 
00511 void BrowserExtension::slotEnableAction( const char * name, bool enabled )
00512 {
00513     //kdDebug() << "BrowserExtension::slotEnableAction " << name << " " << enabled << endl;
00514     ActionNumberMap::ConstIterator it = s_actionNumberMap->find( name );
00515     if ( it != s_actionNumberMap->end() )
00516     {
00517         d->m_actionStatus.setBit( it.data(), enabled );
00518         //kdDebug() << "BrowserExtension::slotEnableAction setting bit " << it.data() << " to " << enabled << endl;
00519     }
00520     else
00521         kdWarning() << "BrowserExtension::slotEnableAction unknown action " << name << endl;
00522 }
00523 
00524 bool BrowserExtension::isActionEnabled( const char * name ) const
00525 {
00526     int actionNumber = (*s_actionNumberMap)[ name ];
00527     return d->m_actionStatus[ actionNumber ];
00528 }
00529 
00530 // for compatibility
00531 BrowserExtension::ActionSlotMap BrowserExtension::actionSlotMap()
00532 {
00533     return *actionSlotMapPtr();
00534 }
00535 
00536 BrowserExtension::ActionSlotMap * BrowserExtension::actionSlotMapPtr()
00537 {
00538     if (!s_actionSlotMap)
00539         createActionSlotMap();
00540     return s_actionSlotMap;
00541 }
00542 
00543 void BrowserExtension::createActionSlotMap()
00544 {
00545     assert(!s_actionSlotMap);
00546     s_actionSlotMap = actionSlotMapsd.setObject( s_actionSlotMap, new ActionSlotMap );
00547 
00548     s_actionSlotMap->insert( "cut", SLOT( cut() ) );
00549     s_actionSlotMap->insert( "copy", SLOT( copy() ) );
00550     s_actionSlotMap->insert( "paste", SLOT( paste() ) );
00551     s_actionSlotMap->insert( "rename", SLOT( rename() ) );
00552     s_actionSlotMap->insert( "trash", SLOT( trash() ) );
00553     s_actionSlotMap->insert( "del", SLOT( del() ) );
00554     s_actionSlotMap->insert( "properties", SLOT( properties() ) );
00555     s_actionSlotMap->insert( "editMimeType", SLOT( editMimeType() ) );
00556     s_actionSlotMap->insert( "print", SLOT( print() ) );
00557     // Tricky. Those aren't actions in fact, but simply methods that a browserextension
00558     // can have or not. No need to return them here.
00559     //s_actionSlotMap->insert( "reparseConfiguration", SLOT( reparseConfiguration() ) );
00560     //s_actionSlotMap->insert( "refreshMimeTypes", SLOT( refreshMimeTypes() ) );
00561     // nothing for setSaveViewPropertiesLocally either
00562 
00563     // Create the action-number map
00564     assert(!s_actionNumberMap);
00565     s_actionNumberMap = actionNumberMapsd.setObject( s_actionNumberMap, new ActionNumberMap );
00566     ActionSlotMap::ConstIterator it = s_actionSlotMap->begin();
00567     ActionSlotMap::ConstIterator itEnd = s_actionSlotMap->end();
00568     for ( int i=0 ; it != itEnd ; ++it, ++i )
00569     {
00570         //kdDebug(1202) << " action " << it.key() << " number " << i << endl;
00571         s_actionNumberMap->insert( it.key(), i );
00572     }
00573 }
00574 
00575 BrowserExtension *BrowserExtension::childObject( QObject *obj )
00576 {
00577     if ( !obj || !obj->children() )
00578         return 0L;
00579 
00580     // we try to do it on our own, in hope that we are faster than
00581     // queryList, which looks kind of big :-)
00582     const QObjectList *children = obj->children();
00583     QObjectListIt it( *children );
00584     for (; it.current(); ++it )
00585         if ( it.current()->inherits( "KParts::BrowserExtension" ) )
00586             return static_cast<KParts::BrowserExtension *>( it.current() );
00587 
00588     return 0L;
00589 }
00590 
00591 namespace KParts
00592 {
00593 
00594 class BrowserHostExtension::BrowserHostExtensionPrivate
00595 {
00596 public:
00597   BrowserHostExtensionPrivate()
00598   {
00599   }
00600   ~BrowserHostExtensionPrivate()
00601   {
00602   }
00603 
00604   KParts::ReadOnlyPart *m_part;
00605 };
00606 
00607 }
00608 
00609 BrowserHostExtension::BrowserHostExtension( KParts::ReadOnlyPart *parent, const char *name )
00610  : QObject( parent, name )
00611 {
00612   d = new BrowserHostExtensionPrivate;
00613   d->m_part = parent;
00614 }
00615 
00616 BrowserHostExtension::~BrowserHostExtension()
00617 {
00618   delete d;
00619 }
00620 
00621 QStringList BrowserHostExtension::frameNames() const
00622 {
00623   return QStringList();
00624 }
00625 
00626 const QPtrList<KParts::ReadOnlyPart> BrowserHostExtension::frames() const
00627 {
00628   return QPtrList<KParts::ReadOnlyPart>();
00629 }
00630 
00631 bool BrowserHostExtension::openURLInFrame( const KURL &, const KParts::URLArgs & )
00632 {
00633   return false;
00634 }
00635 
00636 BrowserHostExtension *BrowserHostExtension::childObject( QObject *obj )
00637 {
00638     if ( !obj || !obj->children() )
00639         return 0L;
00640 
00641     // we try to do it on our own, in hope that we are faster than
00642     // queryList, which looks kind of big :-)
00643     const QObjectList *children = obj->children();
00644     QObjectListIt it( *children );
00645     for (; it.current(); ++it )
00646         if ( it.current()->inherits( "KParts::BrowserHostExtension" ) )
00647             return static_cast<KParts::BrowserHostExtension *>( it.current() );
00648 
00649     return 0L;
00650 }
00651 
00652 void BrowserExtension::virtual_hook( int, void* )
00653 { /*BASE::virtual_hook( id, data );*/ }
00654 
00655 BrowserHostExtension *
00656 BrowserHostExtension::findFrameParent(KParts::ReadOnlyPart *callingPart, const QString &frame)
00657 {
00658     FindFrameParentParams param;
00659     param.parent = 0;
00660     param.callingPart = callingPart;
00661     param.frame = frame;
00662     virtual_hook(VIRTUAL_FIND_FRAME_PARENT, &param);
00663     return param.parent;
00664 }
00665 
00666 void BrowserHostExtension::virtual_hook( int, void* )
00667 { /*BASE::virtual_hook( id, data );*/ }
00668 
00669 LiveConnectExtension::LiveConnectExtension( KParts::ReadOnlyPart *parent, const char *name ) : QObject( parent, name) {}
00670 
00671 bool LiveConnectExtension::get( const unsigned long, const QString &, Type &, unsigned long &, QString & ) {
00672     return false;
00673 }
00674 
00675 bool LiveConnectExtension::put( const unsigned long, const QString &, const QString & ) {
00676       return false;
00677 }
00678 
00679 bool LiveConnectExtension::call( const unsigned long, const QString &, const QStringList &, Type &, unsigned long &, QString & ) {
00680       return false;
00681 }
00682 
00683 void LiveConnectExtension::unregister( const unsigned long ) {}
00684 
00685 LiveConnectExtension *LiveConnectExtension::childObject( QObject *obj )
00686 {
00687     if ( !obj || !obj->children() )
00688         return 0L;
00689 
00690     // we try to do it on our own, in hope that we are faster than
00691     // queryList, which looks kind of big :-)
00692     const QObjectList *children = obj->children();
00693     QObjectListIt it( *children );
00694     for (; it.current(); ++it )
00695         if ( it.current()->inherits( "KParts::LiveConnectExtension" ) )
00696             return static_cast<KParts::LiveConnectExtension *>( it.current() );
00697 
00698     return 0L;
00699 }
00700 
00701 #include "browserextension.moc"
KDE Logo
This file is part of the documentation for kparts Library Version 3.4.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Aug 2 12:25:07 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003