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