diff --git a/widget/form/addfriendform.cpp b/widget/form/addfriendform.cpp index ba186df42..ae38d2f92 100644 --- a/widget/form/addfriendform.cpp +++ b/widget/form/addfriendform.cpp @@ -1,9 +1,14 @@ #include "addfriendform.h" -#include "ui_widget.h" -#include -AddFriendForm::AddFriendForm() +#include +#include + +#define TOX_ID_SIZE 76 + +AddFriendForm::AddFriendForm() : dns(this) { + dns.setType(QDnsLookup::TXT); + main = new QWidget(), head = new QWidget(); QFont bold; bold.setBold(true); @@ -25,6 +30,13 @@ AddFriendForm::AddFriendForm() headLayout.addWidget(&headLabel); connect(&sendButton, SIGNAL(clicked()), this, SLOT(onSendTriggered())); + connect(&dns, SIGNAL(finished()), this, SLOT(handleDnsLookup())); +} + +AddFriendForm::~AddFriendForm() +{ + head->deleteLater(); + main->deleteLater(); } void AddFriendForm::show(Ui::Widget &ui) @@ -35,13 +47,81 @@ void AddFriendForm::show(Ui::Widget &ui) head->show(); } +bool AddFriendForm::isToxId(const QString &value) const +{ + const QRegularExpression hexRegExp("^[A-Fa-f0-9]+$"); + return value.length() == TOX_ID_SIZE && value.contains(hexRegExp); +} + +void AddFriendForm::showWarning(const QString &message) const +{ + QMessageBox warning(main); + warning.setText(message); + warning.setIcon(QMessageBox::Warning); + warning.exec(); +} + +QString AddFriendForm::getMessage() const +{ + const QString msg = message.toPlainText(); + return !msg.isEmpty() ? msg : "Tox me maybe?"; +} + void AddFriendForm::onSendTriggered() { - QString id = toxId.text(), msg = message.toPlainText(); - if (id.isEmpty()) - return; - if (msg.isEmpty()) - msg = "Tox me maybe?"; + QString id = toxId.text().trimmed(); - emit friendRequested(id, msg); + if (id.isEmpty()) { + showWarning("Please fill in a valid Tox ID"); + } else if (isToxId(id)) { + emit friendRequested(id, getMessage()); + } else { + id = id.replace("@", "._tox."); + dns.setName(id); + dns.lookup(); + } +} + +void AddFriendForm::handleDnsLookup() +{ + const QString idKeyWord("id="); + + if (dns.error() != QDnsLookup::NoError) { + showWarning("Error while looking up DNS"); + return; + } + + const QList textRecords = dns.textRecords(); + if (textRecords.length() != 1) { + showWarning("Unexpected number of text records"); + return; + } + + const QList textRecordValues = textRecords.first().values(); + if (textRecordValues.length() != 1) { + showWarning("Unexpected number of values in text record"); + return; + } + + const QString entry(textRecordValues.first()); + int idx = entry.indexOf(idKeyWord); + if (idx < 0) { + showWarning("The DNS lookup does not contain any Tox ID"); + return; + } + + idx += idKeyWord.length(); + if (entry.length() < idx + static_cast(TOX_ID_SIZE)) { + showWarning("The DNS lookup does not contain a valid Tox ID"); + return; + } + + const QString friendAdress = entry.mid(idx, TOX_ID_SIZE); + if (!isToxId(friendAdress)) { + showWarning("The DNS lookup does not contain a valid Tox ID"); + return; + } + + // finally we got it + emit friendRequested(friendAdress, getMessage()); } diff --git a/widget/form/addfriendform.h b/widget/form/addfriendform.h index 72fb0fd9f..de049b49a 100644 --- a/widget/form/addfriendform.h +++ b/widget/form/addfriendform.h @@ -1,27 +1,33 @@ #ifndef ADDFRIENDFORM_H #define ADDFRIENDFORM_H +#include "ui_widget.h" + #include #include #include #include #include - -#include "ui_widget.h" +#include class AddFriendForm : public QObject { Q_OBJECT public: AddFriendForm(); + ~AddFriendForm(); void show(Ui::Widget& ui); + bool isToxId(const QString& value) const; + void showWarning(const QString& message) const; + QString getMessage() const; signals: void friendRequested(const QString& friendAddress, const QString& message); private slots: void onSendTriggered(); + void handleDnsLookup(); private: QLabel headLabel, toxIdLabel, messageLabel; @@ -30,6 +36,9 @@ private: QTextEdit message; QVBoxLayout layout, headLayout; QWidget *head, *main; + + /** will be used for dns discovery if necessary */ + QDnsLookup dns; }; #endif // ADDFRIENDFORM_H