|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the Qt3Support module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include "q3sqlform.h" |
|
43 |
|
44 #ifndef QT_NO_SQL_FORM |
|
45 |
|
46 #include "qsqlfield.h" |
|
47 #include "q3sqlpropertymap.h" |
|
48 #include "qsqlrecord.h" |
|
49 #include "qstringlist.h" |
|
50 #include "qwidget.h" |
|
51 #include "qhash.h" |
|
52 |
|
53 QT_BEGIN_NAMESPACE |
|
54 |
|
55 class Q3SqlFormPrivate |
|
56 { |
|
57 public: |
|
58 Q3SqlFormPrivate() : propertyMap(0), buf(0), dirty(false) {} |
|
59 ~Q3SqlFormPrivate() { if (propertyMap) delete propertyMap; } |
|
60 QStringList fld; |
|
61 QHash <QString, QWidget*> wgt; |
|
62 QMap <QWidget*, QSqlField *> map; |
|
63 Q3SqlPropertyMap * propertyMap; |
|
64 QSqlRecord* buf; |
|
65 bool dirty; |
|
66 }; |
|
67 |
|
68 /*! |
|
69 \class Q3SqlForm |
|
70 \brief The Q3SqlForm class creates and manages data entry forms |
|
71 tied to SQL databases. |
|
72 |
|
73 \compat |
|
74 |
|
75 Typical use of a Q3SqlForm consists of the following steps: |
|
76 \list |
|
77 \i Create the widgets you want to appear in the form. |
|
78 \i Create a cursor and navigate to the record to be edited. |
|
79 \i Create the Q3SqlForm. |
|
80 \i Set the form's record buffer to the cursor's update buffer. |
|
81 \i Insert each widget and the field it is to edit into the form. |
|
82 \i Use readFields() to update the editor widgets with values from |
|
83 the database's fields. |
|
84 \i Display the form and let the user edit values etc. |
|
85 \i Use writeFields() to update the database's field values with |
|
86 the values in the editor widgets. |
|
87 \endlist |
|
88 |
|
89 Note that a Q3SqlForm does not access the database directly, but |
|
90 most often via QSqlFields which are part of a Q3SqlCursor. A |
|
91 Q3SqlCursor::insert(), Q3SqlCursor::update() or Q3SqlCursor::del() |
|
92 call is needed to actually write values to the database. |
|
93 |
|
94 Some sample code to initialize a form successfully: |
|
95 |
|
96 \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlform.cpp 0 |
|
97 |
|
98 If you want to use custom editors for displaying and editing data |
|
99 fields, you must install a custom Q3SqlPropertyMap. The form |
|
100 uses this object to get or set the value of a widget. |
|
101 |
|
102 \sa installPropertyMap(), Q3SqlPropertyMap |
|
103 */ |
|
104 |
|
105 |
|
106 /*! |
|
107 Constructs a Q3SqlForm with parent \a parent. |
|
108 */ |
|
109 Q3SqlForm::Q3SqlForm(QObject * parent) |
|
110 : QObject(parent) |
|
111 { |
|
112 d = new Q3SqlFormPrivate(); |
|
113 } |
|
114 |
|
115 /*! |
|
116 Destroys the object and frees any allocated resources. |
|
117 */ |
|
118 Q3SqlForm::~Q3SqlForm() |
|
119 { |
|
120 delete d; |
|
121 } |
|
122 |
|
123 /*! |
|
124 Installs a custom Q3SqlPropertyMap. This is useful if you plan to |
|
125 create your own custom editor widgets. |
|
126 |
|
127 Q3SqlForm takes ownership of \a pmap, so \a pmap is deleted when |
|
128 Q3SqlForm goes out of scope. |
|
129 |
|
130 \sa Q3DataTable::installEditorFactory() |
|
131 */ |
|
132 void Q3SqlForm::installPropertyMap(Q3SqlPropertyMap * pmap) |
|
133 { |
|
134 if(d->propertyMap) |
|
135 delete d->propertyMap; |
|
136 d->propertyMap = pmap; |
|
137 } |
|
138 |
|
139 /*! |
|
140 Sets \a buf as the record buffer for the form. To force the |
|
141 display of the data from \a buf, use readFields(). |
|
142 |
|
143 \sa readFields() writeFields() |
|
144 */ |
|
145 |
|
146 void Q3SqlForm::setRecord(QSqlRecord* buf) |
|
147 { |
|
148 d->dirty = true; |
|
149 d->buf = buf; |
|
150 } |
|
151 |
|
152 /*! |
|
153 Inserts a \a widget, and the name of the \a field it is to be |
|
154 mapped to, into the form. To actually associate inserted widgets |
|
155 with an edit buffer, use setRecord(). |
|
156 |
|
157 \sa setRecord() |
|
158 */ |
|
159 |
|
160 void Q3SqlForm::insert(QWidget * widget, const QString& field) |
|
161 { |
|
162 d->dirty = true; |
|
163 d->wgt.insert(field, widget); |
|
164 d->fld += field; |
|
165 } |
|
166 |
|
167 /*! |
|
168 \overload |
|
169 |
|
170 Removes \a field from the form. |
|
171 */ |
|
172 |
|
173 void Q3SqlForm::remove(const QString& field) |
|
174 { |
|
175 d->dirty = true; |
|
176 int i = d->fld.indexOf(field); |
|
177 if (i >= 0) |
|
178 d->fld.removeAt(i); |
|
179 d->wgt.remove(field); |
|
180 } |
|
181 |
|
182 /*! |
|
183 \overload |
|
184 |
|
185 Inserts a \a widget, and the \a field it is to be mapped to, into |
|
186 the form. |
|
187 */ |
|
188 |
|
189 void Q3SqlForm::insert(QWidget * widget, QSqlField * field) |
|
190 { |
|
191 d->map[widget] = field; |
|
192 } |
|
193 |
|
194 /*! |
|
195 Removes a \a widget, and hence the field it's mapped to, from the |
|
196 form. |
|
197 */ |
|
198 |
|
199 void Q3SqlForm::remove(QWidget * widget) |
|
200 { |
|
201 d->map.remove(widget); |
|
202 } |
|
203 |
|
204 /*! |
|
205 Clears the values in all the widgets, and the fields they are |
|
206 mapped to, in the form, and sets them to NULL. |
|
207 */ |
|
208 void Q3SqlForm::clearValues() |
|
209 { |
|
210 QMap< QWidget *, QSqlField * >::Iterator it; |
|
211 for(it = d->map.begin(); it != d->map.end(); ++it){ |
|
212 QSqlField* f = (*it); |
|
213 if (f) |
|
214 f->clear(); |
|
215 } |
|
216 readFields(); |
|
217 } |
|
218 |
|
219 /*! |
|
220 Removes every widget, and the fields they're mapped to, from the form. |
|
221 */ |
|
222 void Q3SqlForm::clear() |
|
223 { |
|
224 d->dirty = true; |
|
225 d->fld.clear(); |
|
226 clearMap(); |
|
227 } |
|
228 |
|
229 /*! |
|
230 Returns the number of widgets in the form. |
|
231 */ |
|
232 int Q3SqlForm::count() const |
|
233 { |
|
234 return d->map.size(); |
|
235 } |
|
236 |
|
237 /*! |
|
238 Returns the \a{i}-th widget in the form. Useful for traversing |
|
239 the widgets in the form. |
|
240 */ |
|
241 QWidget * Q3SqlForm::widget(int i) const |
|
242 { |
|
243 QMap< QWidget *, QSqlField * >::ConstIterator it; |
|
244 int cnt = 0; |
|
245 |
|
246 if(i > d->map.size()) |
|
247 return 0; |
|
248 for(it = d->map.constBegin(); it != d->map.constEnd(); ++it){ |
|
249 if(cnt++ == i) |
|
250 return it.key(); |
|
251 } |
|
252 return 0; |
|
253 } |
|
254 |
|
255 /*! |
|
256 Returns the widget that field \a field is mapped to. |
|
257 */ |
|
258 QWidget * Q3SqlForm::fieldToWidget(QSqlField * field) const |
|
259 { |
|
260 QMap< QWidget *, QSqlField * >::ConstIterator it; |
|
261 for(it = d->map.constBegin(); it != d->map.constEnd(); ++it){ |
|
262 if(*it == field) |
|
263 return it.key(); |
|
264 } |
|
265 return 0; |
|
266 } |
|
267 |
|
268 /*! |
|
269 Returns the SQL field that widget \a widget is mapped to. |
|
270 */ |
|
271 QSqlField * Q3SqlForm::widgetToField(QWidget * widget) const |
|
272 { |
|
273 return d->map.value(widget, 0); |
|
274 } |
|
275 |
|
276 /*! |
|
277 Updates the widgets in the form with current values from the SQL |
|
278 fields they are mapped to. |
|
279 */ |
|
280 void Q3SqlForm::readFields() |
|
281 { |
|
282 sync(); |
|
283 QSqlField * f; |
|
284 QMap< QWidget *, QSqlField * >::Iterator it; |
|
285 Q3SqlPropertyMap * pmap = (d->propertyMap == 0) ? |
|
286 Q3SqlPropertyMap::defaultMap() : d->propertyMap; |
|
287 for(it = d->map.begin() ; it != d->map.end(); ++it){ |
|
288 f = widgetToField(it.key()); |
|
289 if(!f) |
|
290 continue; |
|
291 pmap->setProperty(it.key(), f->value()); |
|
292 } |
|
293 } |
|
294 |
|
295 /*! |
|
296 Updates the SQL fields with values from the widgets they are |
|
297 mapped to. To actually update the database with the contents of |
|
298 the record buffer, use Q3SqlCursor::insert(), Q3SqlCursor::update() |
|
299 or Q3SqlCursor::del() as appropriate. |
|
300 */ |
|
301 void Q3SqlForm::writeFields() |
|
302 { |
|
303 sync(); |
|
304 QSqlField * f; |
|
305 QMap< QWidget *, QSqlField * >::Iterator it; |
|
306 Q3SqlPropertyMap * pmap = (d->propertyMap == 0) ? |
|
307 Q3SqlPropertyMap::defaultMap() : d->propertyMap; |
|
308 |
|
309 for(it = d->map.begin() ; it != d->map.end(); ++it){ |
|
310 f = widgetToField(it.key()); |
|
311 if(!f) |
|
312 continue; |
|
313 f->setValue(pmap->property(it.key())); |
|
314 } |
|
315 } |
|
316 |
|
317 /*! |
|
318 Updates the widget \a widget with the value from the SQL field it |
|
319 is mapped to. Nothing happens if no SQL field is mapped to the \a |
|
320 widget. |
|
321 */ |
|
322 void Q3SqlForm::readField(QWidget * widget) |
|
323 { |
|
324 sync(); |
|
325 QSqlField * field = 0; |
|
326 Q3SqlPropertyMap * pmap = (d->propertyMap == 0) ? |
|
327 Q3SqlPropertyMap::defaultMap() : d->propertyMap; |
|
328 field = widgetToField(widget); |
|
329 if(field) |
|
330 pmap->setProperty(widget, field->value()); |
|
331 } |
|
332 |
|
333 /*! |
|
334 Updates the SQL field with the value from the \a widget it is |
|
335 mapped to. Nothing happens if no SQL field is mapped to the \a |
|
336 widget. |
|
337 */ |
|
338 void Q3SqlForm::writeField(QWidget * widget) |
|
339 { |
|
340 sync(); |
|
341 QSqlField * field = 0; |
|
342 Q3SqlPropertyMap * pmap = (d->propertyMap == 0) ? |
|
343 Q3SqlPropertyMap::defaultMap() : d->propertyMap; |
|
344 field = widgetToField(widget); |
|
345 if(field) |
|
346 field->setValue(pmap->property(widget)); |
|
347 } |
|
348 |
|
349 /*! \internal |
|
350 */ |
|
351 |
|
352 void Q3SqlForm::sync() |
|
353 { |
|
354 if (d->dirty) { |
|
355 clearMap(); |
|
356 if (d->buf) { |
|
357 for (int i = 0; i < d->fld.count(); ++i) { |
|
358 const QSqlField *field = d->buf->fieldPtr(d->fld.at(i)); |
|
359 insert(d->wgt.value(d->fld.at(i)), const_cast<QSqlField *>(field)); |
|
360 } |
|
361 } |
|
362 } |
|
363 d->dirty = false; |
|
364 } |
|
365 |
|
366 /*! \internal |
|
367 |
|
368 Clears the internal map of widget/field associations |
|
369 */ |
|
370 |
|
371 void Q3SqlForm::clearMap() |
|
372 { |
|
373 d->map.clear(); |
|
374 } |
|
375 |
|
376 QT_END_NAMESPACE |
|
377 |
|
378 #endif // QT_NO_SQL |