/* * accountdlg.cpp - dialogs for manipulating PsiAccounts * Copyright (C) 2001, 2002 Justin Karneges * * 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"accountdlg.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include"psicon.h" #include"psiaccount.h" #include"common.h" #include"im.h" #include"xmpp_tasks.h" #include"proxy.h" #include"sslcertdlg.h" #include"busywidget.h" #include"iconwidget.h" #include"fancylabel.h" #include"base64.h" using namespace XMPP; //---------------------------------------------------------------------------- // MiniClient //---------------------------------------------------------------------------- static QCA::Cert readCertXml(const QDomElement &e) { QCA::Cert cert; // there should be one child data tag QDomElement data = e.elementsByTagName("data").item(0).toElement(); if(!data.isNull()) cert.fromDER(Base64::stringToArray(data.text())); return cert; } static QPtrList getRootCerts(const QStringList &stores) { QPtrList list; for(QStringList::ConstIterator dit = stores.begin(); dit != stores.end(); ++dit) { QDir dir(*dit); dir.setNameFilter("*.xml"); QStringList entries = dir.entryList(); for(QStringList::ConstIterator it = entries.begin(); it != entries.end(); ++it) { QFile f(dir.filePath(*it)); if(!f.open(IO_ReadOnly)) continue; QDomDocument doc; bool ok = doc.setContent(&f); f.close(); if(!ok) continue; QDomElement base = doc.documentElement(); if(base.tagName() != "store") continue; QDomNodeList cl = base.elementsByTagName("certificate"); int num = 0; for(int n = 0; n < (int)cl.count(); ++n) { QCA::Cert *cert = new QCA::Cert(readCertXml(cl.item(n).toElement())); if(cert->isNull()) { delete cert; continue; } ++num; list.append(cert); } } } return list; } MiniClient::MiniClient(QObject *parent) :QObject(parent) { _client = new Client; conn = 0; tls = 0; tlsHandler = 0; stream = 0; certList.setAutoDelete(true); } MiniClient::~MiniClient() { delete _client; reset(); } void MiniClient::reset() { delete stream; stream = 0; delete tls; tls = 0; tlsHandler = 0; delete conn; conn = 0; certList.clear(); } void MiniClient::connectToServer(const Jid &jid, bool ssl, const QString &_host, int _port, ProxyManager *pm, int proxy, QString *_pass) { j = jid; QString host; int port; if(!_host.isEmpty()) { host = _host; port = _port; } else { host = jid.host(); if(ssl) port = 5223; else port = 5222; } AdvancedConnector::Proxy p; if(proxy > 0) { const ProxyItem &pi = pm->getItem(proxy-1); if(pi.type == "http") // HTTP Connect p.setHttpConnect(pi.settings.host, pi.settings.port); else if(pi.type == "socks") // SOCKS p.setSocks(pi.settings.host, pi.settings.port); else if(pi.type == "poll") { // HTTP Poll QUrl u = pi.settings.url; if(u.query().isEmpty()) { QString v = host + ':' + QString::number(port); QUrl::encode(v); u.setQuery(QString("server=") + v); } p.setHttpPoll(pi.settings.host, pi.settings.port, u.toString()); p.setPollInterval(2); } if(pi.settings.useAuth) p.setUserPass(pi.settings.user, pi.settings.pass); } conn = new AdvancedConnector; if(ssl) { QStringList certDirs; certDirs += g.pathBase + "/certs"; certList = getRootCerts(certDirs); tls = new QCA::TLS; tls->setCertificateStore(certList); tlsHandler = new QCATLSHandler(tls); connect(tlsHandler, SIGNAL(tlsHandshaken()), SLOT(tls_handshaken())); } conn->setProxy(p); conn->setOptHostPort(host, port); conn->setOptSSL(ssl); stream = new ClientStream(conn, tlsHandler); stream->setOldOnly(true); connect(stream, SIGNAL(connected()), SLOT(cs_connected())); connect(stream, SIGNAL(securityLayerActivated(int)), SLOT(cs_securityLayerActivated(int))); connect(stream, SIGNAL(needAuthParams(bool, bool, bool)), SLOT(cs_needAuthParams(bool, bool, bool))); connect(stream, SIGNAL(authenticated()), SLOT(cs_authenticated())); connect(stream, SIGNAL(connectionClosed()), SLOT(cs_connectionClosed())); connect(stream, SIGNAL(delayedCloseFinished()), SLOT(cs_delayedCloseFinished())); connect(stream, SIGNAL(warning(int)), SLOT(cs_warning(int))); connect(stream, SIGNAL(error(int)), SLOT(cs_error(int))); if(_pass) { pass = *_pass; _client->connectToServer(stream, j); } else _client->connectToServer(stream, j, false); } void MiniClient::close() { _client->close(); reset(); } Client *MiniClient::client() { return _client; } void MiniClient::tls_handshaken() { QCA::Cert cert = tls->peerCertificate(); int r = tls->certificateValidityResult(); if(r != QCA::TLS::Valid) { QString str = PsiAccount::resultToString(r); while(1) { int n = QMessageBox::warning(0, tr("Server Authentication"), tr("The %1 certificate failed the authenticity test.").arg(j.host()) + '\n' + tr("Reason: %1").arg(str), tr("&Details..."), tr("Co&ntinue"), tr("&Cancel"), 0, 2); if(n == 0) { SSLCertDlg::showCert(cert, r); } else if(n == 1) { tlsHandler->continueAfterHandshake(); break; } else if(n == 2) { close(); error(); break; } } } else tlsHandler->continueAfterHandshake(); } void MiniClient::cs_connected() { } void MiniClient::cs_securityLayerActivated(int) { } void MiniClient::cs_needAuthParams(bool, bool, bool) { stream->setPassword(pass); stream->continueAfterParams(); } void MiniClient::cs_authenticated() { _client->start(j.host(), j.user(), "", ""); handshaken(); } void MiniClient::cs_connectionClosed() { cs_error(-1); } void MiniClient::cs_delayedCloseFinished() { } void MiniClient::cs_warning(int) { stream->continueAfterWarning(); } void MiniClient::cs_error(int err) { QString str; bool reconn; PsiAccount::getErrorInfo(err, conn, stream, tlsHandler, &str, &reconn); close(); QMessageBox::critical(0, tr("Server Error"), tr("There was an error communicating with the Jabber server.\nDetails: %1").arg(str)); error(); } //---------------------------------------------------------------------------- // AccountManageDlg //---------------------------------------------------------------------------- class AccountManageItem : public QCheckListItem { public: AccountManageItem(QListView *par, PsiAccount *_pa) :QCheckListItem(par,"",CheckBox) { pa = _pa; updateInfo(); } void updateInfo() { const UserAccount &acc = pa->userAccount(); setText(0, pa->name()); //setPixmap(0, IconsetFactory::icon("psi/account")); Jid j = acc.jid; setText(1, acc.opt_host ? acc.host : j.host()); setText(2, pa->isActive() ? AccountManageDlg::tr("Active") : AccountManageDlg::tr("Not active")); setOn(pa->enabled()); } void stateChange( bool s) { if (pa->enabled()!=s) pa->setEnabled(s); updateInfo(); } int rtti() const { return 8109; } PsiAccount *pa; }; AccountManageDlg::AccountManageDlg(PsiCon *_psi, const char *name) :AccountManageUI(0, name, false, WDestructiveClose) { psi = _psi; psi->dialogRegister(this); setCaption(CAP(caption())); // setup signals connect(pb_add, SIGNAL(clicked()), SLOT(add())); connect(pb_modify, SIGNAL(clicked()), SLOT(modify())); connect(pb_remove, SIGNAL(clicked()), SLOT(remove())); connect(pb_close, SIGNAL(clicked()), SLOT(close())); connect(lv_accs, SIGNAL(doubleClicked(QListViewItem *)), SLOT(modify(QListViewItem *))); connect(lv_accs, SIGNAL(selectionChanged(QListViewItem *)), SLOT(qlv_selectionChanged(QListViewItem *))); connect(psi, SIGNAL(accountAdded(PsiAccount *)), SLOT(accountAdded(PsiAccount *))); connect(psi, SIGNAL(accountUpdated(PsiAccount *)), SLOT(accountUpdated(PsiAccount *))); connect(psi, SIGNAL(accountRemoved(PsiAccount *)), SLOT(accountRemoved(PsiAccount *))); lv_accs->setAllColumnsShowFocus(true); lv_accs->setResizeMode(QListView::LastColumn); PsiAccountListIt it(psi->accountList()); for(PsiAccount *pa; (pa = it.current()); ++it) { new AccountManageItem(lv_accs, pa); } if(lv_accs->childCount() > 0) lv_accs->setSelected(lv_accs->firstChild(), true); else qlv_selectionChanged(0); } AccountManageDlg::~AccountManageDlg() { psi->dialogUnregister(this); } void AccountManageDlg::qlv_selectionChanged(QListViewItem *lvi) { AccountManageItem *i = (AccountManageItem *)lvi; bool ok = i ? true: false; pb_modify->setEnabled(ok); pb_remove->setEnabled(ok); } void AccountManageDlg::add() { AccountAddDlg *w = new AccountAddDlg(psi, 0); w->show(); } void AccountManageDlg::modify() { modify(lv_accs->currentItem()); } void AccountManageDlg::modify(QListViewItem *lvi) { AccountManageItem *i = (AccountManageItem *)lvi; if(!i) return; psi->modifyAccount(i->pa); } void AccountManageDlg::remove() { AccountManageItem *i = (AccountManageItem *)lv_accs->currentItem(); if(!i) return; if(i->pa->isActive()) { QMessageBox::information(this, tr("Error"), tr("Unable to remove the account, as it is currently active.")); return; } AccountRemoveDlg *w = new AccountRemoveDlg(psi->proxy(), i->pa->userAccount()); int n = w->exec(); if(n != QDialog::Accepted) { delete w; return; } delete w; psi->removeAccount(i->pa); } void AccountManageDlg::accountAdded(PsiAccount *pa) { new AccountManageItem(lv_accs, pa); } void AccountManageDlg::accountUpdated(PsiAccount *pa) { AccountManageItem *i; QListViewItemIterator it(lv_accs); for(; (i = (AccountManageItem *)it.current()) ; ++it) { if(i->pa == pa) break; } if(!i) return; i->updateInfo(); } void AccountManageDlg::accountRemoved(PsiAccount *pa) { AccountManageItem *i; QListViewItemIterator it(lv_accs); for(; (i = (AccountManageItem *)it.current()) ; ++it) { if(i->pa == pa) break; } if(!i) return; delete i; qlv_selectionChanged(lv_accs->currentItem()); } //---------------------------------------------------------------------------- // AccountAddDlg //---------------------------------------------------------------------------- AccountAddDlg::AccountAddDlg(PsiCon *_psi, QWidget *parent, const char *name) :AccountAddUI(parent, name, false, WDestructiveClose) { psi = _psi; psi->dialogRegister(this); setCaption(CAP(caption())); connect(pb_close, SIGNAL(clicked()), SLOT(close())); connect(pb_add, SIGNAL(clicked()), SLOT(add())); connect(le_name, SIGNAL(textChanged(const QString &)), SLOT(setAddButton(const QString &))); QWhatsThis::add(ck_reg, tr("Check this option if you don't yet have a Jabber account " "and you want to register one. Note that this will only work " "on servers that allow anonymous registration.")); QString def = tr("Default"); QString aname = def; int n = 0; while(1) { bool taken = false; PsiAccountListIt it(psi->accountList()); for(PsiAccount *pa; (pa = it.current()); ++it) { if(aname == pa->name()) { taken = true; break; } } if(!taken) break; aname = def + '_' + QString::number(++n); } le_name->setText(aname); le_name->setFocus(); } AccountAddDlg::~AccountAddDlg() { psi->dialogUnregister(this); } void AccountAddDlg::add() { QString def = le_name->text(); QString aname = def; int n = 0; while(1) { bool taken = false; PsiAccountListIt it(psi->accountList()); for(PsiAccount *pa; (pa = it.current()); ++it) { if(aname == pa->name()) { taken = true; break; } } if(!taken) break; aname = def + '_' + QString::number(++n); } le_name->setText( aname ); if(ck_reg->isChecked()) { AccountRegDlg *w = new AccountRegDlg(psi->proxy(), this); int n = w->exec(); if(n != QDialog::Accepted) { delete w; return; } Jid jid = w->jid; QString pass = w->pass; bool opt_host = w->opt_host; QString host = w->sp_host; int port = w->sp_port; bool ssl = w->ssl; int proxy = w->proxy; delete w; psi->createAccount(le_name->text(), jid, pass, opt_host, host, port, ssl, proxy); } else { psi->createAccount(le_name->text()); } close(); } void AccountAddDlg::setAddButton(const QString &s) { pb_add->setEnabled(!s.isEmpty()); } //---------------------------------------------------------------------------- // AccountModifyDlg //---------------------------------------------------------------------------- AccountModifyDlg::AccountModifyDlg(PsiAccount *_pa, QWidget *parent, const char *name) :AccountModifyUI(parent, name, false, WDestructiveClose) { pa = _pa; connect(pa->psi(), SIGNAL(pgpToggled(bool)), SLOT(pgpToggled(bool))); pa->dialogRegister(this); setCaption(CAP(caption())); setIcon(IconsetFactory::icon("psi/account")); const UserAccount &acc = pa->userAccount(); connect(pb_close, SIGNAL(clicked()), SLOT(reject())); connect(ck_host, SIGNAL(toggled(bool)), SLOT(hostToggled(bool))); connect(pb_key, SIGNAL(clicked()), SLOT(chooseKey())); connect(pb_keyclear, SIGNAL(clicked()), SLOT(clearKey())); connect(pb_save, SIGNAL(clicked()), SLOT(save())); le_pass->setEnabled(true); le_host->setEnabled(false); le_port->setEnabled(false); gb_pgp->setEnabled(false); connect(pb_vcard, SIGNAL(clicked()), SLOT(detailsVCard())); connect(pb_changepw, SIGNAL(clicked()), SLOT(detailsChangePW())); le_name->setText(acc.name); le_jid->setText(acc.jid); ck_ssl->setChecked(acc.opt_ssl); connect(ck_ssl, SIGNAL(toggled(bool)), SLOT(sslToggled(bool))); if (acc.opt_pass) le_pass->setText(acc.pass); ck_host->setChecked(acc.opt_host); le_host->setText(acc.host); le_port->setText(QString::number(acc.port)); le_resource->setText(acc.resource); le_priority->setText(QString::number(acc.priority)); ck_plain->setChecked(acc.opt_plain); ck_auto->setChecked(acc.opt_auto); ck_reconn->setChecked(acc.opt_reconn); ck_log->setChecked(acc.opt_log); ck_keepAlive->setChecked(acc.opt_keepAlive); ck_ignoreSSLWarnings->setChecked(acc.opt_ignoreSSLWarnings); le_dtProxy->setText(acc.dtProxy.full()); keyID = acc.pgpSecretKeyID; updateUserID(); if(pa->psi()->pgp()) { gb_pgp->setEnabled(true); } pc = pa->psi()->proxy()->createProxyChooser(gb_proxy); replaceWidget(lb_proxychooser, pc); pc->setCurrentItem(acc.proxy_index); if(le_name->text().isEmpty()) le_name->setFocus(); else if(le_jid->text().isEmpty()) le_jid->setFocus(); else pb_save->setFocus(); // QWhatsThis helpers QWhatsThis::add(ck_plain, tr("Normally, Psi logs in using the digest authentication " "method. Check this box to force a plain text login " "to the Jabber server. Use this option only if you have " "problems connecting with the normal login procedure, as it " "makes your connection potentially vulnerable to " "attacks.")); QWhatsThis::add(ck_auto, tr("Automatically login to this account on Psi startup. Useful if " "you have Psi automatically launched when an Internet " "connection is detected.")); QWhatsThis::add(ck_reconn, tr("Makes Psi try to reconnect if the connection was broken. " "Useful, if you have an unstable connection and have to " "reconnect often.")); QWhatsThis::add(ck_log, tr("Keep a log of message history. Disable this " "option if you want to conserve disk space or if you need " "maximum security.")); QWhatsThis::add(ck_keepAlive, tr("Sends so called \"Keep-alive\" packets periodically. " "It is useful if your connection is set to be " "automatically disconnected after a certain period of " "inactivity (for example, by your ISP) and you want to keep it " "up all the time.")); QWhatsThis::add(ck_ignoreSSLWarnings, tr("Ignores all the SSL warnings, for example, about " "incorrect certificates. Useful if your server doesn't " "use a validated SSL certificate and you are " "annoyed with warnings.")); QWhatsThis::add(ck_ssl, tr("Check this option to use an encrypted SSL connection to " "the Jabber server. You may use this option if your " "server supports it and if you have the necessary QSSL " "plugin installed. For more information, check the " "Psi homepage.")); QWhatsThis::add(ck_host, tr("Use this option for manual configuration of your Jabber host " "if it is not the same as the host you are connecting to. This option is mostly useful " "if you have some sort of proxy route on your " "local machine (i.e. you connect to localhost), but your " "account is registered on an external server.")); QWhatsThis::add(le_resource, tr("You can have multiple clients connected to the Jabber server " "with your single account. Each login is distinguished by a \"resource\" " "name, which you can specify in this field.")); QWhatsThis::add(le_priority, tr("

You can have multiple clients connected to the Jabber " "server with your single account. In such a situation, " "the client with the highest priority (that is specified in " "this field) will be the one that will receive " "all incoming events.

" "

For example, if you have a permanent connection " "to the Internet at your work location, and have a dial-up at home, " "you can have your Jabber client permanently running at work " "with a low priority, and you can still use the same account " "from home, using a client with higher priority to " "temporary \"disable\" the lower priority client at work.

")); resize(minimumSize()); } AccountModifyDlg::~AccountModifyDlg() { pa->dialogUnregister(this); } void AccountModifyDlg::updateUserID() { if(keyID.isEmpty()) { setKeyID(false); } else { QString userID = QString::null; if(pa->psi()->pgp()) { OpenPGP::KeyList list = pa->psi()->pgp()->secretKeys(); for(OpenPGP::KeyList::ConstIterator it = list.begin(); it != list.end(); ++it) { const OpenPGP::Key &k = *it; if(k.keyID() == keyID) { userID = k.userID(); break; } } } if(userID.isNull()) setKeyID(true, tr("Unknown Key: %1").arg(keyID.left(8))); else setKeyID(true, userID); } } void AccountModifyDlg::setKeyID(bool b, const QString &s) { if(b) { lb_keyname->setText(s); lb_keyname->setMinimumWidth(100); lb_keyicon->setEnabled(true); lb_keyname->setEnabled(true); pb_keyclear->setEnabled(true); } else { lb_keyname->setText(tr("No Key Selected")); lb_keyicon->setEnabled(false); lb_keyname->setEnabled(false); pb_keyclear->setEnabled(false); } } void AccountModifyDlg::pgpToggled(bool b) { if(b) { gb_pgp->setEnabled(true); } else { gb_pgp->setEnabled(false); } updateUserID(); } void AccountModifyDlg::setPassword(const QString &pw) { if (!le_pass->text().isEmpty()) le_pass->setText(pw); } void AccountModifyDlg::sslToggled(bool on) { if(on && !QCA::isSupported(QCA::CAP_TLS)) { QMessageBox::information(this, tr("SSL error"), tr("Cannot enable SSL/TLS. Plugin not found.")); ck_ssl->setChecked(false); return; } le_port->setText(on ? "5223": "5222"); } void AccountModifyDlg::hostToggled(bool on) { le_host->setEnabled(on); le_port->setEnabled(on); } void AccountModifyDlg::chooseKey() { OpenPGP::KeyList list = pa->psi()->pgp()->secretKeys(); PGPKeyDlg *w = new PGPKeyDlg(list, keyID, this); w->setCaption(tr("Secret Key")); int r = w->exec(); QString key; if(r == QDialog::Accepted) key = w->keyID(); delete w; if(!key.isEmpty()) { keyID = key; updateUserID(); } } void AccountModifyDlg::clearKey() { setKeyID(false); keyID = ""; } void AccountModifyDlg::detailsVCard() { pa->changeVCard(); } void AccountModifyDlg::detailsChangePW() { pa->changePW(); } void AccountModifyDlg::save() { UserAccount acc = pa->userAccount(); if(le_name->text().isEmpty()) { QMessageBox::information(this, tr("Error"), tr("You must specify a name for the account before you may save it.")); return; } Jid newJid( le_jid->text() ); if ( newJid.user().isEmpty() || newJid.host().isEmpty() ) { QMessageBox::information(this, tr("Error"), tr("Jabber ID must be specified in the format user@host.")); return; } // do not allow duplicate account names QString def = le_name->text(); QString aname = def; int n = 0; { PsiAccountListIt it(pa->psi()->accountList()); for(PsiAccount *pa; (pa = it.current()); ++it) if(aname == pa->name()) n++; } if ( aname == acc.name ) n--; if ( n ) aname = def + '_' + QString::number(++n); le_name->setText( aname ); acc.name = le_name->text(); acc.jid = le_jid->text(); acc.pass = le_pass->text(); acc.opt_pass = !acc.pass.isEmpty(); acc.opt_host = ck_host->isChecked(); acc.host = le_host->text(); acc.port = le_port->text().toInt(); acc.resource = le_resource->text(); acc.priority = le_priority->text().toInt(); acc.opt_ssl = ck_ssl->isChecked(); acc.opt_plain = ck_plain->isChecked(); acc.opt_auto = ck_auto->isChecked(); acc.opt_reconn = ck_reconn->isChecked(); acc.opt_log = ck_log->isChecked(); acc.opt_keepAlive = ck_keepAlive->isChecked(); acc.opt_ignoreSSLWarnings = ck_ignoreSSLWarnings->isChecked(); acc.dtProxy = le_dtProxy->text(); acc.pgpSecretKeyID = keyID; acc.proxy_index = pc->currentItem(); if(pa->isActive()) { QMessageBox::information(this, tr("Warning"), tr("This account is currently active, so certain changes may not take effect until the next login.")); } pa->setUserAccount(acc); accept(); } //---------------------------------------------------------------------------- // AccountRegDlg //---------------------------------------------------------------------------- AccountRegDlg::AccountRegDlg(ProxyManager *_proxyman, QWidget *parent, const char *name) :AccountRegUI(parent, name, false) { setCaption(CAP(caption())); le_host->setEnabled(false); le_port->setEnabled(false); connect(pb_reg, SIGNAL(clicked()), SLOT(reg())); connect(ck_ssl, SIGNAL(toggled(bool)), SLOT(sslToggled(bool))); connect(ck_host, SIGNAL(toggled(bool)), SLOT(hostToggled(bool))); proxyman = _proxyman; pc = proxyman->createProxyChooser(gb_proxy); replaceWidget(lb_proxychooser, pc); pc->fixTabbing(le_confirm, ck_ssl); pc->setCurrentItem(0); le_port->setText("5222"); le_host->setFocus(); client = new MiniClient; connect(client, SIGNAL(handshaken()), SLOT(client_handshaken())); connect(client, SIGNAL(error()), SLOT(client_error())); } AccountRegDlg::~AccountRegDlg() { delete client; } /*void AccountRegDlg::closeEvent(QCloseEvent *e) { e->ignore(); reject(); }*/ void AccountRegDlg::done(int r) { if(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; } QDialog::done(r); } void AccountRegDlg::sslToggled(bool on) { if(on && !QCA::isSupported(QCA::CAP_TLS)) { QMessageBox::information(this, tr("SSL error"), tr("Cannot enable SSL/TLS. Plugin not found.")); ck_ssl->setChecked(false); return; } le_port->setText(on ? "5223": "5222"); } void AccountRegDlg::hostToggled(bool on) { le_host->setEnabled(on); le_port->setEnabled(on); } void AccountRegDlg::reg() { // sanity check Jid j(le_jid->text()); if ( j.user().isEmpty() || j.host().isEmpty() ) { QMessageBox::information(this, tr("Error"), tr("Jabber ID must be specified in the format user@host.")); return; } if(le_pass->text().isEmpty()) { QMessageBox::information(this, tr("Error"), tr("You must fill out the fields properly before you can register.")); return; } if(le_pass->text() != le_confirm->text()) { QMessageBox::information(this, tr("Error"), tr("Password and confirmation do not match. Please enter them again.")); le_pass->setText(""); le_confirm->setText(""); le_pass->setFocus(); return; } busy->start(); block(); jid = j; ssl = ck_ssl->isChecked(); pass = le_pass->text(); opt_host = ck_host->isChecked(); sp_host = le_host->text(); sp_port = le_port->text().toInt(); client->connectToServer(jid, ssl, opt_host ? sp_host : QString(), sp_port, proxyman, pc->currentItem(), 0); } void AccountRegDlg::client_handshaken() { // try to register an account JT_Register *reg = new JT_Register(client->client()->rootTask()); connect(reg, SIGNAL(finished()), SLOT(reg_finished())); reg->reg(jid.user(), pass); reg->go(true); } void AccountRegDlg::client_error() { busy->stop(); unblock(); } void AccountRegDlg::reg_finished() { JT_Register *reg = (JT_Register *)sender(); client->close(); busy->stop(); if(reg->success()) { QMessageBox::information(this, tr("Success"), tr("The account was registered successfully.")); proxy = pc->currentItem(); accept(); return; } else if(reg->statusCode() != Task::ErrDisc) { unblock(); QMessageBox::critical(this, tr("Error"), QString(tr("There was an error registering the account.\nReason: %1")).arg(reg->statusString())); } } void AccountRegDlg::block() { gb_account->setEnabled(false); gb_proxy->setEnabled(false); gb_advanced->setEnabled(false); pb_reg->setEnabled(false); } void AccountRegDlg::unblock() { gb_account->setEnabled(true); gb_proxy->setEnabled(true); gb_advanced->setEnabled(true); pb_reg->setEnabled(true); le_jid->setFocus(); } //---------------------------------------------------------------------------- // AccountRemoveDlg //---------------------------------------------------------------------------- class AccountRemoveDlg::Private { public: Private() {} UserAccount acc; QButtonGroup *bg; ProxyManager *proxyman; }; AccountRemoveDlg::AccountRemoveDlg(ProxyManager *proxyman, const UserAccount &acc, QWidget *parent, const char *name) :AccountRemoveUI(parent, name, false) { d = new Private; d->acc = acc; d->proxyman = proxyman; setCaption(CAP(caption())); connect(pb_close, SIGNAL(clicked()), SLOT(close())); connect(pb_remove, SIGNAL(clicked()), SLOT(remove())); d->bg = new QButtonGroup(0); d->bg->insert(rb_remove, 0); d->bg->insert(rb_removeAndUnreg, 1); connect(d->bg, SIGNAL(clicked(int)), SLOT(bg_clicked(int))); d->bg->setButton(0); bg_clicked(0); pb_close->setFocus(); client = new MiniClient; connect(client, SIGNAL(handshaken()), SLOT(client_handshaken())); connect(client, SIGNAL(error()), SLOT(client_error())); } AccountRemoveDlg::~AccountRemoveDlg() { delete client; delete d->bg; delete d; } /*void AccountRemoveDlg::closeEvent(QCloseEvent *e) { e->ignore(); reject(); }*/ void AccountRemoveDlg::done(int r) { if(busy->isActive()) { int n = QMessageBox::information(this, tr("Warning"), tr("Are you sure you want to cancel the unregistration?"), tr("&Yes"), tr("&No")); if(n != 0) return; } QDialog::done(r); } void AccountRemoveDlg::bg_clicked(int x) { if(x == 0) { lb_pass->setEnabled(false); le_pass->setEnabled(false); } else if(x == 1) { lb_pass->setEnabled(true); le_pass->setEnabled(true); le_pass->setFocus(); } } void AccountRemoveDlg::remove() { bool unreg = rb_removeAndUnreg->isChecked(); if(unreg) { if(le_pass->text() != d->acc.pass) { QMessageBox::information(this, tr("Error"), tr("Password does not match account. Please try again.")); le_pass->setFocus(); return; } } int n = QMessageBox::information(this, tr("Warning"), tr("Are you sure you want to remove %1 ?").arg(d->acc.name), tr("&Yes"), tr("&No")); if(n != 0) return; if(!unreg) { accept(); return; } busy->start(); gb_account->setEnabled(false); pb_remove->setEnabled(false); Jid j = d->acc.jid; j.setResource(d->acc.resource); client->connectToServer(j, d->acc.opt_ssl, d->acc.opt_host ? d->acc.host : QString(), d->acc.port, d->proxyman, d->acc.proxy_index, &d->acc.pass); } void AccountRemoveDlg::client_handshaken() { // try to unregister an account JT_Register *reg = new JT_Register(client->client()->rootTask()); connect(reg, SIGNAL(finished()), SLOT(unreg_finished())); reg->unreg(); reg->go(true); } void AccountRemoveDlg::client_error() { busy->stop(); gb_account->setEnabled(true); pb_remove->setEnabled(true); } void AccountRemoveDlg::unreg_finished() { JT_Register *reg = (JT_Register *)sender(); client->close(); busy->stop(); if(reg->success()) { QMessageBox::information(this, tr("Success"), tr("The account was unregistered successfully.")); accept(); return; } else if(reg->statusCode() != Task::ErrDisc) { gb_account->setEnabled(true); pb_remove->setEnabled(true); QMessageBox::critical(this, tr("Error"), QString(tr("There was an error unregistering the account.\nReason: %1")).arg(reg->statusString())); } }