00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "keyinfodialog.h"
00017
00018 #include <QGridLayout>
00019 #include <QHBoxLayout>
00020 #include <QVBoxLayout>
00021 #include <QGroupBox>
00022 #include <QCheckBox>
00023 #include <QPixmap>
00024 #include <QImage>
00025 #include <QApplication>
00026
00027 #include <KToolInvocation>
00028 #include <KPassivePopup>
00029 #include <KPushButton>
00030 #include <KDatePicker>
00031 #include <KMessageBox>
00032 #include <KUrlLabel>
00033 #include <KComboBox>
00034 #include <KLocale>
00035
00036 #include "kgpginterface.h"
00037 #include "convert.h"
00038 #include "images.h"
00039 #include "kgpgchangekey.h"
00040 #include "kgpgchangepass.h"
00041 #include "kgpgitemnode.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, 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 (date.isNull())
00110 date = QDate::currentDate();
00111
00112 m_datepicker = new KDatePicker(date, page);
00113 if (date.isNull()) {
00114 m_datepicker->setEnabled(false);
00115 m_unlimited->setChecked(true);
00116 }
00117
00118 QVBoxLayout *layout = new QVBoxLayout(page);
00119 layout->setSpacing(3);
00120 layout->addWidget(m_datepicker);
00121 layout->addWidget(m_unlimited);
00122
00123 connect(m_unlimited, SIGNAL(toggled(bool)), this, SLOT(slotEnableDate(bool)));
00124 connect(m_datepicker, SIGNAL(dateChanged(QDate)), this, SLOT(slotCheckDate(QDate)));
00125 connect(m_datepicker, SIGNAL(dateEntered(QDate)), this, SLOT(slotCheckDate(QDate)));
00126
00127 setMainWidget(page);
00128 show();
00129 }
00130
00131 QDate KgpgDateDialog::date() const
00132 {
00133 if (m_unlimited->isChecked())
00134 return QDate();
00135 else
00136 return m_datepicker->date();
00137 }
00138
00139 void KgpgDateDialog::slotCheckDate(const QDate &date)
00140 {
00141 enableButtonOk(date >= QDate::currentDate());
00142 }
00143
00144 void KgpgDateDialog::slotEnableDate(const bool &ison)
00145 {
00146 m_datepicker->setEnabled(!ison);
00147 if (ison)
00148 enableButtonOk(true);
00149 else
00150 slotCheckDate(m_datepicker->date());
00151 }
00152
00153 KgpgKeyInfo::KgpgKeyInfo(KGpgKeyNode *node, QWidget *parent)
00154 : KDialog(parent), keychange(new KGpgChangeKey(node))
00155 {
00156 m_node = node;
00157 m_key = node->getKey();
00158 init();
00159 }
00160
00161 KgpgKeyInfo::KgpgKeyInfo(KgpgCore::KgpgKey *key, QWidget *parent)
00162 : KDialog(parent), keychange(new KGpgChangeKey(key))
00163 {
00164 m_node = NULL;
00165 m_key = key;
00166 init();
00167 }
00168
00169 void KgpgKeyInfo::init()
00170 {
00171 setButtons(Ok | Apply | Cancel);
00172 setDefaultButton(Ok);
00173 setModal(true);
00174 enableButtonApply(false);
00175
00176 m_keywaschanged = false;
00177
00178 m_changepass = NULL;
00179
00180 QWidget *page = new QWidget(this);
00181 QWidget *top = new QWidget(page);
00182 QWidget *right = new QWidget(top);
00183
00184 QGroupBox *gr_properties = _keypropertiesGroup(top);
00185 QGroupBox *gr_photo = _photoGroup(right);
00186 QGroupBox *gr_buttons = _buttonsGroup(right);
00187 QGroupBox *gr_fingerprint = _fingerprintGroup(page);
00188
00189 QVBoxLayout *layout_right = new QVBoxLayout(right);
00190 layout_right->setSpacing(spacingHint());
00191 layout_right->setMargin(0);
00192 layout_right->addWidget(gr_photo);
00193 layout_right->addWidget(gr_buttons);
00194
00195 QHBoxLayout *layout_top = new QHBoxLayout(top);
00196 layout_top->setSpacing(spacingHint());
00197 layout_top->setMargin(0);
00198 layout_top->addWidget(gr_properties);
00199 layout_top->addWidget(right);
00200
00201 QVBoxLayout *layout_page = new QVBoxLayout(page);
00202 layout_page->setSpacing(spacingHint());
00203 layout_page->setMargin(0);
00204 layout_page->addWidget(top);
00205 layout_page->addWidget(gr_fingerprint);
00206
00207 setMainWidget(page);
00208
00209 connect(m_owtrust, SIGNAL(activated(int)), this, SLOT(slotChangeTrust(int)));
00210 connect(m_photoid, SIGNAL(activated (const QString &)), this, SLOT(slotLoadPhoto(const QString &)));
00211 connect(m_email, SIGNAL(leftClickedUrl(const QString &)), this, SLOT(slotOpenUrl(const QString &)));
00212 connect(this, SIGNAL(okClicked()), this, SLOT(slotPreOk()));
00213 connect(this, SIGNAL(cancelClicked()), this, SLOT(slotPreCancel()));
00214 connect(this, SIGNAL(applyClicked()), SLOT(slotApply()));
00215 connect(keychange, SIGNAL(done(int)), SLOT(slotApplied(int)));
00216
00217 displayKey();
00218 if (!m_hasphoto)
00219 m_photoid->setEnabled(false);
00220 else
00221 slotLoadPhoto(m_photoid->currentText());
00222 }
00223
00224 KgpgKeyInfo::~KgpgKeyInfo()
00225 {
00226 if (keychange)
00227 keychange->selfdestruct(false);
00228 if (!m_node)
00229 delete m_key;
00230 delete m_changepass;
00231 }
00232
00233 QGroupBox* KgpgKeyInfo::_keypropertiesGroup(QWidget *parent)
00234 {
00235 QGroupBox *group = new QGroupBox(i18n("Key properties"), parent);
00236
00237
00238
00239
00240 QWidget *widget_name = new QWidget(group);
00241
00242 m_name = new QLabel(widget_name);
00243 m_name->setTextInteractionFlags(Qt::TextSelectableByMouse);
00244
00245 m_email = new KUrlLabel(widget_name);
00246 m_email->setUnderline(false);
00247 m_email->setTextInteractionFlags(Qt::TextSelectableByMouse);
00248
00249
00250
00251
00252 QWidget *widget_properties = new QWidget(group);
00253
00254 QLabel *tl_id = new QLabel(i18n("Key ID:"), widget_properties);
00255 QLabel *tl_comment = new QLabel(i18n("Comment:"), widget_properties);
00256 QLabel *tl_creation = new QLabel(i18n("Creation:"), widget_properties);
00257 QLabel *tl_expiration = new QLabel(i18n("Expiration:"), widget_properties);
00258 QLabel *tl_trust = new QLabel(i18n("Trust:"), widget_properties);
00259 QLabel *tl_owtrust = new QLabel(i18n("Owner trust:"), widget_properties);
00260 QLabel *tl_algorithm = new QLabel(i18n("Algorithm:"), widget_properties);
00261 QLabel *tl_length = new QLabel(i18n("Length:"), widget_properties);
00262
00263 m_id = new QLabel(widget_properties);
00264 m_comment = new QLabel(widget_properties);
00265 m_creation = new QLabel(widget_properties);
00266 m_expiration = new QLabel(widget_properties);
00267 m_trust = new KgpgTrustLabel(widget_properties);
00268 m_owtrust = new KComboBox(widget_properties);
00269 m_algorithm = new QLabel(widget_properties);
00270 m_length = new QLabel(widget_properties);
00271
00272 m_owtrust->addItem(i18n("I do not know"));
00273 m_owtrust->addItem(i18n("I do NOT trust"));
00274 m_owtrust->addItem(i18n("Marginally"));
00275 m_owtrust->addItem(i18n("Fully"));
00276 m_owtrust->addItem(i18n("Ultimately"));
00277
00278 m_id->setTextInteractionFlags(Qt::TextSelectableByMouse);
00279 m_comment->setTextInteractionFlags(Qt::TextSelectableByMouse);
00280 m_creation->setTextInteractionFlags(Qt::TextSelectableByMouse);
00281 m_expiration->setTextInteractionFlags(Qt::TextSelectableByMouse);
00282 m_algorithm->setTextInteractionFlags(Qt::TextSelectableByMouse);
00283 m_length->setTextInteractionFlags(Qt::TextSelectableByMouse);
00284
00285 QHBoxLayout *layout_name = new QHBoxLayout(widget_name);
00286 layout_name->setMargin(0);
00287 layout_name->setSpacing(spacingHint());
00288 layout_name->addWidget(m_name);
00289 layout_name->addWidget(m_email);
00290 layout_name->addStretch();
00291
00292 QGridLayout *layout_properties = new QGridLayout(widget_properties);
00293 layout_properties->setMargin(0);
00294 layout_properties->setSpacing(spacingHint());
00295 layout_properties->addWidget(tl_id, 0, 0, Qt::AlignRight);
00296 layout_properties->addWidget(m_id, 0, 1);
00297 layout_properties->addWidget(tl_comment, 1, 0, Qt::AlignRight);
00298 layout_properties->addWidget(m_comment, 1, 1);
00299 layout_properties->addWidget(tl_creation, 2, 0, Qt::AlignRight);
00300 layout_properties->addWidget(m_creation, 2, 1);
00301 layout_properties->addWidget(tl_expiration, 3, 0, Qt::AlignRight);
00302 layout_properties->addWidget(m_expiration, 3, 1);
00303 layout_properties->addWidget(tl_trust, 4, 0, Qt::AlignRight);
00304 layout_properties->addWidget(m_trust, 4, 1);
00305 layout_properties->addWidget(tl_owtrust, 5, 0, Qt::AlignRight);
00306 layout_properties->addWidget(m_owtrust, 5, 1);
00307 layout_properties->addWidget(tl_algorithm, 6, 0, Qt::AlignRight);
00308 layout_properties->addWidget(m_algorithm, 6, 1);
00309 layout_properties->addWidget(tl_length, 7, 0, Qt::AlignRight);
00310 layout_properties->addWidget(m_length, 7, 1);
00311 layout_properties->setColumnStretch(1, 1);
00312 layout_properties->setRowStretch(8, 1);
00313
00314 QVBoxLayout *layout_keyproperties = new QVBoxLayout(group);
00315 layout_keyproperties->addWidget(widget_name);
00316 layout_keyproperties->addWidget(widget_properties);
00317
00318 return group;
00319 }
00320
00321 QGroupBox* KgpgKeyInfo::_photoGroup(QWidget *parent)
00322 {
00323 QGroupBox *group = new QGroupBox(i18n("Photo"), parent);
00324 m_photo = new QLabel(i18n("No Photo"), group);
00325 m_photoid = new KComboBox(group);
00326
00327 m_photo->setMinimumSize(120, 140);
00328 m_photo->setMaximumSize(32767, 140);
00329 m_photo->setLineWidth(2);
00330 m_photo->setAlignment(Qt::AlignCenter);
00331 m_photo->setFrameShape(QFrame::Box);
00332 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>");
00333
00334 QVBoxLayout *layout = new QVBoxLayout(group);
00335 layout->setMargin(marginHint());
00336 layout->setSpacing(spacingHint());
00337 layout->addWidget(m_photo);
00338 layout->addWidget(m_photoid);
00339 layout->addStretch();
00340
00341 return group;
00342 }
00343
00344 QGroupBox* KgpgKeyInfo::_buttonsGroup(QWidget *parent)
00345 {
00346 QGroupBox *group = new QGroupBox(parent);
00347 m_disable = new QCheckBox(i18n("Disable key"), group);
00348
00349 if (m_key->secret())
00350 {
00351 m_expirationbtn = new KPushButton(i18n("Change Expiration..."), group);
00352 m_password = new KPushButton(i18n("Change Passphrase..."), group);
00353
00354 connect(m_expirationbtn, SIGNAL(clicked()), this, SLOT(slotChangeDate()));
00355 connect(m_password, SIGNAL(clicked()), this, SLOT(slotChangePass()));
00356 }
00357 else
00358 {
00359 m_password = 0;
00360 m_expirationbtn = 0;
00361 }
00362
00363 connect(m_disable, SIGNAL(toggled(bool)), this, SLOT(slotDisableKey(bool)));
00364
00365 QVBoxLayout *layout = new QVBoxLayout(group);
00366 layout->setMargin(marginHint());
00367 layout->setSpacing(spacingHint());
00368 layout->addWidget(m_disable);
00369
00370 if (m_key->secret())
00371 {
00372 layout->addWidget(m_expirationbtn);
00373 layout->addWidget(m_password);
00374 }
00375
00376 return group;
00377 }
00378
00379 QGroupBox* KgpgKeyInfo::_fingerprintGroup(QWidget *parent)
00380 {
00381 QGroupBox *group = new QGroupBox(i18n("Fingerprint"), parent);
00382 m_fingerprint = new QLabel(group);
00383 m_fingerprint->setTextInteractionFlags(Qt::TextSelectableByMouse);
00384
00385 QVBoxLayout *layout = new QVBoxLayout(group);
00386 layout->setMargin(marginHint());
00387 layout->setSpacing(spacingHint());
00388 layout->addWidget(m_fingerprint);
00389
00390 return group;
00391 }
00392
00393 void KgpgKeyInfo::reloadKey()
00394 {
00395 KgpgInterface *interface = new KgpgInterface();
00396 KgpgKeyList listkeys = interface->readPublicKeys(true, m_key->fullId());
00397 delete interface;
00398
00399 Q_ASSERT(listkeys.count() > 0);
00400
00401 delete m_key;
00402 m_key = new KgpgKey(listkeys.at(0));
00403 displayKey();
00404 }
00405
00406 void KgpgKeyInfo::displayKey()
00407 {
00408 KgpgKeySub subkey;
00409
00410
00411 KgpgKeySubListPtr sublist = m_key->subList();
00412 for (int i = 0; i < sublist->count(); ++i)
00413 {
00414 KgpgKeySub temp = sublist->at(i);
00415 if (temp.type() == SKT_ENCRYPTION)
00416 {
00417 subkey = temp;
00418 break;
00419 }
00420 }
00421
00422 QString name = m_key->name();
00423 setCaption(name);
00424 m_name->setText("<qt><b>" + name + "</b></qt>");
00425
00426 if (m_key->email().isEmpty())
00427 {
00428 m_email->setText(i18nc("no email address", "none"));
00429 m_email->setUrl("");
00430 }
00431 else
00432 {
00433 m_email->setText("<qt><b><" + m_key->email() + "></b></qt>");
00434 m_email->setUrl("mailto:" + name + '<' + m_key->email() + '>');
00435 }
00436
00437 KgpgKeyTrust keytrust = m_key->valid() ? m_key->trust() : TRUST_DISABLED;
00438 QString tr = Convert::toString(keytrust);
00439 QColor trustcolor = Convert::toColor(keytrust);
00440
00441 m_id->setText(m_key->fullId());
00442 m_algorithm->setText(Convert::toString(m_key->algorithm()) + " / " + Convert::toString(subkey.algorithm()));
00443 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>");
00444 m_creation->setText(m_key->creation());
00445 m_expiration->setText(m_key->expiration());
00446 m_trust->setText(tr);
00447 m_trust->setColor(trustcolor);
00448 m_length->setText(QString::number(m_key->size()) + " / " + QString::number(subkey.size()));
00449 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>");
00450 m_fingerprint->setText(m_key->fingerprintBeautified());
00451
00452 if (m_key->comment().isEmpty())
00453 m_comment->setText(i18nc("no key comment", "none"));
00454 else
00455 m_comment->setText(m_key->comment());
00456
00457 QStringList photolist = m_key->photoList();
00458 m_photoid->clear();
00459 if (photolist.isEmpty())
00460 {
00461 m_photoid->setVisible(false);
00462 m_hasphoto = false;
00463 }
00464 else
00465 {
00466 m_photoid->setVisible(true);
00467 m_hasphoto = true;
00468 m_photoid->addItems(photolist);
00469 }
00470
00471 switch (m_key->ownerTrust())
00472 {
00473 case OWTRUST_NONE:
00474 m_owtrust->setCurrentIndex(1);
00475 break;
00476
00477 case OWTRUST_MARGINAL:
00478 m_owtrust->setCurrentIndex(2);
00479 break;
00480
00481 case OWTRUST_FULL:
00482 m_owtrust->setCurrentIndex(3);
00483 break;
00484
00485 case OWTRUST_ULTIMATE:
00486 m_owtrust->setCurrentIndex(4);
00487 break;
00488
00489 case OWTRUST_UNDEFINED:
00490 default:
00491 m_owtrust->setCurrentIndex(0);
00492 break;
00493 }
00494
00495 if (!m_key->valid())
00496 m_disable->setChecked(true);
00497 }
00498
00499 void KgpgKeyInfo::slotOpenUrl(const QString &url) const
00500 {
00501 KToolInvocation::invokeBrowser(url);
00502 }
00503
00504 void KgpgKeyInfo::slotLoadPhoto(const QString &uid)
00505 {
00506 KgpgInterface *interface = new KgpgInterface();
00507 connect(interface, SIGNAL(loadPhotoFinished(QPixmap, KgpgInterface*)), this, SLOT(slotSetPhoto(QPixmap, KgpgInterface*)));
00508 interface->loadPhoto(m_key->fullId(), uid);
00509 }
00510
00511 void KgpgKeyInfo::slotSetPhoto(const QPixmap &pixmap, KgpgInterface *interface)
00512 {
00513 interface->deleteLater();
00514
00515 QImage img = pixmap.toImage();
00516 QPixmap pix = QPixmap::fromImage(img.scaled(m_photo->width(), m_photo->height(), Qt::KeepAspectRatio));
00517 m_photo->setPixmap(pix);
00518 }
00519
00520 void KgpgKeyInfo::slotPreOk()
00521 {
00522 if (m_keywaschanged && m_node)
00523 emit keyNeedsRefresh(m_node);
00524 keychange->selfdestruct(true);
00525 keychange = NULL;
00526 accept();
00527 }
00528
00529 void KgpgKeyInfo::slotChangeDate()
00530 {
00531 KgpgDateDialog *dialog = new KgpgDateDialog(this, m_key->expirationDate());
00532 if (dialog->exec() == QDialog::Accepted) {
00533 keychange->setExpiration(dialog->date());
00534 enableButtonApply(keychange->wasChanged());
00535 }
00536 delete dialog;
00537 }
00538
00539 void KgpgKeyInfo::slotDisableKey(const bool &ison)
00540 {
00541 keychange->setDisable(ison);
00542 enableButtonApply(keychange->wasChanged());
00543 }
00544
00545 void KgpgKeyInfo::slotChangePass()
00546 {
00547 if (m_changepass == NULL) {
00548 m_changepass = new KGpgChangePass(this, m_key->fingerprint());
00549
00550 connect(m_changepass, SIGNAL(done(int)), SLOT(slotInfoPasswordChanged(int)));
00551 }
00552
00553 m_changepass->start();
00554 QApplication::setOverrideCursor(QCursor(Qt::BusyCursor));
00555 }
00556
00557 void KgpgKeyInfo::slotInfoPasswordChanged(const int &res)
00558 {
00559 if (res == 2)
00560 KPassivePopup::message(i18n("Passphrase for the key was changed"), QString(), Images::kgpg(), this);
00561 else 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 QApplication::restoreOverrideCursor();
00564 }
00565
00566 void KgpgKeyInfo::slotChangeTrust(const int &newtrust)
00567 {
00568 keychange->setOwTrust(KgpgKeyOwnerTrust(newtrust + 1));
00569 enableButtonApply(keychange->wasChanged());
00570 }
00571
00572 void KgpgKeyInfo::setControlEnable(const bool &b)
00573 {
00574 m_owtrust->setEnabled(b);
00575 m_disable->setEnabled(b);
00576 enableButtonApply(b && keychange->wasChanged());
00577
00578 if (m_expirationbtn)
00579 m_expirationbtn->setEnabled(b);
00580 if (m_password)
00581 m_password->setEnabled(b);
00582
00583 if (b)
00584 QApplication::restoreOverrideCursor();
00585 else
00586 QApplication::setOverrideCursor(QCursor(Qt::BusyCursor));
00587 }
00588
00589 void KgpgKeyInfo::slotApply()
00590 {
00591 setControlEnable(false);
00592 keychange->apply();
00593 }
00594
00595 void KgpgKeyInfo::slotApplied(int result)
00596 {
00597 if (result) {
00598 KMessageBox::error(this, i18n("Changing key properties failed."), i18n("Key properties"));
00599 } else {
00600 m_keywaschanged = true;
00601 reloadKey();
00602 }
00603 setControlEnable(true);
00604 }
00605
00606 void KgpgKeyInfo::slotPreCancel()
00607 {
00608 if (m_keywaschanged && m_node)
00609 emit keyNeedsRefresh(m_node);
00610 reject();
00611 }
00612
00613 #include "keyinfodialog.moc"