~ubuntu-branches/ubuntu/edgy/psi/edgy

« back to all changes in this revision

Viewing changes to src/xdata_widget.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Stephan Hermann
  • Date: 2005-09-14 16:33:49 UTC
  • mfrom: (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050914163349-3zacov4afysz5cw5
Tags: 0.9.3-2ubuntu1
* Sync with debian
* Applied patch to psi.desktop to start psi without gpg-agent use (known
  issue)
* Updated README.Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * xdata_widget.cpp - a class for displaying jabber:x:data forms
 
3
 * Copyright (C) 2003-2004  Michail Pishchagin
 
4
 *
 
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.
 
9
 *
 
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.
 
14
 *
 
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
 
18
 *
 
19
 */
 
20
 
 
21
#include "xdata_widget.h"
 
22
 
 
23
#include <qlayout.h>
 
24
#include <qlabel.h>
 
25
#include <qcheckbox.h>
 
26
#include <qcombobox.h>
 
27
#include <qlistbox.h>
 
28
#include <qlineedit.h>
 
29
#include <qptrlist.h>
 
30
#include <qobjectlist.h>
 
31
#include <qtooltip.h>
 
32
#include <qtextedit.h>
 
33
 
 
34
//----------------------------------------------------------------------------
 
35
// XDataField
 
36
//----------------------------------------------------------------------------
 
37
class XDataField
 
38
{
 
39
public:
 
40
        XDataField(XData::Field f)
 
41
        {
 
42
                _field = f;
 
43
        }
 
44
        virtual ~XDataField()
 
45
        {
 
46
        }
 
47
 
 
48
        virtual XData::Field field() const
 
49
        {
 
50
                return _field;
 
51
        }
 
52
 
 
53
        QString labelText() const
 
54
        {
 
55
                QString text = _field.label();
 
56
                if ( text.isEmpty() )
 
57
                        text = _field.var();
 
58
                return text + ": ";
 
59
        }
 
60
 
 
61
        QString reqText() const
 
62
        {
 
63
                QString req;
 
64
                if ( _field.required() )
 
65
                        req = "*";
 
66
                if ( !_field.desc().isEmpty() ) {
 
67
                        if ( !req.isEmpty() )
 
68
                                req += " ";
 
69
                        req += "(?)";
 
70
                }
 
71
                return req;
 
72
        }
 
73
 
 
74
        virtual bool isValid() const
 
75
        {
 
76
                return field().isValid();
 
77
        }
 
78
 
 
79
private:
 
80
        XData::Field _field;
 
81
};
 
82
 
 
83
////////////////////////////////////////
 
84
 
 
85
class XDataField_Hidden : public XDataField
 
86
{
 
87
public:
 
88
        XDataField_Hidden(XData::Field f)
 
89
        : XDataField(f)
 
90
        {
 
91
        }
 
92
};
 
93
 
 
94
////////////////////////////////////////
 
95
 
 
96
class XDataField_Boolean : public XDataField
 
97
{
 
98
public:
 
99
        XDataField_Boolean(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
100
        : XDataField(f)
 
101
        {
 
102
                bool checked = false;
 
103
                if ( f.value().count() ) {
 
104
                        QString s = f.value().first();
 
105
                        if ( s == "1" || s == "true" || s == "yes" )
 
106
                                checked = true;
 
107
                }
 
108
 
 
109
                QLabel *label = new QLabel(labelText(), parent);
 
110
                grid->addWidget(label, row, 0);
 
111
 
 
112
                check = new QCheckBox(parent);
 
113
                check->setChecked(checked);
 
114
                grid->addWidget(check, row, 1);
 
115
 
 
116
                QLabel *req = new QLabel(reqText(), parent);
 
117
                grid->addWidget(req, row, 2);
 
118
 
 
119
                if ( !f.desc().isEmpty() ) {
 
120
                        QToolTip::add(label, f.desc());
 
121
                        QToolTip::add(check, f.desc());
 
122
                        QToolTip::add(req, f.desc());
 
123
                }
 
124
        }
 
125
 
 
126
        XData::Field field() const
 
127
        {
 
128
                XData::Field f = XDataField::field();
 
129
                QStringList val;
 
130
                val << QString( check->isChecked() ? "1" : "0" );
 
131
                f.setValue(val);
 
132
                return f;
 
133
        }
 
134
 
 
135
private:
 
136
        QCheckBox *check;
 
137
};
 
138
 
 
139
////////////////////////////////////////
 
140
 
 
141
class XDataField_Fixed : public XDataField
 
142
{
 
143
public:
 
144
        XDataField_Fixed(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
145
        : XDataField(f)
 
146
        {
 
147
                QString text;
 
148
                QStringList val = f.value();
 
149
                QStringList::Iterator it = val.begin();
 
150
                for ( ; it != val.end(); ++it) {
 
151
                        if ( !text.isEmpty() )
 
152
                                text += "<br>";
 
153
                        text += *it;
 
154
                }
 
155
 
 
156
                QLabel *fixed = new QLabel("<qt>" + text + "</qt>", parent);
 
157
                grid->addMultiCellWidget(fixed, row, row, 0, 2);
 
158
 
 
159
                if ( !f.desc().isEmpty() ) {
 
160
                        QToolTip::add(fixed, f.desc());
 
161
                }
 
162
        }
 
163
};
 
164
 
 
165
////////////////////////////////////////
 
166
 
 
167
class XDataField_TextSingle : public XDataField
 
168
{
 
169
public:
 
170
        XDataField_TextSingle(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
171
        : XDataField(f)
 
172
        {
 
173
                QString text;
 
174
                if ( f.value().count() )
 
175
                        text = f.value().first();
 
176
 
 
177
                QLabel *label = new QLabel(labelText(), parent);
 
178
                grid->addWidget(label, row, 0);
 
179
 
 
180
                edit = new QLineEdit(parent);
 
181
                edit->setText(text);
 
182
                grid->addWidget(edit, row, 1);
 
183
 
 
184
                QLabel *req = new QLabel(reqText(), parent);
 
185
                grid->addWidget(req, row, 2);
 
186
 
 
187
                if ( !f.desc().isEmpty() ) {
 
188
                        QToolTip::add(label, f.desc());
 
189
                        QToolTip::add(edit, f.desc());
 
190
                        QToolTip::add(req, f.desc());
 
191
                }
 
192
        }
 
193
 
 
194
        XData::Field field() const
 
195
        {
 
196
                XData::Field f = XDataField::field();
 
197
                QStringList val;
 
198
                val << edit->text();
 
199
                f.setValue(val);
 
200
                return f;
 
201
        }
 
202
 
 
203
protected:
 
204
        QLineEdit *edit;
 
205
};
 
206
 
 
207
////////////////////////////////////////
 
208
 
 
209
class XDataField_TextPrivate : public XDataField_TextSingle
 
210
{
 
211
public:
 
212
        XDataField_TextPrivate(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
213
        : XDataField_TextSingle(f, grid, row, parent)
 
214
        {
 
215
                edit->setEchoMode(QLineEdit::Password);
 
216
        }
 
217
};
 
218
 
 
219
////////////////////////////////////////
 
220
 
 
221
class XDataField_JidSingle : public XDataField_TextSingle
 
222
{
 
223
public:
 
224
        XDataField_JidSingle(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
225
        : XDataField_TextSingle(f, grid, row, parent)
 
226
        {
 
227
                // TODO: add proper validation
 
228
        }
 
229
};
 
230
 
 
231
////////////////////////////////////////
 
232
 
 
233
class XDataField_ListSingle : public XDataField
 
234
{
 
235
public:
 
236
        XDataField_ListSingle(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
237
        : XDataField(f)
 
238
        {
 
239
                QLabel *label = new QLabel(labelText(), parent);
 
240
                grid->addWidget(label, row, 0);
 
241
 
 
242
                combo = new QComboBox(parent);
 
243
                grid->addWidget(combo, row, 1);
 
244
                combo->setInsertionPolicy(QComboBox::NoInsertion);
 
245
 
 
246
                QString sel;
 
247
                if ( !f.value().isEmpty() )
 
248
                        sel = f.value().first();
 
249
 
 
250
                XData::Field::OptionList opts = f.options();
 
251
                XData::Field::OptionList::Iterator it = opts.begin();
 
252
                for ( ; it != opts.end(); ++it) {
 
253
                        QString lbl = (*it).label;
 
254
                        if ( lbl.isEmpty() )
 
255
                                lbl = (*it).value;
 
256
 
 
257
                        combo->insertItem(lbl);
 
258
                        if ( (*it).value == sel )
 
259
                                combo->setCurrentText( lbl );
 
260
                }
 
261
 
 
262
                QLabel *req = new QLabel(reqText(), parent);
 
263
                grid->addWidget(req, row, 2);
 
264
 
 
265
                if ( !f.desc().isEmpty() ) {
 
266
                        QToolTip::add(label, f.desc());
 
267
                        QToolTip::add(combo, f.desc());
 
268
                        QToolTip::add(req, f.desc());
 
269
                }
 
270
        }
 
271
 
 
272
        XData::Field field() const
 
273
        {
 
274
                QString lbl = combo->currentText();
 
275
 
 
276
                XData::Field f = XDataField::field();
 
277
                QStringList val;
 
278
 
 
279
                XData::Field::OptionList opts = f.options();
 
280
                XData::Field::OptionList::Iterator it = opts.begin();
 
281
                for ( ; it != opts.end(); ++it) {
 
282
                        if ( (*it).label == lbl || (*it).value == lbl ) {
 
283
                                val << (*it).value;
 
284
                                break;
 
285
                        }
 
286
                }
 
287
 
 
288
                f.setValue(val);
 
289
                return f;
 
290
        }
 
291
 
 
292
private:
 
293
        QComboBox *combo;
 
294
};
 
295
 
 
296
////////////////////////////////////////
 
297
 
 
298
class XDataField_ListMulti : public XDataField
 
299
{
 
300
public:
 
301
        XDataField_ListMulti(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
302
        : XDataField(f)
 
303
        {
 
304
                QLabel *label = new QLabel(labelText(), parent);
 
305
                grid->addWidget(label, row, 0);
 
306
 
 
307
                list = new QListBox(parent);
 
308
                grid->addWidget(list, row, 1);
 
309
                list->setSelectionMode(QListBox::Multi);
 
310
 
 
311
                QListBoxText *last = 0;
 
312
                XData::Field::OptionList opts = f.options();
 
313
                XData::Field::OptionList::Iterator it = opts.begin();
 
314
                for ( ; it != opts.end(); ++it) {
 
315
                        QString lbl = (*it).label;
 
316
                        if ( lbl.isEmpty() )
 
317
                                lbl = (*it).value;
 
318
 
 
319
                        QListBoxText *item = new QListBoxText(list, lbl, last);
 
320
 
 
321
                        QStringList val = f.value();
 
322
                        QStringList::Iterator sit = val.begin();
 
323
                        for ( ; sit != val.end(); ++sit)
 
324
                                if ( (*it).label == *sit || (*it).value == *sit )
 
325
                                        list->setSelected(item, true);
 
326
 
 
327
                        last = item;
 
328
                }
 
329
 
 
330
                QLabel *req = new QLabel(reqText(), parent);
 
331
                grid->addWidget(req, row, 2);
 
332
 
 
333
                if ( !f.desc().isEmpty() ) {
 
334
                        QToolTip::add(label, f.desc());
 
335
                        QToolTip::add(list, f.desc());
 
336
                        QToolTip::add(req, f.desc());
 
337
                }
 
338
        }
 
339
 
 
340
        XData::Field field() const
 
341
        {
 
342
                XData::Field f = XDataField::field();
 
343
                QStringList val;
 
344
 
 
345
                QListBoxItem *item = list->firstItem();
 
346
                while ( item ) {
 
347
                        if ( item->isSelected() ) {
 
348
                                QString lbl = item->text();
 
349
                                XData::Field::OptionList opts = f.options();
 
350
                                XData::Field::OptionList::Iterator it = opts.begin();
 
351
                                for ( ; it != opts.end(); ++it) {
 
352
                                        if ( (*it).label == lbl || (*it).value == lbl ) {
 
353
                                                val << (*it).value;
 
354
                                                break;
 
355
                                        }
 
356
                                }
 
357
                        }
 
358
 
 
359
                        item = item->next();
 
360
                }
 
361
 
 
362
                f.setValue(val);
 
363
                return f;
 
364
        }
 
365
 
 
366
private:
 
367
        QListBox *list;
 
368
};
 
369
 
 
370
////////////////////////////////////////
 
371
 
 
372
class XDataField_TextMulti : public XDataField
 
373
{
 
374
public:
 
375
        XDataField_TextMulti(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
376
        : XDataField(f)
 
377
        {
 
378
                QLabel *label = new QLabel(labelText(), parent);
 
379
                grid->addWidget(label, row, 0);
 
380
 
 
381
                edit = new QTextEdit(parent);
 
382
                grid->addWidget(edit, row, 1);
 
383
 
 
384
                QString text;
 
385
                QStringList val = f.value();
 
386
                QStringList::Iterator it = val.begin();
 
387
                for ( ; it != val.end(); ++it) {
 
388
                        if ( !text.isEmpty() )
 
389
                                text += "\n";
 
390
                        text += *it;
 
391
                }
 
392
                edit->setText(text);
 
393
 
 
394
                QLabel *req = new QLabel(reqText(), parent);
 
395
                grid->addWidget(req, row, 2);
 
396
 
 
397
                if ( !f.desc().isEmpty() ) {
 
398
                        QToolTip::add(label, f.desc());
 
399
                        QToolTip::add(edit, f.desc());
 
400
                        QToolTip::add(req, f.desc());
 
401
                }
 
402
        }
 
403
 
 
404
        XData::Field field() const
 
405
        {
 
406
                XData::Field f = XDataField::field();
 
407
                f.setValue( QStringList::split("\n", edit->text(), true) );
 
408
                return f;
 
409
        }
 
410
 
 
411
private:
 
412
        QTextEdit *edit;
 
413
};
 
414
 
 
415
////////////////////////////////////////
 
416
 
 
417
class XDataField_JidMulti : public XDataField_TextMulti
 
418
{
 
419
public:
 
420
        XDataField_JidMulti(XData::Field f, QGridLayout *grid, int row, QWidget *parent)
 
421
        : XDataField_TextMulti(f, grid, row, parent)
 
422
        {
 
423
                // TODO: improve validation
 
424
        }
 
425
};
 
426
 
 
427
//----------------------------------------------------------------------------
 
428
// XDataWidget
 
429
//----------------------------------------------------------------------------
 
430
class XDataWidget::Private
 
431
{
 
432
public:
 
433
        Private() {
 
434
                fields.setAutoDelete(true);
 
435
        }
 
436
 
 
437
        typedef QPtrList<XDataField> XDataFieldList;
 
438
        XDataFieldList fields;
 
439
};
 
440
 
 
441
XDataWidget::XDataWidget(QWidget *parent, const char *name)
 
442
: QWidget(parent, name)
 
443
{
 
444
        d = new Private;
 
445
}
 
446
 
 
447
XDataWidget::~XDataWidget()
 
448
{
 
449
        delete d;
 
450
}
 
451
 
 
452
XData::FieldList XDataWidget::fields() const
 
453
{
 
454
        XData::FieldList f;
 
455
 
 
456
        QPtrListIterator<XDataField> it (d->fields);
 
457
        XDataField *field;
 
458
        for ( ; (field = it.current()); ++it)
 
459
                f.append( field->field() );
 
460
 
 
461
        return f;
 
462
}
 
463
 
 
464
void XDataWidget::setFields(const XData::FieldList &f)
 
465
{
 
466
        d->fields.clear();
 
467
 
 
468
        // delete all child widgets
 
469
        QObjectList *objlist = queryList();
 
470
        objlist->setAutoDelete(true);
 
471
        delete objlist;
 
472
 
 
473
        if ( f.count() ) {
 
474
                QGridLayout *grid = new QGridLayout(this, 3, f.count(), 0, 3);
 
475
 
 
476
                int row = 0;
 
477
                XData::FieldList::ConstIterator it = f.begin();
 
478
                for ( ; it != f.end(); ++it, ++row) {
 
479
                        XDataField *f;
 
480
                        switch ( (*it).type() ) {
 
481
                                case XData::Field::Field_Boolean:
 
482
                                        f = new XDataField_Boolean(*it, grid, row, this);
 
483
                                        break;
 
484
                                case XData::Field::Field_Fixed:
 
485
                                        f = new XDataField_Fixed(*it, grid, row, this);
 
486
                                        break;
 
487
                                case XData::Field::Field_Hidden:
 
488
                                        f = new XDataField_Hidden(*it);
 
489
                                        break;
 
490
                                case XData::Field::Field_JidSingle:
 
491
                                        f = new XDataField_JidSingle(*it, grid, row, this);
 
492
                                        break;
 
493
                                case XData::Field::Field_ListMulti:
 
494
                                        f = new XDataField_ListMulti(*it, grid, row, this);
 
495
                                        break;
 
496
                                case XData::Field::Field_ListSingle:
 
497
                                        f = new XDataField_ListSingle(*it, grid, row, this);
 
498
                                        break;
 
499
                                case XData::Field::Field_TextMulti:
 
500
                                        f = new XDataField_TextMulti(*it, grid, row, this);
 
501
                                        break;
 
502
                                case XData::Field::Field_JidMulti:
 
503
                                        f = new XDataField_JidMulti(*it, grid, row, this);
 
504
                                        break;
 
505
                                case XData::Field::Field_TextPrivate:
 
506
                                        f = new XDataField_TextPrivate(*it, grid, row, this);
 
507
                                        break;
 
508
 
 
509
                                default:
 
510
                                        f = new XDataField_TextSingle(*it, grid, row, this);
 
511
                        }
 
512
                        d->fields.append(f);
 
513
                }
 
514
        }
 
515
}