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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "xmpp_xdata.h"
22 #include "xmpp_xmlcommon.h"
26 #include <QSharedDataPointer>
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_Hidden
|| _type
== Field_Fixed
) {
122 if ( _type
== Field_Boolean
) {
123 if ( _value
.count() != 1 )
126 QString str
= _value
.first();
127 if ( str
== "0" || str
== "1" || str
== "true" || str
== "false" || str
== "yes" || str
== "no" )
130 if ( _type
== Field_TextSingle
|| _type
== Field_TextPrivate
) {
131 if ( _value
.count() == 1 )
134 if ( _type
== Field_TextMulti
) {
135 //no particular test. empty/required case already caught (see above)
138 if ( _type
== Field_ListSingle
|| _type
== Field_ListMulti
) {
139 //no particular test. empty/required case already caught (see above)
142 if ( _type
== Field_JidSingle
) {
143 if ( _value
.count() != 1 )
146 Jid
j( _value
.first() );
149 if ( _type
== Field_JidMulti
) {
150 QStringList::ConstIterator it
= _value
.begin();
151 bool allValid
= true;
152 for ( ; it
!= _value
.end(); ++it
) {
154 if ( !j
.isValid() ) {
165 void XData::Field::fromXml(const QDomElement
&e
)
167 if ( e
.tagName() != "field" )
170 _var
= e
.attribute("var");
171 _label
= e
.attribute("label");
173 QString type
= e
.attribute("type");
174 if ( type
== "boolean" )
175 _type
= Field_Boolean
;
176 else if ( type
== "fixed" )
178 else if ( type
== "hidden" )
179 _type
= Field_Hidden
;
180 else if ( type
== "jid-multi" )
181 _type
= Field_JidMulti
;
182 else if ( type
== "jid-single" )
183 _type
= Field_JidSingle
;
184 else if ( type
== "list-multi" )
185 _type
= Field_ListMulti
;
186 else if ( type
== "list-single" )
187 _type
= Field_ListSingle
;
188 else if ( type
== "text-multi" )
189 _type
= Field_TextMulti
;
190 else if ( type
== "text-private" )
191 _type
= Field_TextPrivate
;
193 _type
= Field_TextSingle
;
200 QDomNode n
= e
.firstChild();
201 for ( ; !n
.isNull(); n
= n
.nextSibling() ) {
202 QDomElement i
= n
.toElement();
206 QString tag
= i
.tagName();
207 if ( tag
== "required" )
209 else if ( tag
== "desc" )
210 _desc
= i
.text().trimmed();
211 else if ( tag
== "option" ) {
214 o
.label
= i
.attribute("label");
216 QDomElement e
= findSubTag( i
, "value", &found
);
217 o
.value
= ( found
? e
.text() : QString("") );
220 else if ( tag
== "value" ) {
221 _value
.append(i
.text());
226 QDomElement
XData::Field::toXml(QDomDocument
*doc
, bool submitForm
) const
228 QDomElement f
= doc
->createElement("field");
230 // setting attributes...
231 if ( !_var
.isEmpty() )
232 f
.setAttribute("var", _var
);
233 if ( !submitForm
&& !_label
.isEmpty() )
234 f
.setAttribute("label", _label
);
236 // now we're gonna get the 'type'
237 QString type
= "text-single";
238 if ( _type
== Field_Boolean
)
240 else if ( _type
== Field_Fixed
)
242 else if ( _type
== Field_Hidden
)
244 else if ( _type
== Field_JidMulti
)
246 else if ( _type
== Field_JidSingle
)
248 else if ( _type
== Field_ListMulti
)
250 else if ( _type
== Field_ListSingle
)
251 type
= "list-single";
252 else if ( _type
== Field_TextMulti
)
254 else if ( _type
== Field_TextPrivate
)
255 type
= "text-private";
257 f
.setAttribute("type", type
);
259 // now, setting nested tags...
260 if ( !submitForm
&& _required
)
261 f
.appendChild( emptyTag(doc
, "required") );
263 if ( !submitForm
&& !_desc
.isEmpty() )
264 f
.appendChild( textTag(doc
, "desc", _desc
) );
266 if ( !submitForm
&& !_options
.isEmpty() ) {
267 OptionList::ConstIterator it
= _options
.begin();
268 for ( ; it
!= _options
.end(); ++it
) {
269 QDomElement o
= doc
->createElement("option");
270 o
.appendChild(textTag(doc
, "value", (*it
).value
));
271 if ( !(*it
).label
.isEmpty() )
272 o
.setAttribute("label", (*it
).label
);
277 if ( !_value
.isEmpty() ) {
278 QStringList::ConstIterator it
= _value
.begin();
279 for ( ; it
!= _value
.end(); ++it
)
280 f
.appendChild( textTag(doc
, "value", *it
) );
286 //----------------------------------------------------------------------------
288 //----------------------------------------------------------------------------
295 QString
XData::title() const
300 void XData::setTitle(const QString
&t
)
305 QString
XData::instructions() const
307 return d
->instructions
;
310 void XData::setInstructions(const QString
&i
)
315 XData::Type
XData::type() const
320 void XData::setType(Type t
)
325 XData::FieldList
XData::fields() const
330 void XData::setFields(const FieldList
&f
)
335 void XData::fromXml(const QDomElement
&e
)
337 if ( (e
.attribute("xmlns") != "jabber:x:data") && (e
.namespaceURI() != "jabber:x:data") )
340 QString type
= e
.attribute("type");
341 if ( type
== "result" )
342 d
->type
= Data_Result
;
343 else if ( type
== "submit" )
344 d
->type
= Data_Submit
;
345 else if ( type
== "cancel" )
346 d
->type
= Data_Cancel
;
350 d
->title
= subTagText(e
, "title");
351 d
->instructions
= subTagText(e
, "instructions");
355 QDomNode n
= e
.firstChild();
356 for ( ; !n
.isNull(); n
= n
.nextSibling() ) {
357 QDomElement i
= n
.toElement();
361 if ( i
.tagName() == "field" ) {
366 else if ( i
.tagName() == "reported" ) {
368 d
->reportItems
.clear();
370 QDomNode nn
= i
.firstChild();
371 for ( ; !nn
.isNull(); nn
= nn
.nextSibling() ) {
372 QDomElement ii
= nn
.toElement();
376 if ( ii
.tagName() == "field" ) {
377 d
->report
.append( ReportField( ii
.attribute("label"), ii
.attribute("var") ) );
381 else if ( i
.tagName() == "item" ) {
384 QDomNode nn
= i
.firstChild();
385 for ( ; !nn
.isNull(); nn
= nn
.nextSibling() ) {
386 QDomElement ii
= nn
.toElement();
390 if ( ii
.tagName() == "field" ) {
391 QString name
= ii
.attribute("var");
395 QDomElement e
= findSubTag( ii
, "value", &found
);
403 d
->reportItems
.append( item
);
408 QDomElement
XData::toXml(QDomDocument
*doc
, bool submitForm
) const
410 QDomElement x
= doc
->createElementNS("jabber:x:data", "x");
411 x
.setAttribute("xmlns", "jabber:x:data");
413 QString type
= "form";
414 if ( d
->type
== Data_Result
)
416 else if ( d
->type
== Data_Submit
)
418 else if ( d
->type
== Data_Cancel
)
421 x
.setAttribute("type", type
);
423 if ( !submitForm
&& !d
->title
.isEmpty() )
424 x
.appendChild( textTag(doc
, "title", d
->title
) );
425 if ( !submitForm
&& !d
->instructions
.isEmpty() )
426 x
.appendChild( textTag(doc
, "instructions", d
->instructions
) );
428 if ( !d
->fields
.isEmpty() ) {
429 FieldList::ConstIterator it
= d
->fields
.begin();
430 for ( ; it
!= d
->fields
.end(); ++it
) {
432 if ( !(submitForm
&& f
.var().isEmpty()) )
433 x
.appendChild( f
.toXml(doc
, submitForm
) );
440 const QList
<XData::ReportField
> &XData::report() const
445 const QList
<XData::ReportItem
> &XData::reportItems() const
447 return d
->reportItems
;
450 bool XData::isValid() const
452 foreach(Field f
, d
->fields
) {