QGpgME  20.5.1.0000000
Qt API for GpgME
protocol_p.h
1 /*
2  protocol_p.h
3 
4  This file is part of qgpgme, the Qt API binding for gpgme
5  Copyright (c) 2004,2005 Klarälvdalens Datakonsult AB
6  Copyright (c) 2016 by Bundesamt für Sicherheit in der Informationstechnik
7  Software engineering by Intevation GmbH
8  Copyright (c) 2022 by g10 Code GmbH
9  Software engineering by Ingo Klöcker <dev@ingo-kloecker.de>
10 
11  QGpgME is free software; you can redistribute it and/or
12  modify it under the terms of the GNU General Public License as
13  published by the Free Software Foundation; either version 2 of the
14  License, or (at your option) any later version.
15 
16  QGpgME is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  General Public License for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with this program; if not, write to the Free Software
23  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 
25  In addition, as a special exception, the copyright holders give
26  permission to link the code of this program with any edition of
27  the Qt library by Trolltech AS, Norway (or with modified versions
28  of Qt that use the same license as Qt), and distribute linked
29  combinations including the two. You must obey the GNU General
30  Public License in all respects for all of the code used other than
31  Qt. If you modify this file, you may extend this exception to
32  your version of the file, but you are not obligated to do so. If
33  you do not wish to do so, delete this exception statement from
34  your version.
35 */
36 #ifndef __QGPGME_PROTOCOL_P_H__
37 #define __QGPGME_PROTOCOL_P_H__
38 #include "qgpgmenewcryptoconfig.h"
39 
40 #include "qgpgmekeygenerationjob.h"
41 #include "qgpgmekeylistjob.h"
42 #include "qgpgmelistallkeysjob.h"
43 #include "qgpgmedecryptjob.h"
44 #include "qgpgmedecryptverifyarchivejob.h"
45 #include "qgpgmedecryptverifyjob.h"
46 #include "qgpgmerefreshsmimekeysjob.h"
47 #include "qgpgmedeletejob.h"
48 #include "qgpgmedownloadjob.h"
49 #include "qgpgmesignencryptjob.h"
50 #include "qgpgmeencryptarchivejob.h"
51 #include "qgpgmeencryptjob.h"
52 #include "qgpgmesignarchivejob.h"
53 #include "qgpgmesignencryptarchivejob.h"
54 #include "qgpgmesignjob.h"
55 #include "qgpgmesignkeyjob.h"
56 #include "qgpgmeexportjob.h"
57 #include "qgpgmeverifydetachedjob.h"
58 #include "qgpgmeimportjob.h"
59 #include "qgpgmeimportfromkeyserverjob.h"
60 #include "qgpgmeverifyopaquejob.h"
61 #include "qgpgmechangeexpiryjob.h"
62 #include "qgpgmechangeownertrustjob.h"
63 #include "qgpgmechangepasswdjob.h"
64 #include "qgpgmeaddexistingsubkeyjob.h"
65 #include "qgpgmeadduseridjob.h"
66 #include "qgpgmekeyformailboxjob.h"
67 #include "qgpgmewkdlookupjob.h"
68 #include "qgpgmewkspublishjob.h"
69 #include "qgpgmetofupolicyjob.h"
70 #include "qgpgmequickjob.h"
71 #include "qgpgmereceivekeysjob.h"
72 #include "qgpgmerevokekeyjob.h"
73 #include "qgpgmesetprimaryuseridjob.h"
74 #include "qgpgmewkdrefreshjob.h"
75 
76 namespace
77 {
78 
79 class Protocol : public QGpgME::Protocol
80 {
81  GpgME::Protocol mProtocol;
82 public:
83  explicit Protocol(GpgME::Protocol proto) : mProtocol(proto) {}
84 
85  QString name() const override
86  {
87  switch (mProtocol) {
88  case GpgME::OpenPGP: return QStringLiteral("OpenPGP");
89  case GpgME::CMS: return QStringLiteral("SMIME");
90  default: return QString();
91  }
92  }
93 
94  QString displayName() const override
95  {
96  // ah (2.4.16): Where is this used and isn't this inverted
97  // with name
98  switch (mProtocol) {
99  case GpgME::OpenPGP: return QStringLiteral("gpg");
100  case GpgME::CMS: return QStringLiteral("gpgsm");
101  default: return QStringLiteral("unknown");
102  }
103  }
104 
105  QGpgME::SpecialJob *specialJob(const char *, const QMap<QString, QVariant> &) const override
106  {
107  return nullptr;
108  }
109 
110  QGpgME::KeyListJob *keyListJob(bool remote, bool includeSigs, bool validate) const override
111  {
112  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
113  if (!context) {
114  return nullptr;
115  }
116 
117  unsigned int mode = context->keyListMode();
118  if (remote) {
119  mode |= GpgME::Extern;
120  mode &= ~GpgME::Local;
121  } else {
122  mode |= GpgME::Local;
123  mode &= ~GpgME::Extern;
124  }
125  if (includeSigs) {
126  mode |= GpgME::Signatures;
127  }
128  if (validate) {
129  mode |= GpgME::Validate;
130  }
131  context->setKeyListMode(mode);
132  return new QGpgME::QGpgMEKeyListJob(context);
133  }
134 
135  QGpgME::ListAllKeysJob *listAllKeysJob(bool includeSigs, bool validate) const override
136  {
137  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
138  if (!context) {
139  return nullptr;
140  }
141 
142  unsigned int mode = context->keyListMode();
143  mode |= GpgME::Local;
144  mode &= ~GpgME::Extern;
145  if (includeSigs) {
146  mode |= GpgME::Signatures;
147  }
148  if (validate) {
149  mode |= GpgME::Validate;
150  /* Setting the context to offline mode disables CRL / OCSP checks in
151  this Job. Otherwise we would try to fetch the CRL's for all CMS
152  keys in the users keyring because GpgME::Validate includes remote
153  resources by default in the validity check.
154  This setting only has any effect if gpgsm >= 2.1.6 is used.
155  */
156  context->setOffline(true);
157  }
158  context->setKeyListMode(mode);
159  return new QGpgME::QGpgMEListAllKeysJob(context);
160  }
161 
162  QGpgME::EncryptJob *encryptJob(bool armor, bool textmode) const override
163  {
164  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
165  if (!context) {
166  return nullptr;
167  }
168 
169  context->setArmor(armor);
170  context->setTextMode(textmode);
171  return new QGpgME::QGpgMEEncryptJob(context);
172  }
173 
174  QGpgME::DecryptJob *decryptJob() const override
175  {
176  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
177  if (!context) {
178  return nullptr;
179  }
180  return new QGpgME::QGpgMEDecryptJob(context);
181  }
182 
183  QGpgME::SignJob *signJob(bool armor, bool textMode) const override
184  {
185  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
186  if (!context) {
187  return nullptr;
188  }
189 
190  context->setArmor(armor);
191  context->setTextMode(textMode);
192  return new QGpgME::QGpgMESignJob(context);
193  }
194 
195  QGpgME::VerifyDetachedJob *verifyDetachedJob(bool textMode) const override
196  {
197  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
198  if (!context) {
199  return nullptr;
200  }
201 
202  context->setTextMode(textMode);
203  return new QGpgME::QGpgMEVerifyDetachedJob(context);
204  }
205 
206  QGpgME::VerifyOpaqueJob *verifyOpaqueJob(bool textMode) const override
207  {
208  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
209  if (!context) {
210  return nullptr;
211  }
212 
213  context->setTextMode(textMode);
214  return new QGpgME::QGpgMEVerifyOpaqueJob(context);
215  }
216 
217  QGpgME::KeyGenerationJob *keyGenerationJob() const override
218  {
219  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
220  if (!context) {
221  return nullptr;
222  }
223  return new QGpgME::QGpgMEKeyGenerationJob(context);
224  }
225 
226  QGpgME::ImportJob *importJob() const override
227  {
228  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
229  if (!context) {
230  return nullptr;
231  }
232  return new QGpgME::QGpgMEImportJob(context);
233  }
234 
235  QGpgME::ImportFromKeyserverJob *importFromKeyserverJob() const override
236  {
237  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
238  if (!context) {
239  return nullptr;
240  }
241  return new QGpgME::QGpgMEImportFromKeyserverJob(context);
242  }
243 
244  QGpgME::ReceiveKeysJob *receiveKeysJob() const override
245  {
246  if (mProtocol != GpgME::OpenPGP) {
247  return nullptr;
248  }
249 
250  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
251  if (!context) {
252  return nullptr;
253  }
254  return new QGpgME::QGpgMEReceiveKeysJob{context};
255  }
256 
257  QGpgME::ExportJob *publicKeyExportJob(bool armor) const override
258  {
259  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
260  if (!context) {
261  return nullptr;
262  }
263 
264  context->setArmor(armor);
265  return new QGpgME::QGpgMEExportJob(context);
266  }
267 
268  QGpgME::ExportJob *secretKeyExportJob(bool armor, const QString &) const override
269  {
270  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
271  if (!context) {
272  return nullptr;
273  }
274 
275  context->setArmor(armor);
276  return new QGpgME::QGpgMEExportJob(context, GpgME::Context::ExportSecret);
277  }
278 
279  QGpgME::ExportJob *secretSubkeyExportJob(bool armor) const override
280  {
281  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
282  if (!context) {
283  return nullptr;
284  }
285 
286  context->setArmor(armor);
287  return new QGpgME::QGpgMEExportJob(context, GpgME::Context::ExportSecretSubkey);
288  }
289 
290  QGpgME::RefreshKeysJob *refreshKeysJob() const override
291  {
292  if (mProtocol != GpgME::CMS) {
293  return nullptr;
294  }
295 
297  }
298 
299  QGpgME::DownloadJob *downloadJob(bool armor) const override
300  {
301  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
302  if (!context) {
303  return nullptr;
304  }
305 
306  context->setArmor(armor);
307  // this is the hackish interface for downloading from keyserers currently:
308  context->setKeyListMode(GpgME::Extern);
309  return new QGpgME::QGpgMEDownloadJob(context);
310  }
311 
312  QGpgME::DeleteJob *deleteJob() const override
313  {
314  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
315  if (!context) {
316  return nullptr;
317  }
318  return new QGpgME::QGpgMEDeleteJob(context);
319  }
320 
321  QGpgME::SignEncryptJob *signEncryptJob(bool armor, bool textMode) const override
322  {
323  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
324  if (!context) {
325  return nullptr;
326  }
327 
328  context->setArmor(armor);
329  context->setTextMode(textMode);
330  return new QGpgME::QGpgMESignEncryptJob(context);
331  }
332 
333  QGpgME::DecryptVerifyJob *decryptVerifyJob(bool textMode) const override
334  {
335  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
336  if (!context) {
337  return nullptr;
338  }
339 
340  context->setTextMode(textMode);
341  return new QGpgME::QGpgMEDecryptVerifyJob(context);
342  }
343 
344  QGpgME::ChangeExpiryJob *changeExpiryJob() const override
345  {
346  if (mProtocol != GpgME::OpenPGP) {
347  return nullptr; // only supported by gpg
348  }
349 
350  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
351  if (!context) {
352  return nullptr;
353  }
354  return new QGpgME::QGpgMEChangeExpiryJob(context);
355  }
356 
357  QGpgME::ChangePasswdJob *changePasswdJob() const override
358  {
359  if (!GpgME::hasFeature(GpgME::PasswdFeature, 0)) {
360  return nullptr;
361  }
362  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
363  if (!context) {
364  return nullptr;
365  }
366  return new QGpgME::QGpgMEChangePasswdJob(context);
367  }
368 
369  QGpgME::SignKeyJob *signKeyJob() const override
370  {
371  if (mProtocol != GpgME::OpenPGP) {
372  return nullptr; // only supported by gpg
373  }
374 
375  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
376  if (!context) {
377  return nullptr;
378  }
379  return new QGpgME::QGpgMESignKeyJob(context);
380  }
381 
382  QGpgME::ChangeOwnerTrustJob *changeOwnerTrustJob() const override
383  {
384  if (mProtocol != GpgME::OpenPGP) {
385  return nullptr; // only supported by gpg
386  }
387 
388  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
389  if (!context) {
390  return nullptr;
391  }
392  return new QGpgME::QGpgMEChangeOwnerTrustJob(context);
393  }
394 
395  QGpgME:: AddExistingSubkeyJob *addExistingSubkeyJob() const override
396  {
397  if (mProtocol != GpgME::OpenPGP) {
398  return nullptr; // only supported by gpg
399  }
400 
401  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
402  if (!context) {
403  return nullptr;
404  }
405  return new QGpgME::QGpgMEAddExistingSubkeyJob{context};
406  }
407 
408  QGpgME::AddUserIDJob *addUserIDJob() const override
409  {
410  if (mProtocol != GpgME::OpenPGP) {
411  return nullptr; // only supported by gpg
412  }
413 
414  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
415  if (!context) {
416  return nullptr;
417  }
418  return new QGpgME::QGpgMEAddUserIDJob(context);
419  }
420 
421  QGpgME::KeyListJob *locateKeysJob() const override
422  {
423  if (mProtocol != GpgME::OpenPGP) {
424  return nullptr;
425  }
426  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
427  if (!context) {
428  return nullptr;
429  }
430  context->setKeyListMode(GpgME::Locate | GpgME::Signatures | GpgME::Validate);
431  return new QGpgME::QGpgMEKeyListJob(context);
432  }
433 
435  {
436  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
437  if (!context) {
438  return nullptr;
439  }
440  return new QGpgME::QGpgMEKeyForMailboxJob(context);
441  }
442 
443  QGpgME::WKDLookupJob *wkdLookupJob() const override
444  {
445  if (mProtocol != GpgME::OpenPGP) {
446  return nullptr;
447  }
448  auto context = GpgME::Context::createForEngine(GpgME::AssuanEngine);
449  if (!context) {
450  return nullptr;
451  }
452  return new QGpgME::QGpgMEWKDLookupJob(context.release());
453  }
454 
455  QGpgME::WKSPublishJob *wksPublishJob() const override
456  {
457  if (mProtocol != GpgME::OpenPGP) {
458  return nullptr;
459  }
460  auto context = GpgME::Context::createForEngine(GpgME::SpawnEngine);
461  if (!context) {
462  return nullptr;
463  }
464  return new QGpgME::QGpgMEWKSPublishJob(context.release());
465  }
466 
467  QGpgME::TofuPolicyJob *tofuPolicyJob() const override
468  {
469  if (mProtocol != GpgME::OpenPGP) {
470  return nullptr;
471  }
472  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
473  if (!context) {
474  return nullptr;
475  }
476  return new QGpgME::QGpgMETofuPolicyJob(context);
477  }
478 
479  QGpgME::QuickJob *quickJob() const override
480  {
481  if (mProtocol != GpgME::OpenPGP) {
482  return nullptr;
483  }
484  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
485  if (!context) {
486  return nullptr;
487  }
488  return new QGpgME::QGpgMEQuickJob(context);
489  }
490 
491  QGpgME::RevokeKeyJob *revokeKeyJob() const override
492  {
493  if (mProtocol != GpgME::OpenPGP) {
494  return nullptr;
495  }
496  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
497  if (!context) {
498  return nullptr;
499  }
500  return new QGpgME::QGpgMERevokeKeyJob(context);
501  }
502 
504  {
505  if (mProtocol != GpgME::OpenPGP) {
506  return nullptr;
507  }
508  GpgME::Context *context = GpgME::Context::createForProtocol(mProtocol);
509  if (!context) {
510  return nullptr;
511  }
512  return new QGpgME::QGpgMESetPrimaryUserIDJob{context};
513  }
514 
515  QGpgME::EncryptArchiveJob *encryptArchiveJob(bool armor) const override
516  {
517  if (mProtocol != GpgME::OpenPGP) {
518  return nullptr;
519  }
520  if (auto context = GpgME::Context::createForProtocol(mProtocol)) {
521  context->setArmor(armor);
522  return new QGpgME::QGpgMEEncryptArchiveJob{context};
523  }
524  return nullptr;
525  }
526 
527  QGpgME::SignArchiveJob *signArchiveJob(bool armor) const override
528  {
529  if (mProtocol != GpgME::OpenPGP) {
530  return nullptr;
531  }
532  if (auto context = GpgME::Context::createForProtocol(mProtocol)) {
533  context->setArmor(armor);
534  return new QGpgME::QGpgMESignArchiveJob{context};
535  }
536  return nullptr;
537  }
538 
539  QGpgME::SignEncryptArchiveJob *signEncryptArchiveJob(bool armor) const override
540  {
541  if (mProtocol != GpgME::OpenPGP) {
542  return nullptr;
543  }
544  if (auto context = GpgME::Context::createForProtocol(mProtocol)) {
545  context->setArmor(armor);
546  return new QGpgME::QGpgMESignEncryptArchiveJob{context};
547  }
548  return nullptr;
549  }
550 
551  QGpgME::DecryptVerifyArchiveJob *decryptVerifyArchiveJob() const override
552  {
553  if (mProtocol != GpgME::OpenPGP) {
554  return nullptr;
555  }
556  if (auto context = GpgME::Context::createForProtocol(mProtocol)) {
557  return new QGpgME::QGpgMEDecryptVerifyArchiveJob{context};
558  }
559  return nullptr;
560  }
561 
562  QGpgME::WKDRefreshJob *wkdRefreshJob() const override
563  {
564  if (mProtocol != GpgME::OpenPGP) {
565  return nullptr;
566  }
567  if (auto context = GpgME::Context::createForProtocol(mProtocol)) {
568  return new QGpgME::QGpgMEWKDRefreshJob{context};
569  }
570  return nullptr;
571  }
572 };
573 
574 }
575 #endif
Definition: addexistingsubkeyjob.h:53
An abstract base class to asynchronously add UIDs to OpenPGP keys.
Definition: adduseridjob.h:65
An abstract base class to change expiry asynchronously.
Definition: changeexpiryjob.h:72
An abstract base class to change owner trust asynchronously.
Definition: changeownertrustjob.h:63
An abstract base class to change a key's passphrase asynchronously.
Definition: changepasswdjob.h:63
An abstract base class for asynchronous decrypters.
Definition: decryptjob.h:68
Definition: decryptverifyarchivejob.h:57
An abstract base class for asynchronous combined decrypters and verifiers.
Definition: decryptverifyjob.h:69
An abstract base class for asynchronous deleters.
Definition: deletejob.h:64
An abstract base class for asynchronous downloaders.
Definition: downloadjob.h:70
Definition: encryptarchivejob.h:57
An abstract base class for asynchronous encrypters.
Definition: encryptjob.h:79
An abstract base class for asynchronous exporters.
Definition: exportjob.h:66
An abstract base class for asynchronous keyserver-importers.
Definition: importfromkeyserverjob.h:67
An abstract base class for asynchronous importers.
Definition: importjob.h:72
Get the best key to use for a Mailbox.
Definition: keyformailboxjob.h:70
An abstract base class for asynchronous key generation.
Definition: keygenerationjob.h:66
An abstract base class for asynchronous key listers.
Definition: keylistjob.h:76
An abstract base class for asynchronously listing all keys.
Definition: listallkeysjob.h:77
Definition: protocol.h:119
virtual TofuPolicyJob * tofuPolicyJob() const =0
virtual KeyListJob * locateKeysJob() const =0
virtual RefreshKeysJob * refreshKeysJob() const =0
virtual QuickJob * quickJob() const =0
virtual WKDLookupJob * wkdLookupJob() const =0
virtual SetPrimaryUserIDJob * setPrimaryUserIDJob() const =0
virtual WKSPublishJob * wksPublishJob() const =0
virtual KeyForMailboxJob * keyForMailboxJob() const =0
Definition: qgpgmeaddexistingsubkeyjob.h:49
Definition: qgpgmeadduseridjob.h:51
Definition: qgpgmechangeexpiryjob.h:51
Definition: qgpgmechangeownertrustjob.h:51
Definition: qgpgmechangepasswdjob.h:51
Definition: qgpgmedecryptjob.h:57
Definition: qgpgmedecryptverifyarchivejob.h:53
Definition: qgpgmedecryptverifyjob.h:62
Definition: qgpgmedeletejob.h:56
Definition: qgpgmedownloadjob.h:51
Definition: qgpgmeencryptarchivejob.h:52
Definition: qgpgmeencryptjob.h:62
Definition: qgpgmeexportjob.h:53
Definition: qgpgmeimportfromkeyserverjob.h:57
Definition: qgpgmeimportjob.h:59
Definition: qgpgmekeyformailboxjob.h:59
Definition: qgpgmekeygenerationjob.h:57
Definition: qgpgmekeylistjob.h:62
Definition: qgpgmelistallkeysjob.h:62
Definition: qgpgmequickjob.h:52
Definition: qgpgmereceivekeysjob.h:56
Definition: qgpgmerefreshsmimekeysjob.h:52
Definition: qgpgmerevokekeyjob.h:49
Definition: qgpgmesetprimaryuseridjob.h:49
Definition: qgpgmesignarchivejob.h:52
Definition: qgpgmesignencryptarchivejob.h:53
Definition: qgpgmesignencryptjob.h:69
Definition: qgpgmesignjob.h:62
Definition: qgpgmesignkeyjob.h:53
Definition: qgpgmetofupolicyjob.h:50
Definition: qgpgmeverifydetachedjob.h:57
Definition: qgpgmeverifyopaquejob.h:57
Definition: qgpgmewkdlookupjob.h:51
Definition: qgpgmewkdrefreshjob.h:51
Definition: qgpgmewkspublishjob.h:54
Definition: quickjob.h:56
Definition: receivekeysjob.h:44
An abstract base class for asynchronous key refreshers.
Definition: refreshkeysjob.h:68
Definition: revokekeyjob.h:52
Definition: setprimaryuseridjob.h:51
Definition: signarchivejob.h:57
Definition: signencryptarchivejob.h:57
An abstract base class for asynchronous combined signing and encrypting.
Definition: signencryptjob.h:83
An abstract base class for asynchronous signing.
Definition: signjob.h:77
An abstract base class to sign keys asynchronously.
Definition: signkeyjob.h:69
An abstract base class for protocol-specific jobs.
Definition: specialjob.h:71
Definition: tofupolicyjob.h:55
An abstract base class for asynchronous verification of detached signatures.
Definition: verifydetachedjob.h:69
An abstract base class for asynchronous verification of opaque signatures.
Definition: verifyopaquejob.h:68
Definition: wkdlookupjob.h:54
Definition: wkdrefreshjob.h:56
Definition: wkspublishjob.h:60
Definition: qgpgmebackend.h:43