/* * accountregdlg.cpp - dialogs for manipulating PsiAccounts * Copyright (C) 2001, 2002, 2006 Justin Karneges, Remko Troncon * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include "accountregdlg.h" #include "proxy.h" #include "serverlistquerier.h" #include "miniclient.h" #include "xmpp_tasks.h" #include "psioptions.h" #include "jidutil.h" #include "textutil.h" #include "xdata_widget.h" using namespace XMPP; AccountRegDlg::AccountRegDlg(ProxyManager *pm, QWidget *parent) : QDialog(parent) { ui_.setupUi(this); setModal(false); // TODO: If the domain is fixed, and the connection settings are fixed, skip first // step // Initialize settings ssl_ = UserAccount::SSL_Auto; legacy_ssl_probe_ = true; port_ = 5222; // Server select button connect(ui_.le_server,SIGNAL(popup()),SLOT(selectServer())); serverlist_querier_ = new ServerListQuerier(this); connect(serverlist_querier_,SIGNAL(listReceived(const QStringList&)),SLOT(serverListReceived(const QStringList&))); connect(serverlist_querier_,SIGNAL(error(const QString&)),SLOT(serverListError(const QString&))); // Manual Host/Port ui_.le_host->setEnabled(false); ui_.lb_host->setEnabled(false); ui_.le_port->setEnabled(false); ui_.lb_port->setEnabled(false); connect(ui_.ck_host, SIGNAL(toggled(bool)), SLOT(hostToggled(bool))); // SSL ui_.cb_ssl->addItem(tr("Always"),UserAccount::SSL_Yes); ui_.cb_ssl->addItem(tr("When available"),UserAccount::SSL_Auto); ui_.cb_ssl->addItem(tr("Legacy SSL"), UserAccount::SSL_Legacy); ui_.cb_ssl->setCurrentIndex(ui_.cb_ssl->findData(ssl_)); connect(ui_.cb_ssl, SIGNAL(activated(int)), SLOT(sslActivated(int))); ui_.ck_legacy_ssl_probe->setChecked(legacy_ssl_probe_); // Cancel and next buttons connect(ui_.pb_cancel, SIGNAL(clicked()), SLOT(close())); connect(ui_.pb_next, SIGNAL(clicked()), SLOT(next())); // Proxy proxy_manager_ = pm; proxy_chooser_ = proxy_manager_->createProxyChooser(ui_.gb_connection); replaceWidget(ui_.lb_proxychooser, proxy_chooser_); proxy_chooser_->fixTabbing(ui_.ck_legacy_ssl_probe, ui_.pb_cancel); proxy_chooser_->setCurrentItem(0); // Fields pane QVBoxLayout *fields_layout = new QVBoxLayout(ui_.page_fields); fields_layout->setMargin(0); fields_container_ = new QScrollArea(ui_.page_fields); fields_layout->addWidget(fields_container_); fields_container_->setWidgetResizable(true); fields_layout->addStretch(20); fields_ = NULL; ui_.le_port->setText(QString::number(port_)); ui_.le_host->setFocus(); client_ = new MiniClient; connect(client_, SIGNAL(handshaken()), SLOT(client_handshaken())); connect(client_, SIGNAL(error()), SLOT(client_error())); if (!PsiOptions::instance()->getOption("options.account.domain").toString().isEmpty()) { ui_.gb_server->hide(); } } AccountRegDlg::~AccountRegDlg() { delete client_; } void AccountRegDlg::done(int r) { if(ui_.busy->isActive()) { int n = QMessageBox::information(this, tr("Warning"), tr("Are you sure you want to cancel the registration?"), tr("&Yes"), tr("&No")); if(n != 0) return; } client_->close(); QDialog::done(r); } void AccountRegDlg::sslActivated(int i) { if ((ui_.cb_ssl->itemData(i) == UserAccount::SSL_Yes || ui_.cb_ssl->itemData(i) == UserAccount::SSL_Legacy) && !checkSSL()) { ui_.cb_ssl->setCurrentIndex(ui_.cb_ssl->findData(UserAccount::SSL_Auto)); } else if (ui_.cb_ssl->itemData(i) == UserAccount::SSL_Legacy && !ui_.ck_host->isChecked()) { QMessageBox::critical(this, tr("Error"), tr("Legacy SSL is only available in combination with manual host/port.")); ui_.cb_ssl->setCurrentIndex(ui_.cb_ssl->findData(UserAccount::SSL_Auto)); } } bool AccountRegDlg::checkSSL() { if(!QCA::isSupported("tls")) { QMessageBox::information(this, tr("SSL error"), tr("Cannot enable SSL/TLS. Plugin not found.")); return false; } return true; } void AccountRegDlg::hostToggled(bool on) { ui_.le_host->setEnabled(on); ui_.le_port->setEnabled(on); ui_.lb_host->setEnabled(on); ui_.lb_port->setEnabled(on); if (!on && ui_.cb_ssl->currentIndex() == ui_.cb_ssl->findData(UserAccount::SSL_Legacy)) { ui_.cb_ssl->setCurrentIndex(ui_.cb_ssl->findData(UserAccount::SSL_Auto)); } } void AccountRegDlg::selectServer() { if (ui_.le_server->count() == 0) { ui_.busy->start(); block(); serverlist_querier_->getList(); } } void AccountRegDlg::serverListReceived(const QStringList& list) { ui_.busy->stop(); unblock(); ui_.le_server->clear(); ui_.le_server->addItems(list); ui_.le_server->showPopup(); } void AccountRegDlg::serverListError(const QString& e) { ui_.busy->stop(); unblock(); QString error = tr("There was an error retrieving the server list"); if (!e.isEmpty()) { error += ".\n" + tr("Reason: ") + e; } qWarning(error); //QMessageBox::critical(this, tr("Error"), error); ui_.le_server->setFocus(); } void AccountRegDlg::next() { if (ui_.sw_register->currentWidget() == ui_.page_server) { // Update settings server_ = JIDUtil::accountFromString(ui_.le_server->currentText().trimmed()); ssl_ = (UserAccount::SSLFlag) ui_.cb_ssl->itemData(ui_.cb_ssl->currentIndex()).toInt(); legacy_ssl_probe_ = ui_.ck_legacy_ssl_probe->isChecked(); opt_host_ = ui_.ck_host->isChecked(); host_ = ui_.le_host->text(); port_ = ui_.le_port->text().toInt(); proxy_ = proxy_chooser_->currentItem(); // Sanity check if (server_.isNull() || !server_.node().isEmpty() || !server_.resource().isEmpty()) { QMessageBox::critical(this, tr("Error"), tr("You have entered an invalid server name")); return; } // Connect to the server ui_.busy->start(); block(); client_->connectToServer(server_, legacy_ssl_probe_, ssl_ == UserAccount::SSL_Legacy, ssl_ == UserAccount::SSL_Yes, opt_host_ ? host_ : QString(), port_, proxy_manager_, proxy_); } else if (ui_.sw_register->currentWidget() == ui_.page_fields) { // Initialize the form XMPP::XData fields; fields.setFields(fields_->fields()); // Determine the username and password foreach(XMPP::XData::Field field, fields.fields()) { if (field.var() == "username" && !field.value().isEmpty()) { jid_.set(server_.bare(), field.value().at(0), ""); } else if (field.var() == "password" && !field.value().isEmpty()) { pass_ = field.value().at(0); } } // Register ui_.busy->start(); block(); JT_Register *reg = new JT_Register(client_->client()->rootTask()); connect(reg, SIGNAL(finished()), SLOT(setFields_finished())); if (isOld_) { Form form = convertFromXData(fields); form.setJid(server_); reg->setForm(form); } else { reg->setForm(server_,fields); } reg->go(true); } } void AccountRegDlg::client_handshaken() { // try to register an account JT_Register *reg = new JT_Register(client_->client()->rootTask()); connect(reg, SIGNAL(finished()), SLOT(getFields_finished())); reg->getForm(server_); reg->go(true); } void AccountRegDlg::client_error() { ui_.busy->stop(); unblock(); if (ui_.sw_register->currentWidget() == ui_.page_fields) { // Start over delete fields_; fields_ = NULL; ui_.sw_register->setCurrentWidget(ui_.page_server); } } void AccountRegDlg::getFields_finished() { JT_Register *reg = (JT_Register *)sender(); ui_.busy->stop(); if (reg->success()) { unblock(); fields_ = new XDataWidget(ui_.page_fields); XData xdata; if (reg->hasXData()) { isOld_ = false; xdata = reg->xdata(); } else { isOld_ = true; xdata = convertToXData(reg->form()); } if (xdata.instructions().isEmpty()) xdata.setInstructions(tr("Please provide the following information:")); xdata.setInstructions(TextUtil::linkify(xdata.instructions())); fields_->setForm(xdata); fields_container_->setWidget(fields_); fields_container_->updateGeometry(); ui_.sw_register->setCurrentWidget(ui_.page_fields); } else { QMessageBox::critical(this, tr("Error"), tr("This server does not support registration")); unblock(); } } void AccountRegDlg::setFields_finished() { JT_Register *reg = (JT_Register *)sender(); ui_.busy->stop(); if (reg->success()) { QMessageBox::information(this, tr("Success"), QString(tr("You have succesfully registered your account with Jabber ID '%1'")).arg(jid_.bare())); client_->close(); accept(); } else { unblock(); QMessageBox::critical(this, tr("Error"), QString(tr("There was an error registering the account.\nReason: %1")).arg(reg->statusString())); } } XMPP::XData AccountRegDlg::convertToXData(const XMPP::Form& form) { // Convert the fields XData::FieldList fields; foreach(FormField f, form) { XData::Field field; field.setLabel(f.fieldName()); field.setVar(f.realName()); field.setRequired(true); if (f.isSecret()) { field.setType(XData::Field::Field_TextPrivate); } else { field.setType(XData::Field::Field_TextSingle); } fields.push_back(field); } // Create the form XData xdata; xdata.setInstructions(form.instructions()); xdata.setFields(fields); return xdata; } XMPP::Form AccountRegDlg::convertFromXData(const XMPP::XData& xdata) { Form form; foreach(XMPP::XData::Field field, xdata.fields()) { if (!field.value().isEmpty()) { FormField f; f.setType(field.var()); f.setValue(field.value().at(0)); form.push_back(f); } } return form; } void AccountRegDlg::block() { if (ui_.sw_register->currentWidget() == ui_.page_server) { ui_.gb_server->setEnabled(false); ui_.gb_connection->setEnabled(false); ui_.pb_next->setEnabled(false); } else if (ui_.sw_register->currentWidget() == ui_.page_fields) { if (fields_) fields_->setEnabled(false); } } void AccountRegDlg::unblock() { if (ui_.sw_register->currentWidget() == ui_.page_server) { ui_.gb_server->setEnabled(true); ui_.gb_connection->setEnabled(true); ui_.pb_next->setEnabled(true); } else if (ui_.sw_register->currentWidget() == ui_.page_fields) { ui_.pb_next->setEnabled(true); if (fields_) fields_->setEnabled(true); } }