Sophie

Sophie

distrib > Mandriva > 2008.1 > x86_64 > by-pkgid > 98d6b53e11e983e268c3e19f14e091a0 > files > 2542

kdepim-devel-doc-3.5.9-9mdv2008.1.x86_64.rpm

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en_US" xml:lang="en_US">

<head>
  <title>kmail: objecttreeparser.cpp Source File (kmail)</title>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

  <meta http-equiv="Content-Style-Type" content="text/css" />

  <meta http-equiv="pics-label" content='(pics-1.1 "http://www.icra.org/ratingsv02.html" comment "ICRAonline DE v2.0" l gen true for "http://www.kde.org"  r (nz 1 vz 1 lz 1 oz 1 cb 1) "http://www.rsac.org/ratingsv01.html" l gen true for "http://www.kde.org"  r (n 0 s 0 v 0 l 0))' />

  <meta name="trademark" content="KDE e.V." />
  <meta name="description" content="K Desktop Environment Homepage, KDE.org" />
  <meta name="MSSmartTagsPreventParsing" content="true" />
  <meta name="robots" content="all" />

  <link rel="shortcut icon" href="../../favicon.ico" />

<link rel="stylesheet" media="screen" type="text/css" title="APIDOX" href="doxygen.css" />



<style type="text/css">
<!--
hr { display: none; }
#content h2 { margin-left: 0px; }
table.mdTable { background-color: #f8f8f8; border: .2em solid #d7d7d7; }
td.mdRow { padding: 8px 20px; }
td.md { font-weight: bold; }
td.mdname1 { font-weight: bold; color: #602020; }
td.mdname { font-weight: bold; color: #602020;  }

-->
</style>

</head>

<body>

<div id="nav_header_top" align="right">
  <a href="#content" class="doNotDisplay" accesskey="2">Skip to main content ::</a>

  <a href="../.."><img id="nav_header_logo" alt="Home" align="left" src="../../kde_gear_64.png" border="0" /></a>
  <span class="doNotDisplay">::</span>
  <img id="nav_header_logo_right" alt="" align="right" src="../../pimlogo.png" border="0" />

  <div id="nav_header_title" align="left">KDE PIM API Reference</div>


</div>

<div id="nav_header_bottom" align="right">
  <span class="doNotDisplay">:: <a href="#navigation" accesskey="5">Skip to Link Menu</a><br/></span>
  <div id="nav_header_bottom_left" style="text-align: left;">
/ <a href="../../">API Reference</a>
 / <a href=".">kmail</a>
  </div>
</div>


<table id="main" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
      <td valign="top" class="menuheader" height="0"></td>

  <td id="contentcolumn" valign="top" rowspan="2" >
    <div id="content" style="padding-top: 0px;"><div style="width:100%; margin: 0px; padding: 0px;">
    <h2><a name="content"></a>kmail</h2>


<!-- Generated by Doxygen 1.5.5 -->
<h1>objecttreeparser.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 <span class="comment">/*  -*- mode: C++; c-file-style: "gnu" -*-</span>
<a name="l00002"></a>00002 <span class="comment">    objecttreeparser.cpp</span>
<a name="l00003"></a>00003 <span class="comment"></span>
<a name="l00004"></a>00004 <span class="comment">    This file is part of KMail, the KDE mail client.</span>
<a name="l00005"></a>00005 <span class="comment">    Copyright (c) 2002-2004 Klarälvdalens Datakonsult AB</span>
<a name="l00006"></a>00006 <span class="comment">    Copyright (c) 2003      Marc Mutz &lt;mutz@kde.org&gt;</span>
<a name="l00007"></a>00007 <span class="comment"></span>
<a name="l00008"></a>00008 <span class="comment">    KMail is free software; you can redistribute it and/or modify it</span>
<a name="l00009"></a>00009 <span class="comment">    under the terms of the GNU General Public License, version 2, as</span>
<a name="l00010"></a>00010 <span class="comment">    published by the Free Software Foundation.</span>
<a name="l00011"></a>00011 <span class="comment"></span>
<a name="l00012"></a>00012 <span class="comment">    KMail is distributed in the hope that it will be useful, but</span>
<a name="l00013"></a>00013 <span class="comment">    WITHOUT ANY WARRANTY; without even the implied warranty of</span>
<a name="l00014"></a>00014 <span class="comment">    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU</span>
<a name="l00015"></a>00015 <span class="comment">    General Public License for more details.</span>
<a name="l00016"></a>00016 <span class="comment"></span>
<a name="l00017"></a>00017 <span class="comment">    You should have received a copy of the GNU General Public License</span>
<a name="l00018"></a>00018 <span class="comment">    along with this program; if not, write to the Free Software</span>
<a name="l00019"></a>00019 <span class="comment">    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA</span>
<a name="l00020"></a>00020 <span class="comment"></span>
<a name="l00021"></a>00021 <span class="comment">    In addition, as a special exception, the copyright holders give</span>
<a name="l00022"></a>00022 <span class="comment">    permission to link the code of this program with any edition of</span>
<a name="l00023"></a>00023 <span class="comment">    the Qt library by Trolltech AS, Norway (or with modified versions</span>
<a name="l00024"></a>00024 <span class="comment">    of Qt that use the same license as Qt), and distribute linked</span>
<a name="l00025"></a>00025 <span class="comment">    combinations including the two.  You must obey the GNU General</span>
<a name="l00026"></a>00026 <span class="comment">    Public License in all respects for all of the code used other than</span>
<a name="l00027"></a>00027 <span class="comment">    Qt.  If you modify this file, you may extend this exception to</span>
<a name="l00028"></a>00028 <span class="comment">    your version of the file, but you are not obligated to do so.  If</span>
<a name="l00029"></a>00029 <span class="comment">    you do not wish to do so, delete this exception statement from</span>
<a name="l00030"></a>00030 <span class="comment">    your version.</span>
<a name="l00031"></a>00031 <span class="comment">*/</span>
<a name="l00032"></a>00032 
<a name="l00033"></a>00033 <span class="preprocessor">#include &lt;config.h&gt;</span>
<a name="l00034"></a>00034 
<a name="l00035"></a>00035 <span class="comment">// my header file</span>
<a name="l00036"></a>00036 <span class="preprocessor">#include "objecttreeparser.h"</span>
<a name="l00037"></a>00037 
<a name="l00038"></a>00038 <span class="comment">// other KMail headers</span>
<a name="l00039"></a>00039 <span class="preprocessor">#include "kmkernel.h"</span>
<a name="l00040"></a>00040 <span class="preprocessor">#include "kmreaderwin.h"</span>
<a name="l00041"></a>00041 <span class="preprocessor">#include "partNode.h"</span>
<a name="l00042"></a>00042 <span class="preprocessor">#include &lt;libkdepim/kfileio.h&gt;</span>
<a name="l00043"></a>00043 <span class="preprocessor">#include &lt;libemailfunctions/email.h&gt;</span>
<a name="l00044"></a>00044 <span class="preprocessor">#include "partmetadata.h"</span>
<a name="l00045"></a>00045 <span class="preprocessor">#include "attachmentstrategy.h"</span>
<a name="l00046"></a>00046 <span class="preprocessor">#include "interfaces/htmlwriter.h"</span>
<a name="l00047"></a>00047 <span class="preprocessor">#include "htmlstatusbar.h"</span>
<a name="l00048"></a>00048 <span class="preprocessor">#include "csshelper.h"</span>
<a name="l00049"></a>00049 <span class="preprocessor">#include "bodypartformatter.h"</span>
<a name="l00050"></a>00050 <span class="preprocessor">#include "bodypartformatterfactory.h"</span>
<a name="l00051"></a>00051 <span class="preprocessor">#include "partnodebodypart.h"</span>
<a name="l00052"></a>00052 <span class="preprocessor">#include "interfaces/bodypartformatter.h"</span>
<a name="l00053"></a>00053 <span class="preprocessor">#include "globalsettings.h"</span>
<a name="l00054"></a>00054 <span class="preprocessor">#include "util.h"</span>
<a name="l00055"></a>00055 
<a name="l00056"></a>00056 <span class="comment">// other module headers</span>
<a name="l00057"></a>00057 <span class="preprocessor">#include &lt;mimelib/enum.h&gt;</span>
<a name="l00058"></a>00058 <span class="preprocessor">#include &lt;mimelib/bodypart.h&gt;</span>
<a name="l00059"></a>00059 <span class="preprocessor">#include &lt;mimelib/string.h&gt;</span>
<a name="l00060"></a>00060 <span class="preprocessor">#include &lt;mimelib/text.h&gt;</span>
<a name="l00061"></a>00061 
<a name="l00062"></a>00062 <span class="preprocessor">#include &lt;kleo/specialjob.h&gt;</span>
<a name="l00063"></a>00063 <span class="preprocessor">#include &lt;kleo/cryptobackendfactory.h&gt;</span>
<a name="l00064"></a>00064 <span class="preprocessor">#include &lt;kleo/decryptverifyjob.h&gt;</span>
<a name="l00065"></a>00065 <span class="preprocessor">#include &lt;kleo/verifydetachedjob.h&gt;</span>
<a name="l00066"></a>00066 <span class="preprocessor">#include &lt;kleo/verifyopaquejob.h&gt;</span>
<a name="l00067"></a>00067 <span class="preprocessor">#include &lt;kleo/keylistjob.h&gt;</span>
<a name="l00068"></a>00068 <span class="preprocessor">#include &lt;kleo/importjob.h&gt;</span>
<a name="l00069"></a>00069 <span class="preprocessor">#include &lt;kleo/dn.h&gt;</span>
<a name="l00070"></a>00070 
<a name="l00071"></a>00071 <span class="preprocessor">#include &lt;gpgmepp/importresult.h&gt;</span>
<a name="l00072"></a>00072 <span class="preprocessor">#include &lt;gpgmepp/decryptionresult.h&gt;</span>
<a name="l00073"></a>00073 <span class="preprocessor">#include &lt;gpgmepp/key.h&gt;</span>
<a name="l00074"></a>00074 <span class="preprocessor">#include &lt;gpgmepp/keylistresult.h&gt;</span>
<a name="l00075"></a>00075 <span class="preprocessor">#include &lt;gpgme.h&gt;</span>
<a name="l00076"></a>00076 
<a name="l00077"></a>00077 <span class="preprocessor">#include &lt;kpgpblock.h&gt;</span>
<a name="l00078"></a>00078 <span class="preprocessor">#include &lt;kpgp.h&gt;</span>
<a name="l00079"></a>00079 <span class="preprocessor">#include &lt;linklocator.h&gt;</span>
<a name="l00080"></a>00080 
<a name="l00081"></a>00081 <span class="preprocessor">#include &lt;ktnef/ktnefparser.h&gt;</span>
<a name="l00082"></a>00082 <span class="preprocessor">#include &lt;ktnef/ktnefmessage.h&gt;</span>
<a name="l00083"></a>00083 <span class="preprocessor">#include &lt;ktnef/ktnefattach.h&gt;</span>
<a name="l00084"></a>00084 
<a name="l00085"></a>00085 <span class="comment">// other KDE headers</span>
<a name="l00086"></a>00086 <span class="preprocessor">#include &lt;kdebug.h&gt;</span>
<a name="l00087"></a>00087 <span class="preprocessor">#include &lt;klocale.h&gt;</span>
<a name="l00088"></a>00088 <span class="preprocessor">#include &lt;kmimetype.h&gt;</span>
<a name="l00089"></a>00089 <span class="preprocessor">#include &lt;kglobal.h&gt;</span>
<a name="l00090"></a>00090 <span class="preprocessor">#include &lt;khtml_part.h&gt;</span>
<a name="l00091"></a>00091 <span class="preprocessor">#include &lt;ktempfile.h&gt;</span>
<a name="l00092"></a>00092 <span class="preprocessor">#include &lt;kstandarddirs.h&gt;</span>
<a name="l00093"></a>00093 <span class="preprocessor">#include &lt;kapplication.h&gt;</span>
<a name="l00094"></a>00094 <span class="preprocessor">#include &lt;kmessagebox.h&gt;</span>
<a name="l00095"></a>00095 <span class="preprocessor">#include &lt;kiconloader.h&gt;</span>
<a name="l00096"></a>00096 <span class="preprocessor">#include &lt;kmdcodec.h&gt;</span>
<a name="l00097"></a>00097 
<a name="l00098"></a>00098 <span class="comment">// other Qt headers</span>
<a name="l00099"></a>00099 <span class="preprocessor">#include &lt;qtextcodec.h&gt;</span>
<a name="l00100"></a>00100 <span class="preprocessor">#include &lt;qdir.h&gt;</span>
<a name="l00101"></a>00101 <span class="preprocessor">#include &lt;qfile.h&gt;</span>
<a name="l00102"></a>00102 <span class="preprocessor">#include &lt;qapplication.h&gt;</span>
<a name="l00103"></a>00103 <span class="preprocessor">#include &lt;kstyle.h&gt;</span>
<a name="l00104"></a>00104 <span class="preprocessor">#include &lt;qbuffer.h&gt;</span>
<a name="l00105"></a>00105 <span class="preprocessor">#include &lt;qpixmap.h&gt;</span>
<a name="l00106"></a>00106 <span class="preprocessor">#include &lt;qpainter.h&gt;</span>
<a name="l00107"></a>00107 <span class="preprocessor">#include &lt;qregexp.h&gt;</span>
<a name="l00108"></a>00108 
<a name="l00109"></a>00109 <span class="comment">// other headers</span>
<a name="l00110"></a>00110 <span class="preprocessor">#include &lt;memory&gt;</span>
<a name="l00111"></a>00111 <span class="preprocessor">#include &lt;sys/stat.h&gt;</span>
<a name="l00112"></a>00112 <span class="preprocessor">#include &lt;sys/types.h&gt;</span>
<a name="l00113"></a>00113 <span class="preprocessor">#include &lt;unistd.h&gt;</span>
<a name="l00114"></a>00114 <span class="preprocessor">#include "chiasmuskeyselector.h"</span>
<a name="l00115"></a>00115 
<a name="l00116"></a>00116 <span class="keyword">namespace </span>KMail {
<a name="l00117"></a>00117 
<a name="l00118"></a>00118   <span class="comment">// A small class that eases temporary CryptPlugWrapper changes:</span>
<a name="l00119"></a>00119   <span class="keyword">class </span>ObjectTreeParser::CryptoProtocolSaver {
<a name="l00120"></a>00120     ObjectTreeParser * otp;
<a name="l00121"></a>00121     <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * protocol;
<a name="l00122"></a>00122   <span class="keyword">public</span>:
<a name="l00123"></a>00123     CryptoProtocolSaver( ObjectTreeParser * _otp, <span class="keyword">const</span> Kleo::CryptoBackend::Protocol* _w )
<a name="l00124"></a>00124       : otp( _otp ), protocol( _otp ? _otp-&gt;cryptoProtocol() : 0 )
<a name="l00125"></a>00125     {
<a name="l00126"></a>00126       <span class="keywordflow">if</span> ( otp )
<a name="l00127"></a>00127         otp-&gt;setCryptoProtocol( _w );
<a name="l00128"></a>00128     }
<a name="l00129"></a>00129 
<a name="l00130"></a>00130     ~CryptoProtocolSaver() {
<a name="l00131"></a>00131       <span class="keywordflow">if</span> ( otp )
<a name="l00132"></a>00132         otp-&gt;setCryptoProtocol( protocol );
<a name="l00133"></a>00133     }
<a name="l00134"></a>00134   };
<a name="l00135"></a>00135 
<a name="l00136"></a>00136 
<a name="l00137"></a>00137   ObjectTreeParser::ObjectTreeParser( <a class="code" href="classKMReaderWin.html" title="This class implements a &amp;quot;reader window&amp;quot;, that is a window used for reading...">KMReaderWin</a> * reader, <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * protocol,
<a name="l00138"></a>00138                                       <span class="keywordtype">bool</span> showOnlyOneMimePart, <span class="keywordtype">bool</span> keepEncryptions,
<a name="l00139"></a>00139                                       <span class="keywordtype">bool</span> includeSignatures,
<a name="l00140"></a>00140                                       <span class="keyword">const</span> AttachmentStrategy * strategy,
<a name="l00141"></a>00141                                       HtmlWriter * htmlWriter,
<a name="l00142"></a>00142                                       CSSHelper * cssHelper )
<a name="l00143"></a>00143     : mReader( reader ),
<a name="l00144"></a>00144       mCryptoProtocol( protocol ),
<a name="l00145"></a>00145       mShowOnlyOneMimePart( showOnlyOneMimePart ),
<a name="l00146"></a>00146       mKeepEncryptions( keepEncryptions ),
<a name="l00147"></a>00147       mIncludeSignatures( includeSignatures ),
<a name="l00148"></a>00148       mAttachmentStrategy( strategy ),
<a name="l00149"></a>00149       mHtmlWriter( htmlWriter ),
<a name="l00150"></a>00150       mCSSHelper( cssHelper )
<a name="l00151"></a>00151   {
<a name="l00152"></a>00152     <span class="keywordflow">if</span> ( !attachmentStrategy() )
<a name="l00153"></a>00153       mAttachmentStrategy = reader ? reader-&gt;<a class="code" href="classKMReaderWin.html#33e18657eda211a3c2b3bdcaa0166e87" title="Get/set the message attachment strategy.">attachmentStrategy</a>()
<a name="l00154"></a>00154                                    : AttachmentStrategy::smart();
<a name="l00155"></a>00155     <span class="keywordflow">if</span> ( reader &amp;&amp; !this-&gt;htmlWriter() )
<a name="l00156"></a>00156       mHtmlWriter = reader-&gt;<a class="code" href="classKMReaderWin.html#1335cf9f605128a1031468e1077d8fcb" title="Return the HtmlWriter connected to the KHTMLPart we use.">htmlWriter</a>();
<a name="l00157"></a>00157     <span class="keywordflow">if</span> ( reader &amp;&amp; !this-&gt;cssHelper() )
<a name="l00158"></a>00158       mCSSHelper = reader-&gt;<a class="code" href="classKMReaderWin.html#e907a6d47c77f02c080354e7bbe54434">mCSSHelper</a>;
<a name="l00159"></a>00159   }
<a name="l00160"></a>00160 
<a name="l00161"></a>00161   ObjectTreeParser::ObjectTreeParser( <span class="keyword">const</span> ObjectTreeParser &amp; other )
<a name="l00162"></a>00162     : mReader( other.mReader ),
<a name="l00163"></a>00163       mCryptoProtocol( other.cryptoProtocol() ),
<a name="l00164"></a>00164       mShowOnlyOneMimePart( other.showOnlyOneMimePart() ),
<a name="l00165"></a>00165       mKeepEncryptions( other.keepEncryptions() ),
<a name="l00166"></a>00166       mIncludeSignatures( other.includeSignatures() ),
<a name="l00167"></a>00167       mAttachmentStrategy( other.attachmentStrategy() ),
<a name="l00168"></a>00168       mHtmlWriter( other.htmlWriter() ),
<a name="l00169"></a>00169       mCSSHelper( other.cssHelper() )
<a name="l00170"></a>00170   {
<a name="l00171"></a>00171 
<a name="l00172"></a>00172   }
<a name="l00173"></a>00173 
<a name="l00174"></a>00174   ObjectTreeParser::~ObjectTreeParser() {}
<a name="l00175"></a>00175 
<a name="l00176"></a>00176   <span class="keywordtype">void</span> ObjectTreeParser::insertAndParseNewChildNode( partNode&amp; startNode,
<a name="l00177"></a>00177                                                      <span class="keyword">const</span> <span class="keywordtype">char</span>* content,
<a name="l00178"></a>00178                                                      <span class="keyword">const</span> <span class="keywordtype">char</span>* cntDesc,
<a name="l00179"></a>00179                                                      <span class="keywordtype">bool</span> append )
<a name="l00180"></a>00180   {
<a name="l00181"></a>00181     DwBodyPart* myBody = <span class="keyword">new</span> DwBodyPart( DwString( content ), 0 );
<a name="l00182"></a>00182     myBody-&gt;Parse();
<a name="l00183"></a>00183 
<a name="l00184"></a>00184     <span class="keywordflow">if</span> ( ( !myBody-&gt;Body().FirstBodyPart() ||
<a name="l00185"></a>00185            myBody-&gt;Body().AsString().length() == 0 ) &amp;&amp;
<a name="l00186"></a>00186          startNode.dwPart() &amp;&amp;
<a name="l00187"></a>00187          startNode.dwPart()-&gt;Body().Message() &amp;&amp;
<a name="l00188"></a>00188          startNode.dwPart()-&gt;Body().Message()-&gt;Body().FirstBodyPart() )
<a name="l00189"></a>00189     {
<a name="l00190"></a>00190       <span class="comment">// if encapsulated imap messages are loaded the content-string is not complete</span>
<a name="l00191"></a>00191       <span class="comment">// so we need to keep the child dwparts</span>
<a name="l00192"></a>00192       myBody = <span class="keyword">new</span> DwBodyPart( *(startNode.dwPart()-&gt;Body().Message()) );
<a name="l00193"></a>00193     }
<a name="l00194"></a>00194 
<a name="l00195"></a>00195     <span class="keywordflow">if</span> ( myBody-&gt;hasHeaders() ) {
<a name="l00196"></a>00196       DwText&amp; desc = myBody-&gt;Headers().ContentDescription();
<a name="l00197"></a>00197       desc.FromString( cntDesc );
<a name="l00198"></a>00198       desc.SetModified();
<a name="l00199"></a>00199       myBody-&gt;Headers().Parse();
<a name="l00200"></a>00200     }
<a name="l00201"></a>00201 
<a name="l00202"></a>00202     partNode* parentNode = &amp;startNode;
<a name="l00203"></a>00203     partNode* newNode = <span class="keyword">new</span> partNode(<span class="keyword">false</span>, myBody);
<a name="l00204"></a>00204     <span class="keywordflow">if</span> ( append &amp;&amp; parentNode-&gt;firstChild() ) {
<a name="l00205"></a>00205       parentNode = parentNode-&gt;firstChild();
<a name="l00206"></a>00206       <span class="keywordflow">while</span>( parentNode-&gt;nextSibling() )
<a name="l00207"></a>00207         parentNode = parentNode-&gt;nextSibling();
<a name="l00208"></a>00208       parentNode-&gt;setNext( newNode );
<a name="l00209"></a>00209     } <span class="keywordflow">else</span>
<a name="l00210"></a>00210       parentNode-&gt;setFirstChild( newNode );
<a name="l00211"></a>00211 
<a name="l00212"></a>00212     newNode-&gt;buildObjectTree( <span class="keyword">false</span> );
<a name="l00213"></a>00213 
<a name="l00214"></a>00214     <span class="keywordflow">if</span> ( startNode.mimePartTreeItem() ) {
<a name="l00215"></a>00215       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n     -----&gt;  Inserting items into MimePartTree\n"</span> &lt;&lt; endl;
<a name="l00216"></a>00216       newNode-&gt;fillMimePartTree( startNode.mimePartTreeItem(), 0,
<a name="l00217"></a>00217                                  QString::null, QString::null, QString::null, 0,
<a name="l00218"></a>00218                                  append );
<a name="l00219"></a>00219       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n     &lt;-----  Finished inserting items into MimePartTree\n"</span> &lt;&lt; endl;
<a name="l00220"></a>00220     } <span class="keywordflow">else</span> {
<a name="l00221"></a>00221       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n     ------  Sorry, node.mimePartTreeItem() returns ZERO so"</span>
<a name="l00222"></a>00222                     &lt;&lt; <span class="stringliteral">"\n                    we cannot insert new lines into MimePartTree. :-(\n"</span> &lt;&lt; endl;
<a name="l00223"></a>00223     }
<a name="l00224"></a>00224     kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n     -----&gt;  Now parsing the MimePartTree\n"</span> &lt;&lt; endl;
<a name="l00225"></a>00225     ObjectTreeParser otp( mReader, cryptoProtocol() );
<a name="l00226"></a>00226     otp.parseObjectTree( newNode );
<a name="l00227"></a>00227     mRawReplyString += otp.rawReplyString();
<a name="l00228"></a>00228     mTextualContent += otp.textualContent();
<a name="l00229"></a>00229     <span class="keywordflow">if</span> ( !otp.textualContentCharset().isEmpty() )
<a name="l00230"></a>00230       mTextualContentCharset = otp.textualContentCharset();
<a name="l00231"></a>00231     kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n     &lt;-----  Finished parsing the MimePartTree in insertAndParseNewChildNode()\n"</span> &lt;&lt; endl;
<a name="l00232"></a>00232   }
<a name="l00233"></a>00233 
<a name="l00234"></a>00234 
<a name="l00235"></a>00235 <span class="comment">//-----------------------------------------------------------------------------</span>
<a name="l00236"></a>00236 
<a name="l00237"></a>00237   <span class="keywordtype">void</span> ObjectTreeParser::parseObjectTree( partNode * node ) {
<a name="l00238"></a>00238     kdDebug(5006) &lt;&lt; <span class="stringliteral">"ObjectTreeParser::parseObjectTree( "</span>
<a name="l00239"></a>00239                   &lt;&lt; (node ? <span class="stringliteral">"node OK, "</span> : <span class="stringliteral">"no node, "</span>)
<a name="l00240"></a>00240                   &lt;&lt; <span class="stringliteral">"showOnlyOneMimePart: "</span> &lt;&lt; (showOnlyOneMimePart() ? <span class="stringliteral">"TRUE"</span> : <span class="stringliteral">"FALSE"</span>)
<a name="l00241"></a>00241                   &lt;&lt; <span class="stringliteral">" )"</span> &lt;&lt; endl;
<a name="l00242"></a>00242 
<a name="l00243"></a>00243     <span class="keywordflow">if</span> ( !node )
<a name="l00244"></a>00244       <span class="keywordflow">return</span>;
<a name="l00245"></a>00245 
<a name="l00246"></a>00246     <span class="comment">// reset "processed" flags for...</span>
<a name="l00247"></a>00247     <span class="keywordflow">if</span> ( showOnlyOneMimePart() ) {
<a name="l00248"></a>00248       <span class="comment">// ... this node and all descendants</span>
<a name="l00249"></a>00249       node-&gt;setProcessed( <span class="keyword">false</span>, <span class="keyword">false</span> );
<a name="l00250"></a>00250       <span class="keywordflow">if</span> ( partNode * child = node-&gt;firstChild() )
<a name="l00251"></a>00251         child-&gt;setProcessed( <span class="keyword">false</span>, <span class="keyword">true</span> );
<a name="l00252"></a>00252     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( mReader &amp;&amp; !node-&gt;parentNode() ) {
<a name="l00253"></a>00253       <span class="comment">// ...this node and all it's siblings and descendants</span>
<a name="l00254"></a>00254       node-&gt;setProcessed( <span class="keyword">false</span>, <span class="keyword">true</span> );
<a name="l00255"></a>00255     }
<a name="l00256"></a>00256 
<a name="l00257"></a>00257     <span class="keywordflow">for</span> ( ; node ; node = node-&gt;nextSibling() ) {
<a name="l00258"></a>00258       <span class="keywordflow">if</span> ( node-&gt;processed() )
<a name="l00259"></a>00259         <span class="keywordflow">continue</span>;
<a name="l00260"></a>00260 
<a name="l00261"></a>00261       ProcessResult processResult;
<a name="l00262"></a>00262 
<a name="l00263"></a>00263       <span class="keywordflow">if</span> ( mReader )
<a name="l00264"></a>00264         htmlWriter()-&gt;queue( QString::fromLatin1(<span class="stringliteral">"&lt;a name=\"att%1\"/&gt;"</span>).arg( node-&gt;nodeId() ) );
<a name="l00265"></a>00265       <span class="keywordflow">if</span> ( <span class="keyword">const</span> Interface::BodyPartFormatter * formatter
<a name="l00266"></a>00266            = BodyPartFormatterFactory::instance()-&gt;createFor( node-&gt;typeString(), node-&gt;subTypeString() ) ) {
<a name="l00267"></a>00267         PartNodeBodyPart part( *node, codecFor( node ) );
<a name="l00268"></a>00268         <span class="comment">// Set the default display strategy for this body part relying on the</span>
<a name="l00269"></a>00269         <span class="comment">// identity of KMail::Interface::BodyPart::Display and AttachmentStrategy::Display</span>
<a name="l00270"></a>00270         part.setDefaultDisplay( (KMail::Interface::BodyPart::Display) attachmentStrategy()-&gt;defaultDisplay( node ) );
<a name="l00271"></a>00271         <span class="keyword">const</span> Interface::BodyPartFormatter::Result result = formatter-&gt;format( &amp;part, htmlWriter() );
<a name="l00272"></a>00272         <span class="keywordflow">if</span> ( mReader &amp;&amp; node-&gt;bodyPartMemento() )
<a name="l00273"></a>00273           <span class="keywordflow">if</span> ( Interface::Observable * obs = node-&gt;bodyPartMemento()-&gt;asObservable() )
<a name="l00274"></a>00274             obs-&gt;attach( mReader );
<a name="l00275"></a>00275         <span class="keywordflow">switch</span> ( result ) {
<a name="l00276"></a>00276         <span class="keywordflow">case</span> Interface::BodyPartFormatter::AsIcon:
<a name="l00277"></a>00277           processResult.setNeverDisplayInline( <span class="keyword">true</span> );
<a name="l00278"></a>00278           <span class="comment">// fall through:</span>
<a name="l00279"></a>00279         <span class="keywordflow">case</span> Interface::BodyPartFormatter::Failed:
<a name="l00280"></a>00280           defaultHandling( node, processResult );
<a name="l00281"></a>00281           <span class="keywordflow">break</span>;
<a name="l00282"></a>00282         <span class="keywordflow">case</span> Interface::BodyPartFormatter::Ok:
<a name="l00283"></a>00283         <span class="keywordflow">case</span> Interface::BodyPartFormatter::NeedContent:
<a name="l00284"></a>00284           <span class="comment">// FIXME: incomplete content handling</span>
<a name="l00285"></a>00285           ;
<a name="l00286"></a>00286         }
<a name="l00287"></a>00287       } <span class="keywordflow">else</span> {
<a name="l00288"></a>00288         <span class="keyword">const</span> BodyPartFormatter * bpf
<a name="l00289"></a>00289           = BodyPartFormatter::createFor( node-&gt;type(), node-&gt;subType() );
<a name="l00290"></a>00290         kdFatal( !bpf, 5006 ) &lt;&lt; <span class="stringliteral">"THIS SHOULD NO LONGER HAPPEN ("</span>
<a name="l00291"></a>00291                               &lt;&lt; node-&gt;typeString() &lt;&lt; <span class="charliteral">'/'</span> &lt;&lt; node-&gt;subTypeString()
<a name="l00292"></a>00292                               &lt;&lt; <span class="charliteral">')'</span> &lt;&lt; endl;
<a name="l00293"></a>00293 
<a name="l00294"></a>00294         <span class="keywordflow">if</span> ( bpf &amp;&amp; !bpf-&gt;process( <span class="keyword">this</span>, node, processResult ) )
<a name="l00295"></a>00295           defaultHandling( node, processResult );
<a name="l00296"></a>00296       }
<a name="l00297"></a>00297       node-&gt;setProcessed( <span class="keyword">true</span>, <span class="keyword">false</span> );
<a name="l00298"></a>00298 
<a name="l00299"></a>00299       <span class="comment">// adjust signed/encrypted flags if inline PGP was found</span>
<a name="l00300"></a>00300       processResult.adjustCryptoStatesOfNode( node );
<a name="l00301"></a>00301 
<a name="l00302"></a>00302       <span class="keywordflow">if</span> ( showOnlyOneMimePart() )
<a name="l00303"></a>00303         <span class="keywordflow">break</span>;
<a name="l00304"></a>00304     }
<a name="l00305"></a>00305   }
<a name="l00306"></a>00306 
<a name="l00307"></a>00307   <span class="keywordtype">void</span> ObjectTreeParser::defaultHandling( partNode * node, ProcessResult &amp; result ) {
<a name="l00308"></a>00308     <span class="comment">// ### (mmutz) default handling should go into the respective</span>
<a name="l00309"></a>00309     <span class="comment">// ### bodypartformatters.</span>
<a name="l00310"></a>00310     <span class="keywordflow">if</span> ( !mReader )
<a name="l00311"></a>00311       <span class="keywordflow">return</span>;
<a name="l00312"></a>00312     <span class="keywordflow">if</span> ( attachmentStrategy() == AttachmentStrategy::hidden() &amp;&amp;
<a name="l00313"></a>00313          !showOnlyOneMimePart() &amp;&amp;
<a name="l00314"></a>00314          node-&gt;parentNode() <span class="comment">/* message is not an attachment */</span> )
<a name="l00315"></a>00315       <span class="keywordflow">return</span>;
<a name="l00316"></a>00316 
<a name="l00317"></a>00317     <span class="keywordtype">bool</span> asIcon = <span class="keyword">true</span>;
<a name="l00318"></a>00318     <span class="keywordflow">if</span> ( showOnlyOneMimePart() )
<a name="l00319"></a>00319       <span class="comment">// ### (mmutz) this is wrong! If I click on an image part, I</span>
<a name="l00320"></a>00320       <span class="comment">// want the equivalent of "view...", except for the extra</span>
<a name="l00321"></a>00321       <span class="comment">// window!</span>
<a name="l00322"></a>00322       asIcon = !node-&gt;hasContentDispositionInline();
<a name="l00323"></a>00323     <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( !result.neverDisplayInline() )
<a name="l00324"></a>00324       <span class="keywordflow">if</span> ( <span class="keyword">const</span> AttachmentStrategy * as = attachmentStrategy() )
<a name="l00325"></a>00325         asIcon = as-&gt;defaultDisplay( node ) == AttachmentStrategy::AsIcon;
<a name="l00326"></a>00326     <span class="comment">// neither image nor text -&gt; show as icon</span>
<a name="l00327"></a>00327     <span class="keywordflow">if</span> ( !result.isImage()
<a name="l00328"></a>00328          &amp;&amp; node-&gt;type() != DwMime::kTypeText )
<a name="l00329"></a>00329       asIcon = <span class="keyword">true</span>;
<a name="l00330"></a>00330     <span class="comment">// if the image is not complete do not try to show it inline</span>
<a name="l00331"></a>00331     <span class="keywordflow">if</span> ( result.isImage() &amp;&amp; !node-&gt;msgPart().isComplete() )
<a name="l00332"></a>00332       asIcon = <span class="keyword">true</span>;
<a name="l00333"></a>00333     <span class="keywordflow">if</span> ( asIcon ) {
<a name="l00334"></a>00334       <span class="keywordflow">if</span> ( attachmentStrategy() != AttachmentStrategy::hidden()
<a name="l00335"></a>00335            || showOnlyOneMimePart() )
<a name="l00336"></a>00336         writePartIcon( &amp;node-&gt;msgPart(), node-&gt;nodeId() );
<a name="l00337"></a>00337     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( result.isImage() )
<a name="l00338"></a>00338       writePartIcon( &amp;node-&gt;msgPart(), node-&gt;nodeId(), true );
<a name="l00339"></a>00339     <span class="keywordflow">else</span>
<a name="l00340"></a>00340       writeBodyString( node-&gt;msgPart().bodyDecoded(),
<a name="l00341"></a>00341                        node-&gt;trueFromAddress(),
<a name="l00342"></a>00342                        codecFor( node ), result, false );
<a name="l00343"></a>00343     <span class="comment">// end of ###</span>
<a name="l00344"></a>00344   }
<a name="l00345"></a>00345 
<a name="l00346"></a>00346   <span class="keywordtype">void</span> ProcessResult::adjustCryptoStatesOfNode( partNode * node )<span class="keyword"> const </span>{
<a name="l00347"></a>00347     <span class="keywordflow">if</span> ( ( inlineSignatureState()  != KMMsgNotSigned ) ||
<a name="l00348"></a>00348          ( inlineEncryptionState() != KMMsgNotEncrypted ) ) {
<a name="l00349"></a>00349       node-&gt;setSignatureState( inlineSignatureState() );
<a name="l00350"></a>00350       node-&gt;setEncryptionState( inlineEncryptionState() );
<a name="l00351"></a>00351     }
<a name="l00352"></a>00352   }
<a name="l00353"></a>00353 
<a name="l00357"></a>00357 
<a name="l00358"></a>00358   <span class="keyword">static</span> <span class="keywordtype">int</span> signatureToStatus( <span class="keyword">const</span> GpgME::Signature &amp;sig )
<a name="l00359"></a>00359   {
<a name="l00360"></a>00360     <span class="keywordflow">switch</span> ( sig.status().code() ) {
<a name="l00361"></a>00361       <span class="keywordflow">case</span> GPG_ERR_NO_ERROR:
<a name="l00362"></a>00362         <span class="keywordflow">return</span> GPGME_SIG_STAT_GOOD;
<a name="l00363"></a>00363       <span class="keywordflow">case</span> GPG_ERR_BAD_SIGNATURE:
<a name="l00364"></a>00364         <span class="keywordflow">return</span> GPGME_SIG_STAT_BAD;
<a name="l00365"></a>00365       <span class="keywordflow">case</span> GPG_ERR_NO_PUBKEY:
<a name="l00366"></a>00366         <span class="keywordflow">return</span> GPGME_SIG_STAT_NOKEY;
<a name="l00367"></a>00367       <span class="keywordflow">case</span> GPG_ERR_NO_DATA:
<a name="l00368"></a>00368         <span class="keywordflow">return</span> GPGME_SIG_STAT_NOSIG;
<a name="l00369"></a>00369       <span class="keywordflow">case</span> GPG_ERR_SIG_EXPIRED:
<a name="l00370"></a>00370         <span class="keywordflow">return</span> GPGME_SIG_STAT_GOOD_EXP;
<a name="l00371"></a>00371       <span class="keywordflow">case</span> GPG_ERR_KEY_EXPIRED:
<a name="l00372"></a>00372         <span class="keywordflow">return</span> GPGME_SIG_STAT_GOOD_EXPKEY;
<a name="l00373"></a>00373       <span class="keywordflow">default</span>:
<a name="l00374"></a>00374         <span class="keywordflow">return</span> GPGME_SIG_STAT_ERROR;
<a name="l00375"></a>00375     }
<a name="l00376"></a>00376   }
<a name="l00377"></a>00377 
<a name="l00378"></a>00378   <span class="keywordtype">bool</span> ObjectTreeParser::writeOpaqueOrMultipartSignedData( partNode* data,
<a name="l00379"></a>00379                                                       partNode&amp; sign,
<a name="l00380"></a>00380                                                       <span class="keyword">const</span> QString&amp; fromAddress,
<a name="l00381"></a>00381                                                       <span class="keywordtype">bool</span> doCheck,
<a name="l00382"></a>00382                                                       QCString* cleartextData,
<a name="l00383"></a>00383                                                       std::vector&lt;GpgME::Signature&gt; paramSignatures,
<a name="l00384"></a>00384                                                       <span class="keywordtype">bool</span> hideErrors )
<a name="l00385"></a>00385   {
<a name="l00386"></a>00386     <span class="keywordtype">bool</span> bIsOpaqueSigned = <span class="keyword">false</span>;
<a name="l00387"></a>00387     <span class="keyword">enum</span> { NO_PLUGIN, NOT_INITIALIZED, CANT_VERIFY_SIGNATURES }
<a name="l00388"></a>00388       cryptPlugError = NO_PLUGIN;
<a name="l00389"></a>00389 
<a name="l00390"></a>00390     <span class="keyword">const</span> Kleo::CryptoBackend::Protocol* cryptProto = cryptoProtocol();
<a name="l00391"></a>00391 
<a name="l00392"></a>00392     QString cryptPlugLibName;
<a name="l00393"></a>00393     QString cryptPlugDisplayName;
<a name="l00394"></a>00394     <span class="keywordflow">if</span> ( cryptProto ) {
<a name="l00395"></a>00395       cryptPlugLibName = cryptProto-&gt;name();
<a name="l00396"></a>00396       cryptPlugDisplayName = cryptProto-&gt;displayName();
<a name="l00397"></a>00397     }
<a name="l00398"></a>00398 
<a name="l00399"></a>00399 <span class="preprocessor">#ifndef NDEBUG</span>
<a name="l00400"></a>00400 <span class="preprocessor"></span>    <span class="keywordflow">if</span> ( !doCheck )
<a name="l00401"></a>00401       kdDebug(5006) &lt;&lt; <span class="stringliteral">"ObjectTreeParser::writeOpaqueOrMultipartSignedData: showing OpenPGP (Encrypted+Signed) data"</span> &lt;&lt; endl;
<a name="l00402"></a>00402     <span class="keywordflow">else</span>
<a name="l00403"></a>00403       <span class="keywordflow">if</span> ( data )
<a name="l00404"></a>00404         kdDebug(5006) &lt;&lt; <span class="stringliteral">"ObjectTreeParser::writeOpaqueOrMultipartSignedData: processing Multipart Signed data"</span> &lt;&lt; endl;
<a name="l00405"></a>00405       <span class="keywordflow">else</span>
<a name="l00406"></a>00406         kdDebug(5006) &lt;&lt; <span class="stringliteral">"ObjectTreeParser::writeOpaqueOrMultipartSignedData: processing Opaque Signed data"</span> &lt;&lt; endl;
<a name="l00407"></a>00407 <span class="preprocessor">#endif</span>
<a name="l00408"></a>00408 <span class="preprocessor"></span>
<a name="l00409"></a>00409     <span class="keywordflow">if</span> ( doCheck &amp;&amp; cryptProto ) {
<a name="l00410"></a>00410       kdDebug(5006) &lt;&lt; <span class="stringliteral">"ObjectTreeParser::writeOpaqueOrMultipartSignedData: going to call CRYPTPLUG "</span>
<a name="l00411"></a>00411                     &lt;&lt; cryptPlugLibName &lt;&lt; endl;
<a name="l00412"></a>00412     }
<a name="l00413"></a>00413 
<a name="l00414"></a>00414     QCString cleartext;
<a name="l00415"></a>00415     QByteArray signaturetext;
<a name="l00416"></a>00416 
<a name="l00417"></a>00417     <span class="keywordflow">if</span> ( doCheck &amp;&amp; cryptProto ) {
<a name="l00418"></a>00418       <span class="keywordflow">if</span> ( data ) {
<a name="l00419"></a>00419         cleartext = <a class="code" href="namespaceKMail_1_1Util.html#7dbcbfd02aa6cf732ac83c2b6d5b6f8b" title="Construct a QCString from a DwString.">KMail::Util::CString</a>( data-&gt;dwPart()-&gt;AsString() );
<a name="l00420"></a>00420 
<a name="l00421"></a>00421         dumpToFile( <span class="stringliteral">"dat_01_reader_signedtext_before_canonicalization"</span>,
<a name="l00422"></a>00422                     cleartext.data(), cleartext.length() );
<a name="l00423"></a>00423 
<a name="l00424"></a>00424         <span class="comment">// replace simple LFs by CRLSs</span>
<a name="l00425"></a>00425         <span class="comment">// according to RfC 2633, 3.1.1 Canonicalization</span>
<a name="l00426"></a>00426         kdDebug(5006) &lt;&lt; <span class="stringliteral">"Converting LF to CRLF (see RfC 2633, 3.1.1 Canonicalization)"</span> &lt;&lt; endl;
<a name="l00427"></a>00427         cleartext = <a class="code" href="namespaceKMail_1_1Util.html#25431640360875062e0968d223ea6bf8" title="Convert &amp;quot;\n&amp;quot; line endings to &amp;quot;\r\n&amp;quot;.">Util::lf2crlf</a>( cleartext );
<a name="l00428"></a>00428         kdDebug(5006) &lt;&lt; <span class="stringliteral">"                                                       done."</span> &lt;&lt; endl;
<a name="l00429"></a>00429       }
<a name="l00430"></a>00430 
<a name="l00431"></a>00431       dumpToFile( <span class="stringliteral">"dat_02_reader_signedtext_after_canonicalization"</span>,
<a name="l00432"></a>00432                   cleartext.data(), cleartext.length() );
<a name="l00433"></a>00433 
<a name="l00434"></a>00434       signaturetext = sign.msgPart().bodyDecodedBinary();
<a name="l00435"></a>00435       dumpToFile( <span class="stringliteral">"dat_03_reader.sig"</span>, signaturetext.data(),
<a name="l00436"></a>00436                   signaturetext.size() );
<a name="l00437"></a>00437     }
<a name="l00438"></a>00438 
<a name="l00439"></a>00439     std::vector&lt;GpgME::Signature&gt; signatures;
<a name="l00440"></a>00440     <span class="keywordflow">if</span> ( doCheck )
<a name="l00441"></a>00441       signatures = paramSignatures;
<a name="l00442"></a>00442 
<a name="l00443"></a>00443     PartMetaData messagePart;
<a name="l00444"></a>00444     messagePart.isSigned = <span class="keyword">true</span>;
<a name="l00445"></a>00445     messagePart.technicalProblem = ( cryptProto == 0 );
<a name="l00446"></a>00446     messagePart.isGoodSignature = <span class="keyword">false</span>;
<a name="l00447"></a>00447     messagePart.isEncrypted = <span class="keyword">false</span>;
<a name="l00448"></a>00448     messagePart.isDecryptable = <span class="keyword">false</span>;
<a name="l00449"></a>00449     messagePart.keyTrust = Kpgp::KPGP_VALIDITY_UNKNOWN;
<a name="l00450"></a>00450     messagePart.status = i18n(<span class="stringliteral">"Wrong Crypto Plug-In."</span>);
<a name="l00451"></a>00451     messagePart.status_code = GPGME_SIG_STAT_NONE;
<a name="l00452"></a>00452 
<a name="l00453"></a>00453     <span class="keywordflow">if</span> ( doCheck &amp;&amp; cryptProto ) {
<a name="l00454"></a>00454       GpgME::VerificationResult result;
<a name="l00455"></a>00455       <span class="keywordflow">if</span> ( data ) { <span class="comment">// detached</span>
<a name="l00456"></a>00456         <span class="keywordflow">if</span> ( Kleo::VerifyDetachedJob * <span class="keyword">const</span> job = cryptProto-&gt;verifyDetachedJob() ) {
<a name="l00457"></a>00457           QByteArray plainData = cleartext;
<a name="l00458"></a>00458           plainData.resize( cleartext.size() - 1 );
<a name="l00459"></a>00459           result = job-&gt;exec( signaturetext, plainData );
<a name="l00460"></a>00460           messagePart.auditLog = job-&gt;auditLogAsHtml();
<a name="l00461"></a>00461         } <span class="keywordflow">else</span> {
<a name="l00462"></a>00462           cryptPlugError = CANT_VERIFY_SIGNATURES;
<a name="l00463"></a>00463         }
<a name="l00464"></a>00464       } <span class="keywordflow">else</span> { <span class="comment">// opaque</span>
<a name="l00465"></a>00465         <span class="keywordflow">if</span> ( Kleo::VerifyOpaqueJob * <span class="keyword">const</span> job = cryptProto-&gt;verifyOpaqueJob() ) {
<a name="l00466"></a>00466           QByteArray plainData;
<a name="l00467"></a>00467           result = job-&gt;exec( signaturetext, plainData );
<a name="l00468"></a>00468           cleartext = QCString( plainData.data(), plainData.size() + 1 );
<a name="l00469"></a>00469           messagePart.auditLog = job-&gt;auditLogAsHtml();
<a name="l00470"></a>00470         } <span class="keywordflow">else</span> {
<a name="l00471"></a>00471           cryptPlugError = CANT_VERIFY_SIGNATURES;
<a name="l00472"></a>00472         }
<a name="l00473"></a>00473       }
<a name="l00474"></a>00474       signatures = result.signatures();
<a name="l00475"></a>00475     }
<a name="l00476"></a>00476 
<a name="l00477"></a>00477     <span class="keywordflow">if</span> ( doCheck )
<a name="l00478"></a>00478       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\nObjectTreeParser::writeOpaqueOrMultipartSignedData: returned from CRYPTPLUG"</span> &lt;&lt; endl;
<a name="l00479"></a>00479 
<a name="l00480"></a>00480     <span class="comment">// ### only one signature supported</span>
<a name="l00481"></a>00481     <span class="keywordflow">if</span> ( signatures.size() &gt; 0 ) {
<a name="l00482"></a>00482       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\nObjectTreeParser::writeOpaqueOrMultipartSignedData: found signature"</span> &lt;&lt; endl;
<a name="l00483"></a>00483       GpgME::Signature signature = signatures[0];
<a name="l00484"></a>00484 
<a name="l00485"></a>00485       messagePart.status_code = signatureToStatus( signature );
<a name="l00486"></a>00486       messagePart.status = QString::fromUtf8( signature.status().asString() );
<a name="l00487"></a>00487       <span class="keywordflow">for</span> ( uint i = 1; i &lt; signatures.size(); ++i ) {
<a name="l00488"></a>00488         <span class="keywordflow">if</span> ( signatureToStatus( signatures[i] ) != messagePart.status_code ) {
<a name="l00489"></a>00489           messagePart.status_code = GPGME_SIG_STAT_DIFF;
<a name="l00490"></a>00490           messagePart.status = i18n(<span class="stringliteral">"Different results for signatures"</span>);
<a name="l00491"></a>00491         }
<a name="l00492"></a>00492       }
<a name="l00493"></a>00493       <span class="keywordflow">if</span> ( messagePart.status_code &amp; GPGME_SIG_STAT_GOOD )
<a name="l00494"></a>00494         messagePart.isGoodSignature = <span class="keyword">true</span>;
<a name="l00495"></a>00495 
<a name="l00496"></a>00496       <span class="comment">// get key for this signature</span>
<a name="l00497"></a>00497       Kleo::KeyListJob *job = cryptProto-&gt;keyListJob();
<a name="l00498"></a>00498       std::vector&lt;GpgME::Key&gt; keys;
<a name="l00499"></a>00499       GpgME::KeyListResult keyListRes = job-&gt;exec( QString::fromLatin1( signature.fingerprint() ), <span class="keyword">false</span>, keys );
<a name="l00500"></a>00500       GpgME::Key key;
<a name="l00501"></a>00501       <span class="keywordflow">if</span> ( keys.size() == 1 )
<a name="l00502"></a>00502         key = keys[0];
<a name="l00503"></a>00503       <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( keys.size() &gt; 1 )
<a name="l00504"></a>00504         assert( <span class="keyword">false</span> ); <span class="comment">// ### wtf, what should we do in this case??</span>
<a name="l00505"></a>00505 
<a name="l00506"></a>00506       <span class="comment">// save extended signature status flags</span>
<a name="l00507"></a>00507       messagePart.sigSummary = signature.summary();
<a name="l00508"></a>00508 
<a name="l00509"></a>00509       <span class="keywordflow">if</span> ( key.keyID() )
<a name="l00510"></a>00510         messagePart.keyId = key.keyID();
<a name="l00511"></a>00511       <span class="keywordflow">if</span> ( messagePart.keyId.isEmpty() )
<a name="l00512"></a>00512         messagePart.keyId = signature.fingerprint();
<a name="l00513"></a>00513       <span class="comment">// ### Ugh. We depend on two enums being in sync:</span>
<a name="l00514"></a>00514       messagePart.keyTrust = (Kpgp::Validity)signature.validity();
<a name="l00515"></a>00515       <span class="keywordflow">if</span> ( key.numUserIDs() &gt; 0 &amp;&amp; key.userID( 0 ).id() )
<a name="l00516"></a>00516         messagePart.signer = Kleo::DN( key.userID( 0 ).id() ).prettyDN();
<a name="l00517"></a>00517       <span class="keywordflow">for</span> ( uint iMail = 0; iMail &lt; key.numUserIDs(); ++iMail ) {
<a name="l00518"></a>00518         <span class="comment">// The following if /should/ always result in TRUE but we</span>
<a name="l00519"></a>00519         <span class="comment">// won't trust implicitely the plugin that gave us these data.</span>
<a name="l00520"></a>00520         <span class="keywordflow">if</span> ( key.userID( iMail ).email() ) {
<a name="l00521"></a>00521           QString email = QString::fromUtf8( key.userID( iMail ).email() );
<a name="l00522"></a>00522           <span class="comment">// ### work around gpgme 0.3.x / cryptplug bug where the</span>
<a name="l00523"></a>00523           <span class="comment">// ### email addresses are specified as angle-addr, not addr-spec:</span>
<a name="l00524"></a>00524           <span class="keywordflow">if</span> ( email.startsWith( <span class="stringliteral">"&lt;"</span> ) &amp;&amp; email.endsWith( <span class="stringliteral">"&gt;"</span> ) )
<a name="l00525"></a>00525             email = email.mid( 1, email.length() - 2 );
<a name="l00526"></a>00526           <span class="keywordflow">if</span> ( !email.isEmpty() )
<a name="l00527"></a>00527             messagePart.signerMailAddresses.append( email );
<a name="l00528"></a>00528         }
<a name="l00529"></a>00529       }
<a name="l00530"></a>00530 
<a name="l00531"></a>00531       <span class="keywordflow">if</span> ( signature.creationTime() )
<a name="l00532"></a>00532         messagePart.creationTime.setTime_t( signature.creationTime() );
<a name="l00533"></a>00533       <span class="keywordflow">else</span>
<a name="l00534"></a>00534         messagePart.creationTime = QDateTime();
<a name="l00535"></a>00535       <span class="keywordflow">if</span> ( messagePart.signer.isEmpty() ) {
<a name="l00536"></a>00536         <span class="keywordflow">if</span> ( key.numUserIDs() &gt; 0 &amp;&amp; key.userID( 0 ).name() )
<a name="l00537"></a>00537           messagePart.signer = Kleo::DN( key.userID( 0 ).name() ).prettyDN();
<a name="l00538"></a>00538         <span class="keywordflow">if</span> ( !messagePart.signerMailAddresses.empty() ) {
<a name="l00539"></a>00539           <span class="keywordflow">if</span> ( messagePart.signer.isEmpty() )
<a name="l00540"></a>00540             messagePart.signer = messagePart.signerMailAddresses.front();
<a name="l00541"></a>00541           <span class="keywordflow">else</span>
<a name="l00542"></a>00542             messagePart.signer += <span class="stringliteral">" &lt;"</span> + messagePart.signerMailAddresses.front() + <span class="charliteral">'&gt;'</span>;
<a name="l00543"></a>00543         }
<a name="l00544"></a>00544       }
<a name="l00545"></a>00545 
<a name="l00546"></a>00546       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n  key id: "</span> &lt;&lt; messagePart.keyId
<a name="l00547"></a>00547                     &lt;&lt; <span class="stringliteral">"\n  key trust: "</span> &lt;&lt; messagePart.keyTrust
<a name="l00548"></a>00548                     &lt;&lt; <span class="stringliteral">"\n  signer: "</span> &lt;&lt; messagePart.signer &lt;&lt; endl;
<a name="l00549"></a>00549 
<a name="l00550"></a>00550     } <span class="keywordflow">else</span> {
<a name="l00551"></a>00551       messagePart.creationTime = QDateTime();
<a name="l00552"></a>00552     }
<a name="l00553"></a>00553 
<a name="l00554"></a>00554     <span class="keywordflow">if</span> ( !doCheck || !data ){
<a name="l00555"></a>00555       <span class="keywordflow">if</span> ( cleartextData || !cleartext.isEmpty() ) {
<a name="l00556"></a>00556         <span class="keywordflow">if</span> ( mReader )
<a name="l00557"></a>00557           htmlWriter()-&gt;queue( writeSigstatHeader( messagePart,
<a name="l00558"></a>00558                                                    cryptProto,
<a name="l00559"></a>00559                                                    fromAddress ) );
<a name="l00560"></a>00560         bIsOpaqueSigned = <span class="keyword">true</span>;
<a name="l00561"></a>00561 
<a name="l00562"></a>00562         CryptoProtocolSaver cpws( <span class="keyword">this</span>, cryptProto );
<a name="l00563"></a>00563         insertAndParseNewChildNode( sign, doCheck ? cleartext.data() : cleartextData-&gt;data(),
<a name="l00564"></a>00564                                     <span class="stringliteral">"opaqued signed data"</span> );
<a name="l00565"></a>00565 
<a name="l00566"></a>00566         <span class="keywordflow">if</span> ( mReader )
<a name="l00567"></a>00567           htmlWriter()-&gt;queue( writeSigstatFooter( messagePart ) );
<a name="l00568"></a>00568 
<a name="l00569"></a>00569       }
<a name="l00570"></a>00570       <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( !hideErrors ) {
<a name="l00571"></a>00571         QString txt;
<a name="l00572"></a>00572         txt = <span class="stringliteral">"&lt;hr&gt;&lt;b&gt;&lt;h2&gt;"</span>;
<a name="l00573"></a>00573         txt.append( i18n( <span class="stringliteral">"The crypto engine returned no cleartext data."</span> ) );
<a name="l00574"></a>00574         txt.append( <span class="stringliteral">"&lt;/h2&gt;&lt;/b&gt;"</span> );
<a name="l00575"></a>00575         txt.append( <span class="stringliteral">"&lt;br&gt;&amp;nbsp;&lt;br&gt;"</span> );
<a name="l00576"></a>00576         txt.append( i18n( <span class="stringliteral">"Status: "</span> ) );
<a name="l00577"></a>00577         <span class="keywordflow">if</span> ( !messagePart.status.isEmpty() ) {
<a name="l00578"></a>00578           txt.append( <span class="stringliteral">"&lt;i&gt;"</span> );
<a name="l00579"></a>00579           txt.append( messagePart.status );
<a name="l00580"></a>00580           txt.append( <span class="stringliteral">"&lt;/i&gt;"</span> );
<a name="l00581"></a>00581         }
<a name="l00582"></a>00582         <span class="keywordflow">else</span>
<a name="l00583"></a>00583           txt.append( i18n(<span class="stringliteral">"(unknown)"</span>) );
<a name="l00584"></a>00584         <span class="keywordflow">if</span> ( mReader )
<a name="l00585"></a>00585           htmlWriter()-&gt;queue(txt);
<a name="l00586"></a>00586       }
<a name="l00587"></a>00587     }
<a name="l00588"></a>00588     <span class="keywordflow">else</span> {
<a name="l00589"></a>00589       <span class="keywordflow">if</span> ( mReader ) {
<a name="l00590"></a>00590         <span class="keywordflow">if</span> ( !cryptProto ) {
<a name="l00591"></a>00591           QString errorMsg;
<a name="l00592"></a>00592           <span class="keywordflow">switch</span> ( cryptPlugError ) {
<a name="l00593"></a>00593           <span class="keywordflow">case</span> NOT_INITIALIZED:
<a name="l00594"></a>00594             errorMsg = i18n( <span class="stringliteral">"Crypto plug-in \"%1\" is not initialized."</span> )
<a name="l00595"></a>00595                        .arg( cryptPlugLibName );
<a name="l00596"></a>00596             <span class="keywordflow">break</span>;
<a name="l00597"></a>00597           <span class="keywordflow">case</span> CANT_VERIFY_SIGNATURES:
<a name="l00598"></a>00598             errorMsg = i18n( <span class="stringliteral">"Crypto plug-in \"%1\" cannot verify signatures."</span> )
<a name="l00599"></a>00599                        .arg( cryptPlugLibName );
<a name="l00600"></a>00600             <span class="keywordflow">break</span>;
<a name="l00601"></a>00601           <span class="keywordflow">case</span> NO_PLUGIN:
<a name="l00602"></a>00602             <span class="keywordflow">if</span> ( cryptPlugDisplayName.isEmpty() )
<a name="l00603"></a>00603               errorMsg = i18n( <span class="stringliteral">"No appropriate crypto plug-in was found."</span> );
<a name="l00604"></a>00604             <span class="keywordflow">else</span>
<a name="l00605"></a>00605               errorMsg = i18n( <span class="stringliteral">"%1 is either 'OpenPGP' or 'S/MIME'"</span>,
<a name="l00606"></a>00606                                <span class="stringliteral">"No %1 plug-in was found."</span> )
<a name="l00607"></a>00607                            .arg( cryptPlugDisplayName );
<a name="l00608"></a>00608             <span class="keywordflow">break</span>;
<a name="l00609"></a>00609           }
<a name="l00610"></a>00610           messagePart.errorText = i18n( <span class="stringliteral">"The message is signed, but the "</span>
<a name="l00611"></a>00611                                         <span class="stringliteral">"validity of the signature cannot be "</span>
<a name="l00612"></a>00612                                         <span class="stringliteral">"verified.&lt;br /&gt;"</span>
<a name="l00613"></a>00613                                         <span class="stringliteral">"Reason: %1"</span> )
<a name="l00614"></a>00614                                   .arg( errorMsg );
<a name="l00615"></a>00615         }
<a name="l00616"></a>00616 
<a name="l00617"></a>00617         <span class="keywordflow">if</span> ( mReader )
<a name="l00618"></a>00618           htmlWriter()-&gt;queue( writeSigstatHeader( messagePart,
<a name="l00619"></a>00619                                                    cryptProto,
<a name="l00620"></a>00620                                                  fromAddress ) );
<a name="l00621"></a>00621       }
<a name="l00622"></a>00622 
<a name="l00623"></a>00623       ObjectTreeParser otp( mReader, cryptProto, <span class="keyword">true</span> );
<a name="l00624"></a>00624       otp.parseObjectTree( data );
<a name="l00625"></a>00625       mRawReplyString += otp.rawReplyString();
<a name="l00626"></a>00626       mTextualContent += otp.textualContent();
<a name="l00627"></a>00627       <span class="keywordflow">if</span> ( !otp.textualContentCharset().isEmpty() )
<a name="l00628"></a>00628         mTextualContentCharset = otp.textualContentCharset();
<a name="l00629"></a>00629 
<a name="l00630"></a>00630       <span class="keywordflow">if</span> ( mReader )
<a name="l00631"></a>00631         htmlWriter()-&gt;queue( writeSigstatFooter( messagePart ) );
<a name="l00632"></a>00632     }
<a name="l00633"></a>00633 
<a name="l00634"></a>00634     kdDebug(5006) &lt;&lt; <span class="stringliteral">"\nObjectTreeParser::writeOpaqueOrMultipartSignedData: done, returning "</span>
<a name="l00635"></a>00635                   &lt;&lt; ( bIsOpaqueSigned ? <span class="stringliteral">"TRUE"</span> : <span class="stringliteral">"FALSE"</span> ) &lt;&lt; endl;
<a name="l00636"></a>00636     <span class="keywordflow">return</span> bIsOpaqueSigned;
<a name="l00637"></a>00637   }
<a name="l00638"></a>00638 
<a name="l00639"></a>00639 
<a name="l00640"></a>00640 <span class="keywordtype">bool</span> ObjectTreeParser::okDecryptMIME( partNode&amp; data,
<a name="l00641"></a>00641                                       QCString&amp; decryptedData,
<a name="l00642"></a>00642                                       <span class="keywordtype">bool</span>&amp; signatureFound,
<a name="l00643"></a>00643                                       std::vector&lt;GpgME::Signature&gt; &amp;signatures,
<a name="l00644"></a>00644                                       <span class="keywordtype">bool</span> showWarning,
<a name="l00645"></a>00645                                       <span class="keywordtype">bool</span>&amp; passphraseError,
<a name="l00646"></a>00646                                       <span class="keywordtype">bool</span>&amp; actuallyEncrypted,
<a name="l00647"></a>00647                                       QString&amp; aErrorText,
<a name="l00648"></a>00648                                       QString&amp; auditLog )
<a name="l00649"></a>00649 {
<a name="l00650"></a>00650   passphraseError = <span class="keyword">false</span>;
<a name="l00651"></a>00651   aErrorText = QString::null;
<a name="l00652"></a>00652   auditLog = QString::null;
<a name="l00653"></a>00653   <span class="keywordtype">bool</span> bDecryptionOk = <span class="keyword">false</span>;
<a name="l00654"></a>00654   <span class="keyword">enum</span> { NO_PLUGIN, NOT_INITIALIZED, CANT_DECRYPT }
<a name="l00655"></a>00655     cryptPlugError = NO_PLUGIN;
<a name="l00656"></a>00656 
<a name="l00657"></a>00657   <span class="keyword">const</span> Kleo::CryptoBackend::Protocol* cryptProto = cryptoProtocol();
<a name="l00658"></a>00658 
<a name="l00659"></a>00659   QString cryptPlugLibName;
<a name="l00660"></a>00660   <span class="keywordflow">if</span> ( cryptProto )
<a name="l00661"></a>00661     cryptPlugLibName = cryptProto-&gt;name();
<a name="l00662"></a>00662 
<a name="l00663"></a>00663   <span class="keywordflow">if</span> ( mReader &amp;&amp; !mReader-&gt;decryptMessage() ) {
<a name="l00664"></a>00664     QString iconName = KGlobal::instance()-&gt;iconLoader()-&gt;iconPath( <span class="stringliteral">"decrypted"</span>, KIcon::Small );
<a name="l00665"></a>00665     decryptedData = <span class="stringliteral">"&lt;div style=\"font-size:large; text-align:center;"</span>
<a name="l00666"></a>00666                       <span class="stringliteral">"padding-top:20pt;\"&gt;"</span>
<a name="l00667"></a>00667                     + i18n(<span class="stringliteral">"This message is encrypted."</span>).utf8()
<a name="l00668"></a>00668                     + <span class="stringliteral">"&lt;/div&gt;"</span>
<a name="l00669"></a>00669                       <span class="stringliteral">"&lt;div style=\"text-align:center; padding-bottom:20pt;\"&gt;"</span>
<a name="l00670"></a>00670                       <span class="stringliteral">"&lt;a href=\"kmail:decryptMessage\"&gt;"</span>
<a name="l00671"></a>00671                       <span class="stringliteral">"&lt;img src=\""</span> + iconName.utf8() + <span class="stringliteral">"\"/&gt;"</span>
<a name="l00672"></a>00672                     + i18n(<span class="stringliteral">"Decrypt Message"</span>).utf8()
<a name="l00673"></a>00673                     + <span class="stringliteral">"&lt;/a&gt;&lt;/div&gt;"</span>;
<a name="l00674"></a>00674     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00675"></a>00675   }
<a name="l00676"></a>00676 
<a name="l00677"></a>00677   <span class="keywordflow">if</span> ( cryptProto &amp;&amp; !kmkernel-&gt;contextMenuShown() ) {
<a name="l00678"></a>00678     QByteArray ciphertext( data.msgPart().bodyDecodedBinary() );
<a name="l00679"></a>00679 <span class="preprocessor">#ifdef MARCS_DEBUG</span>
<a name="l00680"></a>00680 <span class="preprocessor"></span>    QCString cipherStr( ciphertext.data(), ciphertext.size() + 1 );
<a name="l00681"></a>00681     <span class="keywordtype">bool</span> cipherIsBinary = (-1 == cipherStr.find(<span class="stringliteral">"BEGIN ENCRYPTED MESSAGE"</span>, 0, <span class="keyword">false</span>) ) &amp;&amp;
<a name="l00682"></a>00682                           (-1 == cipherStr.find(<span class="stringliteral">"BEGIN PGP ENCRYPTED MESSAGE"</span>, 0, <span class="keyword">false</span>) ) &amp;&amp;
<a name="l00683"></a>00683                           (-1 == cipherStr.find(<span class="stringliteral">"BEGIN PGP MESSAGE"</span>, 0, <span class="keyword">false</span>) );
<a name="l00684"></a>00684 
<a name="l00685"></a>00685     dumpToFile( <span class="stringliteral">"dat_04_reader.encrypted"</span>, ciphertext.data(), ciphertext.size() );
<a name="l00686"></a>00686 
<a name="l00687"></a>00687     QCString deb;
<a name="l00688"></a>00688     deb =  <span class="stringliteral">"\n\nE N C R Y P T E D    D A T A = "</span>;
<a name="l00689"></a>00689     <span class="keywordflow">if</span> ( cipherIsBinary )
<a name="l00690"></a>00690       deb += <span class="stringliteral">"[binary data]"</span>;
<a name="l00691"></a>00691     <span class="keywordflow">else</span> {
<a name="l00692"></a>00692       deb += <span class="stringliteral">"\""</span>;
<a name="l00693"></a>00693       deb += cipherStr;
<a name="l00694"></a>00694       deb += <span class="stringliteral">"\""</span>;
<a name="l00695"></a>00695     }
<a name="l00696"></a>00696     deb += <span class="stringliteral">"\n\n"</span>;
<a name="l00697"></a>00697     kdDebug(5006) &lt;&lt; deb &lt;&lt; endl;
<a name="l00698"></a>00698 <span class="preprocessor">#endif</span>
<a name="l00699"></a>00699 <span class="preprocessor"></span>
<a name="l00700"></a>00700 
<a name="l00701"></a>00701     kdDebug(5006) &lt;&lt; <span class="stringliteral">"ObjectTreeParser::decryptMIME: going to call CRYPTPLUG "</span>
<a name="l00702"></a>00702                   &lt;&lt; cryptPlugLibName &lt;&lt; endl;
<a name="l00703"></a>00703     <span class="keywordflow">if</span> ( mReader )
<a name="l00704"></a>00704       emit mReader-&gt;noDrag(); <span class="comment">// in case pineentry pops up, don't let kmheaders start a drag afterwards</span>
<a name="l00705"></a>00705 
<a name="l00706"></a>00706     Kleo::DecryptVerifyJob* job = cryptProto-&gt;decryptVerifyJob();
<a name="l00707"></a>00707     <span class="keywordflow">if</span> ( !job ) {
<a name="l00708"></a>00708       cryptPlugError = CANT_DECRYPT;
<a name="l00709"></a>00709       cryptProto = 0;
<a name="l00710"></a>00710     } <span class="keywordflow">else</span> {
<a name="l00711"></a>00711       QByteArray plainText;
<a name="l00712"></a>00712       <span class="keyword">const</span> std::pair&lt;GpgME::DecryptionResult,GpgME::VerificationResult&gt; res = job-&gt;exec( ciphertext, plainText );
<a name="l00713"></a>00713       <span class="keyword">const</span> GpgME::DecryptionResult &amp; decryptResult = res.first;
<a name="l00714"></a>00714       <span class="keyword">const</span> GpgME::VerificationResult &amp; verifyResult = res.second;
<a name="l00715"></a>00715       signatureFound = verifyResult.signatures().size() &gt; 0;
<a name="l00716"></a>00716       signatures = verifyResult.signatures();
<a name="l00717"></a>00717       bDecryptionOk = !decryptResult.error();
<a name="l00718"></a>00718       passphraseError =  decryptResult.error().isCanceled()
<a name="l00719"></a>00719         || decryptResult.error().code() == GPG_ERR_NO_SECKEY;
<a name="l00720"></a>00720       actuallyEncrypted = decryptResult.error().code() != GPG_ERR_NO_DATA;
<a name="l00721"></a>00721       aErrorText = QString::fromLocal8Bit( decryptResult.error().asString() );
<a name="l00722"></a>00722       auditLog = job-&gt;auditLogAsHtml();
<a name="l00723"></a>00723 
<a name="l00724"></a>00724       kdDebug(5006) &lt;&lt; <span class="stringliteral">"ObjectTreeParser::decryptMIME: returned from CRYPTPLUG"</span>
<a name="l00725"></a>00725                     &lt;&lt; endl;
<a name="l00726"></a>00726       <span class="keywordflow">if</span> ( bDecryptionOk )
<a name="l00727"></a>00727         decryptedData = QCString( plainText.data(), plainText.size() + 1 );
<a name="l00728"></a>00728       <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( mReader &amp;&amp; showWarning ) {
<a name="l00729"></a>00729         decryptedData = <span class="stringliteral">"&lt;div style=\"font-size:x-large; text-align:center;"</span>
<a name="l00730"></a>00730                         <span class="stringliteral">"padding:20pt;\"&gt;"</span>
<a name="l00731"></a>00731                       + i18n(<span class="stringliteral">"Encrypted data not shown."</span>).utf8()
<a name="l00732"></a>00732                       + <span class="stringliteral">"&lt;/div&gt;"</span>;
<a name="l00733"></a>00733         <span class="keywordflow">if</span> ( !passphraseError )
<a name="l00734"></a>00734           aErrorText = i18n(<span class="stringliteral">"Crypto plug-in \"%1\" could not decrypt the data."</span>)
<a name="l00735"></a>00735                         .arg( cryptPlugLibName )
<a name="l00736"></a>00736                     + <span class="stringliteral">"&lt;br /&gt;"</span>
<a name="l00737"></a>00737                     + i18n(<span class="stringliteral">"Error: %1"</span>).arg( aErrorText );
<a name="l00738"></a>00738       }
<a name="l00739"></a>00739     }
<a name="l00740"></a>00740   }
<a name="l00741"></a>00741 
<a name="l00742"></a>00742   <span class="keywordflow">if</span> ( !cryptProto ) {
<a name="l00743"></a>00743     decryptedData = <span class="stringliteral">"&lt;div style=\"text-align:center; padding:20pt;\"&gt;"</span>
<a name="l00744"></a>00744                   + i18n(<span class="stringliteral">"Encrypted data not shown."</span>).utf8()
<a name="l00745"></a>00745                   + <span class="stringliteral">"&lt;/div&gt;"</span>;
<a name="l00746"></a>00746     <span class="keywordflow">switch</span> ( cryptPlugError ) {
<a name="l00747"></a>00747     <span class="keywordflow">case</span> NOT_INITIALIZED:
<a name="l00748"></a>00748       aErrorText = i18n( <span class="stringliteral">"Crypto plug-in \"%1\" is not initialized."</span> )
<a name="l00749"></a>00749                      .arg( cryptPlugLibName );
<a name="l00750"></a>00750       <span class="keywordflow">break</span>;
<a name="l00751"></a>00751     <span class="keywordflow">case</span> CANT_DECRYPT:
<a name="l00752"></a>00752       aErrorText = i18n( <span class="stringliteral">"Crypto plug-in \"%1\" cannot decrypt messages."</span> )
<a name="l00753"></a>00753                      .arg( cryptPlugLibName );
<a name="l00754"></a>00754       <span class="keywordflow">break</span>;
<a name="l00755"></a>00755     <span class="keywordflow">case</span> NO_PLUGIN:
<a name="l00756"></a>00756       aErrorText = i18n( <span class="stringliteral">"No appropriate crypto plug-in was found."</span> );
<a name="l00757"></a>00757       <span class="keywordflow">break</span>;
<a name="l00758"></a>00758     }
<a name="l00759"></a>00759   } <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( kmkernel-&gt;contextMenuShown() ) {
<a name="l00760"></a>00760     <span class="comment">// ### Workaround for bug 56693 (kmail freeze with the complete desktop</span>
<a name="l00761"></a>00761     <span class="comment">// ### while pinentry-qt appears)</span>
<a name="l00762"></a>00762     QByteArray ciphertext( data.msgPart().bodyDecodedBinary() );
<a name="l00763"></a>00763     QCString cipherStr( ciphertext.data(), ciphertext.size() + 1 );
<a name="l00764"></a>00764     <span class="keywordtype">bool</span> cipherIsBinary = (-1 == cipherStr.find(<span class="stringliteral">"BEGIN ENCRYPTED MESSAGE"</span>, 0, <span class="keyword">false</span>) ) &amp;&amp;
<a name="l00765"></a>00765                           (-1 == cipherStr.find(<span class="stringliteral">"BEGIN PGP ENCRYPTED MESSAGE"</span>, 0, <span class="keyword">false</span>) ) &amp;&amp;
<a name="l00766"></a>00766                           (-1 == cipherStr.find(<span class="stringliteral">"BEGIN PGP MESSAGE"</span>, 0, <span class="keyword">false</span>) );
<a name="l00767"></a>00767     <span class="keywordflow">if</span> ( !cipherIsBinary ) {
<a name="l00768"></a>00768       decryptedData = cipherStr;
<a name="l00769"></a>00769     }
<a name="l00770"></a>00770     <span class="keywordflow">else</span> {
<a name="l00771"></a>00771       decryptedData = <span class="stringliteral">"&lt;div style=\"font-size:x-large; text-align:center;"</span>
<a name="l00772"></a>00772                       <span class="stringliteral">"padding:20pt;\"&gt;"</span>
<a name="l00773"></a>00773                     + i18n(<span class="stringliteral">"Encrypted data not shown."</span>).utf8()
<a name="l00774"></a>00774                     + <span class="stringliteral">"&lt;/div&gt;"</span>;
<a name="l00775"></a>00775     }
<a name="l00776"></a>00776   }
<a name="l00777"></a>00777 
<a name="l00778"></a>00778   dumpToFile( <span class="stringliteral">"dat_05_reader.decrypted"</span>, decryptedData.data(), decryptedData.size() );
<a name="l00779"></a>00779 
<a name="l00780"></a>00780   <span class="keywordflow">return</span> bDecryptionOk;
<a name="l00781"></a>00781 }
<a name="l00782"></a>00782 
<a name="l00783"></a>00783   <span class="comment">//static</span>
<a name="l00784"></a>00784   <span class="keywordtype">bool</span> ObjectTreeParser::containsExternalReferences( <span class="keyword">const</span> QCString &amp; str )
<a name="l00785"></a>00785   {
<a name="l00786"></a>00786     QRegExp httpRegExp(<span class="stringliteral">"(\\\"|\\\'|url\\s*\\(\\s*)http[s]?:"</span>);
<a name="l00787"></a>00787     <span class="keywordtype">int</span> httpPos = str.find( httpRegExp, 0 );
<a name="l00788"></a>00788 
<a name="l00789"></a>00789     <span class="keywordflow">while</span> ( httpPos &gt;= 0 ) {
<a name="l00790"></a>00790       <span class="comment">// look backwards for "href"</span>
<a name="l00791"></a>00791       <span class="keywordflow">if</span> ( httpPos &gt; 5 ) {
<a name="l00792"></a>00792         <span class="keywordtype">int</span> hrefPos = str.findRev( <span class="stringliteral">"href"</span>, httpPos - 5, <span class="keyword">true</span> );
<a name="l00793"></a>00793         <span class="comment">// if no 'href' is found or the distance between 'href' and '"http[s]:'</span>
<a name="l00794"></a>00794         <span class="comment">// is larger than 7 (7 is the distance in 'href = "http[s]:') then</span>
<a name="l00795"></a>00795         <span class="comment">// we assume that we have found an external reference</span>
<a name="l00796"></a>00796         <span class="keywordflow">if</span> ( ( hrefPos == -1 ) || ( httpPos - hrefPos &gt; 7 ) )
<a name="l00797"></a>00797           <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00798"></a>00798       }
<a name="l00799"></a>00799       <span class="comment">// find next occurrence of "http: or "https:</span>
<a name="l00800"></a>00800       httpPos = str.find( httpRegExp, httpPos + 6 );
<a name="l00801"></a>00801     }
<a name="l00802"></a>00802     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00803"></a>00803   }
<a name="l00804"></a>00804 
<a name="l00805"></a>00805   <span class="keywordtype">bool</span> ObjectTreeParser::processTextHtmlSubtype( partNode * curNode, ProcessResult &amp; ) {
<a name="l00806"></a>00806     QCString cstr( curNode-&gt;msgPart().bodyDecoded() );
<a name="l00807"></a>00807 
<a name="l00808"></a>00808     mRawReplyString = cstr;
<a name="l00809"></a>00809     <span class="keywordflow">if</span> ( curNode-&gt;isFirstTextPart() ) {
<a name="l00810"></a>00810       mTextualContent += curNode-&gt;msgPart().bodyToUnicode();
<a name="l00811"></a>00811       mTextualContentCharset = curNode-&gt;msgPart().charset();
<a name="l00812"></a>00812     }
<a name="l00813"></a>00813 
<a name="l00814"></a>00814     <span class="keywordflow">if</span> ( !mReader )
<a name="l00815"></a>00815       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00816"></a>00816 
<a name="l00817"></a>00817     <span class="keywordflow">if</span> ( curNode-&gt;isFirstTextPart() ||
<a name="l00818"></a>00818          attachmentStrategy()-&gt;defaultDisplay( curNode ) == AttachmentStrategy::Inline ||
<a name="l00819"></a>00819          showOnlyOneMimePart() )
<a name="l00820"></a>00820     {
<a name="l00821"></a>00821       <span class="keywordflow">if</span> ( mReader-&gt;htmlMail() ) {
<a name="l00822"></a>00822         <span class="comment">// ---Sven's strip &lt;/BODY&gt; and &lt;/HTML&gt; from end of attachment start-</span>
<a name="l00823"></a>00823         <span class="comment">// We must fo this, or else we will see only 1st inlined html</span>
<a name="l00824"></a>00824         <span class="comment">// attachment.  It is IMHO enough to search only for &lt;/BODY&gt; and</span>
<a name="l00825"></a>00825         <span class="comment">// put \0 there.</span>
<a name="l00826"></a>00826         <span class="keywordtype">int</span> i = cstr.findRev(<span class="stringliteral">"&lt;/body&gt;"</span>, -1, <span class="keyword">false</span>); <span class="comment">//case insensitive</span>
<a name="l00827"></a>00827         <span class="keywordflow">if</span> ( 0 &lt;= i )
<a name="l00828"></a>00828           cstr.truncate(i);
<a name="l00829"></a>00829         <span class="keywordflow">else</span> <span class="comment">// just in case - search for &lt;/html&gt;</span>
<a name="l00830"></a>00830         {
<a name="l00831"></a>00831           i = cstr.findRev(<span class="stringliteral">"&lt;/html&gt;"</span>, -1, <span class="keyword">false</span>); <span class="comment">//case insensitive</span>
<a name="l00832"></a>00832           <span class="keywordflow">if</span> ( 0 &lt;= i ) cstr.truncate(i);
<a name="l00833"></a>00833         }
<a name="l00834"></a>00834         <span class="comment">// ---Sven's strip &lt;/BODY&gt; and &lt;/HTML&gt; from end of attachment end-</span>
<a name="l00835"></a>00835         <span class="comment">// Show the "external references" warning (with possibility to load</span>
<a name="l00836"></a>00836         <span class="comment">// external references only if loading external references is disabled</span>
<a name="l00837"></a>00837         <span class="comment">// and the HTML code contains obvious external references). For</span>
<a name="l00838"></a>00838         <span class="comment">// messages where the external references are obfuscated the user won't</span>
<a name="l00839"></a>00839         <span class="comment">// have an easy way to load them but that shouldn't be a problem</span>
<a name="l00840"></a>00840         <span class="comment">// because only spam contains obfuscated external references.</span>
<a name="l00841"></a>00841         <span class="keywordflow">if</span> ( !mReader-&gt;htmlLoadExternal() &amp;&amp;
<a name="l00842"></a>00842              containsExternalReferences( cstr ) ) {
<a name="l00843"></a>00843           htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;div class=\"htmlWarn\"&gt;\n"</span> );
<a name="l00844"></a>00844           htmlWriter()-&gt;queue( i18n(<span class="stringliteral">"&lt;b&gt;Note:&lt;/b&gt; This HTML message may contain external "</span>
<a name="l00845"></a>00845                                     <span class="stringliteral">"references to images etc. For security/privacy reasons "</span>
<a name="l00846"></a>00846                                     <span class="stringliteral">"external references are not loaded. If you trust the "</span>
<a name="l00847"></a>00847                                     <span class="stringliteral">"sender of this message then you can load the external "</span>
<a name="l00848"></a>00848                                     <span class="stringliteral">"references for this message "</span>
<a name="l00849"></a>00849                                     <span class="stringliteral">"&lt;a href=\"kmail:loadExternal\"&gt;by clicking here&lt;/a&gt;."</span>) );
<a name="l00850"></a>00850           htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;/div&gt;&lt;br&gt;&lt;br&gt;"</span> );
<a name="l00851"></a>00851         }
<a name="l00852"></a>00852       } <span class="keywordflow">else</span> {
<a name="l00853"></a>00853         htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;div class=\"htmlWarn\"&gt;\n"</span> );
<a name="l00854"></a>00854         htmlWriter()-&gt;queue( i18n(<span class="stringliteral">"&lt;b&gt;Note:&lt;/b&gt; This is an HTML message. For "</span>
<a name="l00855"></a>00855                                   <span class="stringliteral">"security reasons, only the raw HTML code "</span>
<a name="l00856"></a>00856                                   <span class="stringliteral">"is shown. If you trust the sender of this "</span>
<a name="l00857"></a>00857                                   <span class="stringliteral">"message then you can activate formatted "</span>
<a name="l00858"></a>00858                                   <span class="stringliteral">"HTML display for this message "</span>
<a name="l00859"></a>00859                                   <span class="stringliteral">"&lt;a href=\"kmail:showHTML\"&gt;by clicking here&lt;/a&gt;."</span>) );
<a name="l00860"></a>00860         htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;/div&gt;&lt;br&gt;&lt;br&gt;"</span> );
<a name="l00861"></a>00861       }
<a name="l00862"></a>00862       htmlWriter()-&gt;queue( codecFor( curNode )-&gt;toUnicode( mReader-&gt;htmlMail() ? cstr : <a class="code" href="classKMMessage.html#a508a4076d4b63a5c4b2c48906b354bb" title="Convert &amp;#39;&amp;lt;&amp;#39; into &amp;quot;&amp;amp;lt;&amp;quot; resp.">KMMessage::html2source</a>( cstr )));
<a name="l00863"></a>00863       mReader-&gt;mColorBar-&gt;setHtmlMode();
<a name="l00864"></a>00864       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00865"></a>00865     }
<a name="l00866"></a>00866     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00867"></a>00867   }
<a name="l00868"></a>00868 } <span class="comment">// namespace KMail</span>
<a name="l00869"></a>00869 
<a name="l00870"></a>00870 <span class="keyword">static</span> <span class="keywordtype">bool</span> isMailmanMessage( partNode * curNode ) {
<a name="l00871"></a>00871   <span class="keywordflow">if</span> ( !curNode-&gt;dwPart() || !curNode-&gt;dwPart()-&gt;hasHeaders() )
<a name="l00872"></a>00872     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00873"></a>00873   DwHeaders &amp; headers = curNode-&gt;dwPart()-&gt;Headers();
<a name="l00874"></a>00874   <span class="keywordflow">if</span> ( headers.HasField(<span class="stringliteral">"X-Mailman-Version"</span>) )
<a name="l00875"></a>00875     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00876"></a>00876   <span class="keywordflow">if</span> ( headers.HasField(<span class="stringliteral">"X-Mailer"</span>) &amp;&amp;
<a name="l00877"></a>00877        0 == QCString( headers.FieldBody(<span class="stringliteral">"X-Mailer"</span>).AsString().c_str() )
<a name="l00878"></a>00878        .find(<span class="stringliteral">"MAILMAN"</span>, 0, <span class="keyword">false</span>) )
<a name="l00879"></a>00879     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00880"></a>00880   <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00881"></a>00881 }
<a name="l00882"></a>00882 
<a name="l00883"></a>00883 <span class="keyword">namespace </span>KMail {
<a name="l00884"></a>00884 
<a name="l00885"></a>00885   <span class="keywordtype">bool</span> ObjectTreeParser::processMailmanMessage( partNode * curNode ) {
<a name="l00886"></a>00886     <span class="keyword">const</span> QCString cstr = curNode-&gt;msgPart().bodyDecoded();
<a name="l00887"></a>00887 
<a name="l00888"></a>00888     <span class="comment">//###</span>
<a name="l00889"></a>00889     <span class="keyword">const</span> QCString delim1( <span class="stringliteral">"--__--__--\n\nMessage:"</span>);
<a name="l00890"></a>00890     <span class="keyword">const</span> QCString delim2( <span class="stringliteral">"--__--__--\r\n\r\nMessage:"</span>);
<a name="l00891"></a>00891     <span class="keyword">const</span> QCString delimZ2(<span class="stringliteral">"--__--__--\n\n_____________"</span>);
<a name="l00892"></a>00892     <span class="keyword">const</span> QCString delimZ1(<span class="stringliteral">"--__--__--\r\n\r\n_____________"</span>);
<a name="l00893"></a>00893     QCString partStr, digestHeaderStr;
<a name="l00894"></a>00894     <span class="keywordtype">int</span> thisDelim = cstr.find(delim1, 0, <span class="keyword">false</span>);
<a name="l00895"></a>00895     <span class="keywordflow">if</span> ( thisDelim == -1 )
<a name="l00896"></a>00896       thisDelim = cstr.find(delim2, 0, <span class="keyword">false</span>);
<a name="l00897"></a>00897     <span class="keywordflow">if</span> ( thisDelim == -1 ) {
<a name="l00898"></a>00898       kdDebug(5006) &lt;&lt; <span class="stringliteral">"        Sorry: Old style Mailman message but no delimiter found."</span> &lt;&lt; endl;
<a name="l00899"></a>00899       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00900"></a>00900     }
<a name="l00901"></a>00901 
<a name="l00902"></a>00902     <span class="keywordtype">int</span> nextDelim = cstr.find(delim1, thisDelim+1, <span class="keyword">false</span>);
<a name="l00903"></a>00903     <span class="keywordflow">if</span> ( -1 == nextDelim )
<a name="l00904"></a>00904       nextDelim = cstr.find(delim2, thisDelim+1, <span class="keyword">false</span>);
<a name="l00905"></a>00905     <span class="keywordflow">if</span> ( -1 == nextDelim )
<a name="l00906"></a>00906       nextDelim = cstr.find(delimZ1, thisDelim+1, <span class="keyword">false</span>);
<a name="l00907"></a>00907     <span class="keywordflow">if</span> ( -1 == nextDelim )
<a name="l00908"></a>00908       nextDelim = cstr.find(delimZ2, thisDelim+1, <span class="keyword">false</span>);
<a name="l00909"></a>00909     <span class="keywordflow">if</span> ( nextDelim &lt; 0)
<a name="l00910"></a>00910       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00911"></a>00911 
<a name="l00912"></a>00912     kdDebug(5006) &lt;&lt; <span class="stringliteral">"        processing old style Mailman digest"</span> &lt;&lt; endl;
<a name="l00913"></a>00913     <span class="comment">//if ( curNode-&gt;mRoot )</span>
<a name="l00914"></a>00914     <span class="comment">//  curNode = curNode-&gt;mRoot;</span>
<a name="l00915"></a>00915 
<a name="l00916"></a>00916     <span class="comment">// at least one message found: build a mime tree</span>
<a name="l00917"></a>00917     digestHeaderStr = <span class="stringliteral">"Content-Type=text/plain\nContent-Description=digest header\n\n"</span>;
<a name="l00918"></a>00918     digestHeaderStr += cstr.mid( 0, thisDelim );
<a name="l00919"></a>00919     insertAndParseNewChildNode( *curNode,
<a name="l00920"></a>00920                                 &amp;*digestHeaderStr,
<a name="l00921"></a>00921                                 <span class="stringliteral">"Digest Header"</span>, <span class="keyword">true</span> );
<a name="l00922"></a>00922     <span class="comment">//mReader-&gt;queueHtml("&lt;br&gt;&lt;hr&gt;&lt;br&gt;");</span>
<a name="l00923"></a>00923     <span class="comment">// temporarily change curent node's Content-Type</span>
<a name="l00924"></a>00924     <span class="comment">// to get our embedded RfC822 messages properly inserted</span>
<a name="l00925"></a>00925     curNode-&gt;setType(    DwMime::kTypeMultipart );
<a name="l00926"></a>00926     curNode-&gt;setSubType( DwMime::kSubtypeDigest );
<a name="l00927"></a>00927     <span class="keywordflow">while</span>( -1 &lt; nextDelim ){
<a name="l00928"></a>00928       <span class="keywordtype">int</span> thisEoL = cstr.find(<span class="stringliteral">"\nMessage:"</span>, thisDelim, <span class="keyword">false</span>);
<a name="l00929"></a>00929       <span class="keywordflow">if</span> ( -1 &lt; thisEoL )
<a name="l00930"></a>00930         thisDelim = thisEoL+1;
<a name="l00931"></a>00931       <span class="keywordflow">else</span>{
<a name="l00932"></a>00932         thisEoL = cstr.find(<span class="stringliteral">"\n_____________"</span>, thisDelim, <span class="keyword">false</span>);
<a name="l00933"></a>00933         <span class="keywordflow">if</span> ( -1 &lt; thisEoL )
<a name="l00934"></a>00934           thisDelim = thisEoL+1;
<a name="l00935"></a>00935       }
<a name="l00936"></a>00936       thisEoL = cstr.find(<span class="charliteral">'\n'</span>, thisDelim);
<a name="l00937"></a>00937       <span class="keywordflow">if</span> ( -1 &lt; thisEoL )
<a name="l00938"></a>00938         thisDelim = thisEoL+1;
<a name="l00939"></a>00939       <span class="keywordflow">else</span>
<a name="l00940"></a>00940         thisDelim = thisDelim+1;
<a name="l00941"></a>00941       <span class="comment">//while( thisDelim &lt; cstr.size() &amp;&amp; '\n' == cstr[thisDelim] )</span>
<a name="l00942"></a>00942       <span class="comment">//  ++thisDelim;</span>
<a name="l00943"></a>00943 
<a name="l00944"></a>00944       partStr = <span class="stringliteral">"Content-Type=message/rfc822\nContent-Description=embedded message\n"</span>;
<a name="l00945"></a>00945       partStr += cstr.mid( thisDelim, nextDelim-thisDelim );
<a name="l00946"></a>00946       QCString subject(<span class="stringliteral">"embedded message"</span>);
<a name="l00947"></a>00947       QCString subSearch(<span class="stringliteral">"\nSubject:"</span>);
<a name="l00948"></a>00948       <span class="keywordtype">int</span> subPos = partStr.find(subSearch, 0, <span class="keyword">false</span>);
<a name="l00949"></a>00949       <span class="keywordflow">if</span> ( -1 &lt; subPos ){
<a name="l00950"></a>00950         subject = partStr.mid(subPos+subSearch.length());
<a name="l00951"></a>00951         thisEoL = subject.find(<span class="charliteral">'\n'</span>);
<a name="l00952"></a>00952         <span class="keywordflow">if</span> ( -1 &lt; thisEoL )
<a name="l00953"></a>00953           subject.truncate( thisEoL );
<a name="l00954"></a>00954       }
<a name="l00955"></a>00955       kdDebug(5006) &lt;&lt; <span class="stringliteral">"        embedded message found: \""</span> &lt;&lt; subject &lt;&lt; <span class="stringliteral">"\""</span> &lt;&lt; endl;
<a name="l00956"></a>00956       insertAndParseNewChildNode( *curNode,
<a name="l00957"></a>00957                                   &amp;*partStr,
<a name="l00958"></a>00958                                   subject, <span class="keyword">true</span> );
<a name="l00959"></a>00959       <span class="comment">//mReader-&gt;queueHtml("&lt;br&gt;&lt;hr&gt;&lt;br&gt;");</span>
<a name="l00960"></a>00960       thisDelim = nextDelim+1;
<a name="l00961"></a>00961       nextDelim = cstr.find(delim1, thisDelim, <span class="keyword">false</span>);
<a name="l00962"></a>00962       <span class="keywordflow">if</span> ( -1 == nextDelim )
<a name="l00963"></a>00963         nextDelim = cstr.find(delim2, thisDelim, <span class="keyword">false</span>);
<a name="l00964"></a>00964       <span class="keywordflow">if</span> ( -1 == nextDelim )
<a name="l00965"></a>00965         nextDelim = cstr.find(delimZ1, thisDelim, <span class="keyword">false</span>);
<a name="l00966"></a>00966       <span class="keywordflow">if</span> ( -1 == nextDelim )
<a name="l00967"></a>00967         nextDelim = cstr.find(delimZ2, thisDelim, <span class="keyword">false</span>);
<a name="l00968"></a>00968     }
<a name="l00969"></a>00969     <span class="comment">// reset curent node's Content-Type</span>
<a name="l00970"></a>00970     curNode-&gt;setType(    DwMime::kTypeText );
<a name="l00971"></a>00971     curNode-&gt;setSubType( DwMime::kSubtypePlain );
<a name="l00972"></a>00972     <span class="keywordtype">int</span> thisEoL = cstr.find(<span class="stringliteral">"_____________"</span>, thisDelim);
<a name="l00973"></a>00973     <span class="keywordflow">if</span> ( -1 &lt; thisEoL ){
<a name="l00974"></a>00974       thisDelim = thisEoL;
<a name="l00975"></a>00975       thisEoL = cstr.find(<span class="charliteral">'\n'</span>, thisDelim);
<a name="l00976"></a>00976       <span class="keywordflow">if</span> ( -1 &lt; thisEoL )
<a name="l00977"></a>00977         thisDelim = thisEoL+1;
<a name="l00978"></a>00978     }
<a name="l00979"></a>00979     <span class="keywordflow">else</span>
<a name="l00980"></a>00980       thisDelim = thisDelim+1;
<a name="l00981"></a>00981     partStr = <span class="stringliteral">"Content-Type=text/plain\nContent-Description=digest footer\n\n"</span>;
<a name="l00982"></a>00982     partStr += cstr.mid( thisDelim );
<a name="l00983"></a>00983     insertAndParseNewChildNode( *curNode,
<a name="l00984"></a>00984                                 &amp;*partStr,
<a name="l00985"></a>00985                                 <span class="stringliteral">"Digest Footer"</span>, <span class="keyword">true</span> );
<a name="l00986"></a>00986     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00987"></a>00987   }
<a name="l00988"></a>00988 
<a name="l00989"></a>00989   <span class="keywordtype">bool</span> ObjectTreeParser::processTextPlainSubtype( partNode * curNode, ProcessResult &amp; result ) {
<a name="l00990"></a>00990     <span class="keywordflow">if</span> ( !mReader ) {
<a name="l00991"></a>00991       mRawReplyString = curNode-&gt;msgPart().bodyDecoded();
<a name="l00992"></a>00992       <span class="keywordflow">if</span> ( curNode-&gt;isFirstTextPart() ) {
<a name="l00993"></a>00993         mTextualContent += curNode-&gt;msgPart().bodyToUnicode();
<a name="l00994"></a>00994         mTextualContentCharset = curNode-&gt;msgPart().charset();
<a name="l00995"></a>00995       }
<a name="l00996"></a>00996       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00997"></a>00997     }
<a name="l00998"></a>00998 
<a name="l00999"></a>00999     <span class="keywordflow">if</span> ( !curNode-&gt;isFirstTextPart() &amp;&amp;
<a name="l01000"></a>01000          attachmentStrategy()-&gt;defaultDisplay( curNode ) != AttachmentStrategy::Inline &amp;&amp;
<a name="l01001"></a>01001          !showOnlyOneMimePart() )
<a name="l01002"></a>01002       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01003"></a>01003 
<a name="l01004"></a>01004     mRawReplyString = curNode-&gt;msgPart().bodyDecoded();
<a name="l01005"></a>01005     <span class="keywordflow">if</span> ( curNode-&gt;isFirstTextPart() ) {
<a name="l01006"></a>01006       mTextualContent += curNode-&gt;msgPart().bodyToUnicode();
<a name="l01007"></a>01007       mTextualContentCharset = curNode-&gt;msgPart().charset();
<a name="l01008"></a>01008     }
<a name="l01009"></a>01009 
<a name="l01010"></a>01010     QString label = curNode-&gt;msgPart().fileName().stripWhiteSpace();
<a name="l01011"></a>01011     <span class="keywordflow">if</span> ( label.isEmpty() )
<a name="l01012"></a>01012       label = curNode-&gt;msgPart().name().stripWhiteSpace();
<a name="l01013"></a>01013 
<a name="l01014"></a>01014     <span class="keyword">const</span> <span class="keywordtype">bool</span> bDrawFrame = !curNode-&gt;isFirstTextPart()
<a name="l01015"></a>01015                           &amp;&amp; !showOnlyOneMimePart()
<a name="l01016"></a>01016                           &amp;&amp; !label.isEmpty();
<a name="l01017"></a>01017     <span class="keywordflow">if</span> ( bDrawFrame ) {
<a name="l01018"></a>01018       label = <a class="code" href="classKMMessage.html#204f475a310143d5d6cf0aa8a7df55a5" title="Quotes the following characters which have a special meaning in HTML: &amp;#39;&amp;lt;&amp;#39;...">KMMessage::quoteHtmlChars</a>( label, <span class="keyword">true</span> );
<a name="l01019"></a>01019 
<a name="l01020"></a>01020       <span class="keyword">const</span> QString comment =
<a name="l01021"></a>01021         <a class="code" href="classKMMessage.html#204f475a310143d5d6cf0aa8a7df55a5" title="Quotes the following characters which have a special meaning in HTML: &amp;#39;&amp;lt;&amp;#39;...">KMMessage::quoteHtmlChars</a>( curNode-&gt;msgPart().contentDescription(), true );
<a name="l01022"></a>01022 
<a name="l01023"></a>01023       <span class="keyword">const</span> QString fileName =
<a name="l01024"></a>01024         mReader-&gt;writeMessagePartToTempFile( &amp;curNode-&gt;msgPart(),
<a name="l01025"></a>01025                                              curNode-&gt;nodeId() );
<a name="l01026"></a>01026 
<a name="l01027"></a>01027       <span class="keyword">const</span> QString dir = QApplication::reverseLayout() ? <span class="stringliteral">"rtl"</span> : <span class="stringliteral">"ltr"</span> ;
<a name="l01028"></a>01028 
<a name="l01029"></a>01029       QString htmlStr = <span class="stringliteral">"&lt;table cellspacing=\"1\" class=\"textAtm\"&gt;"</span>
<a name="l01030"></a>01030                  <span class="stringliteral">"&lt;tr class=\"textAtmH\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span>;
<a name="l01031"></a>01031       <span class="keywordflow">if</span> ( !fileName.isEmpty() )
<a name="l01032"></a>01032         htmlStr += <span class="stringliteral">"&lt;a href=\""</span> + QString(<span class="stringliteral">"file:"</span>)
<a name="l01033"></a>01033           + KURL::encode_string( fileName ) + <span class="stringliteral">"\"&gt;"</span>
<a name="l01034"></a>01034           + label + <span class="stringliteral">"&lt;/a&gt;"</span>;
<a name="l01035"></a>01035       <span class="keywordflow">else</span>
<a name="l01036"></a>01036         htmlStr += label;
<a name="l01037"></a>01037       <span class="keywordflow">if</span> ( !comment.isEmpty() )
<a name="l01038"></a>01038         htmlStr += <span class="stringliteral">"&lt;br&gt;"</span> + comment;
<a name="l01039"></a>01039       htmlStr += <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\"textAtmB\"&gt;&lt;td&gt;"</span>;
<a name="l01040"></a>01040 
<a name="l01041"></a>01041       htmlWriter()-&gt;queue( htmlStr );
<a name="l01042"></a>01042     }
<a name="l01043"></a>01043     <span class="comment">// process old style not-multipart Mailman messages to</span>
<a name="l01044"></a>01044     <span class="comment">// enable verification of the embedded messages' signatures</span>
<a name="l01045"></a>01045     <span class="keywordflow">if</span> ( !isMailmanMessage( curNode ) ||
<a name="l01046"></a>01046          !processMailmanMessage( curNode ) )
<a name="l01047"></a>01047       writeBodyString( mRawReplyString, curNode-&gt;trueFromAddress(),
<a name="l01048"></a>01048                        codecFor( curNode ), result, !bDrawFrame );
<a name="l01049"></a>01049     <span class="keywordflow">if</span> ( bDrawFrame )
<a name="l01050"></a>01050       htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"</span> );
<a name="l01051"></a>01051 
<a name="l01052"></a>01052     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01053"></a>01053   }
<a name="l01054"></a>01054 
<a name="l01055"></a>01055   <span class="keywordtype">void</span> ObjectTreeParser::stdChildHandling( partNode * child ) {
<a name="l01056"></a>01056     <span class="keywordflow">if</span> ( !child )
<a name="l01057"></a>01057       <span class="keywordflow">return</span>;
<a name="l01058"></a>01058 
<a name="l01059"></a>01059     ObjectTreeParser otp( *<span class="keyword">this</span> );
<a name="l01060"></a>01060     otp.setShowOnlyOneMimePart( <span class="keyword">false</span> );
<a name="l01061"></a>01061     otp.parseObjectTree( child );
<a name="l01062"></a>01062     mRawReplyString += otp.rawReplyString();
<a name="l01063"></a>01063     mTextualContent += otp.textualContent();
<a name="l01064"></a>01064     <span class="keywordflow">if</span> ( !otp.textualContentCharset().isEmpty() )
<a name="l01065"></a>01065       mTextualContentCharset = otp.textualContentCharset();
<a name="l01066"></a>01066   }
<a name="l01067"></a>01067 
<a name="l01068"></a>01068   <span class="keywordtype">bool</span> ObjectTreeParser::processMultiPartMixedSubtype( partNode * node, ProcessResult &amp; ) {
<a name="l01069"></a>01069     partNode * child = node-&gt;firstChild();
<a name="l01070"></a>01070     <span class="keywordflow">if</span> ( !child )
<a name="l01071"></a>01071       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01072"></a>01072 
<a name="l01073"></a>01073     <span class="comment">// normal treatment of the parts in the mp/mixed container</span>
<a name="l01074"></a>01074     stdChildHandling( child );
<a name="l01075"></a>01075     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01076"></a>01076   }
<a name="l01077"></a>01077 
<a name="l01078"></a>01078   <span class="keywordtype">bool</span> ObjectTreeParser::processMultiPartAlternativeSubtype( partNode * node, ProcessResult &amp; ) {
<a name="l01079"></a>01079     partNode * child = node-&gt;firstChild();
<a name="l01080"></a>01080     <span class="keywordflow">if</span> ( !child )
<a name="l01081"></a>01081       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01082"></a>01082 
<a name="l01083"></a>01083     partNode * dataHtml = child-&gt;findType( DwMime::kTypeText,
<a name="l01084"></a>01084                                            DwMime::kSubtypeHtml, <span class="keyword">false</span>, <span class="keyword">true</span> );
<a name="l01085"></a>01085     partNode * dataPlain = child-&gt;findType( DwMime::kTypeText,
<a name="l01086"></a>01086                                             DwMime::kSubtypePlain, <span class="keyword">false</span>, <span class="keyword">true</span> );
<a name="l01087"></a>01087 
<a name="l01088"></a>01088     <span class="keywordflow">if</span> ( (mReader &amp;&amp; mReader-&gt;htmlMail() &amp;&amp; dataHtml) ||
<a name="l01089"></a>01089          (dataHtml &amp;&amp; dataPlain &amp;&amp; dataPlain-&gt;msgPart().body().isEmpty()) ) {
<a name="l01090"></a>01090       <span class="keywordflow">if</span> ( dataPlain )
<a name="l01091"></a>01091         dataPlain-&gt;setProcessed( <span class="keyword">true</span>, <span class="keyword">false</span> );
<a name="l01092"></a>01092       stdChildHandling( dataHtml );
<a name="l01093"></a>01093       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01094"></a>01094     }
<a name="l01095"></a>01095 
<a name="l01096"></a>01096     <span class="keywordflow">if</span> ( !mReader || (!mReader-&gt;htmlMail() &amp;&amp; dataPlain) ) {
<a name="l01097"></a>01097       <span class="keywordflow">if</span> ( dataHtml )
<a name="l01098"></a>01098         dataHtml-&gt;setProcessed( <span class="keyword">true</span>, <span class="keyword">false</span> );
<a name="l01099"></a>01099       stdChildHandling( dataPlain );
<a name="l01100"></a>01100       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01101"></a>01101     }
<a name="l01102"></a>01102 
<a name="l01103"></a>01103     stdChildHandling( child );
<a name="l01104"></a>01104     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01105"></a>01105   }
<a name="l01106"></a>01106 
<a name="l01107"></a>01107   <span class="keywordtype">bool</span> ObjectTreeParser::processMultiPartDigestSubtype( partNode * node, ProcessResult &amp; result ) {
<a name="l01108"></a>01108     <span class="keywordflow">return</span> processMultiPartMixedSubtype( node, result );
<a name="l01109"></a>01109   }
<a name="l01110"></a>01110 
<a name="l01111"></a>01111   <span class="keywordtype">bool</span> ObjectTreeParser::processMultiPartParallelSubtype( partNode * node, ProcessResult &amp; result ) {
<a name="l01112"></a>01112     <span class="keywordflow">return</span> processMultiPartMixedSubtype( node, result );
<a name="l01113"></a>01113   }
<a name="l01114"></a>01114 
<a name="l01115"></a>01115   <span class="keywordtype">bool</span> ObjectTreeParser::processMultiPartSignedSubtype( partNode * node, ProcessResult &amp; ) {
<a name="l01116"></a>01116     <span class="keywordflow">if</span> ( node-&gt;childCount() != 2 ) {
<a name="l01117"></a>01117       kdDebug(5006) &lt;&lt; <span class="stringliteral">"mulitpart/signed must have exactly two child parts!"</span> &lt;&lt; endl
<a name="l01118"></a>01118                     &lt;&lt; <span class="stringliteral">"processing as multipart/mixed"</span> &lt;&lt; endl;
<a name="l01119"></a>01119       <span class="keywordflow">if</span> ( node-&gt;firstChild() )
<a name="l01120"></a>01120         stdChildHandling( node-&gt;firstChild() );
<a name="l01121"></a>01121       <span class="keywordflow">return</span> node-&gt;firstChild();
<a name="l01122"></a>01122     }
<a name="l01123"></a>01123 
<a name="l01124"></a>01124     partNode * signedData = node-&gt;firstChild();
<a name="l01125"></a>01125     assert( signedData );
<a name="l01126"></a>01126 
<a name="l01127"></a>01127     partNode * signature = signedData-&gt;nextSibling();
<a name="l01128"></a>01128     assert( signature );
<a name="l01129"></a>01129 
<a name="l01130"></a>01130     signature-&gt;setProcessed( <span class="keyword">true</span>, <span class="keyword">true</span> );
<a name="l01131"></a>01131 
<a name="l01132"></a>01132     <span class="keywordflow">if</span> ( !includeSignatures() ) {
<a name="l01133"></a>01133       stdChildHandling( signedData );
<a name="l01134"></a>01134       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01135"></a>01135     }
<a name="l01136"></a>01136 
<a name="l01137"></a>01137     <span class="comment">// FIXME(marc) check here that the protocol parameter matches the</span>
<a name="l01138"></a>01138     <span class="comment">// mimetype of "signature" (not required by the RFC, but practised</span>
<a name="l01139"></a>01139     <span class="comment">// by all implementaions of security multiparts</span>
<a name="l01140"></a>01140 
<a name="l01141"></a>01141     <span class="keyword">const</span> QString contentType = node-&gt;contentTypeParameter( <span class="stringliteral">"protocol"</span> ).lower();
<a name="l01142"></a>01142     <span class="keyword">const</span> Kleo::CryptoBackend::Protocol *protocol = 0;
<a name="l01143"></a>01143     <span class="keywordflow">if</span> ( contentType == <span class="stringliteral">"application/pkcs7-signature"</span> || contentType == <span class="stringliteral">"application/x-pkcs7-signature"</span> )
<a name="l01144"></a>01144       protocol = Kleo::CryptoBackendFactory::instance()-&gt;smime();
<a name="l01145"></a>01145     <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( contentType == <span class="stringliteral">"application/pgp-signature"</span> || contentType == <span class="stringliteral">"application/x-pgp-signature"</span> )
<a name="l01146"></a>01146       protocol = Kleo::CryptoBackendFactory::instance()-&gt;openpgp();
<a name="l01147"></a>01147 
<a name="l01148"></a>01148     <span class="keywordflow">if</span> ( !protocol ) {
<a name="l01149"></a>01149       signature-&gt;setProcessed( <span class="keyword">true</span>, <span class="keyword">true</span> );
<a name="l01150"></a>01150       stdChildHandling( signedData );
<a name="l01151"></a>01151       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01152"></a>01152     }
<a name="l01153"></a>01153 
<a name="l01154"></a>01154     CryptoProtocolSaver saver( <span class="keyword">this</span>, protocol );
<a name="l01155"></a>01155 
<a name="l01156"></a>01156     node-&gt;setSignatureState( KMMsgFullySigned );
<a name="l01157"></a>01157     writeOpaqueOrMultipartSignedData( signedData, *signature,
<a name="l01158"></a>01158                                       node-&gt;trueFromAddress() );
<a name="l01159"></a>01159     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01160"></a>01160   }
<a name="l01161"></a>01161 
<a name="l01162"></a>01162   <span class="keywordtype">bool</span> ObjectTreeParser::processMultiPartEncryptedSubtype( partNode * node, ProcessResult &amp; result ) {
<a name="l01163"></a>01163     partNode * child = node-&gt;firstChild();
<a name="l01164"></a>01164     <span class="keywordflow">if</span> ( !child )
<a name="l01165"></a>01165       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01166"></a>01166 
<a name="l01167"></a>01167     <span class="keywordflow">if</span> ( keepEncryptions() ) {
<a name="l01168"></a>01168       node-&gt;setEncryptionState( KMMsgFullyEncrypted );
<a name="l01169"></a>01169       <span class="keyword">const</span> QCString cstr = node-&gt;msgPart().bodyDecoded();
<a name="l01170"></a>01170       <span class="keywordflow">if</span> ( mReader )
<a name="l01171"></a>01171         writeBodyString( cstr, node-&gt;trueFromAddress(),
<a name="l01172"></a>01172                          codecFor( node ), result, false );
<a name="l01173"></a>01173       mRawReplyString += cstr;
<a name="l01174"></a>01174       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01175"></a>01175     }
<a name="l01176"></a>01176 
<a name="l01177"></a>01177     <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * useThisCryptProto = 0;
<a name="l01178"></a>01178 
<a name="l01179"></a>01179     <span class="comment">/*</span>
<a name="l01180"></a>01180 <span class="comment">      ATTENTION: This code is to be replaced by the new 'auto-detect' feature. --------------------------------------</span>
<a name="l01181"></a>01181 <span class="comment">    */</span>
<a name="l01182"></a>01182     partNode * data = child-&gt;findType( DwMime::kTypeApplication,
<a name="l01183"></a>01183                                        DwMime::kSubtypeOctetStream, <span class="keyword">false</span>, <span class="keyword">true</span> );
<a name="l01184"></a>01184     <span class="keywordflow">if</span> ( data ) {
<a name="l01185"></a>01185       useThisCryptProto = Kleo::CryptoBackendFactory::instance()-&gt;openpgp();
<a name="l01186"></a>01186     }
<a name="l01187"></a>01187     <span class="keywordflow">if</span> ( !data ) {
<a name="l01188"></a>01188       data = child-&gt;findType( DwMime::kTypeApplication,
<a name="l01189"></a>01189                               DwMime::kSubtypePkcs7Mime, <span class="keyword">false</span>, <span class="keyword">true</span> );
<a name="l01190"></a>01190       <span class="keywordflow">if</span> ( data ) {
<a name="l01191"></a>01191         useThisCryptProto = Kleo::CryptoBackendFactory::instance()-&gt;smime();
<a name="l01192"></a>01192       }
<a name="l01193"></a>01193     }
<a name="l01194"></a>01194     <span class="comment">/*</span>
<a name="l01195"></a>01195 <span class="comment">      ---------------------------------------------------------------------------------------------------------------</span>
<a name="l01196"></a>01196 <span class="comment">    */</span>
<a name="l01197"></a>01197 
<a name="l01198"></a>01198     <span class="keywordflow">if</span> ( !data ) {
<a name="l01199"></a>01199       stdChildHandling( child );
<a name="l01200"></a>01200       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01201"></a>01201     }
<a name="l01202"></a>01202 
<a name="l01203"></a>01203     CryptoProtocolSaver cpws( <span class="keyword">this</span>, useThisCryptProto );
<a name="l01204"></a>01204 
<a name="l01205"></a>01205     <span class="keywordflow">if</span> ( partNode * dataChild = data-&gt;firstChild() ) {
<a name="l01206"></a>01206       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Calling parseObjectTree( curNode-&gt;mChild )\n"</span> &lt;&lt; endl;
<a name="l01207"></a>01207       stdChildHandling( dataChild );
<a name="l01208"></a>01208       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Returning from parseObjectTree( curNode-&gt;mChild )\n"</span> &lt;&lt; endl;
<a name="l01209"></a>01209       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01210"></a>01210     }
<a name="l01211"></a>01211 
<a name="l01212"></a>01212     kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Initially processing encrypted data\n"</span> &lt;&lt; endl;
<a name="l01213"></a>01213     PartMetaData messagePart;
<a name="l01214"></a>01214     node-&gt;setEncryptionState( KMMsgFullyEncrypted );
<a name="l01215"></a>01215     QCString decryptedData;
<a name="l01216"></a>01216     <span class="keywordtype">bool</span> signatureFound;
<a name="l01217"></a>01217     std::vector&lt;GpgME::Signature&gt; signatures;
<a name="l01218"></a>01218     <span class="keywordtype">bool</span> passphraseError;
<a name="l01219"></a>01219     <span class="keywordtype">bool</span> actuallyEncrypted = <span class="keyword">true</span>;
<a name="l01220"></a>01220 
<a name="l01221"></a>01221     <span class="keywordtype">bool</span> bOkDecrypt = okDecryptMIME( *data,
<a name="l01222"></a>01222                                      decryptedData,
<a name="l01223"></a>01223                                      signatureFound,
<a name="l01224"></a>01224                                      signatures,
<a name="l01225"></a>01225                                      <span class="keyword">true</span>,
<a name="l01226"></a>01226                                      passphraseError,
<a name="l01227"></a>01227                                      actuallyEncrypted,
<a name="l01228"></a>01228                                      messagePart.errorText,
<a name="l01229"></a>01229                                      messagePart.auditLog );
<a name="l01230"></a>01230 
<a name="l01231"></a>01231     <span class="comment">// paint the frame</span>
<a name="l01232"></a>01232     <span class="keywordflow">if</span> ( mReader ) {
<a name="l01233"></a>01233       messagePart.isDecryptable = bOkDecrypt;
<a name="l01234"></a>01234       messagePart.isEncrypted = <span class="keyword">true</span>;
<a name="l01235"></a>01235       messagePart.isSigned = <span class="keyword">false</span>;
<a name="l01236"></a>01236       htmlWriter()-&gt;queue( writeSigstatHeader( messagePart,
<a name="l01237"></a>01237                                                cryptoProtocol(),
<a name="l01238"></a>01238                                                node-&gt;trueFromAddress() ) );
<a name="l01239"></a>01239     }
<a name="l01240"></a>01240 
<a name="l01241"></a>01241     <span class="keywordflow">if</span> ( bOkDecrypt ) {
<a name="l01242"></a>01242       <span class="comment">// Note: Multipart/Encrypted might also be signed</span>
<a name="l01243"></a>01243       <span class="comment">//       without encapsulating a nicely formatted</span>
<a name="l01244"></a>01244       <span class="comment">//       ~~~~~~~                 Multipart/Signed part.</span>
<a name="l01245"></a>01245       <span class="comment">//                               (see RFC 3156 --&gt; 6.2)</span>
<a name="l01246"></a>01246       <span class="comment">// In this case we paint a _2nd_ frame inside the</span>
<a name="l01247"></a>01247       <span class="comment">// encryption frame, but we do _not_ show a respective</span>
<a name="l01248"></a>01248       <span class="comment">// encapsulated MIME part in the Mime Tree Viewer</span>
<a name="l01249"></a>01249       <span class="comment">// since we do want to show the _true_ structure of the</span>
<a name="l01250"></a>01250       <span class="comment">// message there - not the structure that the sender's</span>
<a name="l01251"></a>01251       <span class="comment">// MUA 'should' have sent.  :-D       (khz, 12.09.2002)</span>
<a name="l01252"></a>01252       <span class="comment">//</span>
<a name="l01253"></a>01253       <span class="keywordflow">if</span> ( signatureFound ) {
<a name="l01254"></a>01254         writeOpaqueOrMultipartSignedData( 0,
<a name="l01255"></a>01255                                           *node,
<a name="l01256"></a>01256                                           node-&gt;trueFromAddress(),
<a name="l01257"></a>01257                                           <span class="keyword">false</span>,
<a name="l01258"></a>01258                                           &amp;decryptedData,
<a name="l01259"></a>01259                                           signatures,
<a name="l01260"></a>01260                                           false );
<a name="l01261"></a>01261         node-&gt;setSignatureState( KMMsgFullySigned );
<a name="l01262"></a>01262       } <span class="keywordflow">else</span> {
<a name="l01263"></a>01263         insertAndParseNewChildNode( *node,
<a name="l01264"></a>01264                                     &amp;*decryptedData,
<a name="l01265"></a>01265                                     <span class="stringliteral">"encrypted data"</span> );
<a name="l01266"></a>01266       }
<a name="l01267"></a>01267     } <span class="keywordflow">else</span> {
<a name="l01268"></a>01268       mRawReplyString += decryptedData;
<a name="l01269"></a>01269       <span class="keywordflow">if</span> ( mReader ) {
<a name="l01270"></a>01270         <span class="comment">// print the error message that was returned in decryptedData</span>
<a name="l01271"></a>01271         <span class="comment">// (utf8-encoded)</span>
<a name="l01272"></a>01272         htmlWriter()-&gt;queue( QString::fromUtf8( decryptedData.data() ) );
<a name="l01273"></a>01273       }
<a name="l01274"></a>01274     }
<a name="l01275"></a>01275 
<a name="l01276"></a>01276     <span class="keywordflow">if</span> ( mReader )
<a name="l01277"></a>01277       htmlWriter()-&gt;queue( writeSigstatFooter( messagePart ) );
<a name="l01278"></a>01278     data-&gt;setProcessed( <span class="keyword">true</span>, <span class="keyword">false</span> ); <span class="comment">// Set the data node to done to prevent it from being processed</span>
<a name="l01279"></a>01279     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01280"></a>01280   }
<a name="l01281"></a>01281 
<a name="l01282"></a>01282 
<a name="l01283"></a>01283   <span class="keywordtype">bool</span> ObjectTreeParser::processMessageRfc822Subtype( partNode * node, ProcessResult &amp; ) {
<a name="l01284"></a>01284     <span class="keywordflow">if</span> ( mReader
<a name="l01285"></a>01285          &amp;&amp; !attachmentStrategy()-&gt;inlineNestedMessages()
<a name="l01286"></a>01286          &amp;&amp; !showOnlyOneMimePart() )
<a name="l01287"></a>01287       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01288"></a>01288 
<a name="l01289"></a>01289     <span class="keywordflow">if</span> ( partNode * child = node-&gt;firstChild() ) {
<a name="l01290"></a>01290       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Calling parseObjectTree( curNode-&gt;mChild )\n"</span> &lt;&lt; endl;
<a name="l01291"></a>01291       ObjectTreeParser otp( mReader, cryptoProtocol() );
<a name="l01292"></a>01292       otp.parseObjectTree( child );
<a name="l01293"></a>01293       mRawReplyString += otp.rawReplyString();
<a name="l01294"></a>01294       mTextualContent += otp.textualContent();
<a name="l01295"></a>01295       <span class="keywordflow">if</span> ( !otp.textualContentCharset().isEmpty() )
<a name="l01296"></a>01296         mTextualContentCharset = otp.textualContentCharset();
<a name="l01297"></a>01297       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n&lt;-----  Returning from parseObjectTree( curNode-&gt;mChild )\n"</span> &lt;&lt; endl;
<a name="l01298"></a>01298       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01299"></a>01299     }
<a name="l01300"></a>01300     kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Initially processing data of embedded RfC 822 message\n"</span> &lt;&lt; endl;
<a name="l01301"></a>01301     <span class="comment">// paint the frame</span>
<a name="l01302"></a>01302     PartMetaData messagePart;
<a name="l01303"></a>01303     <span class="keywordflow">if</span> ( mReader ) {
<a name="l01304"></a>01304       messagePart.isEncrypted = <span class="keyword">false</span>;
<a name="l01305"></a>01305       messagePart.isSigned = <span class="keyword">false</span>;
<a name="l01306"></a>01306       messagePart.isEncapsulatedRfc822Message = <span class="keyword">true</span>;
<a name="l01307"></a>01307       QString filename =
<a name="l01308"></a>01308         mReader-&gt;writeMessagePartToTempFile( &amp;node-&gt;msgPart(),
<a name="l01309"></a>01309                                             node-&gt;nodeId() );
<a name="l01310"></a>01310       htmlWriter()-&gt;queue( writeSigstatHeader( messagePart,
<a name="l01311"></a>01311                                                cryptoProtocol(),
<a name="l01312"></a>01312                                                node-&gt;trueFromAddress(),
<a name="l01313"></a>01313                                                filename ) );
<a name="l01314"></a>01314     }
<a name="l01315"></a>01315     QCString rfc822messageStr( node-&gt;msgPart().bodyDecoded() );
<a name="l01316"></a>01316     <span class="comment">// display the headers of the encapsulated message</span>
<a name="l01317"></a>01317     DwMessage* rfc822DwMessage = <span class="keyword">new</span> DwMessage(); <span class="comment">// will be deleted by c'tor of rfc822headers</span>
<a name="l01318"></a>01318     rfc822DwMessage-&gt;FromString( rfc822messageStr );
<a name="l01319"></a>01319     rfc822DwMessage-&gt;Parse();
<a name="l01320"></a>01320     <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a> rfc822message( rfc822DwMessage );
<a name="l01321"></a>01321     node-&gt;setFromAddress( rfc822message.from() );
<a name="l01322"></a>01322     kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Store RfC 822 message header \"From: "</span> &lt;&lt; rfc822message.from() &lt;&lt; <span class="stringliteral">"\"\n"</span> &lt;&lt; endl;
<a name="l01323"></a>01323     <span class="keywordflow">if</span> ( mReader )
<a name="l01324"></a>01324       htmlWriter()-&gt;queue( mReader-&gt;writeMsgHeader( &amp;rfc822message ) );
<a name="l01325"></a>01325       <span class="comment">//mReader-&gt;parseMsgHeader( &amp;rfc822message );</span>
<a name="l01326"></a>01326     <span class="comment">// display the body of the encapsulated message</span>
<a name="l01327"></a>01327     insertAndParseNewChildNode( *node,
<a name="l01328"></a>01328                                 &amp;*rfc822messageStr,
<a name="l01329"></a>01329                                 <span class="stringliteral">"encapsulated message"</span> );
<a name="l01330"></a>01330     <span class="keywordflow">if</span> ( mReader )
<a name="l01331"></a>01331       htmlWriter()-&gt;queue( writeSigstatFooter( messagePart ) );
<a name="l01332"></a>01332     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01333"></a>01333   }
<a name="l01334"></a>01334 
<a name="l01335"></a>01335 
<a name="l01336"></a>01336   <span class="keywordtype">bool</span> ObjectTreeParser::processApplicationOctetStreamSubtype( partNode * node, ProcessResult &amp; result ) {
<a name="l01337"></a>01337     <span class="keywordflow">if</span> ( partNode * child = node-&gt;firstChild() ) {
<a name="l01338"></a>01338       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Calling parseObjectTree( curNode-&gt;mChild )\n"</span> &lt;&lt; endl;
<a name="l01339"></a>01339       ObjectTreeParser otp( mReader, cryptoProtocol() );
<a name="l01340"></a>01340       otp.parseObjectTree( child );
<a name="l01341"></a>01341       mRawReplyString += otp.rawReplyString();
<a name="l01342"></a>01342       mTextualContent += otp.textualContent();
<a name="l01343"></a>01343       <span class="keywordflow">if</span> ( !otp.textualContentCharset().isEmpty() )
<a name="l01344"></a>01344         mTextualContentCharset = otp.textualContentCharset();
<a name="l01345"></a>01345       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n&lt;-----  Returning from parseObjectTree( curNode-&gt;mChild )\n"</span> &lt;&lt; endl;
<a name="l01346"></a>01346       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01347"></a>01347     }
<a name="l01348"></a>01348 
<a name="l01349"></a>01349     <span class="keyword">const</span> Kleo::CryptoBackend::Protocol* oldUseThisCryptPlug = cryptoProtocol();
<a name="l01350"></a>01350     <span class="keywordflow">if</span> (    node-&gt;parentNode()
<a name="l01351"></a>01351             &amp;&amp; DwMime::kTypeMultipart    == node-&gt;parentNode()-&gt;type()
<a name="l01352"></a>01352             &amp;&amp; DwMime::kSubtypeEncrypted == node-&gt;parentNode()-&gt;subType() ) {
<a name="l01353"></a>01353       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Initially processing encrypted data\n"</span> &lt;&lt; endl;
<a name="l01354"></a>01354       node-&gt;setEncryptionState( KMMsgFullyEncrypted );
<a name="l01355"></a>01355       <span class="keywordflow">if</span> ( keepEncryptions() ) {
<a name="l01356"></a>01356         <span class="keyword">const</span> QCString cstr = node-&gt;msgPart().bodyDecoded();
<a name="l01357"></a>01357         <span class="keywordflow">if</span> ( mReader )
<a name="l01358"></a>01358           writeBodyString( cstr, node-&gt;trueFromAddress(),
<a name="l01359"></a>01359                            codecFor( node ), result, false );
<a name="l01360"></a>01360         mRawReplyString += cstr;
<a name="l01361"></a>01361       } <span class="keywordflow">else</span> {
<a name="l01362"></a>01362         <span class="comment">/*</span>
<a name="l01363"></a>01363 <span class="comment">          ATTENTION: This code is to be replaced by the planned 'auto-detect' feature.</span>
<a name="l01364"></a>01364 <span class="comment">        */</span>
<a name="l01365"></a>01365         PartMetaData messagePart;
<a name="l01366"></a>01366         setCryptoProtocol( Kleo::CryptoBackendFactory::instance()-&gt;openpgp() );
<a name="l01367"></a>01367         QCString decryptedData;
<a name="l01368"></a>01368         <span class="keywordtype">bool</span> signatureFound;
<a name="l01369"></a>01369         std::vector&lt;GpgME::Signature&gt; signatures;
<a name="l01370"></a>01370         <span class="keywordtype">bool</span> passphraseError;
<a name="l01371"></a>01371         <span class="keywordtype">bool</span> actuallyEncrypted = <span class="keyword">true</span>;
<a name="l01372"></a>01372 
<a name="l01373"></a>01373         <span class="keywordtype">bool</span> bOkDecrypt = okDecryptMIME( *node,
<a name="l01374"></a>01374                                          decryptedData,
<a name="l01375"></a>01375                                          signatureFound,
<a name="l01376"></a>01376                                          signatures,
<a name="l01377"></a>01377                                          <span class="keyword">true</span>,
<a name="l01378"></a>01378                                          passphraseError,
<a name="l01379"></a>01379                                          actuallyEncrypted,
<a name="l01380"></a>01380                                          messagePart.errorText,
<a name="l01381"></a>01381                                          messagePart.auditLog );
<a name="l01382"></a>01382 
<a name="l01383"></a>01383         <span class="comment">// paint the frame</span>
<a name="l01384"></a>01384         <span class="keywordflow">if</span> ( mReader ) {
<a name="l01385"></a>01385           messagePart.isDecryptable = bOkDecrypt;
<a name="l01386"></a>01386           messagePart.isEncrypted = <span class="keyword">true</span>;
<a name="l01387"></a>01387           messagePart.isSigned = <span class="keyword">false</span>;
<a name="l01388"></a>01388           htmlWriter()-&gt;queue( writeSigstatHeader( messagePart,
<a name="l01389"></a>01389                                                    cryptoProtocol(),
<a name="l01390"></a>01390                                                    node-&gt;trueFromAddress() ) );
<a name="l01391"></a>01391         }
<a name="l01392"></a>01392 
<a name="l01393"></a>01393         <span class="keywordflow">if</span> ( bOkDecrypt ) {
<a name="l01394"></a>01394           <span class="comment">// fixing the missing attachments bug #1090-b</span>
<a name="l01395"></a>01395           insertAndParseNewChildNode( *node,
<a name="l01396"></a>01396                                       &amp;*decryptedData,
<a name="l01397"></a>01397                                       <span class="stringliteral">"encrypted data"</span> );
<a name="l01398"></a>01398         } <span class="keywordflow">else</span> {
<a name="l01399"></a>01399           mRawReplyString += decryptedData;
<a name="l01400"></a>01400           <span class="keywordflow">if</span> ( mReader ) {
<a name="l01401"></a>01401             <span class="comment">// print the error message that was returned in decryptedData</span>
<a name="l01402"></a>01402             <span class="comment">// (utf8-encoded)</span>
<a name="l01403"></a>01403             htmlWriter()-&gt;queue( QString::fromUtf8( decryptedData.data() ) );
<a name="l01404"></a>01404           }
<a name="l01405"></a>01405         }
<a name="l01406"></a>01406 
<a name="l01407"></a>01407         <span class="keywordflow">if</span> ( mReader )
<a name="l01408"></a>01408           htmlWriter()-&gt;queue( writeSigstatFooter( messagePart ) );
<a name="l01409"></a>01409       }
<a name="l01410"></a>01410       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01411"></a>01411     }
<a name="l01412"></a>01412     setCryptoProtocol( oldUseThisCryptPlug );
<a name="l01413"></a>01413     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01414"></a>01414   }
<a name="l01415"></a>01415 
<a name="l01416"></a>01416   <span class="keywordtype">bool</span> ObjectTreeParser::processApplicationPkcs7MimeSubtype( partNode * node, ProcessResult &amp; result ) {
<a name="l01417"></a>01417     <span class="keywordflow">if</span> ( partNode * child = node-&gt;firstChild() ) {
<a name="l01418"></a>01418       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Calling parseObjectTree( curNode-&gt;mChild )\n"</span> &lt;&lt; endl;
<a name="l01419"></a>01419       ObjectTreeParser otp( mReader, cryptoProtocol() );
<a name="l01420"></a>01420       otp.parseObjectTree( child );
<a name="l01421"></a>01421       mRawReplyString += otp.rawReplyString();
<a name="l01422"></a>01422       mTextualContent += otp.textualContent();
<a name="l01423"></a>01423       <span class="keywordflow">if</span> ( !otp.textualContentCharset().isEmpty() )
<a name="l01424"></a>01424         mTextualContentCharset = otp.textualContentCharset();
<a name="l01425"></a>01425       kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n&lt;-----  Returning from parseObjectTree( curNode-&gt;mChild )\n"</span> &lt;&lt; endl;
<a name="l01426"></a>01426       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01427"></a>01427     }
<a name="l01428"></a>01428 
<a name="l01429"></a>01429     kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n-----&gt;  Initially processing signed and/or encrypted data\n"</span> &lt;&lt; endl;
<a name="l01430"></a>01430     <span class="keywordflow">if</span> ( !node-&gt;dwPart() || !node-&gt;dwPart()-&gt;hasHeaders() )
<a name="l01431"></a>01431       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01432"></a>01432 
<a name="l01433"></a>01433     <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * smimeCrypto = Kleo::CryptoBackendFactory::instance()-&gt;smime();
<a name="l01434"></a>01434 
<a name="l01435"></a>01435     <span class="keyword">const</span> QString smimeType = node-&gt;contentTypeParameter(<span class="stringliteral">"smime-type"</span>).lower();
<a name="l01436"></a>01436 
<a name="l01437"></a>01437     <span class="keywordflow">if</span> ( smimeType == <span class="stringliteral">"certs-only"</span> ) {
<a name="l01438"></a>01438       result.setNeverDisplayInline( <span class="keyword">true</span> );
<a name="l01439"></a>01439       <span class="keywordflow">if</span> ( !smimeCrypto || !mReader )
<a name="l01440"></a>01440         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01441"></a>01441 
<a name="l01442"></a>01442       <span class="keyword">const</span> KConfigGroup reader( KMKernel::config(), <span class="stringliteral">"Reader"</span> );
<a name="l01443"></a>01443       <span class="keywordflow">if</span> ( !reader.readBoolEntry( <span class="stringliteral">"AutoImportKeys"</span>, <span class="keyword">false</span> ) )
<a name="l01444"></a>01444         <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01445"></a>01445 
<a name="l01446"></a>01446       <span class="keyword">const</span> QByteArray certData = node-&gt;msgPart().bodyDecodedBinary();
<a name="l01447"></a>01447 
<a name="l01448"></a>01448       Kleo::ImportJob *<span class="keyword">import</span> = smimeCrypto-&gt;importJob();
<a name="l01449"></a>01449       <span class="keyword">const</span> GpgME::ImportResult res = <span class="keyword">import</span>-&gt;exec( certData );
<a name="l01450"></a>01450       <span class="keywordflow">if</span> ( res.error() ) {
<a name="l01451"></a>01451         htmlWriter()-&gt;queue( i18n( <span class="stringliteral">"Sorry, certificate could not be imported.&lt;br&gt;"</span>
<a name="l01452"></a>01452                                    <span class="stringliteral">"Reason: %1"</span>).arg( QString::fromLocal8Bit( res.error().asString() ) ) );
<a name="l01453"></a>01453         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01454"></a>01454       }
<a name="l01455"></a>01455 
<a name="l01456"></a>01456       <span class="keyword">const</span> <span class="keywordtype">int</span> nImp = res.numImported();
<a name="l01457"></a>01457       <span class="keyword">const</span> <span class="keywordtype">int</span> nUnc = res.numUnchanged();
<a name="l01458"></a>01458       <span class="keyword">const</span> <span class="keywordtype">int</span> nSKImp = res.numSecretKeysImported();
<a name="l01459"></a>01459       <span class="keyword">const</span> <span class="keywordtype">int</span> nSKUnc = res.numSecretKeysUnchanged();
<a name="l01460"></a>01460       <span class="keywordflow">if</span> ( !nImp &amp;&amp; !nSKImp &amp;&amp; !nUnc &amp;&amp; !nSKUnc ) {
<a name="l01461"></a>01461         htmlWriter()-&gt;queue( i18n( <span class="stringliteral">"Sorry, no certificates were found in this message."</span> ) );
<a name="l01462"></a>01462         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01463"></a>01463       }
<a name="l01464"></a>01464       QString comment = <span class="stringliteral">"&lt;b&gt;"</span> + i18n( <span class="stringliteral">"Certificate import status:"</span> ) + <span class="stringliteral">"&lt;/b&gt;&lt;br&gt;&amp;nbsp;&lt;br&gt;"</span>;
<a name="l01465"></a>01465       <span class="keywordflow">if</span> ( nImp )
<a name="l01466"></a>01466         comment += i18n( <span class="stringliteral">"1 new certificate was imported."</span>,
<a name="l01467"></a>01467                          <span class="stringliteral">"%n new certificates were imported."</span>, nImp ) + <span class="stringliteral">"&lt;br&gt;"</span>;
<a name="l01468"></a>01468       <span class="keywordflow">if</span> ( nUnc )
<a name="l01469"></a>01469         comment += i18n( <span class="stringliteral">"1 certificate was unchanged."</span>,
<a name="l01470"></a>01470                          <span class="stringliteral">"%n certificates were unchanged."</span>, nUnc ) + <span class="stringliteral">"&lt;br&gt;"</span>;
<a name="l01471"></a>01471       <span class="keywordflow">if</span> ( nSKImp )
<a name="l01472"></a>01472         comment += i18n( <span class="stringliteral">"1 new secret key was imported."</span>,
<a name="l01473"></a>01473                          <span class="stringliteral">"%n new secret keys were imported."</span>, nSKImp ) + <span class="stringliteral">"&lt;br&gt;"</span>;
<a name="l01474"></a>01474       <span class="keywordflow">if</span> ( nSKUnc )
<a name="l01475"></a>01475         comment += i18n( <span class="stringliteral">"1 secret key was unchanged."</span>,
<a name="l01476"></a>01476                          <span class="stringliteral">"%n secret keys were unchanged."</span>, nSKUnc ) + <span class="stringliteral">"&lt;br&gt;"</span>;
<a name="l01477"></a>01477       comment += <span class="stringliteral">"&amp;nbsp;&lt;br&gt;"</span>;
<a name="l01478"></a>01478       htmlWriter()-&gt;queue( comment );
<a name="l01479"></a>01479       <span class="keywordflow">if</span> ( !nImp &amp;&amp; !nSKImp ) {
<a name="l01480"></a>01480         htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;hr&gt;"</span> );
<a name="l01481"></a>01481         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01482"></a>01482       }
<a name="l01483"></a>01483       <span class="keyword">const</span> std::vector&lt;GpgME::Import&gt; imports = res.imports();
<a name="l01484"></a>01484       <span class="keywordflow">if</span> ( imports.empty() ) {
<a name="l01485"></a>01485         htmlWriter()-&gt;queue( i18n( <span class="stringliteral">"Sorry, no details on certificate import available."</span> ) + <span class="stringliteral">"&lt;hr&gt;"</span> );
<a name="l01486"></a>01486         <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01487"></a>01487       }
<a name="l01488"></a>01488       htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;b&gt;"</span> + i18n( <span class="stringliteral">"Certificate import details:"</span> ) + <span class="stringliteral">"&lt;/b&gt;&lt;br&gt;"</span> );
<a name="l01489"></a>01489       <span class="keywordflow">for</span> ( std::vector&lt;GpgME::Import&gt;::const_iterator it = imports.begin() ; it != imports.end() ; ++it ) {
<a name="l01490"></a>01490         <span class="keywordflow">if</span> ( (*it).error() )
<a name="l01491"></a>01491           htmlWriter()-&gt;queue( i18n( <span class="stringliteral">"Failed: %1 (%2)"</span> )
<a name="l01492"></a>01492                                .arg( (*it).fingerprint(),
<a name="l01493"></a>01493                                      QString::fromLocal8Bit( (*it).error().asString() ) ) );
<a name="l01494"></a>01494         <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( (*it).status() &amp; ~GpgME::Import::ContainedSecretKey )
<a name="l01495"></a>01495           <span class="keywordflow">if</span> ( (*it).status() &amp; GpgME::Import::ContainedSecretKey )
<a name="l01496"></a>01496             htmlWriter()-&gt;queue( i18n( <span class="stringliteral">"New or changed: %1 (secret key available)"</span> ).arg( (*it).fingerprint() ) );
<a name="l01497"></a>01497           <span class="keywordflow">else</span>
<a name="l01498"></a>01498             htmlWriter()-&gt;queue( i18n( <span class="stringliteral">"New or changed: %1"</span> ).arg( (*it).fingerprint() ) );
<a name="l01499"></a>01499         htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;br&gt;"</span> );
<a name="l01500"></a>01500       }
<a name="l01501"></a>01501 
<a name="l01502"></a>01502       htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;hr&gt;"</span> );
<a name="l01503"></a>01503       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01504"></a>01504     }
<a name="l01505"></a>01505 
<a name="l01506"></a>01506     <span class="keywordflow">if</span> ( !smimeCrypto )
<a name="l01507"></a>01507       <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01508"></a>01508     CryptoProtocolSaver cpws( <span class="keyword">this</span>, smimeCrypto );
<a name="l01509"></a>01509 
<a name="l01510"></a>01510     <span class="keywordtype">bool</span> isSigned      = smimeType == <span class="stringliteral">"signed-data"</span>;
<a name="l01511"></a>01511     <span class="keywordtype">bool</span> isEncrypted   = smimeType == <span class="stringliteral">"enveloped-data"</span>;
<a name="l01512"></a>01512 
<a name="l01513"></a>01513     <span class="comment">// Analyze "signTestNode" node to find/verify a signature.</span>
<a name="l01514"></a>01514     <span class="comment">// If zero this verification was successfully done after</span>
<a name="l01515"></a>01515     <span class="comment">// decrypting via recursion by insertAndParseNewChildNode().</span>
<a name="l01516"></a>01516     partNode* signTestNode = isEncrypted ? 0 : node;
<a name="l01517"></a>01517 
<a name="l01518"></a>01518 
<a name="l01519"></a>01519     <span class="comment">// We try decrypting the content</span>
<a name="l01520"></a>01520     <span class="comment">// if we either *know* that it is an encrypted message part</span>
<a name="l01521"></a>01521     <span class="comment">// or there is neither signed nor encrypted parameter.</span>
<a name="l01522"></a>01522     <span class="keywordflow">if</span> ( !isSigned ) {
<a name="l01523"></a>01523       <span class="keywordflow">if</span> ( isEncrypted )
<a name="l01524"></a>01524         kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime     ==      S/MIME TYPE: enveloped (encrypted) data"</span> &lt;&lt; endl;
<a name="l01525"></a>01525       <span class="keywordflow">else</span>
<a name="l01526"></a>01526         kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime  -  type unknown  -  enveloped (encrypted) data ?"</span> &lt;&lt; endl;
<a name="l01527"></a>01527       QCString decryptedData;
<a name="l01528"></a>01528       PartMetaData messagePart;
<a name="l01529"></a>01529       messagePart.isEncrypted = <span class="keyword">true</span>;
<a name="l01530"></a>01530       messagePart.isSigned = <span class="keyword">false</span>;
<a name="l01531"></a>01531       <span class="keywordtype">bool</span> signatureFound;
<a name="l01532"></a>01532       std::vector&lt;GpgME::Signature&gt; signatures;
<a name="l01533"></a>01533       <span class="keywordtype">bool</span> passphraseError;
<a name="l01534"></a>01534       <span class="keywordtype">bool</span> actuallyEncrypted = <span class="keyword">true</span>;
<a name="l01535"></a>01535 
<a name="l01536"></a>01536       <span class="keywordflow">if</span> ( okDecryptMIME( *node,
<a name="l01537"></a>01537                           decryptedData,
<a name="l01538"></a>01538                           signatureFound,
<a name="l01539"></a>01539                           signatures,
<a name="l01540"></a>01540                           <span class="keyword">false</span>,
<a name="l01541"></a>01541                           passphraseError,
<a name="l01542"></a>01542                           actuallyEncrypted,
<a name="l01543"></a>01543                           messagePart.errorText,
<a name="l01544"></a>01544                           messagePart.auditLog ) ) {
<a name="l01545"></a>01545         kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime  -  encryption found  -  enveloped (encrypted) data !"</span> &lt;&lt; endl;
<a name="l01546"></a>01546         isEncrypted = <span class="keyword">true</span>;
<a name="l01547"></a>01547         node-&gt;setEncryptionState( KMMsgFullyEncrypted );
<a name="l01548"></a>01548         signTestNode = 0;
<a name="l01549"></a>01549         <span class="comment">// paint the frame</span>
<a name="l01550"></a>01550         messagePart.isDecryptable = <span class="keyword">true</span>;
<a name="l01551"></a>01551         <span class="keywordflow">if</span> ( mReader )
<a name="l01552"></a>01552           htmlWriter()-&gt;queue( writeSigstatHeader( messagePart,
<a name="l01553"></a>01553                                                    cryptoProtocol(),
<a name="l01554"></a>01554                                                    node-&gt;trueFromAddress() ) );
<a name="l01555"></a>01555         insertAndParseNewChildNode( *node,
<a name="l01556"></a>01556                                     &amp;*decryptedData,
<a name="l01557"></a>01557                                     <span class="stringliteral">"encrypted data"</span> );
<a name="l01558"></a>01558         <span class="keywordflow">if</span> ( mReader )
<a name="l01559"></a>01559           htmlWriter()-&gt;queue( writeSigstatFooter( messagePart ) );
<a name="l01560"></a>01560       } <span class="keywordflow">else</span> {
<a name="l01561"></a>01561           <span class="comment">// decryption failed, which could be because the part was encrypted but</span>
<a name="l01562"></a>01562           <span class="comment">// decryption failed, or because we didn't know if it was encrypted, tried,</span>
<a name="l01563"></a>01563           <span class="comment">// and failed. If the message was not actually encrypted, we continue</span>
<a name="l01564"></a>01564           <span class="comment">// assuming it's signed</span>
<a name="l01565"></a>01565         <span class="keywordflow">if</span> ( passphraseError || ( smimeType.isEmpty() &amp;&amp; actuallyEncrypted ) ) {
<a name="l01566"></a>01566           isEncrypted = <span class="keyword">true</span>;
<a name="l01567"></a>01567           signTestNode = 0;
<a name="l01568"></a>01568         }
<a name="l01569"></a>01569 
<a name="l01570"></a>01570         <span class="keywordflow">if</span> ( isEncrypted ) {
<a name="l01571"></a>01571           kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime  -  ERROR: COULD NOT DECRYPT enveloped data !"</span> &lt;&lt; endl;
<a name="l01572"></a>01572           <span class="comment">// paint the frame</span>
<a name="l01573"></a>01573           messagePart.isDecryptable = <span class="keyword">false</span>;
<a name="l01574"></a>01574           <span class="keywordflow">if</span> ( mReader ) {
<a name="l01575"></a>01575             htmlWriter()-&gt;queue( writeSigstatHeader( messagePart,
<a name="l01576"></a>01576                                                      cryptoProtocol(),
<a name="l01577"></a>01577                                                      node-&gt;trueFromAddress() ) );
<a name="l01578"></a>01578             <span class="keywordflow">if</span> ( mReader-&gt;decryptMessage() )
<a name="l01579"></a>01579               writePartIcon( &amp;node-&gt;msgPart(), node-&gt;nodeId() );
<a name="l01580"></a>01580             <span class="keywordflow">else</span>
<a name="l01581"></a>01581               htmlWriter()-&gt;queue( QString::fromUtf8( decryptedData ) );
<a name="l01582"></a>01582             htmlWriter()-&gt;queue( writeSigstatFooter( messagePart ) );
<a name="l01583"></a>01583           }
<a name="l01584"></a>01584         } <span class="keywordflow">else</span> {
<a name="l01585"></a>01585           kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime  -  NO encryption found"</span> &lt;&lt; endl;
<a name="l01586"></a>01586         }
<a name="l01587"></a>01587       }
<a name="l01588"></a>01588       <span class="keywordflow">if</span> ( isEncrypted )
<a name="l01589"></a>01589         node-&gt;setEncryptionState( KMMsgFullyEncrypted );
<a name="l01590"></a>01590     }
<a name="l01591"></a>01591 
<a name="l01592"></a>01592     <span class="comment">// We now try signature verification if necessarry.</span>
<a name="l01593"></a>01593     <span class="keywordflow">if</span> ( signTestNode ) {
<a name="l01594"></a>01594       <span class="keywordflow">if</span> ( isSigned )
<a name="l01595"></a>01595         kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime     ==      S/MIME TYPE: opaque signed data"</span> &lt;&lt; endl;
<a name="l01596"></a>01596       <span class="keywordflow">else</span>
<a name="l01597"></a>01597         kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime  -  type unknown  -  opaque signed data ?"</span> &lt;&lt; endl;
<a name="l01598"></a>01598 
<a name="l01599"></a>01599       <span class="keywordtype">bool</span> sigFound = writeOpaqueOrMultipartSignedData( 0,
<a name="l01600"></a>01600                                                         *signTestNode,
<a name="l01601"></a>01601                                                         node-&gt;trueFromAddress(),
<a name="l01602"></a>01602                                                         <span class="keyword">true</span>,
<a name="l01603"></a>01603                                                         0,
<a name="l01604"></a>01604                                                         std::vector&lt;GpgME::Signature&gt;(),
<a name="l01605"></a>01605                                                         isEncrypted );
<a name="l01606"></a>01606       <span class="keywordflow">if</span> ( sigFound ) {
<a name="l01607"></a>01607         <span class="keywordflow">if</span> ( !isSigned ) {
<a name="l01608"></a>01608           kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime  -  signature found  -  opaque signed data !"</span> &lt;&lt; endl;
<a name="l01609"></a>01609           isSigned = <span class="keyword">true</span>;
<a name="l01610"></a>01610         }
<a name="l01611"></a>01611         signTestNode-&gt;setSignatureState( KMMsgFullySigned );
<a name="l01612"></a>01612         <span class="keywordflow">if</span> ( signTestNode != node )
<a name="l01613"></a>01613           node-&gt;setSignatureState( KMMsgFullySigned );
<a name="l01614"></a>01614       } <span class="keywordflow">else</span> {
<a name="l01615"></a>01615         kdDebug(5006) &lt;&lt; <span class="stringliteral">"pkcs7 mime  -  NO signature found   :-("</span> &lt;&lt; endl;
<a name="l01616"></a>01616       }
<a name="l01617"></a>01617     }
<a name="l01618"></a>01618 
<a name="l01619"></a>01619     <span class="keywordflow">return</span> isSigned || isEncrypted;
<a name="l01620"></a>01620 }
<a name="l01621"></a>01621 
<a name="l01622"></a>01622 <span class="keywordtype">bool</span> ObjectTreeParser::decryptChiasmus( <span class="keyword">const</span> QByteArray&amp; data, QByteArray&amp; bodyDecoded, QString&amp; errorText )
<a name="l01623"></a>01623 {
<a name="l01624"></a>01624   <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * chiasmus =
<a name="l01625"></a>01625     Kleo::CryptoBackendFactory::instance()-&gt;protocol( <span class="stringliteral">"Chiasmus"</span> );
<a name="l01626"></a>01626   Q_ASSERT( chiasmus );
<a name="l01627"></a>01627   <span class="keywordflow">if</span> ( !chiasmus )
<a name="l01628"></a>01628     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01629"></a>01629 
<a name="l01630"></a>01630   <span class="keyword">const</span> STD_NAMESPACE_PREFIX auto_ptr&lt;Kleo::SpecialJob&gt; listjob( chiasmus-&gt;specialJob( <span class="stringliteral">"x-obtain-keys"</span>, QMap&lt;QString,QVariant&gt;() ) );
<a name="l01631"></a>01631   <span class="keywordflow">if</span> ( !listjob.get() ) {
<a name="l01632"></a>01632     errorText = i18n( <span class="stringliteral">"Chiasmus backend does not offer the "</span>
<a name="l01633"></a>01633                       <span class="stringliteral">"\"x-obtain-keys\" function. Please report this bug."</span> );
<a name="l01634"></a>01634     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01635"></a>01635   }
<a name="l01636"></a>01636 
<a name="l01637"></a>01637   <span class="keywordflow">if</span> ( listjob-&gt;exec() ) {
<a name="l01638"></a>01638     errorText = i18n( <span class="stringliteral">"Chiasmus Backend Error"</span> );
<a name="l01639"></a>01639     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01640"></a>01640   }
<a name="l01641"></a>01641 
<a name="l01642"></a>01642   <span class="keyword">const</span> QVariant result = listjob-&gt;property( <span class="stringliteral">"result"</span> );
<a name="l01643"></a>01643   <span class="keywordflow">if</span> ( result.type() != QVariant::StringList ) {
<a name="l01644"></a>01644     errorText = i18n( <span class="stringliteral">"Unexpected return value from Chiasmus backend: "</span>
<a name="l01645"></a>01645                       <span class="stringliteral">"The \"x-obtain-keys\" function did not return a "</span>
<a name="l01646"></a>01646                       <span class="stringliteral">"string list. Please report this bug."</span> );
<a name="l01647"></a>01647     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01648"></a>01648   }
<a name="l01649"></a>01649 
<a name="l01650"></a>01650   <span class="keyword">const</span> QStringList keys = result.toStringList();
<a name="l01651"></a>01651   <span class="keywordflow">if</span> ( keys.empty() ) {
<a name="l01652"></a>01652     errorText = i18n( <span class="stringliteral">"No keys have been found. Please check that a "</span>
<a name="l01653"></a>01653                       <span class="stringliteral">"valid key path has been set in the Chiasmus "</span>
<a name="l01654"></a>01654                       <span class="stringliteral">"configuration."</span> );
<a name="l01655"></a>01655     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01656"></a>01656   }
<a name="l01657"></a>01657 
<a name="l01658"></a>01658   emit mReader-&gt;noDrag();
<a name="l01659"></a>01659   ChiasmusKeySelector selectorDlg( mReader, i18n( <span class="stringliteral">"Chiasmus Decryption Key Selection"</span> ),
<a name="l01660"></a>01660                                    keys, GlobalSettings::chiasmusDecryptionKey(),
<a name="l01661"></a>01661                                    GlobalSettings::chiasmusDecryptionOptions() );
<a name="l01662"></a>01662   <span class="keywordflow">if</span> ( selectorDlg.exec() != QDialog::Accepted )
<a name="l01663"></a>01663     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01664"></a>01664 
<a name="l01665"></a>01665   GlobalSettings::setChiasmusDecryptionOptions( selectorDlg.options() );
<a name="l01666"></a>01666   GlobalSettings::setChiasmusDecryptionKey( selectorDlg.key() );
<a name="l01667"></a>01667   assert( !GlobalSettings::chiasmusDecryptionKey().isEmpty() );
<a name="l01668"></a>01668 
<a name="l01669"></a>01669   Kleo::SpecialJob * job = chiasmus-&gt;specialJob( <span class="stringliteral">"x-decrypt"</span>, QMap&lt;QString,QVariant&gt;() );
<a name="l01670"></a>01670   <span class="keywordflow">if</span> ( !job ) {
<a name="l01671"></a>01671     errorText = i18n( <span class="stringliteral">"Chiasmus backend does not offer the "</span>
<a name="l01672"></a>01672                       <span class="stringliteral">"\"x-decrypt\" function. Please report this bug."</span> );
<a name="l01673"></a>01673     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01674"></a>01674   }
<a name="l01675"></a>01675 
<a name="l01676"></a>01676   <span class="keywordflow">if</span> ( !job-&gt;setProperty( <span class="stringliteral">"key"</span>, GlobalSettings::chiasmusDecryptionKey() ) ||
<a name="l01677"></a>01677        !job-&gt;setProperty( <span class="stringliteral">"options"</span>, GlobalSettings::chiasmusDecryptionOptions() ) ||
<a name="l01678"></a>01678        !job-&gt;setProperty( <span class="stringliteral">"input"</span>, data ) ) {
<a name="l01679"></a>01679     errorText = i18n( <span class="stringliteral">"The \"x-decrypt\" function does not accept "</span>
<a name="l01680"></a>01680                       <span class="stringliteral">"the expected parameters. Please report this bug."</span> );
<a name="l01681"></a>01681     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01682"></a>01682   }
<a name="l01683"></a>01683 
<a name="l01684"></a>01684   <span class="keywordflow">if</span> ( job-&gt;exec() ) {
<a name="l01685"></a>01685     errorText = i18n( <span class="stringliteral">"Chiasmus Decryption Error"</span> );
<a name="l01686"></a>01686     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01687"></a>01687   }
<a name="l01688"></a>01688 
<a name="l01689"></a>01689   <span class="keyword">const</span> QVariant resultData = job-&gt;property( <span class="stringliteral">"result"</span> );
<a name="l01690"></a>01690   <span class="keywordflow">if</span> ( resultData.type() != QVariant::ByteArray ) {
<a name="l01691"></a>01691     errorText = i18n( <span class="stringliteral">"Unexpected return value from Chiasmus backend: "</span>
<a name="l01692"></a>01692                       <span class="stringliteral">"The \"x-decrypt\" function did not return a "</span>
<a name="l01693"></a>01693                       <span class="stringliteral">"byte array. Please report this bug."</span> );
<a name="l01694"></a>01694     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01695"></a>01695   }
<a name="l01696"></a>01696   bodyDecoded = resultData.toByteArray();
<a name="l01697"></a>01697   <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01698"></a>01698 }
<a name="l01699"></a>01699 
<a name="l01700"></a>01700 <span class="keywordtype">bool</span> ObjectTreeParser::processApplicationChiasmusTextSubtype( partNode * curNode, ProcessResult &amp; result )
<a name="l01701"></a>01701 {
<a name="l01702"></a>01702   <span class="keywordflow">if</span> ( !mReader ) {
<a name="l01703"></a>01703     mRawReplyString = curNode-&gt;msgPart().bodyDecoded();
<a name="l01704"></a>01704     mTextualContent += curNode-&gt;msgPart().bodyToUnicode();
<a name="l01705"></a>01705     mTextualContentCharset = curNode-&gt;msgPart().charset();
<a name="l01706"></a>01706     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01707"></a>01707   }
<a name="l01708"></a>01708 
<a name="l01709"></a>01709   QByteArray decryptedBody;
<a name="l01710"></a>01710   QString errorText;
<a name="l01711"></a>01711   <span class="keyword">const</span> QByteArray data = curNode-&gt;msgPart().bodyDecodedBinary();
<a name="l01712"></a>01712   <span class="keywordtype">bool</span> bOkDecrypt = decryptChiasmus( data, decryptedBody, errorText );
<a name="l01713"></a>01713   PartMetaData messagePart;
<a name="l01714"></a>01714   messagePart.isDecryptable = bOkDecrypt;
<a name="l01715"></a>01715   messagePart.isEncrypted = <span class="keyword">true</span>;
<a name="l01716"></a>01716   messagePart.isSigned = <span class="keyword">false</span>;
<a name="l01717"></a>01717   messagePart.errorText = errorText;
<a name="l01718"></a>01718   <span class="keywordflow">if</span> ( mReader )
<a name="l01719"></a>01719     htmlWriter()-&gt;queue( writeSigstatHeader( messagePart,
<a name="l01720"></a>01720                                              0, <span class="comment">//cryptPlugWrapper(),</span>
<a name="l01721"></a>01721                                              curNode-&gt;trueFromAddress() ) );
<a name="l01722"></a>01722   <span class="keyword">const</span> QByteArray body = bOkDecrypt ? decryptedBody : data;
<a name="l01723"></a>01723   <span class="keyword">const</span> QString chiasmusCharset = curNode-&gt;contentTypeParameter(<span class="stringliteral">"chiasmus-charset"</span>);
<a name="l01724"></a>01724   <span class="keyword">const</span> QTextCodec* aCodec = chiasmusCharset.isEmpty()
<a name="l01725"></a>01725     ? codecFor( curNode )
<a name="l01726"></a>01726     : KMMsgBase::codecForName( chiasmusCharset.ascii() );
<a name="l01727"></a>01727   htmlWriter()-&gt;queue( quotedHTML( aCodec-&gt;toUnicode( body ), <span class="keyword">false</span> <span class="comment">/*decorate*/</span> ) );
<a name="l01728"></a>01728   result.setInlineEncryptionState( KMMsgFullyEncrypted );
<a name="l01729"></a>01729   <span class="keywordflow">if</span> ( mReader )
<a name="l01730"></a>01730     htmlWriter()-&gt;queue( writeSigstatFooter( messagePart ) );
<a name="l01731"></a>01731   <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01732"></a>01732 }
<a name="l01733"></a>01733 
<a name="l01734"></a>01734 <span class="keywordtype">bool</span> ObjectTreeParser::processApplicationMsTnefSubtype( partNode *node, ProcessResult &amp;result )
<a name="l01735"></a>01735 {
<a name="l01736"></a>01736   Q_UNUSED( result );
<a name="l01737"></a>01737   <span class="keywordflow">if</span> ( !mReader )
<a name="l01738"></a>01738     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01739"></a>01739 
<a name="l01740"></a>01740   <span class="keyword">const</span> QString fileName = mReader-&gt;writeMessagePartToTempFile( &amp;node-&gt;msgPart(), node-&gt;nodeId() );
<a name="l01741"></a>01741   KTNEFParser parser;
<a name="l01742"></a>01742   <span class="keywordflow">if</span> ( !parser.openFile( fileName ) || !parser.message()) {
<a name="l01743"></a>01743     kdDebug() &lt;&lt; k_funcinfo &lt;&lt; <span class="stringliteral">"Could not parse "</span> &lt;&lt; fileName &lt;&lt; endl;
<a name="l01744"></a>01744     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01745"></a>01745   }
<a name="l01746"></a>01746 
<a name="l01747"></a>01747   QPtrList&lt;KTNEFAttach&gt; tnefatts = parser.message()-&gt;attachmentList();
<a name="l01748"></a>01748   <span class="keywordflow">if</span> ( tnefatts.isEmpty() ) {
<a name="l01749"></a>01749     kdDebug() &lt;&lt; k_funcinfo &lt;&lt; <span class="stringliteral">"No attachments found in "</span> &lt;&lt; fileName &lt;&lt; endl;
<a name="l01750"></a>01750     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01751"></a>01751   }
<a name="l01752"></a>01752 
<a name="l01753"></a>01753   <span class="keywordflow">if</span> ( !showOnlyOneMimePart() ) {
<a name="l01754"></a>01754     QString label = node-&gt;msgPart().fileName().stripWhiteSpace();
<a name="l01755"></a>01755     <span class="keywordflow">if</span> ( label.isEmpty() )
<a name="l01756"></a>01756       label = node-&gt;msgPart().name().stripWhiteSpace();
<a name="l01757"></a>01757     label = <a class="code" href="classKMMessage.html#204f475a310143d5d6cf0aa8a7df55a5" title="Quotes the following characters which have a special meaning in HTML: &amp;#39;&amp;lt;&amp;#39;...">KMMessage::quoteHtmlChars</a>( label, <span class="keyword">true</span> );
<a name="l01758"></a>01758     <span class="keyword">const</span> QString comment = <a class="code" href="classKMMessage.html#204f475a310143d5d6cf0aa8a7df55a5" title="Quotes the following characters which have a special meaning in HTML: &amp;#39;&amp;lt;&amp;#39;...">KMMessage::quoteHtmlChars</a>( node-&gt;msgPart().contentDescription(), true );
<a name="l01759"></a>01759     <span class="keyword">const</span> QString dir = QApplication::reverseLayout() ? <span class="stringliteral">"rtl"</span> : <span class="stringliteral">"ltr"</span> ;
<a name="l01760"></a>01760 
<a name="l01761"></a>01761     QString htmlStr = <span class="stringliteral">"&lt;table cellspacing=\"1\" class=\"textAtm\"&gt;"</span>
<a name="l01762"></a>01762                 <span class="stringliteral">"&lt;tr class=\"textAtmH\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span>;
<a name="l01763"></a>01763     <span class="keywordflow">if</span> ( !fileName.isEmpty() )
<a name="l01764"></a>01764       htmlStr += <span class="stringliteral">"&lt;a href=\""</span> + QString(<span class="stringliteral">"file:"</span>)
<a name="l01765"></a>01765         + KURL::encode_string( fileName ) + <span class="stringliteral">"\"&gt;"</span>
<a name="l01766"></a>01766         + label + <span class="stringliteral">"&lt;/a&gt;"</span>;
<a name="l01767"></a>01767     <span class="keywordflow">else</span>
<a name="l01768"></a>01768       htmlStr += label;
<a name="l01769"></a>01769     <span class="keywordflow">if</span> ( !comment.isEmpty() )
<a name="l01770"></a>01770       htmlStr += <span class="stringliteral">"&lt;br&gt;"</span> + comment;
<a name="l01771"></a>01771     htmlStr += <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\"textAtmB\"&gt;&lt;td&gt;"</span>;
<a name="l01772"></a>01772     htmlWriter()-&gt;queue( htmlStr );
<a name="l01773"></a>01773   }
<a name="l01774"></a>01774 
<a name="l01775"></a>01775   <span class="keywordflow">for</span> ( uint i = 0; i &lt; tnefatts.count(); ++i ) {
<a name="l01776"></a>01776     KTNEFAttach *att = tnefatts.at( i );
<a name="l01777"></a>01777     QString label = att-&gt;displayName();
<a name="l01778"></a>01778     <span class="keywordflow">if</span>( label.isEmpty() )
<a name="l01779"></a>01779       label = att-&gt;name();
<a name="l01780"></a>01780     label = <a class="code" href="classKMMessage.html#204f475a310143d5d6cf0aa8a7df55a5" title="Quotes the following characters which have a special meaning in HTML: &amp;#39;&amp;lt;&amp;#39;...">KMMessage::quoteHtmlChars</a>( label, <span class="keyword">true</span> );
<a name="l01781"></a>01781 
<a name="l01782"></a>01782     QString dir = mReader-&gt;createTempDir( <span class="stringliteral">"ktnef-"</span> + QString::number( i ) );
<a name="l01783"></a>01783     parser.extractFileTo( att-&gt;name(), dir );
<a name="l01784"></a>01784     mReader-&gt;mTempFiles.append( dir + QDir::separator() + att-&gt;name() );
<a name="l01785"></a>01785     QString href = <span class="stringliteral">"file:"</span> + KURL::encode_string( dir + QDir::separator() + att-&gt;name() );
<a name="l01786"></a>01786 
<a name="l01787"></a>01787     KMimeType::Ptr mimeType = KMimeType::mimeType( att-&gt;mimeTag() );
<a name="l01788"></a>01788     QString iconName = KGlobal::instance()-&gt;iconLoader()-&gt;iconPath( mimeType-&gt;icon( QString(), <span class="keyword">false</span> ), KIcon::Desktop );
<a name="l01789"></a>01789 
<a name="l01790"></a>01790     htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;div&gt;&lt;a href=\""</span> + href + <span class="stringliteral">"\"&gt;&lt;img src=\""</span> +
<a name="l01791"></a>01791                           iconName + <span class="stringliteral">"\" border=\"0\" style=\"max-width: 100%\"&gt;"</span> + label +
<a name="l01792"></a>01792                           <span class="stringliteral">"&lt;/a&gt;&lt;/div&gt;&lt;br&gt;"</span> );
<a name="l01793"></a>01793   }
<a name="l01794"></a>01794 
<a name="l01795"></a>01795   <span class="keywordflow">if</span> ( !showOnlyOneMimePart() )
<a name="l01796"></a>01796     htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"</span> );
<a name="l01797"></a>01797 
<a name="l01798"></a>01798   <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01799"></a>01799 }
<a name="l01800"></a>01800 
<a name="l01801"></a>01801   <span class="keywordtype">void</span> ObjectTreeParser::writeBodyString( <span class="keyword">const</span> QCString &amp; bodyString,
<a name="l01802"></a>01802                                           <span class="keyword">const</span> QString &amp; fromAddress,
<a name="l01803"></a>01803                                           <span class="keyword">const</span> QTextCodec * codec,
<a name="l01804"></a>01804                                           ProcessResult &amp; result,
<a name="l01805"></a>01805                                           <span class="keywordtype">bool</span> decorate ) {
<a name="l01806"></a>01806     assert( mReader ); assert( codec );
<a name="l01807"></a>01807     KMMsgSignatureState inlineSignatureState = result.inlineSignatureState();
<a name="l01808"></a>01808     KMMsgEncryptionState inlineEncryptionState = result.inlineEncryptionState();
<a name="l01809"></a>01809     writeBodyStr( bodyString, codec, fromAddress,
<a name="l01810"></a>01810                   inlineSignatureState, inlineEncryptionState, decorate );
<a name="l01811"></a>01811     result.setInlineSignatureState( inlineSignatureState );
<a name="l01812"></a>01812     result.setInlineEncryptionState( inlineEncryptionState );
<a name="l01813"></a>01813   }
<a name="l01814"></a>01814 
<a name="l01815"></a>01815   <span class="keywordtype">void</span> ObjectTreeParser::writePartIcon( KMMessagePart * msgPart, <span class="keywordtype">int</span> partNum, <span class="keywordtype">bool</span> inlineImage ) {
<a name="l01816"></a>01816     <span class="keywordflow">if</span> ( !mReader || !msgPart )
<a name="l01817"></a>01817       <span class="keywordflow">return</span>;
<a name="l01818"></a>01818 
<a name="l01819"></a>01819     kdDebug(5006) &lt;&lt; <span class="stringliteral">"writePartIcon: PartNum: "</span> &lt;&lt; partNum &lt;&lt; endl;
<a name="l01820"></a>01820 
<a name="l01821"></a>01821     QString label = msgPart-&gt;fileName();
<a name="l01822"></a>01822     <span class="keywordflow">if</span>( label.isEmpty() )
<a name="l01823"></a>01823       label = msgPart-&gt;name();
<a name="l01824"></a>01824     <span class="keywordflow">if</span>( label.isEmpty() )
<a name="l01825"></a>01825       label = <span class="stringliteral">"unnamed"</span>;
<a name="l01826"></a>01826     label = <a class="code" href="classKMMessage.html#204f475a310143d5d6cf0aa8a7df55a5" title="Quotes the following characters which have a special meaning in HTML: &amp;#39;&amp;lt;&amp;#39;...">KMMessage::quoteHtmlChars</a>( label, <span class="keyword">true</span> );
<a name="l01827"></a>01827 
<a name="l01828"></a>01828     QString comment = msgPart-&gt;contentDescription();
<a name="l01829"></a>01829     comment = <a class="code" href="classKMMessage.html#204f475a310143d5d6cf0aa8a7df55a5" title="Quotes the following characters which have a special meaning in HTML: &amp;#39;&amp;lt;&amp;#39;...">KMMessage::quoteHtmlChars</a>( comment, <span class="keyword">true</span> );
<a name="l01830"></a>01830     <span class="keywordflow">if</span> ( label == comment ) comment = QString::null;
<a name="l01831"></a>01831 
<a name="l01832"></a>01832     QString fileName = mReader-&gt;writeMessagePartToTempFile( msgPart, partNum );
<a name="l01833"></a>01833 
<a name="l01834"></a>01834     QString href = fileName.isEmpty() ?
<a name="l01835"></a>01835       <span class="stringliteral">"part://"</span> + QString::number( partNum + 1 ) :
<a name="l01836"></a>01836       <span class="stringliteral">"file:"</span> + KURL::encode_string( fileName ) ;
<a name="l01837"></a>01837 
<a name="l01838"></a>01838     QString iconName;
<a name="l01839"></a>01839     <span class="keywordflow">if</span>( inlineImage )
<a name="l01840"></a>01840       iconName = href;
<a name="l01841"></a>01841     <span class="keywordflow">else</span> {
<a name="l01842"></a>01842       iconName = msgPart-&gt;iconName();
<a name="l01843"></a>01843       <span class="keywordflow">if</span>( iconName.right( 14 ) == <span class="stringliteral">"mime_empty.png"</span> ) {
<a name="l01844"></a>01844         msgPart-&gt;magicSetType();
<a name="l01845"></a>01845         iconName = msgPart-&gt;iconName();
<a name="l01846"></a>01846       }
<a name="l01847"></a>01847     }
<a name="l01848"></a>01848 
<a name="l01849"></a>01849     QCString contentId = msgPart-&gt;contentId();
<a name="l01850"></a>01850     <span class="keywordflow">if</span> ( !contentId.isEmpty() ) {
<a name="l01851"></a>01851       htmlWriter()-&gt;embedPart( contentId, href );
<a name="l01852"></a>01852     }
<a name="l01853"></a>01853 
<a name="l01854"></a>01854     <span class="keywordflow">if</span>( inlineImage )
<a name="l01855"></a>01855       <span class="comment">// show the filename of the image below the embedded image</span>
<a name="l01856"></a>01856       htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;div&gt;&lt;a href=\""</span> + href + <span class="stringliteral">"\"&gt;"</span>
<a name="l01857"></a>01857                            <span class="stringliteral">"&lt;img src=\""</span> + iconName + <span class="stringliteral">"\" border=\"0\" style=\"max-width: 100%\"&gt;&lt;/a&gt;"</span>
<a name="l01858"></a>01858                            <span class="stringliteral">"&lt;/div&gt;"</span>
<a name="l01859"></a>01859                            <span class="stringliteral">"&lt;div&gt;&lt;a href=\""</span> + href + <span class="stringliteral">"\"&gt;"</span> + label + <span class="stringliteral">"&lt;/a&gt;"</span>
<a name="l01860"></a>01860                            <span class="stringliteral">"&lt;/div&gt;"</span>
<a name="l01861"></a>01861                            <span class="stringliteral">"&lt;div&gt;"</span> + comment + <span class="stringliteral">"&lt;/div&gt;&lt;br&gt;"</span> );
<a name="l01862"></a>01862     <span class="keywordflow">else</span>
<a name="l01863"></a>01863       <span class="comment">// show the filename next to the image</span>
<a name="l01864"></a>01864       htmlWriter()-&gt;queue( <span class="stringliteral">"&lt;div&gt;&lt;a href=\""</span> + href + <span class="stringliteral">"\"&gt;&lt;img src=\""</span> +
<a name="l01865"></a>01865                            iconName + <span class="stringliteral">"\" border=\"0\" style=\"max-width: 100%\"&gt;"</span> + label +
<a name="l01866"></a>01866                            <span class="stringliteral">"&lt;/a&gt;&lt;/div&gt;"</span>
<a name="l01867"></a>01867                            <span class="stringliteral">"&lt;div&gt;"</span> + comment + <span class="stringliteral">"&lt;/div&gt;&lt;br&gt;"</span> );
<a name="l01868"></a>01868   }
<a name="l01869"></a>01869 
<a name="l01870"></a>01870 <span class="preprocessor">#define SIG_FRAME_COL_UNDEF  99</span>
<a name="l01871"></a>01871 <span class="preprocessor"></span><span class="preprocessor">#define SIG_FRAME_COL_RED    -1</span>
<a name="l01872"></a>01872 <span class="preprocessor"></span><span class="preprocessor">#define SIG_FRAME_COL_YELLOW  0</span>
<a name="l01873"></a>01873 <span class="preprocessor"></span><span class="preprocessor">#define SIG_FRAME_COL_GREEN   1</span>
<a name="l01874"></a>01874 <span class="preprocessor"></span>QString ObjectTreeParser::sigStatusToString( <span class="keyword">const</span> Kleo::CryptoBackend::Protocol* cryptProto,
<a name="l01875"></a>01875                                         <span class="keywordtype">int</span> status_code,
<a name="l01876"></a>01876                                         GpgME::Signature::Summary summary,
<a name="l01877"></a>01877                                         <span class="keywordtype">int</span>&amp; frameColor,
<a name="l01878"></a>01878                                         <span class="keywordtype">bool</span>&amp; showKeyInfos )
<a name="l01879"></a>01879 {
<a name="l01880"></a>01880     <span class="comment">// note: At the moment frameColor and showKeyInfos are</span>
<a name="l01881"></a>01881     <span class="comment">//       used for CMS only but not for PGP signatures</span>
<a name="l01882"></a>01882     <span class="comment">// pending(khz): Implement usage of these for PGP sigs as well.</span>
<a name="l01883"></a>01883     showKeyInfos = <span class="keyword">true</span>;
<a name="l01884"></a>01884     QString result;
<a name="l01885"></a>01885     <span class="keywordflow">if</span>( cryptProto ) {
<a name="l01886"></a>01886         <span class="keywordflow">if</span>( cryptProto == Kleo::CryptoBackendFactory::instance()-&gt;openpgp() ) {
<a name="l01887"></a>01887             <span class="comment">// process enum according to it's definition to be read in</span>
<a name="l01888"></a>01888             <span class="comment">// GNU Privacy Guard CVS repository /gpgme/gpgme/gpgme.h</span>
<a name="l01889"></a>01889             <span class="keywordflow">switch</span>( status_code ) {
<a name="l01890"></a>01890             <span class="keywordflow">case</span> 0: <span class="comment">// GPGME_SIG_STAT_NONE</span>
<a name="l01891"></a>01891                 result = i18n(<span class="stringliteral">"Error: Signature not verified"</span>);
<a name="l01892"></a>01892                 <span class="keywordflow">break</span>;
<a name="l01893"></a>01893             <span class="keywordflow">case</span> 1: <span class="comment">// GPGME_SIG_STAT_GOOD</span>
<a name="l01894"></a>01894                 result = i18n(<span class="stringliteral">"Good signature"</span>);
<a name="l01895"></a>01895                 <span class="keywordflow">break</span>;
<a name="l01896"></a>01896             <span class="keywordflow">case</span> 2: <span class="comment">// GPGME_SIG_STAT_BAD</span>
<a name="l01897"></a>01897                 result = i18n(<span class="stringliteral">"&lt;b&gt;Bad&lt;/b&gt; signature"</span>);
<a name="l01898"></a>01898                 <span class="keywordflow">break</span>;
<a name="l01899"></a>01899             <span class="keywordflow">case</span> 3: <span class="comment">// GPGME_SIG_STAT_NOKEY</span>
<a name="l01900"></a>01900                 result = i18n(<span class="stringliteral">"No public key to verify the signature"</span>);
<a name="l01901"></a>01901                 <span class="keywordflow">break</span>;
<a name="l01902"></a>01902             <span class="keywordflow">case</span> 4: <span class="comment">// GPGME_SIG_STAT_NOSIG</span>
<a name="l01903"></a>01903                 result = i18n(<span class="stringliteral">"No signature found"</span>);
<a name="l01904"></a>01904                 <span class="keywordflow">break</span>;
<a name="l01905"></a>01905             <span class="keywordflow">case</span> 5: <span class="comment">// GPGME_SIG_STAT_ERROR</span>
<a name="l01906"></a>01906                 result = i18n(<span class="stringliteral">"Error verifying the signature"</span>);
<a name="l01907"></a>01907                 <span class="keywordflow">break</span>;
<a name="l01908"></a>01908             <span class="keywordflow">case</span> 6: <span class="comment">// GPGME_SIG_STAT_DIFF</span>
<a name="l01909"></a>01909                 result = i18n(<span class="stringliteral">"Different results for signatures"</span>);
<a name="l01910"></a>01910                 <span class="keywordflow">break</span>;
<a name="l01911"></a>01911             <span class="comment">/* PENDING(khz) Verify exact meaning of the following values:</span>
<a name="l01912"></a>01912 <span class="comment">            case 7: // GPGME_SIG_STAT_GOOD_EXP</span>
<a name="l01913"></a>01913 <span class="comment">                return i18n("Signature certificate is expired");</span>
<a name="l01914"></a>01914 <span class="comment">            break;</span>
<a name="l01915"></a>01915 <span class="comment">            case 8: // GPGME_SIG_STAT_GOOD_EXPKEY</span>
<a name="l01916"></a>01916 <span class="comment">                return i18n("One of the certificate's keys is expired");</span>
<a name="l01917"></a>01917 <span class="comment">            break;</span>
<a name="l01918"></a>01918 <span class="comment">            */</span>
<a name="l01919"></a>01919             <span class="keywordflow">default</span>:
<a name="l01920"></a>01920                 result = <span class="stringliteral">""</span>;   <span class="comment">// do *not* return a default text here !</span>
<a name="l01921"></a>01921                 <span class="keywordflow">break</span>;
<a name="l01922"></a>01922             }
<a name="l01923"></a>01923         }
<a name="l01924"></a>01924         <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( cryptProto == Kleo::CryptoBackendFactory::instance()-&gt;smime() ) {
<a name="l01925"></a>01925             <span class="comment">// process status bits according to SigStatus_...</span>
<a name="l01926"></a>01926             <span class="comment">// definitions in kdenetwork/libkdenetwork/cryptplug.h</span>
<a name="l01927"></a>01927 
<a name="l01928"></a>01928             <span class="keywordflow">if</span>( summary == GpgME::Signature::None ) {
<a name="l01929"></a>01929                 result = i18n(<span class="stringliteral">"No status information available."</span>);
<a name="l01930"></a>01930                 frameColor = SIG_FRAME_COL_YELLOW;
<a name="l01931"></a>01931                 showKeyInfos = <span class="keyword">false</span>;
<a name="l01932"></a>01932                 <span class="keywordflow">return</span> result;
<a name="l01933"></a>01933             }
<a name="l01934"></a>01934 
<a name="l01935"></a>01935             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::Valid ) {
<a name="l01936"></a>01936                 result = i18n(<span class="stringliteral">"Good signature."</span>);
<a name="l01937"></a>01937                 <span class="comment">// Note:</span>
<a name="l01938"></a>01938                 <span class="comment">// Here we are work differently than KMail did before!</span>
<a name="l01939"></a>01939                 <span class="comment">//</span>
<a name="l01940"></a>01940                 <span class="comment">// The GOOD case ( == sig matching and the complete</span>
<a name="l01941"></a>01941                 <span class="comment">// certificate chain was verified and is valid today )</span>
<a name="l01942"></a>01942                 <span class="comment">// by definition does *not* show any key</span>
<a name="l01943"></a>01943                 <span class="comment">// information but just states that things are OK.</span>
<a name="l01944"></a>01944                 <span class="comment">//           (khz, according to LinuxTag 2002 meeting)</span>
<a name="l01945"></a>01945                 frameColor = SIG_FRAME_COL_GREEN;
<a name="l01946"></a>01946                 showKeyInfos = <span class="keyword">false</span>;
<a name="l01947"></a>01947                 <span class="keywordflow">return</span> result;
<a name="l01948"></a>01948             }
<a name="l01949"></a>01949 
<a name="l01950"></a>01950             <span class="comment">// we are still there?  OK, let's test the different cases:</span>
<a name="l01951"></a>01951 
<a name="l01952"></a>01952             <span class="comment">// we assume green, test for yellow or red (in this order!)</span>
<a name="l01953"></a>01953             frameColor = SIG_FRAME_COL_GREEN;
<a name="l01954"></a>01954             QString result2;
<a name="l01955"></a>01955             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::KeyExpired ){
<a name="l01956"></a>01956                 <span class="comment">// still is green!</span>
<a name="l01957"></a>01957                 result2 += i18n(<span class="stringliteral">"One key has expired."</span>);
<a name="l01958"></a>01958             }
<a name="l01959"></a>01959             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::SigExpired ){
<a name="l01960"></a>01960                 <span class="comment">// and still is green!</span>
<a name="l01961"></a>01961                 result2 += i18n(<span class="stringliteral">"The signature has expired."</span>);
<a name="l01962"></a>01962             }
<a name="l01963"></a>01963 
<a name="l01964"></a>01964             <span class="comment">// test for yellow:</span>
<a name="l01965"></a>01965             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::KeyMissing ) {
<a name="l01966"></a>01966                 result2 += i18n(<span class="stringliteral">"Unable to verify: key missing."</span>);
<a name="l01967"></a>01967                 <span class="comment">// if the signature certificate is missing</span>
<a name="l01968"></a>01968                 <span class="comment">// we cannot show infos on it</span>
<a name="l01969"></a>01969                 showKeyInfos = <span class="keyword">false</span>;
<a name="l01970"></a>01970                 frameColor = SIG_FRAME_COL_YELLOW;
<a name="l01971"></a>01971             }
<a name="l01972"></a>01972             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::CrlMissing ){
<a name="l01973"></a>01973                 result2 += i18n(<span class="stringliteral">"CRL not available."</span>);
<a name="l01974"></a>01974                 frameColor = SIG_FRAME_COL_YELLOW;
<a name="l01975"></a>01975             }
<a name="l01976"></a>01976             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::CrlTooOld ){
<a name="l01977"></a>01977                 result2 += i18n(<span class="stringliteral">"Available CRL is too old."</span>);
<a name="l01978"></a>01978                 frameColor = SIG_FRAME_COL_YELLOW;
<a name="l01979"></a>01979             }
<a name="l01980"></a>01980             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::BadPolicy ){
<a name="l01981"></a>01981                 result2 += i18n(<span class="stringliteral">"A policy was not met."</span>);
<a name="l01982"></a>01982                 frameColor = SIG_FRAME_COL_YELLOW;
<a name="l01983"></a>01983             }
<a name="l01984"></a>01984             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::SysError ){
<a name="l01985"></a>01985                 result2 += i18n(<span class="stringliteral">"A system error occurred."</span>);
<a name="l01986"></a>01986                 <span class="comment">// if a system error occurred</span>
<a name="l01987"></a>01987                 <span class="comment">// we cannot trust any information</span>
<a name="l01988"></a>01988                 <span class="comment">// that was given back by the plug-in</span>
<a name="l01989"></a>01989                 showKeyInfos = <span class="keyword">false</span>;
<a name="l01990"></a>01990                 frameColor = SIG_FRAME_COL_YELLOW;
<a name="l01991"></a>01991             }
<a name="l01992"></a>01992 
<a name="l01993"></a>01993             <span class="comment">// test for red:</span>
<a name="l01994"></a>01994             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::KeyRevoked ){
<a name="l01995"></a>01995                 <span class="comment">// this is red!</span>
<a name="l01996"></a>01996                 result2 += i18n(<span class="stringliteral">"One key has been revoked."</span>);
<a name="l01997"></a>01997                 frameColor = SIG_FRAME_COL_RED;
<a name="l01998"></a>01998             }
<a name="l01999"></a>01999             <span class="keywordflow">if</span>( summary &amp; GpgME::Signature::Red ) {
<a name="l02000"></a>02000                 <span class="keywordflow">if</span>( result2.isEmpty() )
<a name="l02001"></a>02001                     <span class="comment">// Note:</span>
<a name="l02002"></a>02002                     <span class="comment">// Here we are work differently than KMail did before!</span>
<a name="l02003"></a>02003                     <span class="comment">//</span>
<a name="l02004"></a>02004                     <span class="comment">// The BAD case ( == sig *not* matching )</span>
<a name="l02005"></a>02005                     <span class="comment">// by definition does *not* show any key</span>
<a name="l02006"></a>02006                     <span class="comment">// information but just states that things are BAD.</span>
<a name="l02007"></a>02007                     <span class="comment">//</span>
<a name="l02008"></a>02008                     <span class="comment">// The reason for this: In this case ALL information</span>
<a name="l02009"></a>02009                     <span class="comment">// might be falsificated, we can NOT trust the data</span>
<a name="l02010"></a>02010                     <span class="comment">// in the body NOT the signature - so we don't show</span>
<a name="l02011"></a>02011                     <span class="comment">// any key/signature information at all!</span>
<a name="l02012"></a>02012                     <span class="comment">//         (khz, according to LinuxTag 2002 meeting)</span>
<a name="l02013"></a>02013                     showKeyInfos = <span class="keyword">false</span>;
<a name="l02014"></a>02014                 frameColor = SIG_FRAME_COL_RED;
<a name="l02015"></a>02015             }
<a name="l02016"></a>02016             <span class="keywordflow">else</span>
<a name="l02017"></a>02017                 result = <span class="stringliteral">""</span>;
<a name="l02018"></a>02018 
<a name="l02019"></a>02019             <span class="keywordflow">if</span>( SIG_FRAME_COL_GREEN == frameColor ) {
<a name="l02020"></a>02020                 result = i18n(<span class="stringliteral">"Good signature."</span>);
<a name="l02021"></a>02021             } <span class="keywordflow">else</span> <span class="keywordflow">if</span>( SIG_FRAME_COL_RED == frameColor ) {
<a name="l02022"></a>02022                 result = i18n(<span class="stringliteral">"&lt;b&gt;Bad&lt;/b&gt; signature."</span>);
<a name="l02023"></a>02023             } <span class="keywordflow">else</span>
<a name="l02024"></a>02024                 result = <span class="stringliteral">""</span>;
<a name="l02025"></a>02025 
<a name="l02026"></a>02026             <span class="keywordflow">if</span>( !result2.isEmpty() ) {
<a name="l02027"></a>02027                 <span class="keywordflow">if</span>( !result.isEmpty() )
<a name="l02028"></a>02028                     result.append(<span class="stringliteral">"&lt;br /&gt;"</span>);
<a name="l02029"></a>02029                 result.append( result2 );
<a name="l02030"></a>02030             }
<a name="l02031"></a>02031         }
<a name="l02032"></a>02032         <span class="comment">/*</span>
<a name="l02033"></a>02033 <span class="comment">        // add i18n support for 3rd party plug-ins here:</span>
<a name="l02034"></a>02034 <span class="comment">        else if (0 &lt;= cryptPlug-&gt;libName().find( "yetanotherpluginname", 0, false )) {</span>
<a name="l02035"></a>02035 <span class="comment"></span>
<a name="l02036"></a>02036 <span class="comment">        }</span>
<a name="l02037"></a>02037 <span class="comment">        */</span>
<a name="l02038"></a>02038     }
<a name="l02039"></a>02039     <span class="keywordflow">return</span> result;
<a name="l02040"></a>02040 }
<a name="l02041"></a>02041 
<a name="l02042"></a>02042 
<a name="l02043"></a>02043 <span class="keyword">static</span> QString writeSimpleSigstatHeader( <span class="keyword">const</span> PartMetaData &amp;block )
<a name="l02044"></a>02044 {
<a name="l02045"></a>02045   QString html;
<a name="l02046"></a>02046   html += <span class="stringliteral">"&lt;table cellspacing=\"0\" cellpadding=\"0\" width=\"100%\"&gt;&lt;tr&gt;&lt;td&gt;"</span>;
<a name="l02047"></a>02047 
<a name="l02048"></a>02048   <span class="keywordflow">if</span> ( block.signClass == <span class="stringliteral">"signErr"</span> ) {
<a name="l02049"></a>02049     html += i18n( <span class="stringliteral">"Invalid signature."</span> );
<a name="l02050"></a>02050   } <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( block.signClass == <span class="stringliteral">"signOkKeyBad"</span> || block.signClass == <span class="stringliteral">"signWarn"</span> ) {
<a name="l02051"></a>02051     html += i18n( <span class="stringliteral">"Not enough information to check signature validity."</span> );
<a name="l02052"></a>02052   } <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( block.signClass == <span class="stringliteral">"signOkKeyOk"</span> ) {
<a name="l02053"></a>02053     QString addr;
<a name="l02054"></a>02054     <span class="keywordflow">if</span> ( !block.signerMailAddresses.isEmpty() )
<a name="l02055"></a>02055       addr = block.signerMailAddresses.first();
<a name="l02056"></a>02056     QString name = addr;
<a name="l02057"></a>02057     <span class="keywordflow">if</span> ( name.isEmpty() )
<a name="l02058"></a>02058       name = block.signer;
<a name="l02059"></a>02059     if ( addr.isEmpty() ) {
<a name="l02060"></a>02060       html += i18n( <span class="stringliteral">"Signature is valid."</span> );
<a name="l02061"></a>02061     } <span class="keywordflow">else</span> {
<a name="l02062"></a>02062       html += i18n( <span class="stringliteral">"Signed by &lt;a href=\"mailto:%1\"&gt;%2&lt;/a&gt;."</span> ).arg( addr, name );
<a name="l02063"></a>02063     }
<a name="l02064"></a>02064   } <span class="keywordflow">else</span> {
<a name="l02065"></a>02065     <span class="comment">// should not happen</span>
<a name="l02066"></a>02066     html += i18n( <span class="stringliteral">"Unknown signature state"</span> );
<a name="l02067"></a>02067   }
<a name="l02068"></a>02068   html += <span class="stringliteral">"&lt;/td&gt;&lt;td align=\"right\"&gt;"</span>;
<a name="l02069"></a>02069   html += <span class="stringliteral">"&lt;a href=\"kmail:showSignatureDetails\"&gt;"</span>;
<a name="l02070"></a>02070   html += i18n( <span class="stringliteral">"Show Details"</span> );
<a name="l02071"></a>02071   html += <span class="stringliteral">"&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"</span>;
<a name="l02072"></a>02072   <span class="keywordflow">return</span> html;
<a name="l02073"></a>02073 }
<a name="l02074"></a>02074 
<a name="l02075"></a>02075 <span class="keyword">static</span> QString beginVerboseSigstatHeader()
<a name="l02076"></a>02076 {
<a name="l02077"></a>02077   <span class="keywordflow">return</span> <span class="stringliteral">"&lt;table cellspacing=\"0\" cellpadding=\"0\" width=\"100%\"&gt;&lt;tr&gt;&lt;td rowspan=\"2\"&gt;"</span>;
<a name="l02078"></a>02078 }
<a name="l02079"></a>02079 
<a name="l02080"></a>02080 <span class="keyword">static</span> QString makeShowAuditLogLink( <span class="keyword">const</span> QString &amp; auditLog ) {
<a name="l02081"></a>02081   <span class="keywordflow">if</span> ( auditLog.isEmpty() )
<a name="l02082"></a>02082     <span class="keywordflow">return</span> i18n(<span class="stringliteral">"No Audit Log available"</span>);
<a name="l02083"></a>02083 
<a name="l02084"></a>02084   KURL url;
<a name="l02085"></a>02085   url.setProtocol( <span class="stringliteral">"kmail"</span> );
<a name="l02086"></a>02086   url.setPath( <span class="stringliteral">"showAuditLog"</span> );
<a name="l02087"></a>02087   url.addQueryItem( <span class="stringliteral">"log"</span>, auditLog );
<a name="l02088"></a>02088 
<a name="l02089"></a>02089   <span class="keywordflow">return</span> <span class="stringliteral">"&lt;a href=\""</span> + url.htmlURL() + <span class="stringliteral">"\"&gt;"</span> + i18n(<span class="stringliteral">"Show Audit Log"</span>) + <span class="stringliteral">"&lt;/a&gt;"</span>;
<a name="l02090"></a>02090 }
<a name="l02091"></a>02091 
<a name="l02092"></a>02092 <span class="keyword">static</span> QString endVerboseSigstatHeader( <span class="keyword">const</span> PartMetaData &amp; pmd )
<a name="l02093"></a>02093 {
<a name="l02094"></a>02094   QString html;
<a name="l02095"></a>02095   html += <span class="stringliteral">"&lt;/td&gt;&lt;td align=\"right\" valign=\"top\" nowrap=\"nowrap\"&gt;"</span>;
<a name="l02096"></a>02096   html += <span class="stringliteral">"&lt;a href=\"kmail:hideSignatureDetails\"&gt;"</span>;
<a name="l02097"></a>02097   html += i18n( <span class="stringliteral">"Hide Details"</span> );
<a name="l02098"></a>02098   html += <span class="stringliteral">"&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;"</span>;
<a name="l02099"></a>02099   html += <span class="stringliteral">"&lt;tr&gt;&lt;td align=\"right\" valign=\"bottom\" nowrap=\"nowrap\"&gt;"</span>;
<a name="l02100"></a>02100   html += makeShowAuditLogLink( pmd.auditLog );
<a name="l02101"></a>02101   html += <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"</span>;
<a name="l02102"></a>02102   <span class="keywordflow">return</span> html;
<a name="l02103"></a>02103 }
<a name="l02104"></a>02104 
<a name="l02105"></a>02105 QString ObjectTreeParser::writeSigstatHeader( PartMetaData &amp; block,
<a name="l02106"></a>02106                                               <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * cryptProto,
<a name="l02107"></a>02107                                               <span class="keyword">const</span> QString &amp; fromAddress,
<a name="l02108"></a>02108                                               <span class="keyword">const</span> QString &amp; filename )
<a name="l02109"></a>02109 {
<a name="l02110"></a>02110     <span class="keyword">const</span> <span class="keywordtype">bool</span> isSMIME = cryptProto &amp;&amp; ( cryptProto == Kleo::CryptoBackendFactory::instance()-&gt;smime() );
<a name="l02111"></a>02111     QString signer = block.signer;
<a name="l02112"></a>02112 
<a name="l02113"></a>02113     QString htmlStr, simpleHtmlStr;
<a name="l02114"></a>02114     QString dir = ( QApplication::reverseLayout() ? <span class="stringliteral">"rtl"</span> : <span class="stringliteral">"ltr"</span> );
<a name="l02115"></a>02115     QString cellPadding(<span class="stringliteral">"cellpadding=\"1\""</span>);
<a name="l02116"></a>02116 
<a name="l02117"></a>02117     <span class="keywordflow">if</span>( block.isEncapsulatedRfc822Message )
<a name="l02118"></a>02118     {
<a name="l02119"></a>02119         htmlStr += <span class="stringliteral">"&lt;table cellspacing=\"1\" "</span>+cellPadding+<span class="stringliteral">" class=\"rfc822\"&gt;"</span>
<a name="l02120"></a>02120             <span class="stringliteral">"&lt;tr class=\"rfc822H\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span>;
<a name="l02121"></a>02121         <span class="keywordflow">if</span>( !filename.isEmpty() )
<a name="l02122"></a>02122             htmlStr += <span class="stringliteral">"&lt;a href=\""</span> + QString(<span class="stringliteral">"file:"</span>)
<a name="l02123"></a>02123                      + KURL::encode_string( filename ) + <span class="stringliteral">"\"&gt;"</span>
<a name="l02124"></a>02124                      + i18n(<span class="stringliteral">"Encapsulated message"</span>) + <span class="stringliteral">"&lt;/a&gt;"</span>;
<a name="l02125"></a>02125         <span class="keywordflow">else</span>
<a name="l02126"></a>02126             htmlStr += i18n(<span class="stringliteral">"Encapsulated message"</span>);
<a name="l02127"></a>02127         htmlStr += <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\"rfc822B\"&gt;&lt;td&gt;"</span>;
<a name="l02128"></a>02128     }
<a name="l02129"></a>02129 
<a name="l02130"></a>02130     <span class="keywordflow">if</span>( block.isEncrypted )
<a name="l02131"></a>02131     {
<a name="l02132"></a>02132         htmlStr += <span class="stringliteral">"&lt;table cellspacing=\"1\" "</span>+cellPadding+<span class="stringliteral">" class=\"encr\"&gt;"</span>
<a name="l02133"></a>02133             <span class="stringliteral">"&lt;tr class=\"encrH\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span>;
<a name="l02134"></a>02134         <span class="keywordflow">if</span>( block.isDecryptable )
<a name="l02135"></a>02135             htmlStr += i18n(<span class="stringliteral">"Encrypted message"</span>);
<a name="l02136"></a>02136         <span class="keywordflow">else</span> {
<a name="l02137"></a>02137             htmlStr += i18n(<span class="stringliteral">"Encrypted message (decryption not possible)"</span>);
<a name="l02138"></a>02138             <span class="keywordflow">if</span>( !block.errorText.isEmpty() )
<a name="l02139"></a>02139                 htmlStr += <span class="stringliteral">"&lt;br /&gt;"</span> + i18n(<span class="stringliteral">"Reason: %1"</span>).arg( block.errorText );
<a name="l02140"></a>02140         }
<a name="l02141"></a>02141         htmlStr += <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\"encrB\"&gt;&lt;td&gt;"</span>;
<a name="l02142"></a>02142     }
<a name="l02143"></a>02143     simpleHtmlStr = htmlStr;
<a name="l02144"></a>02144 
<a name="l02145"></a>02145     <span class="keywordflow">if</span>( block.isSigned ) {
<a name="l02146"></a>02146         QStringList&amp; blockAddrs( block.signerMailAddresses );
<a name="l02147"></a>02147         <span class="comment">// note: At the moment frameColor and showKeyInfos are</span>
<a name="l02148"></a>02148         <span class="comment">//       used for CMS only but not for PGP signatures</span>
<a name="l02149"></a>02149         <span class="comment">// pending(khz): Implement usage of these for PGP sigs as well.</span>
<a name="l02150"></a>02150         <span class="keywordtype">int</span> frameColor = SIG_FRAME_COL_UNDEF;
<a name="l02151"></a>02151         <span class="keywordtype">bool</span> showKeyInfos;
<a name="l02152"></a>02152         <span class="keywordtype">bool</span> onlyShowKeyURL = <span class="keyword">false</span>;
<a name="l02153"></a>02153         <span class="keywordtype">bool</span> cannotCheckSignature = <span class="keyword">true</span>;
<a name="l02154"></a>02154         QString statusStr = sigStatusToString( cryptProto,
<a name="l02155"></a>02155                                                block.status_code,
<a name="l02156"></a>02156                                                block.sigSummary,
<a name="l02157"></a>02157                                                frameColor,
<a name="l02158"></a>02158                                                showKeyInfos );
<a name="l02159"></a>02159         <span class="comment">// if needed fallback to english status text</span>
<a name="l02160"></a>02160         <span class="comment">// that was reported by the plugin</span>
<a name="l02161"></a>02161         <span class="keywordflow">if</span>( statusStr.isEmpty() )
<a name="l02162"></a>02162             statusStr = block.status;
<a name="l02163"></a>02163         <span class="keywordflow">if</span>( block.technicalProblem )
<a name="l02164"></a>02164             frameColor = SIG_FRAME_COL_YELLOW;
<a name="l02165"></a>02165 
<a name="l02166"></a>02166         <span class="keywordflow">switch</span>( frameColor ){
<a name="l02167"></a>02167             <span class="keywordflow">case</span> SIG_FRAME_COL_RED:
<a name="l02168"></a>02168                 cannotCheckSignature = <span class="keyword">false</span>;
<a name="l02169"></a>02169                 <span class="keywordflow">break</span>;
<a name="l02170"></a>02170             <span class="keywordflow">case</span> SIG_FRAME_COL_YELLOW:
<a name="l02171"></a>02171                 cannotCheckSignature = <span class="keyword">true</span>;
<a name="l02172"></a>02172                 <span class="keywordflow">break</span>;
<a name="l02173"></a>02173             <span class="keywordflow">case</span> SIG_FRAME_COL_GREEN:
<a name="l02174"></a>02174                 cannotCheckSignature = <span class="keyword">false</span>;
<a name="l02175"></a>02175                 <span class="keywordflow">break</span>;
<a name="l02176"></a>02176         }
<a name="l02177"></a>02177 
<a name="l02178"></a>02178         <span class="comment">// compose the string for displaying the key ID</span>
<a name="l02179"></a>02179         <span class="comment">// either as URL or not linked (for PGP)</span>
<a name="l02180"></a>02180         <span class="comment">// note: Once we can start PGP key manager programs</span>
<a name="l02181"></a>02181         <span class="comment">//       from within KMail we could change this and</span>
<a name="l02182"></a>02182         <span class="comment">//       always show the URL.    (khz, 2002/06/27)</span>
<a name="l02183"></a>02183         QString startKeyHREF;
<a name="l02184"></a>02184         <span class="keywordflow">if</span>( isSMIME )
<a name="l02185"></a>02185             startKeyHREF =
<a name="l02186"></a>02186                 QString(<span class="stringliteral">"&lt;a href=\"kmail:showCertificate#%1 ### %2 ### %3\"&gt;"</span>)
<a name="l02187"></a>02187                 .arg( cryptProto-&gt;displayName(),
<a name="l02188"></a>02188                       cryptProto-&gt;name(),
<a name="l02189"></a>02189                       block.keyId );
<a name="l02190"></a>02190         QString keyWithWithoutURL
<a name="l02191"></a>02191             = isSMIME
<a name="l02192"></a>02192             ? QString(<span class="stringliteral">"%1%2&lt;/a&gt;"</span>)
<a name="l02193"></a>02193                 .arg( startKeyHREF,
<a name="l02194"></a>02194                       cannotCheckSignature ? i18n(<span class="stringliteral">"[Details]"</span>) : (<span class="stringliteral">"0x"</span> + block.keyId) )
<a name="l02195"></a>02195             : <span class="stringliteral">"0x"</span> + QString::fromUtf8( block.keyId );
<a name="l02196"></a>02196 
<a name="l02197"></a>02197 
<a name="l02198"></a>02198         <span class="comment">// temporary hack: always show key infos!</span>
<a name="l02199"></a>02199         showKeyInfos = <span class="keyword">true</span>;
<a name="l02200"></a>02200 
<a name="l02201"></a>02201         <span class="comment">// Sorry for using 'black' as null color but .isValid()</span>
<a name="l02202"></a>02202         <span class="comment">// checking with QColor default c'tor did not work for</span>
<a name="l02203"></a>02203         <span class="comment">// some reason.</span>
<a name="l02204"></a>02204         <span class="keywordflow">if</span>( isSMIME &amp;&amp; (SIG_FRAME_COL_UNDEF != frameColor) ) {
<a name="l02205"></a>02205 
<a name="l02206"></a>02206             <span class="comment">// new frame settings for CMS:</span>
<a name="l02207"></a>02207             <span class="comment">// beautify the status string</span>
<a name="l02208"></a>02208             <span class="keywordflow">if</span>( !statusStr.isEmpty() ) {
<a name="l02209"></a>02209                 statusStr.prepend(<span class="stringliteral">"&lt;i&gt;"</span>);
<a name="l02210"></a>02210                 statusStr.append( <span class="stringliteral">"&lt;/i&gt;"</span>);
<a name="l02211"></a>02211             }
<a name="l02212"></a>02212 
<a name="l02213"></a>02213             <span class="comment">// special color handling: S/MIME uses only green/yellow/red.</span>
<a name="l02214"></a>02214             <span class="keywordflow">switch</span>( frameColor ) {
<a name="l02215"></a>02215                 <span class="keywordflow">case</span> SIG_FRAME_COL_RED:
<a name="l02216"></a>02216                     block.signClass = <span class="stringliteral">"signErr"</span>;<span class="comment">//"signCMSRed";</span>
<a name="l02217"></a>02217                     onlyShowKeyURL = <span class="keyword">true</span>;
<a name="l02218"></a>02218                     <span class="keywordflow">break</span>;
<a name="l02219"></a>02219                 <span class="keywordflow">case</span> SIG_FRAME_COL_YELLOW:
<a name="l02220"></a>02220                     <span class="keywordflow">if</span>( block.technicalProblem )
<a name="l02221"></a>02221                         block.signClass = <span class="stringliteral">"signWarn"</span>;
<a name="l02222"></a>02222                     <span class="keywordflow">else</span>
<a name="l02223"></a>02223                         block.signClass = <span class="stringliteral">"signOkKeyBad"</span>;<span class="comment">//"signCMSYellow";</span>
<a name="l02224"></a>02224                     <span class="keywordflow">break</span>;
<a name="l02225"></a>02225                 <span class="keywordflow">case</span> SIG_FRAME_COL_GREEN:
<a name="l02226"></a>02226                     block.signClass = <span class="stringliteral">"signOkKeyOk"</span>;<span class="comment">//"signCMSGreen";</span>
<a name="l02227"></a>02227                     <span class="comment">// extra hint for green case</span>
<a name="l02228"></a>02228                     <span class="comment">// that email addresses in DN do not match fromAddress</span>
<a name="l02229"></a>02229                     QString greenCaseWarning;
<a name="l02230"></a>02230                     QString msgFrom( KPIM::getEmailAddress(fromAddress) );
<a name="l02231"></a>02231                     QString certificate;
<a name="l02232"></a>02232                     <span class="keywordflow">if</span>( block.keyId.isEmpty() )
<a name="l02233"></a>02233                         certificate = i18n(<span class="stringliteral">"certificate"</span>);
<a name="l02234"></a>02234                     <span class="keywordflow">else</span>
<a name="l02235"></a>02235                         certificate = startKeyHREF + i18n(<span class="stringliteral">"certificate"</span>) + <span class="stringliteral">"&lt;/a&gt;"</span>; 
<a name="l02236"></a>02236                     <span class="keywordflow">if</span>( !blockAddrs.empty() ){
<a name="l02237"></a>02237                         <span class="keywordflow">if</span>( blockAddrs.grep(
<a name="l02238"></a>02238                                 msgFrom,
<a name="l02239"></a>02239                                 <span class="keyword">false</span> ).isEmpty() ) {
<a name="l02240"></a>02240                             greenCaseWarning =
<a name="l02241"></a>02241                                 <span class="stringliteral">"&lt;u&gt;"</span> +
<a name="l02242"></a>02242                                 i18n(<span class="stringliteral">"Warning:"</span>) +
<a name="l02243"></a>02243                                 <span class="stringliteral">"&lt;/u&gt; "</span> +
<a name="l02244"></a>02244                                 i18n(<span class="stringliteral">"Sender's mail address is not stored "</span>
<a name="l02245"></a>02245                                      <span class="stringliteral">"in the %1 used for signing."</span>).arg(certificate) +
<a name="l02246"></a>02246                                 <span class="stringliteral">"&lt;br /&gt;"</span> +
<a name="l02247"></a>02247                                 i18n(<span class="stringliteral">"sender: "</span>) +
<a name="l02248"></a>02248                                 msgFrom +
<a name="l02249"></a>02249                                 <span class="stringliteral">"&lt;br /&gt;"</span> +
<a name="l02250"></a>02250                                 i18n(<span class="stringliteral">"stored: "</span>);
<a name="l02251"></a>02251                             <span class="comment">// We cannot use Qt's join() function here but</span>
<a name="l02252"></a>02252                             <span class="comment">// have to join the addresses manually to</span>
<a name="l02253"></a>02253                             <span class="comment">// extract the mail addresses (without '&lt;''&gt;')</span>
<a name="l02254"></a>02254                             <span class="comment">// before including it into our string:</span>
<a name="l02255"></a>02255                             <span class="keywordtype">bool</span> bStart = <span class="keyword">true</span>;
<a name="l02256"></a>02256                             <span class="keywordflow">for</span>(QStringList::ConstIterator it = blockAddrs.begin();
<a name="l02257"></a>02257                                 it != blockAddrs.end(); ++it ){
<a name="l02258"></a>02258                                 <span class="keywordflow">if</span>( !bStart )
<a name="l02259"></a>02259                                     greenCaseWarning.append(<span class="stringliteral">", &lt;br /&gt;&amp;nbsp; &amp;nbsp;"</span>);
<a name="l02260"></a>02260                                 bStart = <span class="keyword">false</span>;
<a name="l02261"></a>02261                                 greenCaseWarning.append( KPIM::getEmailAddress(*it) );
<a name="l02262"></a>02262                             }
<a name="l02263"></a>02263                         }
<a name="l02264"></a>02264                     } <span class="keywordflow">else</span> {
<a name="l02265"></a>02265                         greenCaseWarning =
<a name="l02266"></a>02266                             <span class="stringliteral">"&lt;u&gt;"</span> +
<a name="l02267"></a>02267                             i18n(<span class="stringliteral">"Warning:"</span>) +
<a name="l02268"></a>02268                             <span class="stringliteral">"&lt;/u&gt; "</span> +
<a name="l02269"></a>02269                             i18n(<span class="stringliteral">"No mail address is stored in the %1 used for signing, "</span>
<a name="l02270"></a>02270                                  <span class="stringliteral">"so we cannot compare it to the sender's address %2."</span>)
<a name="l02271"></a>02271                             .arg(certificate,msgFrom);
<a name="l02272"></a>02272                     }
<a name="l02273"></a>02273                     <span class="keywordflow">if</span>( !greenCaseWarning.isEmpty() ) {
<a name="l02274"></a>02274                         <span class="keywordflow">if</span>( !statusStr.isEmpty() )
<a name="l02275"></a>02275                             statusStr.append(<span class="stringliteral">"&lt;br /&gt;&amp;nbsp;&lt;br /&gt;"</span>);
<a name="l02276"></a>02276                         statusStr.append( greenCaseWarning );
<a name="l02277"></a>02277                     }
<a name="l02278"></a>02278                     <span class="keywordflow">break</span>;
<a name="l02279"></a>02279             }
<a name="l02280"></a>02280 
<a name="l02281"></a>02281             QString frame = <span class="stringliteral">"&lt;table cellspacing=\"1\" "</span>+cellPadding+<span class="stringliteral">" "</span>
<a name="l02282"></a>02282                 <span class="stringliteral">"class=\""</span> + block.signClass + <span class="stringliteral">"\"&gt;"</span>
<a name="l02283"></a>02283                 <span class="stringliteral">"&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"H\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span>;
<a name="l02284"></a>02284             htmlStr += frame + beginVerboseSigstatHeader();
<a name="l02285"></a>02285             simpleHtmlStr += frame;
<a name="l02286"></a>02286             simpleHtmlStr += writeSimpleSigstatHeader( block );
<a name="l02287"></a>02287             <span class="keywordflow">if</span>( block.technicalProblem ) {
<a name="l02288"></a>02288                 htmlStr += block.errorText;
<a name="l02289"></a>02289             }
<a name="l02290"></a>02290             <span class="keywordflow">else</span> <span class="keywordflow">if</span>( showKeyInfos ) {
<a name="l02291"></a>02291                 <span class="keywordflow">if</span>( cannotCheckSignature ) {
<a name="l02292"></a>02292                     htmlStr += i18n( <span class="stringliteral">"Not enough information to check "</span>
<a name="l02293"></a>02293                                      <span class="stringliteral">"signature. %1"</span> )
<a name="l02294"></a>02294                                 .arg( keyWithWithoutURL );
<a name="l02295"></a>02295                 }
<a name="l02296"></a>02296                 <span class="keywordflow">else</span> {
<a name="l02297"></a>02297 
<a name="l02298"></a>02298                     <span class="keywordflow">if</span> (block.signer.isEmpty())
<a name="l02299"></a>02299                         signer = <span class="stringliteral">""</span>;
<a name="l02300"></a>02300                     <span class="keywordflow">else</span> {
<a name="l02301"></a>02301                         <span class="keywordflow">if</span>( !blockAddrs.empty() ){
<a name="l02302"></a>02302                             QString address = <a class="code" href="classKMMessage.html#ba85fd5c4264aeec336a5992e20e4568" title="Encodes an email address as mailto URL.">KMMessage::encodeMailtoUrl</a>( blockAddrs.first() );
<a name="l02303"></a>02303                             signer = <span class="stringliteral">"&lt;a href=\"mailto:"</span> + address + <span class="stringliteral">"\"&gt;"</span> + signer + <span class="stringliteral">"&lt;/a&gt;"</span>;
<a name="l02304"></a>02304                         }
<a name="l02305"></a>02305                     }
<a name="l02306"></a>02306 
<a name="l02307"></a>02307                     <span class="keywordflow">if</span>( block.keyId.isEmpty() ) {
<a name="l02308"></a>02308                         <span class="keywordflow">if</span>( signer.isEmpty() || onlyShowKeyURL )
<a name="l02309"></a>02309                             htmlStr += i18n( <span class="stringliteral">"Message was signed with unknown key."</span> );
<a name="l02310"></a>02310                         <span class="keywordflow">else</span>
<a name="l02311"></a>02311                             htmlStr += i18n( <span class="stringliteral">"Message was signed by %1."</span> )
<a name="l02312"></a>02312                                     .arg( signer );
<a name="l02313"></a>02313                     } <span class="keywordflow">else</span> {
<a name="l02314"></a>02314                         QDateTime created = block.creationTime;
<a name="l02315"></a>02315                         <span class="keywordflow">if</span>( created.isValid() ) {
<a name="l02316"></a>02316                             <span class="keywordflow">if</span>( signer.isEmpty() ) {
<a name="l02317"></a>02317                                 <span class="keywordflow">if</span>( onlyShowKeyURL )
<a name="l02318"></a>02318                                     htmlStr += i18n( <span class="stringliteral">"Message was signed with key %1."</span> )
<a name="l02319"></a>02319                                                 .arg( keyWithWithoutURL );
<a name="l02320"></a>02320                                 <span class="keywordflow">else</span>
<a name="l02321"></a>02321                                     htmlStr += i18n( <span class="stringliteral">"Message was signed on %1 with key %2."</span> )
<a name="l02322"></a>02322                                                 .arg( KGlobal::locale()-&gt;formatDateTime( created ),
<a name="l02323"></a>02323                                                       keyWithWithoutURL );
<a name="l02324"></a>02324                             }
<a name="l02325"></a>02325                             <span class="keywordflow">else</span> {
<a name="l02326"></a>02326                                 <span class="keywordflow">if</span>( onlyShowKeyURL )
<a name="l02327"></a>02327                                     htmlStr += i18n( <span class="stringliteral">"Message was signed with key %1."</span> )
<a name="l02328"></a>02328                                             .arg( keyWithWithoutURL );
<a name="l02329"></a>02329                                 <span class="keywordflow">else</span>
<a name="l02330"></a>02330                                     htmlStr += i18n( <span class="stringliteral">"Message was signed by %3 on %1 with key %2"</span> )
<a name="l02331"></a>02331                                             .arg( KGlobal::locale()-&gt;formatDateTime( created ),
<a name="l02332"></a>02332                                                   keyWithWithoutURL,
<a name="l02333"></a>02333                                                   signer );
<a name="l02334"></a>02334                             }
<a name="l02335"></a>02335                         }
<a name="l02336"></a>02336                         <span class="keywordflow">else</span> {
<a name="l02337"></a>02337                             <span class="keywordflow">if</span>( signer.isEmpty() || onlyShowKeyURL )
<a name="l02338"></a>02338                                 htmlStr += i18n( <span class="stringliteral">"Message was signed with key %1."</span> )
<a name="l02339"></a>02339                                         .arg( keyWithWithoutURL );
<a name="l02340"></a>02340                             <span class="keywordflow">else</span>
<a name="l02341"></a>02341                                 htmlStr += i18n( <span class="stringliteral">"Message was signed by %2 with key %1."</span> )
<a name="l02342"></a>02342                                         .arg( keyWithWithoutURL,
<a name="l02343"></a>02343                                               signer );
<a name="l02344"></a>02344                         }
<a name="l02345"></a>02345                     }
<a name="l02346"></a>02346                 }
<a name="l02347"></a>02347                 htmlStr += <span class="stringliteral">"&lt;br /&gt;"</span>;
<a name="l02348"></a>02348                 <span class="keywordflow">if</span>( !statusStr.isEmpty() ) {
<a name="l02349"></a>02349                     htmlStr += <span class="stringliteral">"&amp;nbsp;&lt;br /&gt;"</span>;
<a name="l02350"></a>02350                     htmlStr += i18n( <span class="stringliteral">"Status: "</span> );
<a name="l02351"></a>02351                     htmlStr += statusStr;
<a name="l02352"></a>02352                 }
<a name="l02353"></a>02353             } <span class="keywordflow">else</span> {
<a name="l02354"></a>02354                 htmlStr += statusStr;
<a name="l02355"></a>02355             }
<a name="l02356"></a>02356             frame = <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"B\"&gt;&lt;td&gt;"</span>;
<a name="l02357"></a>02357             htmlStr += endVerboseSigstatHeader( block ) + frame;
<a name="l02358"></a>02358             simpleHtmlStr += frame;
<a name="l02359"></a>02359 
<a name="l02360"></a>02360         } <span class="keywordflow">else</span> {
<a name="l02361"></a>02361 
<a name="l02362"></a>02362             <span class="comment">// old frame settings for PGP:</span>
<a name="l02363"></a>02363 
<a name="l02364"></a>02364             <span class="keywordflow">if</span>( block.signer.isEmpty() || block.technicalProblem ) {
<a name="l02365"></a>02365                 block.signClass = <span class="stringliteral">"signWarn"</span>;
<a name="l02366"></a>02366                 QString frame = <span class="stringliteral">"&lt;table cellspacing=\"1\" "</span>+cellPadding+<span class="stringliteral">" "</span>
<a name="l02367"></a>02367                     <span class="stringliteral">"class=\""</span> + block.signClass + <span class="stringliteral">"\"&gt;"</span>
<a name="l02368"></a>02368                     <span class="stringliteral">"&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"H\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span>;
<a name="l02369"></a>02369                 htmlStr += frame + beginVerboseSigstatHeader();
<a name="l02370"></a>02370                 simpleHtmlStr += frame;
<a name="l02371"></a>02371                 simpleHtmlStr += writeSimpleSigstatHeader( block );
<a name="l02372"></a>02372                 <span class="keywordflow">if</span>( block.technicalProblem ) {
<a name="l02373"></a>02373                     htmlStr += block.errorText;
<a name="l02374"></a>02374                 }
<a name="l02375"></a>02375                 <span class="keywordflow">else</span> {
<a name="l02376"></a>02376                   <span class="keywordflow">if</span>( !block.keyId.isEmpty() ) {
<a name="l02377"></a>02377                     QDateTime created = block.creationTime;
<a name="l02378"></a>02378                     <span class="keywordflow">if</span> ( created.isValid() )
<a name="l02379"></a>02379                         htmlStr += i18n( <span class="stringliteral">"Message was signed on %1 with unknown key %2."</span> )
<a name="l02380"></a>02380                                 .arg( KGlobal::locale()-&gt;formatDateTime( created ),
<a name="l02381"></a>02381                                       keyWithWithoutURL );
<a name="l02382"></a>02382                     <span class="keywordflow">else</span>
<a name="l02383"></a>02383                         htmlStr += i18n( <span class="stringliteral">"Message was signed with unknown key %1."</span> )
<a name="l02384"></a>02384                                 .arg( keyWithWithoutURL );
<a name="l02385"></a>02385                   }
<a name="l02386"></a>02386                   <span class="keywordflow">else</span>
<a name="l02387"></a>02387                     htmlStr += i18n( <span class="stringliteral">"Message was signed with unknown key."</span> );
<a name="l02388"></a>02388                   htmlStr += <span class="stringliteral">"&lt;br /&gt;"</span>;
<a name="l02389"></a>02389                   htmlStr += i18n( <span class="stringliteral">"The validity of the signature cannot be "</span>
<a name="l02390"></a>02390                                    <span class="stringliteral">"verified."</span> );
<a name="l02391"></a>02391                   <span class="keywordflow">if</span>( !statusStr.isEmpty() ) {
<a name="l02392"></a>02392                     htmlStr += <span class="stringliteral">"&lt;br /&gt;"</span>;
<a name="l02393"></a>02393                     htmlStr += i18n( <span class="stringliteral">"Status: "</span> );
<a name="l02394"></a>02394                     htmlStr += <span class="stringliteral">"&lt;i&gt;"</span>;
<a name="l02395"></a>02395                     htmlStr += statusStr;
<a name="l02396"></a>02396                     htmlStr += <span class="stringliteral">"&lt;/i&gt;"</span>;
<a name="l02397"></a>02397                   }
<a name="l02398"></a>02398                 }
<a name="l02399"></a>02399                 frame = <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"B\"&gt;&lt;td&gt;"</span>;
<a name="l02400"></a>02400                 htmlStr += endVerboseSigstatHeader( block ) + frame;
<a name="l02401"></a>02401                 simpleHtmlStr += frame;
<a name="l02402"></a>02402             }
<a name="l02403"></a>02403             <span class="keywordflow">else</span>
<a name="l02404"></a>02404             {
<a name="l02405"></a>02405                 <span class="comment">// HTMLize the signer's user id and create mailto: link</span>
<a name="l02406"></a>02406                 signer = <a class="code" href="classKMMessage.html#204f475a310143d5d6cf0aa8a7df55a5" title="Quotes the following characters which have a special meaning in HTML: &amp;#39;&amp;lt;&amp;#39;...">KMMessage::quoteHtmlChars</a>( signer, <span class="keyword">true</span> );
<a name="l02407"></a>02407                 signer = <span class="stringliteral">"&lt;a href=\"mailto:"</span> + signer + <span class="stringliteral">"\"&gt;"</span> + signer + <span class="stringliteral">"&lt;/a&gt;"</span>;
<a name="l02408"></a>02408 
<a name="l02409"></a>02409                 <span class="keywordflow">if</span> (block.isGoodSignature) {
<a name="l02410"></a>02410                     <span class="keywordflow">if</span>( block.keyTrust &lt; Kpgp::KPGP_VALIDITY_MARGINAL )
<a name="l02411"></a>02411                         block.signClass = <span class="stringliteral">"signOkKeyBad"</span>;
<a name="l02412"></a>02412                     <span class="keywordflow">else</span>
<a name="l02413"></a>02413                         block.signClass = <span class="stringliteral">"signOkKeyOk"</span>;
<a name="l02414"></a>02414                     QString frame = <span class="stringliteral">"&lt;table cellspacing=\"1\" "</span>+cellPadding+<span class="stringliteral">" "</span>
<a name="l02415"></a>02415                         <span class="stringliteral">"class=\""</span> + block.signClass + <span class="stringliteral">"\"&gt;"</span>
<a name="l02416"></a>02416                         <span class="stringliteral">"&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"H\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span>;
<a name="l02417"></a>02417                     htmlStr += frame + beginVerboseSigstatHeader();
<a name="l02418"></a>02418                     simpleHtmlStr += frame;
<a name="l02419"></a>02419                     simpleHtmlStr += writeSimpleSigstatHeader( block );
<a name="l02420"></a>02420                     <span class="keywordflow">if</span>( !block.keyId.isEmpty() )
<a name="l02421"></a>02421                         htmlStr += i18n( <span class="stringliteral">"Message was signed by %2 (Key ID: %1)."</span> )
<a name="l02422"></a>02422                                    .arg( keyWithWithoutURL,
<a name="l02423"></a>02423                                          signer );
<a name="l02424"></a>02424                     <span class="keywordflow">else</span>
<a name="l02425"></a>02425                         htmlStr += i18n( <span class="stringliteral">"Message was signed by %1."</span> ).arg( signer );
<a name="l02426"></a>02426                     htmlStr += <span class="stringliteral">"&lt;br /&gt;"</span>;
<a name="l02427"></a>02427 
<a name="l02428"></a>02428                     <span class="keywordflow">switch</span>( block.keyTrust )
<a name="l02429"></a>02429                     {
<a name="l02430"></a>02430                         <span class="keywordflow">case</span> Kpgp::KPGP_VALIDITY_UNKNOWN:
<a name="l02431"></a>02431                         htmlStr += i18n( <span class="stringliteral">"The signature is valid, but the key's "</span>
<a name="l02432"></a>02432                                 <span class="stringliteral">"validity is unknown."</span> );
<a name="l02433"></a>02433                         <span class="keywordflow">break</span>;
<a name="l02434"></a>02434                         <span class="keywordflow">case</span> Kpgp::KPGP_VALIDITY_MARGINAL:
<a name="l02435"></a>02435                         htmlStr += i18n( <span class="stringliteral">"The signature is valid and the key is "</span>
<a name="l02436"></a>02436                                 <span class="stringliteral">"marginally trusted."</span> );
<a name="l02437"></a>02437                         <span class="keywordflow">break</span>;
<a name="l02438"></a>02438                         <span class="keywordflow">case</span> Kpgp::KPGP_VALIDITY_FULL:
<a name="l02439"></a>02439                         htmlStr += i18n( <span class="stringliteral">"The signature is valid and the key is "</span>
<a name="l02440"></a>02440                                 <span class="stringliteral">"fully trusted."</span> );
<a name="l02441"></a>02441                         <span class="keywordflow">break</span>;
<a name="l02442"></a>02442                         <span class="keywordflow">case</span> Kpgp::KPGP_VALIDITY_ULTIMATE:
<a name="l02443"></a>02443                         htmlStr += i18n( <span class="stringliteral">"The signature is valid and the key is "</span>
<a name="l02444"></a>02444                                 <span class="stringliteral">"ultimately trusted."</span> );
<a name="l02445"></a>02445                         <span class="keywordflow">break</span>;
<a name="l02446"></a>02446                         <span class="keywordflow">default</span>:
<a name="l02447"></a>02447                         htmlStr += i18n( <span class="stringliteral">"The signature is valid, but the key is "</span>
<a name="l02448"></a>02448                                 <span class="stringliteral">"untrusted."</span> );
<a name="l02449"></a>02449                     }
<a name="l02450"></a>02450                     frame = <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;"</span>
<a name="l02451"></a>02451                         <span class="stringliteral">"&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"B\"&gt;&lt;td&gt;"</span>;
<a name="l02452"></a>02452                     htmlStr += endVerboseSigstatHeader( block ) + frame;
<a name="l02453"></a>02453                     simpleHtmlStr += frame;
<a name="l02454"></a>02454                 }
<a name="l02455"></a>02455                 <span class="keywordflow">else</span>
<a name="l02456"></a>02456                 {
<a name="l02457"></a>02457                     block.signClass = <span class="stringliteral">"signErr"</span>;
<a name="l02458"></a>02458                     QString frame = <span class="stringliteral">"&lt;table cellspacing=\"1\" "</span>+cellPadding+<span class="stringliteral">" "</span>
<a name="l02459"></a>02459                         <span class="stringliteral">"class=\""</span> + block.signClass + <span class="stringliteral">"\"&gt;"</span>
<a name="l02460"></a>02460                         <span class="stringliteral">"&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"H\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span>;
<a name="l02461"></a>02461                     htmlStr += frame + beginVerboseSigstatHeader();
<a name="l02462"></a>02462                     simpleHtmlStr += frame;
<a name="l02463"></a>02463                     simpleHtmlStr += writeSimpleSigstatHeader( block );
<a name="l02464"></a>02464                     <span class="keywordflow">if</span>( !block.keyId.isEmpty() )
<a name="l02465"></a>02465                         htmlStr += i18n( <span class="stringliteral">"Message was signed by %2 (Key ID: %1)."</span> )
<a name="l02466"></a>02466                         .arg( keyWithWithoutURL,
<a name="l02467"></a>02467                               signer );
<a name="l02468"></a>02468                     <span class="keywordflow">else</span>
<a name="l02469"></a>02469                         htmlStr += i18n( <span class="stringliteral">"Message was signed by %1."</span> ).arg( signer );
<a name="l02470"></a>02470                     htmlStr += <span class="stringliteral">"&lt;br /&gt;"</span>;
<a name="l02471"></a>02471                     htmlStr += i18n(<span class="stringliteral">"Warning: The signature is bad."</span>);
<a name="l02472"></a>02472                     frame = <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;"</span>
<a name="l02473"></a>02473                         <span class="stringliteral">"&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"B\"&gt;&lt;td&gt;"</span>;
<a name="l02474"></a>02474                     htmlStr += endVerboseSigstatHeader( block ) + frame;
<a name="l02475"></a>02475                     simpleHtmlStr += frame;
<a name="l02476"></a>02476                 }
<a name="l02477"></a>02477             }
<a name="l02478"></a>02478         }
<a name="l02479"></a>02479     }
<a name="l02480"></a>02480 
<a name="l02481"></a>02481     <span class="keywordflow">if</span> ( mReader-&gt;showSignatureDetails() )
<a name="l02482"></a>02482       <span class="keywordflow">return</span> htmlStr;
<a name="l02483"></a>02483     <span class="keywordflow">return</span> simpleHtmlStr;
<a name="l02484"></a>02484 }
<a name="l02485"></a>02485 
<a name="l02486"></a>02486 QString ObjectTreeParser::writeSigstatFooter( PartMetaData&amp; block )
<a name="l02487"></a>02487 {
<a name="l02488"></a>02488     QString dir = ( QApplication::reverseLayout() ? <span class="stringliteral">"rtl"</span> : <span class="stringliteral">"ltr"</span> );
<a name="l02489"></a>02489 
<a name="l02490"></a>02490     QString htmlStr;
<a name="l02491"></a>02491 
<a name="l02492"></a>02492     <span class="keywordflow">if</span> (block.isSigned) {
<a name="l02493"></a>02493         htmlStr += <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\""</span> + block.signClass + <span class="stringliteral">"H\"&gt;"</span>;
<a name="l02494"></a>02494         htmlStr += <span class="stringliteral">"&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span> +
<a name="l02495"></a>02495             i18n( <span class="stringliteral">"End of signed message"</span> ) +
<a name="l02496"></a>02496             <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"</span>;
<a name="l02497"></a>02497     }
<a name="l02498"></a>02498 
<a name="l02499"></a>02499     <span class="keywordflow">if</span> (block.isEncrypted) {
<a name="l02500"></a>02500         htmlStr += <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\"encrH\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span> +
<a name="l02501"></a>02501                 i18n( <span class="stringliteral">"End of encrypted message"</span> ) +
<a name="l02502"></a>02502             <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"</span>;
<a name="l02503"></a>02503     }
<a name="l02504"></a>02504 
<a name="l02505"></a>02505     <span class="keywordflow">if</span>( block.isEncapsulatedRfc822Message )
<a name="l02506"></a>02506     {
<a name="l02507"></a>02507         htmlStr += <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;tr class=\"rfc822H\"&gt;&lt;td dir=\""</span> + dir + <span class="stringliteral">"\"&gt;"</span> +
<a name="l02508"></a>02508             i18n( <span class="stringliteral">"End of encapsulated message"</span> ) +
<a name="l02509"></a>02509             <span class="stringliteral">"&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;"</span>;
<a name="l02510"></a>02510     }
<a name="l02511"></a>02511 
<a name="l02512"></a>02512     <span class="keywordflow">return</span> htmlStr;
<a name="l02513"></a>02513 }
<a name="l02514"></a>02514 
<a name="l02515"></a>02515 <span class="comment">//-----------------------------------------------------------------------------</span>
<a name="l02516"></a>02516 <span class="keywordtype">void</span> ObjectTreeParser::writeBodyStr( <span class="keyword">const</span> QCString&amp; aStr, <span class="keyword">const</span> QTextCodec *aCodec,
<a name="l02517"></a>02517                                 <span class="keyword">const</span> QString&amp; fromAddress )
<a name="l02518"></a>02518 {
<a name="l02519"></a>02519   KMMsgSignatureState dummy1;
<a name="l02520"></a>02520   KMMsgEncryptionState dummy2;
<a name="l02521"></a>02521   writeBodyStr( aStr, aCodec, fromAddress, dummy1, dummy2, <span class="keyword">false</span> );
<a name="l02522"></a>02522 }
<a name="l02523"></a>02523 
<a name="l02524"></a>02524 <span class="comment">//-----------------------------------------------------------------------------</span>
<a name="l02525"></a>02525 <span class="keywordtype">void</span> ObjectTreeParser::writeBodyStr( <span class="keyword">const</span> QCString&amp; aStr, <span class="keyword">const</span> QTextCodec *aCodec,
<a name="l02526"></a>02526                                 <span class="keyword">const</span> QString&amp; fromAddress,
<a name="l02527"></a>02527                                 KMMsgSignatureState&amp;  inlineSignatureState,
<a name="l02528"></a>02528                                 KMMsgEncryptionState&amp; inlineEncryptionState,
<a name="l02529"></a>02529                                 <span class="keywordtype">bool</span> decorate )
<a name="l02530"></a>02530 {
<a name="l02531"></a>02531   <span class="keywordtype">bool</span> goodSignature = <span class="keyword">false</span>;
<a name="l02532"></a>02532   Kpgp::Module* pgp = Kpgp::Module::getKpgp();
<a name="l02533"></a>02533   assert(pgp != 0);
<a name="l02534"></a>02534   <span class="keywordtype">bool</span> isPgpMessage = <span class="keyword">false</span>; <span class="comment">// true if the message contains at least one</span>
<a name="l02535"></a>02535                              <span class="comment">// PGP MESSAGE or one PGP SIGNED MESSAGE block</span>
<a name="l02536"></a>02536   QString dir = ( QApplication::reverseLayout() ? <span class="stringliteral">"rtl"</span> : <span class="stringliteral">"ltr"</span> );
<a name="l02537"></a>02537   QString headerStr = QString(<span class="stringliteral">"&lt;div dir=\"%1\"&gt;"</span>).arg(dir);
<a name="l02538"></a>02538 
<a name="l02539"></a>02539   inlineSignatureState  = KMMsgNotSigned;
<a name="l02540"></a>02540   inlineEncryptionState = KMMsgNotEncrypted;
<a name="l02541"></a>02541   QPtrList&lt;Kpgp::Block&gt; pgpBlocks;
<a name="l02542"></a>02542   QStrList nonPgpBlocks;
<a name="l02543"></a>02543   <span class="keywordflow">if</span>( Kpgp::Module::prepareMessageForDecryption( aStr, pgpBlocks, nonPgpBlocks ) )
<a name="l02544"></a>02544   {
<a name="l02545"></a>02545       <span class="keywordtype">bool</span> isEncrypted = <span class="keyword">false</span>, isSigned = <span class="keyword">false</span>;
<a name="l02546"></a>02546       <span class="keywordtype">bool</span> fullySignedOrEncrypted = <span class="keyword">true</span>;
<a name="l02547"></a>02547       <span class="keywordtype">bool</span> firstNonPgpBlock = <span class="keyword">true</span>;
<a name="l02548"></a>02548       <span class="keywordtype">bool</span> couldDecrypt = <span class="keyword">false</span>;
<a name="l02549"></a>02549       QString signer;
<a name="l02550"></a>02550       QCString keyId;
<a name="l02551"></a>02551       QString decryptionError;
<a name="l02552"></a>02552       Kpgp::Validity keyTrust = Kpgp::KPGP_VALIDITY_FULL;
<a name="l02553"></a>02553 
<a name="l02554"></a>02554       QPtrListIterator&lt;Kpgp::Block&gt; pbit( pgpBlocks );
<a name="l02555"></a>02555 
<a name="l02556"></a>02556       QStrListIterator npbit( nonPgpBlocks );
<a name="l02557"></a>02557 
<a name="l02558"></a>02558       QString htmlStr;
<a name="l02559"></a>02559       <span class="keywordflow">for</span>( ; *pbit != 0; ++pbit, ++npbit )
<a name="l02560"></a>02560       {
<a name="l02561"></a>02561           <span class="comment">// insert the next Non-OpenPGP block</span>
<a name="l02562"></a>02562           QCString str( *npbit );
<a name="l02563"></a>02563           <span class="keywordflow">if</span>( !str.isEmpty() ) {
<a name="l02564"></a>02564             htmlStr += quotedHTML( aCodec-&gt;toUnicode( str ), decorate );
<a name="l02565"></a>02565             kdDebug( 5006 ) &lt;&lt; <span class="stringliteral">"Non-empty Non-OpenPGP block found: '"</span> &lt;&lt; str
<a name="l02566"></a>02566                             &lt;&lt; <span class="stringliteral">"'"</span> &lt;&lt; endl;
<a name="l02567"></a>02567             <span class="comment">// treat messages with empty lines before the first clearsigned</span>
<a name="l02568"></a>02568             <span class="comment">// block as fully signed/encrypted</span>
<a name="l02569"></a>02569             <span class="keywordflow">if</span>( firstNonPgpBlock ) {
<a name="l02570"></a>02570               <span class="comment">// check whether str only consists of \n</span>
<a name="l02571"></a>02571               <span class="keywordflow">for</span>( QCString::ConstIterator c = str.begin(); *c; ++c ) {
<a name="l02572"></a>02572                 <span class="keywordflow">if</span>( *c != <span class="charliteral">'\n'</span> ) {
<a name="l02573"></a>02573                   fullySignedOrEncrypted = <span class="keyword">false</span>;
<a name="l02574"></a>02574                   <span class="keywordflow">break</span>;
<a name="l02575"></a>02575                 }
<a name="l02576"></a>02576               }
<a name="l02577"></a>02577             }
<a name="l02578"></a>02578             <span class="keywordflow">else</span> {
<a name="l02579"></a>02579               fullySignedOrEncrypted = <span class="keyword">false</span>;
<a name="l02580"></a>02580             }
<a name="l02581"></a>02581           }
<a name="l02582"></a>02582           firstNonPgpBlock = <span class="keyword">false</span>;
<a name="l02583"></a>02583 
<a name="l02584"></a>02584           <span class="comment">//htmlStr += "&lt;br&gt;";</span>
<a name="l02585"></a>02585 
<a name="l02586"></a>02586           Kpgp::Block* block = *pbit;
<a name="l02587"></a>02587           <span class="keywordflow">if</span>( ( block-&gt;type() == Kpgp::PgpMessageBlock &amp;&amp;
<a name="l02588"></a>02588                 <span class="comment">// ### Workaround for bug 56693</span>
<a name="l02589"></a>02589                 !kmkernel-&gt;contextMenuShown() ) ||
<a name="l02590"></a>02590               ( block-&gt;type() == Kpgp::ClearsignedBlock ) )
<a name="l02591"></a>02591           {
<a name="l02592"></a>02592               isPgpMessage = <span class="keyword">true</span>;
<a name="l02593"></a>02593               <span class="keywordflow">if</span>( block-&gt;type() == Kpgp::PgpMessageBlock )
<a name="l02594"></a>02594               {
<a name="l02595"></a>02595                 <span class="keywordflow">if</span> ( mReader )
<a name="l02596"></a>02596                   emit mReader-&gt;noDrag();
<a name="l02597"></a>02597                 <span class="comment">// try to decrypt this OpenPGP block</span>
<a name="l02598"></a>02598                 couldDecrypt = block-&gt;decrypt();
<a name="l02599"></a>02599                 isEncrypted = block-&gt;isEncrypted();
<a name="l02600"></a>02600                 <span class="keywordflow">if</span> (!couldDecrypt) {
<a name="l02601"></a>02601                   decryptionError = pgp-&gt;lastErrorMsg();
<a name="l02602"></a>02602                 }
<a name="l02603"></a>02603               }
<a name="l02604"></a>02604               <span class="keywordflow">else</span>
<a name="l02605"></a>02605               {
<a name="l02606"></a>02606                   <span class="comment">// try to verify this OpenPGP block</span>
<a name="l02607"></a>02607                   block-&gt;verify();
<a name="l02608"></a>02608               }
<a name="l02609"></a>02609 
<a name="l02610"></a>02610               isSigned = block-&gt;isSigned();
<a name="l02611"></a>02611               <span class="keywordflow">if</span>( isSigned )
<a name="l02612"></a>02612               {
<a name="l02613"></a>02613                   keyId = block-&gt;signatureKeyId();
<a name="l02614"></a>02614                   signer = block-&gt;signatureUserId();
<a name="l02615"></a>02615                   <span class="keywordflow">if</span>( !signer.isEmpty() )
<a name="l02616"></a>02616                   {
<a name="l02617"></a>02617                       goodSignature = block-&gt;goodSignature();
<a name="l02618"></a>02618 
<a name="l02619"></a>02619                       <span class="keywordflow">if</span>( !keyId.isEmpty() ) {
<a name="l02620"></a>02620                         keyTrust = pgp-&gt;keyTrust( keyId );
<a name="l02621"></a>02621                         Kpgp::Key* key = pgp-&gt;publicKey( keyId );
<a name="l02622"></a>02622                         <span class="keywordflow">if</span> ( key ) {
<a name="l02623"></a>02623                           <span class="comment">// Use the user ID from the key because this one</span>
<a name="l02624"></a>02624                           <span class="comment">// is charset safe.</span>
<a name="l02625"></a>02625                           signer = key-&gt;primaryUserID();
<a name="l02626"></a>02626                         }
<a name="l02627"></a>02627                       }
<a name="l02628"></a>02628                       <span class="keywordflow">else</span>
<a name="l02629"></a>02629                         <span class="comment">// This is needed for the PGP 6 support because PGP 6 doesn't</span>
<a name="l02630"></a>02630                         <span class="comment">// print the key id of the signing key if the key is known.</span>
<a name="l02631"></a>02631                         keyTrust = pgp-&gt;keyTrust( signer );
<a name="l02632"></a>02632                   }
<a name="l02633"></a>02633               }
<a name="l02634"></a>02634 
<a name="l02635"></a>02635               <span class="keywordflow">if</span>( isSigned )
<a name="l02636"></a>02636                 inlineSignatureState = KMMsgPartiallySigned;
<a name="l02637"></a>02637               <span class="keywordflow">if</span>( isEncrypted )
<a name="l02638"></a>02638                 inlineEncryptionState = KMMsgPartiallyEncrypted;
<a name="l02639"></a>02639 
<a name="l02640"></a>02640               PartMetaData messagePart;
<a name="l02641"></a>02641 
<a name="l02642"></a>02642               messagePart.isSigned = isSigned;
<a name="l02643"></a>02643               messagePart.technicalProblem = <span class="keyword">false</span>;
<a name="l02644"></a>02644               messagePart.isGoodSignature = goodSignature;
<a name="l02645"></a>02645               messagePart.isEncrypted = isEncrypted;
<a name="l02646"></a>02646               messagePart.isDecryptable = couldDecrypt;
<a name="l02647"></a>02647               messagePart.decryptionError = decryptionError;
<a name="l02648"></a>02648               messagePart.signer = signer;
<a name="l02649"></a>02649               messagePart.keyId = keyId;
<a name="l02650"></a>02650               messagePart.keyTrust = keyTrust;
<a name="l02651"></a>02651 
<a name="l02652"></a>02652               htmlStr += writeSigstatHeader( messagePart, 0, fromAddress );
<a name="l02653"></a>02653 
<a name="l02654"></a>02654               htmlStr += quotedHTML( aCodec-&gt;toUnicode( block-&gt;text() ), decorate );
<a name="l02655"></a>02655               htmlStr += writeSigstatFooter( messagePart );
<a name="l02656"></a>02656           }
<a name="l02657"></a>02657           <span class="keywordflow">else</span> <span class="comment">// block is neither message block nor clearsigned block</span>
<a name="l02658"></a>02658             htmlStr += quotedHTML( aCodec-&gt;toUnicode( block-&gt;text() ),
<a name="l02659"></a>02659                                    decorate );
<a name="l02660"></a>02660       }
<a name="l02661"></a>02661 
<a name="l02662"></a>02662       <span class="comment">// add the last Non-OpenPGP block</span>
<a name="l02663"></a>02663       QCString str( nonPgpBlocks.last() );
<a name="l02664"></a>02664       <span class="keywordflow">if</span>( !str.isEmpty() ) {
<a name="l02665"></a>02665         htmlStr += quotedHTML( aCodec-&gt;toUnicode( str ), decorate );
<a name="l02666"></a>02666         <span class="comment">// Even if the trailing Non-OpenPGP block isn't empty we still</span>
<a name="l02667"></a>02667         <span class="comment">// consider the message part fully signed/encrypted because else</span>
<a name="l02668"></a>02668         <span class="comment">// all inline signed mailing list messages would only be partially</span>
<a name="l02669"></a>02669         <span class="comment">// signed because of the footer which is often added by the mailing</span>
<a name="l02670"></a>02670         <span class="comment">// list software. IK, 2003-02-15</span>
<a name="l02671"></a>02671       }
<a name="l02672"></a>02672       <span class="keywordflow">if</span>( fullySignedOrEncrypted ) {
<a name="l02673"></a>02673         <span class="keywordflow">if</span>( inlineSignatureState == KMMsgPartiallySigned )
<a name="l02674"></a>02674           inlineSignatureState = KMMsgFullySigned;
<a name="l02675"></a>02675         <span class="keywordflow">if</span>( inlineEncryptionState == KMMsgPartiallyEncrypted )
<a name="l02676"></a>02676           inlineEncryptionState = KMMsgFullyEncrypted;
<a name="l02677"></a>02677       }
<a name="l02678"></a>02678       htmlWriter()-&gt;queue( htmlStr );
<a name="l02679"></a>02679   }
<a name="l02680"></a>02680   <span class="keywordflow">else</span>
<a name="l02681"></a>02681     htmlWriter()-&gt;queue( quotedHTML( aCodec-&gt;toUnicode( aStr ), decorate ) );
<a name="l02682"></a>02682 }
<a name="l02683"></a>02683 
<a name="l02684"></a>02684 
<a name="l02685"></a>02685 QString ObjectTreeParser::quotedHTML( <span class="keyword">const</span> QString&amp; s, <span class="keywordtype">bool</span> decorate )
<a name="l02686"></a>02686 {
<a name="l02687"></a>02687   assert( mReader );
<a name="l02688"></a>02688   assert( cssHelper() );
<a name="l02689"></a>02689 
<a name="l02690"></a>02690   <span class="keywordtype">int</span> convertFlags = LinkLocator::PreserveSpaces;
<a name="l02691"></a>02691   <span class="keywordflow">if</span> ( decorate &amp;&amp; GlobalSettings::self()-&gt;showEmoticons() ) {
<a name="l02692"></a>02692     convertFlags |= LinkLocator::ReplaceSmileys;
<a name="l02693"></a>02693   }
<a name="l02694"></a>02694   QString htmlStr;
<a name="l02695"></a>02695   <span class="keyword">const</span> QString normalStartTag = cssHelper()-&gt;nonQuotedFontTag();
<a name="l02696"></a>02696   QString quoteFontTag[3];
<a name="l02697"></a>02697   QString deepQuoteFontTag[3];
<a name="l02698"></a>02698   <span class="keywordflow">for</span> ( <span class="keywordtype">int</span> i = 0 ; i &lt; 3 ; ++i ) {
<a name="l02699"></a>02699     quoteFontTag[i] = cssHelper()-&gt;quoteFontTag( i );
<a name="l02700"></a>02700     deepQuoteFontTag[i] = cssHelper()-&gt;quoteFontTag( i+3 );
<a name="l02701"></a>02701   }
<a name="l02702"></a>02702   <span class="keyword">const</span> QString normalEndTag = <span class="stringliteral">"&lt;/div&gt;"</span>;
<a name="l02703"></a>02703   <span class="keyword">const</span> QString quoteEnd = <span class="stringliteral">"&lt;/div&gt;"</span>;
<a name="l02704"></a>02704 
<a name="l02705"></a>02705   <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> pos, beg;
<a name="l02706"></a>02706   <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> length = s.length();
<a name="l02707"></a>02707 
<a name="l02708"></a>02708   <span class="comment">// skip leading empty lines</span>
<a name="l02709"></a>02709   <span class="keywordflow">for</span> ( pos = 0; pos &lt; length &amp;&amp; s[pos] &lt;= <span class="charliteral">' '</span>; pos++ );
<a name="l02710"></a>02710   <span class="keywordflow">while</span> (pos &gt; 0 &amp;&amp; (s[pos-1] == <span class="charliteral">' '</span> || s[pos-1] == <span class="charliteral">'\t'</span>)) pos--;
<a name="l02711"></a>02711   beg = pos;
<a name="l02712"></a>02712 
<a name="l02713"></a>02713   <span class="keywordtype">int</span> currQuoteLevel = -2; <span class="comment">// -2 == no previous lines</span>
<a name="l02714"></a>02714   <span class="keywordtype">bool</span> curHidden = <span class="keyword">false</span>; <span class="comment">// no hide any block</span>
<a name="l02715"></a>02715 
<a name="l02716"></a>02716   <span class="keywordflow">while</span> (beg&lt;length)
<a name="l02717"></a>02717   {
<a name="l02718"></a>02718     QString line;
<a name="l02719"></a>02719 
<a name="l02720"></a>02720     <span class="comment">/* search next occurrence of '\n' */</span>
<a name="l02721"></a>02721     pos = s.find(<span class="charliteral">'\n'</span>, beg, FALSE);
<a name="l02722"></a>02722     <span class="keywordflow">if</span> (pos == (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span>)(-1))
<a name="l02723"></a>02723         pos = length;
<a name="l02724"></a>02724 
<a name="l02725"></a>02725     line = s.mid(beg,pos-beg);
<a name="l02726"></a>02726     beg = pos+1;
<a name="l02727"></a>02727 
<a name="l02728"></a>02728     <span class="comment">/* calculate line's current quoting depth */</span>
<a name="l02729"></a>02729     <span class="keywordtype">int</span> actQuoteLevel = -1;
<a name="l02730"></a>02730 
<a name="l02731"></a>02731     <span class="keywordflow">if</span> ( GlobalSettings::self()-&gt;showExpandQuotesMark() )
<a name="l02732"></a>02732     {
<a name="l02733"></a>02733       <span class="comment">// Cache Icons</span>
<a name="l02734"></a>02734       <span class="keywordflow">if</span> ( mCollapseIcon.isEmpty() ) {
<a name="l02735"></a>02735         mCollapseIcon= LinkLocator::pngToDataUrl(
<a name="l02736"></a>02736             KGlobal::instance()-&gt;iconLoader()-&gt;iconPath( <span class="stringliteral">"quotecollapse"</span>,0 ));
<a name="l02737"></a>02737       }
<a name="l02738"></a>02738       <span class="keywordflow">if</span> ( mExpandIcon.isEmpty() )
<a name="l02739"></a>02739         mExpandIcon= LinkLocator::pngToDataUrl(
<a name="l02740"></a>02740             KGlobal::instance()-&gt;iconLoader()-&gt;iconPath( <span class="stringliteral">"quoteexpand"</span>,0 ));
<a name="l02741"></a>02741     }
<a name="l02742"></a>02742 
<a name="l02743"></a>02743     <span class="keywordflow">for</span> (<span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> p=0; p&lt;line.length(); p++) {
<a name="l02744"></a>02744       <span class="keywordflow">switch</span> (line[p].latin1()) {
<a name="l02745"></a>02745         <span class="keywordflow">case</span> <span class="charliteral">'&gt;'</span>:
<a name="l02746"></a>02746         <span class="keywordflow">case</span> <span class="charliteral">'|'</span>:
<a name="l02747"></a>02747           actQuoteLevel++;
<a name="l02748"></a>02748           <span class="keywordflow">break</span>;
<a name="l02749"></a>02749         <span class="keywordflow">case</span> <span class="charliteral">' '</span>:  <span class="comment">// spaces and tabs are allowed between the quote markers</span>
<a name="l02750"></a>02750         <span class="keywordflow">case</span> <span class="charliteral">'\t'</span>:
<a name="l02751"></a>02751         <span class="keywordflow">case</span> <span class="charliteral">'\r'</span>:
<a name="l02752"></a>02752           <span class="keywordflow">break</span>;
<a name="l02753"></a>02753         <span class="keywordflow">default</span>:  <span class="comment">// stop quoting depth calculation</span>
<a name="l02754"></a>02754           p = line.length();
<a name="l02755"></a>02755           <span class="keywordflow">break</span>;
<a name="l02756"></a>02756       }
<a name="l02757"></a>02757     } <span class="comment">/* for() */</span>
<a name="l02758"></a>02758 
<a name="l02759"></a>02759     <span class="keywordtype">bool</span> actHidden = <span class="keyword">false</span>;
<a name="l02760"></a>02760     QString textExpand;
<a name="l02761"></a>02761 
<a name="l02762"></a>02762     <span class="comment">// This quoted line needs be hiden</span>
<a name="l02763"></a>02763     <span class="keywordflow">if</span> (GlobalSettings::self()-&gt;showExpandQuotesMark() &amp;&amp; mReader-&gt;mLevelQuote &gt;= 0
<a name="l02764"></a>02764         &amp;&amp; mReader-&gt;mLevelQuote &lt;= ( actQuoteLevel ) )
<a name="l02765"></a>02765       actHidden = <span class="keyword">true</span>;
<a name="l02766"></a>02766 
<a name="l02767"></a>02767     <span class="keywordflow">if</span> ( actQuoteLevel != currQuoteLevel ) {
<a name="l02768"></a>02768       <span class="comment">/* finish last quotelevel */</span>
<a name="l02769"></a>02769       <span class="keywordflow">if</span> (currQuoteLevel == -1)
<a name="l02770"></a>02770         htmlStr.append( normalEndTag );
<a name="l02771"></a>02771       <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( currQuoteLevel &gt;= 0 &amp;&amp; !curHidden )
<a name="l02772"></a>02772         htmlStr.append( quoteEnd );
<a name="l02773"></a>02773 
<a name="l02774"></a>02774       <span class="comment">/* start new quotelevel */</span>
<a name="l02775"></a>02775       <span class="keywordflow">if</span> (actQuoteLevel == -1)
<a name="l02776"></a>02776         htmlStr += normalStartTag;
<a name="l02777"></a>02777       <span class="keywordflow">else</span>
<a name="l02778"></a>02778       {
<a name="l02779"></a>02779         <span class="keywordflow">if</span> ( GlobalSettings::self()-&gt;showExpandQuotesMark() )
<a name="l02780"></a>02780         {
<a name="l02781"></a>02781           <span class="keywordflow">if</span> (  actHidden )
<a name="l02782"></a>02782           {
<a name="l02783"></a>02783             <span class="comment">//only show the QuoteMark when is the first line of the level hidden</span>
<a name="l02784"></a>02784             <span class="keywordflow">if</span> ( !curHidden )
<a name="l02785"></a>02785             {
<a name="l02786"></a>02786               <span class="comment">//Expand all quotes</span>
<a name="l02787"></a>02787               htmlStr += <span class="stringliteral">"&lt;div class=\"quotelevelmark\" &gt;"</span> ;
<a name="l02788"></a>02788               htmlStr += QString( <span class="stringliteral">"&lt;a href=\"kmail:levelquote?%1 \"&gt;"</span>
<a name="l02789"></a>02789                   <span class="stringliteral">"&lt;img src=\"%2\" alt=\"\" title=\"\"/&gt;&lt;/a&gt;"</span> )
<a name="l02790"></a>02790                 .arg(-1)
<a name="l02791"></a>02791                 .arg( mExpandIcon );
<a name="l02792"></a>02792               htmlStr += <span class="stringliteral">"&lt;/div&gt;&lt;br/&gt;"</span>;
<a name="l02793"></a>02793               htmlStr += quoteEnd;
<a name="l02794"></a>02794             }
<a name="l02795"></a>02795           }<span class="keywordflow">else</span> {
<a name="l02796"></a>02796             htmlStr += <span class="stringliteral">"&lt;div class=\"quotelevelmark\" &gt;"</span> ;
<a name="l02797"></a>02797             htmlStr += QString( <span class="stringliteral">"&lt;a href=\"kmail:levelquote?%1 \"&gt;"</span>
<a name="l02798"></a>02798                 <span class="stringliteral">"&lt;img src=\"%2\" alt=\"\" title=\"\"/&gt;&lt;/a&gt;"</span> )
<a name="l02799"></a>02799               .arg(actQuoteLevel)
<a name="l02800"></a>02800               .arg( mCollapseIcon);
<a name="l02801"></a>02801             htmlStr += <span class="stringliteral">"&lt;/div&gt;"</span>;
<a name="l02802"></a>02802             <span class="keywordflow">if</span> ( actQuoteLevel &lt; 3 )
<a name="l02803"></a>02803               htmlStr += quoteFontTag[actQuoteLevel];
<a name="l02804"></a>02804             <span class="keywordflow">else</span>
<a name="l02805"></a>02805               htmlStr += deepQuoteFontTag[actQuoteLevel%3];
<a name="l02806"></a>02806           }
<a name="l02807"></a>02807         } <span class="keywordflow">else</span>
<a name="l02808"></a>02808             <span class="keywordflow">if</span> ( actQuoteLevel &lt; 3 )
<a name="l02809"></a>02809               htmlStr += quoteFontTag[actQuoteLevel];
<a name="l02810"></a>02810             <span class="keywordflow">else</span>
<a name="l02811"></a>02811               htmlStr += deepQuoteFontTag[actQuoteLevel%3];
<a name="l02812"></a>02812       }
<a name="l02813"></a>02813       currQuoteLevel = actQuoteLevel;
<a name="l02814"></a>02814     }
<a name="l02815"></a>02815     curHidden = actHidden;
<a name="l02816"></a>02816 
<a name="l02817"></a>02817 
<a name="l02818"></a>02818     <span class="keywordflow">if</span> ( !actHidden )
<a name="l02819"></a>02819     {
<a name="l02820"></a>02820       <span class="comment">// don't write empty &lt;div ...&gt;&lt;/div&gt; blocks (they have zero height)</span>
<a name="l02821"></a>02821       <span class="comment">// ignore ^M DOS linebreaks</span>
<a name="l02822"></a>02822       <span class="keywordflow">if</span>( !line.replace(<span class="charliteral">'\015'</span>, <span class="stringliteral">""</span>).isEmpty() )
<a name="l02823"></a>02823       {
<a name="l02824"></a>02824          htmlStr +=QString( <span class="stringliteral">"&lt;div dir=\"%1\"&gt;"</span> ).arg( line.isRightToLeft() ? <span class="stringliteral">"rtl"</span>:<span class="stringliteral">"ltr"</span> );
<a name="l02825"></a>02825          htmlStr += LinkLocator::convertToHtml( line, convertFlags );
<a name="l02826"></a>02826          htmlStr += QString( <span class="stringliteral">"&lt;/div&gt;"</span> );
<a name="l02827"></a>02827       }
<a name="l02828"></a>02828       <span class="keywordflow">else</span>
<a name="l02829"></a>02829         htmlStr += <span class="stringliteral">"&lt;br&gt;"</span>;
<a name="l02830"></a>02830     }
<a name="l02831"></a>02831   } <span class="comment">/* while() */</span>
<a name="l02832"></a>02832 
<a name="l02833"></a>02833   <span class="comment">/* really finish the last quotelevel */</span>
<a name="l02834"></a>02834   <span class="keywordflow">if</span> (currQuoteLevel == -1)
<a name="l02835"></a>02835      htmlStr.append( normalEndTag );
<a name="l02836"></a>02836   <span class="keywordflow">else</span>
<a name="l02837"></a>02837      htmlStr.append( quoteEnd );
<a name="l02838"></a>02838 
<a name="l02839"></a>02839   <span class="comment">//kdDebug(5006) &lt;&lt; "KMReaderWin::quotedHTML:\n"</span>
<a name="l02840"></a>02840   <span class="comment">//              &lt;&lt; "========================================\n"</span>
<a name="l02841"></a>02841   <span class="comment">//              &lt;&lt; htmlStr</span>
<a name="l02842"></a>02842   <span class="comment">//              &lt;&lt; "\n======================================\n";</span>
<a name="l02843"></a>02843   <span class="keywordflow">return</span> htmlStr;
<a name="l02844"></a>02844 }
<a name="l02845"></a>02845 
<a name="l02846"></a>02846 
<a name="l02847"></a>02847 
<a name="l02848"></a>02848   <span class="keyword">const</span> QTextCodec * ObjectTreeParser::codecFor( partNode * node )<span class="keyword"> const </span>{
<a name="l02849"></a>02849     assert( node );
<a name="l02850"></a>02850     <span class="keywordflow">if</span> ( mReader &amp;&amp; mReader-&gt;overrideCodec() )
<a name="l02851"></a>02851       <span class="keywordflow">return</span> mReader-&gt;overrideCodec();
<a name="l02852"></a>02852     <span class="keywordflow">return</span> node-&gt;msgPart().codec();
<a name="l02853"></a>02853   }
<a name="l02854"></a>02854 
<a name="l02855"></a>02855 <span class="preprocessor">#ifdef MARCS_DEBUG</span>
<a name="l02856"></a>02856 <span class="preprocessor"></span>  <span class="keywordtype">void</span> ObjectTreeParser::dumpToFile( <span class="keyword">const</span> <span class="keywordtype">char</span> * filename, <span class="keyword">const</span> <span class="keywordtype">char</span> * start,
<a name="l02857"></a>02857                                      <span class="keywordtype">size_t</span> len ) {
<a name="l02858"></a>02858     assert( filename );
<a name="l02859"></a>02859 
<a name="l02860"></a>02860     QFile f( filename );
<a name="l02861"></a>02861     <span class="keywordflow">if</span> ( f.open( IO_WriteOnly ) ) {
<a name="l02862"></a>02862       <span class="keywordflow">if</span> ( start ) {
<a name="l02863"></a>02863         QDataStream ds( &amp;f );
<a name="l02864"></a>02864         ds.writeRawBytes( start, len );
<a name="l02865"></a>02865       }
<a name="l02866"></a>02866       f.close();  <span class="comment">// If data is 0 we just create a zero length file.</span>
<a name="l02867"></a>02867     }
<a name="l02868"></a>02868   }
<a name="l02869"></a>02869 <span class="preprocessor">#endif // !NDEBUG</span>
<a name="l02870"></a>02870 <span class="preprocessor"></span>
<a name="l02871"></a>02871 
<a name="l02872"></a>02872 } <span class="comment">// namespace KMail</span>
</pre></div></div>
    </div></div>


      </td>
  </tr>
  <tr>
    <td valign="top" id="leftmenu" width="25%">
      <a name="navigation"></a>
      <div class="menu_box"><h2>kmail</h2>
<div class="nav_list">
<ul><li><a href="index.html">Main Page</a></li><li><a href="namespaces.html">Namespace List</a></li><li><a href="hierarchy.html">Class Hierarchy</a></li><li><a href="classes.html">Alphabetical List</a></li><li><a href="annotated.html">Class List</a></li><li><a href="files.html">File List</a></li><li><a href="namespacemembers.html">Namespace Members</a></li><li><a href="functions.html">Class Members</a></li><li><a href="pages.html">Related Pages</a></li></ul>
<!--
<h2>Class Picker</h2>
<div style="text-align: center;">
<form name="guideform">
<select name="guidelinks" style="width:100%;" onChange="window.location=document.guideform.guidelinks.options[document.guideform.guidelinks.selectedIndex].value">
<option value="annotated.html">-- Choose --</option>
  <option value="classAccountUpdater.html">accountupdater</option>,  <option value="classAttachmentModifyCommand.html">attachmentmodifycommand</option>,  <option value="classFolderStorage.html">folderstorage</option>,  <option value="classKCursorSaver.html">kcursorsaver</option>,  <option value="classKleo_1_1KeyResolver.html">kleo::keyresolver</option>,  <option value="classKListViewIndexedSearchLine.html">klistviewindexedsearchline</option>,  <option value="classKMAcctFolder.html">kmacctfolder</option>,  <option value="classKMAcctSelDlg.html">kmacctseldlg</option>,  <option value="classKMail_1_1AccountComboBox.html">kmail::accountcombobox</option>,  <option value="classKMail_1_1AccountManager.html">kmail::accountmanager</option>,  <option value="classKMail_1_1ACLEntryDialog.html">kmail::aclentrydialog</option>,  <option value="classKMail_1_1ACLJobs_1_1DeleteACLJob.html">kmail::acljobs::deleteacljob</option>,  <option value="classKMail_1_1ACLJobs_1_1GetACLJob.html">kmail::acljobs::getacljob</option>,  <option value="classKMail_1_1ACLJobs_1_1GetUserRightsJob.html">kmail::acljobs::getuserrightsjob</option>,  <option value="classKMail_1_1ACLJobs_1_1MultiSetACLJob.html">kmail::acljobs::multisetacljob</option>,  <option value="classKMail_1_1AnnotationJobs_1_1GetAnnotationJob.html">kmail::annotationjobs::getannotationjob</option>,  <option value="classKMail_1_1AnnotationJobs_1_1MultiGetAnnotationJob.html">kmail::annotationjobs::multigetannotationjob</option>,  <option value="classKMail_1_1AnnotationJobs_1_1MultiSetAnnotationJob.html">kmail::annotationjobs::multisetannotationjob</option>,  <option value="classKMail_1_1AnnotationJobs_1_1MultiUrlGetAnnotationJob.html">kmail::annotationjobs::multiurlgetannotationjob</option>,  <option value="classKMail_1_1AntiSpamConfig.html">kmail::antispamconfig</option>,  <option value="classKMail_1_1AntiSpamWizard.html">kmail::antispamwizard</option>,  <option value="classKMail_1_1AntiSpamWizard_1_1ConfigReader.html">kmail::antispamwizard::configreader</option>,  <option value="classKMail_1_1AntiSpamWizard_1_1SpamToolConfig.html">kmail::antispamwizard::spamtoolconfig</option>,  <option value="classKMail_1_1Callback.html">kmail::callback</option>,  <option value="classKMail_1_1CopyFolderJob.html">kmail::copyfolderjob</option>,  <option value="classKMail_1_1DictionaryComboBox.html">kmail::dictionarycombobox</option>,  <option value="classKMail_1_1EditorWatcher.html">kmail::editorwatcher</option>,  <option value="classKMail_1_1FilterImporterExporter.html">kmail::filterimporterexporter</option>,  <option value="classKMail_1_1FilterLog.html">kmail::filterlog</option>,  <option value="classKMail_1_1FilterLogDialog.html">kmail::filterlogdialog</option>,  <option value="classKMail_1_1FolderDiaACLTab.html">kmail::folderdiaacltab</option>,  <option value="classKMail_1_1FolderDiaGeneralTab.html">kmail::folderdiageneraltab</option>,  <option value="classKMail_1_1FolderDiaQuotaTab.html">kmail::folderdiaquotatab</option>,  <option value="classKMail_1_1FolderDiaTab.html">kmail::folderdiatab</option>,  <option value="classKMail_1_1FolderDiaTemplatesTab.html">kmail::folderdiatemplatestab</option>,  <option value="classKMail_1_1FolderRequester.html">kmail::folderrequester</option>,  <option value="classKMail_1_1HeaderItem.html">kmail::headeritem</option>,  <option value="classKMail_1_1HeaderStyle.html">kmail::headerstyle</option>,  <option value="classKMail_1_1HtmlStatusBar.html">kmail::htmlstatusbar</option>,  <option value="classKMail_1_1HtmlWriter.html">kmail::htmlwriter</option>,  <option value="classKMail_1_1IdentityDrag.html">kmail::identitydrag</option>,  <option value="classKMail_1_1IdentityListView.html">kmail::identitylistview</option>,  <option value="classKMail_1_1IdentityListViewItem.html">kmail::identitylistviewitem</option>,  <option value="classKMail_1_1Interface_1_1BodyPart.html">kmail::interface::bodypart</option>,  <option value="classKMail_1_1Interface_1_1BodyPartFormatterPlugin.html">kmail::interface::bodypartformatterplugin</option>,  <option value="classKMail_1_1Interface_1_1BodyPartMemento.html">kmail::interface::bodypartmemento</option>,  <option value="classKMail_1_1Interface_1_1BodyPartURLHandler.html">kmail::interface::bodyparturlhandler</option>,  <option value="classKMail_1_1Interface_1_1Observable.html">kmail::interface::observable</option>,  <option value="classKMail_1_1Interface_1_1Observer.html">kmail::interface::observer</option>,  <option value="classKMail_1_1JobScheduler.html">kmail::jobscheduler</option>,  <option value="classKMail_1_1ListJob.html">kmail::listjob</option>,  <option value="classKMail_1_1MaildirCompactionJob.html">kmail::maildircompactionjob</option>,  <option value="classKMail_1_1MailingList.html">kmail::mailinglist</option>,  <option value="classKMail_1_1MboxCompactionJob.html">kmail::mboxcompactionjob</option>,  <option value="classKMail_1_1MessageActions.html">kmail::messageactions</option>,  <option value="classKMail_1_1MessageCopyHelper.html">kmail::messagecopyhelper</option>,  <option value="classKMail_1_1PartNodeBodyPart.html">kmail::partnodebodypart</option>,  <option value="classKMail_1_1PopAccount.html">kmail::popaccount</option>,  <option value="classKMail_1_1QuotaJobs_1_1GetQuotarootJob.html">kmail::quotajobs::getquotarootjob</option>,  <option value="classKMail_1_1QuotaJobs_1_1GetStorageQuotaJob.html">kmail::quotajobs::getstoragequotajob</option>,  <option value="classKMail_1_1RedirectDialog.html">kmail::redirectdialog</option>,  <option value="classKMail_1_1RenameJob.html">kmail::renamejob</option>,  <option value="classKMail_1_1RuleWidgetHandler.html">kmail::rulewidgethandler</option>,  <option value="classKMail_1_1RuleWidgetHandlerManager.html">kmail::rulewidgethandlermanager</option>,  <option value="classKMail_1_1ScheduledCompactionTask.html">kmail::scheduledcompactiontask</option>,  <option value="classKMail_1_1ScheduledExpireTask.html">kmail::scheduledexpiretask</option>,  <option value="classKMail_1_1ScheduledJob.html">kmail::scheduledjob</option>,  <option value="classKMail_1_1ScheduledTask.html">kmail::scheduledtask</option>,  <option value="classKMail_1_1SearchJob.html">kmail::searchjob</option>,  <option value="classKMail_1_1SearchWindow.html">kmail::searchwindow</option>,  <option value="classKMail_1_1SecondaryWindow.html">kmail::secondarywindow</option>,  <option value="classKMail_1_1SieveDebugDialog.html">kmail::sievedebugdialog</option>,  <option value="classKMail_1_1SortCacheItem.html">kmail::sortcacheitem</option>,  <option value="classKMail_1_1SpamHeaderAnalyzer.html">kmail::spamheaderanalyzer</option>,  <option value="classKMail_1_1SpamScore.html">kmail::spamscore</option>,  <option value="classKMail_1_1TeeHtmlWriter.html">kmail::teehtmlwriter</option>,  <option value="classKMail_1_1TransportManager.html">kmail::transportmanager</option>,  <option value="classKMail_1_1UndoInfo.html">kmail::undoinfo</option>,  <option value="classKMail_1_1URLHandler.html">kmail::urlhandler</option>,  <option value="classKMail_1_1URLHandlerManager.html">kmail::urlhandlermanager</option>,  <option value="classKMail_1_1Util_1_1LaterDeleter.html">kmail::util::laterdeleter</option>,  <option value="classKMailICalIfaceImpl.html">kmailicalifaceimpl</option>,  <option value="classKMailIface.html">kmailiface</option>,  <option value="classKMDict.html">kmdict</option>,  <option value="classKMDictItem.html">kmdictitem</option>,  <option value="classKMFilterAction.html">kmfilteraction</option>,  <option value="classKMFilterActionDict.html">kmfilteractiondict</option>,  <option value="classKMFilterActionWidget.html">kmfilteractionwidget</option>,  <option value="classKMFilterActionWithAddress.html">kmfilteractionwithaddress</option>,  <option value="classKMFilterActionWithFolder.html">kmfilteractionwithfolder</option>,  <option value="classKMFilterActionWithNone.html">kmfilteractionwithnone</option>,  <option value="classKMFilterActionWithString.html">kmfilteractionwithstring</option>,  <option value="classKMFilterActionWithStringList.html">kmfilteractionwithstringlist</option>,  <option value="classKMFilterActionWithUOID.html">kmfilteractionwithuoid</option>,  <option value="classKMFilterActionWithUrl.html">kmfilteractionwithurl</option>,  <option value="classKMFilterDlg.html">kmfilterdlg</option>,  <option value="classKMFilterListBox.html">kmfilterlistbox</option>,  <option value="classKMFolder.html">kmfolder</option>,  <option value="classKMFolderDialog.html">kmfolderdialog</option>,  <option value="classKMFolderDir.html">kmfolderdir</option>,  <option value="classKMFolderIndex.html">kmfolderindex</option>,  <option value="classKMFolderOpener.html">kmfolderopener</option>,  <option value="classKMHeaders.html">kmheaders</option>,  <option value="classKMKernel.html">kmkernel</option>,  <option value="classKMMenuCommand.html">kmmenucommand</option>,  <option value="classKMMessage.html">kmmessage</option>,  <option value="classKMMsgDict.html">kmmsgdict</option>,  <option value="classKMMsgList.html">kmmsglist</option>,  <option value="classKMMsgPartDialog.html">kmmsgpartdialog</option>,  <option value="classKMMsgPartDialogCompat.html">kmmsgpartdialogcompat</option>,  <option value="classKMPopHeadersView.html">kmpopheadersview</option>,  <option value="classKMReaderWin.html">kmreaderwin</option>,  <option value="classKMSearchPattern.html">kmsearchpattern</option>,  <option value="classKMSearchPatternEdit.html">kmsearchpatternedit</option>,  <option value="classKMSearchRule.html">kmsearchrule</option>,  <option value="classKMSearchRuleNumerical.html">kmsearchrulenumerical</option>,  <option value="classKMSearchRuleStatus.html">kmsearchrulestatus</option>,  <option value="classKMSearchRuleString.html">kmsearchrulestring</option>,  <option value="classKMSearchRuleWidget.html">kmsearchrulewidget</option>,  <option value="classKMSystemTray.html">kmsystemtray</option>,  <option value="classMailComposerIface.html">mailcomposeriface</option>,  <option value="classScalix_1_1FolderAttributeParser.html">scalix::folderattributeparser</option>,  <option value="classSnippetConfig.html">snippetconfig</option>,  <option value="classSnippetGroup.html">snippetgroup</option>,  <option value="classSnippetItem.html">snippetitem</option>,  <option value="classSnippetSettings.html">snippetsettings</option>,  <option value="classSnippetWidget.html">snippetwidget</option>,
</select>
</form>
</div>
-->
</div></div>
<div class="menu_box"><h2>API Dox</h2>
<div class="nav_list">
<ul>
<li><a href="../../akregator/html/index.html">akregator</a></li><li>&nbsp;&nbsp;<a href="../../akregator/src/html/index.html">src</a></li><li>&nbsp;&nbsp;&nbsp;&nbsp;<a href="../../akregator/src/librss/html/index.html">librss</a></li><li><a href="../../certmanager/html/index.html">certmanager</a></li><li>&nbsp;&nbsp;<a href="../../certmanager/lib/html/index.html">lib</a></li><li><a href="../../kaddressbook/html/index.html">kaddressbook</a></li><li><a href="../../kalarm/html/index.html">kalarm</a></li><li>&nbsp;&nbsp;<a href="../../kalarm/lib/html/index.html">lib</a></li><li><a href="../../kandy/html/index.html">kandy</a></li><li><a href="../../karm/html/index.html">karm</a></li><li><a href="../../kdgantt/html/index.html">kdgantt</a></li><li><a href="../../kgantt/html/index.html">kgantt</a></li><li><a href="../../kioslaves/html/index.html">kioslaves</a></li><li>&nbsp;&nbsp;<a href="../../kioslaves/imap4/html/index.html">imap4</a></li><li>&nbsp;&nbsp;<a href="../../kioslaves/mbox/html/index.html">mbox</a></li><li><a href="../../kitchensync/html/index.html">kitchensync</a></li><li><a href="../../kmail/html/index.html">kmail</a></li><li><a href="../../knotes/html/index.html">knotes</a></li><li><a href="../../konsolekalendar/html/index.html">konsolekalendar</a></li><li><a href="../../kontact/html/index.html">kontact</a></li><li><a href="../../korganizer/html/index.html">korganizer</a></li><li><a href="../../kpilot/html/index.html">kpilot</a></li><li>&nbsp;&nbsp;<a href="../../kpilot/kpilot/html/index.html">kpilot</a></li><li>&nbsp;&nbsp;<a href="../../kpilot/lib/html/index.html">lib</a></li><li><a href="../../libemailfunctions/html/index.html">libemailfunctions</a></li><li><a href="../../libkcal/html/index.html">libkcal</a></li><li><a href="../../libkdepim/html/index.html">libkdepim</a></li><li><a href="../../libkholidays/html/index.html">libkholidays</a></li><li><a href="../../libkmime/html/index.html">libkmime</a></li><li><a href="../../libkpgp/html/index.html">libkpgp</a></li><li><a href="../../libkpimidentities/html/index.html">libkpimidentities</a></li>
</ul></div></div>


        </td>
</tr>
</table>

<span class="doNotDisplay">
  <a href="http://www.kde.org/" accesskey="8">KDE Home</a> |
  <a href="http://accessibility.kde.org/" accesskey="9">KDE Accessibility Home</a> |
  <a href="http://www.kde.org/media/accesskeys.php" accesskey="0">Description of Access Keys</a>
</span>


<div style="height: 8px"></div>

<div id="footer">
  <div id="footer_left">
    Maintained by <a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;groo&#116;&#64;kde&#46;or&#x67;">Adriaan de Groot</a>
and
<a href="&#109;a&#105;&#108;&#116;&#111;&#58;w&#105;nter&#64;kde&#46;or&#x67">Allen Winter</a>.
<br/>
    KDE and K Desktop Environment are trademarks of <a href="http://www.kde.org/areas/kde-ev/" title="Homepage of the KDE non-profit Organization">KDE e.V.</a> |
    <a href="http://www.kde.org/contact/impressum.php">Legal</a>
  </div>
  <div id="footer_right"><img src="/media/images/footer_right.png" style="margin: 0px" alt="" /></div>
</div>

<!--
WARNING: DO NOT SEND MAIL TO THE FOLLOWING EMAIL ADDRESS! YOU WILL
BE BLOCKED INSTANTLY AND PERMANENTLY!
<a href="mailto:aaaatrap-425acc3b5374943f@kde.org">Block me</a>
WARNING END
-->

</body>
</html>