2
* xmpp_xdata.cpp - a class for jabber:x:data forms
3
* Copyright (C) 2003-2004 Michail Pishchagin
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 "xmpp_xdata.h"
25
#include "im.h" // for JID validation
26
#include "xmpp_xmlcommon.h"
29
using namespace XMLHelper;
33
//----------------------------------------------------------------------------
35
//----------------------------------------------------------------------------
40
XData::Field::~Field()
44
QString XData::Field::desc() const
49
void XData::Field::setDesc(const QString &d)
54
XData::Field::OptionList XData::Field::options() const
59
void XData::Field::setOptions(XData::Field::OptionList o)
64
bool XData::Field::required() const
69
void XData::Field::setRequired(bool r)
74
QString XData::Field::label() const
79
void XData::Field::setLabel(const QString &l)
84
QString XData::Field::var() const
89
void XData::Field::setVar(const QString &v)
94
QStringList XData::Field::value() const
99
void XData::Field::setValue(const QStringList &v)
104
XData::Field::Type XData::Field::type() const
109
void XData::Field::setType(XData::Field::Type t)
114
bool XData::Field::isValid() const
116
if ( _required && _value.isEmpty() )
119
if ( _type == Field_Boolean ) {
120
if ( _value.count() != 1 )
123
QString str = _value.first();
124
if ( str == "0" || str == "1" || str == "true" || str == "false" || str == "yes" || str == "no" )
127
if ( _type == Field_TextSingle || _type == Field_TextPrivate ) {
128
if ( _value.count() == 1 )
131
if ( _type == Field_JidSingle ) {
132
if ( _value.count() != 1 )
135
Jid j( _value.first() );
138
if ( _type == Field_JidMulti ) {
139
QStringList::ConstIterator it = _value.begin();
140
bool allValid = true;
141
for ( ; it != _value.end(); ++it) {
143
if ( !j.isValid() ) {
154
void XData::Field::fromXml(const QDomElement &e)
156
if ( e.tagName() != "field" )
159
_var = e.attribute("var");
160
_label = e.attribute("label");
162
QString type = e.attribute("type");
163
if ( type == "boolean" )
164
_type = Field_Boolean;
165
else if ( type == "fixed" )
167
else if ( type == "hidden" )
168
_type = Field_Hidden;
169
else if ( type == "jid-multi" )
170
_type = Field_JidMulti;
171
else if ( type == "jid-single" )
172
_type = Field_JidSingle;
173
else if ( type == "list-multi" )
174
_type = Field_ListMulti;
175
else if ( type == "list-single" )
176
_type = Field_ListSingle;
177
else if ( type == "text-multi" )
178
_type = Field_TextMulti;
179
else if ( type == "text-private" )
180
_type = Field_TextPrivate;
182
_type = Field_TextSingle;
185
_desc = QString::null;
189
QDomNode n = e.firstChild();
190
for ( ; !n.isNull(); n = n.nextSibling() ) {
191
QDomElement i = n.toElement();
195
QString tag = i.tagName();
196
if ( tag == "required" )
198
else if ( tag == "desc" )
199
_desc = i.text().simplifyWhiteSpace();
200
else if ( tag == "option" ) {
203
o.label = i.attribute("label");
205
QDomElement e = findSubTag( i, "value", &found );
206
o.value = ( found ? e.text() : QString("") );
209
else if ( tag == "value" ) {
210
_value.append(i.text());
215
QDomElement XData::Field::toXml(QDomDocument *doc, bool submitForm) const
217
QDomElement f = doc->createElement("field");
219
// setting attributes...
220
if ( !_var.isEmpty() )
221
f.setAttribute("var", _var);
222
if ( !submitForm && !_label.isEmpty() )
223
f.setAttribute("label", _label);
225
// now we're gonna get the 'type'
226
QString type = "text-single";
227
if ( _type == Field_Boolean )
229
else if ( _type == Field_Fixed )
231
else if ( _type == Field_Hidden )
233
else if ( _type == Field_JidMulti )
235
else if ( _type == Field_JidSingle )
237
else if ( _type == Field_ListMulti )
239
else if ( _type == Field_ListSingle )
240
type = "list-single";
241
else if ( _type == Field_TextMulti )
243
else if ( _type == Field_TextPrivate )
244
type = "text-private";
246
f.setAttribute("type", type);
248
// now, setting nested tags...
249
if ( !submitForm && _required )
250
f.appendChild( emptyTag(doc, "required") );
252
if ( !submitForm && !_desc.isEmpty() )
253
f.appendChild( textTag(doc, "desc", _desc) );
255
if ( !submitForm && !_options.isEmpty() ) {
256
OptionList::ConstIterator it = _options.begin();
257
for ( ; it != _options.end(); ++it) {
258
QDomElement o = doc->createElement("option");
259
o.appendChild(textTag(doc, "value", (*it).value));
260
if ( !(*it).label.isEmpty() )
261
o.setAttribute("label", (*it).label);
266
if ( !_value.isEmpty() ) {
267
QStringList::ConstIterator it = _value.begin();
268
for ( ; it != _value.end(); ++it)
269
f.appendChild( textTag(doc, "value", *it) );
275
//----------------------------------------------------------------------------
277
//----------------------------------------------------------------------------
278
class XData::Private : public QShared {
280
QString title, instructions;
283
QValueList<ReportField> report;
284
QValueList<ReportItem> reportItems;
298
XData::XData(const XData &x)
304
QString XData::title() const
309
void XData::setTitle(const QString &t)
315
QString XData::instructions() const
317
return d->instructions;
320
void XData::setInstructions(const QString &i)
326
XData::Type XData::type() const
331
void XData::setType(Type t)
337
XData::FieldList XData::fields() const
342
void XData::setFields(const FieldList &f)
348
void XData::fromXml(const QDomElement &e)
350
if ( e.attribute("xmlns") != "jabber:x:data" )
355
QString type = e.attribute("type");
356
if ( type == "result" )
357
d->type = Data_Result;
358
else if ( type == "submit" )
359
d->type = Data_Submit;
360
else if ( type == "cancel" )
361
d->type = Data_Cancel;
365
d->title = subTagText(e, "title");
366
d->instructions = subTagText(e, "instructions");
370
QDomNode n = e.firstChild();
371
for ( ; !n.isNull(); n = n.nextSibling() ) {
372
QDomElement i = n.toElement();
376
if ( i.tagName() == "field" ) {
381
else if ( i.tagName() == "reported" ) {
383
d->reportItems.clear();
385
QDomNode nn = i.firstChild();
386
for ( ; !nn.isNull(); nn = nn.nextSibling() ) {
387
QDomElement ii = nn.toElement();
391
if ( ii.tagName() == "field" ) {
392
d->report.append( ReportField( ii.attribute("label"), ii.attribute("var") ) );
396
else if ( i.tagName() == "item" ) {
399
QDomNode nn = i.firstChild();
400
for ( ; !nn.isNull(); nn = nn.nextSibling() ) {
401
QDomElement ii = nn.toElement();
405
if ( ii.tagName() == "field" ) {
406
QString name = ii.attribute("var");
410
QDomElement e = findSubTag( ii, "value", &found );
418
d->reportItems.append( item );
423
QDomElement XData::toXml(QDomDocument *doc, bool submitForm) const
425
QDomElement x = doc->createElement("x");
426
x.setAttribute("xmlns", "jabber:x:data");
428
QString type = "form";
429
if ( d->type == Data_Result )
431
else if ( d->type == Data_Submit )
433
else if ( d->type == Data_Cancel )
436
x.setAttribute("type", type);
438
if ( !submitForm && !d->title.isEmpty() )
439
x.appendChild( textTag(doc, "title", d->title) );
440
if ( !submitForm && !d->instructions.isEmpty() )
441
x.appendChild( textTag(doc, "instructions", d->instructions) );
443
if ( !d->fields.isEmpty() ) {
444
FieldList::ConstIterator it = d->fields.begin();
445
for ( ; it != d->fields.end(); ++it) {
447
if ( !(submitForm && f.var().isEmpty()) )
448
x.appendChild( f.toXml(doc, submitForm) );
455
XData &XData::operator= (const XData &from)
466
XData XData::copy() const
470
foo.d = new Private( *this->d );
477
if ( d->count != 1 ) // only if >1 reference
481
const QValueList<XData::ReportField> &XData::report() const
486
const QValueList<XData::ReportItem> &XData::reportItems() const
488
return d->reportItems;