kmail

urlhandlermanager.cpp

00001 /*  -*- c++ -*-
00002     urlhandlermanager.cpp
00003 
00004     This file is part of KMail, the KDE mail client.
00005     Copyright (c) 2002-2003 Klar�lvdalens Datakonsult AB
00006     Copyright (c) 2003      Marc Mutz <mutz@kde.org>
00007 
00008     KMail is free software; you can redistribute it and/or modify it
00009     under the terms of the GNU General Public License, version 2, as
00010     published by the Free Software Foundation.
00011 
00012     KMail is distributed in the hope that it will be useful, but
00013     WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015     General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021     In addition, as a special exception, the copyright holders give
00022     permission to link the code of this program with any edition of
00023     the Qt library by Trolltech AS, Norway (or with modified versions
00024     of Qt that use the same license as Qt), and distribute linked
00025     combinations including the two.  You must obey the GNU General
00026     Public License in all respects for all of the code used other than
00027     Qt.  If you modify this file, you may extend this exception to
00028     your version of the file, but you are not obligated to do so.  If
00029     you do not wish to do so, delete this exception statement from
00030     your version.
00031 */
00032 
00033 #ifdef HAVE_CONFIG_H
00034 #include <config.h>
00035 #endif
00036 
00037 #include "urlhandlermanager.h"
00038 
00039 #include "interfaces/urlhandler.h"
00040 #include "interfaces/bodyparturlhandler.h"
00041 #include "partNode.h"
00042 #include "partnodebodypart.h"
00043 #include "kmreaderwin.h"
00044 #include "kmkernel.h"
00045 #include "callback.h"
00046 
00047 #include <kimproxy.h>
00048 #include "stl_util.h"
00049 #include <kurl.h>
00050 
00051 #include <algorithm>
00052 using std::for_each;
00053 using std::remove;
00054 using std::find;
00055 
00056 KMail::URLHandlerManager * KMail::URLHandlerManager::self = 0;
00057 
00058 namespace {
00059   class KMailProtocolURLHandler : public KMail::URLHandler {
00060   public:
00061     KMailProtocolURLHandler() : KMail::URLHandler() {}
00062     ~KMailProtocolURLHandler() {}
00063 
00064     bool handleClick( const KURL &, KMReaderWin * ) const;
00065     bool handleContextMenuRequest( const KURL & url, const QPoint &, KMReaderWin * ) const {
00066       return url.protocol() == "kmail";
00067     }
00068     QString statusBarMessage( const KURL &, KMReaderWin * ) const;
00069   };
00070 
00071   class ExpandCollapseQuoteURLManager : public KMail::URLHandler {
00072   public:
00073     ExpandCollapseQuoteURLManager() : KMail::URLHandler() {}
00074     ~ExpandCollapseQuoteURLManager() {}
00075 
00076     bool handleClick( const KURL &, KMReaderWin * ) const;
00077     bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const {
00078       return false;
00079     }
00080     QString statusBarMessage( const KURL &, KMReaderWin * ) const;
00081 
00082   };
00083 
00084   class SMimeURLHandler : public KMail::URLHandler {
00085   public:
00086     SMimeURLHandler() : KMail::URLHandler() {}
00087     ~SMimeURLHandler() {}
00088 
00089     bool handleClick( const KURL &, KMReaderWin * ) const;
00090     bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const {
00091       return false;
00092     }
00093     QString statusBarMessage( const KURL &, KMReaderWin * ) const;
00094   };
00095 
00096   class MailToURLHandler : public KMail::URLHandler {
00097   public:
00098     MailToURLHandler() : KMail::URLHandler() {}
00099     ~MailToURLHandler() {}
00100 
00101     bool handleClick( const KURL &, KMReaderWin * ) const { return false; }
00102     bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const {
00103       return false;
00104     }
00105     QString statusBarMessage( const KURL &, KMReaderWin * ) const;
00106   };
00107 
00108   class HtmlAnchorHandler : public KMail::URLHandler {
00109   public:
00110     HtmlAnchorHandler() : KMail::URLHandler() {}
00111     ~HtmlAnchorHandler() {}
00112 
00113     bool handleClick( const KURL &, KMReaderWin * ) const;
00114     bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const {
00115       return false;
00116     }
00117     QString statusBarMessage( const KURL &, KMReaderWin * ) const { return QString::null; }
00118   };
00119 
00120   class AttachmentURLHandler : public KMail::URLHandler {
00121   public:
00122     AttachmentURLHandler() : KMail::URLHandler() {}
00123     ~AttachmentURLHandler() {}
00124 
00125     bool handleClick( const KURL &, KMReaderWin * ) const;
00126     bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const;
00127     QString statusBarMessage( const KURL &, KMReaderWin * ) const;
00128   private:
00129     partNode* partNodeForUrl( const KURL &url, KMReaderWin *w ) const;
00130     bool attachmentIsInHeader( const KURL &url ) const;
00131   };
00132 
00133   class ShowAuditLogURLHandler : public KMail::URLHandler {
00134   public:
00135       ShowAuditLogURLHandler() : KMail::URLHandler() {}
00136       ~ShowAuditLogURLHandler() {}
00137 
00138       bool handleClick( const KURL &, KMReaderWin * ) const;
00139       bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const;
00140       QString statusBarMessage( const KURL &, KMReaderWin * ) const;
00141   };
00142 
00143   class FallBackURLHandler : public KMail::URLHandler {
00144   public:
00145     FallBackURLHandler() : KMail::URLHandler() {}
00146     ~FallBackURLHandler() {}
00147 
00148     bool handleClick( const KURL &, KMReaderWin * ) const;
00149     bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const;
00150     QString statusBarMessage( const KURL & url, KMReaderWin * ) const {
00151       return url.prettyURL();
00152     }
00153   };
00154 
00155 } // anon namespace
00156 
00157 
00158 //
00159 //
00160 // BodyPartURLHandlerManager
00161 //
00162 //
00163 
00164 class KMail::URLHandlerManager::BodyPartURLHandlerManager : public KMail::URLHandler {
00165 public:
00166   BodyPartURLHandlerManager() : KMail::URLHandler() {}
00167   ~BodyPartURLHandlerManager();
00168 
00169   bool handleClick( const KURL &, KMReaderWin * ) const;
00170   bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const;
00171   QString statusBarMessage( const KURL &, KMReaderWin * ) const;
00172 
00173   void registerHandler( const Interface::BodyPartURLHandler * handler );
00174   void unregisterHandler( const Interface::BodyPartURLHandler * handler );
00175 
00176 private:
00177   typedef QValueVector<const Interface::BodyPartURLHandler*> BodyPartHandlerList;
00178   BodyPartHandlerList mHandlers;
00179 };
00180 
00181 KMail::URLHandlerManager::BodyPartURLHandlerManager::~BodyPartURLHandlerManager() {
00182   for_each( mHandlers.begin(), mHandlers.end(),
00183         DeleteAndSetToZero<Interface::BodyPartURLHandler>() );
00184 }
00185 
00186 void KMail::URLHandlerManager::BodyPartURLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) {
00187   if ( !handler )
00188     return;
00189   unregisterHandler( handler ); // don't produce duplicates
00190   mHandlers.push_back( handler );
00191 }
00192 
00193 void KMail::URLHandlerManager::BodyPartURLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) {
00194   // don't delete them, only remove them from the list!
00195   mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
00196 }
00197 
00198 static partNode * partNodeFromXKMailUrl( const KURL & url, KMReaderWin * w, QString * path ) {
00199   assert( path );
00200 
00201   if ( !w || url.protocol() != "x-kmail" )
00202     return 0;
00203   const QString urlPath = url.path();
00204 
00205   // urlPath format is: /bodypart/<random number>/<part id>/<path>
00206 
00207   kdDebug( 5006 ) << "BodyPartURLHandler: urlPath == \"" << urlPath << "\"" << endl;
00208   if ( !urlPath.startsWith( "/bodypart/" ) )
00209     return 0;
00210 
00211   const QStringList urlParts = QStringList::split( '/', urlPath.mid( 10 ), true );
00212   if ( urlParts.size() != 3 )
00213     return 0;
00214   bool ok = false;
00215   const int part_id = urlParts[1].toInt( &ok );
00216   if ( !ok )
00217     return 0;
00218   *path = KURL::decode_string( urlParts[2], 106 );
00219   return w->partNodeForId( part_id );
00220 }
00221 
00222 bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleClick( const KURL & url, KMReaderWin * w ) const {
00223   QString path;
00224   partNode * node = partNodeFromXKMailUrl( url, w, &path );
00225   if ( !node )
00226     return false;
00227   KMMessage *msg = w->message();
00228   if ( !msg ) return false;
00229   Callback callback( msg, w );
00230   KMail::PartNodeBodyPart part( *node, w->overrideCodec() );
00231   for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00232     if ( (*it)->handleClick( &part, path, callback ) )
00233       return true;
00234   return false;
00235 }
00236 
00237 bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const {
00238   QString path;
00239   partNode * node = partNodeFromXKMailUrl( url, w, &path );
00240   if ( !node )
00241     return false;
00242 
00243   KMail::PartNodeBodyPart part( *node, w->overrideCodec() );
00244   for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00245     if ( (*it)->handleContextMenuRequest( &part, path, p ) )
00246       return true;
00247   return false;
00248 }
00249 
00250 QString KMail::URLHandlerManager::BodyPartURLHandlerManager::statusBarMessage( const KURL & url, KMReaderWin * w ) const {
00251   QString path;
00252   partNode * node = partNodeFromXKMailUrl( url, w, &path );
00253   if ( !node )
00254     return QString::null;
00255 
00256   KMail::PartNodeBodyPart part( *node, w->overrideCodec() );
00257   for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) {
00258     const QString msg = (*it)->statusBarMessage( &part, path );
00259     if ( !msg.isEmpty() )
00260       return msg;
00261   }
00262   return QString::null;
00263 }
00264 
00265 //
00266 //
00267 // URLHandlerManager
00268 //
00269 //
00270 
00271 KMail::URLHandlerManager::URLHandlerManager() {
00272   registerHandler( new KMailProtocolURLHandler() );
00273   registerHandler( new ExpandCollapseQuoteURLManager() );
00274   registerHandler( new SMimeURLHandler() );
00275   registerHandler( new MailToURLHandler() );
00276   registerHandler( new HtmlAnchorHandler() );
00277   registerHandler( new AttachmentURLHandler() );
00278   registerHandler( mBodyPartURLHandlerManager = new BodyPartURLHandlerManager() );
00279   registerHandler( new ShowAuditLogURLHandler() );
00280   registerHandler( new FallBackURLHandler() );
00281 }
00282 
00283 KMail::URLHandlerManager::~URLHandlerManager() {
00284   for_each( mHandlers.begin(), mHandlers.end(),
00285         DeleteAndSetToZero<URLHandler>() );
00286 }
00287 
00288 void KMail::URLHandlerManager::registerHandler( const URLHandler * handler ) {
00289   if ( !handler )
00290     return;
00291   unregisterHandler( handler ); // don't produce duplicates
00292   mHandlers.push_back( handler );
00293 }
00294 
00295 void KMail::URLHandlerManager::unregisterHandler( const URLHandler * handler ) {
00296   // don't delete them, only remove them from the list!
00297   mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
00298 }
00299 
00300 void KMail::URLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) {
00301   if ( mBodyPartURLHandlerManager )
00302     mBodyPartURLHandlerManager->registerHandler( handler );
00303 }
00304 
00305 void KMail::URLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) {
00306   if ( mBodyPartURLHandlerManager )
00307     mBodyPartURLHandlerManager->unregisterHandler( handler );
00308 }
00309 
00310 bool KMail::URLHandlerManager::handleClick( const KURL & url, KMReaderWin * w ) const {
00311   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00312     if ( (*it)->handleClick( url, w ) )
00313       return true;
00314   return false;
00315 }
00316 
00317 bool KMail::URLHandlerManager::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const {
00318   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00319     if ( (*it)->handleContextMenuRequest( url, p, w ) )
00320       return true;
00321   return false;
00322 }
00323 
00324 QString KMail::URLHandlerManager::statusBarMessage( const KURL & url, KMReaderWin * w ) const {
00325   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) {
00326     const QString msg = (*it)->statusBarMessage( url, w );
00327     if ( !msg.isEmpty() )
00328       return msg;
00329   }
00330   return QString::null;
00331 }
00332 
00333 
00334 //
00335 //
00336 // URLHandler
00337 //
00338 //
00339 
00340 // these includes are temporary and should not be needed for the code
00341 // above this line, so they appear only here:
00342 #include "kmmessage.h"
00343 #include "kmreaderwin.h"
00344 #include "partNode.h"
00345 #include "kmmsgpart.h"
00346 
00347 #include <ui/messagebox.h>
00348 
00349 #include <klocale.h>
00350 #include <kprocess.h>
00351 #include <kmessagebox.h>
00352 #include <khtml_part.h>
00353 
00354 #include <qstring.h>
00355 
00356 namespace {
00357   bool KMailProtocolURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00358     if ( url.protocol() == "kmail" ) {
00359       if ( !w )
00360         return false;
00361 
00362       if ( url.path() == "showHTML" ) {
00363         w->setHtmlOverride( !w->htmlOverride() );
00364         w->update( true );
00365         return true;
00366       }
00367 
00368       if ( url.path() == "loadExternal" ) {
00369         w->setHtmlLoadExtOverride( !w->htmlLoadExtOverride() );
00370         w->update( true );
00371         return true;
00372       }
00373 
00374       if ( url.path() == "goOnline" ) {
00375         kmkernel->resumeNetworkJobs();
00376         return true;
00377       }
00378 
00379       if ( url.path() == "decryptMessage" ) {
00380         w->setDecryptMessageOverwrite( true );
00381         w->update( true );
00382         return true;
00383       }
00384 
00385       if ( url.path() == "showSignatureDetails" ) {
00386         w->setShowSignatureDetails( true );
00387         w->update( true );
00388         return true;
00389       }
00390 
00391       if ( url.path() == "hideSignatureDetails" ) {
00392         w->setShowSignatureDetails( false );
00393         w->update( true );
00394         return true;
00395       }
00396 
00397       if ( url.path() == "showAttachmentQuicklist" ) {
00398       w->saveRelativePosition();
00399       w->setShowAttachmentQuicklist( true );
00400       w->update( true );
00401       return true;
00402       }
00403 
00404       if ( url.path() == "hideAttachmentQuicklist" ) {
00405       w->saveRelativePosition();
00406       w->setShowAttachmentQuicklist( false );
00407       w->update( true );
00408       return true;
00409       }
00410 
00411 //       if ( url.path() == "startIMApp" )
00412 //       {
00413 //         kmkernel->imProxy()->startPreferredApp();
00414 //         return true;
00415 //       }
00416 //       //FIXME: handle startIMApp urls in their own handler, or rename this one
00417     }
00418     return false;
00419   }
00420 
00421   QString KMailProtocolURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const {
00422     if ( url.protocol() == "kmail" )
00423     {
00424       if ( url.path() == "showHTML" )
00425         return i18n("Turn on HTML rendering for this message.");
00426       if ( url.path() == "loadExternal" )
00427         return i18n("Load external references from the Internet for this message.");
00428       if ( url.path() == "goOnline" )
00429         return i18n("Work online.");
00430       if ( url.path() == "decryptMessage" )
00431         return i18n("Decrypt message.");
00432       if ( url.path() == "showSignatureDetails" )
00433         return i18n("Show signature details.");
00434       if ( url.path() == "hideSignatureDetails" )
00435         return i18n("Hide signature details.");
00436     }
00437     return QString::null ;
00438   }
00439 }
00440 
00441 namespace {
00442 
00443   bool ExpandCollapseQuoteURLManager::handleClick(
00444       const KURL & url, KMReaderWin * w ) const
00445   {
00446     //  kmail:levelquote/?num      -> the level quote to collapse.
00447     //  kmail:levelquote/?-num      -> expand all levels quote.
00448     if ( url.protocol() == "kmail" && url.path()=="levelquote" )
00449     {
00450       QString levelStr= url.query().mid( 1,url.query().length() );
00451       bool isNumber;
00452       int levelQuote= levelStr.toInt(&isNumber);
00453       if ( isNumber )
00454         w->slotLevelQuote( levelQuote );
00455       return true;
00456     }
00457     return false;
00458   }
00459   QString ExpandCollapseQuoteURLManager::statusBarMessage(
00460       const KURL & url, KMReaderWin * ) const
00461   {
00462       if ( url.protocol() == "kmail" && url.path() == "levelquote" )
00463       {
00464         QString query= url.query();
00465         if ( query.length()>=2 ) {
00466           if ( query[ 1 ] =='-'  ) {
00467             return i18n("Expand all quoted text.");
00468           }
00469           else {
00470             return i18n("Collapse quoted text.");
00471           }
00472         }
00473       }
00474       return QString::null ;
00475   }
00476 
00477 }
00478 
00479 // defined in kmreaderwin.cpp...
00480 extern bool foundSMIMEData( const QString aUrl, QString & displayName,
00481                 QString & libName, QString & keyId );
00482 
00483 namespace {
00484   bool SMimeURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00485     if ( !url.hasRef() )
00486       return false;
00487     QString displayName, libName, keyId;
00488     if ( !foundSMIMEData( url.path() + '#' + url.ref(), displayName, libName, keyId ) )
00489       return false;
00490     KProcess cmp;
00491     cmp << "kleopatra" << "-query" << keyId;
00492     if ( !cmp.start( KProcess::DontCare ) )
00493       KMessageBox::error( w, i18n("Could not start certificate manager. "
00494                   "Please check your installation."),
00495               i18n("KMail Error") );
00496     return true;
00497   }
00498 
00499   QString SMimeURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const {
00500     QString displayName, libName, keyId;
00501     if ( !foundSMIMEData( url.path() + '#' + url.ref(), displayName, libName, keyId ) )
00502       return QString::null;
00503     return i18n("Show certificate 0x%1").arg( keyId );
00504   }
00505 }
00506 
00507 namespace {
00508   bool HtmlAnchorHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00509     if ( url.hasHost() || url.path() != "/" || !url.hasRef() )
00510       return false;
00511     if ( w && !w->htmlPart()->gotoAnchor( url.ref() ) )
00512       static_cast<QScrollView*>( w->htmlPart()->widget() )->ensureVisible( 0, 0 );
00513     return true;
00514   }
00515 }
00516 
00517 namespace {
00518   QString MailToURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const {
00519     if ( url.protocol() != "mailto" )
00520       return QString::null;
00521     return KMMessage::decodeMailtoUrl( url.url() );
00522   }
00523 }
00524 
00525 namespace {
00526 
00527   partNode* AttachmentURLHandler::partNodeForUrl( const KURL &url, KMReaderWin *w ) const
00528   {
00529     if ( !w || !w->message() )
00530       return 0;
00531     if ( url.protocol() != "attachment" )
00532       return 0;
00533 
00534     bool ok;
00535     int nodeId = url.path().toInt( &ok );
00536     if ( !ok )
00537       return 0;
00538 
00539     partNode * node = w->partNodeForId( nodeId );
00540     return node;
00541   }
00542 
00543   bool AttachmentURLHandler::attachmentIsInHeader( const KURL &url ) const
00544   {
00545     bool inHeader = false;
00546     const QString place = url.queryItem( "place" ).lower();
00547     if ( place != QString::null ) {
00548       inHeader = ( place == "header" );
00549     }
00550     return inHeader;
00551   }
00552 
00553   bool AttachmentURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const
00554   {
00555     partNode * node = partNodeForUrl( url, w );
00556     if ( !node )
00557       return false;
00558 
00559     const bool inHeader = attachmentIsInHeader( url );
00560     const bool shouldShowDialog = !node->isDisplayedEmbedded() || !inHeader;
00561     if ( !shouldShowDialog )
00562       w->scrollToAttachment( node );
00563     else
00564       w->openAttachment( node->nodeId(), w->tempFileUrlFromPartNode( node ).path() );
00565     return true;
00566   }
00567 
00568   bool AttachmentURLHandler::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const
00569   {
00570     partNode * node = partNodeForUrl( url, w );
00571     if ( !node )
00572       return false;
00573 
00574     w->showAttachmentPopup( node->nodeId(), w->tempFileUrlFromPartNode( node ).path(), p );
00575     return true;
00576   }
00577 
00578   QString AttachmentURLHandler::statusBarMessage( const KURL & url, KMReaderWin * w ) const
00579   {
00580     partNode * node = partNodeForUrl( url, w );
00581     if ( !node )
00582       return QString::null;
00583 
00584     const KMMessagePart & msgPart = node->msgPart();
00585     QString name = msgPart.fileName();
00586     if ( name.isEmpty() )
00587       name = msgPart.name();
00588     if ( !name.isEmpty() )
00589       return i18n( "Attachment: %1" ).arg( name );
00590     return i18n( "Attachment #%1 (unnamed)" ).arg( KMReaderWin::msgPartFromUrl( url ) );
00591   }
00592 }
00593 
00594 namespace {
00595   static QString extractAuditLog( const KURL & url ) {
00596     if ( url.protocol() != "kmail" || url.path() != "showAuditLog" )
00597       return QString();
00598     assert( !url.queryItem( "log" ).isEmpty() );
00599     return url.queryItem( "log" );
00600   }
00601 
00602   bool ShowAuditLogURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00603     const QString auditLog = extractAuditLog( url );
00604     if ( auditLog.isEmpty() )
00605         return false;
00606     Kleo::MessageBox::auditLog( w, auditLog );
00607     return true;
00608   }
00609 
00610   bool ShowAuditLogURLHandler::handleContextMenuRequest( const KURL & url, const QPoint &, KMReaderWin * w ) const
00611   {
00612     Q_UNUSED( w );
00613     // disable RMB for my own links:
00614     return !extractAuditLog( url ).isEmpty();
00615   }
00616 
00617   QString ShowAuditLogURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const {
00618     if ( extractAuditLog( url ).isEmpty() )
00619       return QString();
00620     else
00621       return i18n("Show GnuPG Audit Log for this operation");
00622   }
00623 }
00624 
00625 namespace {
00626   bool FallBackURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00627     if ( w )
00628       w->emitUrlClicked( url, Qt::LeftButton );
00629     return true;
00630   }
00631 
00632   bool FallBackURLHandler::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const {
00633     if ( w )
00634       w->emitPopupMenu( url, p );
00635     return true;
00636   }
00637 }
KDE Home | KDE Accessibility Home | Description of Access Keys