00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
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 }
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
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 );
00180 mHandlers.push_back( handler );
00181 }
00182
00183
void KMail::URLHandlerManager::BodyPartURLHandlerManager::unregisterHandler(
const Interface::BodyPartURLHandler * handler ) {
00184
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
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
00257
00258
00259
00260 KMail::URLHandlerManager::URLHandlerManager() {
00261 registerHandler(
new ShowHtmlSwitchURLHandler() );
00262 registerHandler(
new SMimeURLHandler() );
00263
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 );
00280 mHandlers.push_back( handler );
00281 }
00282
00283
void KMail::URLHandlerManager::unregisterHandler(
const URLHandler * handler ) {
00284
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
00325
00326
00327
00328
00329
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
00357
00358
00359
00360
00361
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
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
00412
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 }