37#include "urlhandlermanager.h" 
   39#include "interfaces/urlhandler.h" 
   40#include "interfaces/bodyparturlhandler.h" 
   42#include "partnodebodypart.h" 
   43#include "kmreaderwin.h" 
   48#include <tdestandarddirs.h> 
   50#include <tdeimproxy.h> 
   63    KMailProtocolURLHandler() : 
KMail::URLHandler() {}
 
   64    ~KMailProtocolURLHandler() {}
 
   68      return url.protocol() == 
"kmail";
 
   75    ExpandCollapseQuoteURLManager() : 
KMail::URLHandler() {}
 
   76    ~ExpandCollapseQuoteURLManager() {}
 
   88    SMimeURLHandler() : 
KMail::URLHandler() {}
 
  100    MailToURLHandler() : 
KMail::URLHandler() {}
 
  101    ~MailToURLHandler() {}
 
  112    HtmlAnchorHandler() : 
KMail::URLHandler() {}
 
  113    ~HtmlAnchorHandler() {}
 
  124    AttachmentURLHandler() : 
KMail::URLHandler() {}
 
  125    ~AttachmentURLHandler() {}
 
  134    partNode* partNodeForUrl( 
const KURL &url, 
KMReaderWin *w ) 
const;
 
  135    bool attachmentIsInHeader( 
const KURL &url ) 
const;
 
  140      ShowAuditLogURLHandler() : 
KMail::URLHandler() {}
 
  141      ~ShowAuditLogURLHandler() {}
 
  152      InternalImageURLHandler() : 
KMail::URLHandler()
 
  154      ~InternalImageURLHandler()
 
  163        { 
return TQString(); }
 
  168    FallBackURLHandler() : 
KMail::URLHandler() {}
 
  169    ~FallBackURLHandler() {}
 
  174      return url.prettyURL();
 
  187class KMail::URLHandlerManager::BodyPartURLHandlerManager : 
public KMail::URLHandler {
 
  189  BodyPartURLHandlerManager() : 
KMail::URLHandler() {}
 
  190  ~BodyPartURLHandlerManager();
 
  196  void registerHandler( 
const Interface::BodyPartURLHandler * handler );
 
  197  void unregisterHandler( 
const Interface::BodyPartURLHandler * handler );
 
  200  typedef TQValueVector<const Interface::BodyPartURLHandler*> BodyPartHandlerList;
 
  201  BodyPartHandlerList mHandlers;
 
  204KMail::URLHandlerManager::BodyPartURLHandlerManager::~BodyPartURLHandlerManager() {
 
  205  for_each( mHandlers.begin(), mHandlers.end(),
 
  206        DeleteAndSetToZero<Interface::BodyPartURLHandler>() );
 
  209void KMail::URLHandlerManager::BodyPartURLHandlerManager::registerHandler( 
const Interface::BodyPartURLHandler * handler ) {
 
  212  unregisterHandler( handler ); 
 
  213  mHandlers.push_back( handler );
 
  216void KMail::URLHandlerManager::BodyPartURLHandlerManager::unregisterHandler( 
const Interface::BodyPartURLHandler * handler ) {
 
  218  mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
 
  221static partNode * partNodeFromXKMailUrl( 
const KURL & url, 
KMReaderWin * w, TQString * path ) {
 
  224  if ( !w || url.protocol() != 
"x-kmail" )
 
  226  const TQString urlPath = url.path();
 
  230  kdDebug( 5006 ) << 
"BodyPartURLHandler: urlPath == \"" << urlPath << 
"\"" << endl;
 
  231  if ( !urlPath.startsWith( 
"/bodypart/" ) )
 
  234  const TQStringList urlParts = TQStringList::split( 
'/', urlPath.mid( 10 ), 
true );
 
  235  if ( urlParts.size() != 3 )
 
  238  const int part_id = urlParts[1].toInt( &ok );
 
  241  *path = KURL::decode_string( urlParts[2] );
 
  242  return w->partNodeForId( part_id );
 
  245bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleClick( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  247  partNode * node = partNodeFromXKMailUrl( url, w, &path );
 
  251  if ( !msg ) 
return false;
 
  252  Callback callback( msg, w );
 
  254  for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
 
  255    if ( (*it)->handleClick( &part, path, callback ) )
 
  260bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleContextMenuRequest( 
const KURL & url, 
const TQPoint & p, 
KMReaderWin * w )
 const {
 
  262  partNode * node = partNodeFromXKMailUrl( url, w, &path );
 
  267  for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
 
  268    if ( (*it)->handleContextMenuRequest( &part, path, p ) )
 
  273TQString KMail::URLHandlerManager::BodyPartURLHandlerManager::statusBarMessage( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  275  partNode * node = partNodeFromXKMailUrl( url, w, &path );
 
  280  for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) {
 
  281    const TQString msg = (*it)->statusBarMessage( &part, path );
 
  282    if ( !msg.isEmpty() )
 
  294KMail::URLHandlerManager::URLHandlerManager() {
 
  295  registerHandler( 
new KMailProtocolURLHandler() );
 
  296  registerHandler( 
new ExpandCollapseQuoteURLManager() );
 
  297  registerHandler( 
new SMimeURLHandler() );
 
  298  registerHandler( 
new MailToURLHandler() );
 
  299  registerHandler( 
new HtmlAnchorHandler() );
 
  300  registerHandler( 
new AttachmentURLHandler() );
 
  301  registerHandler( mBodyPartURLHandlerManager = 
new BodyPartURLHandlerManager() );
 
  302  registerHandler( 
new ShowAuditLogURLHandler() );
 
  303  registerHandler( 
new InternalImageURLHandler );
 
  304  registerHandler( 
new FallBackURLHandler() );
 
  307KMail::URLHandlerManager::~URLHandlerManager() {
 
  308  for_each( mHandlers.begin(), mHandlers.end(),
 
  309        DeleteAndSetToZero<URLHandler>() );
 
  312void KMail::URLHandlerManager::registerHandler( 
const URLHandler * handler ) {
 
  315  unregisterHandler( handler ); 
 
  316  mHandlers.push_back( handler );
 
  319void KMail::URLHandlerManager::unregisterHandler( 
const URLHandler * handler ) {
 
  321  mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
 
  324void KMail::URLHandlerManager::registerHandler( 
const Interface::BodyPartURLHandler * handler ) {
 
  325  if ( mBodyPartURLHandlerManager )
 
  326    mBodyPartURLHandlerManager->registerHandler( handler );
 
  329void KMail::URLHandlerManager::unregisterHandler( 
const Interface::BodyPartURLHandler * handler ) {
 
  330  if ( mBodyPartURLHandlerManager )
 
  331    mBodyPartURLHandlerManager->unregisterHandler( handler );
 
  334bool KMail::URLHandlerManager::handleClick( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  335  for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
 
  336    if ( (*it)->handleClick( url, w ) )
 
  341bool KMail::URLHandlerManager::handleShiftClick( 
const KURL &url, 
KMReaderWin *window )
 const 
  343  for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
 
  344    if ( (*it)->handleShiftClick( url, window ) )
 
  349bool KMail::URLHandlerManager::willHandleDrag( 
const KURL &url, 
const TQString& imagePath,
 
  352  for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
 
  353    if ( (*it)->willHandleDrag( url, imagePath, window ) )
 
  358bool KMail::URLHandlerManager::handleDrag( 
const KURL &url, 
const TQString& imagePath,
 
  361  for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
 
  362    if ( (*it)->handleDrag( url, imagePath, window ) )
 
  367bool KMail::URLHandlerManager::handleContextMenuRequest( 
const KURL & url, 
const TQPoint & p, 
KMReaderWin * w )
 const {
 
  368  for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it )
 
  369    if ( (*it)->handleContextMenuRequest( url, p, w ) )
 
  374TQString KMail::URLHandlerManager::statusBarMessage( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  375  for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) {
 
  376    const TQString msg = (*it)->statusBarMessage( url, w );
 
  377    if ( !msg.isEmpty() )
 
  392#include "kmmessage.h" 
  393#include "kmreaderwin.h" 
  395#include "kmmsgpart.h" 
  397#include <ui/messagebox.h> 
  399#include <tdelocale.h> 
  400#include <tdeprocess.h> 
  401#include <tdemessagebox.h> 
  402#include <tdehtml_part.h> 
  407  bool KMailProtocolURLHandler::handleClick( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  408    if ( url.protocol() == 
"kmail" ) {
 
  412      if ( url.path() == 
"showHTML" ) {
 
  418      if ( url.path() == 
"loadExternal" ) {
 
  424      if ( url.path() == 
"goOnline" ) {
 
  425        kmkernel->resumeNetworkJobs();
 
  429      if ( url.path() == 
"decryptMessage" ) {
 
  435      if ( url.path() == 
"showSignatureDetails" ) {
 
  441      if ( url.path() == 
"hideSignatureDetails" ) {
 
  447      if ( url.path() == 
"showAttachmentQuicklist" ) {
 
  449      w->setShowAttachmentQuicklist( 
true );
 
  454      if ( url.path() == 
"hideAttachmentQuicklist" ) {
 
  456      w->setShowAttachmentQuicklist( 
false );
 
  461      if ( url.path() == 
"showRawToltecMail" ) {
 
  463        w->setShowRawToltecMail( 
true );
 
  478  TQString KMailProtocolURLHandler::statusBarMessage( 
const KURL & url, 
KMReaderWin * )
 const {
 
  479    if ( url.protocol() == 
"kmail" )
 
  481      if ( url.path() == 
"showHTML" )
 
  482        return i18n(
"Turn on HTML rendering for this message.");
 
  483      if ( url.path() == 
"loadExternal" )
 
  484        return i18n(
"Load external references from the Internet for this message.");
 
  485      if ( url.path() == 
"goOnline" )
 
  486        return i18n(
"Work online.");
 
  487      if ( url.path() == 
"decryptMessage" )
 
  488        return i18n(
"Decrypt message.");
 
  489      if ( url.path() == 
"showSignatureDetails" )
 
  490        return i18n(
"Show signature details.");
 
  491      if ( url.path() == 
"hideSignatureDetails" )
 
  492        return i18n(
"Hide signature details.");
 
  493      if ( url.path() == 
"hideAttachmentQuicklist" )
 
  494        return i18n( 
"Hide attachment list" );
 
  495      if ( url.path() == 
"showAttachmentQuicklist" )
 
  496        return i18n( 
"Show attachment list" );
 
  504  bool ExpandCollapseQuoteURLManager::handleClick(
 
  509    if ( url.protocol() == 
"kmail" && url.path()==
"levelquote" )
 
  511      TQString levelStr= url.query().mid( 1,url.query().length() );
 
  513      int levelQuote= levelStr.toInt(&isNumber);
 
  515        w->slotLevelQuote( levelQuote );
 
  520  TQString ExpandCollapseQuoteURLManager::statusBarMessage(
 
  523      if ( url.protocol() == 
"kmail" && url.path() == 
"levelquote" )
 
  525        TQString query= url.query();
 
  526        if ( query.length()>=2 ) {
 
  527          if ( query[ 1 ] ==
'-'  ) {
 
  528            return i18n(
"Expand all quoted text.");
 
  531            return i18n(
"Collapse quoted text.");
 
  541extern bool foundSMIMEData( 
const TQString aUrl, TQString & displayName,
 
  542                TQString & libName, TQString & keyId );
 
  545  bool SMimeURLHandler::handleClick( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  548    TQString displayName, libName, keyId;
 
  549    if ( !foundSMIMEData( url.path() + 
'#' + url.ref(), displayName, libName, keyId ) )
 
  552    cmp << 
"kleopatra" << 
"-query" << keyId;
 
  553    if ( !cmp.start( TDEProcess::DontCare ) )
 
  554      KMessageBox::error( w, i18n(
"Could not start certificate manager. " 
  555                  "Please check your installation."),
 
  556              i18n(
"KMail Error") );
 
  560  TQString SMimeURLHandler::statusBarMessage( 
const KURL & url, 
KMReaderWin * )
 const {
 
  561    TQString displayName, libName, keyId;
 
  562    if ( !foundSMIMEData( url.path() + 
'#' + url.ref(), displayName, libName, keyId ) )
 
  564    return i18n(
"Show certificate 0x%1").arg( keyId );
 
  569  bool HtmlAnchorHandler::handleClick( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  570    if ( url.hasHost() || url.path() != 
"/" || !url.hasRef() )
 
  572    if ( w && !w->
htmlPart()->gotoAnchor( url.ref() ) )
 
  573      static_cast<TQScrollView*
>( w->
htmlPart()->widget() )->ensureVisible( 0, 0 );
 
  579  TQString MailToURLHandler::statusBarMessage( 
const KURL & url, 
KMReaderWin * )
 const {
 
  580    if ( url.protocol() != 
"mailto" )
 
  588  partNode* AttachmentURLHandler::partNodeForUrl( 
const KURL &url, 
KMReaderWin *w )
 const 
  592    if ( url.protocol() != 
"attachment" )
 
  596    int nodeId = url.path().toInt( &ok );
 
  600    partNode * node = w->partNodeForId( nodeId );
 
  604  bool AttachmentURLHandler::attachmentIsInHeader( 
const KURL &url )
 const 
  606    bool inHeader = 
false;
 
  607    const TQString place = url.queryItem( 
"place" ).lower();
 
  608    if ( place != TQString() ) {
 
  609      inHeader = ( place == 
"header" );
 
  614  bool AttachmentURLHandler::handleClick( 
const KURL & url, 
KMReaderWin * w )
 const 
  616    partNode * node = partNodeForUrl( url, w );
 
  620    const bool inHeader = attachmentIsInHeader( url );
 
  621    const bool shouldShowDialog = !node->isDisplayedEmbedded() || !inHeader;
 
  624    if ( shouldShowDialog )
 
  625      w->openAttachment( node->nodeId(), w->tempFileUrlFromPartNode( node ).path() );
 
  629  bool AttachmentURLHandler::handleShiftClick( 
const KURL &url, 
KMReaderWin *window )
 const 
  631    partNode * node = partNodeForUrl( url, window );
 
  636    window->saveAttachment( window->tempFileUrlFromPartNode( node ) );
 
  640  bool AttachmentURLHandler::willHandleDrag( 
const KURL &url, 
const TQString& imagePath,
 
  643    Q_UNUSED( imagePath );
 
  644    return partNodeForUrl( url, window ) != 0;
 
  647  bool AttachmentURLHandler::handleDrag( 
const KURL &url, 
const TQString& imagePath,
 
  650    Q_UNUSED( imagePath );
 
  651    const partNode * node = partNodeForUrl( url, window );
 
  655    KURL file = window->tempFileUrlFromPartNode( node ).path();
 
  656    if ( !file.isEmpty() ) {
 
  657      TQString icon = node->msgPart().iconName( TDEIcon::Small );
 
  658      KURLDrag* urlDrag = 
new KURLDrag( file, window );
 
  659      if ( !icon.isEmpty() ) {
 
  660        TQPixmap iconMap( icon );
 
  661        urlDrag->setPixmap( iconMap );
 
  671  bool AttachmentURLHandler::handleContextMenuRequest( 
const KURL & url, 
const TQPoint & p, 
KMReaderWin * w )
 const 
  673    partNode * node = partNodeForUrl( url, w );
 
  677    w->showAttachmentPopup( node->nodeId(), w->tempFileUrlFromPartNode( node ).path(), p );
 
  681  TQString AttachmentURLHandler::statusBarMessage( 
const KURL & url, 
KMReaderWin * w )
 const 
  683    partNode * node = partNodeForUrl( url, w );
 
  687    const KMMessagePart & msgPart = node->msgPart();
 
  688    TQString name = msgPart.fileName();
 
  689    if ( name.isEmpty() )
 
  690      name = msgPart.name();
 
  691    if ( !name.isEmpty() )
 
  692      return i18n( 
"Attachment: %1" ).arg( name );
 
  698  static TQString extractAuditLog( 
const KURL & url ) {
 
  699    if ( url.protocol() != 
"kmail" || url.path() != 
"showAuditLog" )
 
  701    assert( !url.queryItem( 
"log" ).isEmpty() );
 
  702    return url.queryItem( 
"log" );
 
  705  bool ShowAuditLogURLHandler::handleClick( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  706    const TQString auditLog = extractAuditLog( url );
 
  707    if ( auditLog.isEmpty() )
 
  709    Kleo::MessageBox::auditLog( w, auditLog );
 
  713  bool ShowAuditLogURLHandler::handleContextMenuRequest( 
const KURL & url, 
const TQPoint &, 
KMReaderWin * w )
 const 
  717    return !extractAuditLog( url ).isEmpty();
 
  720  TQString ShowAuditLogURLHandler::statusBarMessage( 
const KURL & url, 
KMReaderWin * )
 const {
 
  721    if ( extractAuditLog( url ).isEmpty() )
 
  724      return i18n(
"Show GnuPG Audit Log for this operation");
 
  729  bool InternalImageURLHandler::handleDrag( 
const KURL &url, 
const TQString& imagePath,
 
  734    const TQString kmailImagePath = locate( 
"data", 
"kmail/pics/" );
 
  735    if ( imagePath.contains( kmailImagePath ) ) {
 
  742  bool InternalImageURLHandler::willHandleDrag( 
const KURL &url, 
const TQString& imagePath,
 
  747    const TQString kmailImagePath = locate( 
"data", 
"kmail/pics/" );
 
  748    return imagePath.contains( kmailImagePath );
 
  753  bool FallBackURLHandler::handleClick( 
const KURL & url, 
KMReaderWin * w )
 const {
 
  755      w->emitUrlClicked( url, TQt::LeftButton );
 
  759  bool FallBackURLHandler::handleContextMenuRequest( 
const KURL & url, 
const TQPoint & p, 
KMReaderWin * w )
 const {
 
  761      w->emitPopupMenu( url, p );
 
static TQString decodeMailtoUrl(const TQString &url)
Decodes a mailto URL.
 
This class implements a "reader window", that is a window used for reading or viewing messages.
 
void setDecryptMessageOverwrite(bool overwrite=true)
Enforce message decryption.
 
const TQTextCodec * overrideCodec() const
Get codec corresponding to the currently selected override character encoding.
 
void setShowSignatureDetails(bool showDetails=true)
Show signature details.
 
KMMessage * message(KMFolder **folder=0) const
Returns the current message or 0 if none.
 
bool htmlLoadExtOverride() const
Get the load external references override setting.
 
void scrollToAttachment(const partNode *node)
Scrolls to the given attachment and marks it with a yellow border.
 
static int msgPartFromUrl(const KURL &url)
Returns id of message part from given URL or -1 if invalid.
 
TDEHTMLPart * htmlPart() const
Access to the TDEHTMLPart used for the viewer.
 
void setHtmlLoadExtOverride(bool loadExtOverride)
Override default load external references setting.
 
void saveRelativePosition()
Saves the relative position of the scroll view.
 
bool htmlOverride() const
Override default html mail setting.
 
void update(KMail::Interface::Observable *)
 
an implemenation of the BodyPart interface using partNodes
 
Singleton to manage the list of URLHandlers.
 
An interface to reader link handlers.
 
virtual bool handleClick(const KURL &url, KMReaderWin *w) const =0
Called when LMB-clicking on a link in the reader.
 
virtual bool handleDrag(const KURL &url, const TQString &imagePath, KMReaderWin *window) const
Called when starting a drag with the given URL.
 
virtual bool handleContextMenuRequest(const KURL &url, const TQPoint &p, KMReaderWin *w) const =0
Called when RMB-clicking on a link in the reader.
 
virtual bool handleShiftClick(const KURL &url, KMReaderWin *window) const
Called when shift-clicking the link in the reader.
 
virtual TQString statusBarMessage(const KURL &url, KMReaderWin *w) const =0
Called when hovering over a link.
 
virtual bool willHandleDrag(const KURL &url, const TQString &imagePath, KMReaderWin *window) const