X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fsettingspages%2Fidentityeditwidget.cpp;h=234232b96e513b9a27f0e533dc8fbcfbdad891fd;hp=0f270c7f39b7bd802d8983ff255b62649d476d44;hb=cc6e7c08709c4e761e2fd9c2e322751015497003;hpb=f3d6f8088d8be6af9319a99fb8d2fee2837b540a diff --git a/src/qtui/settingspages/identityeditwidget.cpp b/src/qtui/settingspages/identityeditwidget.cpp index 0f270c7f..234232b9 100644 --- a/src/qtui/settingspages/identityeditwidget.cpp +++ b/src/qtui/settingspages/identityeditwidget.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-2014 by the Quassel Project * + * Copyright (C) 2005-2019 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -23,54 +23,50 @@ #include #include #include -#include +#include #include +#include #include -#include - -#if QT_VERSION < 0x050000 -# include -#else -# include -#endif #include "client.h" +#include "icon.h" +#include "util.h" -IdentityEditWidget::IdentityEditWidget(QWidget *parent) +IdentityEditWidget::IdentityEditWidget(QWidget* parent) : QWidget(parent) { ui.setupUi(this); - ui.addNick->setIcon(QIcon::fromTheme("list-add")); - ui.deleteNick->setIcon(QIcon::fromTheme("edit-delete")); - ui.renameNick->setIcon(QIcon::fromTheme("edit-rename")); - ui.nickUp->setIcon(QIcon::fromTheme("go-up")); - ui.nickDown->setIcon(QIcon::fromTheme("go-down")); + ui.addNick->setIcon(icon::get("list-add")); + ui.deleteNick->setIcon(icon::get("edit-delete")); + ui.renameNick->setIcon(icon::get("edit-rename")); + ui.nickUp->setIcon(icon::get("go-up")); + ui.nickDown->setIcon(icon::get("go-down")); // We need to know whenever the state of input widgets changes... - connect(ui.realName, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); - connect(ui.nicknameList, SIGNAL(itemChanged(QListWidgetItem *)), this, SIGNAL(widgetHasChanged())); - connect(ui.awayNick, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); - connect(ui.awayReason, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); - connect(ui.autoAwayEnabled, SIGNAL(clicked(bool)), this, SIGNAL(widgetHasChanged())); - connect(ui.autoAwayTime, SIGNAL(valueChanged(int)), this, SIGNAL(widgetHasChanged())); - connect(ui.autoAwayReason, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); - connect(ui.autoAwayReasonEnabled, SIGNAL(clicked(bool)), this, SIGNAL(widgetHasChanged())); - connect(ui.detachAwayEnabled, SIGNAL(clicked(bool)), this, SIGNAL(widgetHasChanged())); - connect(ui.detachAwayReason, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); - connect(ui.ident, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); - connect(ui.kickReason, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); - connect(ui.partReason, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); - connect(ui.quitReason, SIGNAL(textEdited(const QString &)), this, SIGNAL(widgetHasChanged())); + connect(ui.realName, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.nicknameList, &QListWidget::itemChanged, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.awayNick, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.awayReason, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.autoAwayEnabled, &QGroupBox::clicked, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.autoAwayTime, selectOverload(&QSpinBox::valueChanged), this, &IdentityEditWidget::widgetHasChanged); + connect(ui.autoAwayReason, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.autoAwayReasonEnabled, &QAbstractButton::clicked, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.detachAwayEnabled, &QGroupBox::clicked, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.detachAwayReason, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.ident, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.kickReason, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.partReason, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); + connect(ui.quitReason, &QLineEdit::textEdited, this, &IdentityEditWidget::widgetHasChanged); setWidgetStates(); - connect(ui.nicknameList, SIGNAL(itemSelectionChanged()), this, SLOT(setWidgetStates())); + connect(ui.nicknameList, &QListWidget::itemSelectionChanged, this, &IdentityEditWidget::setWidgetStates); - connect(ui.continueUnsecured, SIGNAL(clicked()), this, SIGNAL(requestEditSsl())); + connect(ui.continueUnsecured, &QAbstractButton::clicked, this, &IdentityEditWidget::requestEditSsl); // we would need this if we enabled drag and drop in the nicklist... - //connect(ui.nicknameList, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(setWidgetStates())); - //connect(ui.nicknameList->model(), SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(nicklistHasChanged())); + // connect(ui.nicknameList, &QListWidget::rowsInserted, this, &IdentityEditWidget::setWidgetStates); + // connect(ui.nicknameList->model(), &NickListModel::rowsInserted, this, IdentityEditWidget::nicklistHasChanged); // disabling unused stuff ui.autoAwayEnabled->hide(); @@ -85,15 +81,59 @@ IdentityEditWidget::IdentityEditWidget(QWidget *parent) ui.sslCertGroupBox->setAcceptDrops(true); ui.sslCertGroupBox->installEventFilter(this); #endif -} + if (Client::isCoreFeatureEnabled(Quassel::Feature::AwayFormatTimestamp)) { + // Core allows formatting %%timestamp%% messages in away strings. Update tooltips. + QString strFormatTooltip; + QTextStream formatTooltip(&strFormatTooltip, QIODevice::WriteOnly); + formatTooltip << ""; + + // Function to add a row to the tooltip table + auto addRow = [&](const QString& key, const QString& value, bool condition) { + if (condition) { + formatTooltip << "" << key << "" << value << ""; + } + }; + + // Original tooltip goes here + formatTooltip << "

%1

"; + // New timestamp formatting guide here + formatTooltip << "

" + << tr("You can add date/time to this message " + "using the syntax: " + "
%%<format>%%, where " + "<format> is:") + << "

"; + formatTooltip << ""; + addRow("hh", tr("the hour"), true); + addRow("mm", tr("the minutes"), true); + addRow("ss", tr("seconds"), true); + addRow("AP", tr("AM/PM"), true); + addRow("dd", tr("day"), true); + addRow("MM", tr("month"), true); + addRow("t", tr("current timezone"), true); + formatTooltip << "
"; + formatTooltip << "

" << tr("Example: Away since %%hh:mm%% on %%dd.MM%%.") << "

"; + formatTooltip << "

" + << tr("%%%% without anything inside represents %%. Other format " + "codes are available.") + << "

"; + formatTooltip << "
"; + + // Split up the message to allow re-using translations: + // [Original tool-tip] [Timestamp format message] + ui.awayReason->setToolTip(strFormatTooltip.arg(ui.awayReason->toolTip())); + ui.detachAwayEnabled->setToolTip(strFormatTooltip.arg(ui.detachAwayEnabled->toolTip())); + } // else: Do nothing, leave the original translated string +} void IdentityEditWidget::setWidgetStates() { if (ui.nicknameList->selectedItems().count()) { ui.renameNick->setEnabled(true); ui.nickUp->setEnabled(ui.nicknameList->row(ui.nicknameList->selectedItems()[0]) > 0); - ui.nickDown->setEnabled(ui.nicknameList->row(ui.nicknameList->selectedItems()[0]) < ui.nicknameList->count()-1); + ui.nickDown->setEnabled(ui.nicknameList->row(ui.nicknameList->selectedItems()[0]) < ui.nicknameList->count() - 1); } else { ui.renameNick->setDisabled(true); @@ -103,8 +143,7 @@ void IdentityEditWidget::setWidgetStates() ui.deleteNick->setEnabled(ui.nicknameList->count() > 1); } - -void IdentityEditWidget::displayIdentity(CertIdentity *id, CertIdentity *saveId) +void IdentityEditWidget::displayIdentity(CertIdentity* id, CertIdentity* saveId) { if (saveId) { saveToIdentity(saveId); @@ -116,10 +155,11 @@ void IdentityEditWidget::displayIdentity(CertIdentity *id, CertIdentity *saveId) ui.realName->setText(id->realName()); ui.nicknameList->clear(); ui.nicknameList->addItems(id->nicks()); - //for(int i = 0; i < ui.nicknameList->count(); i++) { + // for(int i = 0; i < ui.nicknameList->count(); i++) { // ui.nicknameList->item(i)->setFlags(Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled); //} - if (ui.nicknameList->count()) ui.nicknameList->setCurrentRow(0); + if (ui.nicknameList->count()) + ui.nicknameList->setCurrentRow(0); ui.awayNick->setText(id->awayNick()); ui.awayReason->setText(id->awayReason()); ui.autoAwayEnabled->setChecked(id->autoAwayEnabled()); @@ -138,8 +178,7 @@ void IdentityEditWidget::displayIdentity(CertIdentity *id, CertIdentity *saveId) #endif } - -void IdentityEditWidget::saveToIdentity(CertIdentity *id) +void IdentityEditWidget::saveToIdentity(CertIdentity* id) { QRegExp linebreaks = QRegExp("[\\r\\n]"); id->setRealName(ui.realName->text()); @@ -164,77 +203,77 @@ void IdentityEditWidget::saveToIdentity(CertIdentity *id) id->setPartReason(ui.partReason->text().remove(linebreaks)); id->setQuitReason(ui.quitReason->text().remove(linebreaks)); #ifdef HAVE_SSL - id->setSslKey(QSslKey(ui.keyTypeLabel->property("sslKey").toByteArray(), (QSsl::KeyAlgorithm)(ui.keyTypeLabel->property("sslKeyType").toInt()))); + id->setSslKey( + QSslKey(ui.keyTypeLabel->property("sslKey").toByteArray(), (QSsl::KeyAlgorithm)(ui.keyTypeLabel->property("sslKeyType").toInt()))); id->setSslCert(QSslCertificate(ui.certOrgLabel->property("sslCert").toByteArray())); #endif } - void IdentityEditWidget::on_addNick_clicked() { QStringList existing; - for (int i = 0; i < ui.nicknameList->count(); i++) existing << ui.nicknameList->item(i)->text(); + for (int i = 0; i < ui.nicknameList->count(); i++) + existing << ui.nicknameList->item(i)->text(); NickEditDlg dlg(QString(), existing, this); if (dlg.exec() == QDialog::Accepted) { ui.nicknameList->addItem(dlg.nick()); - ui.nicknameList->setCurrentRow(ui.nicknameList->count()-1); + ui.nicknameList->setCurrentRow(ui.nicknameList->count() - 1); setWidgetStates(); emit widgetHasChanged(); } } - void IdentityEditWidget::on_deleteNick_clicked() { // no confirmation, since a nickname is really nothing hard to recreate if (ui.nicknameList->selectedItems().count()) { delete ui.nicknameList->takeItem(ui.nicknameList->row(ui.nicknameList->selectedItems()[0])); - ui.nicknameList->setCurrentRow(qMin(ui.nicknameList->currentRow()+1, ui.nicknameList->count()-1)); + ui.nicknameList->setCurrentRow(qMin(ui.nicknameList->currentRow() + 1, ui.nicknameList->count() - 1)); setWidgetStates(); emit widgetHasChanged(); } } - void IdentityEditWidget::on_renameNick_clicked() { - if (!ui.nicknameList->selectedItems().count()) return; + if (!ui.nicknameList->selectedItems().count()) + return; QString old = ui.nicknameList->selectedItems()[0]->text(); QStringList existing; - for (int i = 0; i < ui.nicknameList->count(); i++) existing << ui.nicknameList->item(i)->text(); + for (int i = 0; i < ui.nicknameList->count(); i++) + existing << ui.nicknameList->item(i)->text(); NickEditDlg dlg(old, existing, this); if (dlg.exec() == QDialog::Accepted) { ui.nicknameList->selectedItems()[0]->setText(dlg.nick()); } } - void IdentityEditWidget::on_nickUp_clicked() { - if (!ui.nicknameList->selectedItems().count()) return; + if (!ui.nicknameList->selectedItems().count()) + return; int row = ui.nicknameList->row(ui.nicknameList->selectedItems()[0]); if (row > 0) { - ui.nicknameList->insertItem(row-1, ui.nicknameList->takeItem(row)); - ui.nicknameList->setCurrentRow(row-1); + ui.nicknameList->insertItem(row - 1, ui.nicknameList->takeItem(row)); + ui.nicknameList->setCurrentRow(row - 1); setWidgetStates(); emit widgetHasChanged(); } } - void IdentityEditWidget::on_nickDown_clicked() { - if (!ui.nicknameList->selectedItems().count()) return; + if (!ui.nicknameList->selectedItems().count()) + return; int row = ui.nicknameList->row(ui.nicknameList->selectedItems()[0]); - if (row < ui.nicknameList->count()-1) { - ui.nicknameList->insertItem(row+1, ui.nicknameList->takeItem(row)); - ui.nicknameList->setCurrentRow(row+1); + if (row < ui.nicknameList->count() - 1) { + ui.nicknameList->insertItem(row + 1, ui.nicknameList->takeItem(row)); + ui.nicknameList->setCurrentRow(row + 1); setWidgetStates(); emit widgetHasChanged(); } } - void IdentityEditWidget::showAdvanced(bool advanced) { int idx = ui.tabWidget->indexOf(ui.advancedTab); @@ -250,7 +289,6 @@ void IdentityEditWidget::showAdvanced(bool advanced) } } - void IdentityEditWidget::setSslState(SslState state) { switch (state) { @@ -266,25 +304,23 @@ void IdentityEditWidget::setSslState(SslState state) } } - #ifdef HAVE_SSL -bool IdentityEditWidget::eventFilter(QObject *watched, QEvent *event) +bool IdentityEditWidget::eventFilter(QObject* watched, QEvent* event) { bool isCert = (watched == ui.sslCertGroupBox); switch (event->type()) { case QEvent::DragEnter: - sslDragEnterEvent(static_cast(event)); + sslDragEnterEvent(static_cast(event)); return true; case QEvent::Drop: - sslDropEvent(static_cast(event), isCert); + sslDropEvent(static_cast(event), isCert); return true; default: return false; } } - -void IdentityEditWidget::sslDragEnterEvent(QDragEnterEvent *event) +void IdentityEditWidget::sslDragEnterEvent(QDragEnterEvent* event) { if (event->mimeData()->hasFormat("text/uri-list") || event->mimeData()->hasFormat("text/uri")) { event->setDropAction(Qt::CopyAction); @@ -292,8 +328,7 @@ void IdentityEditWidget::sslDragEnterEvent(QDragEnterEvent *event) } } - -void IdentityEditWidget::sslDropEvent(QDropEvent *event, bool isCert) +void IdentityEditWidget::sslDropEvent(QDropEvent* event, bool isCert) { QByteArray rawUris; if (event->mimeData()->hasFormat("text/uri-list")) @@ -318,25 +353,19 @@ void IdentityEditWidget::sslDropEvent(QDropEvent *event, bool isCert) emit widgetHasChanged(); } - void IdentityEditWidget::on_clearOrLoadKeyButton_clicked() { QSslKey key; if (ui.keyTypeLabel->property("sslKey").toByteArray().isEmpty()) - key = keyByFilename(QFileDialog::getOpenFileName(this, tr("Load a Key"), -#if QT_VERSION < 0x050000 - QDesktopServices::storageLocation(QDesktopServices::HomeLocation))); -#else - QStandardPaths::writableLocation(QStandardPaths::HomeLocation))); -#endif + key = keyByFilename( + QFileDialog::getOpenFileName(this, tr("Load a Key"), QStandardPaths::writableLocation(QStandardPaths::HomeLocation))); showKeyState(key); emit widgetHasChanged(); } - -QSslKey IdentityEditWidget::keyByFilename(const QString &filename) +QSslKey IdentityEditWidget::keyByFilename(const QString& filename) { QSslKey key; @@ -346,19 +375,29 @@ QSslKey IdentityEditWidget::keyByFilename(const QString &filename) keyFile.close(); for (int i = 0; i < 2; i++) { - for (int j = 0; j < 2; j++) { + // On Qt5.5+, support QSsl::KeyAlgorithm::Rsa (1), QSsl::KeyAlgorithm::Dsa (2), and QSsl::KeyAlgorithm::Ec (3) + for (int j = 1; j < 4; j++) { key = QSslKey(keyRaw, (QSsl::KeyAlgorithm)j, (QSsl::EncodingFormat)i); if (!key.isNull()) goto returnKey; } } - QMessageBox::information(this, tr("Failed to read key"), tr("Failed to read the key file. It is either incompatible or invalid. Note that the key file must not have a passphrase.")); + QMessageBox::information( + this, + tr("Failed to read key"), + tr("Failed to read the key file. It is either incompatible or invalid. Note that the key file must not have a passphrase.")); returnKey: + if (!key.isNull() && key.algorithm() == QSsl::KeyAlgorithm::Ec && !Client::isCoreFeatureEnabled(Quassel::Feature::EcdsaCertfpKeys)) { + QMessageBox:: + information(this, + tr("Core does not support ECDSA keys"), + tr("You loaded an ECDSA key, but the core does not support ECDSA keys. Please contact the core administrator.")); + key.clear(); + } return key; } - -void IdentityEditWidget::showKeyState(const QSslKey &key) +void IdentityEditWidget::showKeyState(const QSslKey& key) { if (key.isNull()) { ui.keyTypeLabel->setText(tr("No Key loaded")); @@ -369,11 +408,14 @@ void IdentityEditWidget::showKeyState(const QSslKey &key) case QSsl::Rsa: ui.keyTypeLabel->setText(tr("RSA")); break; + case QSsl::Ec: + ui.keyTypeLabel->setText(tr("ECDSA")); + break; case QSsl::Dsa: ui.keyTypeLabel->setText(tr("DSA")); break; default: - ui.keyTypeLabel->setText(tr("No Key loaded")); + ui.keyTypeLabel->setText(tr("Invalid key or no key loaded")); } ui.clearOrLoadKeyButton->setText(tr("Clear")); } @@ -381,24 +423,18 @@ void IdentityEditWidget::showKeyState(const QSslKey &key) ui.keyTypeLabel->setProperty("sslKeyType", (int)key.algorithm()); } - void IdentityEditWidget::on_clearOrLoadCertButton_clicked() { QSslCertificate cert; if (ui.certOrgLabel->property("sslCert").toByteArray().isEmpty()) - cert = certByFilename(QFileDialog::getOpenFileName(this, tr("Load a Certificate"), -#if QT_VERSION < 0x050000 - QDesktopServices::storageLocation(QDesktopServices::HomeLocation))); -#else - QStandardPaths::writableLocation(QStandardPaths::HomeLocation))); -#endif + cert = certByFilename( + QFileDialog::getOpenFileName(this, tr("Load a Certificate"), QStandardPaths::writableLocation(QStandardPaths::HomeLocation))); showCertState(cert); emit widgetHasChanged(); } - -QSslCertificate IdentityEditWidget::certByFilename(const QString &filename) +QSslCertificate IdentityEditWidget::certByFilename(const QString& filename) { QSslCertificate cert; QFile certFile(filename); @@ -414,8 +450,7 @@ QSslCertificate IdentityEditWidget::certByFilename(const QString &filename) return cert; } - -void IdentityEditWidget::showCertState(const QSslCertificate &cert) +void IdentityEditWidget::showCertState(const QSslCertificate& cert) { if (cert.isNull()) { ui.certOrgLabel->setText(tr("No Certificate loaded")); @@ -423,17 +458,11 @@ void IdentityEditWidget::showCertState(const QSslCertificate &cert) ui.clearOrLoadCertButton->setText(tr("Load")); } else { -#if QT_VERSION < 0x050000 - ui.certOrgLabel->setText(cert.subjectInfo(QSslCertificate::Organization)); - ui.certCNameLabel->setText(cert.subjectInfo(QSslCertificate::CommonName)); -#else ui.certOrgLabel->setText(cert.subjectInfo(QSslCertificate::Organization).join(", ")); ui.certCNameLabel->setText(cert.subjectInfo(QSslCertificate::CommonName).join(", ")); -#endif ui.clearOrLoadCertButton->setText(tr("Clear")); } ui.certOrgLabel->setProperty("sslCert", cert.toPem()); } - -#endif //HAVE_SSL +#endif // HAVE_SSL