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 TQt library by Trolltech AS, Norway (or with modified versions
00024     of TQt that use the same license as TQt), 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     TQt.  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 #include "stl_util.h"
00047 
00048 #include <kstandarddirs.h>
00049 #include <kurldrag.h>
00050 #include <tdeimproxy.h>
00051 #include <kurl.h>
00052 
00053 #include <algorithm>
00054 using std::for_each;
00055 using std::remove;
00056 using std::find;
00057 
00058 KMail::URLHandlerManager * KMail::URLHandlerManager::self = 0;
00059 
00060 namespace {
00061   class KMailProtocolURLHandler : public KMail::URLHandler {
00062   public:
00063     KMailProtocolURLHandler() : KMail::URLHandler() {}
00064     ~KMailProtocolURLHandler() {}
00065 
00066     bool handleClick( const KURL &, KMReaderWin * ) const;
00067     bool handleContextMenuRequest( const KURL & url, const TQPoint &, KMReaderWin * ) const {
00068       return url.protocol() == "kmail";
00069     }
00070     TQString statusBarMessage( const KURL &, KMReaderWin * ) const;
00071   };
00072 
00073   class ExpandCollapseQuoteURLManager : public KMail::URLHandler {
00074   public:
00075     ExpandCollapseQuoteURLManager() : KMail::URLHandler() {}
00076     ~ExpandCollapseQuoteURLManager() {}
00077 
00078     bool handleClick( const KURL &, KMReaderWin * ) const;
00079     bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const {
00080       return false;
00081     }
00082     TQString statusBarMessage( const KURL &, KMReaderWin * ) const;
00083 
00084   };
00085 
00086   class SMimeURLHandler : public KMail::URLHandler {
00087   public:
00088     SMimeURLHandler() : KMail::URLHandler() {}
00089     ~SMimeURLHandler() {}
00090 
00091     bool handleClick( const KURL &, KMReaderWin * ) const;
00092     bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const {
00093       return false;
00094     }
00095     TQString statusBarMessage( const KURL &, KMReaderWin * ) const;
00096   };
00097 
00098   class MailToURLHandler : public KMail::URLHandler {
00099   public:
00100     MailToURLHandler() : KMail::URLHandler() {}
00101     ~MailToURLHandler() {}
00102 
00103     bool handleClick( const KURL &, KMReaderWin * ) const { return false; }
00104     bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const {
00105       return false;
00106     }
00107     TQString statusBarMessage( const KURL &, KMReaderWin * ) const;
00108   };
00109 
00110   class HtmlAnchorHandler : public KMail::URLHandler {
00111   public:
00112     HtmlAnchorHandler() : KMail::URLHandler() {}
00113     ~HtmlAnchorHandler() {}
00114 
00115     bool handleClick( const KURL &, KMReaderWin * ) const;
00116     bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const {
00117       return false;
00118     }
00119     TQString statusBarMessage( const KURL &, KMReaderWin * ) const { return TQString(); }
00120   };
00121 
00122   class AttachmentURLHandler : public KMail::URLHandler {
00123   public:
00124     AttachmentURLHandler() : KMail::URLHandler() {}
00125     ~AttachmentURLHandler() {}
00126 
00127     bool handleClick( const KURL &, KMReaderWin * ) const;
00128     bool handleShiftClick( const KURL &url, KMReaderWin *window ) const;
00129     bool handleDrag( const KURL &url, const TQString& imagePath, KMReaderWin *window ) const;
00130     bool willHandleDrag( const KURL &url, const TQString& imagePath, KMReaderWin *window ) const;
00131     bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const;
00132     TQString statusBarMessage( const KURL &, KMReaderWin * ) const;
00133   private:
00134     partNode* partNodeForUrl( const KURL &url, KMReaderWin *w ) const;
00135     bool attachmentIsInHeader( const KURL &url ) const;
00136   };
00137 
00138   class ShowAuditLogURLHandler : public KMail::URLHandler {
00139   public:
00140       ShowAuditLogURLHandler() : KMail::URLHandler() {}
00141       ~ShowAuditLogURLHandler() {}
00142 
00143       bool handleClick( const KURL &, KMReaderWin * ) const;
00144       bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const;
00145       TQString statusBarMessage( const KURL &, KMReaderWin * ) const;
00146   };
00147 
00148   // Handler that prevents dragging of internal images added by KMail, such as the envelope image
00149   // in the enterprise header
00150   class InternalImageURLHandler : public KMail::URLHandler {
00151   public:
00152       InternalImageURLHandler() : KMail::URLHandler()
00153         {}
00154       ~InternalImageURLHandler()
00155         {}
00156       bool handleDrag( const KURL &url, const TQString& imagePath, KMReaderWin *window ) const;
00157       bool willHandleDrag( const KURL &url, const TQString& imagePath, KMReaderWin *window ) const;
00158       bool handleClick( const KURL &, KMReaderWin * ) const
00159         { return false; }
00160       bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const
00161         { return false; }
00162       TQString statusBarMessage( const KURL &, KMReaderWin * ) const
00163         { return TQString(); }
00164   };
00165 
00166   class FallBackURLHandler : public KMail::URLHandler {
00167   public:
00168     FallBackURLHandler() : KMail::URLHandler() {}
00169     ~FallBackURLHandler() {}
00170 
00171     bool handleClick( const KURL &, KMReaderWin * ) const;
00172     bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const;
00173     TQString statusBarMessage( const KURL & url, KMReaderWin * ) const {
00174       return url.prettyURL();
00175     }
00176   };
00177 
00178 } // anon namespace
00179 
00180 
00181 //
00182 //
00183 // BodyPartURLHandlerManager
00184 //
00185 //
00186 
00187 class KMail::URLHandlerManager::BodyPartURLHandlerManager : public KMail::URLHandler {
00188 public:
00189   BodyPartURLHandlerManager() : KMail::URLHandler() {}
00190   ~BodyPartURLHandlerManager();
00191 
00192   bool handleClick( const KURL &, KMReaderWin * ) const;
00193   bool handleContextMenuRequest( const KURL &, const TQPoint &, KMReaderWin * ) const;
00194   TQString statusBarMessage( const KURL &, KMReaderWin * ) const;
00195 
00196   void registerHandler( const Interface::BodyPartURLHandler * handler );
00197   void unregisterHandler( const Interface::BodyPartURLHandler * handler );
00198 
00199 private:
00200   typedef TQValueVector<const Interface::BodyPartURLHandler*> BodyPartHandlerList;
00201   BodyPartHandlerList mHandlers;
00202 };
00203 
00204 KMail::URLHandlerManager::BodyPartURLHandlerManager::~BodyPartURLHandlerManager() {
00205   for_each( mHandlers.begin(), mHandlers.end(),
00206         DeleteAndSetToZero<Interface::BodyPartURLHandler>() );
00207 }
00208 
00209 void KMail::URLHandlerManager::BodyPartURLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) {
00210   if ( !handler )
00211     return;
00212   unregisterHandler( handler ); // don't produce duplicates
00213   mHandlers.push_back( handler );
00214 }
00215 
00216 void KMail::URLHandlerManager::BodyPartURLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) {
00217   // don't delete them, only remove them from the list!
00218   mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
00219 }
00220 
00221 static partNode * partNodeFromXKMailUrl( const KURL & url, KMReaderWin * w, TQString * path ) {
00222   assert( path );
00223 
00224   if ( !w || url.protocol() != "x-kmail" )
00225     return 0;
00226   const TQString urlPath = url.path();
00227 
00228   // urlPath format is: /bodypart/<random number>/<part id>/<path>
00229 
00230   kdDebug( 5006 ) << "BodyPartURLHandler: urlPath == \"" << urlPath << "\"" << endl;
00231   if ( !urlPath.startsWith( "/bodypart/" ) )
00232     return 0;
00233 
00234   const TQStringList urlParts = TQStringList::split( '/', urlPath.mid( 10 ), true );
00235   if ( urlParts.size() != 3 )
00236     return 0;
00237   bool ok = false;
00238   const int part_id = urlParts[1].toInt( &ok );
00239   if ( !ok )
00240     return 0;
00241   *path = KURL::decode_string( urlParts[2] );
00242   return w->partNodeForId( part_id );
00243 }
00244 
00245 bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleClick( const KURL & url, KMReaderWin * w ) const {
00246   TQString path;
00247   partNode * node = partNodeFromXKMailUrl( url, w, &path );
00248   if ( !node )
00249     return false;
00250   KMMessage *msg = w->message();
00251   if ( !msg ) return false;
00252   Callback callback( msg, w );
00253   KMail::PartNodeBodyPart part( *node, w->overrideCodec() );
00254   for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00255     if ( (*it)->handleClick( &part, path, callback ) )
00256       return true;
00257   return false;
00258 }
00259 
00260 bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleContextMenuRequest( const KURL & url, const TQPoint & p, KMReaderWin * w ) const {
00261   TQString path;
00262   partNode * node = partNodeFromXKMailUrl( url, w, &path );
00263   if ( !node )
00264     return false;
00265 
00266   KMail::PartNodeBodyPart part( *node, w->overrideCodec() );
00267   for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00268     if ( (*it)->handleContextMenuRequest( &part, path, p ) )
00269       return true;
00270   return false;
00271 }
00272 
00273 TQString KMail::URLHandlerManager::BodyPartURLHandlerManager::statusBarMessage( const KURL & url, KMReaderWin * w ) const {
00274   TQString path;
00275   partNode * node = partNodeFromXKMailUrl( url, w, &path );
00276   if ( !node )
00277     return TQString();
00278 
00279   KMail::PartNodeBodyPart part( *node, w->overrideCodec() );
00280   for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) {
00281     const TQString msg = (*it)->statusBarMessage( &part, path );
00282     if ( !msg.isEmpty() )
00283       return msg;
00284   }
00285   return TQString();
00286 }
00287 
00288 //
00289 //
00290 // URLHandlerManager
00291 //
00292 //
00293 
00294 KMail::URLHandlerManager::URLHandlerManager() {
00295   registerHandler( new KMailProtocolURLHandler() );
00296   registerHandler( new ExpandCollapseQuoteURLManager() );
00297   registerHandler( new SMimeURLHandler() );
00298   registerHandler( new MailToURLHandler() );
00299   registerHandler( new HtmlAnchorHandler() );
00300   registerHandler( new AttachmentURLHandler() );
00301   registerHandler( mBodyPartURLHandlerManager = new BodyPartURLHandlerManager() );
00302   registerHandler( new ShowAuditLogURLHandler() );
00303   registerHandler( new InternalImageURLHandler );
00304   registerHandler( new FallBackURLHandler() );
00305 }
00306 
00307 KMail::URLHandlerManager::~URLHandlerManager() {
00308   for_each( mHandlers.begin(), mHandlers.end(),
00309         DeleteAndSetToZero<URLHandler>() );
00310 }
00311 
00312 void KMail::URLHandlerManager::registerHandler( const URLHandler * handler ) {
00313   if ( !handler )
00314     return;
00315   unregisterHandler( handler ); // don't produce duplicates
00316   mHandlers.push_back( handler );
00317 }
00318 
00319 void KMail::URLHandlerManager::unregisterHandler( const URLHandler * handler ) {
00320   // don't delete them, only remove them from the list!
00321   mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
00322 }
00323 
00324 void KMail::URLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) {
00325   if ( mBodyPartURLHandlerManager )
00326     mBodyPartURLHandlerManager->registerHandler( handler );
00327 }
00328 
00329 void KMail::URLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) {
00330   if ( mBodyPartURLHandlerManager )
00331     mBodyPartURLHandlerManager->unregisterHandler( handler );
00332 }
00333 
00334 bool KMail::URLHandlerManager::handleClick( const KURL & url, KMReaderWin * w ) const {
00335   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00336     if ( (*it)->handleClick( url, w ) )
00337       return true;
00338   return false;
00339 }
00340 
00341 bool KMail::URLHandlerManager::handleShiftClick( const KURL &url, KMReaderWin *window ) const
00342 {
00343   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00344     if ( (*it)->handleShiftClick( url, window ) )
00345       return true;
00346   return false;
00347 }
00348 
00349 bool KMail::URLHandlerManager::willHandleDrag( const KURL &url, const TQString& imagePath,
00350                                                KMReaderWin *window ) const
00351 {
00352   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00353     if ( (*it)->willHandleDrag( url, imagePath, window ) )
00354       return true;
00355   return false;
00356 }
00357 
00358 bool KMail::URLHandlerManager::handleDrag( const KURL &url, const TQString& imagePath,
00359                                            KMReaderWin *window ) const
00360 {
00361   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00362     if ( (*it)->handleDrag( url, imagePath, window ) )
00363       return true;
00364   return false;
00365 }
00366 
00367 bool KMail::URLHandlerManager::handleContextMenuRequest( const KURL & url, const TQPoint & p, KMReaderWin * w ) const {
00368   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
00369     if ( (*it)->handleContextMenuRequest( url, p, w ) )
00370       return true;
00371   return false;
00372 }
00373 
00374 TQString KMail::URLHandlerManager::statusBarMessage( const KURL & url, KMReaderWin * w ) const {
00375   for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) {
00376     const TQString msg = (*it)->statusBarMessage( url, w );
00377     if ( !msg.isEmpty() )
00378       return msg;
00379   }
00380   return TQString();
00381 }
00382 
00383 
00384 //
00385 //
00386 // URLHandler
00387 //
00388 //
00389 
00390 // these includes are temporary and should not be needed for the code
00391 // above this line, so they appear only here:
00392 #include "kmmessage.h"
00393 #include "kmreaderwin.h"
00394 #include "partNode.h"
00395 #include "kmmsgpart.h"
00396 
00397 #include <ui/messagebox.h>
00398 
00399 #include <tdelocale.h>
00400 #include <kprocess.h>
00401 #include <tdemessagebox.h>
00402 #include <tdehtml_part.h>
00403 
00404 #include <tqstring.h>
00405 
00406 namespace {
00407   bool KMailProtocolURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00408     if ( url.protocol() == "kmail" ) {
00409       if ( !w )
00410         return false;
00411 
00412       if ( url.path() == "showHTML" ) {
00413         w->setHtmlOverride( !w->htmlOverride() );
00414         w->update( true );
00415         return true;
00416       }
00417 
00418       if ( url.path() == "loadExternal" ) {
00419         w->setHtmlLoadExtOverride( !w->htmlLoadExtOverride() );
00420         w->update( true );
00421         return true;
00422       }
00423 
00424       if ( url.path() == "goOnline" ) {
00425         kmkernel->resumeNetworkJobs();
00426         return true;
00427       }
00428 
00429       if ( url.path() == "decryptMessage" ) {
00430         w->setDecryptMessageOverwrite( true );
00431         w->update( true );
00432         return true;
00433       }
00434 
00435       if ( url.path() == "showSignatureDetails" ) {
00436         w->setShowSignatureDetails( true );
00437         w->update( true );
00438         return true;
00439       }
00440 
00441       if ( url.path() == "hideSignatureDetails" ) {
00442         w->setShowSignatureDetails( false );
00443         w->update( true );
00444         return true;
00445       }
00446 
00447       if ( url.path() == "showAttachmentQuicklist" ) {
00448       w->saveRelativePosition();
00449       w->setShowAttachmentQuicklist( true );
00450       w->update( true );
00451       return true;
00452       }
00453 
00454       if ( url.path() == "hideAttachmentQuicklist" ) {
00455       w->saveRelativePosition();
00456       w->setShowAttachmentQuicklist( false );
00457       w->update( true );
00458       return true;
00459       }
00460 
00461       if ( url.path() == "showRawToltecMail" ) {
00462         w->saveRelativePosition();
00463         w->setShowRawToltecMail( true );
00464         w->update( true );
00465         return true;
00466       }
00467 
00468 //       if ( url.path() == "startIMApp" )
00469 //       {
00470 //         kmkernel->imProxy()->startPreferredApp();
00471 //         return true;
00472 //       }
00473 //       //FIXME: handle startIMApp urls in their own handler, or rename this one
00474     }
00475     return false;
00476   }
00477 
00478   TQString KMailProtocolURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const {
00479     if ( url.protocol() == "kmail" )
00480     {
00481       if ( url.path() == "showHTML" )
00482         return i18n("Turn on HTML rendering for this message.");
00483       if ( url.path() == "loadExternal" )
00484         return i18n("Load external references from the Internet for this message.");
00485       if ( url.path() == "goOnline" )
00486         return i18n("Work online.");
00487       if ( url.path() == "decryptMessage" )
00488         return i18n("Decrypt message.");
00489       if ( url.path() == "showSignatureDetails" )
00490         return i18n("Show signature details.");
00491       if ( url.path() == "hideSignatureDetails" )
00492         return i18n("Hide signature details.");
00493       if ( url.path() == "hideAttachmentQuicklist" )
00494         return i18n( "Hide attachment list" );
00495       if ( url.path() == "showAttachmentQuicklist" )
00496         return i18n( "Show attachment list" );
00497     }
00498     return TQString() ;
00499   }
00500 }
00501 
00502 namespace {
00503 
00504   bool ExpandCollapseQuoteURLManager::handleClick(
00505       const KURL & url, KMReaderWin * w ) const
00506   {
00507     //  kmail:levelquote/?num      -> the level quote to collapse.
00508     //  kmail:levelquote/?-num      -> expand all levels quote.
00509     if ( url.protocol() == "kmail" && url.path()=="levelquote" )
00510     {
00511       TQString levelStr= url.query().mid( 1,url.query().length() );
00512       bool isNumber;
00513       int levelQuote= levelStr.toInt(&isNumber);
00514       if ( isNumber )
00515         w->slotLevelQuote( levelQuote );
00516       return true;
00517     }
00518     return false;
00519   }
00520   TQString ExpandCollapseQuoteURLManager::statusBarMessage(
00521       const KURL & url, KMReaderWin * ) const
00522   {
00523       if ( url.protocol() == "kmail" && url.path() == "levelquote" )
00524       {
00525         TQString query= url.query();
00526         if ( query.length()>=2 ) {
00527           if ( query[ 1 ] =='-'  ) {
00528             return i18n("Expand all quoted text.");
00529           }
00530           else {
00531             return i18n("Collapse quoted text.");
00532           }
00533         }
00534       }
00535       return TQString() ;
00536   }
00537 
00538 }
00539 
00540 // defined in kmreaderwin.cpp...
00541 extern bool foundSMIMEData( const TQString aUrl, TQString & displayName,
00542                 TQString & libName, TQString & keyId );
00543 
00544 namespace {
00545   bool SMimeURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00546     if ( !url.hasRef() )
00547       return false;
00548     TQString displayName, libName, keyId;
00549     if ( !foundSMIMEData( url.path() + '#' + url.ref(), displayName, libName, keyId ) )
00550       return false;
00551     TDEProcess cmp;
00552     cmp << "kleopatra" << "-query" << keyId;
00553     if ( !cmp.start( TDEProcess::DontCare ) )
00554       KMessageBox::error( w, i18n("Could not start certificate manager. "
00555                   "Please check your installation."),
00556               i18n("KMail Error") );
00557     return true;
00558   }
00559 
00560   TQString SMimeURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const {
00561     TQString displayName, libName, keyId;
00562     if ( !foundSMIMEData( url.path() + '#' + url.ref(), displayName, libName, keyId ) )
00563       return TQString();
00564     return i18n("Show certificate 0x%1").arg( keyId );
00565   }
00566 }
00567 
00568 namespace {
00569   bool HtmlAnchorHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00570     if ( url.hasHost() || url.path() != "/" || !url.hasRef() )
00571       return false;
00572     if ( w && !w->htmlPart()->gotoAnchor( url.ref() ) )
00573       static_cast<TQScrollView*>( w->htmlPart()->widget() )->ensureVisible( 0, 0 );
00574     return true;
00575   }
00576 }
00577 
00578 namespace {
00579   TQString MailToURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const {
00580     if ( url.protocol() != "mailto" )
00581       return TQString();
00582     return KMMessage::decodeMailtoUrl( url.url() );
00583   }
00584 }
00585 
00586 namespace {
00587 
00588   partNode* AttachmentURLHandler::partNodeForUrl( const KURL &url, KMReaderWin *w ) const
00589   {
00590     if ( !w || !w->message() )
00591       return 0;
00592     if ( url.protocol() != "attachment" )
00593       return 0;
00594 
00595     bool ok;
00596     int nodeId = url.path().toInt( &ok );
00597     if ( !ok )
00598       return 0;
00599 
00600     partNode * node = w->partNodeForId( nodeId );
00601     return node;
00602   }
00603 
00604   bool AttachmentURLHandler::attachmentIsInHeader( const KURL &url ) const
00605   {
00606     bool inHeader = false;
00607     const TQString place = url.queryItem( "place" ).lower();
00608     if ( place != TQString() ) {
00609       inHeader = ( place == "header" );
00610     }
00611     return inHeader;
00612   }
00613 
00614   bool AttachmentURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const
00615   {
00616     partNode * node = partNodeForUrl( url, w );
00617     if ( !node )
00618       return false;
00619 
00620     const bool inHeader = attachmentIsInHeader( url );
00621     const bool shouldShowDialog = !node->isDisplayedEmbedded() || !inHeader;
00622     if ( inHeader )
00623       w->scrollToAttachment( node );
00624     if ( shouldShowDialog )
00625       w->openAttachment( node->nodeId(), w->tempFileUrlFromPartNode( node ).path() );
00626     return true;
00627   }
00628 
00629   bool AttachmentURLHandler::handleShiftClick( const KURL &url, KMReaderWin *window ) const
00630   {
00631     partNode * node = partNodeForUrl( url, window );
00632     if ( !node )
00633       return false;
00634     if ( !window )
00635       return false;
00636     window->saveAttachment( window->tempFileUrlFromPartNode( node ) );
00637     return true;
00638   }
00639 
00640   bool AttachmentURLHandler::willHandleDrag( const KURL &url, const TQString& imagePath,
00641                                              KMReaderWin *window ) const
00642   {
00643     Q_UNUSED( imagePath );
00644     return partNodeForUrl( url, window ) != 0;
00645   }
00646 
00647   bool AttachmentURLHandler::handleDrag( const KURL &url, const TQString& imagePath,
00648                                          KMReaderWin *window ) const
00649   {
00650     Q_UNUSED( imagePath );
00651     const partNode * node = partNodeForUrl( url, window );
00652     if ( !node )
00653       return false;
00654 
00655     KURL file = window->tempFileUrlFromPartNode( node ).path();
00656     if ( !file.isEmpty() ) {
00657       TQString icon = node->msgPart().iconName( TDEIcon::Small );
00658       KURLDrag* urlDrag = new KURLDrag( file, window );
00659       if ( !icon.isEmpty() ) {
00660         TQPixmap iconMap( icon );
00661         urlDrag->setPixmap( iconMap );
00662       }
00663       urlDrag->drag();
00664       return true;
00665     }
00666     else {
00667       return false;
00668     }
00669   }
00670 
00671   bool AttachmentURLHandler::handleContextMenuRequest( const KURL & url, const TQPoint & p, KMReaderWin * w ) const
00672   {
00673     partNode * node = partNodeForUrl( url, w );
00674     if ( !node )
00675       return false;
00676 
00677     w->showAttachmentPopup( node->nodeId(), w->tempFileUrlFromPartNode( node ).path(), p );
00678     return true;
00679   }
00680 
00681   TQString AttachmentURLHandler::statusBarMessage( const KURL & url, KMReaderWin * w ) const
00682   {
00683     partNode * node = partNodeForUrl( url, w );
00684     if ( !node )
00685       return TQString();
00686 
00687     const KMMessagePart & msgPart = node->msgPart();
00688     TQString name = msgPart.fileName();
00689     if ( name.isEmpty() )
00690       name = msgPart.name();
00691     if ( !name.isEmpty() )
00692       return i18n( "Attachment: %1" ).arg( name );
00693     return i18n( "Attachment #%1 (unnamed)" ).arg( KMReaderWin::msgPartFromUrl( url ) );
00694   }
00695 }
00696 
00697 namespace {
00698   static TQString extractAuditLog( const KURL & url ) {
00699     if ( url.protocol() != "kmail" || url.path() != "showAuditLog" )
00700       return TQString();
00701     assert( !url.queryItem( "log" ).isEmpty() );
00702     return url.queryItem( "log" );
00703   }
00704 
00705   bool ShowAuditLogURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00706     const TQString auditLog = extractAuditLog( url );
00707     if ( auditLog.isEmpty() )
00708         return false;
00709     Kleo::MessageBox::auditLog( w, auditLog );
00710     return true;
00711   }
00712 
00713   bool ShowAuditLogURLHandler::handleContextMenuRequest( const KURL & url, const TQPoint &, KMReaderWin * w ) const
00714   {
00715     Q_UNUSED( w );
00716     // disable RMB for my own links:
00717     return !extractAuditLog( url ).isEmpty();
00718   }
00719 
00720   TQString ShowAuditLogURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const {
00721     if ( extractAuditLog( url ).isEmpty() )
00722       return TQString();
00723     else
00724       return i18n("Show GnuPG Audit Log for this operation");
00725   }
00726 }
00727 
00728 namespace {
00729   bool InternalImageURLHandler::handleDrag( const KURL &url, const TQString& imagePath,
00730                                             KMReaderWin *window ) const
00731   {
00732     Q_UNUSED( window );
00733     Q_UNUSED( url );
00734     const TQString kmailImagePath = locate( "data", "kmail/pics/" );
00735     if ( imagePath.contains( kmailImagePath ) ) {
00736       // Do nothing, don't start a drag
00737       return true;
00738     }
00739     return false;
00740   }
00741 
00742   bool InternalImageURLHandler::willHandleDrag( const KURL &url, const TQString& imagePath,
00743                                                 KMReaderWin *window ) const
00744   {
00745     Q_UNUSED( window );
00746     Q_UNUSED( url );
00747     const TQString kmailImagePath = locate( "data", "kmail/pics/" );
00748     return imagePath.contains( kmailImagePath );
00749   }
00750 }
00751 
00752 namespace {
00753   bool FallBackURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const {
00754     if ( w )
00755       w->emitUrlClicked( url, Qt::LeftButton );
00756     return true;
00757   }
00758 
00759   bool FallBackURLHandler::handleContextMenuRequest( const KURL & url, const TQPoint & p, KMReaderWin * w ) const {
00760     if ( w )
00761       w->emitPopupMenu( url, p );
00762     return true;
00763   }
00764 }