source: trunk/src/sql/qsqlform.cpp

Last change on this file was 196, checked in by rudi, 14 years ago

Add SQL module (currently it isn't build by default, however it's needed for QtDesigner)

File size: 10.5 KB
Line 
1/****************************************************************************
2**
3** Implementation of QSqlForm class
4**
5** Created : 2000-11-03
6**
7** Copyright (C) 2005-2007 Trolltech ASA. All rights reserved.
8**
9** This file is part of the sql module of the Qt GUI Toolkit.
10**
11** This file may be distributed under the terms of the Q Public License
12** as defined by Trolltech ASA of Norway and appearing in the file
13** LICENSE.QPL included in the packaging of this file.
14**
15** This file may be distributed and/or modified under the terms of the
16** GNU General Public License version 2 as published by the Free Software
17** Foundation and appearing in the file LICENSE.GPL included in the
18** packaging of this file.
19**
20** Licensees holding valid Qt Enterprise Edition licenses may use this
21** file in accordance with the Qt Commercial License Agreement provided
22** with the Software.
23**
24** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26**
27** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
28** information about Qt Commercial License Agreements.
29** See http://www.trolltech.com/qpl/ for QPL licensing information.
30** See http://www.trolltech.com/gpl/ for GPL licensing information.
31**
32** Contact info@trolltech.com if any conditions of this licensing are
33** not clear to you.
34**
35**********************************************************************/
36
37#include "qsqlform.h"
38
39#ifndef QT_NO_SQL_FORM
40
41#include "qsqlfield.h"
42#include "qsqlpropertymap.h"
43#include "qsqlrecord.h"
44#include "qstringlist.h"
45#include "qwidget.h"
46#include "qdict.h"
47
48class QSqlFormPrivate
49{
50public:
51 QSqlFormPrivate() : propertyMap( 0 ), buf( 0 ), dirty( FALSE ) {}
52 ~QSqlFormPrivate() { if ( propertyMap ) delete propertyMap; }
53 QStringList fld;
54 QDict<QWidget> wgt;
55 QMap< QWidget *, QSqlField * > map;
56 QSqlPropertyMap * propertyMap;
57 QSqlRecord* buf;
58 bool dirty;
59};
60
61/*!
62 \class QSqlForm
63 \brief The QSqlForm class creates and manages data entry forms
64 tied to SQL databases.
65
66 \ingroup database
67 \mainclass
68 \module sql
69
70 Typical use of a QSqlForm consists of the following steps:
71 \list
72 \i Create the widgets you want to appear in the form.
73 \i Create a cursor and navigate to the record to be edited.
74 \i Create the QSqlForm.
75 \i Set the form's record buffer to the cursor's update buffer.
76 \i Insert each widget and the field it is to edit into the form.
77 \i Use readFields() to update the editor widgets with values from
78 the database's fields.
79 \i Display the form and let the user edit values etc.
80 \i Use writeFields() to update the database's field values with
81 the values in the editor widgets.
82 \endlist
83
84 Note that a QSqlForm does not access the database directly, but
85 most often via QSqlFields which are part of a QSqlCursor. A
86 QSqlCursor::insert(), QSqlCursor::update() or QSqlCursor::del()
87 call is needed to actually write values to the database.
88
89 Some sample code to initialize a form successfully:
90
91 \code
92 QLineEdit myEditor( this );
93 QSqlForm myForm( this );
94 QSqlCursor myCursor( "mytable" );
95
96 // Execute a query to make the cursor valid
97 myCursor.select();
98 // Move the cursor to a valid record (the first record)
99 myCursor.next();
100 // Set the form's record pointer to the cursor's edit buffer (which
101 // contains the current record's values)
102 myForm.setRecord( myCursor.primeUpdate() );
103
104 // Insert a field into the form that uses myEditor to edit the
105 // field 'somefield' in 'mytable'
106 myForm.insert( &myEditor, "somefield" );
107
108 // Update myEditor with the value from the mapped database field
109 myForm.readFields();
110 ...
111 // Let the user edit the form
112 ...
113 // Update the database
114 myForm.writeFields(); // Update the cursor's edit buffer from the form
115 myCursor.update(); // Update the database from the cursor's buffer
116 \endcode
117
118 If you want to use custom editors for displaying and editing data
119 fields, you must install a custom QSqlPropertyMap. The form
120 uses this object to get or set the value of a widget.
121
122 Note that \link designer-manual.book Qt Designer\endlink provides
123 a visual means of creating data-aware forms.
124
125 \sa installPropertyMap(), QSqlPropertyMap
126*/
127
128
129/*!
130 Constructs a QSqlForm with parent \a parent and called \a name.
131*/
132QSqlForm::QSqlForm( QObject * parent, const char * name )
133 : QObject( parent, name )
134{
135 d = new QSqlFormPrivate();
136}
137
138/*!
139 Destroys the object and frees any allocated resources.
140*/
141QSqlForm::~QSqlForm()
142{
143 delete d;
144}
145
146/*!
147 Installs a custom QSqlPropertyMap. This is useful if you plan to
148 create your own custom editor widgets.
149
150 QSqlForm takes ownership of \a pmap, so \a pmap is deleted when
151 QSqlForm goes out of scope.
152
153 \sa QDataTable::installEditorFactory()
154*/
155void QSqlForm::installPropertyMap( QSqlPropertyMap * pmap )
156{
157 if( d->propertyMap )
158 delete d->propertyMap;
159 d->propertyMap = pmap;
160}
161
162/*!
163 Sets \a buf as the record buffer for the form. To force the
164 display of the data from \a buf, use readFields().
165
166 \sa readFields() writeFields()
167*/
168
169void QSqlForm::setRecord( QSqlRecord* buf )
170{
171 d->dirty = TRUE;
172 d->buf = buf;
173}
174
175/*!
176 Inserts a \a widget, and the name of the \a field it is to be
177 mapped to, into the form. To actually associate inserted widgets
178 with an edit buffer, use setRecord().
179
180 \sa setRecord()
181*/
182
183void QSqlForm::insert( QWidget * widget, const QString& field )
184{
185 d->dirty = TRUE;
186 d->wgt.insert( field, widget );
187 d->fld += field;
188}
189
190/*!
191 \overload
192
193 Removes \a field from the form.
194*/
195
196void QSqlForm::remove( const QString& field )
197{
198 d->dirty = TRUE;
199 if ( d->fld.find( field ) != d->fld.end() )
200 d->fld.remove( d->fld.find( field ) );
201 d->wgt.remove( field );
202}
203
204/*!
205 \overload
206
207 Inserts a \a widget, and the \a field it is to be mapped to, into
208 the form.
209*/
210
211void QSqlForm::insert( QWidget * widget, QSqlField * field )
212{
213 d->map[widget] = field;
214}
215
216/*!
217 Removes a \a widget, and hence the field it's mapped to, from the
218 form.
219*/
220
221void QSqlForm::remove( QWidget * widget )
222{
223 d->map.remove( widget );
224}
225
226/*!
227 Clears the values in all the widgets, and the fields they are
228 mapped to, in the form. If \a nullify is TRUE (the default is
229 FALSE), each field is also set to NULL.
230*/
231void QSqlForm::clearValues( bool nullify )
232{
233 QMap< QWidget *, QSqlField * >::Iterator it;
234 for( it = d->map.begin(); it != d->map.end(); ++it ){
235 QSqlField* f = (*it);
236 if ( f )
237 f->clear( nullify );
238 }
239 readFields();
240}
241
242/*!
243 Removes every widget, and the fields they're mapped to, from the form.
244*/
245void QSqlForm::clear()
246{
247 d->dirty = TRUE;
248 d->fld.clear();
249 clearMap();
250}
251
252/*!
253 Returns the number of widgets in the form.
254*/
255uint QSqlForm::count() const
256{
257 return (uint)d->map.count();
258}
259
260/*!
261 Returns the \a{i}-th widget in the form. Useful for traversing
262 the widgets in the form.
263*/
264QWidget * QSqlForm::widget( uint i ) const
265{
266 QMap< QWidget *, QSqlField * >::ConstIterator it;
267 uint cnt = 0;
268
269 if( i > d->map.count() ) return 0;
270 for( it = d->map.begin(); it != d->map.end(); ++it ){
271 if( cnt++ == i )
272 return it.key();
273 }
274 return 0;
275}
276
277/*!
278 Returns the widget that field \a field is mapped to.
279*/
280QWidget * QSqlForm::fieldToWidget( QSqlField * field ) const
281{
282 QMap< QWidget *, QSqlField * >::ConstIterator it;
283 for( it = d->map.begin(); it != d->map.end(); ++it ){
284 if( *it == field )
285 return it.key();
286 }
287 return 0;
288}
289
290/*!
291 Returns the SQL field that widget \a widget is mapped to.
292*/
293QSqlField * QSqlForm::widgetToField( QWidget * widget ) const
294{
295 if( d->map.contains( widget ) )
296 return d->map[widget];
297 else
298 return 0;
299}
300
301/*!
302 Updates the widgets in the form with current values from the SQL
303 fields they are mapped to.
304*/
305void QSqlForm::readFields()
306{
307 sync();
308 QSqlField * f;
309 QMap< QWidget *, QSqlField * >::Iterator it;
310 QSqlPropertyMap * pmap = (d->propertyMap == 0) ?
311 QSqlPropertyMap::defaultMap() : d->propertyMap;
312 for(it = d->map.begin() ; it != d->map.end(); ++it ){
313 f = widgetToField( it.key() );
314 if( !f )
315 continue;
316 pmap->setProperty( it.key(), f->value() );
317 }
318}
319
320/*!
321 Updates the SQL fields with values from the widgets they are
322 mapped to. To actually update the database with the contents of
323 the record buffer, use QSqlCursor::insert(), QSqlCursor::update()
324 or QSqlCursor::del() as appropriate.
325*/
326void QSqlForm::writeFields()
327{
328 sync();
329 QSqlField * f;
330 QMap< QWidget *, QSqlField * >::Iterator it;
331 QSqlPropertyMap * pmap = (d->propertyMap == 0) ?
332 QSqlPropertyMap::defaultMap() : d->propertyMap;
333
334 for(it = d->map.begin() ; it != d->map.end(); ++it ){
335 f = widgetToField( it.key() );
336 if( !f )
337 continue;
338 f->setValue( pmap->property( it.key() ) );
339 }
340}
341
342/*!
343 Updates the widget \a widget with the value from the SQL field it
344 is mapped to. Nothing happens if no SQL field is mapped to the \a
345 widget.
346*/
347void QSqlForm::readField( QWidget * widget )
348{
349 sync();
350 QSqlField * field = 0;
351 QSqlPropertyMap * pmap = (d->propertyMap == 0) ?
352 QSqlPropertyMap::defaultMap() : d->propertyMap;
353 field = widgetToField( widget );
354 if( field )
355 pmap->setProperty( widget, field->value() );
356}
357
358/*!
359 Updates the SQL field with the value from the \a widget it is
360 mapped to. Nothing happens if no SQL field is mapped to the \a
361 widget.
362*/
363void QSqlForm::writeField( QWidget * widget )
364{
365 sync();
366 QSqlField * field = 0;
367 QSqlPropertyMap * pmap = (d->propertyMap == 0) ?
368 QSqlPropertyMap::defaultMap() : d->propertyMap;
369 field = widgetToField( widget );
370 if( field )
371 field->setValue( pmap->property( widget ) );
372}
373
374/*! \internal
375*/
376
377void QSqlForm::sync()
378{
379 if ( d->dirty ) {
380 clearMap();
381 if ( d->buf ) {
382 for ( uint i = 0; i < d->fld.count(); ++i )
383 insert( d->wgt[ d->fld[ i ] ], d->buf->field( d->fld[ i ] ) );
384 }
385 }
386 d->dirty = FALSE;
387}
388
389/*! \internal
390
391 Clears the internal map of widget/field associations
392*/
393
394void QSqlForm::clearMap()
395{
396 d->map.clear();
397}
398
399#endif // QT_NO_SQL
Note: See TracBrowser for help on using the repository browser.