• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

messageviewer

  • sources
  • kde-4.12
  • kdepim
  • messageviewer
  • viewer
urlhandlermanager.cpp
Go to the documentation of this file.
1 
2 /* -*- c++ -*-
3  urlhandlermanager.cpp
4 
5  This file is part of KMail, the KDE mail client.
6  Copyright (c) 2003 Marc Mutz <mutz@kde.org>
7  Copyright (C) 2002-2003, 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
8  Copyright (c) 2009 Andras Mantia <andras@kdab.net>
9 
10  KMail is free software; you can redistribute it and/or modify it
11  under the terms of the GNU General Public License, version 2, as
12  published by the Free Software Foundation.
13 
14  KMail is distributed in the hope that it will be useful, but
15  WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 
23  In addition, as a special exception, the copyright holders give
24  permission to link the code of this program with any edition of
25  the Qt library by Trolltech AS, Norway (or with modified versions
26  of Qt that use the same license as Qt), and distribute linked
27  combinations including the two. You must obey the GNU General
28  Public License in all respects for all of the code used other than
29  Qt. If you modify this file, you may extend this exception to
30  your version of the file, but you are not obligated to do so. If
31  you do not wish to do so, delete this exception statement from
32  your version.
33 */
34 
35 
36 
37 
38 #include "urlhandlermanager.h"
39 
40 #include "interfaces/urlhandler.h"
41 #include "interfaces/bodyparturlhandler.h"
42 #include "partnodebodypart.h"
43 #include "viewer/viewer_p.h"
44 #include "viewer/mailwebview.h"
45 #include "viewer/nodehelper.h"
46 #include "utils/util.h"
47 #include "stl_util.h"
48 
49 #include <messagecore/utils/stringutil.h>
50 #include <libkdepim/misc/broadcaststatus.h>
51 #include <libkdepim/job/openemailaddressjob.h>
52 
53 #include <akonadi/contact/contactsearchjob.h>
54 
55 #include <kmime/kmime_content.h>
56 #include <KPIMUtils/Email>
57 #include <KPIMUtils/KFileIO>
58 
59 #include <KMenu>
60 #include <KMimeType>
61 #include <KRun>
62 #include <KStandardDirs>
63 #include <KUrl>
64 
65 #include <QApplication>
66 #include <QClipboard>
67 #include <QProcess>
68 #include <QFile>
69 #include <QMimeData>
70 #include <QDrag>
71 
72 #include <algorithm>
73 
74 using std::for_each;
75 using std::remove;
76 using std::find;
77 using namespace MessageViewer;
78 using namespace MessageCore;
79 
80 URLHandlerManager * URLHandlerManager::self = 0;
81 
82 namespace {
83  class KMailProtocolURLHandler : public URLHandler {
84  public:
85  KMailProtocolURLHandler() : URLHandler() {}
86  ~KMailProtocolURLHandler() {}
87 
88  bool handleClick( const KUrl &, ViewerPrivate * ) const;
89  bool handleContextMenuRequest( const KUrl & url, const QPoint &, ViewerPrivate * ) const {
90  return url.protocol() == QLatin1String( "kmail" );
91  }
92  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const;
93  };
94 
95  class ExpandCollapseQuoteURLManager : public URLHandler {
96  public:
97  ExpandCollapseQuoteURLManager() : URLHandler() {}
98  ~ExpandCollapseQuoteURLManager() {}
99 
100  bool handleClick( const KUrl &, ViewerPrivate * ) const;
101  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const {
102  return false;
103  }
104  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const;
105 
106  };
107 
108  class SMimeURLHandler : public URLHandler {
109  public:
110  SMimeURLHandler() : URLHandler() {}
111  ~SMimeURLHandler() {}
112 
113  bool handleClick( const KUrl &, ViewerPrivate * ) const;
114  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const {
115  return false;
116  }
117  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const;
118  };
119 
120  class MailToURLHandler : public URLHandler {
121  public:
122  MailToURLHandler() : URLHandler() {}
123  ~MailToURLHandler() {}
124 
125  bool handleClick( const KUrl &, ViewerPrivate * ) const { return false; }
126  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const {
127  return false;
128  }
129  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const;
130  };
131 
132  class ContactUidURLHandler : public URLHandler {
133  public:
134  ContactUidURLHandler() : URLHandler() {}
135  ~ContactUidURLHandler() {}
136 
137  bool handleClick( const KUrl &, ViewerPrivate * ) const;
138  bool handleContextMenuRequest( const KUrl &url, const QPoint &p, ViewerPrivate * ) const;
139  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const;
140  };
141 
142  class HtmlAnchorHandler : public URLHandler {
143  public:
144  HtmlAnchorHandler() : URLHandler() {}
145  ~HtmlAnchorHandler() {}
146 
147  bool handleClick( const KUrl &, ViewerPrivate * ) const;
148  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const {
149  return false;
150  }
151  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const { return QString(); }
152  };
153 
154  class AttachmentURLHandler : public URLHandler {
155  public:
156  AttachmentURLHandler() : URLHandler() {}
157  ~AttachmentURLHandler() {}
158 
159  bool handleClick( const KUrl &, ViewerPrivate * ) const;
160  bool handleShiftClick( const KUrl &, ViewerPrivate *window ) const;
161  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const;
162  bool handleDrag( const KUrl &url, ViewerPrivate *window ) const;
163  bool willHandleDrag( const KUrl &url, ViewerPrivate *window ) const;
164  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const;
165  private:
166  KMime::Content* nodeForUrl( const KUrl &url, ViewerPrivate *w ) const;
167  bool attachmentIsInHeader( const KUrl &url ) const;
168  };
169 
170  class ShowAuditLogURLHandler : public URLHandler {
171  public:
172  ShowAuditLogURLHandler() : URLHandler() {}
173  ~ShowAuditLogURLHandler() {}
174 
175  bool handleClick( const KUrl &, ViewerPrivate * ) const;
176  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const;
177  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const;
178  };
179 
180  // Handler that prevents dragging of internal images added by KMail, such as the envelope image
181  // in the enterprise header
182  class InternalImageURLHandler : public URLHandler {
183  public:
184  InternalImageURLHandler() : URLHandler()
185  {}
186  ~InternalImageURLHandler()
187  {}
188  bool handleDrag( const KUrl &url, ViewerPrivate *window ) const;
189  bool willHandleDrag( const KUrl &url, ViewerPrivate *window ) const;
190  bool handleClick( const KUrl &, ViewerPrivate * ) const
191  { return false; }
192  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const
193  { return false; }
194  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const
195  { return QString(); }
196  };
197 
198  class KRunURLHandler : public URLHandler {
199  public:
200  KRunURLHandler() : URLHandler()
201  {}
202  ~KRunURLHandler()
203  {}
204 
205  bool handleClick( const KUrl &, ViewerPrivate * ) const;
206  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const {
207  return false;
208  }
209  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const { return QString(); }
210  };
211 
212 } // anon namespace
213 
214 
215 //
216 //
217 // BodyPartURLHandlerManager
218 //
219 //
220 
221 class URLHandlerManager::BodyPartURLHandlerManager : public URLHandler {
222 public:
223  BodyPartURLHandlerManager() : URLHandler() {}
224  ~BodyPartURLHandlerManager();
225 
226  bool handleClick( const KUrl &, ViewerPrivate * ) const;
227  bool handleContextMenuRequest( const KUrl &, const QPoint &, ViewerPrivate * ) const;
228  QString statusBarMessage( const KUrl &, ViewerPrivate * ) const;
229 
230  void registerHandler( const Interface::BodyPartURLHandler * handler );
231  void unregisterHandler( const Interface::BodyPartURLHandler * handler );
232 
233 private:
234  typedef QVector<const Interface::BodyPartURLHandler*> BodyPartHandlerList;
235  BodyPartHandlerList mHandlers;
236 };
237 
238 URLHandlerManager::BodyPartURLHandlerManager::~BodyPartURLHandlerManager() {
239  for_each( mHandlers.begin(), mHandlers.end(),
240  DeleteAndSetToZero<Interface::BodyPartURLHandler>() );
241 }
242 
243 void URLHandlerManager::BodyPartURLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) {
244  if ( !handler )
245  return;
246  unregisterHandler( handler ); // don't produce duplicates
247  mHandlers.push_back( handler );
248 }
249 
250 void URLHandlerManager::BodyPartURLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) {
251  // don't delete them, only remove them from the list!
252  mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
253 }
254 
255 static KMime::Content * partNodeFromXKMailUrl( const KUrl & url, ViewerPrivate * w, QString * path ) {
256  assert( path );
257 
258  if ( !w || url.protocol() != QLatin1String( "x-kmail" ) )
259  return 0;
260  const QString urlPath = url.path();
261 
262  // urlPath format is: /bodypart/<random number>/<part id>/<path>
263 
264  kDebug() << "BodyPartURLHandler: urlPath ==" << urlPath;
265  if ( !urlPath.startsWith( QLatin1String("/bodypart/") ) )
266  return 0;
267 
268  const QStringList urlParts = urlPath.mid( 10 ).split( QLatin1Char('/') );
269  if ( urlParts.size() != 3 )
270  return 0;
271  //KMime::ContentIndex index( urlParts[1] );
272  *path = KUrl::fromPercentEncoding( urlParts[2].toLatin1() );
273  return w->nodeFromUrl( urlParts[1] );
274 }
275 
276 bool URLHandlerManager::BodyPartURLHandlerManager::handleClick( const KUrl & url, ViewerPrivate * w ) const {
277  QString path;
278  KMime::Content * node = partNodeFromXKMailUrl( url, w, &path );
279  if ( !node )
280  return false;
281 
282  PartNodeBodyPart part( w->message().get(), node, w->nodeHelper(), w->overrideCodec() );
283  BodyPartHandlerList::const_iterator end( mHandlers.constEnd() );
284 
285  for ( BodyPartHandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it ) {
286  if ( (*it)->handleClick( w->viewer(), &part, path ) )
287  return true;
288  }
289 
290  return false;
291 }
292 
293 bool URLHandlerManager::BodyPartURLHandlerManager::handleContextMenuRequest( const KUrl & url, const QPoint & p, ViewerPrivate * w ) const {
294  QString path;
295  KMime::Content * node = partNodeFromXKMailUrl( url, w, &path );
296  if ( !node )
297  return false;
298 
299  PartNodeBodyPart part( w->message().get(), node, w->nodeHelper(), w->overrideCodec() );
300  BodyPartHandlerList::const_iterator end( mHandlers.constEnd() );
301  for ( BodyPartHandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it )
302  if ( (*it)->handleContextMenuRequest( &part, path, p ) )
303  return true;
304  return false;
305 }
306 
307 QString URLHandlerManager::BodyPartURLHandlerManager::statusBarMessage( const KUrl & url, ViewerPrivate * w ) const {
308  QString path;
309  KMime::Content * node = partNodeFromXKMailUrl( url, w, &path );
310  if ( !node )
311  return QString();
312 
313  PartNodeBodyPart part( w->message().get(), node, w->nodeHelper(), w->overrideCodec() );
314  BodyPartHandlerList::const_iterator end( mHandlers.constEnd() );
315  for ( BodyPartHandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it ) {
316  const QString msg = (*it)->statusBarMessage( &part, path );
317  if ( !msg.isEmpty() )
318  return msg;
319  }
320  return QString();
321 }
322 
323 //
324 //
325 // URLHandlerManager
326 //
327 //
328 
329 URLHandlerManager::URLHandlerManager() {
330  registerHandler( new KMailProtocolURLHandler() );
331  registerHandler( new ExpandCollapseQuoteURLManager() );
332  registerHandler( new SMimeURLHandler() );
333  registerHandler( new MailToURLHandler() );
334  registerHandler( new ContactUidURLHandler() );
335  registerHandler( new HtmlAnchorHandler() );
336  registerHandler( new AttachmentURLHandler() );
337  registerHandler( mBodyPartURLHandlerManager = new BodyPartURLHandlerManager() );
338  registerHandler( new ShowAuditLogURLHandler() );
339  registerHandler( new InternalImageURLHandler );
340  registerHandler( new KRunURLHandler() );
341 }
342 
343 URLHandlerManager::~URLHandlerManager() {
344  for_each( mHandlers.begin(), mHandlers.end(),
345  DeleteAndSetToZero<URLHandler>() );
346 }
347 
348 void URLHandlerManager::registerHandler( const URLHandler * handler ) {
349  if ( !handler )
350  return;
351  unregisterHandler( handler ); // don't produce duplicates
352  mHandlers.push_back( handler );
353 }
354 
355 void URLHandlerManager::unregisterHandler( const URLHandler * handler ) {
356  // don't delete them, only remove them from the list!
357  mHandlers.erase( remove( mHandlers.begin(), mHandlers.end(), handler ), mHandlers.end() );
358 }
359 
360 void URLHandlerManager::registerHandler( const Interface::BodyPartURLHandler * handler ) {
361  if ( mBodyPartURLHandlerManager )
362  mBodyPartURLHandlerManager->registerHandler( handler );
363 }
364 
365 void URLHandlerManager::unregisterHandler( const Interface::BodyPartURLHandler * handler ) {
366  if ( mBodyPartURLHandlerManager )
367  mBodyPartURLHandlerManager->unregisterHandler( handler );
368 }
369 
370 bool URLHandlerManager::handleClick( const KUrl & url, ViewerPrivate * w ) const {
371  HandlerList::const_iterator end( mHandlers.constEnd() );
372  for ( HandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it )
373  if ( (*it)->handleClick( url, w ) )
374  return true;
375  return false;
376 }
377 
378 bool URLHandlerManager::handleShiftClick( const KUrl &url, ViewerPrivate *window ) const
379 {
380  HandlerList::const_iterator end( mHandlers.constEnd() );
381  for ( HandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it )
382  if ( (*it)->handleShiftClick( url, window ) )
383  return true;
384  return false;
385 }
386 
387 bool URLHandlerManager::willHandleDrag( const KUrl &url, ViewerPrivate *window ) const
388 {
389  HandlerList::const_iterator end( mHandlers.constEnd() );
390 
391  for ( HandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it )
392  if ( (*it)->willHandleDrag( url, window ) )
393  return true;
394  return false;
395 }
396 
397 bool URLHandlerManager::handleDrag( const KUrl &url, ViewerPrivate *window ) const
398 {
399  HandlerList::const_iterator end( mHandlers.constEnd() );
400  for ( HandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it )
401  if ( (*it)->handleDrag( url, window ) )
402  return true;
403  return false;
404 }
405 
406 bool URLHandlerManager::handleContextMenuRequest( const KUrl & url, const QPoint & p, ViewerPrivate * w ) const {
407 
408  HandlerList::const_iterator end( mHandlers.constEnd() );
409  for ( HandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it )
410  if ( (*it)->handleContextMenuRequest( url, p, w ) )
411  return true;
412  return false;
413 }
414 
415 QString URLHandlerManager::statusBarMessage( const KUrl & url, ViewerPrivate * w ) const {
416  HandlerList::const_iterator end( mHandlers.constEnd() );
417  for ( HandlerList::const_iterator it = mHandlers.constBegin() ; it != end ; ++it ) {
418  const QString msg = (*it)->statusBarMessage( url, w );
419  if ( !msg.isEmpty() )
420  return msg;
421  }
422  return QString();
423 }
424 
425 
426 //
427 //
428 // URLHandler
429 //
430 //
431 
432 #include <ui/messagebox.h>
433 
434 #include <klocale.h>
435 #include <kmessagebox.h>
436 
437 namespace {
438  bool KMailProtocolURLHandler::handleClick( const KUrl & url, ViewerPrivate * w ) const {
439  if ( url.protocol() == QLatin1String( "kmail" ) ) {
440  if ( !w )
441  return false;
442  const QString urlPath( url.path() );
443  if ( urlPath == QLatin1String( "showHTML" ) ) {
444  w->setHtmlOverride( !w->htmlOverride() );
445  w->update( Viewer::Force );
446  return true;
447  }
448  else if ( urlPath == QLatin1String( "goOnline" ) ) {
449  w->goOnline();
450  return true;
451  }
452  else if ( urlPath == QLatin1String( "goResourceOnline" ) ) {
453  w->goResourceOnline();
454  return true;
455  }
456  else if ( urlPath == QLatin1String( "loadExternal" ) ) {
457  w->setHtmlLoadExtOverride( !w->htmlLoadExtOverride() );
458  w->update( Viewer::Force );
459  return true;
460  }
461  else if ( urlPath == QLatin1String( "decryptMessage" ) ) {
462  w->setDecryptMessageOverwrite( true );
463  w->update( Viewer::Force );
464  return true;
465  }
466  else if ( urlPath == QLatin1String( "showSignatureDetails" ) ) {
467  w->setShowSignatureDetails( true );
468  w->update( Viewer::Force );
469  return true;
470  }
471  else if ( urlPath == QLatin1String( "hideSignatureDetails" ) ) {
472  w->setShowSignatureDetails( false );
473  w->update( Viewer::Force );
474  return true;
475  }
476  else if ( urlPath == QLatin1String( "showAttachmentQuicklist" ) ) {
477  w->setShowAttachmentQuicklist( true );
478  w->update( Viewer::Force );
479  return true;
480  }
481  else if ( urlPath == QLatin1String( "hideAttachmentQuicklist" ) ) {
482  w->setShowAttachmentQuicklist( false );
483  w->update( Viewer::Force );
484  return true;
485  }
486  else if ( urlPath == QLatin1String( "showFullToAddressList" ) ) {
487  w->setShowFullToAddressList( true );
488  w->update( Viewer::Force );
489  return true;
490  }
491  else if ( urlPath == QLatin1String( "hideFullToAddressList" ) ) {
492  w->setShowFullToAddressList( false );
493  w->update( Viewer::Force );
494  return true;
495  }
496  else if ( urlPath == QLatin1String( "showFullCcAddressList" ) ) {
497  w->setShowFullCcAddressList( true );
498  w->update( Viewer::Force );
499  return true;
500  }
501  else if ( urlPath == QLatin1String( "hideFullCcAddressList" ) ) {
502  w->setShowFullCcAddressList( false );
503  w->update( Viewer::Force );
504  return true;
505  }
506  else if ( urlPath == QLatin1String( "showRawToltecMail" ) ) {
507  w->setShowRawToltecMail( true );
508  w->update( Viewer::Force );
509  return true;
510  }
511  }
512  return false;
513  }
514 
515  QString KMailProtocolURLHandler::statusBarMessage( const KUrl & url, ViewerPrivate * ) const {
516  if ( url.protocol() == QLatin1String( "kmail" ) )
517  {
518  const QString urlPath( url.path() );
519  if ( urlPath == QLatin1String( "showHTML" ) )
520  return i18n("Turn on HTML rendering for this message.");
521  else if ( urlPath == QLatin1String( "loadExternal" ) )
522  return i18n("Load external references from the Internet for this message.");
523  else if ( urlPath == QLatin1String( "goOnline" ) )
524  return i18n("Work online.");
525  else if ( urlPath == QLatin1String( "goResourceOnline" ) )
526  return i18n("Make account online.");
527  else if ( urlPath == QLatin1String( "decryptMessage" ) )
528  return i18n("Decrypt message.");
529  else if ( urlPath == QLatin1String( "showSignatureDetails" ) )
530  return i18n("Show signature details.");
531  else if ( urlPath == QLatin1String( "hideSignatureDetails" ) )
532  return i18n("Hide signature details.");
533  else if ( urlPath == QLatin1String( "showAttachmentQuicklist" ) )
534  return i18n( "Show attachment list." );
535  else if ( urlPath == QLatin1String( "hideAttachmentQuicklist" ) )
536  return i18n( "Hide attachment list." );
537  else if ( urlPath == QLatin1String( "showFullToAddressList" ) )
538  return i18n( "Show full \"To\" list" );
539  else if ( urlPath == QLatin1String( "hideFullToAddressList" ) )
540  return i18n( "Hide full \"To\" list" );
541  else if ( urlPath == QLatin1String( "showFullCcAddressList" ) )
542  return i18n( "Show full \"Cc\" list" );
543  else if ( urlPath == QLatin1String( "hideFullCcAddressList" ) )
544  return i18n( "Hide full \"Cc\" list" );
545  else if ( urlPath == QLatin1String( "showRawToltecMail" ) )
546  return i18n( "Show Raw Message" );
547  else return QString();
548  }
549  return QString() ;
550  }
551 }
552 
553 namespace {
554 
555  bool ExpandCollapseQuoteURLManager::handleClick(
556  const KUrl & url, ViewerPrivate * w ) const
557  {
558  // kmail:levelquote/?num -> the level quote to collapse.
559  // kmail:levelquote/?-num -> expand all levels quote.
560  if ( url.protocol() == QLatin1String( "kmail" ) && url.path()==QLatin1String( "levelquote" ) )
561  {
562  const QString levelStr= url.query().mid( 1,url.query().length() );
563  bool isNumber = false;
564  const int levelQuote= levelStr.toInt(&isNumber);
565  if ( isNumber )
566  w->slotLevelQuote( levelQuote );
567  return true;
568  }
569  return false;
570  }
571  QString ExpandCollapseQuoteURLManager::statusBarMessage(
572  const KUrl & url, ViewerPrivate * ) const
573  {
574  if ( url.protocol() == QLatin1String( "kmail" ) && url.path() == QLatin1String( "levelquote" ) )
575  {
576  const QString query= url.query();
577  if ( query.length()>=2 ) {
578  if ( query[ 1 ] ==QLatin1Char( '-' ) ) {
579  return i18n("Expand all quoted text.");
580  }
581  else {
582  return i18n("Collapse quoted text.");
583  }
584  }
585  }
586  return QString() ;
587  }
588 
589 }
590 
591 bool foundSMIMEData( const QString &aUrl,
592  QString& displayName,
593  QString& libName,
594  QString& keyId )
595 {
596  static QString showCertMan(QLatin1String("showCertificate#"));
597  displayName.clear();
598  libName.clear();
599  keyId.clear();
600  int i1 = aUrl.indexOf( showCertMan );
601  if( -1 < i1 ) {
602  i1 += showCertMan.length();
603  int i2 = aUrl.indexOf(QLatin1String(" ### "), i1);
604  if( i1 < i2 )
605  {
606  displayName = aUrl.mid( i1, i2-i1 );
607  i1 = i2+5;
608  i2 = aUrl.indexOf(QLatin1String(" ### "), i1);
609  if( i1 < i2 )
610  {
611  libName = aUrl.mid( i1, i2-i1 );
612  i2 += 5;
613 
614  keyId = aUrl.mid( i2 );
615  /*
616  int len = aUrl.length();
617  if( len > i2+1 ) {
618  keyId = aUrl.mid( i2, 2 );
619  i2 += 2;
620  while( len > i2+1 ) {
621  keyId += ':';
622  keyId += aUrl.mid( i2, 2 );
623  i2 += 2;
624  }
625  }
626  */
627  }
628  }
629  }
630  return !keyId.isEmpty();
631 }
632 
633 
634 namespace {
635  bool SMimeURLHandler::handleClick( const KUrl & url, ViewerPrivate * w ) const {
636  if ( !url.hasRef() )
637  return false;
638  QString displayName, libName, keyId;
639  if ( !foundSMIMEData( url.path() + QLatin1Char('#') +
640  QUrl::fromPercentEncoding( url.ref().toLatin1() ),
641  displayName, libName, keyId ) )
642  return false;
643  QStringList lst;
644  lst << QLatin1String("-parent-windowid") << QString::number((qlonglong)w->viewer()->mainWindow()->winId() ) << QLatin1String("-query") << keyId;
645  if ( !QProcess::startDetached( QLatin1String("kleopatra"),lst) )
646  KMessageBox::error( w->mMainWindow, i18n("Could not start certificate manager. "
647  "Please check your installation."),
648  i18n("KMail Error") );
649  return true;
650  }
651 
652  QString SMimeURLHandler::statusBarMessage( const KUrl & url, ViewerPrivate * ) const {
653  QString displayName, libName, keyId;
654  if ( !foundSMIMEData( url.path() + QLatin1Char('#') +
655  QUrl::fromPercentEncoding( url.ref().toLatin1() ),
656  displayName, libName, keyId ) )
657  return QString();
658  return i18n("Show certificate 0x%1", keyId );
659  }
660 }
661 
662 namespace {
663  bool HtmlAnchorHandler::handleClick( const KUrl & url, ViewerPrivate * w ) const {
664  if ( url.hasHost() || !url.hasRef() )
665  return false;
666 
667  w->htmlPart()->scrollToAnchor( url.ref() );
668  return true;
669  }
670 }
671 
672 namespace {
673  QString MailToURLHandler::statusBarMessage( const KUrl & url, ViewerPrivate * ) const {
674  if ( url.protocol() == QLatin1String( "mailto" ) )
675  return KPIMUtils::decodeMailtoUrl( url );
676  return QString();
677  }
678 }
679 
680 namespace {
681  static QString searchFullEmailByUid( const QString &uid )
682  {
683  QString fullEmail;
684  Akonadi::ContactSearchJob *job = new Akonadi::ContactSearchJob();
685  job->setLimit( 1 );
686  job->setQuery( Akonadi::ContactSearchJob::ContactUid, uid, Akonadi::ContactSearchJob::ExactMatch );
687  job->exec();
688  const KABC::Addressee::List res = job->contacts();
689  if ( !res.isEmpty() ) {
690  KABC::Addressee addr = res.first();
691  fullEmail = addr.fullEmail();
692  }
693  return fullEmail;
694  }
695 
696  static void runKAddressBook( const KUrl &url )
697  {
698  KPIM::OpenEmailAddressJob *job = new KPIM::OpenEmailAddressJob( url.path(), 0 );
699  job->start();
700  }
701 
702  bool ContactUidURLHandler::handleClick( const KUrl &url, ViewerPrivate * ) const
703  {
704  if ( url.protocol() == QLatin1String( "uid" ) ) {
705  runKAddressBook( url );
706  return true;
707  } else {
708  return false;
709  }
710  }
711 
712  bool ContactUidURLHandler::handleContextMenuRequest( const KUrl &url, const QPoint &p,
713  ViewerPrivate * ) const
714  {
715  if ( url.protocol() != QLatin1String( "uid" ) || url.path().isEmpty() ) {
716  return false;
717  }
718 
719  KMenu *menu = new KMenu();
720  QAction *open =
721  menu->addAction( KIcon( QLatin1String("view-pim-contacts") ), i18n( "&Open in Address Book" ) );
722 #ifndef QT_NO_CLIPBOARD
723  QAction *copy =
724  menu->addAction( KIcon( QLatin1String("edit-copy") ), i18n( "&Copy Email Address" ) );
725 #endif
726 
727  QAction *a = menu->exec( p );
728  if ( a == open ) {
729  runKAddressBook( url );
730 #ifndef QT_NO_CLIPBOARD
731  } else if ( a == copy ) {
732  const QString fullEmail = searchFullEmailByUid( url.path() );
733  if ( !fullEmail.isEmpty() ) {
734  QClipboard *clip = QApplication::clipboard();
735  clip->setText( fullEmail, QClipboard::Clipboard );
736  clip->setText( fullEmail, QClipboard::Selection );
737  KPIM::BroadcastStatus::instance()->setStatusMsg( i18n( "Address copied to clipboard." ) );
738  }
739 #endif
740  }
741  delete menu;
742 
743  return true;
744  }
745 
746  QString ContactUidURLHandler::statusBarMessage( const KUrl &url, ViewerPrivate * ) const
747  {
748  if ( url.protocol() == QLatin1String( "uid" ) ) {
749  return i18n( "Lookup the contact in KAddressbook" );
750  } else {
751  return QString();
752  }
753  }
754 }
755 
756 namespace {
757  KMime::Content* AttachmentURLHandler::nodeForUrl( const KUrl &url, ViewerPrivate *w ) const
758  {
759  if ( !w || !w->mMessage )
760  return 0;
761  if ( url.protocol() == QLatin1String( "attachment" ) )
762  {
763  KMime::Content * node = w->nodeFromUrl( url );
764  return node;
765  }
766  return 0;
767  }
768 
769  bool AttachmentURLHandler::attachmentIsInHeader( const KUrl &url ) const
770  {
771  bool inHeader = false;
772  const QString place = url.queryItem( QLatin1String("place") ).toLower();
773  if ( !place.isNull() ) {
774  inHeader = ( place == QLatin1String( "header" ) );
775  }
776  return inHeader;
777  }
778 
779  bool AttachmentURLHandler::handleClick( const KUrl & url, ViewerPrivate * w ) const
780  {
781  KMime::Content *node = nodeForUrl( url, w );
782  if ( !node )
783  return false;
784 
785  const bool inHeader = attachmentIsInHeader( url );
786  const bool shouldShowDialog = !w->nodeHelper()->isNodeDisplayedEmbedded( node ) || !inHeader;
787  if ( inHeader )
788  w->scrollToAttachment( node );
789  if ( shouldShowDialog )
790  // PENDING(romain_kdab) : replace with toLocalFile() ?
791  w->openAttachment( node, w->nodeHelper()->tempFileUrlFromNode( node ).path() );
792 
793  return true;
794  }
795 
796  bool AttachmentURLHandler::handleShiftClick( const KUrl &url, ViewerPrivate *window ) const
797  {
798  KMime::Content *node = nodeForUrl( url, window );
799  if ( !node )
800  return false;
801  if ( !window )
802  return false;
803  Util::saveContents( window->viewer(), QList<KMime::Content*>() << node );
804  return true;
805  }
806 
807  bool AttachmentURLHandler::willHandleDrag( const KUrl &url, ViewerPrivate *window ) const
808  {
809  return nodeForUrl( url, window ) != 0;
810  }
811 
812  bool AttachmentURLHandler::handleDrag( const KUrl &url, ViewerPrivate *window ) const
813  {
814 #ifndef QT_NO_DRAGANDDROP
815  KMime::Content *node = nodeForUrl( url, window );
816  if ( !node )
817  return false;
818 
819  const KUrl tUrl = window->nodeHelper()->tempFileUrlFromNode( node );
820  const QString fileName = tUrl.path();
821  if ( !fileName.isEmpty() ) {
822  QFile f(fileName);
823  f.setPermissions(QFile::ReadOwner|QFile::WriteOwner|QFile::ReadUser|QFile::ReadGroup|QFile::ReadOther);
824  const QString icon = window->nodeHelper()->iconName( node, KIconLoader::Small );
825  QDrag *drag = new QDrag( window->viewer() );
826  QMimeData *mimeData = new QMimeData();
827  mimeData->setUrls( QList<QUrl>() << tUrl );
828  drag->setMimeData( mimeData );
829  if ( !icon.isEmpty() ) {
830  drag->setPixmap( QPixmap( icon ) );
831  }
832  drag->start();
833  return true;
834  }
835  else
836 #endif
837  return false;
838  }
839 
840  bool AttachmentURLHandler::handleContextMenuRequest( const KUrl & url, const QPoint & p, ViewerPrivate * w ) const
841  {
842  KMime::Content *node = nodeForUrl( url, w );
843  if ( !node )
844  return false;
845  // PENDING(romain_kdab) : replace with toLocalFile() ?
846  w->showAttachmentPopup( node, w->nodeHelper()->tempFileUrlFromNode( node ).path(), p );
847  return true;
848  }
849 
850  QString AttachmentURLHandler::statusBarMessage( const KUrl & url, ViewerPrivate * w ) const
851  {
852  KMime::Content *node = nodeForUrl( url, w );
853  if ( !node )
854  return QString();
855  const QString name = MessageViewer::NodeHelper::fileName( node );
856  if ( !name.isEmpty() )
857  return i18n( "Attachment: %1", name );
858  else if ( dynamic_cast<KMime::Message*>( node ) ) {
859  if ( node->header<KMime::Headers::Subject>() ) {
860  return i18n( "Encapsulated Message (Subject: %1)",
861  node->header<KMime::Headers::Subject>()->asUnicodeString() );
862  } else {
863  return i18n( "Encapsulated Message" );
864  }
865  }
866  return i18n( "Unnamed attachment" );
867  }
868 }
869 
870 namespace {
871  static QString extractAuditLog( const KUrl & url ) {
872  if ( url.protocol() != QLatin1String( "kmail" )
873  || url.path() != QLatin1String( "showAuditLog" ) )
874  return QString();
875  assert( !url.queryItem( QLatin1String("log") ).isEmpty() );
876  return url.queryItem( QLatin1String("log") );
877  }
878 
879  bool ShowAuditLogURLHandler::handleClick( const KUrl & url, ViewerPrivate * w ) const {
880  const QString auditLog = extractAuditLog( url );
881  if ( auditLog.isEmpty() )
882  return false;
883  Kleo::MessageBox::auditLog( w->mMainWindow, auditLog );
884  return true;
885  }
886 
887  bool ShowAuditLogURLHandler::handleContextMenuRequest( const KUrl & url, const QPoint &, ViewerPrivate * w ) const {
888  Q_UNUSED( w );
889  // disable RMB for my own links:
890  return !extractAuditLog( url ).isEmpty();
891  }
892 
893  QString ShowAuditLogURLHandler::statusBarMessage( const KUrl & url, ViewerPrivate * ) const {
894  if ( extractAuditLog( url ).isEmpty() )
895  return QString();
896  else
897  return i18n("Show GnuPG Audit Log for this operation");
898  }
899 }
900 
901 namespace {
902  bool InternalImageURLHandler::handleDrag( const KUrl &url, ViewerPrivate *window ) const
903  {
904  Q_UNUSED( window );
905  Q_UNUSED( url );
906 
907  // This will only be called when willHandleDrag() was true. Return false here, that will
908  // notify ViewerPrivate::eventFilter() that no drag was started.
909  return false;
910  }
911 
912  bool InternalImageURLHandler::willHandleDrag( const KUrl &url, ViewerPrivate *window ) const
913  {
914  Q_UNUSED( window );
915  if ( url.protocol() == QLatin1String( "data" ) && url.path().startsWith( QLatin1String("image") ) )
916  return true;
917 
918  const QString imagePath = KStandardDirs::locate( "data", QLatin1String("libmessageviewer/pics/") );
919  return url.path().contains( imagePath );
920  }
921 }
922 
923 namespace {
924  bool KRunURLHandler::handleClick( const KUrl & url, ViewerPrivate * w ) const
925  {
926  const QString protocol(url.protocol() );
927  if ( ( protocol == QLatin1String( "http" ) ) || ( protocol == QLatin1String( "https" ) ) ||
928  ( protocol == QLatin1String( "ftp" ) ) || ( protocol == QLatin1String( "file" ) ) ||
929  ( protocol == QLatin1String( "ftps" ) ) || ( protocol == QLatin1String( "sftp" ) ) ||
930  ( protocol == QLatin1String( "help" ) ) || ( protocol == QLatin1String( "vnc" ) ) ||
931  ( protocol == QLatin1String( "smb" ) ) || ( protocol == QLatin1String( "fish" ) ) ||
932  ( protocol == QLatin1String( "news" ) ) )
933  {
934  KPIM::BroadcastStatus::instance()->setTransientStatusMsg( i18n("Opening URL..."));
935  QTimer::singleShot( 2000, KPIM::BroadcastStatus::instance(), SLOT(reset()) );
936 
937  KMimeType::Ptr mime = KMimeType::findByUrl( url );
938  if (mime->name() == QLatin1String("application/x-desktop") ||
939  mime->name() == QLatin1String("application/x-executable") ||
940  mime->name() == QLatin1String("application/x-ms-dos-executable") ||
941  mime->name() == QLatin1String("application/x-shellscript") )
942  {
943  if ( KMessageBox::warningYesNo( 0, i18nc( "@info", "Do you really want to execute <filename>%1</filename>?",
944  url.pathOrUrl() ), QString(), KGuiItem(i18n("Execute")), KStandardGuiItem::cancel() ) != KMessageBox::Yes)
945  return true;
946  }
947  if ( !MessageViewer::Util::handleUrlWithQDesktopServices( url.pathOrUrl() ) ) {
948  KRun *runner = new KRun( url, w->viewer() ); // will delete itself
949  runner->setRunExecutables( false );
950  }
951 
952  return true;
953  }
954  else return false;
955  }
956 }
MessageViewer::ViewerPrivate::setShowSignatureDetails
void setShowSignatureDetails(bool showDetails=true)
Show signature details.
foundSMIMEData
bool foundSMIMEData(const QString &aUrl, QString &displayName, QString &libName, QString &keyId)
Definition: urlhandlermanager.cpp:591
MessageViewer::URLHandlerManager::statusBarMessage
QString statusBarMessage(const KUrl &url, ViewerPrivate *w=0) const
Definition: urlhandlermanager.cpp:415
MessageViewer::ViewerPrivate::mMessage
KMime::Message::Ptr mMessage
Definition: viewer_p.h:629
MessageViewer::PartNodeBodyPart
an implementation of the BodyPart interface using KMime::Content's
Definition: partnodebodypart.h:55
stl_util.h
MessageViewer::URLHandlerManager::registerHandler
void registerHandler(const URLHandler *handler)
Definition: urlhandlermanager.cpp:348
MessageViewer::ViewerPrivate::goResourceOnline
void goResourceOnline()
MessageViewer::URLHandlerManager::handleShiftClick
bool handleShiftClick(const KUrl &url, ViewerPrivate *window=0) const
Definition: urlhandlermanager.cpp:378
MessageViewer::ViewerPrivate::scrollToAttachment
void scrollToAttachment(KMime::Content *node)
MessageViewer::ViewerPrivate::setDecryptMessageOverwrite
void setDecryptMessageOverwrite(bool overwrite=true)
Enforce message decryption.
MessageViewer::Viewer::mainWindow
QWidget * mainWindow()
Definition: viewer.cpp:292
MessageViewer::ViewerPrivate::setHtmlLoadExtOverride
void setHtmlLoadExtOverride(bool override)
Override default load external references setting.
MessageViewer::ViewerPrivate::htmlLoadExtOverride
bool htmlLoadExtOverride() const
Get the load external references override setting.
MessageViewer::URLHandlerManager::~URLHandlerManager
~URLHandlerManager()
Definition: urlhandlermanager.cpp:343
nodehelper.h
partnodebodypart.h
MessageViewer::ViewerPrivate::nodeFromUrl
KMime::Content * nodeFromUrl(const KUrl &url)
Returns message part from given URL or null if invalid.
bodyparturlhandler.h
MessageViewer::ViewerPrivate
Private class for the Viewer, the main widget in the messageviewer library.
Definition: viewer_p.h:182
MessageViewer::Util::saveContents
bool MESSAGEVIEWER_EXPORT saveContents(QWidget *parent, const QList< KMime::Content * > &contents)
Definition: util.cpp:190
viewer_p.h
MessageViewer::DeleteAndSetToZero
Definition: stl_util.h:38
MessageViewer::MailWebView::scrollToAnchor
void scrollToAnchor(const QString &anchor)
Definition: mailwebview_textbrowser.cpp:168
MessageViewer::ViewerPrivate::mMainWindow
QWidget * mMainWindow
Definition: viewer_p.h:660
MessageViewer::ViewerPrivate::goOnline
void goOnline()
MessageViewer::Interface::BodyPartURLHandler
An interface to body part reader link handlers.
Definition: bodyparturlhandler.h:71
MessageViewer::ViewerPrivate::setShowRawToltecMail
void setShowRawToltecMail(bool showRawToltecMail)
Definition: viewer_p.h:427
MessageViewer::URLHandlerManager
Singleton to manage the list of URLHandlers.
Definition: urlhandlermanager.h:59
MessageViewer::ViewerPrivate::htmlPart
MailWebView * htmlPart() const
Access to the MailWebView used for the viewer.
Definition: viewer_p.h:215
MessageViewer::URLHandlerManager::handleContextMenuRequest
bool handleContextMenuRequest(const KUrl &url, const QPoint &p, ViewerPrivate *w=0) const
Definition: urlhandlermanager.cpp:406
MessageViewer::ViewerPrivate::viewer
Viewer * viewer() const
Definition: viewer_p.h:242
MessageViewer::ViewerPrivate::nodeHelper
NodeHelper * nodeHelper() const
Definition: viewer_p.h:240
util.h
MessageViewer::ViewerPrivate::overrideCodec
const QTextCodec * overrideCodec() const
Get codec corresponding to the currently selected override character encoding.
MessageViewer::NodeHelper::tempFileUrlFromNode
KUrl tempFileUrlFromNode(const KMime::Content *node)
Returns the temporary file path and name where this node was saved, or an empty url if it wasn't save...
Definition: nodehelper.cpp:257
MessageViewer::ViewerPrivate::slotLevelQuote
void slotLevelQuote(int l)
MessageViewer::ViewerPrivate::htmlOverride
bool htmlOverride() const
Get the html override setting.
MessageViewer::URLHandler
An interface to reader link handlers.
Definition: urlhandler.h:51
partNodeFromXKMailUrl
static KMime::Content * partNodeFromXKMailUrl(const KUrl &url, ViewerPrivate *w, QString *path)
Definition: urlhandlermanager.cpp:255
MessageViewer::ViewerPrivate::setShowAttachmentQuicklist
void setShowAttachmentQuicklist(bool showAttachmentQuicklist=true)
MessageViewer::ViewerPrivate::showAttachmentPopup
void showAttachmentPopup(KMime::Content *node, const QString &name, const QPoint &p)
MessageViewer::ViewerPrivate::setShowFullToAddressList
void setShowFullToAddressList(bool showFullToAddressList=true)
Show or hide the full list of "To" addresses.
MessageViewer::ViewerPrivate::update
void update(MessageViewer::Viewer::UpdateMode updateMode=Viewer::Delayed)
Re-parse the current message.
MessageViewer::URLHandlerManager::handleDrag
bool handleDrag(const KUrl &url, ViewerPrivate *window=0) const
Definition: urlhandlermanager.cpp:397
mailwebview.h
MessageViewer::NodeHelper::iconName
static QString iconName(KMime::Content *node, int size=KIconLoader::Desktop)
Definition: nodehelper.cpp:469
MessageViewer::ViewerPrivate::setShowFullCcAddressList
void setShowFullCcAddressList(bool showFullCcAddressList=true)
Show or hide the full list of "To" addresses.
MessageViewer::ViewerPrivate::setHtmlOverride
void setHtmlOverride(bool override)
Override default html mail setting.
MessageViewer::ViewerPrivate::openAttachment
void openAttachment(KMime::Content *node, const QString &fileName)
Open the attachment pointed to the node.
MessageViewer::ViewerPrivate::message
KMime::Message::Ptr message() const
Definition: viewer_p.h:246
urlhandlermanager.h
MessageViewer::Viewer::Force
Definition: viewer.h:133
MessageViewer::NodeHelper::isNodeDisplayedEmbedded
bool isNodeDisplayedEmbedded(KMime::Content *node) const
Definition: nodehelper.cpp:631
urlhandler.h
MessageViewer::URLHandlerManager::handleClick
bool handleClick(const KUrl &url, ViewerPrivate *w=0) const
Definition: urlhandlermanager.cpp:370
MessageViewer::Util::handleUrlWithQDesktopServices
bool MESSAGEVIEWER_EXPORT handleUrlWithQDesktopServices(const KUrl &url)
Delegates opening a URL to the QDesktopServices mechanisms for that on Windows and MacOSX...
Definition: util.cpp:142
MessageViewer::NodeHelper::fileName
static QString fileName(const KMime::Content *node)
Returns a usable filename for a node, that can be the filename from the content disposition header...
Definition: nodehelper.cpp:586
MessageViewer::URLHandlerManager::unregisterHandler
void unregisterHandler(const URLHandler *handler)
Definition: urlhandlermanager.cpp:355
MessageViewer::URLHandlerManager::willHandleDrag
bool willHandleDrag(const KUrl &url, ViewerPrivate *window=0) const
Definition: urlhandlermanager.cpp:387
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:57 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

messageviewer

Skip menu "messageviewer"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal