kmail Library API Documentation

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�vdalens 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 "callback.h" 00045 #include "kimproxy.h" 00046 00047 #include <kurl.h> 00048 00049 #include <algorithm> 00050 using std::for_each; 00051 using std::remove; 00052 using std::find; 00053 00054 KMail::URLHandlerManager * KMail::URLHandlerManager::self = 0; 00055 00056 namespace { 00057 class ShowHtmlSwitchURLHandler : public KMail::URLHandler { 00058 public: 00059 ShowHtmlSwitchURLHandler() : KMail::URLHandler() {} 00060 ~ShowHtmlSwitchURLHandler() {} 00061 00062 bool handleClick( const KURL &, KMReaderWin * ) const; 00063 bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const { 00064 return false; 00065 } 00066 QString statusBarMessage( const KURL &, KMReaderWin * ) const; 00067 }; 00068 00069 class SMimeURLHandler : public KMail::URLHandler { 00070 public: 00071 SMimeURLHandler() : KMail::URLHandler() {} 00072 ~SMimeURLHandler() {} 00073 00074 bool handleClick( const KURL &, KMReaderWin * ) const; 00075 bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const { 00076 return false; 00077 } 00078 QString statusBarMessage( const KURL &, KMReaderWin * ) const; 00079 }; 00080 00081 class GroupwareURLHandler : public KMail::URLHandler { 00082 public: 00083 GroupwareURLHandler() : KMail::URLHandler() {} 00084 ~GroupwareURLHandler() {} 00085 00086 bool handleClick( const KURL &, KMReaderWin * ) const; 00087 bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const { 00088 return false; 00089 } 00090 QString statusBarMessage( const KURL &, KMReaderWin * ) const; 00091 }; 00092 00093 class MailToURLHandler : public KMail::URLHandler { 00094 public: 00095 MailToURLHandler() : KMail::URLHandler() {} 00096 ~MailToURLHandler() {} 00097 00098 bool handleClick( const KURL &, KMReaderWin * ) const { return false; } 00099 bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const { 00100 return false; 00101 } 00102 QString statusBarMessage( const KURL &, KMReaderWin * ) const; 00103 }; 00104 00105 class HtmlAnchorHandler : public KMail::URLHandler { 00106 public: 00107 HtmlAnchorHandler() : KMail::URLHandler() {} 00108 ~HtmlAnchorHandler() {} 00109 00110 bool handleClick( const KURL &, KMReaderWin * ) const; 00111 bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const { 00112 return false; 00113 } 00114 QString statusBarMessage( const KURL &, KMReaderWin * ) const { return QString::null; } 00115 }; 00116 00117 class AttachmentURLHandler : public KMail::URLHandler { 00118 public: 00119 AttachmentURLHandler() : KMail::URLHandler() {} 00120 ~AttachmentURLHandler() {} 00121 00122 bool handleClick( const KURL &, KMReaderWin * ) const; 00123 bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const; 00124 QString statusBarMessage( const KURL &, KMReaderWin * ) const; 00125 }; 00126 00127 class FallBackURLHandler : public KMail::URLHandler { 00128 public: 00129 FallBackURLHandler() : KMail::URLHandler() {} 00130 ~FallBackURLHandler() {} 00131 00132 bool handleClick( const KURL &, KMReaderWin * ) const; 00133 bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const; 00134 QString statusBarMessage( const KURL & url, KMReaderWin * ) const { 00135 return url.prettyURL(); 00136 } 00137 }; 00138 00139 } // anon namespace 00140 00141 00142 namespace { 00143 template <typename T> struct Delete { 00144 void operator()( const T * x ) { delete x; x = 0; } 00145 }; 00146 } 00147 00148 // 00149 // 00150 // BodyPartURLHandlerManager 00151 // 00152 // 00153 00154 class KMail::URLHandlerManager::BodyPartURLHandlerManager : public KMail::URLHandler { 00155 public: 00156 BodyPartURLHandlerManager() : KMail::URLHandler() {} 00157 ~BodyPartURLHandlerManager(); 00158 00159 bool handleClick( const KURL &, KMReaderWin * ) const; 00160 bool handleContextMenuRequest( const KURL &, const QPoint &, KMReaderWin * ) const; 00161 QString statusBarMessage( const KURL &, KMReaderWin * ) const; 00162 00163 void registerHandler( const Interface::BodyPartURLHandler * handler ); 00164 void unregisterHandler( const Interface::BodyPartURLHandler * handler ); 00165 00166 private: 00167 typedef QValueVector<const Interface::BodyPartURLHandler*> BodyPartHandlerList; 00168 BodyPartHandlerList mHandlers; 00169 }; 00170 00171 KMail::URLHandlerManager::BodyPartURLHandlerManager::~BodyPartURLHandlerManager() { 00172 for_each( mHandlers.begin(), mHandlers.end(), 00173 Delete<Interface::BodyPartURLHandler>() ); 00174 } 00175 00176 void KMail::URLHandlerManager::BodyPartURLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) { 00177 if ( !handler ) 00178 return; 00179 unregisterHandler( handler ); // don't produce duplicates 00180 mHandlers.push_back( handler ); 00181 } 00182 00183 void KMail::URLHandlerManager::BodyPartURLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) { 00184 // don't delete them, only remove them from the list! 00185 mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() ); 00186 } 00187 00188 static partNode * partNodeFromXKMailUrl( const KURL & url, KMReaderWin * w, QString * path ) { 00189 assert( path ); 00190 00191 if ( !w || url.protocol() != "x-kmail" ) 00192 return 0; 00193 const QString urlPath = url.path(); 00194 00195 // urlPath format is: /bodypart/<random number>/<part id>/<path> 00196 00197 kdDebug( 5006 ) << "BodyPartURLHandler: urlPath == \"" << urlPath << "\"" << endl; 00198 if ( !urlPath.startsWith( "/bodypart/" ) ) 00199 return 0; 00200 00201 const QStringList urlParts = QStringList::split( '/', urlPath.mid( 10 ), true ); 00202 if ( urlParts.size() != 3 ) 00203 return 0; 00204 bool ok = false; 00205 const int part_id = urlParts[1].toInt( &ok ); 00206 if ( !ok ) 00207 return 0; 00208 *path = KURL::decode_string( urlParts[2], 106 ); 00209 return w->partNodeForId( part_id ); 00210 } 00211 00212 bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleClick( const KURL & url, KMReaderWin * w ) const { 00213 QString path; 00214 partNode * node = partNodeFromXKMailUrl( url, w, &path ); 00215 if ( !node ) 00216 return false; 00217 KMMessage *msg = w->message(); 00218 if ( !msg ) return false; 00219 Callback callback( msg ); 00220 KMail::PartNodeBodyPart part( *node, w->overrideCodec() ); 00221 for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) 00222 if ( (*it)->handleClick( &part, path, callback ) ) 00223 return true; 00224 return false; 00225 } 00226 00227 bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const { 00228 QString path; 00229 partNode * node = partNodeFromXKMailUrl( url, w, &path ); 00230 if ( !node ) 00231 return false; 00232 00233 KMail::PartNodeBodyPart part( *node, w->overrideCodec() ); 00234 for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) 00235 if ( (*it)->handleContextMenuRequest( &part, path, p ) ) 00236 return true; 00237 return false; 00238 } 00239 00240 QString KMail::URLHandlerManager::BodyPartURLHandlerManager::statusBarMessage( const KURL & url, KMReaderWin * w ) const { 00241 QString path; 00242 partNode * node = partNodeFromXKMailUrl( url, w, &path ); 00243 if ( !node ) 00244 return QString::null; 00245 00246 KMail::PartNodeBodyPart part( *node, w->overrideCodec() ); 00247 for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) { 00248 const QString msg = (*it)->statusBarMessage( &part, path ); 00249 if ( !msg.isEmpty() ) 00250 return msg; 00251 } 00252 return QString::null; 00253 } 00254 00255 // 00256 // 00257 // URLHandlerManager 00258 // 00259 // 00260 00261 KMail::URLHandlerManager::URLHandlerManager() { 00262 registerHandler( new ShowHtmlSwitchURLHandler() ); 00263 registerHandler( new SMimeURLHandler() ); 00264 // registerHandler( new GroupwareURLHandler() ); 00265 registerHandler( new MailToURLHandler() ); 00266 registerHandler( new HtmlAnchorHandler() ); 00267 registerHandler( new AttachmentURLHandler() ); 00268 registerHandler( mBodyPartURLHandlerManager = new BodyPartURLHandlerManager() ); 00269 registerHandler( new FallBackURLHandler() ); 00270 } 00271 00272 KMail::URLHandlerManager::~URLHandlerManager() { 00273 for_each( mHandlers.begin(), mHandlers.end(), 00274 Delete<URLHandler>() ); 00275 } 00276 00277 void KMail::URLHandlerManager::registerHandler( const URLHandler * handler ) { 00278 if ( !handler ) 00279 return; 00280 unregisterHandler( handler ); // don't produce duplicates 00281 mHandlers.push_back( handler ); 00282 } 00283 00284 void KMail::URLHandlerManager::unregisterHandler( const URLHandler * handler ) { 00285 // don't delete them, only remove them from the list! 00286 mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() ); 00287 } 00288 00289 void KMail::URLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) { 00290 if ( mBodyPartURLHandlerManager ) 00291 mBodyPartURLHandlerManager->registerHandler( handler ); 00292 } 00293 00294 void KMail::URLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) { 00295 if ( mBodyPartURLHandlerManager ) 00296 mBodyPartURLHandlerManager->unregisterHandler( handler ); 00297 } 00298 00299 bool KMail::URLHandlerManager::handleClick( const KURL & url, KMReaderWin * w ) const { 00300 for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) 00301 if ( (*it)->handleClick( url, w ) ) 00302 return true; 00303 return false; 00304 } 00305 00306 bool KMail::URLHandlerManager::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const { 00307 for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) 00308 if ( (*it)->handleContextMenuRequest( url, p, w ) ) 00309 return true; 00310 return false; 00311 } 00312 00313 QString KMail::URLHandlerManager::statusBarMessage( const KURL & url, KMReaderWin * w ) const { 00314 for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) { 00315 const QString msg = (*it)->statusBarMessage( url, w ); 00316 if ( !msg.isEmpty() ) 00317 return msg; 00318 } 00319 return QString::null; 00320 } 00321 00322 00323 // 00324 // 00325 // URLHandler 00326 // 00327 // 00328 00329 // these includes are temporary and should not be needed for the code 00330 // above this line, so they appear only here: 00331 #include "kmgroupware.h" 00332 #include "kmmessage.h" 00333 #include "kmkernel.h" 00334 #include "kmreaderwin.h" 00335 #include "partNode.h" 00336 #include "kmmsgpart.h" 00337 00338 #include <klocale.h> 00339 #include <kprocess.h> 00340 #include <kmessagebox.h> 00341 #include <khtml_part.h> 00342 00343 #include <qstring.h> 00344 00345 namespace { 00346 bool ShowHtmlSwitchURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00347 if ( url.protocol() == "kmail" ) 00348 { 00349 if ( url.path() == "showHTML" ) 00350 { 00351 if ( w ) { 00352 w->setHtmlOverride( !w->htmlOverride() ); 00353 w->update( true ); 00354 } 00355 return true; 00356 } 00357 // if ( url.path() == "startIMApp" ) 00358 // { 00359 // kmkernel->imProxy()->startPreferredApp(); 00360 // return true; 00361 // } 00362 // //FIXME: handle startIMApp urls in their own handler, or rename this one 00363 } 00364 return false; 00365 } 00366 00367 QString ShowHtmlSwitchURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const { 00368 return url.url() == "kmail:showHTML" 00369 ? i18n("Turn on HTML rendering for this message.") 00370 : QString::null ; 00371 } 00372 } 00373 00374 // defined in kmreaderwin.cpp... 00375 extern bool foundSMIMEData( const QString aUrl, QString & displayName, 00376 QString & libName, QString & keyId ); 00377 00378 namespace { 00379 bool SMimeURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00380 if ( !url.hasRef() ) 00381 return false; 00382 QString displayName, libName, keyId; 00383 if ( !foundSMIMEData( url.path() + '#' + url.ref(), displayName, libName, keyId ) ) 00384 return false; 00385 KProcess cmp; 00386 cmp << "kleopatra" << "-query" << keyId; 00387 if ( !cmp.start( KProcess::DontCare ) ) 00388 KMessageBox::error( w, i18n("Could not start certificate manager. " 00389 "Please check your installation."), 00390 i18n("KMail Error") ); 00391 return true; 00392 } 00393 00394 QString SMimeURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const { 00395 QString displayName, libName, keyId; 00396 if ( !foundSMIMEData( url.path() + '#' + url.ref(), displayName, libName, keyId ) ) 00397 return QString::null; 00398 return i18n("Show certificate 0x%1").arg( keyId ); 00399 } 00400 } 00401 00402 namespace { 00403 bool GroupwareURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00404 if ( !kmkernel->groupware().isEnabled() ) 00405 return false; 00406 return !w || kmkernel->groupware().handleLink( url, w->message() ); 00407 } 00408 00409 QString GroupwareURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const { 00410 QString type, action, action2, dummy; 00411 if ( url.url().find( "groupware_" ) == -1 ) return QString::null; 00412 //if ( !KMGroupware::foundGroupwareLink( url.url(), type, action, action2, dummy ) ) 00413 // return QString::null; 00414 QString result = type + ' ' + action; 00415 if ( !action2.isEmpty() ) 00416 result += ' ' + action2; 00417 return i18n("Groupware: \"%1\"").arg( result ); 00418 } 00419 } 00420 00421 namespace { 00422 bool HtmlAnchorHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00423 if ( url.hasHost() || url.path() != "/" || !url.hasRef() ) 00424 return false; 00425 if ( w && !w->htmlPart()->gotoAnchor( url.ref() ) ) 00426 static_cast<QScrollView*>( w->htmlPart()->widget() )->ensureVisible( 0, 0 ); 00427 return true; 00428 } 00429 } 00430 00431 namespace { 00432 QString MailToURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const { 00433 if ( url.protocol() != "mailto" ) 00434 return QString::null; 00435 return KMMessage::decodeMailtoUrl( url.url() ); 00436 } 00437 } 00438 00439 namespace { 00440 bool AttachmentURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00441 if ( !w || !w->message() ) 00442 return false; 00443 const int id = KMReaderWin::msgPartFromUrl( url ); 00444 if ( id <= 0 ) 00445 return false; 00446 w->openAttachment( id, url.path() ); 00447 return true; 00448 } 00449 00450 bool AttachmentURLHandler::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const { 00451 if ( !w || !w->message() ) 00452 return false; 00453 const int id = KMReaderWin::msgPartFromUrl( url ); 00454 if ( id <= 0 ) 00455 return false; 00456 w->showAttachmentPopup( id, url.path(), p ); 00457 return true; 00458 } 00459 00460 QString AttachmentURLHandler::statusBarMessage( const KURL & url, KMReaderWin * w ) const { 00461 if ( !w || !w->message() ) 00462 return QString::null; 00463 const partNode * node = w->partNodeFromUrl( url ); 00464 if ( !node ) 00465 return QString::null; 00466 const KMMessagePart & msgPart = node->msgPart(); 00467 QString name = msgPart.fileName(); 00468 if ( name.isEmpty() ) 00469 name = msgPart.name(); 00470 if ( !name.isEmpty() ) 00471 return i18n( "Attachment: %1" ).arg( name ); 00472 return i18n( "Attachment #%1 (unnamed)" ).arg( KMReaderWin::msgPartFromUrl( url ) ); 00473 } 00474 } 00475 00476 namespace { 00477 bool FallBackURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00478 if ( w ) 00479 w->emitUrlClicked( url, Qt::LeftButton ); 00480 return true; 00481 } 00482 00483 bool FallBackURLHandler::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const { 00484 if ( w ) 00485 w->emitPopupMenu( url, p ); 00486 return true; 00487 } 00488 }
KDE Logo
This file is part of the documentation for kmail Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 1 15:19:25 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003