source: trunk/src/qt3support/sql/q3databrowser.cpp@ 166

Last change on this file since 166 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 35.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the Qt3Support module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "q3databrowser.h"
43
44#ifndef QT_NO_SQL_VIEW_WIDGETS
45
46#include "q3sqlform.h"
47#include "private/q3sqlmanager_p.h"
48#include "qsqlresult.h"
49
50QT_BEGIN_NAMESPACE
51
52class Q3DataBrowserPrivate
53{
54public:
55 Q3DataBrowserPrivate() : boundaryCheck(true), readOnly(false) {}
56 Q3SqlCursorManager cur;
57 Q3SqlFormManager frm;
58 Q3DataManager dat;
59 bool boundaryCheck;
60 bool readOnly;
61};
62
63/*!
64 \class Q3DataBrowser
65 \brief The Q3DataBrowser class provides data manipulation and
66 navigation for data entry forms.
67
68 \compat
69
70 A high-level API is provided for navigating through data records
71 in a cursor, for inserting, updating and deleting records, and for
72 refreshing data in the display.
73
74 If you want a read-only form to present database data use
75 Q3DataView; if you want a table-based presentation of your data use
76 Q3DataTable.
77
78 A Q3DataBrowser is used to associate a dataset with a form in much
79 the same way as a Q3DataTable associates a dataset with a table.
80 Once the data browser has been constructed it can be associated
81 with a dataset with setSqlCursor(), and with a form with
82 setForm(). Boundary checking, sorting and filtering can be set
83 with setBoundaryChecking(), setSort() and setFilter(),
84 respectively.
85
86 The insertCurrent() function reads the fields from the default
87 form into the default cursor and performs the insert. The
88 updateCurrent() and deleteCurrent() functions perform similarly to
89 update and delete the current record respectively.
90
91 The user can be asked to confirm all edits with setConfirmEdits().
92 For more precise control use setConfirmInsert(),
93 setConfirmUpdate(), setConfirmDelete() and setConfirmCancels().
94 Use setAutoEdit() to control the behavior of the form when the
95 user edits a record and then navigates.
96
97 The record set is navigated using first(), next(), prev(), last()
98 and seek(). The form's display is updated with refresh(). When
99 navigation takes place the firstRecordAvailable(),
100 lastRecordAvailable(), nextRecordAvailable() and
101 prevRecordAvailable() signals are emitted. When the cursor record
102 is changed due to navigation the cursorChanged() signal is
103 emitted.
104
105 If you want finer control of the insert, update and delete
106 processes then you can use the lower level functions to perform
107 these operations as described below.
108
109 The form is populated with data from the database with
110 readFields(). If the user is allowed to edit, (see setReadOnly()),
111 write the form's data back to the cursor's edit buffer with
112 writeFields(). You can clear the values in the form with
113 clearValues(). Editing is performed as follows:
114 \list
115 \i \e insert When the data browser enters insertion mode it emits the
116 primeInsert() signal which you can connect to, for example to
117 pre-populate fields. Call writeFields() to write the user's edits to
118 the cursor's edit buffer then call insert() to insert the record
119 into the database. The beforeInsert() signal is emitted just before
120 the cursor's edit buffer is inserted into the database; connect to
121 this for example, to populate fields such as an auto-generated
122 primary key.
123 \i \e update For updates the primeUpdate() signal is emitted when
124 the data browser enters update mode. After calling writeFields()
125 call update() to update the record and connect to the beforeUpdate()
126 signal to manipulate the user's data before the update takes place.
127 \i \e delete For deletion the primeDelete() signal is emitted when
128 the data browser enters deletion mode. After calling writeFields()
129 call del() to delete the record and connect to the beforeDelete()
130 signal, for example to record an audit of the deleted record.
131 \endlist
132
133*/
134
135/*!
136 \enum Q3DataBrowser::Boundary
137
138 This enum describes where the data browser is positioned.
139
140 \value Unknown the boundary cannot be determined (usually because
141 there is no default cursor, or the default cursor is not active).
142
143 \value None the browser is not positioned on a boundary, but it is
144 positioned on a record somewhere in the middle.
145
146 \value BeforeBeginning the browser is positioned before the
147 first available record.
148
149 \value Beginning the browser is positioned at the first record.
150
151 \value End the browser is positioned at the last
152 record.
153
154 \value AfterEnd the browser is positioned after the last
155 available record.
156*/
157
158/*!
159 Constructs a data browser which is a child of \a parent, with the
160 name \a name and widget flags set to \a fl.
161*/
162
163Q3DataBrowser::Q3DataBrowser(QWidget *parent, const char *name, Qt::WindowFlags fl)
164 : QWidget(parent, name, fl)
165{
166 d = new Q3DataBrowserPrivate();
167 d->dat.setMode(QSql::Update);
168}
169
170/*!
171 Destroys the object and frees any allocated resources.
172*/
173
174Q3DataBrowser::~Q3DataBrowser()
175{
176 delete d;
177}
178
179
180/*!
181 Returns an enum indicating the boundary status of the browser.
182
183 This is achieved by moving the default cursor and checking the
184 position, however the current default form values will not be
185 altered. After checking for the boundary, the cursor is moved back
186 to its former position. See \l Q3DataBrowser::Boundary.
187
188 \sa Boundary
189*/
190
191Q3DataBrowser::Boundary Q3DataBrowser::boundary()
192{
193 Q3SqlCursor* cur = d->cur.cursor();
194 if (!cur || !cur->isActive())
195 return Unknown;
196 if (!cur->isValid()) {
197 if (cur->at() == QSql::BeforeFirst)
198 return BeforeBeginning;
199 if (cur->at() == QSql::AfterLast)
200 return AfterEnd;
201 return Unknown;
202 }
203 if (cur->at() == 0)
204 return Beginning;
205 int currentAt = cur->at();
206
207 Boundary b = None;
208 if (!cur->previous())
209 b = Beginning;
210 else
211 cur->seek(currentAt);
212 if (b == None && !cur->next())
213 b = End;
214 cur->seek(currentAt);
215 return b;
216}
217
218
219/*!
220 \property Q3DataBrowser::boundaryChecking
221 \brief whether boundary checking is active
222
223 When boundary checking is active (the default), signals are
224 emitted indicating the current position of the default cursor.
225
226 \sa boundary()
227*/
228
229void Q3DataBrowser::setBoundaryChecking(bool active)
230{
231 d->boundaryCheck = active;
232}
233
234bool Q3DataBrowser::boundaryChecking() const
235{
236 return d->boundaryCheck;
237}
238
239/*!
240 \property Q3DataBrowser::sort
241 \brief the data browser's sort
242
243 The data browser's sort affects the order in which records are
244 viewed in the browser. Call refresh() to apply the new sort.
245
246 When retrieving the sort property, a string list is returned in
247 the form 'fieldname order', e.g. 'id ASC', 'surname DESC'.
248
249 There is no default sort.
250
251 Note that if you want to iterate over the list, you should iterate
252 over a copy, e.g.
253 \snippet doc/src/snippets/code/src_qt3support_sql_q3databrowser.cpp 0
254*/
255
256void Q3DataBrowser::setSort(const QStringList& sort)
257{
258 d->cur.setSort(sort);
259}
260
261/*!
262 \overload
263
264 Sets the data browser's sort to the QSqlIndex \a sort. To apply
265 the new sort, use refresh().
266
267*/
268void Q3DataBrowser::setSort(const QSqlIndex& sort)
269{
270 d->cur.setSort(sort);
271}
272
273QStringList Q3DataBrowser::sort() const
274{
275 return d->cur.sort();
276}
277
278
279/*!
280 \property Q3DataBrowser::filter
281 \brief the data browser's filter
282
283 The filter applies to the data shown in the browser. Call
284 refresh() to apply the new filter. A filter is a string containing
285 a SQL WHERE clause without the WHERE keyword, e.g. "id>1000",
286 "name LIKE 'A%'", etc.
287
288 There is no default filter.
289
290 \sa sort()
291*/
292
293void Q3DataBrowser::setFilter(const QString& filter)
294{
295 d->cur.setFilter(filter);
296}
297
298
299QString Q3DataBrowser::filter() const
300{
301 return d->cur.filter();
302}
303
304
305/*!
306 Sets the default cursor used by the data browser to \a cursor. If
307 \a autoDelete is true (the default is false), the data browser
308 takes ownership of the \a cursor pointer, which will be deleted
309 when the browser is destroyed, or when setSqlCursor() is called
310 again. To activate the \a cursor use refresh(). The cursor's edit
311 buffer is used in the default form to browse and edit records.
312
313 \sa sqlCursor() form() setForm()
314*/
315
316void Q3DataBrowser::setSqlCursor(Q3SqlCursor* cursor, bool autoDelete)
317{
318 if (!cursor)
319 return;
320 d->cur.setCursor(cursor, autoDelete);
321 d->frm.setRecord(cursor->editBuffer());
322 if (cursor->isReadOnly())
323 setReadOnly(true);
324}
325
326
327/*!
328 Returns the default cursor used for navigation, or 0 if there is
329 no default cursor.
330
331 \sa setSqlCursor()
332*/
333
334Q3SqlCursor* Q3DataBrowser::sqlCursor() const
335{
336 return d->cur.cursor();
337}
338
339
340/*!
341 Sets the browser's default form to \a form. The cursor and all
342 navigation and data manipulation functions that the browser
343 provides become available to the \a form.
344*/
345
346void Q3DataBrowser::setForm(Q3SqlForm* form)
347{
348 d->frm.setForm(form);
349}
350
351
352/*!
353 Returns the data browser's default form or 0 if no form has been
354 set.
355*/
356
357Q3SqlForm* Q3DataBrowser::form()
358{
359 return d->frm.form();
360}
361
362/*!
363 \property Q3DataBrowser::readOnly
364 \brief whether the browser is read-only
365
366 The default is false, i.e. data can be edited. If the data browser
367 is read-only, no database edits will be allowed.
368*/
369
370void Q3DataBrowser::setReadOnly(bool active)
371{
372 d->readOnly = active;
373}
374
375bool Q3DataBrowser::isReadOnly() const
376{
377 return d->readOnly;
378}
379
380void Q3DataBrowser::setConfirmEdits(bool confirm)
381{
382 d->dat.setConfirmEdits(confirm);
383}
384
385/*!
386 \property Q3DataBrowser::confirmInsert
387 \brief whether the data browser confirms insertions
388
389 If this property is true, the browser confirms insertions,
390 otherwise insertions happen immediately.
391
392 \sa confirmCancels() confirmEdits() confirmUpdate() confirmDelete() confirmEdit()
393*/
394
395void Q3DataBrowser::setConfirmInsert(bool confirm)
396{
397 d->dat.setConfirmInsert(confirm);
398}
399
400/*!
401 \property Q3DataBrowser::confirmUpdate
402 \brief whether the browser confirms updates
403
404 If this property is true, the browser confirms updates, otherwise
405 updates happen immediately.
406
407 \sa confirmCancels() confirmEdits() confirmInsert() confirmDelete() confirmEdit()
408*/
409
410void Q3DataBrowser::setConfirmUpdate(bool confirm)
411{
412 d->dat.setConfirmUpdate(confirm);
413}
414
415/*!
416 \property Q3DataBrowser::confirmDelete
417 \brief whether the browser confirms deletions
418
419 If this property is true, the browser confirms deletions,
420 otherwise deletions happen immediately.
421
422 \sa confirmCancels() confirmEdits() confirmUpdate() confirmInsert() confirmEdit()
423*/
424
425void Q3DataBrowser::setConfirmDelete(bool confirm)
426{
427 d->dat.setConfirmDelete(confirm);
428}
429
430/*!
431 \property Q3DataBrowser::confirmEdits
432 \brief whether the browser confirms edits
433
434 If this property is true, the browser confirms all edit operations
435 (insertions, updates and deletions), otherwise all edit operations
436 happen immediately. Confirmation is achieved by presenting the
437 user with a message box -- this behavior can be changed by
438 reimplementing the confirmEdit() function,
439
440 \sa confirmEdit() confirmCancels() confirmInsert() confirmUpdate() confirmDelete()
441*/
442
443bool Q3DataBrowser::confirmEdits() const
444{
445 return (d->dat.confirmEdits());
446}
447
448bool Q3DataBrowser::confirmInsert() const
449{
450 return (d->dat.confirmInsert());
451}
452
453bool Q3DataBrowser::confirmUpdate() const
454{
455 return (d->dat.confirmUpdate());
456}
457
458bool Q3DataBrowser::confirmDelete() const
459{
460 return (d->dat.confirmDelete());
461}
462
463/*!
464 \property Q3DataBrowser::confirmCancels
465 \brief whether the browser confirms cancel operations
466
467 If this property is true, all cancels must be confirmed by the
468 user through a message box (this behavior can be changed by
469 overriding the confirmCancel() function), otherwise all cancels
470 occur immediately. The default is false.
471
472 \sa confirmEdits() confirmCancel()
473*/
474
475void Q3DataBrowser::setConfirmCancels(bool confirm)
476{
477 d->dat.setConfirmCancels(confirm);
478}
479
480bool Q3DataBrowser::confirmCancels() const
481{
482 return d->dat.confirmCancels();
483}
484
485/*!
486 \property Q3DataBrowser::autoEdit
487 \brief whether the browser automatically applies edits
488
489 The default value for this property is true. When the user begins
490 an insertion or an update on a form there are two possible
491 outcomes when they navigate to another record:
492
493 \list
494 \i the insert or update is is performed -- this occurs if autoEdit is true
495 \i the insert or update is discarded -- this occurs if autoEdit is false
496 \endlist
497*/
498
499void Q3DataBrowser::setAutoEdit(bool autoEdit)
500{
501 d->dat.setAutoEdit(autoEdit);
502}
503
504bool Q3DataBrowser::autoEdit() const
505{
506 return d->dat.autoEdit();
507}
508
509/*!
510 \fn void Q3DataBrowser::firstRecordAvailable(bool available)
511
512 This signal is emitted whenever the position of the cursor
513 changes. The \a available parameter indicates whether or not the
514 first record in the default cursor is available.
515*/
516
517/*!
518 \fn void Q3DataBrowser::lastRecordAvailable(bool available)
519
520 This signal is emitted whenever the position of the cursor
521 changes. The \a available parameter indicates whether or not the
522 last record in the default cursor is available.
523*/
524
525/*!
526 \fn void Q3DataBrowser::nextRecordAvailable(bool available)
527
528 This signal is emitted whenever the position of the cursor
529 changes. The \a available parameter indicates whether or not the
530 next record in the default cursor is available.
531*/
532
533
534/*!
535 \fn void Q3DataBrowser::prevRecordAvailable(bool available)
536
537 This signal is emitted whenever the position of the cursor
538 changes. The \a available parameter indicates whether or not the
539 previous record in the default cursor is available.
540*/
541
542
543/*!
544 \fn void Q3DataBrowser::currentChanged(const QSqlRecord* record)
545
546 This signal is emitted whenever the current cursor position
547 changes. The \a record parameter points to the contents of the
548 current cursor's record.
549*/
550
551
552/*!
553 \fn void Q3DataBrowser::primeInsert(QSqlRecord* buf)
554
555 This signal is emitted when the data browser enters insertion
556 mode. The \a buf parameter points to the record buffer that is to
557 be inserted. Connect to this signal to, for example, prime the
558 record buffer with default data values, auto-numbered fields etc.
559 (Note that Q3SqlCursor::primeInsert() is \e not called on the
560 default cursor, as this would corrupt values in the form.)
561
562 \sa insert()
563*/
564
565
566/*!
567 \fn void Q3DataBrowser::primeUpdate(QSqlRecord* buf)
568
569 This signal is emitted when the data browser enters update mode.
570 Note that during navigation (first(), last(), next(), prev()),
571 each record that is shown in the default form is primed for
572 update. The \a buf parameter points to the record buffer being
573 updated. (Note that Q3SqlCursor::primeUpdate() is \e not called on
574 the default cursor, as this would corrupt values in the form.)
575 Connect to this signal in order to, for example, keep track of
576 which records have been updated, perhaps for auditing purposes.
577
578 \sa update()
579*/
580
581/*!
582 \fn void Q3DataBrowser::primeDelete(QSqlRecord* buf)
583
584 This signal is emitted when the data browser enters deletion mode.
585 The \a buf parameter points to the record buffer being deleted.
586 (Note that Q3SqlCursor::primeDelete() is \e not called on the
587 default cursor, as this would corrupt values in the form.)
588 Connect to this signal in order to, for example, save a copy of
589 the deleted record for auditing purposes.
590
591 \sa del()
592*/
593
594
595/*!
596 \fn void Q3DataBrowser::cursorChanged(Q3SqlCursor::Mode mode)
597
598 This signal is emitted whenever the cursor record was changed due
599 to navigation. The \a mode parameter is the edit that just took
600 place, e.g. Insert, Update or Delete. See \l Q3SqlCursor::Mode.
601*/
602
603
604/*!
605 Refreshes the data browser's data using the default cursor. The
606 browser's current filter and sort are applied if they have been
607 set.
608
609 \sa setFilter() setSort()
610*/
611
612void Q3DataBrowser::refresh()
613{
614 d->cur.refresh();
615}
616
617
618/*!
619 Performs an insert operation on the data browser's cursor. If
620 there is no default cursor or no default form, nothing happens.
621
622 If auto-editing is on (see setAutoEdit()), the following happens:
623
624 \list
625 \i If the browser is already actively inserting a record,
626 the current form's data is inserted into the database.
627 \i If the browser is not inserting a record, but the current record
628 was changed by the user, the record is updated in the database with
629 the current form's data (i.e. with the changes).
630 \endlist
631