• 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
nodehelper.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-file-style: "gnu" -*-
2  Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
3  Copyright (c) 2009 Andras Mantia <andras@kdab.net>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19 
20 
21 #include "nodehelper.h"
22 #include "utils/iconnamecache.h"
23 #include "settings/globalsettings.h"
24 #include "partmetadata.h"
25 #include "interfaces/bodypart.h"
26 #include "utils/util.h"
27 #include "viewer/attachmenttemporaryfilesdirs.h"
28 
29 #include <messagecore/helpers/nodehelper.h>
30 #include <messagecore/utils/stringutil.h>
31 #include "messagecore/settings/globalsettings.h"
32 
33 #include <kmime/kmime_content.h>
34 #include <kmime/kmime_message.h>
35 #include <kmime/kmime_headers.h>
36 #include <kmimetype.h>
37 #include <kdebug.h>
38 #include <kascii.h>
39 #include <ktemporaryfile.h>
40 #include <klocale.h>
41 #include <kcharsets.h>
42 #include <kde_file.h>
43 #include <kpimutils/kfileio.h>
44 
45 #include <QDir>
46 #include <QTextCodec>
47 
48 #include <string>
49 #include <sstream>
50 #include <algorithm>
51 
52 
53 namespace MessageViewer {
54 
55 QStringList replySubjPrefixes(QStringList() << QLatin1String("Re\\s*:") << QLatin1String("Re\\[\\d+\\]:") << QLatin1String("Re\\d+:"));
56 QStringList forwardSubjPrefixes( QStringList() << QLatin1String("Fwd:") << QLatin1String("FW:"));
57 
58 NodeHelper::NodeHelper() :
59  mAttachmentFilesDir(new AttachmentTemporaryFilesDirs())
60 {
61  //TODO(Andras) add methods to modify these prefixes
62 
63  mLocalCodec = QTextCodec::codecForName( KGlobal::locale()->encoding() );
64 
65  // In the case of Japan. Japanese locale name is "eucjp" but
66  // The Japanese mail systems normally used "iso-2022-jp" of locale name.
67  // We want to change locale name from eucjp to iso-2022-jp at KMail only.
68 
69  // (Introduction to i18n, 6.6 Limit of Locale technology):
70  // EUC-JP is the de-facto standard for UNIX systems, ISO 2022-JP
71  // is the standard for Internet, and Shift-JIS is the encoding
72  // for Windows and Macintosh.
73  if ( mLocalCodec ) {
74  if ( mLocalCodec->name().toLower() == "eucjp"
75 #if defined Q_WS_WIN || defined Q_WS_MACX
76  || mLocalCodec->name().toLower() == "shift-jis" // OK?
77 #endif
78  )
79  {
80  mLocalCodec = QTextCodec::codecForName("jis7");
81  // QTextCodec *cdc = QTextCodec::codecForName("jis7");
82  // QTextCodec::setCodecForLocale(cdc);
83  // KGlobal::locale()->setEncoding(cdc->mibEnum());
84  }
85  }
86 }
87 
88 NodeHelper::~NodeHelper()
89 {
90  //Don't delete it it will delete in class with a deleteLater;
91  mAttachmentFilesDir->removeTempFiles();
92  mAttachmentFilesDir = 0;
93 }
94 
95 void NodeHelper::setNodeProcessed(KMime::Content* node, bool recurse )
96 {
97  if ( !node )
98  return;
99  mProcessedNodes.append( node );
100  //kDebug() << "Node processed: " << node->index().toString() << node->contentType()->as7BitString();
101  //<< " decodedContent" << node->decodedContent();
102  if ( recurse ) {
103  KMime::Content::List contents = node->contents();
104  Q_FOREACH( KMime::Content *c, contents )
105  {
106  setNodeProcessed( c, true );
107  }
108  }
109 }
110 
111 void NodeHelper::setNodeUnprocessed(KMime::Content* node, bool recurse )
112 {
113  if ( !node )
114  return;
115  mProcessedNodes.removeAll( node );
116 
117  //avoid double addition of extra nodes, eg. encrypted attachments
118  const QMap<KMime::Content*, QList<KMime::Content*> >::iterator it = mExtraContents.find( node );
119  if ( it != mExtraContents.end() ) {
120  Q_FOREACH( KMime::Content* c, it.value() ) {
121  KMime::Content * p = c->parent();
122  if ( p )
123  p->removeContent( c );
124  }
125  qDeleteAll( it.value() );
126  //kDebug() << "mExtraContents deleted for" << it.key();
127  mExtraContents.erase( it );
128  }
129 
130  //kDebug() << "Node UNprocessed: " << node;
131  if ( recurse ) {
132  KMime::Content::List contents = node->contents();
133  Q_FOREACH( KMime::Content *c, contents )
134  {
135  setNodeUnprocessed( c, true );
136  }
137  }
138 }
139 
140 bool NodeHelper::nodeProcessed( KMime::Content* node ) const
141 {
142  if ( !node )
143  return true;
144  return mProcessedNodes.contains( node );
145 }
146 
147 static void clearBodyPartMemento(QMap<QByteArray, Interface::BodyPartMemento*> & bodyPartMementoMap)
148 {
149  for ( QMap<QByteArray, Interface::BodyPartMemento*>::iterator
150  it = bodyPartMementoMap.begin(), end = bodyPartMementoMap.end();
151  it != end; ++it ) {
152  Interface::BodyPartMemento *memento = it.value();
153  memento->detach();
154  delete memento;
155  }
156  bodyPartMementoMap.clear();
157 }
158 
159 
160 void NodeHelper::clear()
161 {
162  mProcessedNodes.clear();
163  mEncryptionState.clear();
164  mSignatureState.clear();
165  mOverrideCodecs.clear();
166  std::for_each( mBodyPartMementoMap.begin(), mBodyPartMementoMap.end(),
167  &clearBodyPartMemento );
168  mBodyPartMementoMap.clear();
169  QMap<KMime::Content*, QList<KMime::Content*> >::ConstIterator end( mExtraContents.constEnd() );
170 
171  for ( QMap<KMime::Content*, QList<KMime::Content*> >::ConstIterator it = mExtraContents.constBegin(); it != end; ++it) {
172  Q_FOREACH( KMime::Content* c, it.value() ) {
173  KMime::Content * p = c->parent();
174  if ( p )
175  p->removeContent( c );
176  }
177  qDeleteAll( it.value() );
178  kDebug() << "mExtraContents deleted for" << it.key();
179  }
180  mExtraContents.clear();
181  mDisplayEmbeddedNodes.clear();
182  mDisplayHiddenNodes.clear();
183 }
184 
185 
186 void NodeHelper::setEncryptionState( KMime::Content* node, const KMMsgEncryptionState state )
187 {
188  mEncryptionState[node] = state;
189 }
190 
191 KMMsgEncryptionState NodeHelper::encryptionState( KMime::Content *node ) const
192 {
193  return mEncryptionState.value( node, KMMsgNotEncrypted );
194 }
195 
196 void NodeHelper::setSignatureState( KMime::Content* node, const KMMsgSignatureState state )
197 {
198  mSignatureState[node] = state;
199 }
200 
201 KMMsgSignatureState NodeHelper::signatureState( KMime::Content *node ) const
202 {
203  return mSignatureState.value( node, KMMsgNotSigned );
204 }
205 
206 PartMetaData NodeHelper::partMetaData(KMime::Content* node)
207 {
208  return mPartMetaDatas.value( node, PartMetaData() );
209 }
210 
211 void NodeHelper::setPartMetaData(KMime::Content* node, const PartMetaData& metaData)
212 {
213  mPartMetaDatas.insert( node, metaData );
214 }
215 
216 QString NodeHelper::writeNodeToTempFile(KMime::Content* node)
217 {
218  // If the message part is already written to a file, no point in doing it again.
219  // This function is called twice actually, once from the rendering of the attachment
220  // in the body and once for the header.
221  KUrl existingFileName = tempFileUrlFromNode( node );
222  if ( !existingFileName.isEmpty() ) {
223  return existingFileName.toLocalFile();
224  }
225 
226  QString fname = createTempDir( persistentIndex( node ) );
227  if ( fname.isEmpty() )
228  return QString();
229 
230  QString fileName = NodeHelper::fileName( node );
231  // strip off a leading path
232  int slashPos = fileName.lastIndexOf( QLatin1Char('/') );
233  if( -1 != slashPos )
234  fileName = fileName.mid( slashPos + 1 );
235  if( fileName.isEmpty() )
236  fileName = QLatin1String("unnamed");
237  fname += QLatin1Char('/') + fileName;
238 
239  //kDebug() << "Create temp file: " << fname;
240  QByteArray data = node->decodedContent();
241  if ( node->contentType()->isText() && data.size() > 0 ) {
242  // convert CRLF to LF before writing text attachments to disk
243  data = KMime::CRLFtoLF( data );
244  }
245  if( !KPIMUtils::kByteArrayToFile( data, fname, false, false, false ) )
246  return QString();
247  mAttachmentFilesDir->addTempFile( fname );
248  // make file read-only so that nobody gets the impression that he might
249  // edit attached files (cf. bug #52813)
250  ::chmod( QFile::encodeName( fname ), S_IRUSR );
251 
252  return fname;
253 }
254 
255 
256 
257 KUrl NodeHelper::tempFileUrlFromNode( const KMime::Content *node )
258 {
259  if (!node)
260  return KUrl();
261 
262  const QString index = persistentIndex( node );
263 
264  foreach ( const QString &path, mAttachmentFilesDir->temporaryFiles() ) {
265  const int right = path.lastIndexOf( QLatin1Char('/') );
266  int left = path.lastIndexOf( QLatin1String(".index."), right );
267  if ( left != -1 )
268  left += 7;
269 
270  QStringRef storedIndex( &path, left, right - left );
271  if ( left != -1 && storedIndex == index )
272  return KUrl( path );
273  }
274  return KUrl();
275 }
276 
277 
278 QString NodeHelper::createTempDir( const QString &param )
279 {
280  KTemporaryFile *tempFile = new KTemporaryFile();
281  tempFile->setSuffix( QLatin1String(".index.") + param );
282  tempFile->open();
283  QString fname = tempFile->fileName();
284  delete tempFile;
285 
286  if ( ::access( QFile::encodeName( fname ), W_OK ) != 0 ) {
287  // Not there or not writable
288  if( KDE_mkdir( QFile::encodeName( fname ), 0 ) != 0 ||
289  ::chmod( QFile::encodeName( fname ), S_IRWXU ) != 0 ) {
290  return QString(); //failed create
291  }
292  }
293 
294  Q_ASSERT( !fname.isNull() );
295 
296  mAttachmentFilesDir->addTempDir( fname );
297  return fname;
298 }
299 
300 void NodeHelper::forceCleanTempFiles()
301 {
302  mAttachmentFilesDir->forceCleanTempFiles();
303  delete mAttachmentFilesDir;
304  mAttachmentFilesDir = 0;
305 }
306 
307 void NodeHelper::removeTempFiles()
308 {
309  //Don't delete it it will delete in class
310  mAttachmentFilesDir->removeTempFiles();
311  mAttachmentFilesDir = new AttachmentTemporaryFilesDirs();
312 }
313 
314 void NodeHelper::addTempFile( const QString& file )
315 {
316  mAttachmentFilesDir->addTempFile( file );
317 }
318 
319 bool NodeHelper::isToltecMessage( KMime::Content* node )
320 {
321  if ( !node->contentType( false ) )
322  return false;
323 
324  if ( node->contentType()->mediaType().toLower() != "multipart" ||
325  node->contentType()->subType().toLower() != "mixed" )
326  return false;
327 
328  if ( node->contents().size() != 3 )
329  return false;
330 
331  const KMime::Headers::Base *libraryHeader = node->headerByType( "X-Library" );
332  if ( !libraryHeader )
333  return false;
334 
335  if ( QString::fromLatin1( libraryHeader->as7BitString( false ) ).toLower() !=
336  QLatin1String( "toltec" ) )
337  return false;
338 
339  const KMime::Headers::Base *kolabTypeHeader = node->headerByType( "X-Kolab-Type" );
340  if ( !kolabTypeHeader )
341  return false;
342 
343  if ( !QString::fromLatin1( kolabTypeHeader->as7BitString( false ) ).toLower().startsWith(
344  QLatin1String( "application/x-vnd.kolab" ) ) )
345  return false;
346 
347  return true;
348 }
349 
350 bool NodeHelper::isInEncapsulatedMessage( KMime::Content* node )
351 {
352  const KMime::Content * const topLevel = node->topLevel();
353  const KMime::Content * cur = node;
354  while ( cur && cur != topLevel ) {
355  const bool parentIsMessage = cur->parent() && cur->parent()->contentType( false ) &&
356  cur->parent()->contentType()->mimeType().toLower() == "message/rfc822";
357  if ( parentIsMessage && cur->parent() != topLevel ) {
358  return true;
359  }
360  cur = cur->parent();
361  }
362  return false;
363 }
364 
365 
366 QByteArray NodeHelper::charset( KMime::Content *node )
367 {
368  if ( node->contentType( false ) )
369  return node->contentType( false )->charset();
370  else
371  return node->defaultCharset();
372 }
373 
374 KMMsgEncryptionState NodeHelper::overallEncryptionState( KMime::Content *node ) const
375 {
376  KMMsgEncryptionState myState = KMMsgEncryptionStateUnknown;
377  if ( !node )
378  return myState;
379 
380  if( encryptionState( node ) == KMMsgNotEncrypted ) {
381  // NOTE: children are tested ONLY when parent is not encrypted
382  KMime::Content *child = MessageCore::NodeHelper::firstChild( node );
383  if ( child )
384  myState = overallEncryptionState( child );
385  else
386  myState = KMMsgNotEncrypted;
387  }
388  else { // part is partially or fully encrypted
389  myState = encryptionState( node );
390  }
391  // siblings are tested always
392  KMime::Content * next = MessageCore::NodeHelper::nextSibling( node );
393  if( next ) {
394  KMMsgEncryptionState otherState = overallEncryptionState( next );
395  switch( otherState ) {
396  case KMMsgEncryptionStateUnknown:
397  break;
398  case KMMsgNotEncrypted:
399  if( myState == KMMsgFullyEncrypted )
400  myState = KMMsgPartiallyEncrypted;
401  else if( myState != KMMsgPartiallyEncrypted )
402  myState = KMMsgNotEncrypted;
403  break;
404  case KMMsgPartiallyEncrypted:
405  myState = KMMsgPartiallyEncrypted;
406  break;
407  case KMMsgFullyEncrypted:
408  if( myState != KMMsgFullyEncrypted )
409  myState = KMMsgPartiallyEncrypted;
410  break;
411  case KMMsgEncryptionProblematic:
412  break;
413  }
414  }
415 
416 //kDebug() <<"\n\n KMMsgEncryptionState:" << myState;
417 
418  return myState;
419 }
420 
421 
422 KMMsgSignatureState NodeHelper::overallSignatureState( KMime::Content* node ) const
423 {
424  KMMsgSignatureState myState = KMMsgSignatureStateUnknown;
425  if ( !node )
426  return myState;
427 
428  if( signatureState( node ) == KMMsgNotSigned ) {
429  // children are tested ONLY when parent is not signed
430  KMime::Content* child = MessageCore::NodeHelper::firstChild( node );
431  if( child )
432  myState = overallSignatureState( child );
433  else
434  myState = KMMsgNotSigned;
435  }
436  else { // part is partially or fully signed
437  myState = signatureState( node );
438  }
439  // siblings are tested always
440  KMime::Content *next = MessageCore::NodeHelper::nextSibling( node );
441  if( next ) {
442  KMMsgSignatureState otherState = overallSignatureState( next );
443  switch( otherState ) {
444  case KMMsgSignatureStateUnknown:
445  break;
446  case KMMsgNotSigned:
447  if( myState == KMMsgFullySigned )
448  myState = KMMsgPartiallySigned;
449  else if( myState != KMMsgPartiallySigned )
450  myState = KMMsgNotSigned;
451  break;
452  case KMMsgPartiallySigned:
453  myState = KMMsgPartiallySigned;
454  break;
455  case KMMsgFullySigned:
456  if( myState != KMMsgFullySigned )
457  myState = KMMsgPartiallySigned;
458  break;
459  case KMMsgSignatureProblematic:
460  break;
461  }
462  }
463 
464 //kDebug() <<"\n\n KMMsgSignatureState:" << myState;
465 
466  return myState;
467 }
468 
469 QString NodeHelper::iconName( KMime::Content *node, int size )
470 {
471  if ( !node )
472  return QString();
473 
474  QByteArray mimeType = node->contentType()->mimeType();
475  if(mimeType.isNull() || mimeType == "application/octet-stream" ) {
476  const QString mime = Util::mimetype(node->contentDisposition()->filename())->name();
477  mimeType = mime.toLatin1();
478  }
479  kAsciiToLower( mimeType.data() );
480  return Util::fileNameForMimetype( QLatin1String(mimeType), size, node->contentDisposition()->filename(),
481  node->contentType()->name() );
482 }
483 
484 void NodeHelper::magicSetType( KMime::Content* node, bool aAutoDecode )
485 {
486  const QByteArray body = ( aAutoDecode ) ? node->decodedContent() : node->body() ;
487  KMimeType::Ptr mime = KMimeType::findByContent( body );
488 
489  QString mimetype = mime->name();
490  node->contentType()->setMimeType( mimetype.toLatin1() );
491 }
492 
493 // static
494 QString NodeHelper::replacePrefixes( const QString& str,
495  const QStringList& prefixRegExps,
496  bool replace,
497  const QString& newPrefix )
498 {
499  bool recognized = false;
500  // construct a big regexp that
501  // 1. is anchored to the beginning of str (sans whitespace)
502  // 2. matches at least one of the part regexps in prefixRegExps
503  QString bigRegExp = QString::fromLatin1("^(?:\\s+|(?:%1))+\\s*")
504  .arg( prefixRegExps.join(QLatin1String(")|(?:")) );
505  QRegExp rx( bigRegExp, Qt::CaseInsensitive );
506  if ( !rx.isValid() ) {
507  kWarning() << "bigRegExp = \""
508  << bigRegExp << "\"\n"
509  << "prefix regexp is invalid!";
510  // try good ole Re/Fwd:
511  recognized = str.startsWith( newPrefix );
512  } else { // valid rx
513  QString tmp = str;
514  if ( rx.indexIn( tmp ) == 0 ) {
515  recognized = true;
516  if ( replace )
517  return tmp.replace( 0, rx.matchedLength(), newPrefix + QLatin1Char(' ') );
518  }
519  }
520  if ( !recognized )
521  return newPrefix + QLatin1Char(' ') + str;
522  else
523  return str;
524 }
525 
526 QString NodeHelper::cleanSubject( KMime::Message *message )
527 {
528  return cleanSubject( message, replySubjPrefixes + forwardSubjPrefixes,
529  true, QString() ).trimmed();
530 }
531 
532 QString NodeHelper::cleanSubject( KMime::Message *message,
533  const QStringList &prefixRegExps,
534  bool replace,
535  const QString &newPrefix )
536 {
537  QString cleanStr;
538  if ( message ) {
539  cleanStr =
540  NodeHelper::replacePrefixes(
541  message->subject()->asUnicodeString(), prefixRegExps, replace, newPrefix );
542  }
543  return cleanStr;
544 }
545 
546 void NodeHelper::setOverrideCodec( KMime::Content * node, const QTextCodec* codec )
547 {
548  if ( !node )
549  return;
550 
551  mOverrideCodecs[node] = codec;
552 }
553 
554 const QTextCodec * NodeHelper::codec( KMime::Content* node )
555 {
556  if (! node )
557  return mLocalCodec;
558 
559  const QTextCodec *c = mOverrideCodecs.value( node, 0 );
560  if ( !c ) {
561  // no override-codec set for this message, try the CT charset parameter:
562  c = codecForName( node->contentType()->charset() );
563  }
564  if ( !c ) {
565  // Ok, no override and nothing in the message, let's use the fallback
566  // the user configured
567  c = codecForName( MessageCore::GlobalSettings::self()->fallbackCharacterEncoding().toLatin1() );
568  }
569  if ( !c ) {
570  // no charset means us-ascii (RFC 2045), so using local encoding should
571  // be okay
572  c = mLocalCodec;
573  }
574  return c;
575 }
576 
577 const QTextCodec* NodeHelper::codecForName(const QByteArray& _str)
578 {
579  if (_str.isEmpty())
580  return 0;
581  QByteArray codec = _str;
582  kAsciiToLower(codec.data());
583  return KGlobal::charsets()->codecForName(QLatin1String(codec));
584 }
585 
586 QString NodeHelper::fileName( const KMime::Content *node )
587 {
588  QString name = const_cast<KMime::Content*>( node )->contentDisposition()->filename();
589  if ( name.isEmpty() )
590  name = const_cast<KMime::Content*>( node )->contentType()->name();
591 
592  name = name.trimmed();
593  return name;
594 }
595 
596 //FIXME(Andras) review it (by Marc?) to see if I got it right. This is supposed to be the partNode::internalBodyPartMemento replacement
597 Interface::BodyPartMemento *NodeHelper::bodyPartMemento( KMime::Content *node,
598  const QByteArray &which ) const
599 {
600  const QMap< QString, QMap<QByteArray,Interface::BodyPartMemento*> >::const_iterator nit
601  = mBodyPartMementoMap.find( persistentIndex( node ) );
602  if ( nit == mBodyPartMementoMap.end() )
603  return 0;
604  const QMap<QByteArray,Interface::BodyPartMemento*>::const_iterator it =
605  nit->find( which.toLower() );
606  return it != nit->end() ? it.value() : 0 ;
607 }
608 
609  //FIXME(Andras) review it (by Marc?) to see if I got it right. This is supposed to be the partNode::internalSetBodyPartMemento replacement
610 void NodeHelper::setBodyPartMemento( KMime::Content* node, const QByteArray &which,
611  Interface::BodyPartMemento *memento )
612 {
613  QMap<QByteArray,Interface::BodyPartMemento*> & mementos
614  = mBodyPartMementoMap[persistentIndex(node)];
615 
616  const QMap<QByteArray,Interface::BodyPartMemento*>::iterator it =
617  mementos.lowerBound( which.toLower() );
618 
619  if ( it != mementos.end() && it.key() == which.toLower() ) {
620  delete it.value();
621  if ( memento ) {
622  it.value() = memento;
623  } else {
624  mementos.erase( it );
625  }
626  } else {
627  mementos.insert( which.toLower(), memento );
628  }
629 }
630 
631 bool NodeHelper::isNodeDisplayedEmbedded( KMime::Content* node ) const
632 {
633  //kDebug() << "IS NODE: " << mDisplayEmbeddedNodes.contains( node );
634  return mDisplayEmbeddedNodes.contains( node );
635 }
636 
637 void NodeHelper::setNodeDisplayedEmbedded( KMime::Content* node, bool displayedEmbedded )
638 {
639  //kDebug() << "SET NODE: " << node << displayedEmbedded;
640  if ( displayedEmbedded )
641  mDisplayEmbeddedNodes.insert( node );
642  else
643  mDisplayEmbeddedNodes.remove( node );
644 }
645 
646 bool NodeHelper::isNodeDisplayedHidden( KMime::Content* node ) const
647 {
648  return mDisplayHiddenNodes.contains( node );
649 }
650 
651 void NodeHelper::setNodeDisplayedHidden( KMime::Content* node, bool displayedHidden )
652 {
653  if( displayedHidden ) {
654  mDisplayHiddenNodes.insert( node );
655  } else {
656  mDisplayEmbeddedNodes.remove( node );
657  }
658 }
659 
666 QString NodeHelper::persistentIndex( const KMime::Content * node ) const
667 {
668  if ( !node )
669  return QString();
670 
671  QString indexStr = node->index().toString();
672  const KMime::Content * const topLevel = node->topLevel();
673  //if the node is an extra node, prepend the index of the extra node to the url
674  Q_FOREACH( const QList<KMime::Content*> & extraNodes, mExtraContents ) {
675  const int extraNodesSize( extraNodes.size() );
676  for ( int i = 0; i < extraNodesSize; ++i )
677  if ( topLevel == extraNodes[i] )
678  return indexStr.prepend( QString::fromLatin1("%1:").arg(i) );
679  }
680  return indexStr;
681 }
682 
683 QString NodeHelper::asHREF( const KMime::Content* node, const QString &place )
684 {
685  return QString::fromLatin1( "attachment:%1?place=%2" ).arg( persistentIndex( node ), place );
686 }
687 
688 QString NodeHelper::fixEncoding( const QString &encoding )
689 {
690  QString returnEncoding = encoding;
691  // According to http://www.iana.org/assignments/character-sets, uppercase is
692  // preferred in MIME headers
693  if ( returnEncoding.toUpper().contains( QLatin1String("ISO ") ) ) {
694  returnEncoding = returnEncoding.toUpper();
695  returnEncoding.replace( QLatin1String("ISO "), QLatin1String("ISO-") );
696  }
697  return returnEncoding;
698 }
699 
700 
701 //-----------------------------------------------------------------------------
702 QString NodeHelper::encodingForName( const QString &descriptiveName )
703 {
704  QString encoding = KGlobal::charsets()->encodingForName( descriptiveName );
705  return NodeHelper::fixEncoding( encoding );
706 }
707 
708 QStringList NodeHelper::supportedEncodings(bool usAscii)
709 {
710  QStringList encodingNames = KGlobal::charsets()->availableEncodingNames();
711  QStringList encodings;
712  QMap<QString,bool> mimeNames;
713  QStringList::ConstIterator constEnd( encodingNames.constEnd() );
714  for (QStringList::ConstIterator it = encodingNames.constBegin();
715  it != constEnd; ++it)
716  {
717  QTextCodec *codec = KGlobal::charsets()->codecForName(*it);
718  QString mimeName = (codec) ? QString::fromLatin1(codec->name()).toLower() : (*it);
719  if (!mimeNames.contains(mimeName) )
720  {
721  encodings.append( KGlobal::charsets()->descriptionForEncoding(*it) );
722  mimeNames.insert( mimeName, true );
723  }
724  }
725  encodings.sort();
726  if (usAscii)
727  encodings.prepend(KGlobal::charsets()->descriptionForEncoding(QLatin1String("us-ascii")) );
728  return encodings;
729 }
730 
731 
732 QByteArray NodeHelper::autoDetectCharset(const QByteArray &_encoding, const QStringList &encodingList, const QString &text)
733 {
734  QStringList charsets = encodingList;
735  if (!_encoding.isEmpty())
736  {
737  QString currentCharset = QString::fromLatin1(_encoding);
738  charsets.removeAll(currentCharset);
739  charsets.prepend(currentCharset);
740  }
741 
742  QStringList::ConstIterator it = charsets.constBegin();
743  QStringList::ConstIterator end = charsets.constEnd();
744  for (; it != end; ++it)
745  {
746  QByteArray encoding = (*it).toLatin1();
747  if (encoding == "locale")
748  {
749  encoding = QTextCodec::codecForName( KGlobal::locale()->encoding() )->name();
750  kAsciiToLower(encoding.data());
751  }
752  if (text.isEmpty())
753  return encoding;
754  if (encoding == "us-ascii") {
755  bool ok;
756  (void) toUsAscii(text, &ok);
757  if (ok)
758  return encoding;
759  }
760  else
761  {
762  const QTextCodec *codec = codecForName(encoding);
763  if (!codec) {
764  kDebug() << "Auto-Charset: Something is wrong and I cannot get a codec:" << encoding;
765  } else {
766  if (codec->canEncode(text))
767  return encoding;
768  }
769  }
770  }
771  return 0;
772 }
773 
774 QByteArray NodeHelper::toUsAscii(const QString& _str, bool *ok)
775 {
776  bool all_ok =true;
777  QString result = _str;
778  const int len = result.length();
779  for (int i = 0; i < len; ++i)
780  if (result.at(i).unicode() >= 128) {
781  result[i] = '?';
782  all_ok = false;
783  }
784  if (ok)
785  *ok = all_ok;
786  return result.toLatin1();
787 }
788 
789 QString NodeHelper::fromAsString( KMime::Content* node )
790 {
791  KMime::Message* topLevel = dynamic_cast<KMime::Message*>( node->topLevel() );
792  if ( topLevel )
793  return topLevel->from()->asUnicodeString();
794  return QString();
795 }
796 
797 void NodeHelper::attachExtraContent( KMime::Content *topLevelNode, KMime::Content* content )
798 {
799  //kDebug() << "mExtraContents added for" << topLevelNode << " extra content: " << content;
800  mExtraContents[topLevelNode].append( content );
801 }
802 
803 void NodeHelper::removeAllExtraContent( KMime::Content *topLevelNode )
804 {
805  const QMap< KMime::Content*, QList<KMime::Content*> >::iterator it
806  = mExtraContents.find( topLevelNode );
807  if ( it != mExtraContents.end() ) {
808  qDeleteAll( *it );
809  mExtraContents.erase( it );
810  }
811 }
812 
813 QList< KMime::Content* > NodeHelper::extraContents( KMime::Content *topLevelnode ) const
814 {
815  const QMap< KMime::Content*, QList<KMime::Content*> >::const_iterator it
816  = mExtraContents.find( topLevelnode );
817  if ( it == mExtraContents.end() )
818  return QList<KMime::Content*>();
819  else
820  return *it;
821 }
822 
823 bool NodeHelper::isPermanentWithExtraContent( KMime::Content* node ) const
824 {
825  const QMap< KMime::Content*, QList<KMime::Content*> >::const_iterator it
826  = mExtraContents.find( node );
827  return it != mExtraContents.end() && !it->empty();
828 }
829 
830 
831 void NodeHelper::mergeExtraNodes( KMime::Content *node )
832 {
833  if ( !node )
834  return;
835 
836  QList<KMime::Content* > extraNodes = extraContents( node );
837  Q_FOREACH( KMime::Content* extra, extraNodes ) {
838  if( node->bodyIsMessage() ) {
839  kWarning() << "Asked to attach extra content to a kmime::message, this does not make sense. Attaching to:" << node <<
840  node->encodedContent() << "\n====== with =======\n" << extra << extra->encodedContent();
841  continue;
842  }
843  KMime::Content *c = new KMime::Content( node );
844  c->setContent( extra->encodedContent() );
845  c->parse();
846  node->addContent( c );
847  }
848 
849  Q_FOREACH( KMime::Content* child, node->contents() ) {
850  mergeExtraNodes( child );
851  }
852 }
853 
854 void NodeHelper::cleanFromExtraNodes( KMime::Content* node )
855 {
856  if ( !node )
857  return;
858  QList<KMime::Content* > extraNodes = extraContents( node );
859  Q_FOREACH( KMime::Content* extra, extraNodes ) {
860  QByteArray s = extra->encodedContent();
861  QList<KMime::Content* > children = node->contents();
862  Q_FOREACH( KMime::Content *c, children ) {
863  if ( c->encodedContent() == s ) {
864  node->removeContent( c );
865  }
866  }
867  }
868  Q_FOREACH( KMime::Content* child, node->contents() ) {
869  cleanFromExtraNodes( child );
870  }
871 }
872 
873 
874 KMime::Message* NodeHelper::messageWithExtraContent( KMime::Content* topLevelNode )
875 {
876  /*The merge is done in several steps:
877  1) merge the extra nodes into topLevelNode
878  2) copy the modified (merged) node tree into a new node tree
879  3) restore the original node tree in topLevelNode by removing the extra nodes from it
880 
881  The reason is that extra nodes are assigned by pointer value to the nodes in the original tree.
882  */
883  if (!topLevelNode)
884  return 0;
885 
886  mergeExtraNodes( topLevelNode );
887 
888  KMime::Message *m = new KMime::Message;
889  m->setContent( topLevelNode->encodedContent() );
890  m->parse();
891 
892  cleanFromExtraNodes( topLevelNode );
893 // qDebug() << "MESSAGE WITH EXTRA: " << m->encodedContent();
894 // qDebug() << "MESSAGE WITHOUT EXTRA: " << topLevelNode->encodedContent();
895 
896  return m;
897 }
898 
899 NodeHelper::AttachmentDisplayInfo NodeHelper::attachmentDisplayInfo( KMime::Content* node )
900 {
901  AttachmentDisplayInfo info;
902  info.icon = iconName( node, KIconLoader::Small );
903  const QString name = node->contentType()->name();
904  info.label = name.isEmpty() ? fileName( node ) : name;
905  if( info.label.isEmpty() ) {
906  info.label = node->contentDescription()->asUnicodeString();
907  }
908 
909  bool typeBlacklisted = node->contentType()->mediaType().toLower() == "multipart";
910  if ( !typeBlacklisted ) {
911  typeBlacklisted = MessageCore::StringUtil::isCryptoPart( QLatin1String(node->contentType()->mediaType()),
912  QLatin1String(node->contentType()->subType()),
913  node->contentDisposition()->filename() );
914  }
915  typeBlacklisted = typeBlacklisted || node == node->topLevel();
916  const bool firstTextChildOfEncapsulatedMsg =
917  node->contentType()->mediaType().toLower() == "text" &&
918  node->contentType()->subType().toLower() == "plain" &&
919  node->parent() && node->parent()->contentType()->mediaType().toLower() == "message";
920  typeBlacklisted = typeBlacklisted || firstTextChildOfEncapsulatedMsg;
921  info.displayInHeader = !info.label.isEmpty() && !info.icon.isEmpty() && !typeBlacklisted;
922  return info;
923 }
924 
925 KMime::Content * NodeHelper::decryptedNodeForContent( KMime::Content * content ) const
926 {
927  const QList<KMime::Content*> xc = extraContents( content );
928  if ( !xc.empty() ) {
929  if ( xc.size() == 1 ) {
930  return xc.front();
931  } else {
932  kWarning() << "WTF, encrypted node has multiple extra contents?";
933  }
934  }
935  return 0;
936 }
937 
938 bool NodeHelper::unencryptedMessage_helper( KMime::Content *node, QByteArray &resultingData, bool addHeaders,
939  int recursionLevel )
940 {
941  bool returnValue = false;
942  if ( node ) {
943  KMime::Content *curNode = node;
944  KMime::Content *decryptedNode = 0;
945  const QByteArray type = node->contentType( false ) ? QByteArray( node->contentType()->mediaType() ).toLower() : "text";
946  const QByteArray subType = node->contentType( false ) ? node->contentType()->subType().toLower() : "plain";
947  const bool isMultipart = node->contentType( false ) && node->contentType()->isMultipart();
948  bool isSignature = false;
949 
950  //kDebug() << "(" << recursionLevel << ") Looking at" << type << "/" << subType;
951 
952  if ( isMultipart ) {
953  if ( subType == "signed" ) {
954  isSignature = true;
955  } else if ( subType == "encrypted" ) {
956  decryptedNode = decryptedNodeForContent( curNode );
957  }
958  } else if ( type == "application" ) {
959  if ( subType == "octet-stream" ) {
960  decryptedNode = decryptedNodeForContent( curNode );
961  } else if ( subType == "pkcs7-signature" ) {
962  isSignature = true;
963  } else if ( subType == "pkcs7-mime" ) {
964  // note: subtype pkcs7-mime can also be signed
965  // and we do NOT want to remove the signature!
966  if ( encryptionState( curNode ) != KMMsgNotEncrypted ) {
967  decryptedNode = decryptedNodeForContent( curNode );
968  }
969  }
970  }
971 
972  if ( decryptedNode ) {
973  //kDebug() << "Current node has an associated decrypted node, adding a modified header "
974  // "and then processing the children.";
975 
976  Q_ASSERT( addHeaders );
977  KMime::Content headers;
978  headers.setHead( curNode->head() );
979  headers.parse();
980  if ( decryptedNode->contentType( false ) ) {
981  headers.contentType()->from7BitString( decryptedNode->contentType()->as7BitString( false ) );
982  } else {
983  headers.removeHeader( headers.contentType()->type() );
984  }
985  if ( decryptedNode->contentTransferEncoding( false ) ) {
986  headers.contentTransferEncoding()->from7BitString( decryptedNode->contentTransferEncoding()->as7BitString( false ) );
987  } else {
988  headers.removeHeader( headers.contentTransferEncoding()->type() );
989  }
990  if ( decryptedNode->contentDisposition( false ) ) {
991  headers.contentDisposition()->from7BitString( decryptedNode->contentDisposition()->as7BitString( false ) );
992  } else {
993  headers.removeHeader( headers.contentDisposition()->type() );
994  }
995  if ( decryptedNode->contentDescription( false ) ) {
996  headers.contentDescription()->from7BitString( decryptedNode->contentDescription()->as7BitString( false ) );
997  } else {
998  headers.removeHeader( headers.contentDescription()->type() );
999  }
1000  headers.assemble();
1001 
1002  resultingData += headers.head() + '\n';
1003  unencryptedMessage_helper( decryptedNode, resultingData, false, recursionLevel + 1 );
1004 
1005  returnValue = true;
1006  }
1007 
1008  else if ( isSignature ) {
1009  //kDebug() << "Current node is a signature, adding it as-is.";
1010  // We can't change the nodes under the signature, as that would invalidate it. Add the signature
1011  // and its child as-is
1012  if ( addHeaders ) {
1013  resultingData += curNode->head() + '\n';
1014  }
1015  resultingData += curNode->encodedBody();
1016  returnValue = false;
1017  }
1018 
1019  else if ( isMultipart ) {
1020  //kDebug() << "Current node is a multipart node, adding its header and then processing all children.";
1021  // Normal multipart node, add the header and all of its children
1022  bool somethingChanged = false;
1023  if ( addHeaders ) {
1024  resultingData += curNode->head() + '\n';
1025  }
1026  const QByteArray boundary = curNode->contentType()->boundary();
1027  foreach( KMime::Content *child, curNode->contents() ) {
1028  resultingData += "\n--" + boundary + '\n';
1029  const bool changed = unencryptedMessage_helper( child, resultingData, true, recursionLevel + 1 );
1030  if ( changed ) {
1031  somethingChanged = true;
1032  }
1033  }
1034  resultingData += "\n--" + boundary + "--\n\n";
1035  returnValue = somethingChanged;
1036  }
1037 
1038  else if ( curNode->bodyIsMessage() ) {
1039  //kDebug() << "Current node is a message, adding the header and then processing the child.";
1040  if ( addHeaders ) {
1041  resultingData += curNode->head() + '\n';
1042  }
1043 
1044  returnValue = unencryptedMessage_helper( curNode->bodyAsMessage().get(), resultingData, true, recursionLevel + 1 );
1045  }
1046 
1047  else {
1048  //kDebug() << "Current node is an ordinary leaf node, adding it as-is.";
1049  if ( addHeaders ) {
1050  resultingData += curNode->head() + '\n';
1051  }
1052  resultingData += curNode->body();
1053  returnValue = false;
1054  }
1055  }
1056 
1057  //kDebug() << "(" << recursionLevel << ") done.";
1058  return returnValue;
1059 }
1060 
1061 KMime::Message::Ptr NodeHelper::unencryptedMessage( const KMime::Message::Ptr& originalMessage )
1062 {
1063  QByteArray resultingData;
1064  const bool messageChanged = unencryptedMessage_helper( originalMessage.get(), resultingData, true );
1065  if ( messageChanged ) {
1066 #if 0
1067  kDebug() << "Resulting data is:" << resultingData;
1068  QFile bla("stripped.mbox");
1069  bla.open(QIODevice::WriteOnly);
1070  bla.write(resultingData);
1071  bla.close();
1072 #endif
1073  KMime::Message::Ptr newMessage( new KMime::Message );
1074  newMessage->setContent( resultingData );
1075  newMessage->parse();
1076  return newMessage;
1077  } else {
1078  return KMime::Message::Ptr();
1079  }
1080 }
1081 
1082 }
MessageViewer::NodeHelper::unencryptedMessage
KMime::Message::Ptr unencryptedMessage(const KMime::Message::Ptr &originalMessage)
This function returns the unencrypted message that is based on originalMessage.
Definition: nodehelper.cpp:1061
MessageViewer::AttachmentTemporaryFilesDirs::addTempFile
void addTempFile(const QString &file)
Definition: attachmenttemporaryfilesdirs.cpp:69
globalsettings.h
MessageViewer::AttachmentTemporaryFilesDirs::forceCleanTempFiles
void forceCleanTempFiles()
Definition: attachmenttemporaryfilesdirs.cpp:48
MessageViewer::PartMetaData
Definition: partmetadata.h:31
MessageViewer::NodeHelper::attachExtraContent
void attachExtraContent(KMime::Content *topLevelNode, KMime::Content *content)
Attach an extra node to an existing node.
Definition: nodehelper.cpp:797
MessageViewer::Util::fileNameForMimetype
QString MESSAGEVIEWER_EXPORT fileNameForMimetype(const QString &mimeType, int iconSize, const QString &fallbackFileName1=QString(), const QString &fallbackFileName2=QString())
Finds the filename of an icon based on the given mimetype or filenames.
Definition: util.cpp:93
MessageViewer::AttachmentTemporaryFilesDirs::addTempDir
void addTempDir(const QString &dir)
Definition: attachmenttemporaryfilesdirs.cpp:74
iconnamecache.h
MessageViewer::NodeHelper::AttachmentDisplayInfo::icon
QString icon
Definition: nodehelper.h:252
MessageViewer::NodeHelper::overallSignatureState
KMMsgSignatureState overallSignatureState(KMime::Content *node) const
Definition: nodehelper.cpp:422
MessageViewer::AttachmentTemporaryFilesDirs
Definition: attachmenttemporaryfilesdirs.h:29
MessageViewer::NodeHelper::supportedEncodings
static QStringList supportedEncodings(bool usAscii)
Return a list of the supported encodings.
Definition: nodehelper.cpp:708
MessageViewer::NodeHelper::decryptedNodeForContent
KMime::Content * decryptedNodeForContent(KMime::Content *content) const
Definition: nodehelper.cpp:925
MessageViewer::NodeHelper::partMetaData
PartMetaData partMetaData(KMime::Content *node)
Definition: nodehelper.cpp:206
MessageViewer::forwardSubjPrefixes
QStringList forwardSubjPrefixes(QStringList()<< QLatin1String("Fwd:")<< QLatin1String("FW:"))
MessageViewer::NodeHelper::extraContents
QList< KMime::Content * > extraContents(KMime::Content *topLevelNode) const
Get the extra nodes attached to the.
Definition: nodehelper.cpp:813
MessageViewer::KMMsgSignatureState
KMMsgSignatureState
Flags for the signature state.
Definition: nodehelper.h:58
partmetadata.h
MessageViewer::NodeHelper::toUsAscii
static QByteArray toUsAscii(const QString &_str, bool *ok)
Definition: nodehelper.cpp:774
MessageViewer::KMMsgPartiallySigned
Definition: nodehelper.h:62
nodehelper.h
MessageViewer::KMMsgPartiallyEncrypted
Definition: nodehelper.h:52
MessageViewer::NodeHelper::NodeHelper
NodeHelper()
Definition: nodehelper.cpp:58
MessageViewer::KMMsgSignatureStateUnknown
Definition: nodehelper.h:60
MessageViewer::KMMsgNotSigned
Definition: nodehelper.h:61
MessageViewer::KMMsgFullySigned
Definition: nodehelper.h:63
MessageViewer::KMMsgNotEncrypted
Definition: nodehelper.h:51
MessageViewer::NodeHelper::forceCleanTempFiles
void forceCleanTempFiles()
Definition: nodehelper.cpp:300
MessageViewer::NodeHelper::messageWithExtraContent
KMime::Message * messageWithExtraContent(KMime::Content *topLevelNode)
Return a modified message (node tree) starting from.
Definition: nodehelper.cpp:874
MessageViewer::AttachmentTemporaryFilesDirs::temporaryFiles
QStringList temporaryFiles() const
Definition: attachmenttemporaryfilesdirs.cpp:79
bodypart.h
MessageViewer::NodeHelper::addTempFile
void addTempFile(const QString &file)
Add a file to the list of managed temporary files.
Definition: nodehelper.cpp:314
MessageViewer::NodeHelper::setOverrideCodec
void setOverrideCodec(KMime::Content *node, const QTextCodec *codec)
Set the charset the user selected for the message to display.
Definition: nodehelper.cpp:546
MessageViewer::NodeHelper::autoDetectCharset
static QByteArray autoDetectCharset(const QByteArray &_encoding, const QStringList &encodingList, const QString &text)
Definition: nodehelper.cpp:732
MessageViewer::NodeHelper::nodeProcessed
bool nodeProcessed(KMime::Content *node) const
Definition: nodehelper.cpp:140
util.h
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::NodeHelper::AttachmentDisplayInfo
Definition: nodehelper.h:249
MessageViewer::NodeHelper::codecForName
static const QTextCodec * codecForName(const QByteArray &_str)
Return a QTextCodec for the specified charset.
Definition: nodehelper.cpp:577
MessageViewer::NodeHelper::encryptionState
KMMsgEncryptionState encryptionState(KMime::Content *node) const
Definition: nodehelper.cpp:191
MessageViewer::AttachmentTemporaryFilesDirs::removeTempFiles
void removeTempFiles()
Definition: attachmenttemporaryfilesdirs.cpp:43
MessageViewer::NodeHelper::asHREF
QString asHREF(const KMime::Content *node, const QString &place)
Definition: nodehelper.cpp:683
MessageViewer::NodeHelper::setBodyPartMemento
void setBodyPartMemento(KMime::Content *node, const QByteArray &which, Interface::BodyPartMemento *memento)
Definition: nodehelper.cpp:610
MessageViewer::NodeHelper::encodingForName
static QString encodingForName(const QString &descriptiveName)
Drop-in replacement for KCharsets::encodingForName().
Definition: nodehelper.cpp:702
MessageViewer::NodeHelper::isNodeDisplayedHidden
bool isNodeDisplayedHidden(KMime::Content *node) const
Definition: nodehelper.cpp:646
MessageViewer::replySubjPrefixes
QStringList replySubjPrefixes(QStringList()<< QLatin1String("Re\\s*:")<< QLatin1String("Re\\[\\d+\\]:")<< QLatin1String("Re\\d+:"))
MessageViewer::Util::mimetype
MESSAGEVIEWER_EXPORT KMimeType::Ptr mimetype(const QString &name)
Search mimetype from filename when mimetype is empty or application/octet-stream. ...
Definition: util.cpp:568
MessageViewer::KMMsgSignatureProblematic
Definition: nodehelper.h:64
MessageViewer::NodeHelper::setSignatureState
void setSignatureState(KMime::Content *node, const KMMsgSignatureState state)
Definition: nodehelper.cpp:196
MessageViewer::NodeHelper::writeNodeToTempFile
QString writeNodeToTempFile(KMime::Content *node)
Writes the given message part to a temporary file and returns the name of this file or QString() if w...
Definition: nodehelper.cpp:216
MessageViewer::NodeHelper::bodyPartMemento
Interface::BodyPartMemento * bodyPartMemento(KMime::Content *node, const QByteArray &which) const
Definition: nodehelper.cpp:597
MessageViewer::NodeHelper::cleanSubject
static QString cleanSubject(KMime::Message *message)
Return this mails subject, with all "forward" and "reply" prefixes removed.
Definition: nodehelper.cpp:526
MessageViewer::NodeHelper::overallEncryptionState
KMMsgEncryptionState overallEncryptionState(KMime::Content *node) const
Definition: nodehelper.cpp:374
MessageViewer::NodeHelper::charset
static QByteArray charset(KMime::Content *node)
Returns the charset for the given node.
Definition: nodehelper.cpp:366
MessageViewer::Interface::BodyPartMemento
interface of classes that implement status for BodyPartFormatters.
Definition: bodypart.h:55
type
const char * type
Definition: bodypartformatter.cpp:192
MessageViewer::NodeHelper::setPartMetaData
void setPartMetaData(KMime::Content *node, const PartMetaData &metaData)
Definition: nodehelper.cpp:211
MessageViewer::NodeHelper::fromAsString
static QString fromAsString(KMime::Content *node)
Definition: nodehelper.cpp:789
MessageViewer::NodeHelper::isToltecMessage
static bool isToltecMessage(KMime::Content *node)
Definition: nodehelper.cpp:319
MessageViewer::NodeHelper::removeAllExtraContent
void removeAllExtraContent(KMime::Content *topLevelNode)
Definition: nodehelper.cpp:803
attachmenttemporaryfilesdirs.h
MessageViewer::NodeHelper::setNodeDisplayedHidden
void setNodeDisplayedHidden(KMime::Content *node, bool displayedHidden)
Definition: nodehelper.cpp:651
MessageViewer::NodeHelper::setNodeDisplayedEmbedded
void setNodeDisplayedEmbedded(KMime::Content *node, bool displayedEmbedded)
Definition: nodehelper.cpp:637
MessageViewer::clearBodyPartMemento
static void clearBodyPartMemento(QMap< QByteArray, Interface::BodyPartMemento * > &bodyPartMementoMap)
Definition: nodehelper.cpp:147
MessageViewer::KMMsgFullyEncrypted
Definition: nodehelper.h:53
MessageViewer::Interface::BodyPartMemento::detach
virtual void detach()=0
MessageViewer::NodeHelper::~NodeHelper
~NodeHelper()
Definition: nodehelper.cpp:88
MessageViewer::KMMsgEncryptionState
KMMsgEncryptionState
Flags for the encryption state.
Definition: nodehelper.h:48
MessageViewer::NodeHelper::iconName
static QString iconName(KMime::Content *node, int size=KIconLoader::Desktop)
Definition: nodehelper.cpp:469
MessageViewer::NodeHelper::setNodeUnprocessed
void setNodeUnprocessed(KMime::Content *node, bool recurse)
Definition: nodehelper.cpp:111
MessageViewer::KMMsgEncryptionStateUnknown
Definition: nodehelper.h:50
MessageViewer::NodeHelper::setNodeProcessed
void setNodeProcessed(KMime::Content *node, bool recurse)
Definition: nodehelper.cpp:95
MessageViewer::NodeHelper::removeTempFiles
void removeTempFiles()
Cleanup the attachment temp files.
Definition: nodehelper.cpp:307
MessageViewer::NodeHelper::AttachmentDisplayInfo::displayInHeader
bool displayInHeader
Definition: nodehelper.h:253
MessageViewer::NodeHelper::signatureState
KMMsgSignatureState signatureState(KMime::Content *node) const
Definition: nodehelper.cpp:201
MessageViewer::NodeHelper::AttachmentDisplayInfo::label
QString label
Definition: nodehelper.h:251
MessageViewer::NodeHelper::isInEncapsulatedMessage
static bool isInEncapsulatedMessage(KMime::Content *node)
Definition: nodehelper.cpp:350
MessageViewer::NodeHelper::codec
const QTextCodec * codec(KMime::Content *node)
Get a QTextCodec suitable for this message part.
Definition: nodehelper.cpp:554
MessageViewer::NodeHelper::isNodeDisplayedEmbedded
bool isNodeDisplayedEmbedded(KMime::Content *node) const
Definition: nodehelper.cpp:631
MessageViewer::KMMsgEncryptionProblematic
Definition: nodehelper.h:54
MessageViewer::NodeHelper::replacePrefixes
static QString replacePrefixes(const QString &str, const QStringList &prefixRegExps, bool replace, const QString &newPrefix)
Check for prefixes prefixRegExps in str.
Definition: nodehelper.cpp:494
MessageViewer::NodeHelper::attachmentDisplayInfo
static AttachmentDisplayInfo attachmentDisplayInfo(KMime::Content *node)
Definition: nodehelper.cpp:899
MessageViewer::NodeHelper::clear
void clear()
Definition: nodehelper.cpp:160
MessageViewer::NodeHelper::fixEncoding
static QString fixEncoding(const QString &encoding)
Fixes an encoding received by a KDE function and returns the proper, MIME-compilant encoding name ins...
Definition: nodehelper.cpp:688
MessageViewer::NodeHelper::createTempDir
QString createTempDir(const QString &param=QString())
Creates a temporary dir for saving attachments, etc.
Definition: nodehelper.cpp:278
MessageViewer::NodeHelper::isPermanentWithExtraContent
bool isPermanentWithExtraContent(KMime::Content *node) const
Returns true if the given node at least one extra content node, implying that the given node is an en...
Definition: nodehelper.cpp:823
MessageViewer::NodeHelper::setEncryptionState
void setEncryptionState(KMime::Content *node, const KMMsgEncryptionState state)
Definition: nodehelper.cpp:186
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::NodeHelper::magicSetType
void magicSetType(KMime::Content *node, bool autoDecode=true)
Set the 'Content-Type' by mime-magic from the contents of the body.
Definition: nodehelper.cpp:484
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