00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "keyinfodialog.h"
00019
00020 #include <QGridLayout>
00021 #include <QHBoxLayout>
00022 #include <QVBoxLayout>
00023 #include <QPushButton>
00024 #include <QGroupBox>
00025 #include <QCheckBox>
00026 #include <QPainter>
00027 #include <QPixmap>
00028 #include <QImage>
00029
00030 #include <KToolInvocation>
00031 #include <KPassivePopup>
00032 #include <KDatePicker>
00033 #include <KMessageBox>
00034 #include <KUrlLabel>
00035 #include <KStandardDirs>
00036 #include <KIconEffect>
00037 #include <KLocale>
00038
00039 #include "kgpginterface.h"
00040 #include "convert.h"
00041 #include "images.h"
00042
00043 using namespace KgpgCore;
00044
00045 KgpgTrustLabel::KgpgTrustLabel(QWidget *parent, const QString &text, const QColor &color)
00046 : QWidget(parent)
00047 {
00048 m_text_w = new QLabel(this);
00049 m_text_w->setTextInteractionFlags(Qt::TextSelectableByMouse);
00050
00051 m_color_w = new QLabel(this);
00052 m_color_w->setLineWidth(1);
00053 m_color_w->setFrameShape(QFrame::Box);
00054 m_color_w->setAutoFillBackground(true);
00055
00056 QHBoxLayout *layout = new QHBoxLayout(this);
00057 layout->setSpacing(0);
00058 layout->setMargin(2);
00059 layout->addWidget(m_text_w);
00060 layout->addWidget(m_color_w);
00061
00062 m_text = text;
00063 m_color = color;
00064 change();
00065 }
00066
00067 void KgpgTrustLabel::setText(const QString &text)
00068 {
00069 m_text = text;
00070 change();
00071 }
00072
00073 void KgpgTrustLabel::setColor(const QColor &color)
00074 {
00075 m_color = color;
00076 change();
00077 }
00078
00079 QString KgpgTrustLabel::text() const
00080 {
00081 return m_text;
00082 }
00083
00084 QColor KgpgTrustLabel::color() const
00085 {
00086 return m_color;
00087 }
00088
00089 void KgpgTrustLabel::change()
00090 {
00091 m_text_w->setText(m_text);
00092
00093 QPalette palette = m_color_w->palette();
00094 palette.setColor(m_color_w->backgroundRole(), m_color);
00095 m_color_w->setPalette(palette);
00096 }
00097
00098 KgpgDateDialog::KgpgDateDialog(QWidget *parent, const bool &unlimited, QDate date)
00099 : KDialog(parent)
00100 {
00101 setCaption(i18n("Choose New Expiration"));
00102 setButtons(Ok | Cancel);
00103 setDefaultButton(Ok);
00104 setModal(true);
00105
00106 QWidget *page = new QWidget(this);
00107 m_unlimited = new QCheckBox(i18nc("Key has unlimited lifetime", "Unlimited"), page);
00108
00109 if (unlimited)
00110 date = QDate::currentDate();
00111
00112 m_datepicker = new KDatePicker(date, page);
00113 if (unlimited)
00114 {
00115 m_datepicker->setEnabled(false);
00116 m_unlimited->setChecked(true);
00117 }
00118
00119 QVBoxLayout *layout = new QVBoxLayout(page);
00120 layout->setSpacing(3);
00121 layout->addWidget(m_datepicker);
00122 layout->addWidget(m_unlimited);
00123
00124 connect(m_unlimited, SIGNAL(toggled(bool)), this, SLOT(slotEnableDate(bool)));
00125 connect(m_datepicker, SIGNAL(dateChanged(QDate)), this, SLOT(slotCheckDate(QDate)));
00126 connect(m_datepicker, SIGNAL(dateEntered(QDate)), this, SLOT(slotCheckDate(QDate)));
00127
00128 setMainWidget(page);
00129 show();
00130 }
00131
00132 QDate KgpgDateDialog::date() const
00133 {
00134 return m_datepicker->date();
00135 }
00136
00137 bool KgpgDateDialog::unlimited() const
00138 {
00139 return m_unlimited->isChecked();
00140 }
00141
00142 void KgpgDateDialog::slotCheckDate(const QDate &date)
00143 {
00144 enableButtonOk(date >= QDate::currentDate());
00145 }
00146
00147 void KgpgDateDialog::slotEnableDate(const bool &ison)
00148 {
00149 if (ison)
00150 {
00151 m_datepicker->setEnabled(false);
00152 enableButtonOk(true);
00153 }
00154 else
00155 {
00156 m_datepicker->setEnabled(true);
00157 enableButtonOk(m_datepicker->date() >= QDate::currentDate());
00158 }
00159 }
00160
00161 KgpgKeyInfo::KgpgKeyInfo(const QString &keyid, QWidget *parent)
00162 : KDialog(parent)
00163 {
00164 setButtons(Close);
00165 setDefaultButton(Close);
00166 setModal(true);
00167
00168 m_keyid = keyid;
00169 m_keywaschanged = false;
00170
00171 QWidget *page = new QWidget(this);
00172 QWidget *top = new QWidget(page);
00173 QWidget *right = new QWidget(top);
00174
00175 QGroupBox *gr_properties = _keypropertiesGroup(top);
00176 QGroupBox *gr_photo = _photoGroup(right);
00177 QGroupBox *gr_buttons = _buttonsGroup(right);
00178 QGroupBox *gr_fingerprint = _fingerprintGroup(page);
00179
00180 QVBoxLayout *layout_right = new QVBoxLayout(right);
00181 layout_right->setSpacing(spacingHint());
00182 layout_right->setMargin(0);
00183 layout_right->addWidget(gr_photo);
00184 layout_right->addWidget(gr_buttons);
00185
00186 QHBoxLayout *layout_top = new QHBoxLayout(top);
00187 layout_top->setSpacing(spacingHint());
00188 layout_top->setMargin(0);
00189 layout_top->addWidget(gr_properties);
00190 layout_top->addWidget(right);
00191
00192 QVBoxLayout *layout_page = new QVBoxLayout(page);
00193 layout_page->setSpacing(spacingHint());
00194 layout_page->setMargin(0);
00195 layout_page->addWidget(top);
00196 layout_page->addWidget(gr_fingerprint);
00197
00198 setMainWidget(page);
00199
00200 connect(m_owtrust, SIGNAL(activated(int)), this, SLOT(slotChangeTrust(int)));
00201 connect(m_photoid, SIGNAL(activated (const QString &)), this, SLOT(slotLoadPhoto(const QString &)));
00202 connect(m_email, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
00203 connect(this, SIGNAL(closeClicked()), this, SLOT(slotPreOk()));
00204
00205 loadKey();
00206 if (!m_hasphoto)
00207 m_photoid->setEnabled(false);
00208 else
00209 slotLoadPhoto(m_photoid->currentText());
00210 }
00211
00212 QGroupBox* KgpgKeyInfo::_keypropertiesGroup(QWidget *parent)
00213 {
00214 QGroupBox *group = new QGroupBox(i18n("Key properties"), parent);
00215
00216
00217
00218
00219 QWidget *widget_name = new QWidget(group);
00220
00221 m_name = new QLabel(widget_name);
00222 m_name->setTextInteractionFlags(Qt::TextSelectableByMouse);
00223
00224 m_email = new KUrlLabel(widget_name);
00225 m_email->setUnderline(false);
00226 m_email->setTextInteractionFlags(Qt::TextSelectableByMouse);
00227
00228
00229
00230
00231 QWidget *widget_properties = new QWidget(group);
00232
00233 QLabel *tl_id = new QLabel(i18n("Key ID:"), widget_properties);
00234 QLabel *tl_comment = new QLabel(i18n("Comment:"), widget_properties);
00235 QLabel *tl_creation = new QLabel(i18n("Creation:"), widget_properties);
00236 QLabel *tl_expiration = new QLabel(i18n("Expiration:"), widget_properties);
00237 QLabel *tl_trust = new QLabel(i18n("Trust:"), widget_properties);
00238 QLabel *tl_owtrust = new QLabel(i18n("Owner trust:"), widget_properties);
00239 QLabel *tl_algorithm = new QLabel(i18n("Algorithm:"), widget_properties);
00240 QLabel *tl_length = new QLabel(i18n("Length:"), widget_properties);
00241
00242 m_id = new QLabel(widget_properties);
00243 m_comment = new QLabel(widget_properties);
00244 m_creation = new QLabel(widget_properties);
00245 m_expiration = new QLabel(widget_properties);
00246 m_trust = new KgpgTrustLabel(widget_properties);
00247 m_owtrust = new KComboBox(widget_properties);
00248 m_algorithm = new QLabel(widget_properties);
00249 m_length = new QLabel(widget_properties);
00250
00251 m_owtrust->addItem(i18n("Don't Know"));
00252 m_owtrust->addItem(i18n("Do NOT Trust"));
00253 m_owtrust->addItem(i18n("Marginally"));
00254 m_owtrust->addItem(i18n("Fully"));
00255 m_owtrust->addItem(i18n("Ultimately"));
00256
00257 m_id->setTextInteractionFlags(Qt::TextSelectableByMouse);
00258 m_comment->setTextInteractionFlags(Qt::TextSelectableByMouse);
00259 m_creation->setTextInteractionFlags(Qt::TextSelectableByMouse);
00260 m_expiration->setTextInteractionFlags(Qt::TextSelectableByMouse);
00261 m_algorithm->setTextInteractionFlags(Qt::TextSelectableByMouse);
00262 m_length->setTextInteractionFlags(Qt::TextSelectableByMouse);
00263
00264 QHBoxLayout *layout_name = new QHBoxLayout(widget_name);
00265 layout_name->setMargin(0);
00266 layout_name->setSpacing(spacingHint());
00267 layout_name->addWidget(m_name);
00268 layout_name->addWidget(m_email);
00269 layout_name->addStretch();
00270
00271 QGridLayout *layout_properties = new QGridLayout(widget_properties);
00272 layout_properties->setMargin(0);
00273 layout_properties->setSpacing(spacingHint());
00274 layout_properties->addWidget(tl_id, 0, 0, Qt::AlignRight);
00275 layout_properties->addWidget(m_id, 0, 1);
00276 layout_properties->addWidget(tl_comment, 1, 0, Qt::AlignRight);
00277 layout_properties->addWidget(m_comment, 1, 1);
00278 layout_properties->addWidget(tl_creation, 2, 0, Qt::AlignRight);
00279 layout_properties->addWidget(m_creation, 2, 1);
00280 layout_properties->addWidget(tl_expiration, 3, 0, Qt::AlignRight);
00281 layout_properties->addWidget(m_expiration, 3, 1);
00282 layout_properties->addWidget(tl_trust, 4, 0, Qt::AlignRight);
00283 layout_properties->addWidget(m_trust, 4, 1);
00284 layout_properties->addWidget(tl_owtrust, 5, 0, Qt::AlignRight);
00285 layout_properties->addWidget(m_owtrust, 5, 1);
00286 layout_properties->addWidget(tl_algorithm, 6, 0, Qt::AlignRight);
00287 layout_properties->addWidget(m_algorithm, 6, 1);
00288 layout_properties->addWidget(tl_length, 7, 0, Qt::AlignRight);
00289 layout_properties->addWidget(m_length, 7, 1);
00290 layout_properties->setColumnStretch(1, 1);
00291 layout_properties->setRowStretch(8, 1);
00292
00293 QVBoxLayout *layout_keyproperties = new QVBoxLayout(group);
00294 layout_keyproperties->addWidget(widget_name);
00295 layout_keyproperties->addWidget(widget_properties);
00296
00297 return group;
00298 }
00299
00300 QGroupBox* KgpgKeyInfo::_photoGroup(QWidget *parent)
00301 {
00302 QGroupBox *group = new QGroupBox(i18n("Photo"), parent);
00303 m_photo = new QLabel(i18n("No Photo"), group);
00304 m_photoid = new KComboBox(group);
00305
00306 m_photo->setMinimumSize(120, 140);
00307 m_photo->setMaximumSize(32767, 140);
00308 m_photo->setLineWidth(2);
00309 m_photo->setAlignment(Qt::AlignCenter);
00310 m_photo->setFrameShape(QFrame::Box);
00311 m_photo->setWhatsThis("<qt><b>Photo:</b><p>A photo can be included with a public key for extra security. The photo can be used as an additional method of authenticating the key. However, it should not be relied upon as the only form of authentication.</p></qt>");
00312
00313 QVBoxLayout *layout = new QVBoxLayout(group);
00314 layout->setMargin(marginHint());
00315 layout->setSpacing(spacingHint());
00316 layout->addWidget(m_photo);
00317 layout->addWidget(m_photoid);
00318 layout->addStretch();
00319
00320 return group;
00321 }
00322
00323 QGroupBox* KgpgKeyInfo::_buttonsGroup(QWidget *parent)
00324 {
00325 KgpgInterface *interface = new KgpgInterface();
00326 KgpgKeyList keys = interface->readSecretKeys(QStringList(m_keyid));
00327 delete interface;
00328 bool isscretkey = keys.size() != 0;
00329
00330 QPushButton *expiration = 0;
00331 QPushButton *password = 0;
00332
00333 QGroupBox *group = new QGroupBox(parent);
00334 m_disable = new QCheckBox(i18n("Disable key"), group);
00335
00336 if (isscretkey)
00337 {
00338 expiration = new QPushButton(i18n("Change Expiration..."), group);
00339 password = new QPushButton(i18n("Change Passphrase..."), group);
00340
00341 connect(expiration, SIGNAL(clicked()), this, SLOT(slotChangeDate()));
00342 connect(password, SIGNAL(clicked()), this, SLOT(slotChangePass()));
00343 }
00344 connect(m_disable, SIGNAL(toggled(bool)), this, SLOT(slotDisableKey(bool)));
00345
00346 QVBoxLayout *layout = new QVBoxLayout(group);
00347 layout->setMargin(marginHint());
00348 layout->setSpacing(spacingHint());
00349 layout->addWidget(m_disable);
00350
00351 if (isscretkey)
00352 {
00353 layout->addWidget(expiration);
00354 layout->addWidget(password);
00355 }
00356
00357 return group;
00358 }
00359
00360 QGroupBox* KgpgKeyInfo::_fingerprintGroup(QWidget *parent)
00361 {
00362 QGroupBox *group = new QGroupBox(i18n("Fingerprint"), parent);
00363 m_fingerprint = new QLabel(group);
00364 m_fingerprint->setTextInteractionFlags(Qt::TextSelectableByMouse);
00365
00366 QVBoxLayout *layout = new QVBoxLayout(group);
00367 layout->setMargin(marginHint());
00368 layout->setSpacing(spacingHint());
00369 layout->addWidget(m_fingerprint);
00370
00371 return group;
00372 }
00373
00374 void KgpgKeyInfo::loadKey()
00375 {
00376 KgpgInterface *interface = new KgpgInterface();
00377 KgpgKeyList listkeys = interface->readPublicKeys(true, m_keyid);
00378 delete interface;
00379
00380 KgpgKey key = listkeys.at(0);
00381 KgpgKeySub subkey;
00382
00383
00384 KgpgKeySubListPtr sublist = key.subList();
00385 for (int i = 0; i < sublist->count(); ++i)
00386 {
00387 KgpgKeySub temp = sublist->at(i);
00388 if (temp.type() == SKT_ENCRYPTION)
00389 {
00390 subkey = temp;
00391 break;
00392 }
00393 }
00394
00395 QString name = key.name();
00396 setCaption(name);
00397 m_name->setText("<qt><b>" + name + "</b></qt>");
00398
00399 if (key.email().isEmpty())
00400 {
00401 m_email->setText(i18nc("no email address", "none"));
00402 m_email->setUrl("");
00403 }
00404 else
00405 {
00406 m_email->setText("<qt><b><" + key.email() + "></b></qt>");
00407 m_email->setUrl("mailto:" + key.email());
00408 }
00409
00410 KgpgKeyTrust keytrust = key.valid() ? key.trust() : TRUST_DISABLED;
00411 QString tr = Convert::toString(keytrust);
00412 QColor trustcolor = Convert::toColor(keytrust);
00413
00414 m_id->setText(key.fullId());
00415 m_algorithm->setText(Convert::toString(key.algorithm()) + " / " + Convert::toString(subkey.algorithm()));
00416 m_algorithm->setWhatsThis("<qt>The left part is the algorithm used by the <b>signature</b> key. The right part is the algorithm used by the <b>encryption</b> key.</qt>");
00417 m_creation->setText(key.creation());
00418 m_expiration->setText(key.expiration());
00419 m_trust->setText(tr);
00420 m_trust->setColor(trustcolor);
00421 m_length->setText(QString::number(key.size()) + " / " + QString::number(subkey.size()));
00422 m_length->setWhatsThis("<qt>The left part is the size of the <b>signature</b> key. The right part is the size of the <b>encryption</b> key.</qt>");
00423 m_fingerprint->setText(key.fingerprintBeautified());
00424
00425 if (key.comment().isEmpty())
00426 m_comment->setText(i18nc("no key comment", "none"));
00427 else
00428 m_comment->setText(key.comment());
00429
00430 QStringList photolist = key.photoList();
00431 m_photoid->clear();
00432 if (photolist.isEmpty())
00433 {
00434 m_photoid->setVisible(false);
00435 m_hasphoto = false;
00436 }
00437 else
00438 {
00439 m_photoid->setVisible(true);
00440 m_hasphoto = true;
00441 m_photoid->addItems(photolist);
00442 }
00443
00444 switch (key.ownerTrust())
00445 {
00446 case OWTRUST_NONE:
00447 m_owtrust->setCurrentIndex(1);
00448 break;
00449
00450 case OWTRUST_MARGINAL:
00451 m_owtrust->setCurrentIndex(2);
00452 break;
00453
00454 case OWTRUST_FULL:
00455 m_owtrust->setCurrentIndex(3);
00456 break;
00457
00458 case OWTRUST_ULTIMATE:
00459 m_owtrust->setCurrentIndex(4);
00460 break;
00461
00462 case OWTRUST_UNDEFINED:
00463 default:
00464 m_owtrust->setCurrentIndex(0);
00465 break;
00466 }
00467
00468 if (!key.valid())
00469 m_disable->setChecked(true);
00470
00471 m_isunlimited = key.unlimited();
00472 m_expirationdate = key.expirationDate();
00473 }
00474
00475 void KgpgKeyInfo::slotOpenUrl(const QString &url) const
00476 {
00477 KToolInvocation::invokeBrowser(url);
00478 }
00479
00480 void KgpgKeyInfo::slotLoadPhoto(const QString &uid)
00481 {
00482 KgpgInterface *interface = new KgpgInterface();
00483 connect(interface, SIGNAL(loadPhotoFinished(QPixmap, KgpgInterface*)), this, SLOT(slotSetPhoto(QPixmap, KgpgInterface*)));
00484 interface->loadPhoto(m_keyid, uid);
00485 }
00486
00487 void KgpgKeyInfo::slotSetPhoto(const QPixmap &pixmap, KgpgInterface *interface)
00488 {
00489 delete interface;
00490
00491 QImage img = pixmap.toImage();
00492 QPixmap pix = QPixmap::fromImage(img.scaled(m_photo->width(), m_photo->height(), Qt::KeepAspectRatio));
00493 m_photo->setPixmap(pix);
00494 }
00495
00496 void KgpgKeyInfo::slotPreOk()
00497 {
00498 if (m_keywaschanged)
00499 emit keyNeedsRefresh(m_keyid);
00500 accept();
00501 }
00502
00503 void KgpgKeyInfo::slotChangeDate()
00504 {
00505 KgpgDateDialog *dialog = new KgpgDateDialog(this, m_isunlimited, m_expirationdate);
00506 if (dialog->exec() == QDialog::Accepted)
00507 {
00508 KgpgInterface *process = new KgpgInterface();
00509 connect(process, SIGNAL(keyExpireFinished(int, KgpgInterface*)), this, SLOT(slotInfoExpirationChanged(int, KgpgInterface*)));
00510
00511 if (dialog->unlimited())
00512 process->keyExpire(m_keyid, QDate());
00513 else
00514 process->keyExpire(m_keyid, dialog->date());
00515 }
00516 delete dialog;
00517 }
00518
00519 void KgpgKeyInfo::slotInfoExpirationChanged(const int &res, KgpgInterface *interface)
00520 {
00521 delete interface;
00522
00523 if (res == 2)
00524 {
00525 m_keywaschanged = true;
00526 loadKey();
00527 }
00528 else
00529 if (res == 1)
00530 KMessageBox::error(this, i18n("Could not change expiration"), i18n("Bad passphrase. Expiration of the key has not been changed."));
00531 }
00532
00533 void KgpgKeyInfo::slotDisableKey(const bool &ison)
00534 {
00535 KgpgInterface *interface = new KgpgInterface;
00536 connect (interface, SIGNAL(changeDisableFinished(KgpgInterface*, int)), this, SLOT(slotDisableKeyFinished(KgpgInterface*, int)));
00537 interface->changeDisable(m_keyid, ison);
00538 }
00539
00540 void KgpgKeyInfo::slotDisableKeyFinished(KgpgInterface *interface, int)
00541 {
00542 delete interface;
00543 loadKey();
00544 m_keywaschanged = true;
00545 }
00546
00547 void KgpgKeyInfo::slotChangePass()
00548 {
00549 KgpgInterface *interface = new KgpgInterface();
00550 connect(interface, SIGNAL(changePassFinished(int, KgpgInterface*)), this, SLOT(slotInfoPasswordChanged(int, KgpgInterface*)));
00551 interface->changePass(m_keyid);
00552 }
00553
00554 void KgpgKeyInfo::slotInfoPasswordChanged(const int &res, KgpgInterface *interface)
00555 {
00556 delete interface;
00557
00558 if (res == 2)
00559 KPassivePopup::message(i18n("Passphrase for the key was changed"), QString(), Images::kgpg(), this);
00560
00561 if (res == 1)
00562 KMessageBox::error(this, i18n("Bad old passphrase, the passphrase for the key was not changed"), i18n("Could not change passphrase"));
00563 }
00564
00565 void KgpgKeyInfo::slotChangeTrust(const int &newtrust)
00566 {
00567 KgpgInterface *interface = new KgpgInterface();
00568 connect(interface, SIGNAL(changeTrustFinished(KgpgInterface*)), this, SLOT(slotInfoTrustChanged(KgpgInterface*)));
00569 interface->changeTrust(m_keyid, KgpgKeyOwnerTrust(newtrust + 1));
00570 }
00571
00572 void KgpgKeyInfo::slotInfoTrustChanged(KgpgInterface *interface)
00573 {
00574 delete interface;
00575 m_keywaschanged = true;
00576 loadKey();
00577 }
00578
00579 #include "keyinfodialog.moc"