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

kleopatra

  • sources
  • kde-4.14
  • kdepim
  • kleopatra
  • commands
importcertificatescommand.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  commands/importcertificatescommand.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2007, 2008 Klarälvdalens Datakonsult AB
6 
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.
11 
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.
16 
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
20 
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.
31 */
32 
33 #include <config-kleopatra.h>
34 
35 #include "importcertificatescommand.h"
36 #include "importcertificatescommand_p.h"
37 
38 #include <models/keylistsortfilterproxymodel.h>
39 #include <models/predicates.h>
40 
41 #include <utils/formatting.h>
42 
43 #include <kleo/stl_util.h>
44 #include <kleo/cryptobackendfactory.h>
45 #include <kleo/importjob.h>
46 #include <kleo/importfromkeyserverjob.h>
47 
48 #include <gpgme++/global.h>
49 #include <gpgme++/importresult.h>
50 
51 #include <KLocalizedString>
52 #include <KMessageBox>
53 #include <KDebug>
54 
55 #include <QByteArray>
56 #include <QFile>
57 #include <QString>
58 #include <QWidget>
59 #include <QTreeView>
60 #include <QTextDocument> // for Qt::escape
61 
62 #ifndef Q_MOC_RUN
63 #include <boost/bind.hpp>
64 #include <boost/mem_fn.hpp>
65 #endif
66 
67 #include <memory>
68 #include <algorithm>
69 #include <cassert>
70 #include <map>
71 #include <set>
72 
73 using namespace GpgME;
74 using namespace Kleo;
75 using namespace boost;
76 
77 namespace {
78 
79  make_comparator_str( ByImportFingerprint, .fingerprint() );
80 
81  class ImportResultProxyModel : public AbstractKeyListSortFilterProxyModel {
82  Q_OBJECT
83  public:
84  ImportResultProxyModel( const std::vector<ImportResult> & results, const QStringList & ids, QObject * parent=0 )
85  : AbstractKeyListSortFilterProxyModel( parent )
86  {
87  updateFindCache( results, ids );
88  }
89 
90  ~ImportResultProxyModel() {}
91 
92  /* reimp */ ImportResultProxyModel * clone() const {
93  // compiler-generated copy ctor is fine!
94  return new ImportResultProxyModel( *this );
95  }
96 
97  void setImportResults( const std::vector<ImportResult> & results, const QStringList & ids ) {
98  updateFindCache( results, ids );
99  invalidateFilter();
100  }
101 
102  protected:
103  /* reimp */ QVariant data( const QModelIndex & index, int role ) const {
104  if ( !index.isValid() || role != Qt::ToolTipRole )
105  return AbstractKeyListSortFilterProxyModel::data( index, role );
106  const QString fpr = index.data( FingerprintRole ).toString();
107  // find information:
108  const std::vector<Import>::const_iterator it
109  = qBinaryFind( m_importsByFingerprint.begin(), m_importsByFingerprint.end(),
110  fpr.toLatin1().constData(),
111  ByImportFingerprint<std::less>() );
112  if ( it == m_importsByFingerprint.end() )
113  return AbstractKeyListSortFilterProxyModel::data( index, role );
114  else
115  return Formatting::importMetaData( *it, kdtools::copy<QStringList>( m_idsByFingerprint[it->fingerprint()] ) );
116  }
117  /* reimp */ bool filterAcceptsRow( int source_row, const QModelIndex & source_parent ) const {
118  //
119  // 0. Keep parents of matching children:
120  //
121  const QModelIndex index = sourceModel()->index( source_row, 0, source_parent );
122  assert( index.isValid() );
123  for ( int i = 0, end = sourceModel()->rowCount( index ) ; i != end ; ++i )
124  if ( filterAcceptsRow( i, index ) )
125  return true;
126  //
127  // 1. Check that this is an imported key:
128  //
129  const QString fpr = index.data( FingerprintRole ).toString();
130 
131  return std::binary_search( m_importsByFingerprint.begin(), m_importsByFingerprint.end(),
132  fpr.toLatin1().constData(),
133  ByImportFingerprint<std::less>() );
134  }
135 
136  private:
137  void updateFindCache( const std::vector<ImportResult> & results, const QStringList & ids ) {
138  assert( results.size() == static_cast<unsigned>( ids.size() ) );
139  m_importsByFingerprint.clear();
140  m_idsByFingerprint.clear();
141  m_results = results;
142  for ( unsigned int i = 0, end = results.size() ; i != end ; ++i ) {
143  const std::vector<Import> imports = results[i].imports();
144  m_importsByFingerprint.insert( m_importsByFingerprint.end(), imports.begin(), imports.end() );
145  const QString & id = ids[i];
146  for ( std::vector<Import>::const_iterator it = imports.begin(), end = imports.end() ; it != end ; ++it ) {
147  m_idsByFingerprint[it->fingerprint()].insert( id );
148  }
149  }
150  std::sort( m_importsByFingerprint.begin(), m_importsByFingerprint.end(),
151  ByImportFingerprint<std::less>() );
152  }
153 
154  private:
155  mutable std::vector<Import> m_importsByFingerprint;
156  mutable std::map< const char*, std::set<QString>, ByImportFingerprint<std::less> > m_idsByFingerprint;
157  std::vector<ImportResult> m_results;
158  };
159 
160 }
161 
162 ImportCertificatesCommand::Private::Private( ImportCertificatesCommand * qq, KeyListController * c )
163  : Command::Private( qq, c ),
164  waitForMoreJobs( false ),
165  nonWorkingProtocols(),
166  idsByJob(),
167  jobs(),
168  results(),
169  ids()
170 {
171 
172 }
173 
174 ImportCertificatesCommand::Private::~Private() {}
175 
176 #define d d_func()
177 #define q q_func()
178 
179 
180 ImportCertificatesCommand::ImportCertificatesCommand( KeyListController * p )
181  : Command( new Private( this, p ) )
182 {
183 
184 }
185 
186 ImportCertificatesCommand::ImportCertificatesCommand( QAbstractItemView * v, KeyListController * p )
187  : Command( v, new Private( this, p ) )
188 {
189 
190 }
191 
192 ImportCertificatesCommand::~ImportCertificatesCommand() {}
193 
194 static QString format_ids( const QStringList & ids ) {
195  return kdtools::transform_if<QStringList>( ids, Qt::escape, !boost::bind( &QString::isEmpty, _1 ) ).join( QLatin1String("<br>") );
196 }
197 
198 static QString make_tooltip( const QStringList & ids ) {
199  if ( ids.empty() )
200  return QString();
201  if ( ids.size() == 1 )
202  if ( ids.front().isEmpty() )
203  return QString();
204  else
205  return i18nc( "@info:tooltip",
206  "Imported Certificates from %1",
207  Qt::escape( ids.front() ) );
208  else
209  return i18nc( "@info:tooltip",
210  "Imported certificates from these sources:<br/>%1",
211  format_ids( ids ) );
212 }
213 
214 void ImportCertificatesCommand::Private::setImportResultProxyModel( const std::vector<ImportResult> & results, const QStringList & ids ) {
215  if ( kdtools::none_of( results, mem_fn( &ImportResult::numConsidered ) ) )
216  return;
217  q->addTemporaryView( i18nc("@title:tab", "Imported Certificates"),
218  new ImportResultProxyModel( results, ids ),
219  make_tooltip( ids ) );
220  if ( QTreeView * const tv = qobject_cast<QTreeView*>( parentWidgetOrView() ) )
221  tv->expandAll();
222 }
223 
224 int sum( const std::vector<ImportResult> & res, int (ImportResult::*fun)() const ) {
225  return kdtools::accumulate_transform( res.begin(), res.end(), mem_fn( fun ), 0 );
226 }
227 
228 static QString make_report( const std::vector<ImportResult> & res, const QString & id=QString() ) {
229 
230  const KLocalizedString normalLine = ki18n("<tr><td align=\"right\">%1</td><td>%2</td></tr>");
231  const KLocalizedString boldLine = ki18n("<tr><td align=\"right\"><b>%1</b></td><td>%2</td></tr>");
232  const KLocalizedString headerLine = ki18n("<tr><th colspan=\"2\" align=\"center\">%1</th></tr>");
233 
234 #define SUM( x ) sum( res, &ImportResult::x )
235 
236  QStringList lines;
237  if ( !id.isEmpty() )
238  lines.push_back( headerLine.subs( id ).toString() );
239  lines.push_back( normalLine.subs( i18n("Total number processed:") )
240  .subs( SUM(numConsidered) ).toString() );
241  lines.push_back( normalLine.subs( i18n("Imported:") )
242  .subs( SUM(numImported) ).toString() );
243  if ( const int n = SUM(newSignatures) )
244  lines.push_back( normalLine.subs( i18n("New signatures:") )
245  .subs( n ).toString() );
246  if ( const int n = SUM(newUserIDs) )
247  lines.push_back( normalLine.subs( i18n("New user IDs:") )
248  .subs( n ).toString() );
249  if ( const int n = SUM(numKeysWithoutUserID) )
250  lines.push_back( normalLine.subs( i18n("Certificates without user IDs:") )
251  .subs( n ).toString() );
252  if ( const int n = SUM(newSubkeys) )
253  lines.push_back( normalLine.subs( i18n("New subkeys:") )
254  .subs( n ).toString() );
255  if ( const int n = SUM(newRevocations) )
256  lines.push_back( boldLine.subs( i18n("Newly revoked:") )
257  .subs( n ).toString() );
258  if ( const int n = SUM(notImported) )
259  lines.push_back( boldLine.subs( i18n("Not imported:") )
260  .subs( n ).toString() );
261  if ( const int n = SUM(numUnchanged) )
262  lines.push_back( normalLine.subs( i18n("Unchanged:") )
263  .subs( n ).toString() );
264  if ( const int n = SUM(numSecretKeysConsidered) )
265  lines.push_back( normalLine.subs( i18n("Secret keys processed:") )
266  .subs( n ).toString() );
267  if ( const int n = SUM(numSecretKeysImported) )
268  lines.push_back( normalLine.subs( i18n("Secret keys imported:") )
269  .subs( n ).toString() );
270  if ( const int n = SUM(numSecretKeysConsidered) - SUM(numSecretKeysImported) - SUM(numSecretKeysUnchanged) )
271  if ( n > 0 )
272  lines.push_back( boldLine.subs( i18n("Secret keys <em>not</em> imported:") )
273  .subs( n ).toString() );
274  if ( const int n = SUM(numSecretKeysUnchanged) )
275  lines.push_back( normalLine.subs( i18n("Secret keys unchanged:") )
276  .subs( n ).toString() );
277 
278 #undef sum
279 
280  return lines.join( QString() );
281 }
282 
283 static QString make_message_report( const std::vector<ImportResult> & res, const QStringList & ids ) {
284 
285  assert( res.size() == static_cast<unsigned>( ids.size() ) );
286 
287  if ( res.empty() )
288  return i18n( "No imports (should not happen, please report a bug)." );
289 
290  if ( res.size() == 1 )
291  return ids.front().isEmpty()
292  ? i18n( "<qt><p>Detailed results of certificate import:</p>"
293  "<table width=\"100%\">%1</table></qt>", make_report( res ) )
294  : i18n( "<qt><p>Detailed results of importing %1:</p>"
295  "<table width=\"100%\">%2</table></qt>", ids.front(), make_report( res ) );
296 
297  return i18n( "<qt><p>Detailed results of certificate import:</p>"
298  "<table width=\"100%\">%1</table></qt>", make_report( res, i18n("Totals") ) );
299 }
300 
301 void ImportCertificatesCommand::Private::showDetails( QWidget * parent, const std::vector<ImportResult> & res, const QStringList & ids ) {
302  if ( parent ) {
303  setImportResultProxyModel( res, ids );
304  KMessageBox::information( parent, make_message_report( res, ids ), i18n( "Certificate Import Result" ) );
305  } else {
306  showDetails( res, ids );
307  }
308 }
309 
310 void ImportCertificatesCommand::Private::showDetails( const std::vector<ImportResult> & res, const QStringList & ids ) {
311  setImportResultProxyModel( res, ids );
312  information( make_message_report( res, ids ), i18n( "Certificate Import Result" ) );
313 }
314 
315 static QString make_error_message( const Error & err, const QString & id ) {
316  assert( err );
317  assert( !err.isCanceled() );
318  return id.isEmpty()
319  ? i18n( "<qt><p>An error occurred while trying "
320  "to import the certificate:</p>"
321  "<p><b>%1</b></p></qt>",
322  QString::fromLocal8Bit( err.asString() ) )
323  : i18n( "<qt><p>An error occurred while trying "
324  "to import the certificate %1:</p>"
325  "<p><b>%2</b></p></qt>",
326  id, QString::fromLocal8Bit( err.asString() ) );
327 }
328 
329 void ImportCertificatesCommand::Private::showError( QWidget * parent, const Error & err, const QString & id ) {
330  if ( parent )
331  KMessageBox::error( parent, make_error_message( err, id ), i18n( "Certificate Import Failed" ) );
332  else
333  showError( err, id );
334 }
335 
336 void ImportCertificatesCommand::Private::showError( const Error & err, const QString & id ) {
337  error( make_error_message( err, id ), i18n( "Certificate Import Failed" ) );
338 }
339 
340 void ImportCertificatesCommand::Private::setWaitForMoreJobs( bool wait ) {
341  if ( wait == waitForMoreJobs )
342  return;
343  waitForMoreJobs = wait;
344  tryToFinish();
345 }
346 
347 void ImportCertificatesCommand::Private::importResult( const ImportResult & result ) {
348 
349  jobs.erase( std::remove( jobs.begin(), jobs.end(), q->sender() ), jobs.end() );
350 
351  importResult( result, idsByJob[q->sender()] );
352 }
353 
354 void ImportCertificatesCommand::Private::importResult( const ImportResult & result, const QString & id ) {
355 
356  results.push_back( result );
357  ids.push_back( id );
358 
359  tryToFinish();
360 }
361 
362 void ImportCertificatesCommand::Private::tryToFinish() {
363 
364  if ( waitForMoreJobs || !jobs.empty() )
365  return;
366 
367  if ( kdtools::any( results, boost::bind( &Error::code, boost::bind( &ImportResult::error, _1 ) ) ) ) {
368  setImportResultProxyModel( results, ids );
369  if ( kdtools::all( results, boost::bind( &Error::isCanceled, boost::bind( &ImportResult::error, _1 ) ) ) )
370  emit q->canceled();
371  else
372  for ( unsigned int i = 0, end = results.size() ; i != end ; ++i )
373  if ( const Error err = results[i].error() )
374  showError( err, ids[i] );
375  }
376  else
377  showDetails( results, ids );
378  finished();
379 }
380 
381 static std::auto_ptr<ImportJob> get_import_job( GpgME::Protocol protocol ) {
382  assert( protocol != UnknownProtocol );
383  if ( const Kleo::CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( protocol ) )
384  return std::auto_ptr<ImportJob>( backend->importJob() );
385  else
386  return std::auto_ptr<ImportJob>();
387 }
388 
389 void ImportCertificatesCommand::Private::startImport( GpgME::Protocol protocol, const QByteArray & data, const QString & id ) {
390  assert( protocol != UnknownProtocol );
391 
392  if ( kdtools::contains( nonWorkingProtocols, protocol ) )
393  return;
394 
395  std::auto_ptr<ImportJob> job = get_import_job( protocol );
396  if ( !job.get() ) {
397  nonWorkingProtocols.push_back( protocol );
398  error( i18n( "The type of this certificate (%1) is not supported by this Kleopatra installation.",
399  Formatting::displayName( protocol ) ),
400  i18n( "Certificate Import Failed" ) );
401  importResult( ImportResult(), id );
402  return;
403  }
404 
405  connect( job.get(), SIGNAL(result(GpgME::ImportResult)),
406  q, SLOT(importResult(GpgME::ImportResult)) );
407  connect( job.get(), SIGNAL(progress(QString,int,int)),
408  q, SIGNAL(progress(QString,int,int)) );
409  const GpgME::Error err = job->start( data );
410  if ( err.code() ) {
411  importResult( ImportResult( err ), id );
412  } else {
413  jobs.push_back( job.release() );
414  idsByJob[jobs.back()] = id;
415  }
416 }
417 
418 static std::auto_ptr<ImportFromKeyserverJob> get_import_from_keyserver_job( GpgME::Protocol protocol ) {
419  assert( protocol != UnknownProtocol );
420  if ( const Kleo::CryptoBackend::Protocol * const backend = CryptoBackendFactory::instance()->protocol( protocol ) )
421  return std::auto_ptr<ImportFromKeyserverJob>( backend->importFromKeyserverJob() );
422  else
423  return std::auto_ptr<ImportFromKeyserverJob>();
424 }
425 
426 void ImportCertificatesCommand::Private::startImport( GpgME::Protocol protocol, const std::vector<Key> & keys, const QString & id ) {
427  assert( protocol != UnknownProtocol );
428 
429  if ( kdtools::contains( nonWorkingProtocols, protocol ) )
430  return;
431 
432  std::auto_ptr<ImportFromKeyserverJob> job = get_import_from_keyserver_job( protocol );
433  if ( !job.get() ) {
434  nonWorkingProtocols.push_back( protocol );
435  error( i18n( "The type of this certificate (%1) is not supported by this Kleopatra installation.",
436  Formatting::displayName( protocol ) ),
437  i18n( "Certificate Import Failed" ) );
438  importResult( ImportResult(), id );
439  return;
440  }
441 
442  connect( job.get(), SIGNAL(result(GpgME::ImportResult)),
443  q, SLOT(importResult(GpgME::ImportResult)) );
444  connect( job.get(), SIGNAL(progress(QString,int,int)),
445  q, SIGNAL(progress(QString,int,int)) );
446  const GpgME::Error err = job->start( keys );
447  if ( err.code() ) {
448  importResult( ImportResult( err ), id );
449  } else {
450  jobs.push_back( job.release() );
451  idsByJob[jobs.back()] = id;
452  }
453 }
454 
455 
456 void ImportCertificatesCommand::doCancel() {
457  kdtools::for_each( d->jobs, mem_fn( &Job::slotCancel ) );
458 }
459 
460 #undef d
461 #undef q
462 
463 #include "moc_importcertificatescommand.cpp"
464 #include "importcertificatescommand.moc"
465 
QModelIndex
QWidget
Kleo::ImportCertificatesCommand::Private::showError
void showError(QWidget *parent, const GpgME::Error &error, const QString &id=QString())
sum
int sum(const std::vector< ImportResult > &res, int(ImportResult::*fun)() const )
Definition: importcertificatescommand.cpp:224
Kleo::Command::finished
void finished()
QAbstractItemView
QList::push_back
void push_back(const T &value)
QByteArray
Kleo::ImportCertificatesCommand::~ImportCertificatesCommand
~ImportCertificatesCommand()
Definition: importcertificatescommand.cpp:192
Kleo::ImportCertificatesCommand::Private
Definition: importcertificatescommand_p.h:55
Kleo::ImportCertificatesCommand::Private::showDetails
void showDetails(QWidget *parent, const std::vector< GpgME::ImportResult > &results, const QStringList &ids)
Kleo::ImportCertificatesCommand::ImportCertificatesCommand
ImportCertificatesCommand(KeyListController *parent)
Definition: importcertificatescommand.cpp:180
Kleo::KeyListController
Definition: keylistcontroller.h:55
Kleo::ImportCertificatesCommand::Private::startImport
void startImport(GpgME::Protocol proto, const QByteArray &data, const QString &id=QString())
Definition: importcertificatescommand.cpp:389
Kleo::Formatting::displayName
QString displayName(GpgME::Protocol prot)
Kleo::Command::addTemporaryView
void addTemporaryView(const QString &title, AbstractKeyListSortFilterProxyModel *proxy=0, const QString &tabToolTip=QString())
Definition: commands/command.cpp:192
formatting.h
make_comparator_str
#define make_comparator_str(Name, expr)
Definition: predicates.h:101
importcertificatescommand_p.h
QStringList::join
QString join(const QString &separator) const
Kleo::ImportCertificatesCommand
Definition: importcertificatescommand.h:42
QList::size
int size() const
importcertificatescommand.h
q
#define q
Definition: importcertificatescommand.cpp:177
Kleo::Command::d
kdtools::pimpl_ptr< Private > d
Definition: commands/command.h:129
Kleo::Command::Private::q
Command *const q
Definition: commands/command_p.h:55
QModelIndex::isValid
bool isValid() const
QString::fromLocal8Bit
QString fromLocal8Bit(const char *str, int size)
Kleo::Command::Private::parentWidgetOrView
QWidget * parentWidgetOrView() const
Definition: commands/command_p.h:61
make_error_message
static QString make_error_message(const Error &err, const QString &id)
Definition: importcertificatescommand.cpp:315
Kleo::ImportCertificatesCommand::Private::setImportResultProxyModel
void setImportResultProxyModel(const std::vector< GpgME::ImportResult > &results, const QStringList &ids)
Definition: importcertificatescommand.cpp:214
QList::empty
bool empty() const
QObject
QString::isEmpty
bool isEmpty() const
QByteArray::constData
const char * constData() const
keylistsortfilterproxymodel.h
Kleo::AbstractKeyListSortFilterProxyModel
Definition: keylistsortfilterproxymodel.h:53
QList::front
T & front()
QString
QStringList
SUM
#define SUM(x)
make_message_report
static QString make_message_report(const std::vector< ImportResult > &res, const QStringList &ids)
Definition: importcertificatescommand.cpp:283
format_ids
static QString format_ids(const QStringList &ids)
Definition: importcertificatescommand.cpp:194
get_import_from_keyserver_job
static std::auto_ptr< ImportFromKeyserverJob > get_import_from_keyserver_job(GpgME::Protocol protocol)
Definition: importcertificatescommand.cpp:418
Kleo::ImportCertificatesCommand::Private::~Private
~Private()
Definition: importcertificatescommand.cpp:174
Kleo::Command::progress
void progress(const QString &message, int current, int total)
QString::toLatin1
QByteArray toLatin1() const
QModelIndex::data
QVariant data(int role) const
get_import_job
static std::auto_ptr< ImportJob > get_import_job(GpgME::Protocol protocol)
Definition: importcertificatescommand.cpp:381
Kleo::Formatting::importMetaData
QString importMetaData(const GpgME::Import &import)
QLatin1String
QTreeView
QList::insert
void insert(int i, const T &value)
Qt::escape
QString escape(const QString &plain)
predicates.h
make_tooltip
static QString make_tooltip(const QStringList &ids)
Definition: importcertificatescommand.cpp:198
make_report
static QString make_report(const std::vector< ImportResult > &res, const QString &id=QString())
Definition: importcertificatescommand.cpp:228
Kleo::ImportCertificatesCommand::doCancel
void doCancel()
Definition: importcertificatescommand.cpp:456
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
Kleo::ImportCertificatesCommand::Private::importResult
void importResult(const GpgME::ImportResult &)
QVariant::toString
QString toString() const
Kleo::Command
Definition: commands/command.h:58
Kleo::ImportCertificatesCommand::Private::setWaitForMoreJobs
void setWaitForMoreJobs(bool waiting)
Definition: importcertificatescommand.cpp:340
QVariant
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:33:11 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kleopatra

Skip menu "kleopatra"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

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

Search



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

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