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 00218 Callback callback( w->message() ); 00219 KMail::PartNodeBodyPart part( *node, w->overrideCodec() ); 00220 for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) 00221 if ( (*it)->handleClick( &part, path, callback ) ) 00222 return true; 00223 return false; 00224 } 00225 00226 bool KMail::URLHandlerManager::BodyPartURLHandlerManager::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const { 00227 QString path; 00228 partNode * node = partNodeFromXKMailUrl( url, w, &path ); 00229 if ( !node ) 00230 return false; 00231 00232 KMail::PartNodeBodyPart part( *node, w->overrideCodec() ); 00233 for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) 00234 if ( (*it)->handleContextMenuRequest( &part, path, p ) ) 00235 return true; 00236 return false; 00237 } 00238 00239 QString KMail::URLHandlerManager::BodyPartURLHandlerManager::statusBarMessage( const KURL & url, KMReaderWin * w ) const { 00240 QString path; 00241 partNode * node = partNodeFromXKMailUrl( url, w, &path ); 00242 if ( !node ) 00243 return QString::null; 00244 00245 KMail::PartNodeBodyPart part( *node, w->overrideCodec() ); 00246 for ( BodyPartHandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) { 00247 const QString msg = (*it)->statusBarMessage( &part, path ); 00248 if ( !msg.isEmpty() ) 00249 return msg; 00250 } 00251 return QString::null; 00252 } 00253 00254 // 00255 // 00256 // URLHandlerManager 00257 // 00258 // 00259 00260 KMail::URLHandlerManager::URLHandlerManager() { 00261 registerHandler( new ShowHtmlSwitchURLHandler() ); 00262 registerHandler( new SMimeURLHandler() ); 00263 // registerHandler( new GroupwareURLHandler() ); 00264 registerHandler( new MailToURLHandler() ); 00265 registerHandler( new HtmlAnchorHandler() ); 00266 registerHandler( new AttachmentURLHandler() ); 00267 registerHandler( mBodyPartURLHandlerManager = new BodyPartURLHandlerManager() ); 00268 registerHandler( new FallBackURLHandler() ); 00269 } 00270 00271 KMail::URLHandlerManager::~URLHandlerManager() { 00272 for_each( mHandlers.begin(), mHandlers.end(), 00273 Delete<URLHandler>() ); 00274 } 00275 00276 void KMail::URLHandlerManager::registerHandler( const URLHandler * handler ) { 00277 if ( !handler ) 00278 return; 00279 unregisterHandler( handler ); // don't produce duplicates 00280 mHandlers.push_back( handler ); 00281 } 00282 00283 void KMail::URLHandlerManager::unregisterHandler( const URLHandler * handler ) { 00284 // don't delete them, only remove them from the list! 00285 mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() ); 00286 } 00287 00288 void KMail::URLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) { 00289 if ( mBodyPartURLHandlerManager ) 00290 mBodyPartURLHandlerManager->registerHandler( handler ); 00291 } 00292 00293 void KMail::URLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) { 00294 if ( mBodyPartURLHandlerManager ) 00295 mBodyPartURLHandlerManager->unregisterHandler( handler ); 00296 } 00297 00298 bool KMail::URLHandlerManager::handleClick( const KURL & url, KMReaderWin * w ) const { 00299 for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) 00300 if ( (*it)->handleClick( url, w ) ) 00301 return true; 00302 return false; 00303 } 00304 00305 bool KMail::URLHandlerManager::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const { 00306 for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) 00307 if ( (*it)->handleContextMenuRequest( url, p, w ) ) 00308 return true; 00309 return false; 00310 } 00311 00312 QString KMail::URLHandlerManager::statusBarMessage( const KURL & url, KMReaderWin * w ) const { 00313 for ( HandlerList::const_iterator it = mHandlers.begin() ; it != mHandlers.end() ; ++it ) { 00314 const QString msg = (*it)->statusBarMessage( url, w ); 00315 if ( !msg.isEmpty() ) 00316 return msg; 00317 } 00318 return QString::null; 00319 } 00320 00321 00322 // 00323 // 00324 // URLHandler 00325 // 00326 // 00327 00328 // these includes are temporary and should not be needed for the code 00329 // above this line, so they appear only here: 00330 #include "kmgroupware.h" 00331 #include "kmmessage.h" 00332 #include "kmkernel.h" 00333 #include "kmreaderwin.h" 00334 #include "partNode.h" 00335 #include "kmmsgpart.h" 00336 00337 #include <klocale.h> 00338 #include <kprocess.h> 00339 #include <kmessagebox.h> 00340 #include <khtml_part.h> 00341 00342 #include <qstring.h> 00343 00344 namespace { 00345 bool ShowHtmlSwitchURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00346 if ( url.protocol() == "kmail" ) 00347 { 00348 if ( url.path() == "showHTML" ) 00349 { 00350 if ( w ) { 00351 w->setHtmlOverride( !w->htmlOverride() ); 00352 w->update( true ); 00353 } 00354 return true; 00355 } 00356 // if ( url.path() == "startIMApp" ) 00357 // { 00358 // kmkernel->imProxy()->startPreferredApp(); 00359 // return true; 00360 // } 00361 // //FIXME: handle startIMApp urls in their own handler, or rename this one 00362 } 00363 return false; 00364 } 00365 00366 QString ShowHtmlSwitchURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const { 00367 return url.url() == "kmail:showHTML" 00368 ? i18n("Turn on HTML rendering for this message.") 00369 : QString::null ; 00370 } 00371 } 00372 00373 // defined in kmreaderwin.cpp... 00374 extern bool foundSMIMEData( const QString aUrl, QString & displayName, 00375 QString & libName, QString & keyId ); 00376 00377 namespace { 00378 bool SMimeURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00379 if ( !url.hasRef() ) 00380 return false; 00381 QString displayName, libName, keyId; 00382 if ( !foundSMIMEData( url.path() + '#' + url.ref(), displayName, libName, keyId ) ) 00383 return false; 00384 KProcess cmp; 00385 cmp << "kleopatra" << "-query" << keyId; 00386 if ( !cmp.start( KProcess::DontCare ) ) 00387 KMessageBox::error( w, i18n("Could not start certificate manager. " 00388 "Please check your installation."), 00389 i18n("KMail Error") ); 00390 return true; 00391 } 00392 00393 QString SMimeURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const { 00394 QString displayName, libName, keyId; 00395 if ( !foundSMIMEData( url.path() + '#' + url.ref(), displayName, libName, keyId ) ) 00396 return QString::null; 00397 return i18n("Show certificate 0x%1").arg( keyId ); 00398 } 00399 } 00400 00401 namespace { 00402 bool GroupwareURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00403 if ( !kmkernel->groupware().isEnabled() ) 00404 return false; 00405 return !w || kmkernel->groupware().handleLink( url, w->message() ); 00406 } 00407 00408 QString GroupwareURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const { 00409 QString type, action, action2, dummy; 00410 if ( url.url().find( "groupware_" ) == -1 ) return QString::null; 00411 //if ( !KMGroupware::foundGroupwareLink( url.url(), type, action, action2, dummy ) ) 00412 // return QString::null; 00413 QString result = type + ' ' + action; 00414 if ( !action2.isEmpty() ) 00415 result += ' ' + action2; 00416 return i18n("Groupware: \"%1\"").arg( result ); 00417 } 00418 } 00419 00420 namespace { 00421 bool HtmlAnchorHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00422 if ( url.hasHost() || url.path() != "/" || !url.hasRef() ) 00423 return false; 00424 if ( w && !w->htmlPart()->gotoAnchor( url.ref() ) ) 00425 static_cast<QScrollView*>( w->htmlPart()->widget() )->ensureVisible( 0, 0 ); 00426 return true; 00427 } 00428 } 00429 00430 namespace { 00431 QString MailToURLHandler::statusBarMessage( const KURL & url, KMReaderWin * ) const { 00432 if ( url.protocol() != "mailto" ) 00433 return QString::null; 00434 return KMMessage::decodeMailtoUrl( url.url() ); 00435 } 00436 } 00437 00438 namespace { 00439 bool AttachmentURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00440 if ( !w || !w->message() ) 00441 return false; 00442 const int id = KMReaderWin::msgPartFromUrl( url ); 00443 if ( id <= 0 ) 00444 return false; 00445 w->openAttachment( id, url.path() ); 00446 return true; 00447 } 00448 00449 bool AttachmentURLHandler::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const { 00450 if ( !w || !w->message() ) 00451 return false; 00452 const int id = KMReaderWin::msgPartFromUrl( url ); 00453 if ( id <= 0 ) 00454 return false; 00455 w->showAttachmentPopup( id, url.path(), p ); 00456 return true; 00457 } 00458 00459 QString AttachmentURLHandler::statusBarMessage( const KURL & url, KMReaderWin * w ) const { 00460 if ( !w || !w->message() ) 00461 return QString::null; 00462 const partNode * node = w->partNodeFromUrl( url ); 00463 if ( !node ) 00464 return QString::null; 00465 const KMMessagePart & msgPart = node->msgPart(); 00466 QString name = msgPart.fileName(); 00467 if ( name.isEmpty() ) 00468 name = msgPart.name(); 00469 if ( !name.isEmpty() ) 00470 return i18n( "Attachment: %1" ).arg( name ); 00471 return i18n( "Attachment #%1 (unnamed)" ).arg( KMReaderWin::msgPartFromUrl( url ) ); 00472 } 00473 } 00474 00475 namespace { 00476 bool FallBackURLHandler::handleClick( const KURL & url, KMReaderWin * w ) const { 00477 if ( w ) 00478 w->emitUrlClicked( url, Qt::LeftButton ); 00479 return true; 00480 } 00481 00482 bool FallBackURLHandler::handleContextMenuRequest( const KURL & url, const QPoint & p, KMReaderWin * w ) const { 00483 if ( w ) 00484 w->emitPopupMenu( url, p ); 00485 return true; 00486 } 00487 }
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 Aug 27 12:52:54 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003