2
* servicesdlg.cpp - a dialog for browsing Jabber services
3
* Copyright (C) 2001, 2002 Justin Karneges
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this library; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
#include"servicesdlg.h"
23
#include<qpushbutton.h>
25
#include<qstringlist.h>
31
#include<qguardedptr.h>
34
#include<qapplication.h>
35
#include<qdesktopwidget.h>
37
#include"psiaccount.h"
39
#include"xmpp_tasks.h"
41
#include"busywidget.h"
42
#include"iconwidget.h"
43
#include"xdata_widget.h"
44
#include"xmpp_xdata.h"
45
#include"xmpp_xmlcommon.h"
47
using namespace XMLHelper;
50
//----------------------------------------------------------------------------
52
//----------------------------------------------------------------------------
54
class JT_XRegister : public JT_Register
58
JT_XRegister(Task *parent);
60
void setXForm(const Form &frm, const XData &_form);
62
bool take(const QDomElement &);
63
QDomElement iq() const;
71
JT_XRegister::JT_XRegister( Task *parent )
72
: JT_Register( parent )
76
bool JT_XRegister::take( const QDomElement &x )
80
return JT_Register::take( x );
83
QDomElement JT_XRegister::iq() const
88
void JT_XRegister::setXForm(const Form &frm, const XData &_form)
90
JT_Register::setForm( frm );
92
_iq = createIQ(doc(), "set", frm.jid().full(), id());
93
QDomElement query = doc()->createElement("query");
94
query.setAttribute("xmlns", "jabber:iq:register");
95
_iq.appendChild(query);
98
form.setType( XData::Data_Submit );
99
query.appendChild( form.toXml( doc() ) );
102
void JT_XRegister::onGo()
110
//----------------------------------------------------------------------------
112
//----------------------------------------------------------------------------
113
class RegistrationDlg::Private
121
QPushButton *pb_close, *pb_reg;
122
QGuardedPtr<JT_XRegister> jt;
129
QPtrList<QLabel> lb_field;
130
QPtrList<QLineEdit> le_field;
134
RegistrationDlg::RegistrationDlg(const Jid &jid, PsiAccount *pa)
135
:QDialog(0, 0, false, WDestructiveClose)
140
d->pa->dialogRegister(this, d->jid);
144
d->lb_field.setAutoDelete(true);
145
d->le_field.setAutoDelete(true);
147
setCaption(tr("Registration: %1").arg(d->jid.full()));
149
QVBoxLayout *vb1 = new QVBoxLayout(this, 4);
150
d->lb_top = new QLabel(this);
151
d->lb_top->setFrameStyle( QFrame::Panel | QFrame::Sunken );
153
vb1->addWidget(d->lb_top);
155
d->gr_form = new QGrid(2, Horizontal, this);
156
d->gr_form->setSpacing(4);
157
vb1->addWidget(d->gr_form);
160
QFrame *line = new QFrame(this);
161
line->setFixedHeight(2);
162
line->setFrameStyle(QFrame::HLine | QFrame::Sunken);
163
vb1->addWidget(line);
165
QHBoxLayout *hb1 = new QHBoxLayout(vb1);
166
d->busy = new BusyWidget(this);
167
hb1->addWidget(d->busy);
169
d->pb_reg = new QPushButton(tr("&Register"), this);
170
d->pb_reg->setDefault(true);
171
connect(d->pb_reg, SIGNAL(clicked()), SLOT(doRegSet()));
172
hb1->addWidget(d->pb_reg);
173
d->pb_close = new QPushButton(tr("&Close"), this);
174
connect(d->pb_close, SIGNAL(clicked()), SLOT(close()));
175
hb1->addWidget(d->pb_close);
182
RegistrationDlg::~RegistrationDlg()
185
d->pa->dialogUnregister(this);
189
/*void RegistrationDlg::closeEvent(QCloseEvent *e)
195
void RegistrationDlg::done(int r)
197
if(d->busy->isActive() && d->type == 1) {
198
int n = QMessageBox::information(this, tr("Busy"), tr("<qt>Registration has already been submitted, so closing this window will not prevent the registration from happening. Do you still wish to close?</qt>"), tr("&Yes"), tr("&No"));
205
void RegistrationDlg::doRegGet()
207
d->lb_top->setText(tr("Fetching registration form for %1 ...").arg(d->jid.full()));
212
d->jt = new JT_XRegister(d->pa->client()->rootTask());
213
connect(d->jt, SIGNAL(finished()), SLOT(jt_finished()));
214
d->jt->getForm(d->jid);
218
void RegistrationDlg::doRegSet()
220
if(!d->pa->checkConnected(this))
223
d->jt = new JT_XRegister(d->pa->client()->rootTask());
226
Form submitForm = d->form;
228
// import the changes back into the form.
229
// the QPtrList of QLineEdits should be in the same order
230
QPtrListIterator<QLineEdit> lit(d->le_field);
231
for(Form::Iterator it = submitForm.begin(); it != submitForm.end(); ++it) {
233
QLineEdit *le = lit.current();
234
f.setValue(le->text());
238
d->jt->setForm(submitForm);
242
form.setFields( d->xdata->fields() );
244
d->jt->setXForm( d->form, form );
247
d->gr_form->setEnabled(false);
248
d->pb_reg->setEnabled(false);
252
connect(d->jt, SIGNAL(finished()), SLOT(jt_finished()));
256
void RegistrationDlg::jt_finished()
259
d->gr_form->setEnabled(true);
260
d->pb_reg->setEnabled(true);
261
JT_XRegister *jt = d->jt;
266
d->form = jt->form();
268
bool useXData = false;
270
QDomNode n = queryTag( jt->iq() ).firstChild();
271
for( ; !n.isNull(); n = n.nextSibling()) {
272
QDomElement i = n.toElement();
276
if( i.attribute( "xmlns" ) == "jabber:x:data" ) {
282
if ( !form.title().isEmpty() )
283
setCaption( form.title() );
285
QString str = tr("<b>Registration for \"%1\":</b><br><br>").arg(d->jid.full());
286
str += plain2rich( form.instructions() );
287
d->lb_top->setText(str);
289
d->xdata = new XDataWidget( d->gr_form );
290
d->xdata->setFields( form.fields() );
300
QString str = tr("<b>Registration for \"%1\":</b><br><br>").arg(d->jid.full());
301
str += plain2rich(d->form.instructions());
302
d->lb_top->setText(str);
303
d->lb_top->setFixedWidth(300);
305
for(Form::ConstIterator it = d->form.begin(); it != d->form.end(); ++it) {
306
const FormField &f = *it;
308
QLabel *lb = new QLabel(f.fieldName(), d->gr_form);
309
QLineEdit *le = new QLineEdit(d->gr_form);
311
le->setEchoMode(QLineEdit::Password);
312
le->setText(f.value());
314
d->lb_field.append(lb);
315
d->le_field.append(le);
318
if (!d->le_field.isEmpty())
319
d->le_field.first()->setFocus();
326
qApp->processEvents();
331
QMessageBox::information(this, tr("Success"), tr("Registration successful."));
337
QMessageBox::critical(this, tr("Error"), tr("Unable to retrieve registration form.\nReason: %1").arg(jt->statusString()));
342
QMessageBox::critical(this, tr("Error"), tr("Error submitting registration form.\nReason: %1").arg(jt->statusString()));
348
//----------------------------------------------------------------------------
350
//----------------------------------------------------------------------------
352
class JT_XSearch : public JT_Search
356
JT_XSearch(Task *parent);
358
void setForm(const Form &frm, const XData &_form);
360
bool take(const QDomElement &);
361
QDomElement iq() const;
369
JT_XSearch::JT_XSearch( Task *parent )
370
: JT_Search( parent )
374
bool JT_XSearch::take( const QDomElement &x )
378
return JT_Search::take( x );
381
QDomElement JT_XSearch::iq() const
386
void JT_XSearch::setForm(const Form &frm, const XData &_form)
388
JT_Search::set( frm );
390
_iq = createIQ(doc(), "set", frm.jid().full(), id());
391
QDomElement query = doc()->createElement("query");
392
query.setAttribute("xmlns", "jabber:iq:search");
393
_iq.appendChild(query);
396
form.setType( XData::Data_Submit );
397
query.appendChild( form.toXml( doc() ) );
400
void JT_XSearch::onGo()
408
//----------------------------------------------------------------------------
410
//----------------------------------------------------------------------------
411
class SearchDlg::Private
420
QGuardedPtr<JT_XSearch> jt;
424
QPtrList<QLabel> lb_field;
425
QPtrList<QLineEdit> le_field;
430
SearchDlg::SearchDlg(const Jid &jid, PsiAccount *pa)
431
:SearchUI(0, 0, WDestructiveClose)
436
d->pa->dialogRegister(this, d->jid);
440
setCaption(caption().arg(d->jid.full()));
444
d->gr_form = new QGrid(2, Horizontal, gb_search);
445
d->gr_form->setSpacing(4);
446
replaceWidget(lb_form, d->gr_form);
449
pb_add->setEnabled(false);
450
pb_info->setEnabled(false);
451
pb_stop->setEnabled(false);
452
pb_search->setEnabled(false);
454
lv_results->setMultiSelection(true);
455
lv_results->setSelectionMode( QListView::Extended );
456
connect(lv_results, SIGNAL(selectionChanged()), SLOT(selectionChanged()));
457
connect(pb_close, SIGNAL(clicked()), SLOT(close()));
458
connect(pb_search, SIGNAL(clicked()), SLOT(doSearchSet()));
459
connect(pb_stop, SIGNAL(clicked()), SLOT(doStop()));
460
connect(pb_add, SIGNAL(clicked()), SLOT(doAdd()));
461
connect(pb_info, SIGNAL(clicked()), SLOT(doInfo()));
468
SearchDlg::~SearchDlg()
471
d->pa->dialogUnregister(this);
475
/*void SearchDlg::localUpdate(const JabRosterEntry &e)
477
int oldstate = localStatus;
478
localStatus = e.localStatus();
480
if(localStatus == STATUS_OFFLINE) {
486
pb_search->setEnabled(FALSE);
487
pb_stop->setEnabled(FALSE);
492
if(oldstate == STATUS_OFFLINE) {
493
pb_search->setEnabled(TRUE);
498
void SearchDlg::addEntry(const QString &jid, const QString &nick, const QString &first, const QString &last, const QString &email)
500
QListViewItem *lvi = new QListViewItem(lv_results);
501
lvi->setText(0, nick);
502
lvi->setText(1, first);
503
lvi->setText(2, last);
504
lvi->setText(3, email);
505
lvi->setText(4, jid);
508
void SearchDlg::doSearchGet()
510
lb_instructions->setText(tr("<qt>Fetching search form for %1 ...</qt>").arg(d->jid.full()));
514
d->jt = new JT_XSearch(d->pa->client()->rootTask());
515
connect(d->jt, SIGNAL(finished()), SLOT(jt_finished()));
520
void SearchDlg::doSearchSet()
522
if(d->busy->isActive())
525
if(!d->pa->checkConnected(this))
528
d->jt = new JT_XSearch(d->pa->client()->rootTask());
531
Form submitForm = d->form;
533
// import the changes back into the form.
534
// the QPtrList of QLineEdits should be in the same order
535
QPtrListIterator<QLineEdit> lit(d->le_field);
536
for(Form::Iterator it = submitForm.begin(); it != submitForm.end(); ++it) {
538
QLineEdit *le = lit.current();
539
f.setValue(le->text());
543
d->jt->set(submitForm);
547
form.setFields( d->xdata->fields() );
549
d->jt->setForm( d->form, form );
554
pb_search->setEnabled(false);
555
pb_stop->setEnabled(true);
556
d->gr_form->setEnabled(false);
560
connect(d->jt, SIGNAL(finished()), SLOT(jt_finished()));
564
void SearchDlg::jt_finished()
567
JT_XSearch *jt = d->jt;
571
d->gr_form->setEnabled(true);
572
pb_search->setEnabled(true);
573
pb_stop->setEnabled(false);
578
d->form = jt->form();
580
bool useXData = false;
582
QDomNode n = queryTag( jt->iq() ).firstChild();
583
for( ; !n.isNull(); n = n.nextSibling()) {
584
QDomElement i = n.toElement();
588
if( i.attribute( "xmlns" ) == "jabber:x:data" ) {
594
//if ( !form.title().isEmpty() )
595
// setCaption( form.title() );
597
QString str = plain2rich( form.instructions() );
598
lb_instructions->setText(str);
600
d->xdata = new XDataWidget( d->gr_form );
601
d->xdata->setFields( form.fields() );
611
QString str = plain2rich(d->form.instructions());
612
lb_instructions->setText(str);
614
for(Form::ConstIterator it = d->form.begin(); it != d->form.end(); ++it) {
615
const FormField &f = *it;
617
QLabel *lb = new QLabel(f.fieldName(), d->gr_form);
618
QLineEdit *le = new QLineEdit(d->gr_form);
620
le->setEchoMode(QLineEdit::Password);
621
le->setText(f.value());
623
d->lb_field.append(lb);
624
d->le_field.append(le);
626
connect(le, SIGNAL(returnPressed()), this, SLOT(doSearchSet()));
631
pb_search->setEnabled(true);
634
qApp->processEvents();
639
const QValueList<SearchResult> &list = jt->results();
641
QMessageBox::information(this, tr("Search Results"), tr("Search returned 0 results."));
643
for(QValueList<SearchResult>::ConstIterator it = list.begin(); it != list.end(); ++it) {
644
const SearchResult &r = *it;
645
addEntry(r.jid().full(), r.nick(), r.first(), r.last(), r.email());
651
QDomNode n = queryTag( jt->iq() ).firstChild();
652
for( ; !n.isNull(); n = n.nextSibling()) {
653
QDomElement i = n.toElement();
657
if( i.attribute( "xmlns" ) == "jabber:x:data" ) {
663
while ( lv_results->columns() )
664
lv_results->removeColumn( 0 );
666
QValueList<XData::ReportField>::ConstIterator it = form.report().begin();
667
for ( ; it != form.report().end(); ++it ) {
668
lv_results->addColumn( ( *it ).label );
671
QValueList<XData::ReportItem>::ConstIterator iit = form.reportItems().begin();
672
for ( ; iit != form.reportItems().end(); ++iit ) {
673
QListViewItem *lvi = new QListViewItem(lv_results);
676
it = form.report().begin();
677
for ( ; it != form.report().end(); ++it ) {
678
QString name = ( *it ).name;
679
lvi->setText( i++, ( *iit )[name] );
683
d->xdata_form = form;
689
QMessageBox::critical(this, tr("Error"), tr("Unable to retrieve search form.\nReason: %1").arg(jt->statusString()));
693
QMessageBox::critical(this, tr("Error"), tr("Error retrieving search results.\nReason: %1").arg(jt->statusString()));
698
void SearchDlg::clear()
701
pb_add->setEnabled(false);
702
pb_info->setEnabled(false);
705
void SearchDlg::doStop()
707
if(!d->busy->isActive())
714
d->gr_form->setEnabled(true);
715
pb_search->setEnabled(true);
716
pb_stop->setEnabled(false);
719
void SearchDlg::selectionChanged()
722
QListViewItem *lastChild = lv_results->firstChild();
725
pb_add->setEnabled(false);
726
pb_info->setEnabled(false);
730
if( lastChild->isSelected() ) {
731
pb_add->setEnabled(true);
732
pb_info->setEnabled(true);
737
while ( lastChild->nextSibling() ) {
738
lastChild = lastChild->nextSibling();
739
if( lastChild->isSelected() ) {
740
pb_add->setEnabled(true);
741
pb_info->setEnabled(true);
748
void SearchDlg::doAdd()
750
QListViewItem *i = lv_results->firstChild();
767
QValueList<XData::ReportField>::ConstIterator it = d->xdata_form.report().begin();
768
for ( ; it != d->xdata_form.report().end(); ++it, ++i ) {
769
QString name = ( *it ).name;
773
if ( name == "nickname" || name == "nick" )
780
if( i->isSelected() ) {
781
name = jidnick(i->text(jid), i->text(nick));
782
add(Jid(i->text(jid)), i->text(nick), QStringList(), true);
787
while( i->nextSibling() ) {
788
i = i->nextSibling();
789
if( i->isSelected() ) {
790
name = jidnick(i->text(jid), i->text(nick));
791
add(Jid(i->text(jid)), i->text(nick), QStringList(), true);
798
QMessageBox::information(this, tr("Add User: Success"), tr("Added %1 to your roster.").arg(name));
800
QMessageBox::information(this, tr("Add User: Success"), tr("Added %1 users to your roster.").arg(d));
803
void SearchDlg::doInfo()
805
QListViewItem *i = lv_results->firstChild();
819
QValueList<XData::ReportField>::ConstIterator it = d->xdata_form.report().begin();
820
for ( ; it != d->xdata_form.report().end(); ++it, ++i ) {
821
QString name = ( *it ).name;
827
if( i->isSelected() ) {
828
aInfo(Jid(i->text(jid)));
832
while( i->nextSibling() ) {
833
i = i->nextSibling();
834
if( i->isSelected() ) {
835
aInfo(Jid(i->text(jid)));
841
#include "servicesdlg.moc"