Porting work:
[kdenetwork.git] / kopete / protocols / jabber / libiris / iris / xmpp-im / xmpp_xdata.cpp
blob660ab43b160913d078d9f1a5dec92b3bfaf91c4f
1 /*
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"
23 #include "xmpp_jid.h"
25 #include <QList>
26 #include <QSharedDataPointer>
28 using namespace XMPP;
29 using namespace XMLHelper;
31 // TODO: report, item
33 //----------------------------------------------------------------------------
34 // XData::Field
35 //----------------------------------------------------------------------------
36 XData::Field::Field()
40 XData::Field::~Field()
44 QString XData::Field::desc() const
46 return _desc;
49 void XData::Field::setDesc(const QString &d)
51 _desc = d;
54 XData::Field::OptionList XData::Field::options() const
56 return _options;
59 void XData::Field::setOptions(XData::Field::OptionList o)
61 _options = o;
64 bool XData::Field::required() const
66 return _required;
69 void XData::Field::setRequired(bool r)
71 _required = r;
74 QString XData::Field::label() const
76 return _label;
79 void XData::Field::setLabel(const QString &l)
81 _label = l;
84 QString XData::Field::var() const
86 return _var;
89 void XData::Field::setVar(const QString &v)
91 _var = v;
94 QStringList XData::Field::value() const
96 return _value;
99 void XData::Field::setValue(const QStringList &v)
101 _value = v;
104 XData::Field::Type XData::Field::type() const
106 return _type;
109 void XData::Field::setType(XData::Field::Type t)
111 _type = t;
114 bool XData::Field::isValid() const
116 if ( _required && _value.isEmpty() )
117 return false;
119 if ( _type == Field_Hidden || _type == Field_Fixed) {
120 return true;
122 if ( _type == Field_Boolean ) {
123 if ( _value.count() != 1 )
124 return false;
126 QString str = _value.first();
127 if ( str == "0" || str == "1" || str == "true" || str == "false" || str == "yes" || str == "no" )
128 return true;
130 if ( _type == Field_TextSingle || _type == Field_TextPrivate ) {
131 if ( _value.count() == 1 )
132 return true;
134 if ( _type == Field_TextMulti ) {
135 //no particular test. empty/required case already caught (see above)
136 return true;
138 if ( _type == Field_ListSingle || _type == Field_ListMulti ) {
139 //no particular test. empty/required case already caught (see above)
140 return true;
142 if ( _type == Field_JidSingle ) {
143 if ( _value.count() != 1 )
144 return false;
146 Jid j( _value.first() );
147 return j.isValid();
149 if ( _type == Field_JidMulti ) {
150 QStringList::ConstIterator it = _value.begin();
151 bool allValid = true;
152 for ( ; it != _value.end(); ++it) {
153 Jid j(*it);
154 if ( !j.isValid() ) {
155 allValid = false;
156 break;
159 return allValid;
162 return false;
165 void XData::Field::fromXml(const QDomElement &e)
167 if ( e.tagName() != "field" )
168 return;
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" )
177 _type = Field_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;
192 else
193 _type = Field_TextSingle;
195 _required = false;
196 _desc = QString();
197 _options.clear();
198 _value.clear();
200 QDomNode n = e.firstChild();
201 for ( ; !n.isNull(); n = n.nextSibling() ) {
202 QDomElement i = n.toElement();
203 if ( i.isNull() )
204 continue;
206 QString tag = i.tagName();
207 if ( tag == "required" )
208 _required = true;
209 else if ( tag == "desc" )
210 _desc = i.text().trimmed();
211 else if ( tag == "option" ) {
212 Option o;
213 bool found;
214 o.label = i.attribute("label");
216 QDomElement e = findSubTag( i, "value", &found );
217 o.value = ( found ? e.text() : QString("") );
218 _options.append(o);
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 )
239 type = "boolean";
240 else if ( _type == Field_Fixed )
241 type = "fixed";
242 else if ( _type == Field_Hidden )
243 type = "hidden";
244 else if ( _type == Field_JidMulti )
245 type = "jid-multi";
246 else if ( _type == Field_JidSingle )
247 type = "jid-single";
248 else if ( _type == Field_ListMulti )
249 type = "list-multi";
250 else if ( _type == Field_ListSingle )
251 type = "list-single";
252 else if ( _type == Field_TextMulti )
253 type = "text-multi";
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);
273 f.appendChild(o);
277 if ( !_value.isEmpty() ) {
278 QStringList::ConstIterator it = _value.begin();
279 for ( ; it != _value.end(); ++it)
280 f.appendChild( textTag(doc, "value", *it) );
283 return f;
286 //----------------------------------------------------------------------------
287 // XData
288 //----------------------------------------------------------------------------
290 XData::XData()
292 d = new Private;
295 QString XData::title() const
297 return d->title;
300 void XData::setTitle(const QString &t)
302 d->title = t;
305 QString XData::instructions() const
307 return d->instructions;
310 void XData::setInstructions(const QString &i)
312 d->instructions = i;
315 XData::Type XData::type() const
317 return d->type;
320 void XData::setType(Type t)
322 d->type = t;
325 XData::FieldList XData::fields() const
327 return d->fields;
330 void XData::setFields(const FieldList &f)
332 d->fields = f;
335 void XData::fromXml(const QDomElement &e)
337 if ( (e.attribute("xmlns") != "jabber:x:data") && (e.namespaceURI() != "jabber:x:data") )
338 return;
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;
347 else
348 d->type = Data_Form;
350 d->title = subTagText(e, "title");
351 d->instructions = subTagText(e, "instructions");
353 d->fields.clear();
355 QDomNode n = e.firstChild();
356 for ( ; !n.isNull(); n = n.nextSibling() ) {
357 QDomElement i = n.toElement();
358 if ( i.isNull() )
359 continue;
361 if ( i.tagName() == "field" ) {
362 Field f;
363 f.fromXml(i);
364 d->fields.append(f);
366 else if ( i.tagName() == "reported" ) {
367 d->report.clear();
368 d->reportItems.clear();
370 QDomNode nn = i.firstChild();
371 for ( ; !nn.isNull(); nn = nn.nextSibling() ) {
372 QDomElement ii = nn.toElement();
373 if ( ii.isNull() )
374 continue;
376 if ( ii.tagName() == "field" ) {
377 d->report.append( ReportField( ii.attribute("label"), ii.attribute("var") ) );
381 else if ( i.tagName() == "item" ) {
382 ReportItem item;
384 QDomNode nn = i.firstChild();
385 for ( ; !nn.isNull(); nn = nn.nextSibling() ) {
386 QDomElement ii = nn.toElement();
387 if ( ii.isNull() )
388 continue;
390 if ( ii.tagName() == "field" ) {
391 QString name = ii.attribute("var");
392 QString value;
394 bool found;
395 QDomElement e = findSubTag( ii, "value", &found );
396 if ( found )
397 value = e.text();
399 item[name] = value;
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 )
415 type = "result";
416 else if ( d->type == Data_Submit )
417 type = "submit";
418 else if ( d->type == Data_Cancel )
419 type = "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) {
431 Field f = *it;
432 if ( !(submitForm && f.var().isEmpty()) )
433 x.appendChild( f.toXml(doc, submitForm) );
437 return x;
440 const QList<XData::ReportField> &XData::report() const
442 return d->report;
445 const QList<XData::ReportItem> &XData::reportItems() const
447 return d->reportItems;
450 bool XData::isValid() const
452 foreach(Field f, d->fields) {
453 if (!f.isValid())
454 return false;
456 return true;