source: trunk/src/sql/qdatabrowser.cpp@ 196

Last change on this file since 196 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: 35.2 KB
Line 
1/****************************************************************************
2**
3** Implementation of QDataBrowser 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 "qdatabrowser.h"
38
39#ifndef QT_NO_SQL_VIEW_WIDGETS
40
41#include "qsqlform.h"
42#include "qsqlmanager_p.h"
43#include "qsqlresult.h"
44
45class QDataBrowserPrivate
46{
47public:
48 QDataBrowserPrivate() : boundaryCheck( TRUE ), readOnly( FALSE ) {}
49 QSqlCursorManager cur;
50 QSqlFormManager frm;
51 QDataManager dat;
52 bool boundaryCheck;
53 bool readOnly;
54};
55
56/*!
57 \class QDataBrowser qdatabrowser.h
58 \brief The QDataBrowser class provides data manipulation and
59 navigation for data entry forms.
60
61 \ingroup database
62 \mainclass
63 \module sql
64
65 A high-level API is provided for navigating through data records
66 in a cursor, for inserting, updating and deleting records, and for
67 refreshing data in the display.
68
69 If you want a read-only form to present database data use
70 QDataView; if you want a table-based presentation of your data use
71 QDataTable.
72
73 A QDataBrowser is used to associate a dataset with a form in much
74 the same way as a QDataTable associates a dataset with a table.
75 Once the data browser has been constructed it can be associated
76 with a dataset with setSqlCursor(), and with a form with
77 setForm(). Boundary checking, sorting and filtering can be set
78 with setBoundaryChecking(), setSort() and setFilter(),
79 respectively.
80
81 The insertCurrent() function reads the fields from the default
82 form into the default cursor and performs the insert. The
83 updateCurrent() and deleteCurrent() functions perform similarly to
84 update and delete the current record respectively.
85
86 The user can be asked to confirm all edits with setConfirmEdits().
87 For more precise control use setConfirmInsert(),
88 setConfirmUpdate(), setConfirmDelete() and setConfirmCancels().
89 Use setAutoEdit() to control the behaviour of the form when the
90 user edits a record and then navigates.
91
92 The record set is navigated using first(), next(), prev(), last()
93 and seek(). The form's display is updated with refresh(). When
94 navigation takes place the firstRecordAvailable(),
95 lastRecordAvailable(), nextRecordAvailable() and
96 prevRecordAvailable() signals are emitted. When the cursor record
97 is changed due to navigation the cursorChanged() signal is
98 emitted.
99
100 If you want finer control of the insert, update and delete
101 processes then you can use the lower level functions to perform
102 these operations as described below.
103
104 The form is populated with data from the database with
105 readFields(). If the user is allowed to edit, (see setReadOnly()),
106 write the form's data back to the cursor's edit buffer with
107 writeFields(). You can clear the values in the form with
108 clearValues(). Editing is performed as follows:
109 \list
110 \i \e insert When the data browser enters insertion mode it emits the
111 primeInsert() signal which you can connect to, for example to
112 pre-populate fields. Call writeFields() to write the user's edits to
113 the cursor's edit buffer then call insert() to insert the record
114 into the database. The beforeInsert() signal is emitted just before
115 the cursor's edit buffer is inserted into the database; connect to
116 this for example, to populate fields such as an auto-generated
117 primary key.
118 \i \e update For updates the primeUpdate() signal is emitted when
119 the data browser enters update mode. After calling writeFields()
120 call update() to update the record and connect to the beforeUpdate()
121 signal to manipulate the user's data before the update takes place.
122 \i \e delete For deletion the primeDelete() signal is emitted when
123 the data browser enters deletion mode. After calling writeFields()
124 call del() to delete the record and connect to the beforeDelete()
125 signal, for example to record an audit of the deleted record.
126 \endlist
127
128*/
129
130/*!
131 \enum QDataBrowser::Boundary
132
133 This enum describes where the data browser is positioned.
134
135 \value Unknown the boundary cannot be determined (usually because
136 there is no default cursor, or the default cursor is not active).
137
138 \value None the browser is not positioned on a boundary, but it is
139 positioned on a record somewhere in the middle.
140
141 \value BeforeBeginning the browser is positioned before the
142 first available record.
143
144 \value Beginning the browser is positioned at the first record.
145
146 \value End the browser is positioned at the last
147 record.
148
149 \value AfterEnd the browser is positioned after the last
150 available record.
151*/
152
153/*!
154 Constructs a data browser which is a child of \a parent, with the
155 name \a name and widget flags set to \a fl.
156*/
157
158QDataBrowser::QDataBrowser( QWidget *parent, const char *name, WFlags fl )
159 : QWidget( parent, name, fl )
160{
161 d = new QDataBrowserPrivate();
162 d->dat.setMode( QSql::Update );
163}
164
165/*!
166 Destroys the object and frees any allocated resources.
167*/
168
169QDataBrowser::~QDataBrowser()
170{
171 delete d;
172}
173
174
175/*!
176 Returns an enum indicating the boundary status of the browser.
177
178 This is achieved by moving the default cursor and checking the
179 position, however the current default form values will not be
180 altered. After checking for the boundary, the cursor is moved back
181 to its former position. See \l QDataBrowser::Boundary.
182
183 \sa Boundary
184*/
185
186QDataBrowser::Boundary QDataBrowser::boundary()
187{
188 QSqlCursor* cur = d->cur.cursor();
189 if ( !cur || !cur->isActive() )
190 return Unknown;
191 if ( !cur->isValid() ) {
192 if ( cur->at() == QSql::BeforeFirst )
193 return BeforeBeginning;
194 if ( cur->at() == QSql::AfterLast )
195 return AfterEnd;
196 return Unknown;
197 }
198 if ( cur->at() == 0 )
199 return Beginning;
200 int currentAt = cur->at();
201
202 Boundary b = None;
203 if ( !cur->prev() )
204 b = Beginning;
205 else
206 cur->seek( currentAt );
207 if ( b == None && !cur->next() )
208 b = End;
209 cur->seek( currentAt );
210 return b;
211}
212
213
214/*!
215 \property QDataBrowser::boundaryChecking
216 \brief whether boundary checking is active
217
218 When boundary checking is active (the default), signals are
219 emitted indicating the current position of the default cursor.
220
221 \sa boundary()
222*/
223
224void QDataBrowser::setBoundaryChecking( bool active )
225{
226 d->boundaryCheck = active;
227}
228
229bool QDataBrowser::boundaryChecking() const
230{
231 return d->boundaryCheck;
232}
233
234/*!
235 \property QDataBrowser::sort
236 \brief the data browser's sort
237
238 The data browser's sort affects the order in which records are
239 viewed in the browser. Call refresh() to apply the new sort.
240
241 When retrieving the sort property, a string list is returned in
242 the form 'fieldname order', e.g. 'id ASC', 'surname DESC'.
243
244 There is no default sort.
245
246 Note that if you want to iterate over the list, you should iterate
247 over a copy, e.g.
248 \code
249 QStringList list = myDataBrowser.sort();
250 QStringList::Iterator it = list.begin();
251 while( it != list.end() ) {
252 myProcessing( *it );
253 ++it;
254 }
255 \endcode
256*/
257
258void QDataBrowser::setSort( const QStringList& sort )
259{
260 d->cur.setSort( sort );
261}
262
263/*!
264 \overload
265
266 Sets the data browser's sort to the QSqlIndex \a sort. To apply
267 the new sort, use refresh().
268
269*/
270void QDataBrowser::setSort( const QSqlIndex& sort )
271{
272 d->cur.setSort( sort );
273}
274
275QStringList QDataBrowser::sort() const
276{
277 return d->cur.sort();
278}
279
280
281/*!
282 \property QDataBrowser::filter
283 \brief the data browser's filter
284
285 The filter applies to the data shown in the browser. Call
286 refresh() to apply the new filter. A filter is a string containing
287 a SQL WHERE clause without the WHERE keyword, e.g. "id>1000",
288 "name LIKE 'A%'", etc.
289
290 There is no default filter.
291
292 \sa sort()
293*/
294
295void QDataBrowser::setFilter( const QString& filter )
296{
297 d->cur.setFilter( filter );
298}
299
300
301QString QDataBrowser::filter() const
302{
303 return d->cur.filter();
304}
305
306
307/*!
308 Sets the default cursor used by the data browser to \a cursor. If
309 \a autoDelete is TRUE (the default is FALSE), the data browser
310 takes ownership of the \a cursor pointer, which will be deleted
311 when the browser is destroyed, or when setSqlCursor() is called
312 again. To activate the \a cursor use refresh(). The cursor's edit
313 buffer is used in the default form to browse and edit records.
314
315 \sa sqlCursor() form() setForm()
316*/
317
318void QDataBrowser::setSqlCursor( QSqlCursor* cursor, bool autoDelete )
319{
320 if ( !cursor )
321 return;
322 d->cur.setCursor( cursor, autoDelete );
323 d->frm.setRecord( cursor->editBuffer() );
324 if ( cursor->isReadOnly() )
325 setReadOnly( TRUE );
326}
327
328
329/*!
330 Returns the default cursor used for navigation, or 0 if there is
331 no default cursor.
332
333 \sa setSqlCursor()
334*/
335
336QSqlCursor* QDataBrowser::sqlCursor() const
337{
338 return d->cur.cursor();
339}
340
341
342/*!
343 Sets the browser's default form to \a form. The cursor and all
344 navigation and data manipulation functions that the browser
345 provides become available to the \a form.
346*/
347
348void QDataBrowser::setForm( QSqlForm* form )
349{
350 d->frm.setForm( form );
351}
352
353
354/*!
355 Returns the data browser's default form or 0 if no form has been
356 set.
357*/
358
359QSqlForm* QDataBrowser::form()
360{
361 return d->frm.form();
362}
363
364/*!
365 \property QDataBrowser::readOnly
366 \brief whether the browser is read-only
367
368 The default is FALSE, i.e. data can be edited. If the data browser
369 is read-only, no database edits will be allowed.
370*/
371
372void QDataBrowser::setReadOnly( bool active )
373{
374 d->readOnly = active;
375}
376
377bool QDataBrowser::isReadOnly() const
378{
379 return d->readOnly;
380}
381
382void QDataBrowser::setConfirmEdits( bool confirm )
383{
384 d->dat.setConfirmEdits( confirm );
385}
386
387/*!
388 \property QDataBrowser::confirmInsert
389 \brief whether the data browser confirms insertions
390
391 If this property is TRUE, the browser confirms insertions,
392 otherwise insertions happen immediately.
393
394 \sa confirmCancels() confirmEdits() confirmUpdate() confirmDelete() confirmEdit()
395*/
396
397void QDataBrowser::setConfirmInsert( bool confirm )
398{
399 d->dat.setConfirmInsert( confirm );
400}
401
402/*!
403 \property QDataBrowser::confirmUpdate
404 \brief whether the browser confirms updates
405
406 If this property is TRUE, the browser confirms updates, otherwise
407 updates happen immediately.
408
409 \sa confirmCancels() confirmEdits() confirmInsert() confirmDelete() confirmEdit()
410*/
411
412void QDataBrowser::setConfirmUpdate( bool confirm )
413{
414 d->dat.setConfirmUpdate( confirm );
415}
416
417/*!
418 \property QDataBrowser::confirmDelete
419 \brief whether the browser confirms deletions
420
421 If this property is TRUE, the browser confirms deletions,
422 otherwise deletions happen immediately.
423
424 \sa confirmCancels() confirmEdits() confirmUpdate() confirmInsert() confirmEdit()
425*/
426
427void QDataBrowser::setConfirmDelete( bool confirm )
428{
429 d->dat.setConfirmDelete( confirm );
430}
431
432/*!
433 \property QDataBrowser::confirmEdits
434 \brief whether the browser confirms edits
435
436 If this property is TRUE, the browser confirms all edit operations
437 (insertions, updates and deletions), otherwise all edit operations
438 happen immediately. Confirmation is achieved by presenting the
439 user with a message box -- this behavior can be changed by
440 reimplementing the confirmEdit() function,
441
442 \sa confirmEdit() confirmCancels() confirmInsert() confirmUpdate() confirmDelete()
443*/
444
445bool QDataBrowser::confirmEdits() const
446{
447 return ( d->dat.confirmEdits() );
448}
449
450bool QDataBrowser::confirmInsert() const
451{
452 return ( d->dat.confirmInsert() );
453}
454
455bool QDataBrowser::confirmUpdate() const
456{
457 return ( d->dat.confirmUpdate() );
458}
459
460bool QDataBrowser::confirmDelete() const
461{
462 return ( d->dat.confirmDelete() );
463}
464
465/*!
466 \property QDataBrowser::confirmCancels
467 \brief whether the browser confirms cancel operations
468
469 If this property is TRUE, all cancels must be confirmed by the
470 user through a message box (this behavior can be changed by
471 overriding the confirmCancel() function), otherwise all cancels
472 occur immediately. The default is FALSE.
473
474 \sa confirmEdits() confirmCancel()
475*/
476
477void QDataBrowser::setConfirmCancels( bool confirm )
478{
479 d->dat.setConfirmCancels( confirm );
480}
481
482bool QDataBrowser::confirmCancels() const
483{
484 return d->dat.confirmCancels();
485}
486
487/*!
488 \property QDataBrowser::autoEdit
489 \brief whether the browser automatically applies edits
490
491 The default value for this property is TRUE. When the user begins
492 an insertion or an update on a form there are two possible
493 outcomes when they navigate to another record:
494
495 \list
496 \i the insert or update is is performed -- this occurs if autoEdit is TRUE
497 \i the insert or update is discarded -- this occurs if autoEdit is FALSE
498 \endlist
499*/
500
501void QDataBrowser::setAutoEdit( bool autoEdit )
502{
503 d->dat.setAutoEdit( autoEdit );
504}
505
506bool QDataBrowser::autoEdit() const
507{
508 return d->dat.autoEdit();
509}
510
511/*!
512 \fn void QDataBrowser::firstRecordAvailable( bool available )
513
514 This signal is emitted whenever the position of the cursor
515 changes. The \a available parameter indicates whether or not the
516 first record in the default cursor is available.
517*/
518
519/*!
520 \fn void QDataBrowser::lastRecordAvailable( bool available )
521
522 This signal is emitted whenever the position of the cursor
523 changes. The \a available parameter indicates whether or not the
524 last record in the default cursor is available.
525*/
526
527/*!
528 \fn void QDataBrowser::nextRecordAvailable( bool available )
529
530 This signal is emitted whenever the position of the cursor
531 changes. The \a available parameter indicates whether or not the
532 next record in the default cursor is available.
533*/
534
535
536/*!
537 \fn void QDataBrowser::prevRecordAvailable( bool available )
538
539 This signal is emitted whenever the position of the cursor
540 changes. The \a available parameter indicates whether or not the
541 previous record in the default cursor is available.
542*/
543
544
545/*!
546 \fn void QDataBrowser::currentChanged( const QSqlRecord* record )
547
548 This signal is emitted whenever the current cursor position
549 changes. The \a record parameter points to the contents of the
550 current cursor's record.
551*/
552
553
554/*!
555 \fn void QDataBrowser::primeInsert( QSqlRecord* buf )
556
557 This signal is emitted when the data browser enters insertion
558 mode. The \a buf parameter points to the record buffer that is to
559 be inserted. Connect to this signal to, for example, prime the
560 record buffer with default data values, auto-numbered fields etc.
561 (Note that QSqlCursor::primeInsert() is \e not called on the
562 default cursor, as this would corrupt values in the form.)
563
564 \sa insert()
565*/
566
567
568/*!
569 \fn void QDataBrowser::primeUpdate( QSqlRecord* buf )
570
571 This signal is emitted when the data browser enters update mode.
572 Note that during navigation (first(), last(), next(), prev()),
573 each record that is shown in the default form is primed for
574 update. The \a buf parameter points to the record buffer being
575 updated. (Note that QSqlCursor::primeUpdate() is \e not called on
576 the default cursor, as this would corrupt values in the form.)
577 Connect to this signal in order to, for example, keep track of
578 which records have been updated, perhaps for auditing purposes.
579
580 \sa update()
581*/
582
583/*!
584 \fn void QDataBrowser::primeDelete( QSqlRecord* buf )
585
586 This signal is emitted when the data browser enters deletion mode.
587 The \a buf parameter points to the record buffer being deleted.
588 (Note that QSqlCursor::primeDelete() is \e not called on the
589 default cursor, as this would corrupt values in the form.)
590 Connect to this signal in order to, for example, save a copy of
591 the deleted record for auditing purposes.
592
593 \sa del()
594*/
595
596
597/*!
598 \fn void QDataBrowser::cursorChanged( QSqlCursor::Mode mode )
599
600 This signal is emitted whenever the cursor record was changed due
601 to navigation. The \a mode parameter is the edit that just took
602 place, e.g. Insert, Update or Delete. See \l QSqlCursor::Mode.
603*/
604
605
606/*!
607 Refreshes the data browser's data using the default cursor. The
608 browser's current filter and sort are applied if they have been
609 set.
610
611 \sa setFilter() setSort()
612*/
613
614void QDataBrowser::refresh()
615{
616 d->cur.refresh();
617}
618
619
620/*!
621 Performs an insert operation on the data browser's cursor. If
622 there is no default cursor or no default form, nothing happens.
623
624 If auto-editing is on (see setAutoEdit()), the following happens:
625
626 \list
627 \i If the browser is already actively inserting a record,
628 the current form's data is inserted into the database.
629 \i If the browser is not inserting a record, but the current record
630 was changed by the user, the record is updated in the database with
631 the current form's data (i.e. with the changes).
632 \endlist
633
634 If there is an error handling any of the above auto-edit actions,
635 handleError() is called and no insert or update is performed.
636
637 If no error occurred, or auto-editing is not enabled, the data browser
638 begins actively inserting a record into the database by performing the
639 following actions:
640
641 \list
642 \i The default cursor is primed for insert using QSqlCursor::primeInsert().
643 \i The primeInsert() signal is emitted.
644 \i The form is updated with the values in the default cursor's.
645 edit buffer so that the user can fill in the values to be inserted.
646 \endlist
647
648*/
649
650void QDataBrowser::insert()
651{
652 QSqlRecord* buf = d->frm.record();
653 QSqlCursor* cur = d->cur.cursor();
654 if ( !buf || !cur )
655 return;
656 bool doIns = TRUE;
657 QSql::Confirm conf = QSql::Yes;
658 switch ( d->dat.mode() ) {
659 case QSql::Insert:
660 if ( autoEdit() ) {
661 if ( confirmInsert() )
662 conf = confirmEdit( QSql::Insert );
663 switch ( conf ) {
664 case QSql::Yes:
665 insertCurrent();
666 break;
667 case QSql::No:
668 break;
669 case QSql::Cancel:
670 doIns = FALSE;
671 break;
672 }
673 }
674 break;
675 default:
676 if ( autoEdit() && currentEdited() ) {
677 if ( confirmUpdate() )
678 conf = confirmEdit( QSql::Update );
679 switch ( conf ) {
680 case QSql::Yes:
681 updateCurrent();
682 break;
683 case QSql::No:
684 break;
685 case QSql::Cancel:
686 doIns = FALSE;
687 break;
688 }
689 }
690 break;
691 }
692 if ( doIns ) {
693 d->dat.setMode( QSql::Insert );
694 sqlCursor()->primeInsert();
695 emit primeInsert( d->frm.record() );
696 readFields();
697 }
698}
699
700
701/*!
702 Performs an update operation on the data browser's cursor.
703
704 If there is no default cursor or no default form, nothing happens.
705 Otherwise, the following happens:
706
707 If the data browser is actively inserting a record (see insert()),
708 that record is inserted into the database using insertCurrent().
709 Otherwise, the database is updated with the current form's data
710 using updateCurrent(). If there is an error handling either
711 action, handleError() is called.
712*/
713
714void QDataBrowser::update()
715{
716 QSqlRecord* buf = d->frm.record();
717 QSqlCursor* cur = d->cur.cursor();
718 if ( !buf || !cur )
719 return;
720 QSql::Confirm conf = QSql::Yes;
721 switch ( d->dat.mode() ){
722 case QSql::Insert:
723 if ( confirmInsert() )
724 conf = confirmEdit( QSql::Insert );
725 switch ( conf ) {
726 case QSql::Yes:
727 if ( insertCurrent() )
728 d->dat.setMode( QSql::Update );
729 break;
730 case QSql::No:
731 d->dat.setMode( QSql::Update );
732 cur->editBuffer( TRUE );
733 readFields();
734 break;
735 case QSql::Cancel:
736 break;
737 }
738 break;
739 default:
740 d->dat.setMode( QSql::Update );
741 if ( confirmUpdate() )
742 conf = confirmEdit( QSql::Update );
743 switch ( conf ) {
744 case QSql::Yes:
745 updateCurrent();
746 break;
747 case QSql::No:
748 case QSql::Cancel:
749 break;
750 }
751 break;
752 }
753}
754
755
756/*!
757 Performs a delete operation on the data browser's cursor. If there
758 is no default cursor or no default form, nothing happens.
759
760 Otherwise, the following happens:
761
762 The current form's record is deleted from the database, providing
763 that the data browser is not in insert mode. If the data browser
764 is actively inserting a record (see insert()), the insert action
765 is canceled, and the browser navigates to the last valid record
766 that was current. If there is an error, handleError() is called.
767*/
768
769void QDataBrowser::del()
770{
771 QSqlRecord* buf = d->frm.record();
772 QSqlCursor* cur = d->cur.cursor();
773 if ( !buf || !cur )
774 return;
775 QSql::Confirm conf = QSql::Yes;
776 switch ( d->dat.mode() ){
777 case QSql::Insert:
778 if ( confirmCancels() )
779 conf = confirmCancel( QSql::Insert );
780 if ( conf == QSql::Yes ) {
781 cur->editBuffer( TRUE ); /* restore from cursor */
782 readFields();
783 d->dat.setMode( QSql::Update );
784 } else
785 d->dat.setMode( QSql::Insert );
786 break;
787 default:
788 if ( confirmDelete() )
789 conf = confirmEdit( QSql::Delete );
790 switch ( conf ) {
791 case QSql::Yes:
792 emit primeDelete( buf );
793 deleteCurrent();
794 break;
795 case QSql::No:
796 case QSql::Cancel:
797 break;
798 }
799 d->dat.setMode( QSql::Update );
800 break;
801 }
802}
803
804/*!
805 Moves the default cursor to the record specified by the index \a i
806 and refreshes the default form to display this record. If there is
807 no default form or no default cursor, nothing happens. If \a
808 relative is TRUE (the default is FALSE), the cursor is moved
809 relative to its current position. If the data browser successfully
810 navigated to the desired record, the default cursor is primed for
811 update and the primeUpdate() signal is emitted.
812
813 If the browser is already positioned on the desired record nothing
814 happens.
815*/
816
817bool QDataBrowser::seek( int i, bool relative )
818{
819 int b = 0;
820 QSqlCursor* cur = d->cur.cursor();
821 if ( !cur )
822 return FALSE;
823 if ( preNav() )
824 b = cur->seek( i, relative );
825 postNav( b );
826 return b;
827}
828
829/*!
830 Moves the default cursor to the first record and refreshes the
831 default form to display this record. If there is no default form
832 or no default cursor, nothing happens. If the data browser
833 successfully navigated to the first record, the default cursor is
834 primed for update and the primeUpdate() signal is emitted.
835
836 If the browser is already positioned on the first record nothing
837 happens.
838
839*/
840
841void QDataBrowser::first()
842{
843 nav( &QSqlCursor::first );
844}
845
846
847/*!
848 Moves the default cursor to the last record and refreshes the
849 default form to display this record. If there is no default form
850 or no default cursor, nothing happens. If the data browser
851 successfully navigated to the last record, the default cursor is
852 primed for update and the primeUpdate() signal is emitted.
853
854 If the browser is already positioned on the last record nothing
855 happens.
856*/
857
858void QDataBrowser::last()
859{
860 nav( &QSqlCursor::last );
861}
862
863
864/*!
865 Moves the default cursor to the next record and refreshes the
866 default form to display this record. If there is no default form
867 or no default cursor, nothing happens. If the data browser
868 successfully navigated to the next record, the default cursor is
869 primed for update and the primeUpdate() signal is emitted.
870
871 If the browser is positioned on the last record nothing happens.
872*/
873
874void QDataBrowser::next()
875{
876 nav( &QSqlCursor::next );
877}
878
879
880/*!
881 Moves the default cursor to the previous record and refreshes the
882 default form to display this record. If there is no default form
883 or no default cursor, nothing happens. If the data browser
884 successfully navigated to the previous record, the default cursor
885 is primed for update and the primeUpdate() signal is emitted.
886
887 If the browser is positioned on the first record nothing happens.
888*/
889
890void QDataBrowser::prev()
891{
892 nav( &QSqlCursor::prev );
893}
894
895/*!
896 Reads the fields from the default cursor's edit buffer and
897 displays them in the form. If there is no default cursor or no
898 default form, nothing happens.
899*/
900
901void QDataBrowser::readFields()
902{
903 d->frm.readFields();
904}
905
906
907/*!
908 Writes the form's data to the default cursor's edit buffer. If
909 there is no default cursor or no default form, nothing happens.
910*/
911
912void QDataBrowser::writeFields()
913{
914 d->frm.writeFields();
915}
916
917
918/*!
919 Clears all the values in the form.
920
921 All the edit buffer field values are set to their 'zero state',
922 e.g. 0 for numeric fields and "" for string fields. Then the
923 widgets are updated using the property map. For example, a
924 combobox that is property-mapped to integers would scroll to the
925 first item. See the \l QSqlPropertyMap constructor for the default
926 mappings of widgets to properties.
927*/
928
929void QDataBrowser::clearValues()
930{
931 d->frm.clearValues();
932}
933
934/*!
935 Reads the fields from the default form into the default cursor and
936 performs an insert on the default cursor. If there is no default
937 form or no default cursor, nothing happens. If an error occurred
938 during the insert into the database, handleError() is called and
939 FALSE is returned. If the insert was successfull, the cursor is
940 refreshed and relocated to the newly inserted record, the
941 cursorChanged() signal is emitted, and TRUE is returned.
942
943 \sa cursorChanged() sqlCursor() form() handleError()
944*/
945
946bool QDataBrowser::insertCurrent()
947{
948 if ( isReadOnly() )
949 return FALSE;
950 QSqlRecord* buf = d->frm.record();
951 QSqlCursor* cur = d->cur.cursor();
952 if ( !buf || !cur )
953 return FALSE;
954 writeFields();
955 emit beforeInsert( buf );
956 int ar = cur->insert();
957 if ( !ar || !cur->isActive() ) {
958 handleError( cur->lastError() );
959 refresh();
960 updateBoundary();
961 } else {
962 refresh();
963 d->cur.findBuffer( cur->primaryIndex() );
964 updateBoundary();
965 cursorChanged( QSqlCursor::Insert );
966 return TRUE;
967 }
968 return FALSE;
969}
970
971
972/*!
973 Reads the fields from the default form into the default cursor and
974 performs an update on the default cursor. If there is no default
975 form or no default cursor, nothing happens. If an error occurred
976 during the update on the database, handleError() is called and
977 FALSE is returned. If the update was successfull, the cursor is
978 refreshed and relocated to the updated record, the cursorChanged()
979 signal is emitted, and TRUE is returned.
980
981 \sa cursor() form() handleError()
982*/
983
984bool QDataBrowser::updateCurrent()
985{
986 if ( isReadOnly() )
987 return FALSE;
988 QSqlRecord* buf = d->frm.record();
989 QSqlCursor* cur = d->cur.cursor();
990 if ( !buf || !cur )
991 return FALSE;
992 writeFields();
993 emit beforeUpdate( buf );
994 int ar = cur->update();
995 if ( !ar || !cur->isActive() ) {
996 handleError( cur->lastError() );
997 refresh();
998 updateBoundary();
999 } else {
1000 refresh();
1001 d->cur.findBuffer( cur->primaryIndex() );
1002 updateBoundary();
1003 cur->editBuffer( TRUE );
1004 cursorChanged( QSqlCursor::Update );
1005 readFields();
1006 return TRUE;
1007 }
1008 return FALSE;
1009}
1010
1011
1012/*!
1013 Performs a delete on the default cursor using the values from the
1014 default form and updates the default form. If there is no default
1015 form or no default cursor, nothing happens. If the deletion was
1016 successful, the cursor is repositioned to the nearest record and
1017 TRUE is returned. The nearest record is the next record if there
1018 is one otherwise the previous record if there is one. If an error
1019 occurred during the deletion from the database, handleError() is
1020 called and FALSE is returned.
1021
1022 \sa cursor() form() handleError()
1023*/
1024
1025bool QDataBrowser::deleteCurrent()
1026{
1027 if ( isReadOnly() )
1028 return FALSE;
1029 QSqlRecord* buf = d->frm.record();
1030 QSqlCursor* cur = d->cur.cursor();
1031 if ( !buf || !cur )
1032 return FALSE;
1033 writeFields();
1034 int n = cur->at();
1035 emit beforeDelete( buf );
1036 int ar = cur->del();
1037 if ( ar ) {
1038 refresh();
1039 updateBoundary();
1040 cursorChanged( QSqlCursor::Delete );
1041 if ( !cur->seek( n ) )
1042 last();
1043 if ( cur->isValid() ) {
1044 cur->editBuffer( TRUE );
1045 readFields();
1046 } else {
1047 clearValues();
1048 }
1049 return TRUE;
1050 } else {
1051 if ( !cur->isActive() ) {
1052 handleError( cur->lastError() );
1053 refresh();
1054 updateBoundary();
1055 }
1056 }
1057 return FALSE;
1058}
1059
1060
1061/*!
1062 Returns TRUE if the form's edit buffer differs from the current
1063 cursor buffer; otherwise returns FALSE.
1064*/
1065
1066bool QDataBrowser::currentEdited()
1067{
1068 QSqlRecord* buf = d->frm.record();
1069 QSqlCursor* cur = d->cur.cursor();
1070 if ( !buf || !cur )
1071 return FALSE;
1072 if ( !cur->isActive() || !cur->isValid() )
1073 return FALSE;
1074 writeFields();
1075 for ( uint i = 0; i < cur->count(); ++i ) {
1076 if ( cur->value(i) != buf->value(i) )
1077 return TRUE;
1078 }
1079 return FALSE;
1080}
1081
1082/*! \internal
1083
1084 Pre-navigation checking.
1085*/
1086
1087bool QDataBrowser::preNav()
1088{
1089 QSqlRecord* buf = d->frm.record();
1090 QSqlCursor* cur = d->cur.cursor();
1091 if ( !buf || !cur )
1092 return FALSE;
1093
1094 if ( !isReadOnly() && autoEdit() && currentEdited() ) {
1095 bool ok = TRUE;
1096 QSql::Confirm conf = QSql::Yes;
1097 switch ( d->dat.mode() ){
1098 case QSql::Insert:
1099 if ( confirmInsert() )
1100 conf = confirmEdit( QSql::Insert );
1101 switch ( conf ) {
1102 case QSql::Yes:
1103 ok = insertCurrent();
1104 d->dat.setMode( QSql::Update );
1105 break;
1106 case QSql::No:
1107 d->dat.setMode( QSql::Update );
1108 break;
1109 case QSql::Cancel:
1110 return FALSE;
1111 }
1112 break;
1113 default:
1114 if ( confirmUpdate() )
1115 conf = confirmEdit( QSql::Update );
1116 switch ( conf ) {
1117 case QSql::Yes:
1118 ok = updateCurrent();
1119 break;
1120 case QSql::No:
1121 break;
1122 case QSql::Cancel:
1123 return FALSE;
1124 }
1125 }
1126 return ok;
1127 }
1128 return TRUE;
1129}
1130
1131/*! \internal
1132
1133 Handles post-navigation according to \a primeUpd.
1134*/
1135
1136void QDataBrowser::postNav( bool primeUpd )
1137{
1138 if ( primeUpd ) {
1139 QSqlRecord* buf = d->frm.record();
1140 QSqlCursor* cur = d->cur.cursor();
1141 if ( !buf || !cur )
1142 return;
1143 currentChanged( cur );
1144 cur->primeUpdate();
1145 emit primeUpdate( buf );
1146 readFields();
1147 }
1148 updateBoundary();
1149}
1150
1151/*! \internal
1152
1153 Navigate default cursor according to \a nav. Handles autoEdit.
1154
1155*/
1156void QDataBrowser::nav( Nav nav )
1157{
1158 int b = 0;
1159 QSqlCursor* cur = d->cur.cursor();
1160 if ( !cur )
1161 return;
1162 if ( preNav() )
1163 b = (cur->*nav)();
1164 postNav( b );
1165}
1166
1167/*!
1168 If boundaryChecking() is TRUE, checks the boundary of the current
1169 default cursor and emits signals which indicate the position of
1170 the cursor.
1171*/
1172
1173void QDataBrowser::updateBoundary()
1174{
1175 if ( d->boundaryCheck ) {
1176 Boundary bound = boundary();
1177 switch ( bound ) {
1178 case Unknown:
1179 case None:
1180 emit firstRecordAvailable( TRUE );
1181 emit prevRecordAvailable( TRUE );
1182 emit nextRecordAvailable( TRUE );
1183 emit lastRecordAvailable( TRUE );
1184 break;
1185
1186 case BeforeBeginning:
1187 emit firstRecordAvailable( FALSE );
1188 emit prevRecordAvailable( FALSE );
1189 emit nextRecordAvailable( TRUE );
1190 emit lastRecordAvailable( TRUE );
1191 break;
1192
1193 case Beginning:
1194 emit firstRecordAvailable( FALSE );
1195 emit prevRecordAvailable( FALSE );
1196 emit nextRecordAvailable( TRUE );
1197 emit lastRecordAvailable( TRUE );
1198 break;
1199
1200 case End:
1201 emit firstRecordAvailable( TRUE );
1202 emit prevRecordAvailable( TRUE );
1203 emit nextRecordAvailable( FALSE );
1204 emit lastRecordAvailable( FALSE );
1205 break;
1206
1207 case AfterEnd:
1208 emit firstRecordAvailable( TRUE );
1209 emit prevRecordAvailable( TRUE );
1210 emit nextRecordAvailable( FALSE );
1211 emit lastRecordAvailable( FALSE );
1212 break;
1213 }
1214 }
1215}
1216
1217/*!
1218 Virtual function which handles the error \a error. The default
1219 implementation warns the user with a message box.
1220*/
1221
1222void QDataBrowser::handleError( const QSqlError& error )
1223{
1224 d->dat.handleError( this, error );
1225}
1226
1227/*!
1228 Protected virtual function which returns a confirmation for an
1229 edit of mode \a m. Derived classes can reimplement this function
1230 and provide their own confirmation dialog. The default
1231 implementation uses a message box which prompts the user to
1232 confirm the edit action.
1233*/
1234
1235QSql::Confirm QDataBrowser::confirmEdit( QSql::Op m )
1236{
1237 return d->dat.confirmEdit( this, m );
1238}
1239
1240/*!
1241 Protected virtual function which returns a confirmation for
1242 cancelling an edit mode \a m. Derived classes can reimplement this
1243 function and provide their own confirmation dialog. The default
1244 implementation uses a message box which prompts the user to
1245 confirm the edit action.
1246*/
1247
1248QSql::Confirm QDataBrowser::confirmCancel( QSql::Op m )
1249{
1250 return d->dat.confirmCancel( this, m );
1251}
1252
1253/*!
1254 \fn void QDataBrowser::beforeInsert( QSqlRecord* buf )
1255
1256 This signal is emitted just before the cursor's edit buffer is
1257 inserted into the database. The \a buf parameter points to the
1258 edit buffer being inserted. You might connect to this signal to
1259 populate a generated primary key for example.
1260*/
1261
1262/*!
1263 \fn void QDataBrowser::beforeUpdate( QSqlRecord* buf )
1264
1265 This signal is emitted just before the cursor's edit buffer is
1266 updated in the database. The \a buf parameter points to the edit
1267 buffer being updated. You might connect to this signal to capture
1268 some auditing information about the update.
1269*/
1270
1271/*!
1272 \fn void QDataBrowser::beforeDelete( QSqlRecord* buf )
1273
1274 This signal is emitted just before the cursor's edit buffer is
1275 deleted from the database. The \a buf parameter points to the edit
1276 buffer being deleted. You might connect to this signal to capture
1277 some auditing information about the deletion.
1278*/
1279
1280#endif
Note: See TracBrowser for help on using the repository browser.