Sophie

Sophie

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

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: messagecomposer.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>messagecomposer.cpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 
<a name="l00031"></a>00031 <span class="preprocessor">#ifdef HAVE_CONFIG_H</span>
<a name="l00032"></a>00032 <span class="preprocessor"></span><span class="preprocessor">#include &lt;config.h&gt;</span>
<a name="l00033"></a>00033 <span class="preprocessor">#endif</span>
<a name="l00034"></a>00034 <span class="preprocessor"></span>
<a name="l00035"></a>00035 <span class="preprocessor">#include "messagecomposer.h"</span>
<a name="l00036"></a>00036 <span class="preprocessor">#include "kmmsgpart.h"</span>
<a name="l00037"></a>00037 <span class="preprocessor">#define REALLY_WANT_KMCOMPOSEWIN_H</span>
<a name="l00038"></a>00038 <span class="preprocessor"></span><span class="preprocessor">#include "kmcomposewin.h"</span>
<a name="l00039"></a>00039 <span class="preprocessor">#undef REALLY_WANT_KMCOMPOSEWIN_H</span>
<a name="l00040"></a>00040 <span class="preprocessor"></span><span class="preprocessor">#include "klistboxdialog.h"</span>
<a name="l00041"></a>00041 <span class="preprocessor">#include "kcursorsaver.h"</span>
<a name="l00042"></a>00042 <span class="preprocessor">#include "messagesender.h"</span>
<a name="l00043"></a>00043 <span class="preprocessor">#include "kmfolder.h"</span>
<a name="l00044"></a>00044 <span class="preprocessor">#include "kmfoldercombobox.h"</span>
<a name="l00045"></a>00045 <span class="preprocessor">#include "keyresolver.h"</span>
<a name="l00046"></a>00046 <span class="preprocessor">#include "kleo_util.h"</span>
<a name="l00047"></a>00047 <span class="preprocessor">#include "globalsettings.h"</span>
<a name="l00048"></a>00048 <span class="preprocessor">#include "custommimeheader.h"</span>
<a name="l00049"></a>00049 <span class="preprocessor">#include "kmedit.h"</span>
<a name="l00050"></a>00050 <span class="preprocessor">#include "util.h"</span>
<a name="l00051"></a>00051 
<a name="l00052"></a>00052 <span class="preprocessor">#include &lt;libkpimidentities/identity.h&gt;</span>
<a name="l00053"></a>00053 <span class="preprocessor">#include &lt;libkpimidentities/identitymanager.h&gt;</span>
<a name="l00054"></a>00054 <span class="preprocessor">#include &lt;libemailfunctions/email.h&gt;</span>
<a name="l00055"></a>00055 
<a name="l00056"></a>00056 <span class="preprocessor">#include &lt;ui/keyselectiondialog.h&gt;</span>
<a name="l00057"></a>00057 <span class="preprocessor">#include &lt;ui/keyapprovaldialog.h&gt;</span>
<a name="l00058"></a>00058 <span class="preprocessor">#include &lt;ui/messagebox.h&gt;</span>
<a name="l00059"></a>00059 <span class="preprocessor">#include &lt;kleo/cryptobackendfactory.h&gt;</span>
<a name="l00060"></a>00060 <span class="preprocessor">#include &lt;kleo/keylistjob.h&gt;</span>
<a name="l00061"></a>00061 <span class="preprocessor">#include &lt;kleo/encryptjob.h&gt;</span>
<a name="l00062"></a>00062 <span class="preprocessor">#include &lt;kleo/signencryptjob.h&gt;</span>
<a name="l00063"></a>00063 <span class="preprocessor">#include &lt;kleo/signjob.h&gt;</span>
<a name="l00064"></a>00064 <span class="preprocessor">#include &lt;kleo/specialjob.h&gt;</span>
<a name="l00065"></a>00065 
<a name="l00066"></a>00066 <span class="preprocessor">#include &lt;kmime_util.h&gt;</span>
<a name="l00067"></a>00067 <span class="preprocessor">#include &lt;kmime_codecs.h&gt;</span>
<a name="l00068"></a>00068 <span class="preprocessor">#include &lt;kpgpblock.h&gt;</span>
<a name="l00069"></a>00069 
<a name="l00070"></a>00070 <span class="preprocessor">#include &lt;mimelib/mimepp.h&gt;</span>
<a name="l00071"></a>00071 
<a name="l00072"></a>00072 <span class="preprocessor">#include &lt;kmessagebox.h&gt;</span>
<a name="l00073"></a>00073 <span class="preprocessor">#include &lt;klocale.h&gt;</span>
<a name="l00074"></a>00074 <span class="preprocessor">#include &lt;kinputdialog.h&gt;</span>
<a name="l00075"></a>00075 <span class="preprocessor">#include &lt;kdebug.h&gt;</span>
<a name="l00076"></a>00076 <span class="preprocessor">#include &lt;kaction.h&gt;</span>
<a name="l00077"></a>00077 <span class="preprocessor">#include &lt;qfile.h&gt;</span>
<a name="l00078"></a>00078 <span class="preprocessor">#include &lt;qtextcodec.h&gt;</span>
<a name="l00079"></a>00079 <span class="preprocessor">#include &lt;qtextedit.h&gt;</span>
<a name="l00080"></a>00080 <span class="preprocessor">#include &lt;qtimer.h&gt;</span>
<a name="l00081"></a>00081 
<a name="l00082"></a>00082 <span class="preprocessor">#include &lt;gpgmepp/key.h&gt;</span>
<a name="l00083"></a>00083 <span class="preprocessor">#include &lt;gpgmepp/keylistresult.h&gt;</span>
<a name="l00084"></a>00084 <span class="preprocessor">#include &lt;gpgmepp/encryptionresult.h&gt;</span>
<a name="l00085"></a>00085 <span class="preprocessor">#include &lt;gpgmepp/signingresult.h&gt;</span>
<a name="l00086"></a>00086 <span class="preprocessor">#include &lt;gpgmepp/context.h&gt;</span>
<a name="l00087"></a>00087 
<a name="l00088"></a>00088 <span class="preprocessor">#include &lt;algorithm&gt;</span>
<a name="l00089"></a>00089 <span class="preprocessor">#include &lt;memory&gt;</span>
<a name="l00090"></a>00090 
<a name="l00091"></a>00091 <span class="comment">// ## keep default values in sync with configuredialog.cpp, Security::CryptoTab::setup()</span>
<a name="l00092"></a>00092 <span class="comment">// This should be ported to a .kcfg one day I suppose (dfaure).</span>
<a name="l00093"></a>00093 
<a name="l00094"></a>00094 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> warnSendUnsigned() {
<a name="l00095"></a>00095     KConfigGroup group( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00096"></a>00096     <span class="keywordflow">return</span> group.readBoolEntry( <span class="stringliteral">"crypto-warning-unsigned"</span>, <span class="keyword">false</span> );
<a name="l00097"></a>00097 }
<a name="l00098"></a>00098 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> warnSendUnencrypted() {
<a name="l00099"></a>00099     KConfigGroup group( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00100"></a>00100     <span class="keywordflow">return</span> group.readBoolEntry( <span class="stringliteral">"crypto-warning-unencrypted"</span>, <span class="keyword">false</span> );
<a name="l00101"></a>00101 }
<a name="l00102"></a>00102 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> saveMessagesEncrypted() {
<a name="l00103"></a>00103     KConfigGroup group( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00104"></a>00104     <span class="keywordflow">return</span> group.readBoolEntry( <span class="stringliteral">"crypto-store-encrypted"</span>, <span class="keyword">true</span> );
<a name="l00105"></a>00105 }
<a name="l00106"></a>00106 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> encryptToSelf() {
<a name="l00107"></a>00107     <span class="comment">// return !Kpgp::Module::getKpgp() || Kpgp::Module::getKpgp()-&gt;encryptToSelf();</span>
<a name="l00108"></a>00108     KConfigGroup group( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00109"></a>00109     <span class="keywordflow">return</span> group.readBoolEntry( <span class="stringliteral">"crypto-encrypt-to-self"</span>, <span class="keyword">true</span> );
<a name="l00110"></a>00110 }
<a name="l00111"></a>00111 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> showKeyApprovalDialog() {
<a name="l00112"></a>00112     KConfigGroup group( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00113"></a>00113     <span class="keywordflow">return</span> group.readBoolEntry( <span class="stringliteral">"crypto-show-keys-for-approval"</span>, <span class="keyword">true</span> );
<a name="l00114"></a>00114 }
<a name="l00115"></a>00115 
<a name="l00116"></a>00116 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> encryptKeyNearExpiryWarningThresholdInDays() {
<a name="l00117"></a>00117   <span class="keyword">const</span> KConfigGroup composer( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00118"></a>00118   <span class="keywordflow">if</span> ( ! composer.readBoolEntry( <span class="stringliteral">"crypto-warn-when-near-expire"</span>, <span class="keyword">true</span> ) )
<a name="l00119"></a>00119     <span class="keywordflow">return</span> -1;
<a name="l00120"></a>00120   <span class="keyword">const</span> <span class="keywordtype">int</span> num = composer.readNumEntry( <span class="stringliteral">"crypto-warn-encr-key-near-expire-int"</span>, 14 );
<a name="l00121"></a>00121   <span class="keywordflow">return</span> kMax( 1, num );
<a name="l00122"></a>00122 }
<a name="l00123"></a>00123 
<a name="l00124"></a>00124 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> signingKeyNearExpiryWarningThresholdInDays() {
<a name="l00125"></a>00125   <span class="keyword">const</span> KConfigGroup composer( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00126"></a>00126   <span class="keywordflow">if</span> ( ! composer.readBoolEntry( <span class="stringliteral">"crypto-warn-when-near-expire"</span>, <span class="keyword">true</span> ) )
<a name="l00127"></a>00127     <span class="keywordflow">return</span> -1;
<a name="l00128"></a>00128   <span class="keyword">const</span> <span class="keywordtype">int</span> num = composer.readNumEntry( <span class="stringliteral">"crypto-warn-sign-key-near-expire-int"</span>, 14 );
<a name="l00129"></a>00129   <span class="keywordflow">return</span> kMax( 1, num );
<a name="l00130"></a>00130 }
<a name="l00131"></a>00131 
<a name="l00132"></a>00132 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> encryptRootCertNearExpiryWarningThresholdInDays() {
<a name="l00133"></a>00133   <span class="keyword">const</span> KConfigGroup composer( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00134"></a>00134   <span class="keywordflow">if</span> ( ! composer.readBoolEntry( <span class="stringliteral">"crypto-warn-when-near-expire"</span>, <span class="keyword">true</span> ) )
<a name="l00135"></a>00135     <span class="keywordflow">return</span> -1;
<a name="l00136"></a>00136   <span class="keyword">const</span> <span class="keywordtype">int</span> num = composer.readNumEntry( <span class="stringliteral">"crypto-warn-encr-root-near-expire-int"</span>, 14 );
<a name="l00137"></a>00137   <span class="keywordflow">return</span> kMax( 1, num );
<a name="l00138"></a>00138 }
<a name="l00139"></a>00139 
<a name="l00140"></a>00140 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> signingRootCertNearExpiryWarningThresholdInDays() {
<a name="l00141"></a>00141   <span class="keyword">const</span> KConfigGroup composer( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00142"></a>00142   <span class="keywordflow">if</span> ( ! composer.readBoolEntry( <span class="stringliteral">"crypto-warn-when-near-expire"</span>, <span class="keyword">true</span> ) )
<a name="l00143"></a>00143     <span class="keywordflow">return</span> -1;
<a name="l00144"></a>00144   <span class="keyword">const</span> <span class="keywordtype">int</span> num = composer.readNumEntry( <span class="stringliteral">"crypto-warn-sign-root-near-expire-int"</span>, 14 );
<a name="l00145"></a>00145   <span class="keywordflow">return</span> kMax( 1, num );
<a name="l00146"></a>00146 }
<a name="l00147"></a>00147 
<a name="l00148"></a>00148 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> encryptChainCertNearExpiryWarningThresholdInDays() {
<a name="l00149"></a>00149   <span class="keyword">const</span> KConfigGroup composer( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00150"></a>00150   <span class="keywordflow">if</span> ( ! composer.readBoolEntry( <span class="stringliteral">"crypto-warn-when-near-expire"</span>, <span class="keyword">true</span> ) )
<a name="l00151"></a>00151     <span class="keywordflow">return</span> -1;
<a name="l00152"></a>00152   <span class="keyword">const</span> <span class="keywordtype">int</span> num = composer.readNumEntry( <span class="stringliteral">"crypto-warn-encr-chaincert-near-expire-int"</span>, 14 );
<a name="l00153"></a>00153   <span class="keywordflow">return</span> kMax( 1, num );
<a name="l00154"></a>00154 }
<a name="l00155"></a>00155 
<a name="l00156"></a>00156 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">int</span> signingChainCertNearExpiryWarningThresholdInDays() {
<a name="l00157"></a>00157   <span class="keyword">const</span> KConfigGroup composer( KMKernel::config(), <span class="stringliteral">"Composer"</span> );
<a name="l00158"></a>00158   <span class="keywordflow">if</span> ( ! composer.readBoolEntry( <span class="stringliteral">"crypto-warn-when-near-expire"</span>, <span class="keyword">true</span> ) )
<a name="l00159"></a>00159     <span class="keywordflow">return</span> -1;
<a name="l00160"></a>00160   <span class="keyword">const</span> <span class="keywordtype">int</span> num = composer.readNumEntry( <span class="stringliteral">"crypto-warn-sign-chaincert-near-expire-int"</span>, 14 );
<a name="l00161"></a>00161   <span class="keywordflow">return</span> kMax( 1, num );
<a name="l00162"></a>00162 }
<a name="l00163"></a>00163 
<a name="l00164"></a>00164 <span class="comment">/*</span>
<a name="l00165"></a>00165 <span class="comment">  Design of this:</span>
<a name="l00166"></a>00166 <span class="comment"></span>
<a name="l00167"></a>00167 <span class="comment">  The idea is that the main run of applyChanges here makes two jobs:</span>
<a name="l00168"></a>00168 <span class="comment">  the first sets the flags for encryption/signing or not, and the other</span>
<a name="l00169"></a>00169 <span class="comment">  starts the encryption process.</span>
<a name="l00170"></a>00170 <span class="comment"></span>
<a name="l00171"></a>00171 <span class="comment">  When a job is run, it has already been removed from the job queue. This</span>
<a name="l00172"></a>00172 <span class="comment">  means if one of the current jobs needs to add new jobs, it can add them</span>
<a name="l00173"></a>00173 <span class="comment">  to the front and that way control when new jobs are added.</span>
<a name="l00174"></a>00174 <span class="comment"></span>
<a name="l00175"></a>00175 <span class="comment">  For example, the compose message job will add jobs that will do the</span>
<a name="l00176"></a>00176 <span class="comment">  actual encryption and signing.</span>
<a name="l00177"></a>00177 <span class="comment"></span>
<a name="l00178"></a>00178 <span class="comment">  There are two types of jobs: synchronous and asynchronous:</span>
<a name="l00179"></a>00179 <span class="comment"></span>
<a name="l00180"></a>00180 <span class="comment">  A synchronous job simply implments the execute() method and performs</span>
<a name="l00181"></a>00181 <span class="comment">  it's operation there and sets mComposer-&gt;mRc to false if the compose</span>
<a name="l00182"></a>00182 <span class="comment">  queue should be canceled.</span>
<a name="l00183"></a>00183 <span class="comment"></span>
<a name="l00184"></a>00184 <span class="comment">  An asynchronous job only sets up and starts it's operation. Before</span>
<a name="l00185"></a>00185 <span class="comment">  returning, it connects to the result signals of the operation</span>
<a name="l00186"></a>00186 <span class="comment">  (e.g. Kleo::Job's result(...) signal) and sets mComposer-&gt;mHoldJobs</span>
<a name="l00187"></a>00187 <span class="comment">  to true. This makes the scheduler return to the event loop. The job</span>
<a name="l00188"></a>00188 <span class="comment">  is now responsible for giving control back to the scheduler by</span>
<a name="l00189"></a>00189 <span class="comment">  calling mComposer-&gt;doNextJob().</span>
<a name="l00190"></a>00190 <span class="comment">*/</span>
<a name="l00191"></a>00191 
<a name="l00192"></a>00192 <span class="comment">/*</span>
<a name="l00193"></a>00193 <span class="comment"> Test plan:</span>
<a name="l00194"></a>00194 <span class="comment"></span>
<a name="l00195"></a>00195 <span class="comment"> For each message format (e.g. openPGP/MIME)</span>
<a name="l00196"></a>00196 <span class="comment"> 1. Body signed</span>
<a name="l00197"></a>00197 <span class="comment"> 2. Body encrypted</span>
<a name="l00198"></a>00198 <span class="comment"> 3. Body signed and encrypted</span>
<a name="l00199"></a>00199 <span class="comment"> 4. Body encrypted, attachments encrypted  (they must be encrypted together, mEarlyAddAttachments)</span>
<a name="l00200"></a>00200 <span class="comment"> 5. Body encrypted, attachments not encrypted</span>
<a name="l00201"></a>00201 <span class="comment"> 6. Body encrypted, attachment encrypted and signed (separately)</span>
<a name="l00202"></a>00202 <span class="comment"> 7. Body not encrypted, one attachment encrypted+signed, one attachment encrypted only, one attachment signed only</span>
<a name="l00203"></a>00203 <span class="comment">       (https://intevation.de/roundup/aegypten/issue295)</span>
<a name="l00204"></a>00204 <span class="comment">       (this is the reason attachments can't be encrypted together)</span>
<a name="l00205"></a>00205 <span class="comment"> 8. Body and attachments encrypted+signed (they must be encrypted+signed together, mEarlyAddAttachments)</span>
<a name="l00206"></a>00206 <span class="comment"> 9. Body encrypted+signed, attachments encrypted</span>
<a name="l00207"></a>00207 <span class="comment"> 10. Body encrypted+signed, one attachment signed, one attachment not encrypted nor signed</span>
<a name="l00208"></a>00208 <span class="comment"> ...</span>
<a name="l00209"></a>00209 <span class="comment"></span>
<a name="l00210"></a>00210 <span class="comment"> I recorded a KDExecutor script sending all of the above (David)</span>
<a name="l00211"></a>00211 <span class="comment"></span>
<a name="l00212"></a>00212 <span class="comment"> Further tests (which test opportunistic encryption):</span>
<a name="l00213"></a>00213 <span class="comment"> 1. Send a message to a person with valid key but without encryption preference</span>
<a name="l00214"></a>00214 <span class="comment">    and answer the question whether the message should be encrypted with Yes.</span>
<a name="l00215"></a>00215 <span class="comment"> 2. Send a message to a person with valid key but without encryption preference</span>
<a name="l00216"></a>00216 <span class="comment">    and answer the question whether the message should be encrypted with No.</span>
<a name="l00217"></a>00217 <span class="comment"> 3. Send a message to a person with valid key and with encryption preference</span>
<a name="l00218"></a>00218 <span class="comment">    "Encrypt whenever possible" (aka opportunistic encryption).</span>
<a name="l00219"></a>00219 <span class="comment">*/</span>
<a name="l00220"></a>00220 
<a name="l00221"></a>00221 <span class="keyword">static</span> QString mErrorProcessingStructuringInfo =
<a name="l00222"></a>00222 i18n(<span class="stringliteral">"&lt;qt&gt;&lt;p&gt;Structuring information returned by the Crypto plug-in "</span>
<a name="l00223"></a>00223      <span class="stringliteral">"could not be processed correctly; the plug-in might be damaged.&lt;/p&gt;"</span>
<a name="l00224"></a>00224      <span class="stringliteral">"&lt;p&gt;Please contact your system administrator.&lt;/p&gt;&lt;/qt&gt;"</span>);
<a name="l00225"></a>00225 <span class="keyword">static</span> QString mErrorNoCryptPlugAndNoBuildIn =
<a name="l00226"></a>00226 i18n(<span class="stringliteral">"&lt;p&gt;No active Crypto Plug-In was found and the built-in OpenPGP code "</span>
<a name="l00227"></a>00227      <span class="stringliteral">"did not run successfully.&lt;/p&gt;"</span>
<a name="l00228"></a>00228      <span class="stringliteral">"&lt;p&gt;You can do two things to change this:&lt;/p&gt;"</span>
<a name="l00229"></a>00229      <span class="stringliteral">"&lt;ul&gt;&lt;li&gt;&lt;em&gt;either&lt;/em&gt; activate a Plug-In using the "</span>
<a name="l00230"></a>00230      <span class="stringliteral">"Settings-&gt;Configure KMail-&gt;Plug-In dialog.&lt;/li&gt;"</span>
<a name="l00231"></a>00231      <span class="stringliteral">"&lt;li&gt;&lt;em&gt;or&lt;/em&gt; specify traditional OpenPGP settings on the same dialog's "</span>
<a name="l00232"></a>00232      <span class="stringliteral">"Identity-&gt;Advanced tab.&lt;/li&gt;&lt;/ul&gt;"</span>);
<a name="l00233"></a>00233 
<a name="l00234"></a>00234 
<a name="l00235"></a>00235 <span class="keyword">class </span>MessageComposerJob {
<a name="l00236"></a>00236 <span class="keyword">public</span>:
<a name="l00237"></a>00237   MessageComposerJob( MessageComposer* composer ) : mComposer( composer ) {}
<a name="l00238"></a>00238   <span class="keyword">virtual</span> ~MessageComposerJob() {}
<a name="l00239"></a>00239 
<a name="l00240"></a>00240   <span class="keyword">virtual</span> <span class="keywordtype">void</span> execute() = 0;
<a name="l00241"></a>00241 
<a name="l00242"></a>00242 <span class="keyword">protected</span>:
<a name="l00243"></a>00243   <span class="comment">// These are the methods that call the private MessageComposer methods</span>
<a name="l00244"></a>00244   <span class="comment">// Workaround for friend not being inherited</span>
<a name="l00245"></a>00245   <span class="keywordtype">void</span> adjustCryptFlags() { mComposer-&gt;adjustCryptFlags(); }
<a name="l00246"></a>00246   <span class="keywordtype">void</span> composeMessage() { mComposer-&gt;composeMessage(); }
<a name="l00247"></a>00247   <span class="keywordtype">void</span> continueComposeMessage( <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>&amp; msg, <span class="keywordtype">bool</span> doSign, <span class="keywordtype">bool</span> doEncrypt,
<a name="l00248"></a>00248                                Kleo::CryptoMessageFormat format )
<a name="l00249"></a>00249   {
<a name="l00250"></a>00250     mComposer-&gt;continueComposeMessage( msg, doSign, doEncrypt, format );
<a name="l00251"></a>00251   }
<a name="l00252"></a>00252   <span class="keywordtype">void</span> chiasmusEncryptAllAttachments() {
<a name="l00253"></a>00253     mComposer-&gt;chiasmusEncryptAllAttachments();
<a name="l00254"></a>00254   }
<a name="l00255"></a>00255 
<a name="l00256"></a>00256   MessageComposer* mComposer;
<a name="l00257"></a>00257 };
<a name="l00258"></a>00258 
<a name="l00259"></a>00259 <span class="keyword">class </span>ChiasmusBodyPartEncryptJob : <span class="keyword">public</span> MessageComposerJob {
<a name="l00260"></a>00260 <span class="keyword">public</span>:
<a name="l00261"></a>00261   ChiasmusBodyPartEncryptJob( MessageComposer * composer )
<a name="l00262"></a>00262     : MessageComposerJob( composer ) {}
<a name="l00263"></a>00263 
<a name="l00264"></a>00264   <span class="keywordtype">void</span> execute() {
<a name="l00265"></a>00265     chiasmusEncryptAllAttachments();
<a name="l00266"></a>00266   }
<a name="l00267"></a>00267 };
<a name="l00268"></a>00268 
<a name="l00269"></a>00269 <span class="keyword">class </span>AdjustCryptFlagsJob : <span class="keyword">public</span> MessageComposerJob {
<a name="l00270"></a>00270 <span class="keyword">public</span>:
<a name="l00271"></a>00271   AdjustCryptFlagsJob( MessageComposer* composer )
<a name="l00272"></a>00272     : MessageComposerJob( composer ) {}
<a name="l00273"></a>00273 
<a name="l00274"></a>00274   <span class="keywordtype">void</span> execute() {
<a name="l00275"></a>00275     adjustCryptFlags();
<a name="l00276"></a>00276   }
<a name="l00277"></a>00277 };
<a name="l00278"></a>00278 
<a name="l00279"></a>00279 <span class="keyword">class </span>ComposeMessageJob : <span class="keyword">public</span> MessageComposerJob {
<a name="l00280"></a>00280 <span class="keyword">public</span>:
<a name="l00281"></a>00281   ComposeMessageJob( MessageComposer* composer )
<a name="l00282"></a>00282     : MessageComposerJob( composer ) {}
<a name="l00283"></a>00283 
<a name="l00284"></a>00284   <span class="keywordtype">void</span> execute() {
<a name="l00285"></a>00285     composeMessage();
<a name="l00286"></a>00286   }
<a name="l00287"></a>00287 };
<a name="l00288"></a>00288 
<a name="l00289"></a>00289 MessageComposer::MessageComposer( KMComposeWin* win, <span class="keyword">const</span> <span class="keywordtype">char</span>* name )
<a name="l00290"></a>00290   : QObject( win, name ), mComposeWin( win ), mCurrentJob( 0 ),
<a name="l00291"></a>00291     mReferenceMessage( 0 ), mKeyResolver( 0 ), 
<a name="l00292"></a>00292     mUseOpportunisticEncryption( false ),
<a name="l00293"></a>00293     mSignBody( false ), mEncryptBody( false ),
<a name="l00294"></a>00294     mSigningRequested(  false ), mEncryptionRequested( false ),
<a name="l00295"></a>00295     mDoSign( false ), mDoEncrypt( false ),
<a name="l00296"></a>00296     mAllowedCryptoMessageFormats( 0 ),
<a name="l00297"></a>00297     mDisableCrypto( false ),
<a name="l00298"></a>00298     mDisableBreaking( false ),
<a name="l00299"></a>00299     mDebugComposerCrypto( false ),
<a name="l00300"></a>00300     mAutoCharset( true ),
<a name="l00301"></a>00301     mIsRichText( false ),
<a name="l00302"></a>00302     mIdentityUid( 0 ), mRc( true ),
<a name="l00303"></a>00303     mHoldJobs( false ),
<a name="l00304"></a>00304     mNewBodyPart( 0 ),
<a name="l00305"></a>00305     mEarlyAddAttachments( false ), mAllAttachmentsAreInBody( false ),
<a name="l00306"></a>00306     mPreviousBoundaryLevel( 0 ),
<a name="l00307"></a>00307     mEncryptWithChiasmus( false ),
<a name="l00308"></a>00308     mPerformingSignOperation( false )
<a name="l00309"></a>00309 {
<a name="l00310"></a>00310 }
<a name="l00311"></a>00311 
<a name="l00312"></a>00312 MessageComposer::~MessageComposer()
<a name="l00313"></a>00313 {
<a name="l00314"></a>00314   <span class="keyword">delete</span> mKeyResolver; mKeyResolver = 0;
<a name="l00315"></a>00315   <span class="keyword">delete</span> mNewBodyPart; mNewBodyPart = 0;
<a name="l00316"></a>00316 }
<a name="l00317"></a>00317 
<a name="l00318"></a>00318 <span class="keywordtype">void</span> MessageComposer::applyChanges( <span class="keywordtype">bool</span> disableCrypto )
<a name="l00319"></a>00319 {
<a name="l00320"></a>00320   <span class="comment">// Do the initial setup</span>
<a name="l00321"></a>00321   <span class="keywordflow">if</span>( getenv(<span class="stringliteral">"KMAIL_DEBUG_COMPOSER_CRYPTO"</span>) != 0 ) {
<a name="l00322"></a>00322     QCString cE = getenv(<span class="stringliteral">"KMAIL_DEBUG_COMPOSER_CRYPTO"</span>);
<a name="l00323"></a>00323     mDebugComposerCrypto = cE == <span class="stringliteral">"1"</span> || cE.upper() == <span class="stringliteral">"ON"</span> || cE.upper() == <span class="stringliteral">"TRUE"</span>;
<a name="l00324"></a>00324     kdDebug(5006) &lt;&lt; <span class="stringliteral">"KMAIL_DEBUG_COMPOSER_CRYPTO = TRUE"</span> &lt;&lt; endl;
<a name="l00325"></a>00325   } <span class="keywordflow">else</span> {
<a name="l00326"></a>00326     mDebugComposerCrypto = <span class="keyword">false</span>;
<a name="l00327"></a>00327     kdDebug(5006) &lt;&lt; <span class="stringliteral">"KMAIL_DEBUG_COMPOSER_CRYPTO = FALSE"</span> &lt;&lt; endl;
<a name="l00328"></a>00328   }
<a name="l00329"></a>00329 
<a name="l00330"></a>00330   mHoldJobs = <span class="keyword">false</span>;
<a name="l00331"></a>00331   mRc = <span class="keyword">true</span>;
<a name="l00332"></a>00332 
<a name="l00333"></a>00333   mDisableCrypto = disableCrypto;
<a name="l00334"></a>00334 
<a name="l00335"></a>00335   <span class="comment">// 1: Read everything from KMComposeWin and set all</span>
<a name="l00336"></a>00336   <span class="comment">//    trivial parts of the message</span>
<a name="l00337"></a>00337   readFromComposeWin();
<a name="l00338"></a>00338 
<a name="l00339"></a>00339   <span class="comment">// From now on, we're not supposed to read from the composer win</span>
<a name="l00340"></a>00340   <span class="comment">// TODO: Make it so ;-)</span>
<a name="l00341"></a>00341   <span class="comment">// 1.5: Replace all body parts with their chiasmus-encrypted equivalent</span>
<a name="l00342"></a>00342   mJobs.push_back( <span class="keyword">new</span> ChiasmusBodyPartEncryptJob( <span class="keyword">this</span> ) );
<a name="l00343"></a>00343 
<a name="l00344"></a>00344   <span class="comment">// 2: Set encryption/signing options and resolve keys</span>
<a name="l00345"></a>00345   mJobs.push_back( <span class="keyword">new</span> AdjustCryptFlagsJob( <span class="keyword">this</span> ) );
<a name="l00346"></a>00346 
<a name="l00347"></a>00347   <span class="comment">// 3: Build the message (makes the crypto jobs also)</span>
<a name="l00348"></a>00348   mJobs.push_back( <span class="keyword">new</span> ComposeMessageJob( <span class="keyword">this</span> ) );
<a name="l00349"></a>00349 
<a name="l00350"></a>00350   <span class="comment">// Finally: Run the jobs</span>
<a name="l00351"></a>00351   doNextJob();
<a name="l00352"></a>00352 }
<a name="l00353"></a>00353 
<a name="l00354"></a>00354 <span class="keywordtype">void</span> MessageComposer::doNextJob()
<a name="l00355"></a>00355 {
<a name="l00356"></a>00356   <span class="keyword">delete</span> mCurrentJob; mCurrentJob = 0;
<a name="l00357"></a>00357 
<a name="l00358"></a>00358   <span class="keywordflow">if</span>( mJobs.isEmpty() ) {
<a name="l00359"></a>00359     <span class="comment">// No more jobs. Signal that we're done</span>
<a name="l00360"></a>00360     emitDone( mRc );
<a name="l00361"></a>00361     <span class="keywordflow">return</span>;
<a name="l00362"></a>00362   }
<a name="l00363"></a>00363 
<a name="l00364"></a>00364   <span class="keywordflow">if</span>( !mRc ) {
<a name="l00365"></a>00365     <span class="comment">// Something has gone wrong - stop the process and bail out</span>
<a name="l00366"></a>00366     <span class="keywordflow">while</span>( !mJobs.isEmpty() ) {
<a name="l00367"></a>00367       <span class="keyword">delete</span> mJobs.front();
<a name="l00368"></a>00368       mJobs.pop_front();
<a name="l00369"></a>00369     }
<a name="l00370"></a>00370     emitDone( <span class="keyword">false</span> );
<a name="l00371"></a>00371     <span class="keywordflow">return</span>;
<a name="l00372"></a>00372   }
<a name="l00373"></a>00373 
<a name="l00374"></a>00374   <span class="comment">// We have more jobs to do, but allow others to come first</span>
<a name="l00375"></a>00375   QTimer::singleShot( 0, <span class="keyword">this</span>, SLOT( slotDoNextJob() ) );
<a name="l00376"></a>00376 }
<a name="l00377"></a>00377 
<a name="l00378"></a>00378 <span class="keywordtype">void</span> MessageComposer::emitDone( <span class="keywordtype">bool</span> b )
<a name="l00379"></a>00379 {
<a name="l00380"></a>00380   <span class="comment">// Save memory - before sending the mail</span>
<a name="l00381"></a>00381   mEncodedBody = QByteArray();
<a name="l00382"></a>00382   <span class="keyword">delete</span> mNewBodyPart; mNewBodyPart = 0;
<a name="l00383"></a>00383   mOldBodyPart.clear();
<a name="l00384"></a>00384   emit done( b );
<a name="l00385"></a>00385 }
<a name="l00386"></a>00386 
<a name="l00387"></a>00387 <span class="keywordtype">void</span> MessageComposer::slotDoNextJob()
<a name="l00388"></a>00388 {
<a name="l00389"></a>00389   assert( !mCurrentJob );
<a name="l00390"></a>00390   <span class="keywordflow">if</span>( mHoldJobs )
<a name="l00391"></a>00391     <span class="comment">// Always make it run from now. If more than one job should be held,</span>
<a name="l00392"></a>00392     <span class="comment">// The individual jobs must do this.</span>
<a name="l00393"></a>00393     mHoldJobs = <span class="keyword">false</span>;
<a name="l00394"></a>00394   <span class="keywordflow">else</span> {
<a name="l00395"></a>00395     assert( !mJobs.empty() );
<a name="l00396"></a>00396     <span class="comment">// Get the next job</span>
<a name="l00397"></a>00397     mCurrentJob = mJobs.front();
<a name="l00398"></a>00398     assert( mCurrentJob );
<a name="l00399"></a>00399     mJobs.pop_front();
<a name="l00400"></a>00400 
<a name="l00401"></a>00401     <span class="comment">// Execute it</span>
<a name="l00402"></a>00402     mCurrentJob-&gt;execute();
<a name="l00403"></a>00403   }
<a name="l00404"></a>00404 
<a name="l00405"></a>00405   <span class="comment">// Finally run the next job if necessary</span>
<a name="l00406"></a>00406   <span class="keywordflow">if</span>( !mHoldJobs )
<a name="l00407"></a>00407     doNextJob();
<a name="l00408"></a>00408 }
<a name="l00409"></a>00409 
<a name="l00410"></a>00410 <span class="keywordtype">void</span> MessageComposer::readFromComposeWin()
<a name="l00411"></a>00411 {
<a name="l00412"></a>00412   <span class="comment">// Copy necessary attributes over</span>
<a name="l00413"></a>00413   mDisableBreaking = <span class="keyword">false</span>;
<a name="l00414"></a>00414 
<a name="l00415"></a>00415   mSignBody = mComposeWin-&gt;mSignAction-&gt;isChecked();
<a name="l00416"></a>00416   mSigningRequested = mSignBody; <span class="comment">// for now; will be adjusted depending on attachments</span>
<a name="l00417"></a>00417   mEncryptBody = mComposeWin-&gt;mEncryptAction-&gt;isChecked();
<a name="l00418"></a>00418   mEncryptionRequested = mEncryptBody; <span class="comment">// for now; will be adjusted depending on attachments</span>
<a name="l00419"></a>00419 
<a name="l00420"></a>00420   mAutoCharset = mComposeWin-&gt;mAutoCharset;
<a name="l00421"></a>00421   mCharset = mComposeWin-&gt;mCharset;
<a name="l00422"></a>00422   mReferenceMessage = mComposeWin-&gt;mMsg;
<a name="l00423"></a>00423   <span class="comment">// if the user made any modifications to the message then the Content-Type</span>
<a name="l00424"></a>00424   <span class="comment">// of the message is no longer reliable (e. g. if he editted a draft/resent a</span>
<a name="l00425"></a>00425   <span class="comment">// message and then removed all attachments or changed from PGP/MIME signed</span>
<a name="l00426"></a>00426   <span class="comment">// to clearsigned);</span>
<a name="l00427"></a>00427   <span class="comment">// even if the user didn't make any modifications to the message the</span>
<a name="l00428"></a>00428   <span class="comment">// Content-Type of the message might be wrong, e.g. when inline-forwarding</span>
<a name="l00429"></a>00429   <span class="comment">// an mp/alt message then the Content-Type is set to mp/alt although it should</span>
<a name="l00430"></a>00430   <span class="comment">// be text/plain (cf. bug 127526);</span>
<a name="l00431"></a>00431   <span class="comment">// OTOH we must not reset the Content-Type of inline invitations;</span>
<a name="l00432"></a>00432   <span class="comment">// therefore we reset the Content-Type to text/plain whenever the current</span>
<a name="l00433"></a>00433   <span class="comment">// Content-Type is multipart/*.</span>
<a name="l00434"></a>00434   <span class="keywordflow">if</span> ( mReferenceMessage-&gt;type() == DwMime::kTypeMultipart )
<a name="l00435"></a>00435     mReferenceMessage-&gt;setHeaderField( <span class="stringliteral">"Content-Type"</span>, <span class="stringliteral">"text/plain"</span> );
<a name="l00436"></a>00436   mUseOpportunisticEncryption = GlobalSettings::self()-&gt;pgpAutoEncrypt();
<a name="l00437"></a>00437   mAllowedCryptoMessageFormats = mComposeWin-&gt;cryptoMessageFormat();
<a name="l00438"></a>00438 
<a name="l00439"></a>00439   <span class="keywordflow">if</span>( mAutoCharset ) {
<a name="l00440"></a>00440     QCString charset = KMMsgBase::autoDetectCharset( mCharset, <a class="code" href="classKMMessage.html#41e2c0836f490db2edf4983899a07591" title="Get a list of preferred message charsets.">KMMessage::preferredCharsets</a>(), mComposeWin-&gt;mEditor-&gt;text() );
<a name="l00441"></a>00441     <span class="keywordflow">if</span>( charset.isEmpty() )
<a name="l00442"></a>00442     {
<a name="l00443"></a>00443       KMessageBox::sorry( mComposeWin,
<a name="l00444"></a>00444                           i18n( <span class="stringliteral">"No suitable encoding could be found for "</span>
<a name="l00445"></a>00445                                 <span class="stringliteral">"your message.\nPlease set an encoding "</span>
<a name="l00446"></a>00446                                 <span class="stringliteral">"using the 'Options' menu."</span> ) );
<a name="l00447"></a>00447       mRc = <span class="keyword">false</span>;
<a name="l00448"></a>00448       <span class="keywordflow">return</span>;
<a name="l00449"></a>00449     }
<a name="l00450"></a>00450     mCharset = charset;
<a name="l00451"></a>00451     <span class="comment">// Also apply this to the composer window</span>
<a name="l00452"></a>00452     mComposeWin-&gt;mCharset = charset;
<a name="l00453"></a>00453   }
<a name="l00454"></a>00454   mReferenceMessage-&gt;setCharset(mCharset);
<a name="l00455"></a>00455 
<a name="l00456"></a>00456   mReferenceMessage-&gt;setTo(mComposeWin-&gt;to());
<a name="l00457"></a>00457   mReferenceMessage-&gt;setFrom(mComposeWin-&gt;from());
<a name="l00458"></a>00458   mReferenceMessage-&gt;setCc(mComposeWin-&gt;cc());
<a name="l00459"></a>00459   mReferenceMessage-&gt;setSubject(mComposeWin-&gt;subject());
<a name="l00460"></a>00460   mReferenceMessage-&gt;setReplyTo(mComposeWin-&gt;replyTo());
<a name="l00461"></a>00461   mReferenceMessage-&gt;setBcc(mComposeWin-&gt;bcc());
<a name="l00462"></a>00462 
<a name="l00463"></a>00463   <span class="keyword">const</span> KPIM::Identity &amp; <span class="keywordtype">id</span> = mComposeWin-&gt;identity();
<a name="l00464"></a>00464 
<a name="l00465"></a>00465   <a class="code" href="classKMFolder.html" title="Mail folder.">KMFolder</a> *f = mComposeWin-&gt;mFcc-&gt;getFolder();
<a name="l00466"></a>00466   assert( f != 0 );
<a name="l00467"></a>00467   <span class="keywordflow">if</span> ( f-&gt;<a class="code" href="classKMFolder.html#bab3b6b7c2758c19aa04c2bf72716b27" title="Returns a string that can be used to identify this folder.">idString</a>() == <span class="keywordtype">id</span>.fcc() )
<a name="l00468"></a>00468     mReferenceMessage-&gt;removeHeaderField(<span class="stringliteral">"X-KMail-Fcc"</span>);
<a name="l00469"></a>00469   <span class="keywordflow">else</span>
<a name="l00470"></a>00470     mReferenceMessage-&gt;setFcc( f-&gt;<a class="code" href="classKMFolder.html#bab3b6b7c2758c19aa04c2bf72716b27" title="Returns a string that can be used to identify this folder.">idString</a>() );
<a name="l00471"></a>00471 
<a name="l00472"></a>00472   <span class="comment">// set the correct drafts folder</span>
<a name="l00473"></a>00473   mReferenceMessage-&gt;setDrafts( <span class="keywordtype">id</span>.drafts() );
<a name="l00474"></a>00474 
<a name="l00475"></a>00475   <span class="keywordflow">if</span> (<span class="keywordtype">id</span>.isDefault())
<a name="l00476"></a>00476     mReferenceMessage-&gt;removeHeaderField(<span class="stringliteral">"X-KMail-Identity"</span>);
<a name="l00477"></a>00477   <span class="keywordflow">else</span> mReferenceMessage-&gt;setHeaderField(<span class="stringliteral">"X-KMail-Identity"</span>, QString::number( <span class="keywordtype">id</span>.uoid() ));
<a name="l00478"></a>00478 
<a name="l00479"></a>00479   QString replyAddr;
<a name="l00480"></a>00480   <span class="keywordflow">if</span> (!mComposeWin-&gt;replyTo().isEmpty()) replyAddr = mComposeWin-&gt;replyTo();
<a name="l00481"></a>00481   <span class="keywordflow">else</span> replyAddr = mComposeWin-&gt;from();
<a name="l00482"></a>00482 
<a name="l00483"></a>00483   <span class="keywordflow">if</span> (mComposeWin-&gt;mRequestMDNAction-&gt;isChecked())
<a name="l00484"></a>00484     mReferenceMessage-&gt;setHeaderField(<span class="stringliteral">"Disposition-Notification-To"</span>, replyAddr);
<a name="l00485"></a>00485   <span class="keywordflow">else</span>
<a name="l00486"></a>00486     mReferenceMessage-&gt;removeHeaderField(<span class="stringliteral">"Disposition-Notification-To"</span>);
<a name="l00487"></a>00487 
<a name="l00488"></a>00488   <span class="keywordflow">if</span> (mComposeWin-&gt;mUrgentAction-&gt;isChecked()) {
<a name="l00489"></a>00489     mReferenceMessage-&gt;setHeaderField(<span class="stringliteral">"X-PRIORITY"</span>, <span class="stringliteral">"2 (High)"</span>);
<a name="l00490"></a>00490     mReferenceMessage-&gt;setHeaderField(<span class="stringliteral">"Priority"</span>, <span class="stringliteral">"urgent"</span>);
<a name="l00491"></a>00491   } <span class="keywordflow">else</span> {
<a name="l00492"></a>00492     mReferenceMessage-&gt;removeHeaderField(<span class="stringliteral">"X-PRIORITY"</span>);
<a name="l00493"></a>00493     mReferenceMessage-&gt;removeHeaderField(<span class="stringliteral">"Priority"</span>);
<a name="l00494"></a>00494   }
<a name="l00495"></a>00495 
<a name="l00496"></a>00496   <span class="keywordtype">int</span> num = GlobalSettings::self()-&gt;custHeaderCount();
<a name="l00497"></a>00497   <span class="keywordflow">for</span>(<span class="keywordtype">int</span> ix=0; ix&lt;num; ix++) {
<a name="l00498"></a>00498     CustomMimeHeader customMimeHeader( QString::number(ix) );
<a name="l00499"></a>00499     customMimeHeader.readConfig();
<a name="l00500"></a>00500     mReferenceMessage-&gt;setHeaderField(
<a name="l00501"></a>00501         KMMsgBase::toUsAscii( customMimeHeader.custHeaderName() ),
<a name="l00502"></a>00502         customMimeHeader.custHeaderValue() );
<a name="l00503"></a>00503   }
<a name="l00504"></a>00504 
<a name="l00505"></a>00505 
<a name="l00506"></a>00506   <span class="comment">// we have to remember the Bcc because it might have been overwritten</span>
<a name="l00507"></a>00507   <span class="comment">// by a custom header (therefore we can't use bcc() later) and because</span>
<a name="l00508"></a>00508   <span class="comment">// mimelib removes addresses without domain part (therefore we can't use</span>
<a name="l00509"></a>00509   <span class="comment">// mReferenceMessage-&gt;bcc() later and also not now. So get the Bcc from</span>
<a name="l00510"></a>00510   <span class="comment">// the composer window.)</span>
<a name="l00511"></a>00511   mBcc = mComposeWin-&gt;bcc();
<a name="l00512"></a>00512   mTo = KPIM::splitEmailAddrList( mComposeWin-&gt;to().stripWhiteSpace() );
<a name="l00513"></a>00513   mCc = KPIM::splitEmailAddrList( mComposeWin-&gt;cc().stripWhiteSpace() );
<a name="l00514"></a>00514   mBccList = KPIM::splitEmailAddrList( mBcc.stripWhiteSpace() );
<a name="l00515"></a>00515 
<a name="l00516"></a>00516   <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0 ; i &lt; mComposeWin-&gt;mAtmList.count() ; ++i )
<a name="l00517"></a>00517     mAttachments.push_back( Attachment( mComposeWin-&gt;mAtmList.at(i),
<a name="l00518"></a>00518                     mComposeWin-&gt;signFlagOfAttachment( i ),
<a name="l00519"></a>00519                     mComposeWin-&gt;encryptFlagOfAttachment( i ) ) );
<a name="l00520"></a>00520 
<a name="l00521"></a>00521   mEncryptWithChiasmus = mComposeWin-&gt;mEncryptWithChiasmus;
<a name="l00522"></a>00522 
<a name="l00523"></a>00523   mIsRichText = mComposeWin-&gt;mEditor-&gt;textFormat() == Qt::RichText;
<a name="l00524"></a>00524   mIdentityUid = mComposeWin-&gt;identityUid();
<a name="l00525"></a>00525   mText = breakLinesAndApplyCodec();
<a name="l00526"></a>00526   assert( mText.isEmpty() || mText[mText.size()-1] == <span class="charliteral">'\n'</span> );
<a name="l00527"></a>00527   <span class="comment">// Hopefully we can get rid of this eventually, it's needed to be able</span>
<a name="l00528"></a>00528   <span class="comment">// to break the plain/text version of a multipart/alternative (html) mail</span>
<a name="l00529"></a>00529   <span class="comment">// according to the line breaks of the richtext version.</span>
<a name="l00530"></a>00530   mLineBreakColumn = mComposeWin-&gt;mEditor-&gt;lineBreakColumn();
<a name="l00531"></a>00531 }
<a name="l00532"></a>00532 
<a name="l00533"></a>00533 <span class="keyword">static</span> QCString escape_quoted_string( <span class="keyword">const</span> QCString &amp; str ) {
<a name="l00534"></a>00534   QCString result;
<a name="l00535"></a>00535   <span class="keyword">const</span> <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> str_len = str.length();
<a name="l00536"></a>00536   result.resize( 2*str_len + 1 );
<a name="l00537"></a>00537   <span class="keywordtype">char</span> * d = result.data();
<a name="l00538"></a>00538   <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0 ; i &lt; str_len ; ++i )
<a name="l00539"></a>00539     <span class="keywordflow">switch</span> ( <span class="keyword">const</span> <span class="keywordtype">char</span> ch = str[i] ) {
<a name="l00540"></a>00540     <span class="keywordflow">case</span> <span class="charliteral">'\\'</span>:
<a name="l00541"></a>00541     <span class="keywordflow">case</span> <span class="charliteral">'"'</span>:
<a name="l00542"></a>00542       *d++ = <span class="charliteral">'\\'</span>;
<a name="l00543"></a>00543     <span class="keywordflow">default</span>: <span class="comment">// fall through:</span>
<a name="l00544"></a>00544       *d++ = ch;
<a name="l00545"></a>00545     }
<a name="l00546"></a>00546   result.truncate( d - result.begin() );
<a name="l00547"></a>00547   <span class="keywordflow">return</span> result;
<a name="l00548"></a>00548 }
<a name="l00549"></a>00549 
<a name="l00550"></a>00550 <span class="keywordtype">bool</span> MessageComposer::encryptWithChiasmus( <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * chiasmus,
<a name="l00551"></a>00551                                            <span class="keyword">const</span> QByteArray&amp; body,
<a name="l00552"></a>00552                                            QByteArray&amp; resultData )
<a name="l00553"></a>00553 {
<a name="l00554"></a>00554   std::auto_ptr&lt;Kleo::SpecialJob&gt; job( chiasmus-&gt;specialJob( <span class="stringliteral">"x-encrypt"</span>, QMap&lt;QString,QVariant&gt;() ) );
<a name="l00555"></a>00555   <span class="keywordflow">if</span> ( !job.get() ) {
<a name="l00556"></a>00556     <span class="keyword">const</span> QString msg = i18n( <span class="stringliteral">"Chiasmus backend does not offer the "</span>
<a name="l00557"></a>00557                               <span class="stringliteral">"\"x-encrypt\" function. Please report this bug."</span> );
<a name="l00558"></a>00558     KMessageBox::error( mComposeWin, msg, i18n( <span class="stringliteral">"Chiasmus Backend Error"</span> ) );
<a name="l00559"></a>00559     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00560"></a>00560   }
<a name="l00561"></a>00561   <span class="keywordflow">if</span> ( !job-&gt;setProperty( <span class="stringliteral">"key"</span>, GlobalSettings::chiasmusKey() ) ||
<a name="l00562"></a>00562        !job-&gt;setProperty( <span class="stringliteral">"options"</span>, GlobalSettings::chiasmusOptions() ) ||
<a name="l00563"></a>00563        !job-&gt;setProperty( <span class="stringliteral">"input"</span>, body ) ) {
<a name="l00564"></a>00564     <span class="keyword">const</span> QString msg = i18n( <span class="stringliteral">"The \"x-encrypt\" function does not accept "</span>
<a name="l00565"></a>00565                               <span class="stringliteral">"the expected parameters. Please report this bug."</span> );
<a name="l00566"></a>00566     KMessageBox::error( mComposeWin, msg, i18n( <span class="stringliteral">"Chiasmus Backend Error"</span> ) );
<a name="l00567"></a>00567     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00568"></a>00568   }
<a name="l00569"></a>00569   <span class="keyword">const</span> GpgME::Error err = job-&gt;exec();
<a name="l00570"></a>00570   <span class="keywordflow">if</span> ( err.isCanceled() || err ) {
<a name="l00571"></a>00571     <span class="keywordflow">if</span> ( err )
<a name="l00572"></a>00572       job-&gt;showErrorDialog( mComposeWin, i18n( <span class="stringliteral">"Chiasmus Encryption Error"</span> ) );
<a name="l00573"></a>00573     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00574"></a>00574   }
<a name="l00575"></a>00575   <span class="keyword">const</span> QVariant result = job-&gt;property( <span class="stringliteral">"result"</span> );
<a name="l00576"></a>00576   <span class="keywordflow">if</span> ( result.type() != QVariant::ByteArray ) {
<a name="l00577"></a>00577     <span class="keyword">const</span> QString msg = i18n( <span class="stringliteral">"Unexpected return value from Chiasmus backend: "</span>
<a name="l00578"></a>00578                               <span class="stringliteral">"The \"x-encrypt\" function did not return a "</span>
<a name="l00579"></a>00579                               <span class="stringliteral">"byte array. Please report this bug."</span> );
<a name="l00580"></a>00580     KMessageBox::error( mComposeWin, msg, i18n( <span class="stringliteral">"Chiasmus Backend Error"</span> ) );
<a name="l00581"></a>00581     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00582"></a>00582   }
<a name="l00583"></a>00583   resultData = result.toByteArray();
<a name="l00584"></a>00584   <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00585"></a>00585 }
<a name="l00586"></a>00586 
<a name="l00587"></a>00587 <span class="keywordtype">void</span> MessageComposer::chiasmusEncryptAllAttachments() {
<a name="l00588"></a>00588   <span class="keywordflow">if</span> ( !mEncryptWithChiasmus )
<a name="l00589"></a>00589     <span class="keywordflow">return</span>;
<a name="l00590"></a>00590   assert( !GlobalSettings::chiasmusKey().isEmpty() ); <span class="comment">// kmcomposewin code should have made sure</span>
<a name="l00591"></a>00591   <span class="keywordflow">if</span> ( mAttachments.empty() )
<a name="l00592"></a>00592     <span class="keywordflow">return</span>;
<a name="l00593"></a>00593   <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * chiasmus
<a name="l00594"></a>00594     = Kleo::CryptoBackendFactory::instance()-&gt;protocol( <span class="stringliteral">"Chiasmus"</span> );
<a name="l00595"></a>00595   assert( chiasmus ); <span class="comment">// kmcomposewin code should have made sure</span>
<a name="l00596"></a>00596 
<a name="l00597"></a>00597 
<a name="l00598"></a>00598   <span class="keywordflow">for</span> ( QValueVector&lt;Attachment&gt;::iterator it = mAttachments.begin(), end = mAttachments.end() ; it != end ; ++it ) {
<a name="l00599"></a>00599     KMMessagePart * part = it-&gt;part;
<a name="l00600"></a>00600     <span class="keyword">const</span> QString filename = part-&gt;fileName();
<a name="l00601"></a>00601     <span class="keywordflow">if</span> ( filename.endsWith( <span class="stringliteral">".xia"</span>, <span class="keyword">false</span> ) )
<a name="l00602"></a>00602       <span class="keywordflow">continue</span>; <span class="comment">// already encrypted</span>
<a name="l00603"></a>00603     <span class="keyword">const</span> QByteArray body = part-&gt;bodyDecodedBinary();
<a name="l00604"></a>00604     QByteArray resultData;
<a name="l00605"></a>00605     <span class="keywordflow">if</span> ( !encryptWithChiasmus( chiasmus, body, resultData ) ) {
<a name="l00606"></a>00606       mRc = <span class="keyword">false</span>;
<a name="l00607"></a>00607       <span class="keywordflow">return</span>;
<a name="l00608"></a>00608     }
<a name="l00609"></a>00609     <span class="comment">// everything ok, so let's fill in the part again:</span>
<a name="l00610"></a>00610     QValueList&lt;int&gt; dummy;
<a name="l00611"></a>00611     part-&gt;setBodyAndGuessCte( resultData, dummy );
<a name="l00612"></a>00612     part-&gt;setTypeStr( <span class="stringliteral">"application"</span> );
<a name="l00613"></a>00613     part-&gt;setSubtypeStr( <span class="stringliteral">"vnd.de.bund.bsi.chiasmus"</span> );
<a name="l00614"></a>00614     part-&gt;setName( filename + <span class="stringliteral">".xia"</span> );
<a name="l00615"></a>00615     <span class="comment">// this is taken from kmmsgpartdlg.cpp:</span>
<a name="l00616"></a>00616     QCString encoding = KMMsgBase::autoDetectCharset( part-&gt;charset(), <a class="code" href="classKMMessage.html#41e2c0836f490db2edf4983899a07591" title="Get a list of preferred message charsets.">KMMessage::preferredCharsets</a>(), filename );
<a name="l00617"></a>00617     <span class="keywordflow">if</span> ( encoding.isEmpty() )
<a name="l00618"></a>00618       encoding = <span class="stringliteral">"utf-8"</span>;
<a name="l00619"></a>00619     <span class="keyword">const</span> QCString enc_name = KMMsgBase::encodeRFC2231String( filename + <span class="stringliteral">".xia"</span>, encoding );
<a name="l00620"></a>00620     <span class="keyword">const</span> QCString cDisp = <span class="stringliteral">"attachment;\n\tfilename"</span>
<a name="l00621"></a>00621                            + ( QString( enc_name ) != filename + <span class="stringliteral">".xia"</span>
<a name="l00622"></a>00622                                ? <span class="stringliteral">"*="</span> + enc_name
<a name="l00623"></a>00623                                : <span class="stringliteral">"=\""</span> + escape_quoted_string( enc_name ) + <span class="charliteral">'\"'</span> );
<a name="l00624"></a>00624     part-&gt;setContentDisposition( cDisp );
<a name="l00625"></a>00625   }
<a name="l00626"></a>00626 }
<a name="l00627"></a>00627 
<a name="l00628"></a>00628 <span class="keywordtype">void</span> MessageComposer::adjustCryptFlags()
<a name="l00629"></a>00629 {
<a name="l00630"></a>00630   <span class="keywordflow">if</span> ( !mDisableCrypto &amp;&amp;
<a name="l00631"></a>00631        mAllowedCryptoMessageFormats &amp; Kleo::InlineOpenPGPFormat &amp;&amp;
<a name="l00632"></a>00632        !mAttachments.empty() &amp;&amp;
<a name="l00633"></a>00633        ( mSigningRequested || mEncryptionRequested ) )
<a name="l00634"></a>00634   {
<a name="l00635"></a>00635     <span class="keywordtype">int</span> ret;
<a name="l00636"></a>00636     <span class="keywordflow">if</span> ( mAllowedCryptoMessageFormats == Kleo::InlineOpenPGPFormat ) {
<a name="l00637"></a>00637       ret = KMessageBox::warningYesNoCancel( mComposeWin,
<a name="l00638"></a>00638                                              i18n(<span class="stringliteral">"The inline OpenPGP crypto message format "</span>
<a name="l00639"></a>00639                                                   <span class="stringliteral">"does not support encryption or signing "</span>
<a name="l00640"></a>00640                                                   <span class="stringliteral">"of attachments.\n"</span>
<a name="l00641"></a>00641                                                   <span class="stringliteral">"Really use deprecated inline OpenPGP?"</span>),
<a name="l00642"></a>00642                                              i18n(<span class="stringliteral">"Insecure Message Format"</span>),
<a name="l00643"></a>00643                                              i18n(<span class="stringliteral">"Use Inline OpenPGP"</span>),
<a name="l00644"></a>00644                                              i18n(<span class="stringliteral">"Use OpenPGP/MIME"</span>) );
<a name="l00645"></a>00645     }
<a name="l00646"></a>00646     <span class="keywordflow">else</span> {
<a name="l00647"></a>00647       <span class="comment">// if other crypto message formats are allowed then simply don't use</span>
<a name="l00648"></a>00648       <span class="comment">// inline OpenPGP</span>
<a name="l00649"></a>00649       ret = KMessageBox::No;
<a name="l00650"></a>00650     }
<a name="l00651"></a>00651 
<a name="l00652"></a>00652     <span class="keywordflow">if</span> ( ret == KMessageBox::Cancel ) {
<a name="l00653"></a>00653       mRc = <span class="keyword">false</span>;
<a name="l00654"></a>00654       <span class="keywordflow">return</span>;
<a name="l00655"></a>00655     } <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( ret == KMessageBox::No ) {
<a name="l00656"></a>00656       mAllowedCryptoMessageFormats &amp;= ~Kleo::InlineOpenPGPFormat;
<a name="l00657"></a>00657       mAllowedCryptoMessageFormats |= Kleo::OpenPGPMIMEFormat;
<a name="l00658"></a>00658       <span class="keywordflow">if</span> ( mSigningRequested ) {
<a name="l00659"></a>00659         <span class="comment">// The composer window disabled signing on the attachments, re-enable it</span>
<a name="l00660"></a>00660         <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> idx = 0 ; idx &lt; mAttachments.size() ; ++idx )
<a name="l00661"></a>00661           mAttachments[idx].sign = <span class="keyword">true</span>;
<a name="l00662"></a>00662       }
<a name="l00663"></a>00663       <span class="keywordflow">if</span> ( mEncryptionRequested ) {
<a name="l00664"></a>00664         <span class="comment">// The composer window disabled encrypting on the attachments, re-enable it</span>
<a name="l00665"></a>00665         <span class="comment">// We assume this is what the user wants - after all he chose OpenPGP/MIME for this.</span>
<a name="l00666"></a>00666         <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> idx = 0 ; idx &lt; mAttachments.size() ; ++idx )
<a name="l00667"></a>00667           mAttachments[idx].encrypt = <span class="keyword">true</span>;
<a name="l00668"></a>00668       }
<a name="l00669"></a>00669     }
<a name="l00670"></a>00670   }
<a name="l00671"></a>00671 
<a name="l00672"></a>00672   mKeyResolver =
<a name="l00673"></a>00673     <span class="keyword">new</span> <a class="code" href="classKleo_1_1KeyResolver.html" title="A class to resolve signing/encryption keys w.r.t.">Kleo::KeyResolver</a>( encryptToSelf(), showKeyApprovalDialog(),
<a name="l00674"></a>00674                mUseOpportunisticEncryption, mAllowedCryptoMessageFormats,
<a name="l00675"></a>00675                encryptKeyNearExpiryWarningThresholdInDays(),
<a name="l00676"></a>00676                signingKeyNearExpiryWarningThresholdInDays(),
<a name="l00677"></a>00677                encryptRootCertNearExpiryWarningThresholdInDays(),
<a name="l00678"></a>00678                signingRootCertNearExpiryWarningThresholdInDays(),
<a name="l00679"></a>00679                encryptChainCertNearExpiryWarningThresholdInDays(),
<a name="l00680"></a>00680                signingChainCertNearExpiryWarningThresholdInDays() );
<a name="l00681"></a>00681 
<a name="l00682"></a>00682   <span class="keywordflow">if</span> ( !mDisableCrypto ) {
<a name="l00683"></a>00683     <span class="keyword">const</span> KPIM::Identity &amp; <span class="keywordtype">id</span> =
<a name="l00684"></a>00684       kmkernel-&gt;identityManager()-&gt;identityForUoidOrDefault( mIdentityUid );
<a name="l00685"></a>00685 
<a name="l00686"></a>00686     QStringList encryptToSelfKeys;
<a name="l00687"></a>00687     <span class="keywordflow">if</span> ( !<span class="keywordtype">id</span>.pgpEncryptionKey().isEmpty() )
<a name="l00688"></a>00688       encryptToSelfKeys.push_back( <span class="keywordtype">id</span>.pgpEncryptionKey() );
<a name="l00689"></a>00689     <span class="keywordflow">if</span> ( !<span class="keywordtype">id</span>.smimeEncryptionKey().isEmpty() )
<a name="l00690"></a>00690       encryptToSelfKeys.push_back( <span class="keywordtype">id</span>.smimeEncryptionKey() );
<a name="l00691"></a>00691     <span class="keywordflow">if</span> ( mKeyResolver-&gt;setEncryptToSelfKeys( encryptToSelfKeys ) != Kpgp::Ok ) {
<a name="l00692"></a>00692       mRc = <span class="keyword">false</span>;
<a name="l00693"></a>00693       <span class="keywordflow">return</span>;
<a name="l00694"></a>00694     }
<a name="l00695"></a>00695 
<a name="l00696"></a>00696     QStringList signKeys;
<a name="l00697"></a>00697     <span class="keywordflow">if</span> ( !<span class="keywordtype">id</span>.pgpSigningKey().isEmpty() )
<a name="l00698"></a>00698       signKeys.push_back( mPGPSigningKey = <span class="keywordtype">id</span>.pgpSigningKey() );
<a name="l00699"></a>00699     <span class="keywordflow">if</span> ( !<span class="keywordtype">id</span>.smimeSigningKey().isEmpty() )
<a name="l00700"></a>00700       signKeys.push_back( mSMIMESigningKey = <span class="keywordtype">id</span>.smimeSigningKey() );
<a name="l00701"></a>00701     <span class="keywordflow">if</span> ( mKeyResolver-&gt;setSigningKeys( signKeys ) != Kpgp::Ok ) {
<a name="l00702"></a>00702       mRc = <span class="keyword">false</span>;
<a name="l00703"></a>00703       <span class="keywordflow">return</span>;
<a name="l00704"></a>00704     }
<a name="l00705"></a>00705   }
<a name="l00706"></a>00706 
<a name="l00707"></a>00707   mKeyResolver-&gt;setPrimaryRecipients( mTo + mCc );
<a name="l00708"></a>00708   mKeyResolver-&gt;setSecondaryRecipients( mBccList );
<a name="l00709"></a>00709 
<a name="l00710"></a>00710   <span class="comment">// check settings of composer buttons *and* attachment check boxes</span>
<a name="l00711"></a>00711   <span class="keywordtype">bool</span> doSignCompletely    = mSigningRequested;
<a name="l00712"></a>00712   <span class="keywordtype">bool</span> doEncryptCompletely = mEncryptionRequested;
<a name="l00713"></a>00713   <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> idx = 0 ; idx &lt; mAttachments.size() ; ++idx ) {
<a name="l00714"></a>00714     <span class="keywordflow">if</span> ( mAttachments[idx].encrypt )
<a name="l00715"></a>00715       mEncryptionRequested = <span class="keyword">true</span>;
<a name="l00716"></a>00716     <span class="keywordflow">else</span>
<a name="l00717"></a>00717       doEncryptCompletely = <span class="keyword">false</span>;
<a name="l00718"></a>00718     <span class="keywordflow">if</span> ( mAttachments[idx].sign )
<a name="l00719"></a>00719       mSigningRequested = <span class="keyword">true</span>;
<a name="l00720"></a>00720     <span class="keywordflow">else</span>
<a name="l00721"></a>00721       doSignCompletely = <span class="keyword">false</span>;
<a name="l00722"></a>00722   }
<a name="l00723"></a>00723 
<a name="l00724"></a>00724   mDoSign = !mDisableCrypto &amp;&amp; determineWhetherToSign( doSignCompletely );
<a name="l00725"></a>00725 
<a name="l00726"></a>00726   <span class="keywordflow">if</span> ( !mRc )
<a name="l00727"></a>00727     <span class="keywordflow">return</span>;
<a name="l00728"></a>00728 
<a name="l00729"></a>00729   mDoEncrypt = !mDisableCrypto &amp;&amp; determineWhetherToEncrypt( doEncryptCompletely );
<a name="l00730"></a>00730 
<a name="l00731"></a>00731   <span class="keywordflow">if</span> ( !mRc )
<a name="l00732"></a>00732     <span class="keywordflow">return</span>;
<a name="l00733"></a>00733 
<a name="l00734"></a>00734   <span class="comment">// resolveAllKeys needs to run even if mDisableCrypto == true, since</span>
<a name="l00735"></a>00735   <span class="comment">// we depend on it collecting all recipients into one dummy</span>
<a name="l00736"></a>00736   <span class="comment">// SplitInfo to avoid special-casing all over the place:</span>
<a name="l00737"></a>00737   <span class="keywordflow">if</span> ( mKeyResolver-&gt;resolveAllKeys( mDoSign, mDoEncrypt ) != Kpgp::Ok )
<a name="l00738"></a>00738     mRc = <span class="keyword">false</span>;
<a name="l00739"></a>00739 }
<a name="l00740"></a>00740 
<a name="l00741"></a>00741 <span class="keywordtype">bool</span> MessageComposer::determineWhetherToSign( <span class="keywordtype">bool</span> doSignCompletely ) {
<a name="l00742"></a>00742   <span class="keywordtype">bool</span> sign = <span class="keyword">false</span>;
<a name="l00743"></a>00743   <span class="keywordflow">switch</span> ( mKeyResolver-&gt;checkSigningPreferences( mSigningRequested ) ) {
<a name="l00744"></a>00744   <span class="keywordflow">case</span> Kleo::DoIt:
<a name="l00745"></a>00745     <span class="keywordflow">if</span> ( !mSigningRequested ) {
<a name="l00746"></a>00746       markAllAttachmentsForSigning( <span class="keyword">true</span> );
<a name="l00747"></a>00747       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00748"></a>00748     }
<a name="l00749"></a>00749     sign = <span class="keyword">true</span>;
<a name="l00750"></a>00750     <span class="keywordflow">break</span>;
<a name="l00751"></a>00751   <span class="keywordflow">case</span> Kleo::DontDoIt:
<a name="l00752"></a>00752     sign = <span class="keyword">false</span>;
<a name="l00753"></a>00753     <span class="keywordflow">break</span>;
<a name="l00754"></a>00754   <span class="keywordflow">case</span> Kleo::AskOpportunistic:
<a name="l00755"></a>00755     assert( 0 );
<a name="l00756"></a>00756   <span class="keywordflow">case</span> Kleo::Ask:
<a name="l00757"></a>00757     {
<a name="l00758"></a>00758       <span class="comment">// the user wants to be asked or has to be asked</span>
<a name="l00759"></a>00759       <span class="keyword">const</span> <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l00760"></a>00760       <span class="keyword">const</span> QString msg = i18n(<span class="stringliteral">"Examination of the recipient's signing preferences "</span>
<a name="l00761"></a>00761                    <span class="stringliteral">"yielded that you be asked whether or not to sign "</span>
<a name="l00762"></a>00762                    <span class="stringliteral">"this message.\n"</span>
<a name="l00763"></a>00763                    <span class="stringliteral">"Sign this message?"</span>);
<a name="l00764"></a>00764       <span class="keywordflow">switch</span> ( KMessageBox::questionYesNoCancel( mComposeWin, msg,
<a name="l00765"></a>00765                          i18n(<span class="stringliteral">"Sign Message?"</span>),
<a name="l00766"></a>00766                          i18n(<span class="stringliteral">"to sign"</span>,<span class="stringliteral">"&amp;Sign"</span>),
<a name="l00767"></a>00767                          i18n(<span class="stringliteral">"Do &amp;Not Sign"</span>) ) ) {
<a name="l00768"></a>00768       <span class="keywordflow">case</span> KMessageBox::Cancel:
<a name="l00769"></a>00769     mRc = <span class="keyword">false</span>;
<a name="l00770"></a>00770     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00771"></a>00771       <span class="keywordflow">case</span> KMessageBox::Yes:
<a name="l00772"></a>00772     markAllAttachmentsForSigning( <span class="keyword">true</span> );
<a name="l00773"></a>00773     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00774"></a>00774       <span class="keywordflow">case</span> KMessageBox::No:
<a name="l00775"></a>00775     markAllAttachmentsForSigning( <span class="keyword">false</span> );
<a name="l00776"></a>00776     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00777"></a>00777       }
<a name="l00778"></a>00778     }
<a name="l00779"></a>00779     <span class="keywordflow">break</span>;
<a name="l00780"></a>00780   <span class="keywordflow">case</span> Kleo::Conflict:
<a name="l00781"></a>00781     {
<a name="l00782"></a>00782       <span class="comment">// warn the user that there are conflicting signing preferences</span>
<a name="l00783"></a>00783       <span class="keyword">const</span> <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l00784"></a>00784       <span class="keyword">const</span> QString msg = i18n(<span class="stringliteral">"There are conflicting signing preferences "</span>
<a name="l00785"></a>00785                    <span class="stringliteral">"for these recipients.\n"</span>
<a name="l00786"></a>00786                    <span class="stringliteral">"Sign this message?"</span>);
<a name="l00787"></a>00787       <span class="keywordflow">switch</span> ( KMessageBox::warningYesNoCancel( mComposeWin, msg,
<a name="l00788"></a>00788                         i18n(<span class="stringliteral">"Sign Message?"</span>),
<a name="l00789"></a>00789                         i18n(<span class="stringliteral">"to sign"</span>,<span class="stringliteral">"&amp;Sign"</span>),
<a name="l00790"></a>00790                         i18n(<span class="stringliteral">"Do &amp;Not Sign"</span>) ) ) {
<a name="l00791"></a>00791       <span class="keywordflow">case</span> KMessageBox::Cancel:
<a name="l00792"></a>00792     mRc = <span class="keyword">false</span>;
<a name="l00793"></a>00793     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00794"></a>00794       <span class="keywordflow">case</span> KMessageBox::Yes:
<a name="l00795"></a>00795     markAllAttachmentsForSigning( <span class="keyword">true</span> );
<a name="l00796"></a>00796     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00797"></a>00797       <span class="keywordflow">case</span> KMessageBox::No:
<a name="l00798"></a>00798     markAllAttachmentsForSigning( <span class="keyword">false</span> );
<a name="l00799"></a>00799     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00800"></a>00800       }
<a name="l00801"></a>00801     }
<a name="l00802"></a>00802     <span class="keywordflow">break</span>;
<a name="l00803"></a>00803   <span class="keywordflow">case</span> Kleo::Impossible:
<a name="l00804"></a>00804     {
<a name="l00805"></a>00805       <span class="keyword">const</span> <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l00806"></a>00806       <span class="keyword">const</span> QString msg = i18n(<span class="stringliteral">"You have requested to sign this message, "</span>
<a name="l00807"></a>00807                    <span class="stringliteral">"but no valid signing keys have been configured "</span>
<a name="l00808"></a>00808                    <span class="stringliteral">"for this identity."</span>);
<a name="l00809"></a>00809       <span class="keywordflow">if</span> ( KMessageBox::warningContinueCancel( mComposeWin, msg,
<a name="l00810"></a>00810                            i18n(<span class="stringliteral">"Send Unsigned?"</span>),
<a name="l00811"></a>00811                                                i18n(<span class="stringliteral">"Send &amp;Unsigned"</span>) )
<a name="l00812"></a>00812        == KMessageBox::Cancel ) {
<a name="l00813"></a>00813     mRc = <span class="keyword">false</span>;
<a name="l00814"></a>00814     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00815"></a>00815       } <span class="keywordflow">else</span> {
<a name="l00816"></a>00816     markAllAttachmentsForSigning( <span class="keyword">false</span> );
<a name="l00817"></a>00817     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00818"></a>00818       }
<a name="l00819"></a>00819     }
<a name="l00820"></a>00820   }
<a name="l00821"></a>00821 
<a name="l00822"></a>00822   <span class="keywordflow">if</span> ( !sign || !doSignCompletely ) {
<a name="l00823"></a>00823     <span class="keywordflow">if</span> ( warnSendUnsigned() ) {
<a name="l00824"></a>00824       <span class="keyword">const</span> <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l00825"></a>00825       <span class="keyword">const</span> QString msg = sign &amp;&amp; !doSignCompletely
<a name="l00826"></a>00826     ? i18n(<span class="stringliteral">"Some parts of this message will not be signed.\n"</span>
<a name="l00827"></a>00827            <span class="stringliteral">"Sending only partially signed messages might violate site policy.\n"</span>
<a name="l00828"></a>00828            <span class="stringliteral">"Sign all parts instead?"</span>) <span class="comment">// oh, I hate this...</span>
<a name="l00829"></a>00829     : i18n(<span class="stringliteral">"This message will not be signed.\n"</span>
<a name="l00830"></a>00830            <span class="stringliteral">"Sending unsigned message might violate site policy.\n"</span>
<a name="l00831"></a>00831            <span class="stringliteral">"Sign message instead?"</span>) ; <span class="comment">// oh, I hate this...</span>
<a name="l00832"></a>00832       <span class="keyword">const</span> QString buttonText = sign &amp;&amp; !doSignCompletely
<a name="l00833"></a>00833     ? i18n(<span class="stringliteral">"&amp;Sign All Parts"</span>) : i18n(<span class="stringliteral">"&amp;Sign"</span>) ;
<a name="l00834"></a>00834       <span class="keywordflow">switch</span> ( KMessageBox::warningYesNoCancel( mComposeWin, msg,
<a name="l00835"></a>00835                         i18n(<span class="stringliteral">"Unsigned-Message Warning"</span>),
<a name="l00836"></a>00836                         buttonText,
<a name="l00837"></a>00837                         i18n(<span class="stringliteral">"Send &amp;As Is"</span>) ) ) {
<a name="l00838"></a>00838       <span class="keywordflow">case</span> KMessageBox::Cancel:
<a name="l00839"></a>00839     mRc = <span class="keyword">false</span>;
<a name="l00840"></a>00840     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00841"></a>00841       <span class="keywordflow">case</span> KMessageBox::Yes:
<a name="l00842"></a>00842     markAllAttachmentsForSigning( <span class="keyword">true</span> );
<a name="l00843"></a>00843     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00844"></a>00844       <span class="keywordflow">case</span> KMessageBox::No:
<a name="l00845"></a>00845     <span class="keywordflow">return</span> sign || doSignCompletely;
<a name="l00846"></a>00846       }
<a name="l00847"></a>00847     }
<a name="l00848"></a>00848   }
<a name="l00849"></a>00849 
<a name="l00850"></a>00850   <span class="keywordflow">return</span> sign || doSignCompletely ;
<a name="l00851"></a>00851 }
<a name="l00852"></a>00852 
<a name="l00853"></a>00853 <span class="keywordtype">bool</span> MessageComposer::determineWhetherToEncrypt( <span class="keywordtype">bool</span> doEncryptCompletely ) {
<a name="l00854"></a>00854   <span class="keywordtype">bool</span> encrypt = <span class="keyword">false</span>;
<a name="l00855"></a>00855   <span class="keywordtype">bool</span> opportunistic = <span class="keyword">false</span>;
<a name="l00856"></a>00856   <span class="keywordflow">switch</span> ( mKeyResolver-&gt;checkEncryptionPreferences( mEncryptionRequested ) ) {
<a name="l00857"></a>00857   <span class="keywordflow">case</span> Kleo::DoIt:
<a name="l00858"></a>00858     <span class="keywordflow">if</span> ( !mEncryptionRequested ) {
<a name="l00859"></a>00859       markAllAttachmentsForEncryption( <span class="keyword">true</span> );
<a name="l00860"></a>00860       <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00861"></a>00861     }
<a name="l00862"></a>00862     encrypt = <span class="keyword">true</span>;
<a name="l00863"></a>00863     <span class="keywordflow">break</span>;
<a name="l00864"></a>00864   <span class="keywordflow">case</span> Kleo::DontDoIt:
<a name="l00865"></a>00865     encrypt = <span class="keyword">false</span>;
<a name="l00866"></a>00866     <span class="keywordflow">break</span>;
<a name="l00867"></a>00867   <span class="keywordflow">case</span> Kleo::AskOpportunistic:
<a name="l00868"></a>00868     opportunistic = <span class="keyword">true</span>;
<a name="l00869"></a>00869     <span class="comment">// fall through...</span>
<a name="l00870"></a>00870   <span class="keywordflow">case</span> Kleo::Ask:
<a name="l00871"></a>00871     {
<a name="l00872"></a>00872       <span class="comment">// the user wants to be asked or has to be asked</span>
<a name="l00873"></a>00873       <span class="keyword">const</span> <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l00874"></a>00874       <span class="keyword">const</span> QString msg = opportunistic
<a name="l00875"></a>00875     ? i18n(<span class="stringliteral">"Valid trusted encryption keys were found for all recipients.\n"</span>
<a name="l00876"></a>00876            <span class="stringliteral">"Encrypt this message?"</span>)
<a name="l00877"></a>00877     : i18n(<span class="stringliteral">"Examination of the recipient's encryption preferences "</span>
<a name="l00878"></a>00878            <span class="stringliteral">"yielded that you be asked whether or not to encrypt "</span>
<a name="l00879"></a>00879            <span class="stringliteral">"this message.\n"</span>
<a name="l00880"></a>00880            <span class="stringliteral">"Encrypt this message?"</span>);
<a name="l00881"></a>00881       <span class="keywordflow">switch</span> ( KMessageBox::questionYesNoCancel( mComposeWin, msg,
<a name="l00882"></a>00882                          i18n(<span class="stringliteral">"Encrypt Message?"</span>),
<a name="l00883"></a>00883                          mDoSign
<a name="l00884"></a>00884                          ? i18n(<span class="stringliteral">"Sign &amp;&amp; &amp;Encrypt"</span>)
<a name="l00885"></a>00885                          : i18n(<span class="stringliteral">"&amp;Encrypt"</span>),
<a name="l00886"></a>00886                          mDoSign
<a name="l00887"></a>00887                          ? i18n(<span class="stringliteral">"&amp;Sign Only"</span>)
<a name="l00888"></a>00888                          : i18n(<span class="stringliteral">"&amp;Send As-Is"</span>) ) ) {
<a name="l00889"></a>00889       <span class="keywordflow">case</span> KMessageBox::Cancel:
<a name="l00890"></a>00890     mRc = <span class="keyword">false</span>;
<a name="l00891"></a>00891     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00892"></a>00892       <span class="keywordflow">case</span> KMessageBox::Yes:
<a name="l00893"></a>00893     markAllAttachmentsForEncryption( <span class="keyword">true</span> );
<a name="l00894"></a>00894     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00895"></a>00895       <span class="keywordflow">case</span> KMessageBox::No:
<a name="l00896"></a>00896     markAllAttachmentsForEncryption( <span class="keyword">false</span> );
<a name="l00897"></a>00897     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00898"></a>00898       }
<a name="l00899"></a>00899     }
<a name="l00900"></a>00900     <span class="keywordflow">break</span>;
<a name="l00901"></a>00901   <span class="keywordflow">case</span> Kleo::Conflict:
<a name="l00902"></a>00902     {
<a name="l00903"></a>00903       <span class="comment">// warn the user that there are conflicting encryption preferences</span>
<a name="l00904"></a>00904       <span class="keyword">const</span> <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l00905"></a>00905       <span class="keyword">const</span> QString msg = i18n(<span class="stringliteral">"There are conflicting encryption preferences "</span>
<a name="l00906"></a>00906                    <span class="stringliteral">"for these recipients.\n"</span>
<a name="l00907"></a>00907                    <span class="stringliteral">"Encrypt this message?"</span>);
<a name="l00908"></a>00908       <span class="keywordflow">switch</span> ( KMessageBox::warningYesNoCancel( mComposeWin, msg,
<a name="l00909"></a>00909                         i18n(<span class="stringliteral">"Encrypt Message?"</span>),
<a name="l00910"></a>00910                         i18n(<span class="stringliteral">"&amp;Encrypt"</span>),
<a name="l00911"></a>00911                         i18n(<span class="stringliteral">"Do &amp;Not Encrypt"</span>) ) ) {
<a name="l00912"></a>00912       <span class="keywordflow">case</span> KMessageBox::Cancel:
<a name="l00913"></a>00913     mRc = <span class="keyword">false</span>;
<a name="l00914"></a>00914     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00915"></a>00915       <span class="keywordflow">case</span> KMessageBox::Yes:
<a name="l00916"></a>00916     markAllAttachmentsForEncryption( <span class="keyword">true</span> );
<a name="l00917"></a>00917     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00918"></a>00918       <span class="keywordflow">case</span> KMessageBox::No:
<a name="l00919"></a>00919     markAllAttachmentsForEncryption( <span class="keyword">false</span> );
<a name="l00920"></a>00920     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00921"></a>00921       }
<a name="l00922"></a>00922     }
<a name="l00923"></a>00923     <span class="keywordflow">break</span>;
<a name="l00924"></a>00924   <span class="keywordflow">case</span> Kleo::Impossible:
<a name="l00925"></a>00925     {
<a name="l00926"></a>00926       <span class="keyword">const</span> <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l00927"></a>00927       <span class="keyword">const</span> QString msg = i18n(<span class="stringliteral">"You have requested to encrypt this message, "</span>
<a name="l00928"></a>00928                    <span class="stringliteral">"and to encrypt a copy to yourself, "</span>
<a name="l00929"></a>00929                    <span class="stringliteral">"but no valid trusted encryption keys have been "</span>
<a name="l00930"></a>00930                    <span class="stringliteral">"configured for this identity."</span>);
<a name="l00931"></a>00931       <span class="keywordflow">if</span> ( KMessageBox::warningContinueCancel( mComposeWin, msg,
<a name="l00932"></a>00932                            i18n(<span class="stringliteral">"Send Unencrypted?"</span>),
<a name="l00933"></a>00933                                                i18n(<span class="stringliteral">"Send &amp;Unencrypted"</span>) )
<a name="l00934"></a>00934        == KMessageBox::Cancel ) {
<a name="l00935"></a>00935     mRc = <span class="keyword">false</span>;
<a name="l00936"></a>00936     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00937"></a>00937       } <span class="keywordflow">else</span> {
<a name="l00938"></a>00938     markAllAttachmentsForEncryption( <span class="keyword">false</span> );
<a name="l00939"></a>00939     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00940"></a>00940       }
<a name="l00941"></a>00941     }
<a name="l00942"></a>00942   }
<a name="l00943"></a>00943 
<a name="l00944"></a>00944   <span class="keywordflow">if</span> ( !encrypt || !doEncryptCompletely ) {
<a name="l00945"></a>00945     <span class="keywordflow">if</span> ( warnSendUnencrypted() ) {
<a name="l00946"></a>00946       <span class="keyword">const</span> <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l00947"></a>00947       <span class="keyword">const</span> QString msg = !doEncryptCompletely
<a name="l00948"></a>00948     ? i18n(<span class="stringliteral">"Some parts of this message will not be encrypted.\n"</span>
<a name="l00949"></a>00949            <span class="stringliteral">"Sending only partially encrypted messages might violate site policy "</span>
<a name="l00950"></a>00950            <span class="stringliteral">"and/or leak sensitive information.\n"</span>
<a name="l00951"></a>00951            <span class="stringliteral">"Encrypt all parts instead?"</span>) <span class="comment">// oh, I hate this...</span>
<a name="l00952"></a>00952     : i18n(<span class="stringliteral">"This message will not be encrypted.\n"</span>
<a name="l00953"></a>00953            <span class="stringliteral">"Sending unencrypted messages might violate site policy and/or "</span>
<a name="l00954"></a>00954            <span class="stringliteral">"leak sensitive information.\n"</span>
<a name="l00955"></a>00955            <span class="stringliteral">"Encrypt messages instead?"</span>) ; <span class="comment">// oh, I hate this...</span>
<a name="l00956"></a>00956       <span class="keyword">const</span> QString buttonText = !doEncryptCompletely
<a name="l00957"></a>00957     ? i18n(<span class="stringliteral">"&amp;Encrypt All Parts"</span>) : i18n(<span class="stringliteral">"&amp;Encrypt"</span>) ;
<a name="l00958"></a>00958       <span class="keywordflow">switch</span> ( KMessageBox::warningYesNoCancel( mComposeWin, msg,
<a name="l00959"></a>00959                         i18n(<span class="stringliteral">"Unencrypted Message Warning"</span>),
<a name="l00960"></a>00960                         buttonText,
<a name="l00961"></a>00961                         mDoSign
<a name="l00962"></a>00962                         ? i18n(<span class="stringliteral">"&amp;Sign Only"</span>)
<a name="l00963"></a>00963                         : i18n(<span class="stringliteral">"&amp;Send As-Is"</span>) ) ) {
<a name="l00964"></a>00964       <span class="keywordflow">case</span> KMessageBox::Cancel:
<a name="l00965"></a>00965     mRc = <span class="keyword">false</span>;
<a name="l00966"></a>00966     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l00967"></a>00967       <span class="keywordflow">case</span> KMessageBox::Yes:
<a name="l00968"></a>00968     markAllAttachmentsForEncryption( <span class="keyword">true</span> );
<a name="l00969"></a>00969     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l00970"></a>00970       <span class="keywordflow">case</span> KMessageBox::No:
<a name="l00971"></a>00971     <span class="keywordflow">return</span> encrypt || doEncryptCompletely;
<a name="l00972"></a>00972       }
<a name="l00973"></a>00973     }
<a name="l00974"></a>00974   }
<a name="l00975"></a>00975 
<a name="l00976"></a>00976   <span class="keywordflow">return</span> encrypt || doEncryptCompletely ;
<a name="l00977"></a>00977 }
<a name="l00978"></a>00978 
<a name="l00979"></a>00979 <span class="keywordtype">void</span> MessageComposer::markAllAttachmentsForSigning( <span class="keywordtype">bool</span> sign ) {
<a name="l00980"></a>00980   mSignBody = sign;
<a name="l00981"></a>00981   <span class="keywordflow">for</span> ( QValueVector&lt;Attachment&gt;::iterator it = mAttachments.begin() ; it != mAttachments.end() ; ++it )
<a name="l00982"></a>00982     it-&gt;sign = sign;
<a name="l00983"></a>00983 }
<a name="l00984"></a>00984 
<a name="l00985"></a>00985 <span class="keywordtype">void</span> MessageComposer::markAllAttachmentsForEncryption( <span class="keywordtype">bool</span> enc ) {
<a name="l00986"></a>00986   mEncryptBody = enc;
<a name="l00987"></a>00987   <span class="keywordflow">for</span> ( QValueVector&lt;Attachment&gt;::iterator it = mAttachments.begin() ; it != mAttachments.end() ; ++it )
<a name="l00988"></a>00988     it-&gt;encrypt = enc;
<a name="l00989"></a>00989 }
<a name="l00990"></a>00990 
<a name="l00991"></a>00991 
<a name="l00992"></a>00992 <span class="keywordtype">void</span> MessageComposer::composeMessage()
<a name="l00993"></a>00993 {
<a name="l00994"></a>00994   <span class="keywordflow">for</span> ( <span class="keywordtype">unsigned</span> <span class="keywordtype">int</span> i = 0 ; i &lt; numConcreteCryptoMessageFormats ; ++i ) {
<a name="l00995"></a>00995     <span class="keywordflow">if</span> ( mKeyResolver-&gt;encryptionItems( concreteCryptoMessageFormats[i] ).empty() )
<a name="l00996"></a>00996       <span class="keywordflow">continue</span>;
<a name="l00997"></a>00997     <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a> * msg = <span class="keyword">new</span> <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>( *mReferenceMessage );
<a name="l00998"></a>00998     composeMessage( *msg, mDoSign, mDoEncrypt, concreteCryptoMessageFormats[i] );
<a name="l00999"></a>00999     <span class="keywordflow">if</span> ( !mRc )
<a name="l01000"></a>01000       <span class="keywordflow">return</span>;
<a name="l01001"></a>01001   }
<a name="l01002"></a>01002 }
<a name="l01003"></a>01003 
<a name="l01004"></a>01004 <span class="comment">//</span>
<a name="l01005"></a>01005 <span class="comment">// These are replacements for StructuringInfo(Wrapper):</span>
<a name="l01006"></a>01006 <span class="comment">//</span>
<a name="l01007"></a>01007 
<a name="l01008"></a>01008 <span class="comment">// check whether to use multipart/{signed,encrypted}</span>
<a name="l01009"></a>01009 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> makeMultiMime( Kleo::CryptoMessageFormat f, <span class="keywordtype">bool</span> sign ) {
<a name="l01010"></a>01010   <span class="keywordflow">switch</span> ( f ) {
<a name="l01011"></a>01011   <span class="keywordflow">default</span>:
<a name="l01012"></a>01012   <span class="keywordflow">case</span> Kleo::InlineOpenPGPFormat:
<a name="l01013"></a>01013   <span class="keywordflow">case</span> Kleo::SMIMEOpaqueFormat:   <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01014"></a>01014   <span class="keywordflow">case</span> Kleo::OpenPGPMIMEFormat:   <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01015"></a>01015   <span class="keywordflow">case</span> Kleo::SMIMEFormat:         <span class="keywordflow">return</span> sign; <span class="comment">// only on sign - there's no mp/encrypted for S/MIME</span>
<a name="l01016"></a>01016   }
<a name="l01017"></a>01017 }
<a name="l01018"></a>01018 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> makeMultiPartSigned( Kleo::CryptoMessageFormat f ) {
<a name="l01019"></a>01019   <span class="keywordflow">return</span> makeMultiMime( f, <span class="keyword">true</span> );
<a name="l01020"></a>01020 }
<a name="l01021"></a>01021 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> makeMultiPartEncrypted( Kleo::CryptoMessageFormat f ) {
<a name="l01022"></a>01022   <span class="keywordflow">return</span> makeMultiMime( f, <span class="keyword">false</span> );
<a name="l01023"></a>01023 }
<a name="l01024"></a>01024 
<a name="l01025"></a>01025 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> makeMimeObject( Kleo::CryptoMessageFormat f, <span class="keywordtype">bool</span> <span class="comment">/*signing*/</span> ) {
<a name="l01026"></a>01026   <span class="keywordflow">return</span> f != Kleo::InlineOpenPGPFormat;
<a name="l01027"></a>01027 }
<a name="l01028"></a>01028 
<a name="l01029"></a>01029 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * toplevelContentType( Kleo::CryptoMessageFormat f, <span class="keywordtype">bool</span> signing ) {
<a name="l01030"></a>01030   <span class="keywordflow">switch</span> ( f ) {
<a name="l01031"></a>01031   <span class="keywordflow">default</span>:
<a name="l01032"></a>01032   <span class="keywordflow">case</span> Kleo::InlineOpenPGPFormat: <span class="keywordflow">return</span> 0;
<a name="l01033"></a>01033   <span class="keywordflow">case</span> Kleo::OpenPGPMIMEFormat:
<a name="l01034"></a>01034     <span class="keywordflow">return</span> signing ?
<a name="l01035"></a>01035       <span class="stringliteral">"multipart/signed;\n\t"</span>
<a name="l01036"></a>01036       <span class="stringliteral">"boundary=\"%boundary\";\n\t"</span>
<a name="l01037"></a>01037       <span class="stringliteral">"protocol=\"application/pgp-signature\";\n\t"</span>
<a name="l01038"></a>01038       <span class="stringliteral">"micalg=pgp-sha1"</span> <span class="comment">// FIXME: obtain this parameter from gpgme!</span>
<a name="l01039"></a>01039       :
<a name="l01040"></a>01040       <span class="stringliteral">"multipart/encrypted;\n\t"</span>
<a name="l01041"></a>01041       <span class="stringliteral">"boundary=\"%boundary\";\n\t"</span>
<a name="l01042"></a>01042       <span class="stringliteral">"protocol=\"application/pgp-encrypted\""</span>
<a name="l01043"></a>01043       ;
<a name="l01044"></a>01044   <span class="keywordflow">case</span> Kleo::SMIMEFormat:
<a name="l01045"></a>01045     <span class="keywordflow">if</span> ( signing )
<a name="l01046"></a>01046       <span class="keywordflow">return</span>
<a name="l01047"></a>01047     <span class="stringliteral">"multipart/signed;\n\t"</span>
<a name="l01048"></a>01048     <span class="stringliteral">"boundary=\"%boundary\";\n\t"</span>
<a name="l01049"></a>01049     <span class="stringliteral">"protocol=\"application/pkcs7-signature\";\n\t"</span>
<a name="l01050"></a>01050     <span class="stringliteral">"micalg=sha1"</span>; <span class="comment">// FIXME: obtain this parameter from gpgme!</span>
<a name="l01051"></a>01051     <span class="comment">// fall through (for encryption, there's no difference between</span>
<a name="l01052"></a>01052     <span class="comment">// SMIME and SMIMEOpaque, since there is no mp/encrypted for</span>
<a name="l01053"></a>01053     <span class="comment">// S/MIME):</span>
<a name="l01054"></a>01054   <span class="keywordflow">case</span> Kleo::SMIMEOpaqueFormat:
<a name="l01055"></a>01055     <span class="keywordflow">return</span> signing ?
<a name="l01056"></a>01056       <span class="stringliteral">"application/pkcs7-mime;\n\t"</span>
<a name="l01057"></a>01057       <span class="stringliteral">"smime-type=signed-data;\n\t"</span>
<a name="l01058"></a>01058       <span class="stringliteral">"name=\"smime.p7m\";\n\t"</span>
<a name="l01059"></a>01059       :
<a name="l01060"></a>01060       <span class="stringliteral">"application/pkcs7-mime;\n\t"</span>
<a name="l01061"></a>01061       <span class="stringliteral">"smime-type=enveloped-data;\n\t"</span>
<a name="l01062"></a>01062       <span class="stringliteral">"name=\"smime.p7m\";\n\t"</span>
<a name="l01063"></a>01063       ;
<a name="l01064"></a>01064   }
<a name="l01065"></a>01065 }
<a name="l01066"></a>01066 
<a name="l01067"></a>01067 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * toplevelContentDisposition( Kleo::CryptoMessageFormat f, <span class="keywordtype">bool</span> signing ) {
<a name="l01068"></a>01068   <span class="keywordflow">switch</span> ( f ) {
<a name="l01069"></a>01069   <span class="keywordflow">default</span>:
<a name="l01070"></a>01070   <span class="keywordflow">case</span> Kleo::InlineOpenPGPFormat:
<a name="l01071"></a>01071   <span class="keywordflow">case</span> Kleo::OpenPGPMIMEFormat:
<a name="l01072"></a>01072     <span class="keywordflow">return</span> 0;
<a name="l01073"></a>01073   <span class="keywordflow">case</span> Kleo::SMIMEFormat:
<a name="l01074"></a>01074     <span class="keywordflow">if</span> ( signing )
<a name="l01075"></a>01075       <span class="keywordflow">return</span> 0;
<a name="l01076"></a>01076   <span class="keywordflow">case</span> Kleo::SMIMEOpaqueFormat:
<a name="l01077"></a>01077     <span class="keywordflow">return</span> <span class="stringliteral">"attachment; filename=\"smime.p7m\""</span>;
<a name="l01078"></a>01078   }
<a name="l01079"></a>01079 }
<a name="l01080"></a>01080 
<a name="l01081"></a>01081 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> includeCleartextWhenSigning( Kleo::CryptoMessageFormat f ) {
<a name="l01082"></a>01082   <span class="keywordflow">return</span> makeMultiPartSigned( f );
<a name="l01083"></a>01083 }
<a name="l01084"></a>01084 
<a name="l01085"></a>01085 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * nestedContentType( Kleo::CryptoMessageFormat f, <span class="keywordtype">bool</span> signing ) {
<a name="l01086"></a>01086   <span class="keywordflow">switch</span> ( f ) {
<a name="l01087"></a>01087   <span class="keywordflow">case</span> Kleo::OpenPGPMIMEFormat:
<a name="l01088"></a>01088     <span class="keywordflow">return</span> signing ? <span class="stringliteral">"application/pgp-signature; name=signature.asc \nContent-Description: This is a digitally signed message part."</span> : <span class="stringliteral">"application/octet-stream"</span> ;
<a name="l01089"></a>01089   <span class="keywordflow">case</span> Kleo::SMIMEFormat:
<a name="l01090"></a>01090     <span class="keywordflow">if</span> ( signing )
<a name="l01091"></a>01091       <span class="keywordflow">return</span> <span class="stringliteral">"application/pkcs7-signature; name=\"smime.p7s\""</span>;
<a name="l01092"></a>01092     <span class="comment">// fall through:</span>
<a name="l01093"></a>01093   <span class="keywordflow">default</span>:
<a name="l01094"></a>01094   <span class="keywordflow">case</span> Kleo::InlineOpenPGPFormat:
<a name="l01095"></a>01095   <span class="keywordflow">case</span> Kleo::SMIMEOpaqueFormat:
<a name="l01096"></a>01096     <span class="keywordflow">return</span> 0;
<a name="l01097"></a>01097   }
<a name="l01098"></a>01098 }
<a name="l01099"></a>01099 
<a name="l01100"></a>01100 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * nestedContentDisposition( Kleo::CryptoMessageFormat f, <span class="keywordtype">bool</span> signing ) {
<a name="l01101"></a>01101   <span class="keywordflow">if</span> ( !signing &amp;&amp; f == Kleo::OpenPGPMIMEFormat )
<a name="l01102"></a>01102     <span class="keywordflow">return</span> <span class="stringliteral">"inline; filename=\"msg.asc\""</span>;
<a name="l01103"></a>01103   <span class="keywordflow">if</span> ( signing &amp;&amp; f == Kleo::SMIMEFormat )
<a name="l01104"></a>01104     <span class="keywordflow">return</span> <span class="stringliteral">"attachment; filename=\"smime.p7s\""</span>;
<a name="l01105"></a>01105   <span class="keywordflow">return</span> 0;
<a name="l01106"></a>01106 }
<a name="l01107"></a>01107 
<a name="l01108"></a>01108 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> binaryHint( Kleo::CryptoMessageFormat f ) {
<a name="l01109"></a>01109   <span class="keywordflow">switch</span> ( f ) {
<a name="l01110"></a>01110   <span class="keywordflow">case</span> Kleo::SMIMEFormat:
<a name="l01111"></a>01111   <span class="keywordflow">case</span> Kleo::SMIMEOpaqueFormat:
<a name="l01112"></a>01112     <span class="keywordflow">return</span> <span class="keyword">true</span>;
<a name="l01113"></a>01113   <span class="keywordflow">default</span>:
<a name="l01114"></a>01114   <span class="keywordflow">case</span> Kleo::OpenPGPMIMEFormat:
<a name="l01115"></a>01115   <span class="keywordflow">case</span> Kleo::InlineOpenPGPFormat:
<a name="l01116"></a>01116     <span class="keywordflow">return</span> <span class="keyword">false</span>;
<a name="l01117"></a>01117   }
<a name="l01118"></a>01118 }
<a name="l01119"></a>01119 
<a name="l01120"></a>01120 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> armor( Kleo::CryptoMessageFormat f ) {
<a name="l01121"></a>01121   <span class="keywordflow">return</span> !binaryHint( f );
<a name="l01122"></a>01122 }
<a name="l01123"></a>01123 
<a name="l01124"></a>01124 <span class="keyword">static</span> <span class="keyword">inline</span> <span class="keywordtype">bool</span> textMode( Kleo::CryptoMessageFormat f ) {
<a name="l01125"></a>01125   <span class="keywordflow">return</span> f == Kleo::InlineOpenPGPFormat;
<a name="l01126"></a>01126 }
<a name="l01127"></a>01127 
<a name="l01128"></a>01128 <span class="keyword">static</span> <span class="keyword">inline</span> GpgME::Context::SignatureMode signingMode( Kleo::CryptoMessageFormat f ) {
<a name="l01129"></a>01129   <span class="keywordflow">switch</span> ( f ) {
<a name="l01130"></a>01130   <span class="keywordflow">case</span> Kleo::SMIMEOpaqueFormat:
<a name="l01131"></a>01131     <span class="keywordflow">return</span> GpgME::Context::Normal;
<a name="l01132"></a>01132   <span class="keywordflow">case</span> Kleo::InlineOpenPGPFormat:
<a name="l01133"></a>01133     <span class="keywordflow">return</span> GpgME::Context::Clearsigned;
<a name="l01134"></a>01134   <span class="keywordflow">default</span>:
<a name="l01135"></a>01135   <span class="keywordflow">case</span> Kleo::SMIMEFormat:
<a name="l01136"></a>01136   <span class="keywordflow">case</span> Kleo::OpenPGPMIMEFormat:
<a name="l01137"></a>01137     <span class="keywordflow">return</span> GpgME::Context::Detached;
<a name="l01138"></a>01138   }
<a name="l01139"></a>01139 }
<a name="l01140"></a>01140 
<a name="l01141"></a>01141 <span class="comment">//</span>
<a name="l01142"></a>01142 <span class="comment">// END replacements for StructuringInfo(Wrapper)</span>
<a name="l01143"></a>01143 <span class="comment">//</span>
<a name="l01144"></a>01144 
<a name="l01145"></a>01145 <span class="keyword">class </span>EncryptMessageJob : <span class="keyword">public</span> MessageComposerJob {
<a name="l01146"></a>01146 <span class="keyword">public</span>:
<a name="l01147"></a>01147   EncryptMessageJob( <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>* msg, <span class="keyword">const</span> Kleo::KeyResolver::SplitInfo &amp; si,
<a name="l01148"></a>01148                      <span class="keywordtype">bool</span> doSign, <span class="keywordtype">bool</span> doEncrypt, <span class="keyword">const</span> QByteArray&amp; encodedBody,
<a name="l01149"></a>01149                      <span class="keywordtype">int</span> boundaryLevel, <span class="comment">/*const KMMessagePart&amp; oldBodyPart,*/</span>
<a name="l01150"></a>01150                      KMMessagePart* newBodyPart, Kleo::CryptoMessageFormat format,
<a name="l01151"></a>01151              MessageComposer* composer )
<a name="l01152"></a>01152     : MessageComposerJob( composer ), mMsg( msg ), mSplitInfo( si ),
<a name="l01153"></a>01153       mDoSign( doSign ), mDoEncrypt( doEncrypt ), mEncodedBody( encodedBody ),
<a name="l01154"></a>01154       mBoundaryLevel( boundaryLevel ), <span class="comment">/*mOldBodyPart( oldBodyPart ),*/</span>
<a name="l01155"></a>01155       mNewBodyPart( newBodyPart ), mFormat( format ) {}
<a name="l01156"></a>01156 
<a name="l01157"></a>01157   <span class="keywordtype">void</span> execute() {
<a name="l01158"></a>01158     KMMessagePart tmpNewBodyPart;
<a name="l01159"></a>01159     tmpNewBodyPart.duplicate( *mNewBodyPart ); <span class="comment">// slow - we duplicate everything again</span>
<a name="l01160"></a>01160 
<a name="l01161"></a>01161     <span class="comment">// TODO: Async call</span>
<a name="l01162"></a>01162 
<a name="l01163"></a>01163     mComposer-&gt;encryptMessage( mMsg, mSplitInfo, mDoSign, mDoEncrypt,
<a name="l01164"></a>01164                                tmpNewBodyPart, mFormat );
<a name="l01165"></a>01165     <span class="keywordflow">if</span> ( !mComposer-&gt;mRc ) {
<a name="l01166"></a>01166       <span class="keyword">delete</span> mMsg; mMsg = 0;
<a name="l01167"></a>01167       <span class="keywordflow">return</span>;
<a name="l01168"></a>01168     }
<a name="l01169"></a>01169     mComposer-&gt;mMessageList.push_back( mMsg );
<a name="l01170"></a>01170   }
<a name="l01171"></a>01171 
<a name="l01172"></a>01172 <span class="keyword">private</span>:
<a name="l01173"></a>01173   <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>* mMsg;
<a name="l01174"></a>01174   Kleo::KeyResolver::SplitInfo mSplitInfo;
<a name="l01175"></a>01175   <span class="keywordtype">bool</span> mDoSign, mDoEncrypt;
<a name="l01176"></a>01176   QByteArray mEncodedBody;
<a name="l01177"></a>01177   <span class="keywordtype">int</span> mBoundaryLevel;
<a name="l01178"></a>01178   <span class="comment">//KMMessagePart mOldBodyPart;</span>
<a name="l01179"></a>01179   KMMessagePart* mNewBodyPart;
<a name="l01180"></a>01180   Kleo::CryptoMessageFormat mFormat;
<a name="l01181"></a>01181 };
<a name="l01182"></a>01182 
<a name="l01183"></a>01183 <span class="keyword">class </span>SetLastMessageAsUnencryptedVersionOfLastButOne : <span class="keyword">public</span> MessageComposerJob {
<a name="l01184"></a>01184 <span class="keyword">public</span>:
<a name="l01185"></a>01185   SetLastMessageAsUnencryptedVersionOfLastButOne( MessageComposer * composer )
<a name="l01186"></a>01186     : MessageComposerJob( composer ) {}
<a name="l01187"></a>01187 
<a name="l01188"></a>01188   <span class="keywordtype">void</span> execute() {
<a name="l01189"></a>01189     <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a> * last = mComposer-&gt;mMessageList.back();
<a name="l01190"></a>01190     mComposer-&gt;mMessageList.pop_back();
<a name="l01191"></a>01191     mComposer-&gt;mMessageList.back()-&gt;setUnencryptedMsg( last );
<a name="l01192"></a>01192   }
<a name="l01193"></a>01193 };
<a name="l01194"></a>01194 
<a name="l01195"></a>01195 <span class="keywordtype">void</span> MessageComposer::composeInlineOpenPGPMessage( <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>&amp; theMessage,
<a name="l01196"></a>01196                                                    <span class="keywordtype">bool</span> doSign, <span class="keywordtype">bool</span> doEncrypt )
<a name="l01197"></a>01197 {
<a name="l01198"></a>01198   <span class="comment">// preprocess the body text</span>
<a name="l01199"></a>01199   <span class="keyword">const</span> QByteArray bodyData = mText;
<a name="l01200"></a>01200   <span class="keywordflow">if</span> (bodyData.isNull()) {
<a name="l01201"></a>01201     mRc = <span class="keyword">false</span>;
<a name="l01202"></a>01202     <span class="keywordflow">return</span>;
<a name="l01203"></a>01203   }
<a name="l01204"></a>01204 
<a name="l01205"></a>01205   mNewBodyPart = 0; <span class="comment">// unused</span>
<a name="l01206"></a>01206   mEarlyAddAttachments = <span class="keyword">false</span>;
<a name="l01207"></a>01207   mAllAttachmentsAreInBody = <span class="keyword">false</span>;
<a name="l01208"></a>01208 
<a name="l01209"></a>01209   <span class="comment">// set the main headers</span>
<a name="l01210"></a>01210   theMessage.<a class="code" href="classKMMessage.html#fc64c26a395d55c6ca96c00051f72c63" title="Delete all body parts.">deleteBodyParts</a>();
<a name="l01211"></a>01211   QString oldContentType = theMessage.<a class="code" href="classKMMessage.html#082d31ece170fb19cd5402a34a3f6727" title="Returns the value of a header field with the given name.">headerField</a>( <span class="stringliteral">"Content-Type"</span> );
<a name="l01212"></a>01212   theMessage.<a class="code" href="classKMMessage.html#d01b9784ec819c2aa44e916098e76f78" title="Remove header field with given name.">removeHeaderField</a>(<span class="stringliteral">"Content-Type"</span>);
<a name="l01213"></a>01213   theMessage.<a class="code" href="classKMMessage.html#d01b9784ec819c2aa44e916098e76f78" title="Remove header field with given name.">removeHeaderField</a>(<span class="stringliteral">"Content-Transfer-Encoding"</span>);
<a name="l01214"></a>01214 
<a name="l01215"></a>01215   <span class="keyword">const</span> std::vector&lt;Kleo::KeyResolver::SplitInfo&gt; splitInfos
<a name="l01216"></a>01216     = mKeyResolver-&gt;encryptionItems( Kleo::InlineOpenPGPFormat );
<a name="l01217"></a>01217   kdWarning( splitInfos.empty() )
<a name="l01218"></a>01218     &lt;&lt; <span class="stringliteral">"MessageComposer::continueComposeMessage(): splitInfos.empty() for InlineOpenPGPFormat"</span>
<a name="l01219"></a>01219     &lt;&lt; endl;
<a name="l01220"></a>01220   std::vector&lt;Kleo::KeyResolver::SplitInfo&gt;::const_iterator it;
<a name="l01221"></a>01221   <span class="keywordflow">for</span> ( it = splitInfos.begin() ; it != splitInfos.end() ; ++it ) {
<a name="l01222"></a>01222     <span class="keyword">const</span> Kleo::KeyResolver::SplitInfo&amp; splitInfo = *it;
<a name="l01223"></a>01223     <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>* msg = <span class="keyword">new</span> <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>( theMessage );
<a name="l01224"></a>01224     <span class="keywordflow">if</span> ( doEncrypt ) {
<a name="l01225"></a>01225       Kpgp::Result result;
<a name="l01226"></a>01226       QByteArray encryptedBody;
<a name="l01227"></a>01227       <span class="keywordflow">if</span> ( doSign ) {  <span class="comment">// Sign and encrypt</span>
<a name="l01228"></a>01228         <span class="keyword">const</span> std::vector&lt;GpgME::Key&gt; signingKeys = mKeyResolver-&gt;signingKeys( Kleo::InlineOpenPGPFormat );
<a name="l01229"></a>01229         result = pgpSignedAndEncryptedMsg( encryptedBody, bodyData, signingKeys,
<a name="l01230"></a>01230                                            splitInfo.keys, Kleo::InlineOpenPGPFormat );
<a name="l01231"></a>01231       } <span class="keywordflow">else</span> { <span class="comment">// Encrypt but don't sign</span>
<a name="l01232"></a>01232         result = pgpEncryptedMsg( encryptedBody, bodyData,
<a name="l01233"></a>01233                                   splitInfo.keys, Kleo::InlineOpenPGPFormat );
<a name="l01234"></a>01234       }
<a name="l01235"></a>01235       <span class="keywordflow">if</span> ( result != Kpgp::Ok ) {
<a name="l01236"></a>01236         mRc = <span class="keyword">false</span>;
<a name="l01237"></a>01237         <span class="keywordflow">return</span>;
<a name="l01238"></a>01238       }
<a name="l01239"></a>01239       assert( !encryptedBody.isNull() ); <span class="comment">// if you hit this, check gpg-agent is running, then blame gpgme.</span>
<a name="l01240"></a>01240       mOldBodyPart.setBodyEncodedBinary( encryptedBody );
<a name="l01241"></a>01241     } <span class="keywordflow">else</span> {
<a name="l01242"></a>01242       <span class="keywordflow">if</span> ( doSign ) { <span class="comment">// Sign but don't encrypt</span>
<a name="l01243"></a>01243         pgpSignedMsg( bodyData, Kleo::InlineOpenPGPFormat );
<a name="l01244"></a>01244         <span class="keywordflow">if</span> ( mSignature.isNull() ) {
<a name="l01245"></a>01245           mRc = <span class="keyword">false</span>;
<a name="l01246"></a>01246           <span class="keywordflow">return</span>;
<a name="l01247"></a>01247         }
<a name="l01248"></a>01248         mOldBodyPart.setBodyEncodedBinary( mSignature );
<a name="l01249"></a>01249       } <span class="keywordflow">else</span> { <span class="comment">// don't sign nor encrypt -&gt; nothing to do</span>
<a name="l01250"></a>01250         assert( !bodyData.isNull() );
<a name="l01251"></a>01251         mOldBodyPart.setBodyEncodedBinary( bodyData );
<a name="l01252"></a>01252       }
<a name="l01253"></a>01253     }
<a name="l01254"></a>01254     mOldBodyPart.setContentDisposition( <span class="stringliteral">"inline"</span> );
<a name="l01255"></a>01255     mOldBodyPart.setOriginalContentTypeStr( oldContentType.utf8() );
<a name="l01256"></a>01256     mOldBodyPart.setCharset(mCharset);
<a name="l01257"></a>01257     addBodyAndAttachments( msg, splitInfo, <span class="keyword">false</span>, <span class="keyword">false</span>, mOldBodyPart, Kleo::InlineOpenPGPFormat );
<a name="l01258"></a>01258     mMessageList.push_back( msg );
<a name="l01259"></a>01259     <span class="keywordflow">if</span> ( it == splitInfos.begin() ) {
<a name="l01260"></a>01260       <span class="keywordflow">if</span> ( doEncrypt &amp;&amp; !saveMessagesEncrypted() ) {
<a name="l01261"></a>01261         mOldBodyPart.setBodyEncodedBinary( bodyData );
<a name="l01262"></a>01262         <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>* msgUnenc = <span class="keyword">new</span> <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>( theMessage );
<a name="l01263"></a>01263         addBodyAndAttachments( msgUnenc, splitInfo, <span class="keyword">false</span>, <span class="keyword">false</span>, mOldBodyPart, Kleo::InlineOpenPGPFormat );
<a name="l01264"></a>01264         msg-&gt;<a class="code" href="classKMMessage.html#50d3a0b18e68f1b4e8d4634debf862e9" title="Specifies an unencrypted copy of this message to be stored in a separate member variable...">setUnencryptedMsg</a>( msgUnenc );
<a name="l01265"></a>01265       }
<a name="l01266"></a>01266     }
<a name="l01267"></a>01267   } <span class="comment">// end for</span>
<a name="l01268"></a>01268 }
<a name="l01269"></a>01269 
<a name="l01270"></a>01270 <span class="comment">// very much inspired by composeInlineOpenPGPMessage</span>
<a name="l01271"></a>01271 <span class="keywordtype">void</span> MessageComposer::composeChiasmusMessage( <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>&amp; theMessage, Kleo::CryptoMessageFormat format )
<a name="l01272"></a>01272 {
<a name="l01273"></a>01273   assert( !GlobalSettings::chiasmusKey().isEmpty() ); <span class="comment">// kmcomposewin code should have made sure</span>
<a name="l01274"></a>01274   <span class="keyword">const</span> Kleo::CryptoBackendFactory * cpf = Kleo::CryptoBackendFactory::instance();
<a name="l01275"></a>01275   assert( cpf );
<a name="l01276"></a>01276   <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * chiasmus
<a name="l01277"></a>01277     = cpf-&gt;protocol( <span class="stringliteral">"Chiasmus"</span> );
<a name="l01278"></a>01278   assert( chiasmus ); <span class="comment">// kmcomposewin code should have made sure</span>
<a name="l01279"></a>01279 
<a name="l01280"></a>01280   <span class="comment">// preprocess the body text</span>
<a name="l01281"></a>01281   <span class="keyword">const</span> QByteArray bodyData = mText;
<a name="l01282"></a>01282   <span class="keywordflow">if</span> (bodyData.isNull()) {
<a name="l01283"></a>01283     mRc = <span class="keyword">false</span>;
<a name="l01284"></a>01284     <span class="keywordflow">return</span>;
<a name="l01285"></a>01285   }
<a name="l01286"></a>01286 
<a name="l01287"></a>01287   mNewBodyPart = 0; <span class="comment">// unused</span>
<a name="l01288"></a>01288   mEarlyAddAttachments = <span class="keyword">false</span>;
<a name="l01289"></a>01289   mAllAttachmentsAreInBody = <span class="keyword">false</span>;
<a name="l01290"></a>01290 
<a name="l01291"></a>01291   <span class="comment">// set the main headers</span>
<a name="l01292"></a>01292   theMessage.<a class="code" href="classKMMessage.html#fc64c26a395d55c6ca96c00051f72c63" title="Delete all body parts.">deleteBodyParts</a>();
<a name="l01293"></a>01293   QString oldContentType = theMessage.<a class="code" href="classKMMessage.html#082d31ece170fb19cd5402a34a3f6727" title="Returns the value of a header field with the given name.">headerField</a>( <span class="stringliteral">"Content-Type"</span> );
<a name="l01294"></a>01294   theMessage.<a class="code" href="classKMMessage.html#d01b9784ec819c2aa44e916098e76f78" title="Remove header field with given name.">removeHeaderField</a>(<span class="stringliteral">"Content-Type"</span>);
<a name="l01295"></a>01295   theMessage.<a class="code" href="classKMMessage.html#d01b9784ec819c2aa44e916098e76f78" title="Remove header field with given name.">removeHeaderField</a>(<span class="stringliteral">"Content-Transfer-Encoding"</span>);
<a name="l01296"></a>01296 
<a name="l01297"></a>01297   <span class="comment">// This reads strange, but we know that AdjustCryptFlagsJob created a single splitinfo,</span>
<a name="l01298"></a>01298   <span class="comment">// under the given "format" (usually openpgp/mime; doesn't matter)</span>
<a name="l01299"></a>01299   <span class="keyword">const</span> std::vector&lt;Kleo::KeyResolver::SplitInfo&gt; splitInfos
<a name="l01300"></a>01300     = mKeyResolver-&gt;encryptionItems( format );
<a name="l01301"></a>01301   assert( splitInfos.size() == 1 );
<a name="l01302"></a>01302   <span class="keywordflow">for</span> ( std::vector&lt;Kleo::KeyResolver::SplitInfo&gt;::const_iterator it = splitInfos.begin() ; it != splitInfos.end() ; ++it )
<a name="l01303"></a>01303   {
<a name="l01304"></a>01304     <span class="keyword">const</span> Kleo::KeyResolver::SplitInfo&amp; splitInfo = *it;
<a name="l01305"></a>01305     <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>* msg = <span class="keyword">new</span> <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>( theMessage );
<a name="l01306"></a>01306     QByteArray encryptedBody;
<a name="l01307"></a>01307 
<a name="l01308"></a>01308     <span class="keywordflow">if</span> ( !encryptWithChiasmus( chiasmus, bodyData, encryptedBody ) ) {
<a name="l01309"></a>01309       mRc = <span class="keyword">false</span>;
<a name="l01310"></a>01310       <span class="keywordflow">return</span>;
<a name="l01311"></a>01311     }
<a name="l01312"></a>01312     assert( !encryptedBody.isNull() );
<a name="l01313"></a>01313     <span class="comment">// This leaves CTE==7-bit, no good</span>
<a name="l01314"></a>01314     <span class="comment">//mOldBodyPart.setBodyEncodedBinary( encryptedBody );</span>
<a name="l01315"></a>01315 
<a name="l01316"></a>01316     <span class="keywordtype">bool</span> doSign = <span class="keyword">false</span>;
<a name="l01317"></a>01317     QValueList&lt;int&gt; allowedCTEs;
<a name="l01318"></a>01318     mOldBodyPart.setBodyAndGuessCte( encryptedBody, allowedCTEs,
<a name="l01319"></a>01319                                      !kmkernel-&gt;msgSender()-&gt;sendQuotedPrintable() &amp;&amp; !doSign,
<a name="l01320"></a>01320                      doSign );
<a name="l01321"></a>01321 
<a name="l01322"></a>01322 
<a name="l01323"></a>01323     mOldBodyPart.setContentDisposition( <span class="stringliteral">"inline"</span> );
<a name="l01324"></a>01324     <span class="comment">// Used in case of no attachments</span>
<a name="l01325"></a>01325     mOldBodyPart.setOriginalContentTypeStr( <span class="stringliteral">"application/vnd.de.bund.bsi.chiasmus-text;chiasmus-charset="</span> + mCharset );
<a name="l01326"></a>01326     <span class="comment">// Used in case of attachments</span>
<a name="l01327"></a>01327     mOldBodyPart.setTypeStr( <span class="stringliteral">"application"</span> );
<a name="l01328"></a>01328     mOldBodyPart.setSubtypeStr( <span class="stringliteral">"vnd.de.bund.bsi.chiasmus-text"</span> );
<a name="l01329"></a>01329     mOldBodyPart.setAdditionalCTypeParamStr( QCString( <span class="stringliteral">"chiasmus-charset="</span> + mCharset ) );
<a name="l01330"></a>01330     addBodyAndAttachments( msg, splitInfo, <span class="keyword">false</span>, <span class="keyword">false</span>, mOldBodyPart, Kleo::InlineOpenPGPFormat );
<a name="l01331"></a>01331     mMessageList.push_back( msg );
<a name="l01332"></a>01332 
<a name="l01333"></a>01333     <span class="keywordflow">if</span> ( it == splitInfos.begin() &amp;&amp; !saveMessagesEncrypted() ) {
<a name="l01334"></a>01334       mOldBodyPart.setBodyEncodedBinary( bodyData );
<a name="l01335"></a>01335       <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>* msgUnenc = <span class="keyword">new</span> <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>( theMessage );
<a name="l01336"></a>01336       addBodyAndAttachments( msgUnenc, splitInfo, <span class="keyword">false</span>, <span class="keyword">false</span>, mOldBodyPart, Kleo::InlineOpenPGPFormat );
<a name="l01337"></a>01337       msg-&gt;<a class="code" href="classKMMessage.html#50d3a0b18e68f1b4e8d4634debf862e9" title="Specifies an unencrypted copy of this message to be stored in a separate member variable...">setUnencryptedMsg</a>( msgUnenc );
<a name="l01338"></a>01338     }
<a name="l01339"></a>01339   }
<a name="l01340"></a>01340 }
<a name="l01341"></a>01341 
<a name="l01342"></a>01342 <span class="keywordtype">void</span> MessageComposer::composeMessage( <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>&amp; theMessage,
<a name="l01343"></a>01343                                       <span class="keywordtype">bool</span> doSign, <span class="keywordtype">bool</span> doEncrypt,
<a name="l01344"></a>01344                                       Kleo::CryptoMessageFormat format )
<a name="l01345"></a>01345 {
<a name="l01346"></a>01346 <span class="preprocessor">#ifdef DEBUG</span>
<a name="l01347"></a>01347 <span class="preprocessor"></span>  kdDebug(5006) &lt;&lt; <span class="stringliteral">"entering KMComposeWin::composeMessage"</span> &lt;&lt; endl;
<a name="l01348"></a>01348 <span class="preprocessor">#endif</span>
<a name="l01349"></a>01349 <span class="preprocessor"></span>  <span class="keywordflow">if</span> ( format == Kleo::InlineOpenPGPFormat ) {
<a name="l01350"></a>01350     composeInlineOpenPGPMessage( theMessage, doSign, doEncrypt );
<a name="l01351"></a>01351     <span class="keywordflow">return</span>;
<a name="l01352"></a>01352   }
<a name="l01353"></a>01353 
<a name="l01354"></a>01354   <span class="keywordflow">if</span> ( mEncryptWithChiasmus )
<a name="l01355"></a>01355   {
<a name="l01356"></a>01356     composeChiasmusMessage( theMessage, format );
<a name="l01357"></a>01357     <span class="keywordflow">return</span>;
<a name="l01358"></a>01358   }
<a name="l01359"></a>01359 
<a name="l01360"></a>01360   <span class="comment">// create informative header for those that have no mime-capable</span>
<a name="l01361"></a>01361   <span class="comment">// email client</span>
<a name="l01362"></a>01362   theMessage.<a class="code" href="classKMMessage.html#1b9c4db08086c94986f00d0c708a01e7" title="Set the message body.">setBody</a>( <span class="stringliteral">"This message is in MIME format."</span> );
<a name="l01363"></a>01363 
<a name="l01364"></a>01364   <span class="comment">// preprocess the body text</span>
<a name="l01365"></a>01365   QByteArray bodyData = mText;
<a name="l01366"></a>01366   <span class="keywordflow">if</span> (bodyData.isNull()) {
<a name="l01367"></a>01367     mRc = <span class="keyword">false</span>;
<a name="l01368"></a>01368     <span class="keywordflow">return</span>;
<a name="l01369"></a>01369   }
<a name="l01370"></a>01370 
<a name="l01371"></a>01371   <span class="comment">// set the main headers</span>
<a name="l01372"></a>01372   QString oldContentType = theMessage.<a class="code" href="classKMMessage.html#082d31ece170fb19cd5402a34a3f6727" title="Returns the value of a header field with the given name.">headerField</a>( <span class="stringliteral">"Content-Type"</span> );
<a name="l01373"></a>01373   theMessage.<a class="code" href="classKMMessage.html#fc64c26a395d55c6ca96c00051f72c63" title="Delete all body parts.">deleteBodyParts</a>();
<a name="l01374"></a>01374   theMessage.<a class="code" href="classKMMessage.html#d01b9784ec819c2aa44e916098e76f78" title="Remove header field with given name.">removeHeaderField</a>(<span class="stringliteral">"Content-Type"</span>);
<a name="l01375"></a>01375   theMessage.<a class="code" href="classKMMessage.html#d01b9784ec819c2aa44e916098e76f78" title="Remove header field with given name.">removeHeaderField</a>(<span class="stringliteral">"Content-Transfer-Encoding"</span>);
<a name="l01376"></a>01376   theMessage.<a class="code" href="classKMMessage.html#3d877210924a2a0ba380e0ef11ff4e10" title="Set fields that are either automatically set (Message-id) or that do not change from...">setAutomaticFields</a>(<span class="keyword">true</span>); <span class="comment">// == multipart/mixed</span>
<a name="l01377"></a>01377 
<a name="l01378"></a>01378   <span class="comment">// this is our *final* body part</span>
<a name="l01379"></a>01379   mNewBodyPart = <span class="keyword">new</span> KMMessagePart;
<a name="l01380"></a>01380 
<a name="l01381"></a>01381   <span class="comment">// this is the boundary depth of the surrounding MIME part</span>
<a name="l01382"></a>01382   mPreviousBoundaryLevel = 0;
<a name="l01383"></a>01383 
<a name="l01384"></a>01384   <span class="comment">// whether the body must be signed/encrypted</span>
<a name="l01385"></a>01385   <span class="keyword">const</span> <span class="keywordtype">bool</span> doEncryptBody = doEncrypt &amp;&amp; mEncryptBody;
<a name="l01386"></a>01386   <span class="keyword">const</span> <span class="keywordtype">bool</span> doSignBody = doSign &amp;&amp; mSignBody;
<a name="l01387"></a>01387 
<a name="l01388"></a>01388   <span class="comment">// create temporary bodyPart for editor text</span>
<a name="l01389"></a>01389   <span class="comment">// (and for all attachments, if mail is to be signed and/or encrypted)</span>
<a name="l01390"></a>01390   mEarlyAddAttachments = !mAttachments.empty() &amp;&amp; ( doSignBody || doEncryptBody );
<a name="l01391"></a>01391 
<a name="l01392"></a>01392   mAllAttachmentsAreInBody = mEarlyAddAttachments;
<a name="l01393"></a>01393 
<a name="l01394"></a>01394   <span class="comment">// test whether there ARE attachments that can be included into the body</span>
<a name="l01395"></a>01395   <span class="keywordflow">if</span>( mEarlyAddAttachments ) {
<a name="l01396"></a>01396     <span class="keywordtype">bool</span> someOk = <span class="keyword">false</span>;
<a name="l01397"></a>01397     <span class="keywordflow">for</span> ( QValueVector&lt;Attachment&gt;::const_iterator it = mAttachments.begin() ; it != mAttachments.end() ; ++it ) {
<a name="l01398"></a>01398       <span class="keywordflow">if</span> ( it-&gt;encrypt == doEncryptBody &amp;&amp; it-&gt;sign == doSignBody )
<a name="l01399"></a>01399         someOk = <span class="keyword">true</span>;
<a name="l01400"></a>01400       <span class="keywordflow">else</span>
<a name="l01401"></a>01401         mAllAttachmentsAreInBody = <span class="keyword">false</span>;
<a name="l01402"></a>01402     }
<a name="l01403"></a>01403     <span class="keywordflow">if</span>( !mAllAttachmentsAreInBody &amp;&amp; !someOk )
<a name="l01404"></a>01404       mEarlyAddAttachments = <span class="keyword">false</span>;
<a name="l01405"></a>01405   }
<a name="l01406"></a>01406 
<a name="l01407"></a>01407   kdDebug(5006) &lt;&lt; <span class="stringliteral">"mEarlyAddAttachments="</span> &lt;&lt; mEarlyAddAttachments &lt;&lt; <span class="stringliteral">" mAllAttachmentsAreInBody="</span> &lt;&lt; mAllAttachmentsAreInBody &lt;&lt; endl;
<a name="l01408"></a>01408 
<a name="l01409"></a>01409   <span class="comment">// if an html message is to be generated, make a text/plain and text/html part</span>
<a name="l01410"></a>01410   mMultipartMixedBoundary = <span class="stringliteral">""</span>;
<a name="l01411"></a>01411   <span class="keywordflow">if</span> ( mEarlyAddAttachments ) {
<a name="l01412"></a>01412     mOldBodyPart.setTypeStr( <span class="stringliteral">"multipart"</span> );
<a name="l01413"></a>01413     mOldBodyPart.setSubtypeStr( <span class="stringliteral">"mixed"</span> );
<a name="l01414"></a>01414     <span class="comment">// calculate a boundary string</span>
<a name="l01415"></a>01415     DwMediaType tmpCT;
<a name="l01416"></a>01416     tmpCT.CreateBoundary( ++mPreviousBoundaryLevel );
<a name="l01417"></a>01417     mMultipartMixedBoundary = tmpCT.Boundary().c_str();
<a name="l01418"></a>01418   }
<a name="l01419"></a>01419   <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( mIsRichText ) {
<a name="l01420"></a>01420     mOldBodyPart.setTypeStr( <span class="stringliteral">"multipart"</span> );
<a name="l01421"></a>01421     mOldBodyPart.setSubtypeStr( <span class="stringliteral">"alternative"</span> );
<a name="l01422"></a>01422   }
<a name="l01423"></a>01423   <span class="keywordflow">else</span>
<a name="l01424"></a>01424     mOldBodyPart.setOriginalContentTypeStr( oldContentType.utf8() );
<a name="l01425"></a>01425 
<a name="l01426"></a>01426   mOldBodyPart.setContentDisposition( <span class="stringliteral">"inline"</span> );
<a name="l01427"></a>01427 
<a name="l01428"></a>01428   <span class="keywordflow">if</span> ( mIsRichText ) { <span class="comment">// create a multipart body</span>
<a name="l01429"></a>01429     <span class="comment">// calculate a boundary string</span>
<a name="l01430"></a>01430     QCString boundaryCStr;  <span class="comment">// storing boundary string data</span>
<a name="l01431"></a>01431     QCString newbody;
<a name="l01432"></a>01432     DwMediaType tmpCT;
<a name="l01433"></a>01433     tmpCT.CreateBoundary( ++mPreviousBoundaryLevel );
<a name="l01434"></a>01434     boundaryCStr = <a class="code" href="namespaceKMail_1_1Util.html#7dbcbfd02aa6cf732ac83c2b6d5b6f8b" title="Construct a QCString from a DwString.">KMail::Util::CString</a>( tmpCT.Boundary() );
<a name="l01435"></a>01435     QValueList&lt;int&gt; allowedCTEs;
<a name="l01436"></a>01436 
<a name="l01437"></a>01437     KMMessagePart textBodyPart;
<a name="l01438"></a>01438     textBodyPart.setTypeStr(<span class="stringliteral">"text"</span>);
<a name="l01439"></a>01439     textBodyPart.setSubtypeStr(<span class="stringliteral">"plain"</span>);
<a name="l01440"></a>01440 
<a name="l01441"></a>01441     QCString textbody = plainTextFromMarkup( mText <span class="comment">/* converted to QString */</span> );
<a name="l01442"></a>01442 
<a name="l01443"></a>01443     <span class="comment">// the signed body must not be 8bit encoded</span>
<a name="l01444"></a>01444     textBodyPart.setBodyAndGuessCte( textbody, allowedCTEs,
<a name="l01445"></a>01445                                      !kmkernel-&gt;msgSender()-&gt;sendQuotedPrintable() &amp;&amp; !doSign,
<a name="l01446"></a>01446                      doSign );
<a name="l01447"></a>01447     textBodyPart.setCharset( mCharset );
<a name="l01448"></a>01448     textBodyPart.setBodyEncoded( textbody );
<a name="l01449"></a>01449     DwBodyPart* textDwPart = theMessage.<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( &amp;textBodyPart );
<a name="l01450"></a>01450     textDwPart-&gt;Assemble();
<a name="l01451"></a>01451     newbody += <span class="stringliteral">"--"</span>;
<a name="l01452"></a>01452     newbody +=     boundaryCStr;
<a name="l01453"></a>01453     newbody +=                 <span class="stringliteral">"\n"</span>;
<a name="l01454"></a>01454     newbody += textDwPart-&gt;AsString().c_str();
<a name="l01455"></a>01455     <span class="keyword">delete</span> textDwPart;
<a name="l01456"></a>01456     textDwPart = 0;
<a name="l01457"></a>01457 
<a name="l01458"></a>01458     KMMessagePart htmlBodyPart;
<a name="l01459"></a>01459     htmlBodyPart.setTypeStr(<span class="stringliteral">"text"</span>);
<a name="l01460"></a>01460     htmlBodyPart.setSubtypeStr(<span class="stringliteral">"html"</span>);
<a name="l01461"></a>01461     QByteArray htmlbody = mText;
<a name="l01462"></a>01462     <span class="comment">// the signed body must not be 8bit encoded</span>
<a name="l01463"></a>01463     htmlBodyPart.setBodyAndGuessCte( htmlbody, allowedCTEs,
<a name="l01464"></a>01464                                      !kmkernel-&gt;msgSender()-&gt;sendQuotedPrintable() &amp;&amp; !doSign,
<a name="l01465"></a>01465                      doSign );
<a name="l01466"></a>01466     htmlBodyPart.setCharset( mCharset );
<a name="l01467"></a>01467     htmlBodyPart.setBodyEncodedBinary( htmlbody );
<a name="l01468"></a>01468     DwBodyPart* htmlDwPart = theMessage.<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( &amp;htmlBodyPart );
<a name="l01469"></a>01469     htmlDwPart-&gt;Assemble();
<a name="l01470"></a>01470     newbody += <span class="stringliteral">"\n--"</span>;
<a name="l01471"></a>01471     newbody +=     boundaryCStr;
<a name="l01472"></a>01472     newbody +=                 <span class="stringliteral">"\n"</span>;
<a name="l01473"></a>01473     newbody += htmlDwPart-&gt;AsString().c_str();
<a name="l01474"></a>01474     <span class="keyword">delete</span> htmlDwPart;
<a name="l01475"></a>01475     htmlDwPart = 0;
<a name="l01476"></a>01476 
<a name="l01477"></a>01477     newbody += <span class="stringliteral">"--"</span>;
<a name="l01478"></a>01478     newbody +=     boundaryCStr;
<a name="l01479"></a>01479     newbody +=                 <span class="stringliteral">"--\n"</span>;
<a name="l01480"></a>01480     bodyData = <a class="code" href="namespaceKMail_1_1Util.html#33f363b5d85de8e69053310d3015744c" title="Creates a QByteArray from a QCString without detaching (duplicating the data).">KMail::Util::byteArrayFromQCStringNoDetach</a>( newbody );
<a name="l01481"></a>01481     mOldBodyPart.setBodyEncodedBinary( bodyData );
<a name="l01482"></a>01482 
<a name="l01483"></a>01483     mSaveBoundary = tmpCT.Boundary();
<a name="l01484"></a>01484   }
<a name="l01485"></a>01485 
<a name="l01486"></a>01486   <span class="comment">// Prepare attachments that will be signed/encrypted</span>
<a name="l01487"></a>01487   <span class="keywordflow">for</span> ( QValueVector&lt;Attachment&gt;::const_iterator it = mAttachments.begin() ; it != mAttachments.end() ; ++it ) {
<a name="l01488"></a>01488     <span class="comment">// signed/encrypted body parts must be either QP or base64 encoded</span>
<a name="l01489"></a>01489     <span class="comment">// Why not 7 bit? Because the LF-&gt;CRLF canonicalization would render</span>
<a name="l01490"></a>01490     <span class="comment">// e.g. 7 bit encoded shell scripts unusable because of the CRs.</span>
<a name="l01491"></a>01491     <span class="comment">//</span>
<a name="l01492"></a>01492     <span class="comment">// (marc) this is a workaround for the KMail bug that doesn't</span>
<a name="l01493"></a>01493     <span class="comment">// respect the CRLF-&gt;LF de-canonicalisation. We should</span>
<a name="l01494"></a>01494     <span class="comment">// eventually get rid of this:</span>
<a name="l01495"></a>01495     <span class="keywordflow">if</span>( it-&gt;sign || it-&gt;encrypt ) {
<a name="l01496"></a>01496       QCString cte = it-&gt;part-&gt;cteStr().lower();
<a name="l01497"></a>01497       <span class="keywordflow">if</span>( ( <span class="stringliteral">"8bit"</span> == cte &amp;&amp; it-&gt;part-&gt;type() != DwMime::kTypeMessage )
<a name="l01498"></a>01498           || ( ( it-&gt;part-&gt;type() == DwMime::kTypeText )
<a name="l01499"></a>01499                &amp;&amp; ( <span class="stringliteral">"7bit"</span> == cte ) ) ) {
<a name="l01500"></a>01500         <span class="keyword">const</span> QByteArray body = it-&gt;part-&gt;bodyDecodedBinary();
<a name="l01501"></a>01501         QValueList&lt;int&gt; dummy;
<a name="l01502"></a>01502         it-&gt;part-&gt;setBodyAndGuessCte(body, dummy, <span class="keyword">false</span>, it-&gt;sign);
<a name="l01503"></a>01503         kdDebug(5006) &lt;&lt; <span class="stringliteral">"Changed encoding of message part from "</span>
<a name="l01504"></a>01504                       &lt;&lt; cte &lt;&lt; <span class="stringliteral">" to "</span> &lt;&lt; it-&gt;part-&gt;cteStr() &lt;&lt; endl;
<a name="l01505"></a>01505       }
<a name="l01506"></a>01506     }
<a name="l01507"></a>01507   }
<a name="l01508"></a>01508 
<a name="l01509"></a>01509   <span class="keywordflow">if</span>( mEarlyAddAttachments ) {
<a name="l01510"></a>01510     <span class="comment">// add the normal body text</span>
<a name="l01511"></a>01511     KMMessagePart innerBodyPart;
<a name="l01512"></a>01512     <span class="keywordflow">if</span> ( mIsRichText ) {
<a name="l01513"></a>01513       innerBodyPart.setTypeStr(   <span class="stringliteral">"multipart"</span>);<span class="comment">//text" );</span>
<a name="l01514"></a>01514       innerBodyPart.setSubtypeStr(<span class="stringliteral">"alternative"</span>);<span class="comment">//html");</span>
<a name="l01515"></a>01515     }
<a name="l01516"></a>01516     <span class="keywordflow">else</span> {
<a name="l01517"></a>01517       innerBodyPart.setOriginalContentTypeStr( oldContentType.utf8() );
<a name="l01518"></a>01518     }
<a name="l01519"></a>01519     innerBodyPart.setContentDisposition( <span class="stringliteral">"inline"</span> );
<a name="l01520"></a>01520     QValueList&lt;int&gt; allowedCTEs;
<a name="l01521"></a>01521     <span class="comment">// the signed body must not be 8bit encoded</span>
<a name="l01522"></a>01522     innerBodyPart.setBodyAndGuessCte( bodyData, allowedCTEs,
<a name="l01523"></a>01523                                       !kmkernel-&gt;msgSender()-&gt;sendQuotedPrintable() &amp;&amp; !doSign,
<a name="l01524"></a>01524                                       doSign );
<a name="l01525"></a>01525     <span class="keywordflow">if</span> ( !mIsRichText )
<a name="l01526"></a>01526       innerBodyPart.setCharset( mCharset );
<a name="l01527"></a>01527     innerBodyPart.setBodyEncodedBinary( bodyData ); <span class="comment">// do we need this, since setBodyAndGuessCte does this already?</span>
<a name="l01528"></a>01528     DwBodyPart* innerDwPart = theMessage.<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( &amp;innerBodyPart );
<a name="l01529"></a>01529     innerDwPart-&gt;Assemble();
<a name="l01530"></a>01530     QByteArray tmpbody = <a class="code" href="namespaceKMail_1_1Util.html#62cdb963731a7eeaeca528f2e2651844" title="Construct a QByteArray from a DwString.">KMail::Util::ByteArray</a>( innerDwPart-&gt;AsString() );
<a name="l01531"></a>01531     <span class="keywordflow">if</span> ( mIsRichText ) { <span class="comment">// and add our mp/a boundary</span>
<a name="l01532"></a>01532         <span class="keywordtype">int</span> boundPos = tmpbody.find( <span class="charliteral">'\n'</span> );
<a name="l01533"></a>01533         <span class="keywordflow">if</span>( -1 &lt; boundPos ) {
<a name="l01534"></a>01534           QCString bStr( <span class="stringliteral">";\n  boundary=\""</span> );
<a name="l01535"></a>01535           bStr += mSaveBoundary.c_str();
<a name="l01536"></a>01536           bStr += <span class="stringliteral">"\""</span>;
<a name="l01537"></a>01537           bodyData = tmpbody;
<a name="l01538"></a>01538           KMail::Util::insert( bodyData, boundPos, bStr );
<a name="l01539"></a>01539           KMail::Util::insert( bodyData, 0, <span class="stringliteral">"--"</span> + mMultipartMixedBoundary + <span class="stringliteral">"\n"</span> ); <span class="comment">// prepend</span>
<a name="l01540"></a>01540         }
<a name="l01541"></a>01541     }
<a name="l01542"></a>01542     <span class="keywordflow">else</span> {
<a name="l01543"></a>01543       bodyData = tmpbody;
<a name="l01544"></a>01544       KMail::Util::insert( bodyData, 0, <span class="stringliteral">"--"</span> + mMultipartMixedBoundary + <span class="stringliteral">"\n"</span> ); <span class="comment">// prepend</span>
<a name="l01545"></a>01545     }
<a name="l01546"></a>01546     <span class="keyword">delete</span> innerDwPart;
<a name="l01547"></a>01547     innerDwPart = 0;
<a name="l01548"></a>01548     <span class="comment">// add all matching Attachments</span>
<a name="l01549"></a>01549     <span class="comment">// NOTE: This code will be changed when KMime is complete.</span>
<a name="l01550"></a>01550     <span class="keywordflow">for</span> ( QValueVector&lt;Attachment&gt;::iterator it = mAttachments.begin() ; it != mAttachments.end() ; ++it ) {
<a name="l01551"></a>01551       <span class="keywordflow">if</span> ( it-&gt;encrypt == doEncryptBody &amp;&amp; it-&gt;sign == doSignBody ) {
<a name="l01552"></a>01552         innerDwPart = theMessage.<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( it-&gt;part );
<a name="l01553"></a>01553         innerDwPart-&gt;Assemble();
<a name="l01554"></a>01554         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( bodyData, QCString( <span class="stringliteral">"\n--"</span> + mMultipartMixedBoundary + <span class="stringliteral">"\n"</span> ) );
<a name="l01555"></a>01555         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( bodyData, innerDwPart-&gt;AsString().c_str() );
<a name="l01556"></a>01556         <span class="keyword">delete</span> innerDwPart;
<a name="l01557"></a>01557         innerDwPart = 0;
<a name="l01558"></a>01558       }
<a name="l01559"></a>01559     }
<a name="l01560"></a>01560     <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( bodyData, QCString( <span class="stringliteral">"\n--"</span> + mMultipartMixedBoundary + <span class="stringliteral">"--\n"</span> ) );
<a name="l01561"></a>01561   } <span class="keywordflow">else</span> { <span class="comment">// !earlyAddAttachments</span>
<a name="l01562"></a>01562     QValueList&lt;int&gt; allowedCTEs;
<a name="l01563"></a>01563     <span class="comment">// the signed body must not be 8bit encoded</span>
<a name="l01564"></a>01564     mOldBodyPart.setBodyAndGuessCte(bodyData, allowedCTEs, !kmkernel-&gt;msgSender()-&gt;sendQuotedPrintable() &amp;&amp; !doSign,
<a name="l01565"></a>01565                                     doSign);
<a name="l01566"></a>01566     <span class="keywordflow">if</span> ( !mIsRichText )
<a name="l01567"></a>01567       mOldBodyPart.setCharset(mCharset);
<a name="l01568"></a>01568   }
<a name="l01569"></a>01569   <span class="comment">// create S/MIME body part for signing and/or encrypting</span>
<a name="l01570"></a>01570   mOldBodyPart.setBodyEncodedBinary( bodyData );
<a name="l01571"></a>01571 
<a name="l01572"></a>01572   <span class="keywordflow">if</span>( doSignBody || doEncryptBody ) {
<a name="l01573"></a>01573     <span class="comment">// get string representation of body part (including the attachments)</span>
<a name="l01574"></a>01574 
<a name="l01575"></a>01575     DwBodyPart* dwPart;
<a name="l01576"></a>01576     <span class="keywordflow">if</span> ( mIsRichText &amp;&amp; !mEarlyAddAttachments ) {
<a name="l01577"></a>01577       <span class="comment">// if we are using richtext and not already have a mp/a body</span>
<a name="l01578"></a>01578       <span class="comment">// make the body a mp/a body</span>
<a name="l01579"></a>01579       dwPart = theMessage.<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( &amp;mOldBodyPart );
<a name="l01580"></a>01580       DwHeaders&amp; headers = dwPart-&gt;Headers();
<a name="l01581"></a>01581       DwMediaType&amp; ct = headers.ContentType();
<a name="l01582"></a>01582       ct.SetBoundary(mSaveBoundary);
<a name="l01583"></a>01583       dwPart-&gt;Assemble();
<a name="l01584"></a>01584     }
<a name="l01585"></a>01585     <span class="keywordflow">else</span> {
<a name="l01586"></a>01586       dwPart = theMessage.<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( &amp;mOldBodyPart );
<a name="l01587"></a>01587       dwPart-&gt;Assemble();
<a name="l01588"></a>01588     }
<a name="l01589"></a>01589     mEncodedBody = <a class="code" href="namespaceKMail_1_1Util.html#62cdb963731a7eeaeca528f2e2651844" title="Construct a QByteArray from a DwString.">KMail::Util::ByteArray</a>( dwPart-&gt;AsString() );
<a name="l01590"></a>01590     <span class="keyword">delete</span> dwPart;
<a name="l01591"></a>01591     dwPart = 0;
<a name="l01592"></a>01592 
<a name="l01593"></a>01593     <span class="comment">// manually add a boundary definition to the Content-Type header</span>
<a name="l01594"></a>01594     <span class="keywordflow">if</span>( !mMultipartMixedBoundary.isEmpty() ) {
<a name="l01595"></a>01595       <span class="keywordtype">int</span> boundPos = mEncodedBody.find( <span class="charliteral">'\n'</span> );
<a name="l01596"></a>01596       <span class="keywordflow">if</span>( -1 &lt; boundPos ) {
<a name="l01597"></a>01597         <span class="comment">// insert new "boundary" parameter</span>
<a name="l01598"></a>01598         QCString bStr( <span class="stringliteral">";\n  boundary=\""</span> );
<a name="l01599"></a>01599         bStr += mMultipartMixedBoundary;
<a name="l01600"></a>01600         bStr += <span class="stringliteral">"\""</span>;
<a name="l01601"></a>01601         KMail::Util::insert( mEncodedBody, boundPos, bStr.data() );
<a name="l01602"></a>01602       }
<a name="l01603"></a>01603     }
<a name="l01604"></a>01604 
<a name="l01605"></a>01605     <span class="comment">// replace simple LFs by CRLFs for all MIME supporting CryptPlugs</span>
<a name="l01606"></a>01606     <span class="comment">// according to RfC 2633, 3.1.1 Canonicalization</span>
<a name="l01607"></a>01607     <span class="comment">//kdDebug(5006) &lt;&lt; "Converting LF to CRLF (see RfC 2633, 3.1.1 Canonicalization)" &lt;&lt; endl;</span>
<a name="l01608"></a>01608     mEncodedBody = <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;.">KMail::Util::lf2crlf</a>( mEncodedBody );
<a name="l01609"></a>01609   }
<a name="l01610"></a>01610 
<a name="l01611"></a>01611   <span class="keywordflow">if</span> ( doSignBody ) {
<a name="l01612"></a>01612     mPerformingSignOperation = <span class="keyword">true</span>;  <span class="comment">// this lets the KMComposeWin know if it is safe to close the window.</span>
<a name="l01613"></a>01613     pgpSignedMsg( mEncodedBody, format );
<a name="l01614"></a>01614     mPerformingSignOperation = <span class="keyword">false</span>;
<a name="l01615"></a>01615 
<a name="l01616"></a>01616     <span class="keywordflow">if</span> ( mSignature.isEmpty() ) {
<a name="l01617"></a>01617       kdDebug() &lt;&lt; <span class="stringliteral">"signature was empty"</span> &lt;&lt; endl;
<a name="l01618"></a>01618       mRc = <span class="keyword">false</span>;
<a name="l01619"></a>01619       <span class="keywordflow">return</span>;
<a name="l01620"></a>01620     }
<a name="l01621"></a>01621     mRc = processStructuringInfo( QString::null,
<a name="l01622"></a>01622                   mOldBodyPart.contentDescription(),
<a name="l01623"></a>01623                   mOldBodyPart.typeStr(),
<a name="l01624"></a>01624                   mOldBodyPart.subtypeStr(),
<a name="l01625"></a>01625                   mOldBodyPart.contentDisposition(),
<a name="l01626"></a>01626                   mOldBodyPart.contentTransferEncodingStr(),
<a name="l01627"></a>01627                   mEncodedBody, <span class="stringliteral">"signature"</span>,
<a name="l01628"></a>01628                   mSignature,
<a name="l01629"></a>01629                   *mNewBodyPart, <span class="keyword">true</span>, format );
<a name="l01630"></a>01630     <span class="keywordflow">if</span> ( mRc ) {
<a name="l01631"></a>01631       <span class="keywordflow">if</span> ( !makeMultiPartSigned( format ) ) {
<a name="l01632"></a>01632     mNewBodyPart-&gt;setCharset( mCharset );
<a name="l01633"></a>01633       }
<a name="l01634"></a>01634     } <span class="keywordflow">else</span>
<a name="l01635"></a>01635       KMessageBox::sorry( mComposeWin,
<a name="l01636"></a>01636               mErrorProcessingStructuringInfo );
<a name="l01637"></a>01637   }
<a name="l01638"></a>01638 
<a name="l01639"></a>01639   <span class="keywordflow">if</span> ( !mRc )
<a name="l01640"></a>01640     <span class="keywordflow">return</span>;
<a name="l01641"></a>01641 
<a name="l01642"></a>01642   continueComposeMessage( theMessage, doSign, doEncrypt, format );
<a name="l01643"></a>01643 }
<a name="l01644"></a>01644 
<a name="l01645"></a>01645 <span class="comment">// Do the encryption stuff</span>
<a name="l01646"></a>01646 <span class="keywordtype">void</span> MessageComposer::continueComposeMessage( <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>&amp; theMessage,
<a name="l01647"></a>01647                                               <span class="keywordtype">bool</span> doSign, <span class="keywordtype">bool</span> doEncrypt,
<a name="l01648"></a>01648                                               Kleo::CryptoMessageFormat format )
<a name="l01649"></a>01649 {
<a name="l01650"></a>01650 
<a name="l01651"></a>01651   <span class="keyword">const</span> std::vector&lt;Kleo::KeyResolver::SplitInfo&gt; splitInfos
<a name="l01652"></a>01652     = mKeyResolver-&gt;encryptionItems( format );
<a name="l01653"></a>01653   kdWarning( splitInfos.empty() )
<a name="l01654"></a>01654     &lt;&lt; <span class="stringliteral">"MessageComposer::continueComposeMessage(): splitInfos.empty() for "</span>
<a name="l01655"></a>01655     &lt;&lt; Kleo::cryptoMessageFormatToString( format ) &lt;&lt; endl;
<a name="l01656"></a>01656 
<a name="l01657"></a>01657   <span class="keywordflow">if</span> ( !splitInfos.empty() &amp;&amp; doEncrypt &amp;&amp; !saveMessagesEncrypted() ) {
<a name="l01658"></a>01658     mJobs.push_front( <span class="keyword">new</span> SetLastMessageAsUnencryptedVersionOfLastButOne( <span class="keyword">this</span> ) );
<a name="l01659"></a>01659     mJobs.push_front( <span class="keyword">new</span> EncryptMessageJob( <span class="keyword">new</span> <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>( theMessage ),
<a name="l01660"></a>01660                          Kleo::KeyResolver::SplitInfo( splitInfos.front().recipients ), doSign,
<a name="l01661"></a>01661                          <span class="keyword">false</span>, mEncodedBody,
<a name="l01662"></a>01662                          mPreviousBoundaryLevel,
<a name="l01663"></a>01663                          <span class="comment">/*mOldBodyPart,*/</span> mNewBodyPart,
<a name="l01664"></a>01664                          format, <span class="keyword">this</span> ) );
<a name="l01665"></a>01665   }
<a name="l01666"></a>01666 
<a name="l01667"></a>01667   <span class="keywordflow">for</span> ( std::vector&lt;Kleo::KeyResolver::SplitInfo&gt;::const_iterator it = splitInfos.begin() ; it != splitInfos.end() ; ++it )
<a name="l01668"></a>01668     mJobs.push_front( <span class="keyword">new</span> EncryptMessageJob( <span class="keyword">new</span> <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>( theMessage ), *it, doSign,
<a name="l01669"></a>01669                          doEncrypt, mEncodedBody,
<a name="l01670"></a>01670                          mPreviousBoundaryLevel,
<a name="l01671"></a>01671                          <span class="comment">/*mOldBodyPart,*/</span> mNewBodyPart,
<a name="l01672"></a>01672                          format, <span class="keyword">this</span> ) );
<a name="l01673"></a>01673 }
<a name="l01674"></a>01674 
<a name="l01675"></a>01675 <span class="keywordtype">void</span> MessageComposer::encryptMessage( <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>* msg,
<a name="l01676"></a>01676                       <span class="keyword">const</span> Kleo::KeyResolver::SplitInfo &amp; splitInfo,
<a name="l01677"></a>01677                                       <span class="keywordtype">bool</span> doSign, <span class="keywordtype">bool</span> doEncrypt,
<a name="l01678"></a>01678                                       KMMessagePart newBodyPart,
<a name="l01679"></a>01679                       Kleo::CryptoMessageFormat format )
<a name="l01680"></a>01680 {
<a name="l01681"></a>01681   <span class="keywordflow">if</span> ( doEncrypt &amp;&amp; splitInfo.keys.empty() ) {
<a name="l01682"></a>01682     <span class="comment">// the user wants to send the message unencrypted</span>
<a name="l01683"></a>01683     <span class="comment">//mComposeWin-&gt;setEncryption( false, false );</span>
<a name="l01684"></a>01684     <span class="comment">//FIXME why is this talkback needed? Till</span>
<a name="l01685"></a>01685     doEncrypt = <span class="keyword">false</span>;
<a name="l01686"></a>01686   }
<a name="l01687"></a>01687 
<a name="l01688"></a>01688   <span class="keyword">const</span> <span class="keywordtype">bool</span> doEncryptBody = doEncrypt &amp;&amp; mEncryptBody;
<a name="l01689"></a>01689   <span class="keyword">const</span> <span class="keywordtype">bool</span> doSignBody = doSign &amp;&amp; mSignBody;
<a name="l01690"></a>01690 
<a name="l01691"></a>01691   <span class="keywordflow">if</span> ( doEncryptBody ) {
<a name="l01692"></a>01692     QByteArray innerContent;
<a name="l01693"></a>01693     <span class="keywordflow">if</span> ( doSignBody ) {
<a name="l01694"></a>01694       <span class="comment">// extract signed body from newBodyPart</span>
<a name="l01695"></a>01695       DwBodyPart* dwPart = msg-&gt;<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( &amp;newBodyPart );
<a name="l01696"></a>01696       dwPart-&gt;Assemble();
<a name="l01697"></a>01697       innerContent = <a class="code" href="namespaceKMail_1_1Util.html#62cdb963731a7eeaeca528f2e2651844" title="Construct a QByteArray from a DwString.">KMail::Util::ByteArray</a>( dwPart-&gt;AsString() );
<a name="l01698"></a>01698       <span class="keyword">delete</span> dwPart;
<a name="l01699"></a>01699       dwPart = 0;
<a name="l01700"></a>01700     } <span class="keywordflow">else</span> {
<a name="l01701"></a>01701       innerContent = mEncodedBody;
<a name="l01702"></a>01702     }
<a name="l01703"></a>01703 
<a name="l01704"></a>01704     <span class="comment">// now do the encrypting:</span>
<a name="l01705"></a>01705     <span class="comment">// replace simple LFs by CRLFs for all MIME supporting CryptPlugs</span>
<a name="l01706"></a>01706     <span class="comment">// according to RfC 2633, 3.1.1 Canonicalization</span>
<a name="l01707"></a>01707     <span class="comment">//kdDebug(5006) &lt;&lt; "Converting LF to CRLF (see RfC 2633, 3.1.1 Canonicalization)" &lt;&lt; endl;</span>
<a name="l01708"></a>01708     innerContent = <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;.">KMail::Util::lf2crlf</a>( innerContent );
<a name="l01709"></a>01709     <span class="comment">//kdDebug(5006) &lt;&lt; "                                                       done." &lt;&lt; endl;</span>
<a name="l01710"></a>01710 
<a name="l01711"></a>01711     QByteArray encryptedBody;
<a name="l01712"></a>01712     Kpgp::Result result = pgpEncryptedMsg( encryptedBody, innerContent,
<a name="l01713"></a>01713                                            splitInfo.keys, format );
<a name="l01714"></a>01714     <span class="keywordflow">if</span> ( result != Kpgp::Ok ) {
<a name="l01715"></a>01715       mRc = <span class="keyword">false</span>;
<a name="l01716"></a>01716       <span class="keywordflow">return</span>;
<a name="l01717"></a>01717     }
<a name="l01718"></a>01718     mRc = processStructuringInfo( <span class="stringliteral">"http://www.gnupg.org/aegypten/"</span>,
<a name="l01719"></a>01719                   newBodyPart.contentDescription(),
<a name="l01720"></a>01720                   newBodyPart.typeStr(),
<a name="l01721"></a>01721                   newBodyPart.subtypeStr(),
<a name="l01722"></a>01722                   newBodyPart.contentDisposition(),
<a name="l01723"></a>01723                   newBodyPart.contentTransferEncodingStr(),
<a name="l01724"></a>01724                   innerContent,
<a name="l01725"></a>01725                   <span class="stringliteral">"encrypted data"</span>,
<a name="l01726"></a>01726                   encryptedBody,
<a name="l01727"></a>01727                   newBodyPart, <span class="keyword">false</span>, format );
<a name="l01728"></a>01728     <span class="keywordflow">if</span> ( !mRc )
<a name="l01729"></a>01729       KMessageBox::sorry(mComposeWin, mErrorProcessingStructuringInfo);
<a name="l01730"></a>01730   }
<a name="l01731"></a>01731 
<a name="l01732"></a>01732   <span class="comment">// process the attachments that are not included into the body</span>
<a name="l01733"></a>01733   <span class="keywordflow">if</span>( mRc ) {
<a name="l01734"></a>01734     <span class="keyword">const</span> <span class="keywordtype">bool</span> useNewBodyPart = doSignBody || doEncryptBody;
<a name="l01735"></a>01735     addBodyAndAttachments( msg, splitInfo, doSign, doEncrypt,
<a name="l01736"></a>01736       useNewBodyPart ? newBodyPart : mOldBodyPart, format );
<a name="l01737"></a>01737   }
<a name="l01738"></a>01738 }
<a name="l01739"></a>01739 
<a name="l01740"></a>01740 <span class="keywordtype">void</span> MessageComposer::addBodyAndAttachments( <a class="code" href="classKMMessage.html" title="This is a Mime Message.">KMMessage</a>* msg,
<a name="l01741"></a>01741                                              <span class="keyword">const</span> Kleo::KeyResolver::SplitInfo &amp; splitInfo,
<a name="l01742"></a>01742                                              <span class="keywordtype">bool</span> doSign, <span class="keywordtype">bool</span> doEncrypt,
<a name="l01743"></a>01743                                              <span class="keyword">const</span> KMMessagePart&amp; ourFineBodyPart,
<a name="l01744"></a>01744                                              Kleo::CryptoMessageFormat format )
<a name="l01745"></a>01745 {
<a name="l01746"></a>01746   <span class="keyword">const</span> <span class="keywordtype">bool</span> doEncryptBody = doEncrypt &amp;&amp; mEncryptBody;
<a name="l01747"></a>01747   <span class="keyword">const</span> <span class="keywordtype">bool</span> doSignBody = doSign &amp;&amp; mSignBody;
<a name="l01748"></a>01748 
<a name="l01749"></a>01749   <span class="keywordflow">if</span>( !mAttachments.empty()
<a name="l01750"></a>01750       &amp;&amp; ( !mEarlyAddAttachments || !mAllAttachmentsAreInBody ) ) {
<a name="l01751"></a>01751     <span class="comment">// set the content type header</span>
<a name="l01752"></a>01752     msg-&gt;<a class="code" href="classKMMessage.html#7dd06ebd026305292fd380c9acb283b6" title="get the DwHeaders (make sure to call setNeedsAssembly() function after directly modyfying...">headers</a>().ContentType().SetType( DwMime::kTypeMultipart );
<a name="l01753"></a>01753     msg-&gt;<a class="code" href="classKMMessage.html#7dd06ebd026305292fd380c9acb283b6" title="get the DwHeaders (make sure to call setNeedsAssembly() function after directly modyfying...">headers</a>().ContentType().SetSubtype( DwMime::kSubtypeMixed );
<a name="l01754"></a>01754     msg-&gt;<a class="code" href="classKMMessage.html#7dd06ebd026305292fd380c9acb283b6" title="get the DwHeaders (make sure to call setNeedsAssembly() function after directly modyfying...">headers</a>().ContentType().CreateBoundary( 0 );
<a name="l01755"></a>01755     kdDebug(5006) &lt;&lt; <span class="stringliteral">"MessageComposer::addBodyAndAttachments() : set top level Content-Type to Multipart/Mixed"</span> &lt;&lt; endl;
<a name="l01756"></a>01756 
<a name="l01757"></a>01757     <span class="comment">// add our Body Part</span>
<a name="l01758"></a>01758     DwBodyPart* tmpDwPart = msg-&gt;<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( &amp;ourFineBodyPart );
<a name="l01759"></a>01759     DwHeaders&amp; headers = tmpDwPart-&gt;Headers();
<a name="l01760"></a>01760     DwMediaType&amp; ct = headers.ContentType();
<a name="l01761"></a>01761     <span class="keywordflow">if</span> ( !mSaveBoundary.empty() )
<a name="l01762"></a>01762       ct.SetBoundary(mSaveBoundary);
<a name="l01763"></a>01763     tmpDwPart-&gt;Assemble();
<a name="l01764"></a>01764 
<a name="l01765"></a>01765     <span class="comment">//KMMessagePart newPart;</span>
<a name="l01766"></a>01766     <span class="comment">//newPart.setBody(tmpDwPart-&gt;AsString().c_str());</span>
<a name="l01767"></a>01767     msg-&gt;<a class="code" href="classKMMessage.html#74c1405916368420c33e1542107b6f82" title="Append a DwBodyPart to the message.">addDwBodyPart</a>(tmpDwPart); <span class="comment">// only this method doesn't add it as text/plain</span>
<a name="l01768"></a>01768 
<a name="l01769"></a>01769     <span class="comment">// add Attachments</span>
<a name="l01770"></a>01770     <span class="comment">// create additional bodyparts for the attachments (if any)</span>
<a name="l01771"></a>01771     KMMessagePart newAttachPart;
<a name="l01772"></a>01772     <span class="keywordflow">for</span> ( QValueVector&lt;Attachment&gt;::iterator it = mAttachments.begin() ; it != mAttachments.end() ; ++it ) {
<a name="l01773"></a>01773 
<a name="l01774"></a>01774       <span class="keyword">const</span> <span class="keywordtype">bool</span> cryptFlagsDifferent = ( it-&gt;encrypt != doEncryptBody || it-&gt;sign != doSignBody ) ;
<a name="l01775"></a>01775 
<a name="l01776"></a>01776       <span class="keywordflow">if</span> ( !cryptFlagsDifferent &amp;&amp; mEarlyAddAttachments )
<a name="l01777"></a>01777         <span class="keywordflow">continue</span>;
<a name="l01778"></a>01778 
<a name="l01779"></a>01779       <span class="keyword">const</span> <span class="keywordtype">bool</span> encryptThisNow = doEncrypt &amp;&amp; cryptFlagsDifferent &amp;&amp; it-&gt;encrypt ;
<a name="l01780"></a>01780       <span class="keyword">const</span> <span class="keywordtype">bool</span> signThisNow = doSign &amp;&amp; cryptFlagsDifferent &amp;&amp; it-&gt;sign ;
<a name="l01781"></a>01781 
<a name="l01782"></a>01782       <span class="keywordflow">if</span> ( !encryptThisNow &amp;&amp; !signThisNow ) {
<a name="l01783"></a>01783         msg-&gt;<a class="code" href="classKMMessage.html#98f53dd0092cd4b6a8a07efef0526217" title="Append a body part to the message.">addBodyPart</a>( it-&gt;part );
<a name="l01784"></a>01784         <span class="comment">// Assemble the message. Not sure why, but this fixes the vanishing boundary parameter</span>
<a name="l01785"></a>01785         (void)msg-&gt;<a class="code" href="classKMMessage.html#dc5c9ceacb31f0149307e693de6fed65">asDwMessage</a>();
<a name="l01786"></a>01786         <span class="keywordflow">continue</span>;
<a name="l01787"></a>01787       }
<a name="l01788"></a>01788 
<a name="l01789"></a>01789       KMMessagePart&amp; rEncryptMessagePart( *it-&gt;part );
<a name="l01790"></a>01790 
<a name="l01791"></a>01791       DwBodyPart* innerDwPart = msg-&gt;<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( it-&gt;part );
<a name="l01792"></a>01792       innerDwPart-&gt;Assemble();
<a name="l01793"></a>01793       QByteArray encodedAttachment = <a class="code" href="namespaceKMail_1_1Util.html#62cdb963731a7eeaeca528f2e2651844" title="Construct a QByteArray from a DwString.">KMail::Util::ByteArray</a>( innerDwPart-&gt;AsString() );
<a name="l01794"></a>01794       <span class="keyword">delete</span> innerDwPart;
<a name="l01795"></a>01795       innerDwPart = 0;
<a name="l01796"></a>01796 
<a name="l01797"></a>01797       <span class="comment">// replace simple LFs by CRLFs for all MIME supporting CryptPlugs</span>
<a name="l01798"></a>01798       <span class="comment">// according to RfC 2633, 3.1.1 Canonicalization</span>
<a name="l01799"></a>01799       <span class="comment">//kdDebug(5006) &lt;&lt; "Converting LF to CRLF (see RfC 2633, 3.1.1 Canonicalization)" &lt;&lt; endl;</span>
<a name="l01800"></a>01800       encodedAttachment = <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;.">KMail::Util::lf2crlf</a>( encodedAttachment );
<a name="l01801"></a>01801 
<a name="l01802"></a>01802       <span class="comment">// sign this attachment</span>
<a name="l01803"></a>01803       <span class="keywordflow">if</span>( signThisNow ) {
<a name="l01804"></a>01804         pgpSignedMsg( encodedAttachment, format );
<a name="l01805"></a>01805         mRc = !mSignature.isEmpty();
<a name="l01806"></a>01806         <span class="keywordflow">if</span>( mRc ) {
<a name="l01807"></a>01807           mRc = processStructuringInfo( <span class="stringliteral">"http://www.gnupg.org/aegypten/"</span>,
<a name="l01808"></a>01808                                         it-&gt;part-&gt;contentDescription(),
<a name="l01809"></a>01809                                         it-&gt;part-&gt;typeStr(),
<a name="l01810"></a>01810                                         it-&gt;part-&gt;subtypeStr(),
<a name="l01811"></a>01811                                         it-&gt;part-&gt;contentDisposition(),
<a name="l01812"></a>01812                                         it-&gt;part-&gt;contentTransferEncodingStr(),
<a name="l01813"></a>01813                                         encodedAttachment,
<a name="l01814"></a>01814                                         <span class="stringliteral">"signature"</span>,
<a name="l01815"></a>01815                                         mSignature,
<a name="l01816"></a>01816                                         newAttachPart, <span class="keyword">true</span>, format );
<a name="l01817"></a>01817           <span class="keywordflow">if</span>( mRc ) {
<a name="l01818"></a>01818             <span class="keywordflow">if</span>( encryptThisNow ) {
<a name="l01819"></a>01819               rEncryptMessagePart = newAttachPart;
<a name="l01820"></a>01820               DwBodyPart* dwPart = msg-&gt;<a class="code" href="classKMMessage.html#fd780c436fe7879034871767c6dc1f18" title="Compose a DwBodyPart (needed for adding a part to the message).">createDWBodyPart</a>( &amp;newAttachPart );
<a name="l01821"></a>01821               dwPart-&gt;Assemble();
<a name="l01822"></a>01822               encodedAttachment = <a class="code" href="namespaceKMail_1_1Util.html#62cdb963731a7eeaeca528f2e2651844" title="Construct a QByteArray from a DwString.">KMail::Util::ByteArray</a>( dwPart-&gt;AsString() );
<a name="l01823"></a>01823               <span class="keyword">delete</span> dwPart;
<a name="l01824"></a>01824               dwPart = 0;
<a name="l01825"></a>01825             }
<a name="l01826"></a>01826           } <span class="keywordflow">else</span>
<a name="l01827"></a>01827             KMessageBox::sorry( mComposeWin, mErrorProcessingStructuringInfo );
<a name="l01828"></a>01828         } <span class="keywordflow">else</span> {
<a name="l01829"></a>01829           <span class="comment">// quit the attachments' loop</span>
<a name="l01830"></a>01830           <span class="keywordflow">break</span>;
<a name="l01831"></a>01831         }
<a name="l01832"></a>01832       }
<a name="l01833"></a>01833       <span class="keywordflow">if</span>( encryptThisNow ) {
<a name="l01834"></a>01834         QByteArray encryptedBody;
<a name="l01835"></a>01835         Kpgp::Result result = pgpEncryptedMsg( encryptedBody,
<a name="l01836"></a>01836                                                encodedAttachment,
<a name="l01837"></a>01837                                                splitInfo.keys,
<a name="l01838"></a>01838                                                format );
<a name="l01839"></a>01839 
<a name="l01840"></a>01840         <span class="keywordflow">if</span>( Kpgp::Ok == result ) {
<a name="l01841"></a>01841           mRc = processStructuringInfo( <span class="stringliteral">"http://www.gnupg.org/aegypten/"</span>,
<a name="l01842"></a>01842                                         rEncryptMessagePart.contentDescription(),
<a name="l01843"></a>01843                                         rEncryptMessagePart.typeStr(),
<a name="l01844"></a>01844                                         rEncryptMessagePart.subtypeStr(),
<a name="l01845"></a>01845                                         rEncryptMessagePart.contentDisposition(),
<a name="l01846"></a>01846                                         rEncryptMessagePart.contentTransferEncodingStr(),
<a name="l01847"></a>01847                                         encodedAttachment,
<a name="l01848"></a>01848                                         <span class="stringliteral">"encrypted data"</span>,
<a name="l01849"></a>01849                                         encryptedBody,
<a name="l01850"></a>01850                                         newAttachPart, <span class="keyword">false</span>, format );
<a name="l01851"></a>01851           <span class="keywordflow">if</span> ( !mRc )
<a name="l01852"></a>01852             KMessageBox::sorry( mComposeWin, mErrorProcessingStructuringInfo );
<a name="l01853"></a>01853         } <span class="keywordflow">else</span>
<a name="l01854"></a>01854           mRc = <span class="keyword">false</span>;
<a name="l01855"></a>01855       }
<a name="l01856"></a>01856       msg-&gt;<a class="code" href="classKMMessage.html#98f53dd0092cd4b6a8a07efef0526217" title="Append a body part to the message.">addBodyPart</a>( &amp;newAttachPart );
<a name="l01857"></a>01857       (void)msg-&gt;<a class="code" href="classKMMessage.html#dc5c9ceacb31f0149307e693de6fed65">asDwMessage</a>(); <span class="comment">// Assemble the message. One gets a completely empty message otherwise :/</span>
<a name="l01858"></a>01858     }
<a name="l01859"></a>01859   } <span class="keywordflow">else</span> { <span class="comment">// no attachments in the final message</span>
<a name="l01860"></a>01860     <span class="keywordflow">if</span>( ourFineBodyPart.originalContentTypeStr() ) {
<a name="l01861"></a>01861       msg-&gt;<a class="code" href="classKMMessage.html#7dd06ebd026305292fd380c9acb283b6" title="get the DwHeaders (make sure to call setNeedsAssembly() function after directly modyfying...">headers</a>().ContentType().FromString( ourFineBodyPart.originalContentTypeStr() );
<a name="l01862"></a>01862       msg-&gt;<a class="code" href="classKMMessage.html#7dd06ebd026305292fd380c9acb283b6" title="get the DwHeaders (make sure to call setNeedsAssembly() function after directly modyfying...">headers</a>().ContentType().Parse();
<a name="l01863"></a>01863       kdDebug(5006) &lt;&lt; <span class="stringliteral">"MessageComposer::addBodyAndAttachments() : set top level Content-Type from originalContentTypeStr()="</span> &lt;&lt; ourFineBodyPart.originalContentTypeStr() &lt;&lt; endl;
<a name="l01864"></a>01864     } <span class="keywordflow">else</span> {
<a name="l01865"></a>01865       QCString ct = ourFineBodyPart.typeStr() + <span class="stringliteral">"/"</span> + ourFineBodyPart.subtypeStr();
<a name="l01866"></a>01866       <span class="keywordflow">if</span> ( ct == <span class="stringliteral">"multipart/mixed"</span> )
<a name="l01867"></a>01867         ct += <span class="stringliteral">";\n\tboundary=\""</span> + mMultipartMixedBoundary + <span class="charliteral">'"'</span>;
<a name="l01868"></a>01868       <span class="keywordflow">else</span> <span class="keywordflow">if</span> ( ct == <span class="stringliteral">"multipart/alternative"</span> )
<a name="l01869"></a>01869         ct += <span class="stringliteral">";\n\tboundary=\""</span> + QCString(mSaveBoundary.c_str()) + <span class="charliteral">'"'</span>;
<a name="l01870"></a>01870       msg-&gt;<a class="code" href="classKMMessage.html#7dd06ebd026305292fd380c9acb283b6" title="get the DwHeaders (make sure to call setNeedsAssembly() function after directly modyfying...">headers</a>().ContentType().FromString( ct );
<a name="l01871"></a>01871       msg-&gt;<a class="code" href="classKMMessage.html#7dd06ebd026305292fd380c9acb283b6" title="get the DwHeaders (make sure to call setNeedsAssembly() function after directly modyfying...">headers</a>().ContentType().Parse();
<a name="l01872"></a>01872       kdDebug(5006) &lt;&lt; <span class="stringliteral">"MessageComposer::addBodyAndAttachments() : set top level Content-Type to "</span> &lt;&lt; ct &lt;&lt; endl;
<a name="l01873"></a>01873     }
<a name="l01874"></a>01874     <span class="keywordflow">if</span> ( !ourFineBodyPart.charset().isEmpty() )
<a name="l01875"></a>01875       msg-&gt;<a class="code" href="classKMMessage.html#6c6413b3690538964ac810f4c6755a5b" title="Set the message charset.">setCharset</a>( ourFineBodyPart.charset() );
<a name="l01876"></a>01876     msg-&gt;<a class="code" href="classKMMessage.html#de227ca74ea9bca2412ddfc63b4025c6" title="Set the header field with the given name to the given value.">setHeaderField</a>( <span class="stringliteral">"Content-Transfer-Encoding"</span>,
<a name="l01877"></a>01877                          ourFineBodyPart.contentTransferEncodingStr() );
<a name="l01878"></a>01878     msg-&gt;<a class="code" href="classKMMessage.html#de227ca74ea9bca2412ddfc63b4025c6" title="Set the header field with the given name to the given value.">setHeaderField</a>( <span class="stringliteral">"Content-Description"</span>,
<a name="l01879"></a>01879                          ourFineBodyPart.contentDescription() );
<a name="l01880"></a>01880     msg-&gt;<a class="code" href="classKMMessage.html#de227ca74ea9bca2412ddfc63b4025c6" title="Set the header field with the given name to the given value.">setHeaderField</a>( <span class="stringliteral">"Content-Disposition"</span>,
<a name="l01881"></a>01881                          ourFineBodyPart.contentDisposition() );
<a name="l01882"></a>01882 
<a name="l01883"></a>01883     <span class="keywordflow">if</span> ( mDebugComposerCrypto )
<a name="l01884"></a>01884       kdDebug(5006) &lt;&lt; <span class="stringliteral">"MessageComposer::addBodyAndAttachments() : top level headers and body adjusted"</span> &lt;&lt; endl;
<a name="l01885"></a>01885 
<a name="l01886"></a>01886     <span class="comment">// set body content</span>
<a name="l01887"></a>01887     msg-&gt;<a class="code" href="classKMMessage.html#1b9c4db08086c94986f00d0c708a01e7" title="Set the message body.">setBody</a>( ourFineBodyPart.dwBody() );
<a name="l01888"></a>01888 
<a name="l01889"></a>01889   }
<a name="l01890"></a>01890 
<a name="l01891"></a>01891   msg-&gt;<a class="code" href="classKMMessage.html#de227ca74ea9bca2412ddfc63b4025c6" title="Set the header field with the given name to the given value.">setHeaderField</a>( <span class="stringliteral">"X-KMail-Recipients"</span>,
<a name="l01892"></a>01892                        splitInfo.recipients.join(<span class="stringliteral">", "</span>), KMMessage::Address );
<a name="l01893"></a>01893 
<a name="l01894"></a>01894   <span class="keywordflow">if</span> ( mDebugComposerCrypto ) {
<a name="l01895"></a>01895     kdDebug(5006) &lt;&lt; <span class="stringliteral">"MessageComposer::addBodyAndAttachments():\n      Final message:\n|||"</span> &lt;&lt; msg-&gt;<a class="code" href="classKMMessage.html#b9b4e74c3446bce61e34201fd1e793d8" title="Return the entire message contents as a string.">asString</a>() &lt;&lt; <span class="stringliteral">"|||\n\n"</span> &lt;&lt; endl;
<a name="l01896"></a>01896     msg-&gt;<a class="code" href="classKMMessage.html#7dd06ebd026305292fd380c9acb283b6" title="get the DwHeaders (make sure to call setNeedsAssembly() function after directly modyfying...">headers</a>().Assemble();
<a name="l01897"></a>01897     kdDebug(5006) &lt;&lt; <span class="stringliteral">"\n\n\nMessageComposer::addBodyAndAttachments():\n      Final headers:\n\n"</span> &lt;&lt; msg-&gt;<a class="code" href="classKMMessage.html#81a56c11d9920301421152b9e0afc45d" title="Return header as string.">headerAsString</a>() &lt;&lt; <span class="stringliteral">"|||\n\n\n\n\n"</span> &lt;&lt; endl;
<a name="l01898"></a>01898   }
<a name="l01899"></a>01899 }
<a name="l01900"></a>01900 
<a name="l01901"></a>01901 <span class="comment">//-----------------------------------------------------------------------------</span>
<a name="l01902"></a>01902 <span class="comment">// This method does not call any crypto ops, so it does not need to be async</span>
<a name="l01903"></a>01903 <span class="keywordtype">bool</span> MessageComposer::processStructuringInfo( <span class="keyword">const</span> QString bugURL,
<a name="l01904"></a>01904                                               <span class="keyword">const</span> QString contentDescClear,
<a name="l01905"></a>01905                                               <span class="keyword">const</span> QCString contentTypeClear,
<a name="l01906"></a>01906                                               <span class="keyword">const</span> QCString contentSubtypeClear,
<a name="l01907"></a>01907                                               <span class="keyword">const</span> QCString contentDispClear,
<a name="l01908"></a>01908                                               <span class="keyword">const</span> QCString contentTEncClear,
<a name="l01909"></a>01909                                               <span class="keyword">const</span> QByteArray&amp; clearCStr,
<a name="l01910"></a>01910                                               <span class="keyword">const</span> QString <span class="comment">/*contentDescCiph*/</span>,
<a name="l01911"></a>01911                                               <span class="keyword">const</span> QByteArray&amp; ciphertext,
<a name="l01912"></a>01912                                               KMMessagePart&amp; resultingPart,
<a name="l01913"></a>01913                           <span class="keywordtype">bool</span> signing, Kleo::CryptoMessageFormat format )
<a name="l01914"></a>01914 {
<a name="l01915"></a>01915   assert( clearCStr.isEmpty() || clearCStr[clearCStr.size()-1] != <span class="charliteral">'\0'</span> ); <span class="comment">// I was called with a QCString !?</span>
<a name="l01916"></a>01916   <span class="keywordtype">bool</span> bOk = <span class="keyword">true</span>;
<a name="l01917"></a>01917 
<a name="l01918"></a>01918   <span class="keywordflow">if</span> ( makeMimeObject( format, signing ) ) {
<a name="l01919"></a>01919     QCString mainHeader = <span class="stringliteral">"Content-Type: "</span>;
<a name="l01920"></a>01920     <span class="keyword">const</span> <span class="keywordtype">char</span> * toplevelCT = toplevelContentType( format, signing );
<a name="l01921"></a>01921     <span class="keywordflow">if</span> ( toplevelCT )
<a name="l01922"></a>01922       mainHeader += toplevelCT;
<a name="l01923"></a>01923     <span class="keywordflow">else</span> {
<a name="l01924"></a>01924       <span class="keywordflow">if</span>( makeMultiMime( format, signing ) )
<a name="l01925"></a>01925         mainHeader += <span class="stringliteral">"text/plain"</span>;
<a name="l01926"></a>01926       <span class="keywordflow">else</span>
<a name="l01927"></a>01927         mainHeader += contentTypeClear + <span class="charliteral">'/'</span> + contentSubtypeClear;
<a name="l01928"></a>01928     }
<a name="l01929"></a>01929 
<a name="l01930"></a>01930     <span class="keyword">const</span> QCString boundaryCStr = KMime::multiPartBoundary();
<a name="l01931"></a>01931     <span class="comment">// add "boundary" parameter</span>
<a name="l01932"></a>01932     <span class="keywordflow">if</span> ( makeMultiMime( format, signing ) )
<a name="l01933"></a>01933       mainHeader.replace( <span class="stringliteral">"%boundary"</span>, boundaryCStr );
<a name="l01934"></a>01934 
<a name="l01935"></a>01935     <span class="keywordflow">if</span> ( toplevelCT ) {
<a name="l01936"></a>01936       <span class="keywordflow">if</span> ( <span class="keyword">const</span> <span class="keywordtype">char</span> * str = toplevelContentDisposition( format, signing ) ) {
<a name="l01937"></a>01937         mainHeader += <span class="stringliteral">"\nContent-Disposition: "</span>;
<a name="l01938"></a>01938         mainHeader += str;
<a name="l01939"></a>01939       }
<a name="l01940"></a>01940       <span class="keywordflow">if</span> ( !makeMultiMime( format, signing ) &amp;&amp;
<a name="l01941"></a>01941        binaryHint( format ) )
<a name="l01942"></a>01942         mainHeader += <span class="stringliteral">"\nContent-Transfer-Encoding: base64"</span>;
<a name="l01943"></a>01943     } <span class="keywordflow">else</span> {
<a name="l01944"></a>01944       <span class="keywordflow">if</span>( 0 &lt; contentDispClear.length() ) {
<a name="l01945"></a>01945         mainHeader += <span class="stringliteral">"\nContent-Disposition: "</span>;
<a name="l01946"></a>01946         mainHeader += contentDispClear;
<a name="l01947"></a>01947       }
<a name="l01948"></a>01948       <span class="keywordflow">if</span>( 0 &lt; contentTEncClear.length() ) {
<a name="l01949"></a>01949         mainHeader += <span class="stringliteral">"\nContent-Transfer-Encoding: "</span>;
<a name="l01950"></a>01950         mainHeader += contentTEncClear;
<a name="l01951"></a>01951       }
<a name="l01952"></a>01952     }
<a name="l01953"></a>01953 
<a name="l01954"></a>01954     <span class="comment">//kdDebug(5006) &lt;&lt; "processStructuringInfo: mainHeader=" &lt;&lt; mainHeader &lt;&lt; endl;</span>
<a name="l01955"></a>01955 
<a name="l01956"></a>01956     DwString mainDwStr;
<a name="l01957"></a>01957     mainDwStr = mainHeader + <span class="stringliteral">"\n\n"</span>;
<a name="l01958"></a>01958     DwBodyPart mainDwPa( mainDwStr, 0 );
<a name="l01959"></a>01959     mainDwPa.Parse();
<a name="l01960"></a>01960     <a class="code" href="classKMMessage.html#2b942616accf9ac39e19351ce2bba17d" title="Fill the KMMessagePart structure for a given DwBodyPart.">KMMessage::bodyPart</a>( &amp;mainDwPa, &amp;resultingPart );
<a name="l01961"></a>01961     <span class="keywordflow">if</span>( !makeMultiMime( format, signing ) ) {
<a name="l01962"></a>01962       <span class="keywordflow">if</span> ( signing &amp;&amp; includeCleartextWhenSigning( format ) ) {
<a name="l01963"></a>01963         QByteArray bodyText( clearCStr );
<a name="l01964"></a>01964         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( bodyText, <span class="stringliteral">"\n"</span> );
<a name="l01965"></a>01965         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( bodyText, ciphertext );
<a name="l01966"></a>01966         resultingPart.setBodyEncodedBinary( bodyText );
<a name="l01967"></a>01967       } <span class="keywordflow">else</span> {
<a name="l01968"></a>01968         resultingPart.setBodyEncodedBinary( ciphertext );
<a name="l01969"></a>01969       }
<a name="l01970"></a>01970     } <span class="keywordflow">else</span> {
<a name="l01971"></a>01971       <span class="comment">// Build the encapsulated MIME parts.</span>
<a name="l01972"></a>01972       <span class="comment">// Build a MIME part holding the version information</span>
<a name="l01973"></a>01973       <span class="comment">// taking the body contents returned in</span>
<a name="l01974"></a>01974       <span class="comment">// structuring.data.bodyTextVersion.</span>
<a name="l01975"></a>01975       QCString versCStr, codeCStr;
<a name="l01976"></a>01976       <span class="keywordflow">if</span> ( !signing &amp;&amp; format == Kleo::OpenPGPMIMEFormat )
<a name="l01977"></a>01977         versCStr =
<a name="l01978"></a>01978       <span class="stringliteral">"Content-Type: application/pgp-encrypted\n"</span>
<a name="l01979"></a>01979       <span class="stringliteral">"Content-Disposition: attachment\n"</span>
<a name="l01980"></a>01980       <span class="stringliteral">"\n"</span>
<a name="l01981"></a>01981       <span class="stringliteral">"Version: 1"</span>;
<a name="l01982"></a>01982 
<a name="l01983"></a>01983       <span class="comment">// Build a MIME part holding the code information</span>
<a name="l01984"></a>01984       <span class="comment">// taking the body contents returned in ciphertext.</span>
<a name="l01985"></a>01985       <span class="keyword">const</span> <span class="keywordtype">char</span> * nestedCT = nestedContentType( format, signing );
<a name="l01986"></a>01986       assert( nestedCT );
<a name="l01987"></a>01987       codeCStr = <span class="stringliteral">"Content-Type: "</span>;
<a name="l01988"></a>01988       codeCStr += nestedCT;
<a name="l01989"></a>01989       codeCStr += <span class="charliteral">'\n'</span>;
<a name="l01990"></a>01990       <span class="keywordflow">if</span> ( <span class="keyword">const</span> <span class="keywordtype">char</span> * str = nestedContentDisposition( format, signing ) ) {
<a name="l01991"></a>01991     codeCStr += <span class="stringliteral">"Content-Disposition: "</span>;
<a name="l01992"></a>01992     codeCStr += str;
<a name="l01993"></a>01993     codeCStr += <span class="charliteral">'\n'</span>;
<a name="l01994"></a>01994       }
<a name="l01995"></a>01995       <span class="keywordflow">if</span> ( binaryHint( format ) ) {
<a name="l01996"></a>01996     codeCStr += <span class="stringliteral">"Content-Transfer-Encoding: base64\n\n"</span>;
<a name="l01997"></a>01997     codeCStr += KMime::Codec::codecForName( <span class="stringliteral">"base64"</span> )-&gt;encodeToQCString( ciphertext );
<a name="l01998"></a>01998       } <span class="keywordflow">else</span>
<a name="l01999"></a>01999     codeCStr += <span class="charliteral">'\n'</span> + QCString( ciphertext.data(), ciphertext.size() + 1 );
<a name="l02000"></a>02000 
<a name="l02001"></a>02001 
<a name="l02002"></a>02002       QByteArray mainStr;
<a name="l02003"></a>02003       <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( mainStr, <span class="stringliteral">"--"</span> );
<a name="l02004"></a>02004       <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( mainStr, boundaryCStr );
<a name="l02005"></a>02005       <span class="keywordflow">if</span> ( signing &amp;&amp; includeCleartextWhenSigning( format ) &amp;&amp;
<a name="l02006"></a>02006        !clearCStr.isEmpty() ) {
<a name="l02007"></a>02007         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( mainStr, <span class="stringliteral">"\n"</span> );
<a name="l02008"></a>02008         <span class="comment">// clearCStr is the one that can be very big for large attachments, don't merge with the other lines</span>
<a name="l02009"></a>02009         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( mainStr, clearCStr );
<a name="l02010"></a>02010         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( mainStr, <span class="stringliteral">"\n--"</span> + boundaryCStr );
<a name="l02011"></a>02011       }
<a name="l02012"></a>02012       <span class="keywordflow">if</span> ( !versCStr.isEmpty() )
<a name="l02013"></a>02013         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( mainStr, <span class="stringliteral">"\n"</span> + versCStr + <span class="stringliteral">"\n--"</span> + boundaryCStr );
<a name="l02014"></a>02014       <span class="keywordflow">if</span>( !codeCStr.isEmpty() )
<a name="l02015"></a>02015         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( mainStr, <span class="stringliteral">"\n"</span> + codeCStr + <span class="stringliteral">"\n--"</span> + boundaryCStr );
<a name="l02016"></a>02016       <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( mainStr, <span class="stringliteral">"--\n"</span> );
<a name="l02017"></a>02017 
<a name="l02018"></a>02018       <span class="comment">//kdDebug(5006) &lt;&lt; "processStructuringInfo: mainStr=" &lt;&lt; mainStr &lt;&lt; endl;</span>
<a name="l02019"></a>02019       resultingPart.setBodyEncodedBinary( mainStr );
<a name="l02020"></a>02020     }
<a name="l02021"></a>02021 
<a name="l02022"></a>02022   } <span class="keywordflow">else</span> { <span class="comment">//  not making a mime object, build a plain message body.</span>
<a name="l02023"></a>02023 
<a name="l02024"></a>02024     resultingPart.setContentDescription( contentDescClear );
<a name="l02025"></a>02025     resultingPart.setTypeStr( contentTypeClear );
<a name="l02026"></a>02026     resultingPart.setSubtypeStr( contentSubtypeClear );
<a name="l02027"></a>02027     resultingPart.setContentDisposition( contentDispClear );
<a name="l02028"></a>02028     resultingPart.setContentTransferEncodingStr( contentTEncClear );
<a name="l02029"></a>02029     QByteArray resultingBody;
<a name="l02030"></a>02030 
<a name="l02031"></a>02031     <span class="keywordflow">if</span> ( signing &amp;&amp; includeCleartextWhenSigning( format ) ) {
<a name="l02032"></a>02032       <span class="keywordflow">if</span>( !clearCStr.isEmpty() )
<a name="l02033"></a>02033         <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( resultingBody, clearCStr );
<a name="l02034"></a>02034     }
<a name="l02035"></a>02035     <span class="keywordflow">if</span> ( !ciphertext.isEmpty() )
<a name="l02036"></a>02036       <a class="code" href="namespaceKMail_1_1Util.html#fe88142bebcaf57181c661999f9a0d17" title="Append a bytearray to a bytearray.">KMail::Util::append</a>( resultingBody, ciphertext );
<a name="l02037"></a>02037     <span class="keywordflow">else</span> {
<a name="l02038"></a>02038       <span class="comment">// Plugin error!</span>
<a name="l02039"></a>02039       KMessageBox::sorry( mComposeWin,
<a name="l02040"></a>02040                           i18n( <span class="stringliteral">"&lt;qt&gt;&lt;p&gt;Error: The backend did not return "</span>
<a name="l02041"></a>02041                                 <span class="stringliteral">"any encoded data.&lt;/p&gt;"</span>
<a name="l02042"></a>02042                                 <span class="stringliteral">"&lt;p&gt;Please report this bug:&lt;br&gt;%2&lt;/p&gt;&lt;/qt&gt;"</span> )
<a name="l02043"></a>02043                           .arg( bugURL ) );
<a name="l02044"></a>02044       bOk = <span class="keyword">false</span>;
<a name="l02045"></a>02045     }
<a name="l02046"></a>02046     resultingPart.setBodyEncodedBinary( resultingBody );
<a name="l02047"></a>02047   }
<a name="l02048"></a>02048 
<a name="l02049"></a>02049   <span class="keywordflow">return</span> bOk;
<a name="l02050"></a>02050 }
<a name="l02051"></a>02051 
<a name="l02052"></a>02052 <span class="comment">//-----------------------------------------------------------------------------</span>
<a name="l02053"></a>02053 QCString MessageComposer::plainTextFromMarkup( <span class="keyword">const</span> QString&amp; markupText )
<a name="l02054"></a>02054 {
<a name="l02055"></a>02055   QTextEdit *hackConspiratorTextEdit = <span class="keyword">new</span> QTextEdit( markupText );
<a name="l02056"></a>02056   hackConspiratorTextEdit-&gt;setTextFormat(Qt::PlainText);
<a name="l02057"></a>02057   <span class="keywordflow">if</span> ( !mDisableBreaking ) {
<a name="l02058"></a>02058     hackConspiratorTextEdit-&gt;setWordWrap( QTextEdit::FixedColumnWidth );
<a name="l02059"></a>02059     hackConspiratorTextEdit-&gt;setWrapColumnOrWidth( mLineBreakColumn );
<a name="l02060"></a>02060   }
<a name="l02061"></a>02061   QString text = hackConspiratorTextEdit-&gt;text();
<a name="l02062"></a>02062   QCString textbody;
<a name="l02063"></a>02063 
<a name="l02064"></a>02064   <span class="keyword">const</span> QTextCodec *codec = KMMsgBase::codecForName( mCharset );
<a name="l02065"></a>02065   <span class="keywordflow">if</span>( mCharset == <span class="stringliteral">"us-ascii"</span> ) {
<a name="l02066"></a>02066     textbody = KMMsgBase::toUsAscii( text );
<a name="l02067"></a>02067   } <span class="keywordflow">else</span> <span class="keywordflow">if</span>( codec == 0 ) {
<a name="l02068"></a>02068     kdDebug(5006) &lt;&lt; <span class="stringliteral">"Something is wrong and I can not get a codec."</span> &lt;&lt; endl;
<a name="l02069"></a>02069     textbody = text.local8Bit();
<a name="l02070"></a>02070   } <span class="keywordflow">else</span> {
<a name="l02071"></a>02071     text = codec-&gt;toUnicode( text.latin1(), text.length() );
<a name="l02072"></a>02072     textbody = codec-&gt;fromUnicode( text );
<a name="l02073"></a>02073   }
<a name="l02074"></a>02074   <span class="keywordflow">if</span> (textbody.isNull()) textbody = <span class="stringliteral">""</span>;
<a name="l02075"></a>02075 
<a name="l02076"></a>02076   <span class="keyword">delete</span> hackConspiratorTextEdit;
<a name="l02077"></a>02077   <span class="keywordflow">return</span> textbody;
<a name="l02078"></a>02078 }
<a name="l02079"></a>02079 
<a name="l02080"></a>02080 <span class="comment">//-----------------------------------------------------------------------------</span>
<a name="l02081"></a>02081 QByteArray MessageComposer::breakLinesAndApplyCodec()
<a name="l02082"></a>02082 {
<a name="l02083"></a>02083   QString text;
<a name="l02084"></a>02084   QCString cText;
<a name="l02085"></a>02085 
<a name="l02086"></a>02086   <span class="keywordflow">if</span>( mDisableBreaking || mIsRichText || !GlobalSettings::self()-&gt;wordWrap() )
<a name="l02087"></a>02087     text = mComposeWin-&gt;mEditor-&gt;text();
<a name="l02088"></a>02088   <span class="keywordflow">else</span>
<a name="l02089"></a>02089     text = mComposeWin-&gt;mEditor-&gt;brokenText();
<a name="l02090"></a>02090   text.truncate( text.length() ); <span class="comment">// to ensure text.size()==text.length()+1</span>
<a name="l02091"></a>02091 
<a name="l02092"></a>02092   QString newText;
<a name="l02093"></a>02093   <span class="keyword">const</span> QTextCodec *codec = KMMsgBase::codecForName( mCharset );
<a name="l02094"></a>02094 
<a name="l02095"></a>02095   <span class="keywordflow">if</span>( mCharset == <span class="stringliteral">"us-ascii"</span> ) {
<a name="l02096"></a>02096     cText = KMMsgBase::toUsAscii( text );
<a name="l02097"></a>02097     newText = QString::fromLatin1( cText );
<a name="l02098"></a>02098   } <span class="keywordflow">else</span> <span class="keywordflow">if</span>( codec == 0 ) {
<a name="l02099"></a>02099     kdDebug(5006) &lt;&lt; <span class="stringliteral">"Something is wrong and I can not get a codec."</span> &lt;&lt; endl;
<a name="l02100"></a>02100     cText = text.local8Bit();
<a name="l02101"></a>02101     newText = QString::fromLocal8Bit( cText );
<a name="l02102"></a>02102   } <span class="keywordflow">else</span> {
<a name="l02103"></a>02103     cText = codec-&gt;fromUnicode( text );
<a name="l02104"></a>02104     newText = codec-&gt;toUnicode( cText );
<a name="l02105"></a>02105   }
<a name="l02106"></a>02106   <span class="keywordflow">if</span> (cText.isNull()) cText = <span class="stringliteral">""</span>;
<a name="l02107"></a>02107 
<a name="l02108"></a>02108   <span class="keywordflow">if</span>( !text.isEmpty() &amp;&amp; (newText != text) ) {
<a name="l02109"></a>02109     QString oldText = mComposeWin-&gt;mEditor-&gt;text();
<a name="l02110"></a>02110     mComposeWin-&gt;mEditor-&gt;setText( newText );
<a name="l02111"></a>02111     <a class="code" href="classKCursorSaver.html" title="sets a cursor and makes sure it&amp;#39;s restored on destruction Create a KCursorSaver...">KCursorSaver</a> idle( KBusyPtr::idle() );
<a name="l02112"></a>02112     <span class="keywordtype">bool</span> anyway = ( KMessageBox::warningYesNo( mComposeWin,
<a name="l02113"></a>02113                                                i18n(<span class="stringliteral">"&lt;qt&gt;Not all characters fit into the chosen"</span>
<a name="l02114"></a>02114                                                     <span class="stringliteral">" encoding.&lt;br&gt;&lt;br&gt;Send the message anyway?&lt;/qt&gt;"</span>),
<a name="l02115"></a>02115                                                i18n(<span class="stringliteral">"Some Characters Will Be Lost"</span>),
<a name="l02116"></a>02116                                                i18n(<span class="stringliteral">"Lose Characters"</span>), i18n(<span class="stringliteral">"Change Encoding"</span>) ) == KMessageBox::Yes );
<a name="l02117"></a>02117     <span class="keywordflow">if</span>( !anyway ) {
<a name="l02118"></a>02118       mComposeWin-&gt;mEditor-&gt;setText(oldText);
<a name="l02119"></a>02119       <span class="keywordflow">return</span> QByteArray();
<a name="l02120"></a>02120     }
<a name="l02121"></a>02121   }
<a name="l02122"></a>02122 
<a name="l02123"></a>02123   <span class="comment">// From RFC 3156:</span>
<a name="l02124"></a>02124   <span class="comment">//  Note: The accepted OpenPGP convention is for signed data to end</span>
<a name="l02125"></a>02125   <span class="comment">//  with a &lt;CR&gt;&lt;LF&gt; sequence.  Note that the &lt;CR&gt;&lt;LF&gt; sequence</span>
<a name="l02126"></a>02126   <span class="comment">//  immediately preceding a MIME boundary delimiter line is considered</span>
<a name="l02127"></a>02127   <span class="comment">//  to be part of the delimiter in [3], 5.1.  Thus, it is not part of</span>
<a name="l02128"></a>02128   <span class="comment">//  the signed data preceding the delimiter line.  An implementation</span>
<a name="l02129"></a>02129   <span class="comment">//  which elects to adhere to the OpenPGP convention has to make sure</span>
<a name="l02130"></a>02130   <span class="comment">//  it inserts a &lt;CR&gt;&lt;LF&gt; pair on the last line of the data to be</span>
<a name="l02131"></a>02131   <span class="comment">//  signed and transmitted (signed message and transmitted message</span>
<a name="l02132"></a>02132   <span class="comment">//  MUST be identical).</span>
<a name="l02133"></a>02133   <span class="comment">// So make sure that the body ends with a &lt;LF&gt;.</span>
<a name="l02134"></a>02134   <span class="keywordflow">if</span>( cText.isEmpty() || cText[cText.length()-1] != <span class="charliteral">'\n'</span> ) {
<a name="l02135"></a>02135     kdDebug(5006) &lt;&lt; <span class="stringliteral">"Added an &lt;LF&gt; on the last line"</span> &lt;&lt; endl;
<a name="l02136"></a>02136     cText += <span class="stringliteral">"\n"</span>;
<a name="l02137"></a>02137   }
<a name="l02138"></a>02138   <span class="keywordflow">return</span> <a class="code" href="namespaceKMail_1_1Util.html#33f363b5d85de8e69053310d3015744c" title="Creates a QByteArray from a QCString without detaching (duplicating the data).">KMail::Util::byteArrayFromQCStringNoDetach</a>( cText );
<a name="l02139"></a>02139 }
<a name="l02140"></a>02140 
<a name="l02141"></a>02141 
<a name="l02142"></a>02142 <span class="comment">//-----------------------------------------------------------------------------</span>
<a name="l02143"></a>02143 <span class="keywordtype">void</span> MessageComposer::pgpSignedMsg( <span class="keyword">const</span> QByteArray&amp; cText, Kleo::CryptoMessageFormat format ) {
<a name="l02144"></a>02144 
<a name="l02145"></a>02145   assert( cText.isEmpty() || cText[cText.size()-1] != <span class="charliteral">'\0'</span> ); <span class="comment">// I was called with a QCString !?</span>
<a name="l02146"></a>02146   mSignature = QByteArray();
<a name="l02147"></a>02147 
<a name="l02148"></a>02148   <span class="keyword">const</span> std::vector&lt;GpgME::Key&gt; signingKeys = mKeyResolver-&gt;signingKeys( format );
<a name="l02149"></a>02149 
<a name="l02150"></a>02150   assert( !signingKeys.empty() );
<a name="l02151"></a>02151 
<a name="l02152"></a>02152   <span class="comment">// TODO: ASync call? Likely, yes :-)</span>
<a name="l02153"></a>02153   <span class="keyword">const</span> Kleo::CryptoBackendFactory * cpf = Kleo::CryptoBackendFactory::instance();
<a name="l02154"></a>02154   assert( cpf );
<a name="l02155"></a>02155   <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * proto
<a name="l02156"></a>02156     = isSMIME( format ) ? cpf-&gt;smime() : cpf-&gt;openpgp() ;
<a name="l02157"></a>02157   assert( proto ); 
<a name="l02158"></a>02158 
<a name="l02159"></a>02159   std::auto_ptr&lt;Kleo::SignJob&gt; job( proto-&gt;signJob( armor( format ),
<a name="l02160"></a>02160                             textMode( format ) ) );
<a name="l02161"></a>02161 
<a name="l02162"></a>02162   <span class="keywordflow">if</span> ( !job.get() ) {
<a name="l02163"></a>02163     KMessageBox::sorry( mComposeWin,
<a name="l02164"></a>02164             i18n(<span class="stringliteral">"This message could not be signed, "</span>
<a name="l02165"></a>02165                  <span class="stringliteral">"since the chosen backend does not seem to support "</span>
<a name="l02166"></a>02166                  <span class="stringliteral">"signing; this should actually never happen, "</span>
<a name="l02167"></a>02167                  <span class="stringliteral">"please report this bug."</span>) );
<a name="l02168"></a>02168     <span class="keywordflow">return</span>;
<a name="l02169"></a>02169   }
<a name="l02170"></a>02170 
<a name="l02171"></a>02171   QByteArray signature;
<a name="l02172"></a>02172   <span class="keyword">const</span> GpgME::SigningResult res =
<a name="l02173"></a>02173     job-&gt;exec( signingKeys, cText, signingMode( format ), signature );
<a name="l02174"></a>02174   <span class="keywordflow">if</span> ( res.error().isCanceled() ) {
<a name="l02175"></a>02175     kdDebug() &lt;&lt; <span class="stringliteral">"signing was canceled by user"</span> &lt;&lt; endl;
<a name="l02176"></a>02176     <span class="keywordflow">return</span>;
<a name="l02177"></a>02177   }
<a name="l02178"></a>02178   <span class="keywordflow">if</span> ( res.error() ) {
<a name="l02179"></a>02179     kdDebug() &lt;&lt; <span class="stringliteral">"signing failed: "</span> &lt;&lt; res.error().asString() &lt;&lt; endl;
<a name="l02180"></a>02180     job-&gt;showErrorDialog( mComposeWin );
<a name="l02181"></a>02181     <span class="keywordflow">return</span>;
<a name="l02182"></a>02182   }
<a name="l02183"></a>02183 
<a name="l02184"></a>02184   <span class="keywordflow">if</span> ( GlobalSettings::showGnuPGAuditLogAfterSuccessfulSignEncrypt() )
<a name="l02185"></a>02185       Kleo::MessageBox::auditLog( 0, job.get(), i18n(<span class="stringliteral">"GnuPG Audit Log for Signing Operation"</span>) );
<a name="l02186"></a>02186 
<a name="l02187"></a>02187   mSignature = signature;
<a name="l02188"></a>02188   <span class="keywordflow">if</span> ( mSignature.isEmpty() ) {
<a name="l02189"></a>02189     KMessageBox::sorry( mComposeWin,
<a name="l02190"></a>02190                         i18n( <span class="stringliteral">"The signing operation failed. "</span>
<a name="l02191"></a>02191                               <span class="stringliteral">"Please make sure that the gpg-agent program "</span>
<a name="l02192"></a>02192                               <span class="stringliteral">"is running."</span> ) );
<a name="l02193"></a>02193   }
<a name="l02194"></a>02194 }
<a name="l02195"></a>02195 
<a name="l02196"></a>02196 <span class="comment">//-----------------------------------------------------------------------------</span>
<a name="l02197"></a>02197 Kpgp::Result MessageComposer::pgpEncryptedMsg( QByteArray &amp; encryptedBody,
<a name="l02198"></a>02198                                                <span class="keyword">const</span> QByteArray&amp; cText,
<a name="l02199"></a>02199                                                <span class="keyword">const</span> std::vector&lt;GpgME::Key&gt; &amp; encryptionKeys,
<a name="l02200"></a>02200                            Kleo::CryptoMessageFormat format )
<a name="l02201"></a>02201 {
<a name="l02202"></a>02202   <span class="comment">// TODO: ASync call? Likely, yes :-)</span>
<a name="l02203"></a>02203   <span class="keyword">const</span> Kleo::CryptoBackendFactory * cpf = Kleo::CryptoBackendFactory::instance();
<a name="l02204"></a>02204   assert( cpf );
<a name="l02205"></a>02205   <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * proto
<a name="l02206"></a>02206     = isSMIME( format ) ? cpf-&gt;smime() : cpf-&gt;openpgp() ;
<a name="l02207"></a>02207   assert( proto ); <span class="comment">// hmmmm....?</span>
<a name="l02208"></a>02208 
<a name="l02209"></a>02209   std::auto_ptr&lt;Kleo::EncryptJob&gt; job( proto-&gt;encryptJob( armor( format ),
<a name="l02210"></a>02210                                                           textMode( format ) ) );
<a name="l02211"></a>02211   <span class="keywordflow">if</span> ( !job.get() ) {
<a name="l02212"></a>02212     KMessageBox::sorry( mComposeWin,
<a name="l02213"></a>02213                         i18n(<span class="stringliteral">"This message could not be encrypted, "</span>
<a name="l02214"></a>02214                              <span class="stringliteral">"since the chosen backend does not seem to support "</span>
<a name="l02215"></a>02215                              <span class="stringliteral">"encryption; this should actually never happen, "</span>
<a name="l02216"></a>02216                              <span class="stringliteral">"please report this bug."</span>) );
<a name="l02217"></a>02217     <span class="keywordflow">return</span> Kpgp::Failure;
<a name="l02218"></a>02218   }
<a name="l02219"></a>02219 
<a name="l02220"></a>02220   <span class="keyword">const</span> GpgME::EncryptionResult res =
<a name="l02221"></a>02221     job-&gt;exec( encryptionKeys, cText, <span class="keyword">true</span> <span class="comment">/* we do ownertrust ourselves */</span>, encryptedBody );
<a name="l02222"></a>02222   <span class="keywordflow">if</span> ( res.error().isCanceled() ) {
<a name="l02223"></a>02223     kdDebug() &lt;&lt; <span class="stringliteral">"encryption was canceled by user"</span> &lt;&lt; endl;
<a name="l02224"></a>02224     <span class="keywordflow">return</span> Kpgp::Canceled;
<a name="l02225"></a>02225   }
<a name="l02226"></a>02226   <span class="keywordflow">if</span> ( res.error() ) {
<a name="l02227"></a>02227     kdDebug() &lt;&lt; <span class="stringliteral">"encryption failed: "</span> &lt;&lt; res.error().asString() &lt;&lt; endl;
<a name="l02228"></a>02228     job-&gt;showErrorDialog( mComposeWin );
<a name="l02229"></a>02229     <span class="keywordflow">return</span> Kpgp::Failure;
<a name="l02230"></a>02230   }
<a name="l02231"></a>02231 
<a name="l02232"></a>02232   <span class="keywordflow">if</span> ( GlobalSettings::showGnuPGAuditLogAfterSuccessfulSignEncrypt() )
<a name="l02233"></a>02233       Kleo::MessageBox::auditLog( 0, job.get(), i18n(<span class="stringliteral">"GnuPG Audit Log for Encryption Operation"</span>) );
<a name="l02234"></a>02234 
<a name="l02235"></a>02235   <span class="keywordflow">return</span> Kpgp::Ok;
<a name="l02236"></a>02236 }
<a name="l02237"></a>02237 
<a name="l02238"></a>02238 Kpgp::Result MessageComposer::pgpSignedAndEncryptedMsg( QByteArray &amp; encryptedBody,
<a name="l02239"></a>02239                             <span class="keyword">const</span> QByteArray&amp; cText,
<a name="l02240"></a>02240                             <span class="keyword">const</span> std::vector&lt;GpgME::Key&gt; &amp; signingKeys,
<a name="l02241"></a>02241                             <span class="keyword">const</span> std::vector&lt;GpgME::Key&gt; &amp; encryptionKeys,
<a name="l02242"></a>02242                             Kleo::CryptoMessageFormat format )
<a name="l02243"></a>02243 {
<a name="l02244"></a>02244   <span class="comment">// TODO: ASync call? Likely, yes :-)</span>
<a name="l02245"></a>02245   <span class="keyword">const</span> Kleo::CryptoBackendFactory * cpf = Kleo::CryptoBackendFactory::instance();
<a name="l02246"></a>02246   assert( cpf );
<a name="l02247"></a>02247   <span class="keyword">const</span> Kleo::CryptoBackend::Protocol * proto
<a name="l02248"></a>02248     = isSMIME( format ) ? cpf-&gt;smime() : cpf-&gt;openpgp() ;
<a name="l02249"></a>02249   assert( proto ); <span class="comment">// hmmmm....?</span>
<a name="l02250"></a>02250 
<a name="l02251"></a>02251   std::auto_ptr&lt;Kleo::SignEncryptJob&gt; job( proto-&gt;signEncryptJob( armor( format ),
<a name="l02252"></a>02252                                   textMode( format ) ) );
<a name="l02253"></a>02253   <span class="keywordflow">if</span> ( !job.get() ) {
<a name="l02254"></a>02254     KMessageBox::sorry( mComposeWin,
<a name="l02255"></a>02255             i18n(<span class="stringliteral">"This message could not be signed and encrypted, "</span>
<a name="l02256"></a>02256                  <span class="stringliteral">"since the chosen backend does not seem to support "</span>
<a name="l02257"></a>02257                  <span class="stringliteral">"combined signing and encryption; this should actually never happen, "</span>
<a name="l02258"></a>02258                  <span class="stringliteral">"please report this bug."</span>) );
<a name="l02259"></a>02259     <span class="keywordflow">return</span> Kpgp::Failure;
<a name="l02260"></a>02260   }
<a name="l02261"></a>02261 
<a name="l02262"></a>02262   <span class="keyword">const</span> std::pair&lt;GpgME::SigningResult,GpgME::EncryptionResult&gt; res =
<a name="l02263"></a>02263     job-&gt;exec( signingKeys, encryptionKeys, cText, <span class="keyword">false</span>, encryptedBody );
<a name="l02264"></a>02264   <span class="keywordflow">if</span> ( res.first.error().isCanceled() || res.second.error().isCanceled() ) {
<a name="l02265"></a>02265     kdDebug() &lt;&lt; <span class="stringliteral">"encrypt/sign was canceled by user"</span> &lt;&lt; endl;
<a name="l02266"></a>02266     <span class="keywordflow">return</span> Kpgp::Canceled;
<a name="l02267"></a>02267   }
<a name="l02268"></a>02268   <span class="keywordflow">if</span> ( res.first.error() || res.second.error() ) {
<a name="l02269"></a>02269     <span class="keywordflow">if</span> ( res.first.error() )
<a name="l02270"></a>02270       kdDebug() &lt;&lt; <span class="stringliteral">"signing failed: "</span> &lt;&lt; res.first.error().asString() &lt;&lt; endl;
<a name="l02271"></a>02271     <span class="keywordflow">else</span>
<a name="l02272"></a>02272       kdDebug() &lt;&lt; <span class="stringliteral">"encryption failed: "</span> &lt;&lt; res.second.error().asString() &lt;&lt; endl;
<a name="l02273"></a>02273     job-&gt;showErrorDialog( mComposeWin );
<a name="l02274"></a>02274     <span class="keywordflow">return</span> Kpgp::Failure;
<a name="l02275"></a>02275   }
<a name="l02276"></a>02276 
<a name="l02277"></a>02277   <span class="keywordflow">if</span> ( GlobalSettings::showGnuPGAuditLogAfterSuccessfulSignEncrypt() )
<a name="l02278"></a>02278       Kleo::MessageBox::auditLog( 0, job.get(), i18n(<span class="stringliteral">"GnuPG Audit Log for Encryption Operation"</span>) );
<a name="l02279"></a>02279 
<a name="l02280"></a>02280   <span class="keywordflow">return</span> Kpgp::Ok;
<a name="l02281"></a>02281 }
<a name="l02282"></a>02282 
<a name="l02283"></a>02283 
<a name="l02284"></a>02284 <span class="preprocessor">#include "messagecomposer.moc"</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>