Better wording
[kdepim.git] / kleopatra / uiserver / encryptcommand.cpp
blobb4774aba7efccab49d095877c849cc2253ab96b3
1 /* -*- mode: c++; c-basic-offset:4 -*-
2 uiserver/encryptcommand.cpp
4 This file is part of Kleopatra, the KDE keymanager
5 Copyright (c) 2007 Klarälvdalens Datakonsult AB
7 Kleopatra is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 Kleopatra is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 In addition, as a special exception, the copyright holders give
22 permission to link the code of this program with any edition of
23 the Qt library by Trolltech AS, Norway (or with modified versions
24 of Qt that use the same license as Qt), and distribute linked
25 combinations including the two. You must obey the GNU General
26 Public License in all respects for all of the code used other than
27 Qt. If you modify this file, you may extend this exception to
28 your version of the file, but you are not obligated to do so. If
29 you do not wish to do so, delete this exception statement from
30 your version.
33 #include <config-kleopatra.h>
35 #include "encryptcommand.h"
37 #include <crypto/newsignencryptemailcontroller.h>
39 #include <utils/kleo_assert.h>
40 #include <utils/input.h>
41 #include <utils/output.h>
43 #include <kleo/exception.h>
45 #include <KLocale>
47 #include <QTimer>
49 using namespace Kleo;
50 using namespace Kleo::Crypto;
51 using namespace boost;
53 class EncryptCommand::Private : public QObject {
54 Q_OBJECT
55 private:
56 friend class ::Kleo::EncryptCommand;
57 EncryptCommand * const q;
58 public:
59 explicit Private( EncryptCommand * qq )
60 : q( qq ),
61 controller()
66 private:
67 void checkForErrors() const;
69 private Q_SLOTS:
70 void slotDone();
71 void slotError( int, const QString & );
72 void slotRecipientsResolved();
74 private:
75 shared_ptr<NewSignEncryptEMailController> controller;
78 EncryptCommand::EncryptCommand()
79 : AssuanCommandMixin<EncryptCommand>(), d( new Private( this ) )
84 EncryptCommand::~EncryptCommand() {}
86 void EncryptCommand::Private::checkForErrors() const {
88 if ( q->numFiles() )
89 throw Exception( makeError( GPG_ERR_CONFLICT ),
90 i18n( "ENCRYPT is an email mode command, connection seems to be in filmanager mode" ) );
92 if ( !q->senders().empty() && !q->informativeSenders() )
93 throw Exception( makeError( GPG_ERR_CONFLICT ),
94 i18n( "SENDER may not be given prior to ENCRYPT, except with --info" ) );
96 if ( q->inputs().empty() )
97 throw Exception( makeError( GPG_ERR_ASS_NO_INPUT ),
98 i18n( "At least one INPUT must be present" ) );
100 if ( q->outputs().empty() )
101 throw Exception( makeError( GPG_ERR_ASS_NO_OUTPUT ),
102 i18n( "At least one OUTPUT must be present" ) );
104 if ( q->outputs().size() != q->inputs().size() )
105 throw Exception( makeError( GPG_ERR_CONFLICT ),
106 i18n( "INPUT/OUTPUT count mismatch" ) );
108 if ( !q->messages().empty() )
109 throw Exception( makeError( GPG_ERR_INV_VALUE ),
110 i18n( "MESSAGE command is not allowed before ENCRYPT" ) );
112 const shared_ptr<NewSignEncryptEMailController> m = q->mementoContent< shared_ptr<NewSignEncryptEMailController> >( NewSignEncryptEMailController::mementoName() );
113 kleo_assert( m );
115 if ( m && m->isEncrypting() ) {
117 if ( m->protocol() != q->checkProtocol( EMail ) )
118 throw Exception( makeError( GPG_ERR_CONFLICT ),
119 i18n( "Protocol given conflicts with protocol determined by PREP_ENCRYPT" ) );
121 if ( !q->recipients().empty() )
122 throw Exception( makeError( GPG_ERR_CONFLICT ),
123 i18n( "New recipients added after PREP_ENCRYPT command" ) );
124 if ( !q->senders().empty() )
125 throw Exception( makeError( GPG_ERR_CONFLICT ),
126 i18n( "New senders added after PREP_ENCRYPT command" ) );
128 } else {
130 if ( q->recipients().empty() || q->informativeRecipients() )
131 throw Exception( makeError( GPG_ERR_MISSING_VALUE ),
132 i18n( "No recipients given, or only with --info" ) );
138 static void connectController( const QObject * controller, const QObject * d ) {
140 QObject::connect( controller, SIGNAL(certificatesResolved()), d, SLOT(slotRecipientsResolved()) );
141 QObject::connect( controller, SIGNAL(done()), d, SLOT(slotDone()) );
142 QObject::connect( controller, SIGNAL(error(int,QString)), d, SLOT(slotError(int,QString)) );
146 int EncryptCommand::doStart() {
148 d->checkForErrors();
150 const shared_ptr<NewSignEncryptEMailController> seec = mementoContent< shared_ptr<NewSignEncryptEMailController> >( NewSignEncryptEMailController::mementoName() );
152 if ( seec && seec->isEncrypting() ) {
153 // reuse the controller from a previous PREP_ENCRYPT, if available:
154 d->controller = seec;
155 connectController( seec.get(), d.get() );
156 removeMemento( NewSignEncryptEMailController::mementoName() );
157 d->controller->setExecutionContext( shared_from_this() );
158 if ( seec->areCertificatesResolved() )
159 QTimer::singleShot( 0, d.get(), SLOT(slotRecipientsResolved()) );
160 else
161 kleo_assert( seec->isResolvingInProgress() );
162 } else {
163 // use a new controller
164 d->controller.reset( new NewSignEncryptEMailController( shared_from_this() ) );
166 const QString session = sessionTitle();
167 if ( !session.isEmpty() )
168 d->controller->setSubject( session );
170 d->controller->setEncrypting( true );
171 d->controller->setSigning( false );
172 d->controller->setProtocol( checkProtocol( EMail ) );
173 connectController( d->controller.get(), d.get() );
174 d->controller->startResolveCertificates( recipients(), senders() );
178 return 0;
181 void EncryptCommand::Private::slotRecipientsResolved() {
182 //hold local shared_ptr to member as q->done() deletes *this
183 const shared_ptr<NewSignEncryptEMailController> cont( controller );
185 try {
186 const QString sessionTitle = q->sessionTitle();
187 if ( !sessionTitle.isEmpty() )
188 Q_FOREACH ( const shared_ptr<Input> & i, q->inputs() )
189 i->setLabel( sessionTitle );
191 cont->startEncryption( q->inputs(), q->outputs() );
193 return;
195 } catch ( const Exception & e ) {
196 q->done( e.error(), e.message() );
197 } catch ( const std::exception & e ) {
198 q->done( makeError( GPG_ERR_UNEXPECTED ),
199 i18n("Caught unexpected exception in EncryptCommand::Private::slotRecipientsResolved: %1",
200 QString::fromLocal8Bit( e.what() ) ) );
201 } catch ( ... ) {
202 q->done( makeError( GPG_ERR_UNEXPECTED ),
203 i18n("Caught unknown exception in EncryptCommand::Private::slotRecipientsResolved") );
205 cont->cancel();
208 void EncryptCommand::Private::slotDone() {
209 q->done();
212 void EncryptCommand::Private::slotError( int err, const QString & details ) {
213 q->done( err, details );
216 void EncryptCommand::doCanceled() {
217 if ( d->controller )
218 d->controller->cancel();
221 #include "encryptcommand.moc"