|
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 "q3sqlmanager_p.h" |
|
43 |
|
44 #ifndef QT_NO_SQL |
|
45 |
|
46 #include "qapplication.h" |
|
47 #include "qcursor.h" |
|
48 #include "qwidget.h" |
|
49 #include "q3sqlcursor.h" |
|
50 #include "qsqlfield.h" |
|
51 #include "q3sqlform.h" |
|
52 #include "qsqldriver.h" |
|
53 #include "qstring.h" |
|
54 #include "qmessagebox.h" |
|
55 #include "qbitarray.h" |
|
56 |
|
57 QT_BEGIN_NAMESPACE |
|
58 |
|
59 //#define QT_DEBUG_DATAMANAGER |
|
60 |
|
61 class Q3SqlCursorManagerPrivate |
|
62 { |
|
63 public: |
|
64 Q3SqlCursorManagerPrivate() |
|
65 : cur(0), autoDelete(false) |
|
66 {} |
|
67 |
|
68 QString ftr; |
|
69 QStringList srt; |
|
70 Q3SqlCursor* cur; |
|
71 bool autoDelete; |
|
72 }; |
|
73 |
|
74 static QSqlIndex indexFromStringList(const QStringList& l, const Q3SqlCursor* cursor) |
|
75 { |
|
76 QSqlIndex newSort; |
|
77 for (int i = 0; i < l.count(); ++i) { |
|
78 QString f = l[i]; |
|
79 bool desc = false; |
|
80 if (f.mid(f.length()-3) == QLatin1String("ASC")) |
|
81 f = f.mid(0, f.length()-3); |
|
82 if (f.mid(f.length()-4) == QLatin1String("DESC")) { |
|
83 desc = true; |
|
84 f = f.mid(0, f.length()-4); |
|
85 } |
|
86 int dot = f.lastIndexOf(QLatin1Char('.')); |
|
87 if (dot != -1) |
|
88 f = f.mid(dot+1); |
|
89 const QSqlField field = cursor->field(f.trimmed()); |
|
90 if (field.isValid()) |
|
91 newSort.append(field, desc); |
|
92 else |
|
93 qWarning("QSqlIndex::indexFromStringList: unknown field: '%s'", f.latin1()); |
|
94 } |
|
95 return newSort; |
|
96 } |
|
97 |
|
98 |
|
99 /*! |
|
100 \class Q3SqlCursorManager |
|
101 \brief The Q3SqlCursorManager class manages a database cursor. |
|
102 |
|
103 \compat |
|
104 \internal |
|
105 |
|
106 This class provides common cursor management functionality. This |
|
107 includes saving and applying sorts and filters, refreshing (i.e., |
|
108 re-selecting) the cursor and searching for records within the |
|
109 cursor. |
|
110 |
|
111 */ |
|
112 |
|
113 /*! \internal |
|
114 |
|
115 Constructs a cursor manager. |
|
116 |
|
117 */ |
|
118 |
|
119 Q3SqlCursorManager::Q3SqlCursorManager() |
|
120 { |
|
121 d = new Q3SqlCursorManagerPrivate; |
|
122 } |
|
123 |
|
124 |
|
125 /*! \internal |
|
126 |
|
127 Destroys the object and frees any allocated resources. |
|
128 |
|
129 */ |
|
130 |
|
131 Q3SqlCursorManager::~Q3SqlCursorManager() |
|
132 { |
|
133 if (d->autoDelete) |
|
134 delete d->cur; |
|
135 delete d; |
|
136 } |
|
137 |
|
138 /*! \internal |
|
139 |
|
140 Sets the manager's sort to the index \a sort. To apply the new |
|
141 sort, use refresh(). |
|
142 |
|
143 */ |
|
144 |
|
145 void Q3SqlCursorManager::setSort(const QSqlIndex& sort) |
|
146 { |
|
147 setSort(sort.toStringList()); |
|
148 } |
|
149 |
|
150 /*! \internal |
|
151 |
|
152 Sets the manager's sort to the stringlist \a sort. To apply the |
|
153 new sort, use refresh(). |
|
154 |
|
155 */ |
|
156 |
|
157 void Q3SqlCursorManager::setSort(const QStringList& sort) |
|
158 { |
|
159 d->srt = sort; |
|
160 } |
|
161 |
|
162 /*! \internal |
|
163 |
|
164 Returns the current sort, or an empty stringlist if there is none. |
|
165 |
|
166 */ |
|
167 |
|
168 QStringList Q3SqlCursorManager::sort() const |
|
169 { |
|
170 return d->srt; |
|
171 } |
|
172 |
|
173 /*! \internal |
|
174 |
|
175 Sets the manager's filter to the string \a filter. To apply the |
|
176 new filter, use refresh(). |
|
177 |
|
178 */ |
|
179 |
|
180 void Q3SqlCursorManager::setFilter(const QString& filter) |
|
181 { |
|
182 d->ftr = filter; |
|
183 } |
|
184 |
|
185 /*! \internal |
|
186 |
|
187 Returns the current filter, or an empty string if there is none. |
|
188 |
|
189 */ |
|
190 |
|
191 QString Q3SqlCursorManager::filter() const |
|
192 { |
|
193 return d->ftr; |
|
194 } |
|
195 |
|
196 /*! \internal |
|
197 |
|
198 Sets auto-delete to \a enable. If true, the default cursor will |
|
199 be deleted when necessary. |
|
200 |
|
201 \sa autoDelete() |
|
202 */ |
|
203 |
|
204 void Q3SqlCursorManager::setAutoDelete(bool enable) |
|
205 { |
|
206 d->autoDelete = enable; |
|
207 } |
|
208 |
|
209 |
|
210 /*! \internal |
|
211 |
|
212 Returns true if auto-deletion is enabled, otherwise false. |
|
213 |
|
214 \sa setAutoDelete() |
|
215 |
|
216 */ |
|
217 |
|
218 bool Q3SqlCursorManager::autoDelete() const |
|
219 { |
|
220 return d->autoDelete; |
|
221 } |
|
222 |
|
223 /*! \internal |
|
224 |
|
225 Sets the default cursor used by the manager to \a cursor. If \a |
|
226 autoDelete is true (the default is false), the manager takes |
|
227 ownership of the \a cursor pointer, which will be deleted when the |
|
228 manager is destroyed, or when setCursor() is called again. To |
|
229 activate the \a cursor use refresh(). |
|
230 |
|
231 \sa cursor() |
|
232 |
|
233 */ |
|
234 |
|
235 void Q3SqlCursorManager::setCursor(Q3SqlCursor* cursor, bool autoDelete) |
|
236 { |
|
237 if (d->autoDelete) |
|
238 delete d->cur; |
|
239 d->cur = cursor; |
|
240 d->autoDelete = autoDelete; |
|
241 } |
|
242 |
|
243 /*! \internal |
|
244 |
|
245 Returns a pointer to the default cursor used for navigation, or 0 |
|
246 if there is no default cursor. |
|
247 |
|
248 \sa setCursor() |
|
249 |
|
250 */ |
|
251 |
|
252 Q3SqlCursor* Q3SqlCursorManager::cursor() const |
|
253 { |
|
254 return d->cur; |
|
255 } |
|
256 |
|
257 |
|
258 /*! \internal |
|
259 |
|
260 Refreshes the manager using the default cursor. The manager's |
|
261 filter and sort are applied. Returns true on success, false if an |
|
262 error occurred or there is no current cursor. |
|
263 |
|
264 \sa setFilter() setSort() |
|
265 |
|
266 */ |
|
267 |
|
268 bool Q3SqlCursorManager::refresh() |
|
269 { |
|
270 Q3SqlCursor* cur = cursor(); |
|
271 if (!cur) |
|
272 return false; |
|
273 QString currentFilter = d->ftr; |
|
274 QStringList currentSort = d->srt; |
|
275 QSqlIndex newSort = indexFromStringList(currentSort, cur); |
|
276 return cur->select(currentFilter, newSort); |
|
277 } |
|
278 |
|
279 /* \internal |
|
280 |
|
281 Returns true if the \a buf field values that correspond to \a idx |
|
282 match the field values in \a cur that correspond to \a idx. |
|
283 */ |
|
284 |
|
285 static bool index_matches(const Q3SqlCursor* cur, const QSqlRecord* buf, |
|
286 const QSqlIndex& idx) |
|
287 { |
|
288 bool indexEquals = false; |
|
289 for (int i = 0; i < idx.count(); ++i) { |
|
290 const QString fn(idx.field(i).name()); |
|
291 if (cur->value(fn) == buf->value(fn)) |
|
292 indexEquals = true; |
|
293 else { |
|
294 indexEquals = false; |
|
295 break; |
|
296 } |
|
297 } |
|
298 return indexEquals; |
|
299 } |
|
300 |
|
301 /* |
|
302 Return less than, equal to or greater than 0 if buf1 is less than, |
|
303 equal to or greater than buf2 according to fields described in idx. |
|
304 (### Currently only uses first field.) |
|
305 */ |
|
306 |
|
307 static int compare_recs(const QSqlRecord* buf1, const QSqlRecord* buf2, |
|
308 const QSqlIndex& idx) |
|
309 { |
|
310 int cmp = 0; |
|
311 |
|
312 int i = 0; |
|
313 const QString fn(idx.field(i).name()); |
|
314 const QSqlField f1 = buf1->field(fn); |
|
315 |
|
316 if (f1.isValid()) { |
|
317 switch (f1.type()) { // ### more types? |
|
318 case QVariant::String: |
|
319 cmp = f1.value().toString().trimmed().compare( |
|
320 buf2->value(fn).toString().trimmed()); |
|
321 break; |
|
322 default: |
|
323 if (f1.value().toDouble() < buf2->value(fn).toDouble()) |
|
324 cmp = -1; |
|
325 else if (f1.value().toDouble() > buf2->value(fn).toDouble()) |
|
326 cmp = 1; |
|
327 } |
|
328 } |
|
329 |
|
330 if (idx.isDescending(i)) |
|
331 cmp = -cmp; |
|
332 return cmp; |
|
333 } |
|
334 |
|
335 #ifdef QT_DEBUG_DATAMANAGER |
|
336 static void debug_datamanager_buffer(const QString& msg, QSqlRecord* cursor) |
|
337 { |
|
338 qDebug("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"); |
|
339 qDebug("%s", msg.latin1()); |
|
340 for (int j = 0; j < cursor->count(); ++j) { |
|
341 qDebug("%s", (cursor->field(j)->name() + " type:" |
|
342 + QString(cursor->field(j)->value().typeName()) |
|
343 + " value:" + cursor->field(j)->value().toString()) |
|
344 .latin1()); |
|
345 } |
|
346 } |
|
347 #endif |
|
348 |
|
349 |
|
350 /*! \internal |
|
351 |
|
352 Relocates the default cursor to the record matching the cursor's |
|
353 edit buffer. Only the field names specified by \a idx are used to |
|
354 determine an exact match of the cursor to the edit buffer. However, |
|
355 other fields in the edit buffer are also used during the search, |
|
356 therefore all fields in the edit buffer should be primed with desired |
|
357 values for the record being sought. This function is typically used |
|
358 to relocate a cursor to the correct position after an insert or |
|
359 update. For example: |
|
360 |
|
361 \snippet doc/src/snippets/code/src_qt3support_sql_q3sqlmanager_p.cpp 0 |
|
362 |
|
363 */ |
|
364 |
|
365 //## possibly add sizeHint parameter |
|
366 bool Q3SqlCursorManager::findBuffer(const QSqlIndex& idx, int atHint) |
|
367 { |
|
368 #ifdef QT_DEBUG_DATAMANAGER |
|
369 qDebug("Q3SqlCursorManager::findBuffer:"); |
|
370 #endif |
|
371 Q3SqlCursor* cur = cursor(); |
|
372 if (!cur) |
|
373 return false; |
|
374 if (!cur->isActive()) |
|
375 return false; |
|
376 if (!idx.count()) { |
|
377 if (cur->at() == QSql::BeforeFirst) |
|
378 cur->next(); |
|
379 return false; |
|
380 } |
|
381 QSqlRecord* buf = cur->editBuffer(); |
|
382 bool indexEquals = false; |
|
383 #ifdef QT_DEBUG_DATAMANAGER |
|
384 qDebug(" Checking hint..."); |
|
385 #endif |
|
386 /* check the hint */ |
|
387 if (cur->seek(atHint)) |
|
388 indexEquals = index_matches(cur, buf, idx); |
|
389 |
|
390 if (!indexEquals) { |
|
391 #ifdef QT_DEBUG_DATAMANAGER |
|
392 qDebug(" Checking current page..."); |
|
393 #endif |
|
394 /* check current page */ |
|
395 int pageSize = 20; |
|
396 int startIdx = qMax(atHint - pageSize, 0); |
|
397 int endIdx = atHint + pageSize; |
|
398 for (int j = startIdx; j <= endIdx; ++j) { |
|
399 if (cur->seek(j)) { |
|
400 indexEquals = index_matches(cur, buf, idx); |
|
401 if (indexEquals) |
|
402 break; |
|
403 } |
|
404 } |
|
405 } |
|
406 |
|
407 if (!indexEquals && cur->driver()->hasFeature(QSqlDriver::QuerySize) |
|
408 && cur->sort().count()) { |
|
409 #ifdef QT_DEBUG_DATAMANAGER |
|
410 qDebug(" Using binary search..."); |
|
411 #endif |
|
412 // binary search based on record buffer and current sort fields |
|
413 int lo = 0; |
|
414 int hi = cur->size(); |
|
415 int mid; |
|
416 if (compare_recs(buf, cur, cur->sort()) >= 0) |
|
417 lo = cur->at(); |
|
418 while (lo != hi) { |
|
419 mid = lo + (hi - lo) / 2; |
|
420 if (!cur->seek(mid)) |
|
421 break; |
|
422 if (index_matches(cur, buf, idx)) { |
|
423 indexEquals = true; |
|
424 break; |
|
425 } |
|
426 int c = compare_recs(buf, cur, cur->sort()); |
|
427 if (c < 0) { |
|
428 hi = mid; |
|
429 } else if (c == 0) { |
|
430 // found it, but there may be duplicates |
|
431 int at = mid; |
|
432 do { |
|
433 mid--; |
|
434 if (!cur->seek(mid)) |
|
435 break; |
|
436 if (index_matches(cur, buf, idx)) { |
|
437 indexEquals = true; |
|
438 break; |
|
439 } |
|
440 } while (compare_recs(buf, cur, cur->sort()) == 0); |
|
441 |
|
442 if (!indexEquals) { |
|
443 mid = at; |
|
444 do { |
|
445 mid++; |
|
446 if (!cur->seek(mid)) |
|
447 break; |
|
448 if (index_matches(cur, buf, idx)) { |
|
449 indexEquals = true; |
|
450 break; |
|
451 } |
|
452 } while (compare_recs(buf, cur, cur->sort()) == 0); |
|
453 } |
|
454 break; |
|
455 } else if (c > 0) { |
|
456 lo = mid + 1; |
|
457 } |
|
458 } |
|
459 } |
|
460 |
|
461 if (!indexEquals) { |
|
462 #ifdef QT_DEBUG_DATAMANAGER |
|
463 qDebug(" Using brute search..."); |
|
464 #endif |
|
465 #ifndef QT_NO_CURSOR |
|
466 QApplication::setOverrideCursor(Qt::WaitCursor); |
|
467 #endif |
|
468 /* give up, use brute force */ |
|
469 int startIdx = 0; |
|
470 if (cur->at() != startIdx) { |
|
471 cur->seek(startIdx); |
|
472 } |
|
473 for (;;) { |
|
474 indexEquals = false; |
|
475 indexEquals = index_matches(cur, buf, idx); |
|
476 if (indexEquals) |
|
477 break; |
|
478 if (!cur->next()) |
|
479 break; |
|
480 } |
|
481 #ifndef QT_NO_CURSOR |
|
482 QApplication::restoreOverrideCursor(); |
|
483 #endif |
|
484 } |
|
485 #ifdef QT_DEBUG_DATAMANAGER |
|
486 qDebug(" Done, result:" + QString::number(indexEquals)); |
|
487 #endif |
|
488 return indexEquals; |
|
489 } |
|
490 |
|
491 #ifndef QT_NO_SQL_FORM |
|
492 |
|
493 class Q3SqlFormManagerPrivate |
|
494 { |
|
495 public: |
|
496 Q3SqlFormManagerPrivate() : frm(0), rcd(0) {} |
|
497 Q3SqlForm* frm; |
|
498 QSqlRecord* rcd; |
|
499 }; |
|
500 |
|
501 |
|
502 /*! \internal |
|
503 |
|
504 Creates a form manager. |
|
505 |
|
506 */ |
|
507 |
|
508 Q3SqlFormManager::Q3SqlFormManager() |
|
509 { |
|
510 d = new Q3SqlFormManagerPrivate(); |
|
511 } |
|
512 |
|
513 /*! \internal |
|
514 |
|
515 Destroys the object and frees any allocated resources. |
|
516 |
|
517 */ |
|
518 |
|
519 Q3SqlFormManager::~Q3SqlFormManager() |
|
520 { |
|
521 delete d; |
|
522 } |
|
523 |
|
524 /*! \internal |
|
525 |
|
526 Clears the default form values. If there is no default form, |
|
527 nothing happens, |
|
528 |
|
529 */ |
|
530 |
|
531 void Q3SqlFormManager::clearValues() |
|
532 { |
|
533 if (form()) |
|
534 form()->clearValues(); |
|
535 } |
|
536 |
|
537 /*! \internal |
|
538 |
|
539 Sets the form used by the form manager to \a form. If a record has |
|
540 already been assigned to the form manager, that record is also used by |
|
541 the \a form to display data. |
|
542 |
|
543 \sa form() |
|
544 |
|
545 */ |
|
546 |
|
547 void Q3SqlFormManager::setForm(Q3SqlForm* form) |
|
548 { |
|
549 d->frm = form; |
|
550 if (d->rcd && d->frm) |
|
551 d->frm->setRecord(d->rcd); |
|
552 } |
|
553 |
|
554 |
|
555 /*! \internal |
|
556 |
|
557 Returns the default form used by the form manager, or 0 if there is |
|
558 none. |
|
559 |
|
560 \sa setForm() |
|
561 |
|
562 */ |
|
563 |
|
564 Q3SqlForm* Q3SqlFormManager::form() |
|
565 { |
|
566 return d->frm; |
|
567 } |
|
568 |
|
569 |
|
570 /*! \internal |
|
571 |
|
572 Sets the record used by the form manager to \a record. If a form has |
|
573 already been assigned to the form manager, \a record is also used by |
|
574 the default form to display data. |
|
575 |
|
576 \sa record() |
|
577 |
|
578 */ |
|
579 |
|
580 void Q3SqlFormManager::setRecord(QSqlRecord* record) |
|
581 { |
|
582 d->rcd = record; |
|
583 if (d->frm) { |
|
584 d->frm->setRecord(d->rcd); |
|
585 } |
|
586 } |
|
587 |
|
588 |
|
589 /*! \internal |
|
590 |
|
591 Returns the default record used by the form manager, or 0 if there is |
|
592 none. |
|
593 |
|
594 \sa setRecord() |
|
595 */ |
|
596 |
|
597 QSqlRecord* Q3SqlFormManager::record() |
|
598 { |
|
599 return d->rcd; |
|
600 } |
|
601 |
|
602 |
|
603 /*! \internal |
|
604 |
|
605 Causes the default form to read its fields . If there is no |
|
606 default form, nothing happens. |
|
607 |
|
608 \sa setForm() |
|
609 |
|
610 */ |
|
611 |
|
612 void Q3SqlFormManager::readFields() |
|
613 { |
|
614 if (d->frm) { |
|
615 d->frm->readFields(); |
|
616 } |
|
617 } |
|
618 |
|
619 /*! \internal |
|
620 |
|
621 Causes the default form to write its fields . If there is no |
|
622 default form, nothing happens. |
|
623 |
|
624 \sa setForm() |
|
625 |
|
626 */ |
|
627 |
|
628 void Q3SqlFormManager::writeFields() |
|
629 { |
|
630 if (d->frm) { |
|
631 d->frm->writeFields(); |
|
632 } |
|
633 } |
|
634 |
|
635 #endif // QT_NO_SQL_FORM |
|
636 |
|
637 class Q3DataManagerPrivate |
|
638 { |
|
639 public: |
|
640 Q3DataManagerPrivate() |
|
641 : mode(QSql::None), autoEd(true), confEdits(3), |
|
642 confCancs(false) {} |
|
643 QSql::Op mode; |
|
644 bool autoEd; |
|
645 QBitArray confEdits; |
|
646 bool confCancs; |
|
647 |
|
648 }; |
|
649 |
|
650 /*! |
|
651 \class Q3DataManager |
|
652 |
|
653 \brief The Q3DataManager class is an internal class for implementing |
|
654 the data-aware widgets. |
|
655 |
|
656 \internal |
|
657 \compat |
|
658 |
|
659 Q3DataManager is a strictly internal class that acts as a base class |
|
660 for other data-aware widgets. |
|
661 |
|
662 */ |
|
663 |
|
664 |
|
665 /*! \internal |
|
666 |
|
667 Constructs an empty data handler. |
|
668 |
|
669 */ |
|
670 |
|
671 Q3DataManager::Q3DataManager() |
|
672 { |
|
673 d = new Q3DataManagerPrivate(); |
|
674 } |
|
675 |
|
676 |
|
677 /*! \internal |
|
678 |
|
679 Destroys the object and frees any allocated resources. |
|
680 |
|
681 */ |
|
682 |
|
683 Q3DataManager::~Q3DataManager() |
|
684 { |
|
685 delete d; |
|
686 } |
|
687 |
|
688 |
|
689 /*! \internal |
|
690 |
|
691 Virtual function which is called when an error has occurred The |
|
692 default implementation displays a warning message to the user with |
|
693 information about the error. |
|
694 |
|
695 */ |
|
696 void Q3DataManager::handleError(QWidget* parent, const QSqlError& e) |
|
697 { |
|
698 #ifndef QT_NO_MESSAGEBOX |
|
699 if (e.driverText().isEmpty() && e.databaseText().isEmpty()) { |
|
700 QMessageBox::warning (parent, QLatin1String("Warning"), QLatin1String("An error occurred while accessing the database")); |
|
701 } else { |
|
702 QMessageBox::warning (parent, QLatin1String("Warning"), e.driverText() + QLatin1Char('\n') + e.databaseText(), |
|
703 0, 0); |
|
704 } |
|
705 #endif // QT_NO_MESSAGEBOX |
|
706 } |
|
707 |
|
708 |
|
709 /*! \internal |
|
710 |
|
711 Sets the internal mode to \a m. |
|
712 |
|
713 */ |
|
714 |
|
715 void Q3DataManager::setMode(QSql::Op m) |
|
716 { |
|
717 d->mode = m; |
|
718 } |
|
719 |
|
720 |
|
721 /*! \internal |
|
722 |
|
723 Returns the current mode. |
|
724 |
|
725 */ |
|
726 |
|
727 QSql::Op Q3DataManager::mode() const |
|
728 { |
|
729 return d->mode; |
|
730 } |
|
731 |
|
732 |
|
733 /*! \internal |
|
734 |
|
735 Sets the auto-edit mode to \a auto. |
|
736 |
|
737 */ |
|
738 |
|
739 void Q3DataManager::setAutoEdit(bool autoEdit) |
|
740 { |
|
741 d->autoEd = autoEdit; |
|
742 } |
|
743 |
|
744 |
|
745 |
|
746 /*! \internal |
|
747 |
|
748 Returns true if auto-edit mode is enabled; otherwise returns false. |
|
749 |
|
750 */ |
|
751 |
|
752 bool Q3DataManager::autoEdit() const |
|
753 { |
|
754 return d->autoEd; |
|
755 } |
|
756 |
|
757 /*! \internal |
|
758 |
|
759 If \a confirm is true, all edit operations (inserts, updates and |
|
760 deletes) will be confirmed by the user. If \a confirm is false (the |
|
761 default), all edits are posted to the database immediately. |
|
762 |
|
763 */ |
|
764 void Q3DataManager::setConfirmEdits(bool confirm) |
|
765 { |
|
766 d->confEdits = QBitArray(d->confEdits.size(), confirm); |
|
767 } |
|
768 |
|
769 /*! \internal |
|
770 |
|
771 If \a confirm is true, all inserts will be confirmed by the user. |
|
772 If \a confirm is false (the default), all edits are posted to the |
|
773 database immediately. |
|
774 |
|
775 */ |
|
776 |
|
777 void Q3DataManager::setConfirmInsert(bool confirm) |
|
778 { |
|
779 d->confEdits[QSql::Insert] = confirm; |
|
780 } |
|
781 |
|
782 /*! \internal |
|
783 |
|
784 If \a confirm is true, all updates will be confirmed by the user. |
|
785 If \a confirm is false (the default), all edits are posted to the |
|
786 database immediately. |
|
787 |
|
788 */ |
|
789 |
|
790 void Q3DataManager::setConfirmUpdate(bool confirm) |
|
791 { |
|
792 d->confEdits[QSql::Update] = confirm; |
|
793 } |
|
794 |
|
795 /*! \internal |
|
796 |
|
797 If \a confirm is true, all deletes will be confirmed by the user. |
|
798 If \a confirm is false (the default), all edits are posted to the |
|
799 database immediately. |
|
800 |
|
801 */ |
|
802 |
|
803 void Q3DataManager::setConfirmDelete(bool confirm) |
|
804 { |
|
805 d->confEdits[QSql::Delete] = confirm; |
|
806 } |
|
807 |
|
808 /*! \internal |
|
809 |
|
810 Returns true if the table confirms all edit operations (inserts, |
|
811 updates and deletes), otherwise returns false. |
|
812 */ |
|
813 |
|
814 bool Q3DataManager::confirmEdits() const |
|
815 { |
|
816 return (confirmInsert() && confirmUpdate() && confirmDelete()); |
|
817 } |
|
818 |
|
819 /*! \internal |
|
820 |
|
821 Returns true if the table confirms inserts, otherwise returns |
|
822 false. |
|
823 */ |
|
824 |
|
825 bool Q3DataManager::confirmInsert() const |
|
826 { |
|
827 return d->confEdits[QSql::Insert]; |
|
828 } |
|
829 |
|
830 /*! \internal |
|
831 |
|
832 Returns true if the table confirms updates, otherwise returns |
|
833 false. |
|
834 */ |
|
835 |
|
836 bool Q3DataManager::confirmUpdate() const |
|
837 { |
|
838 return d->confEdits[QSql::Update]; |
|
839 } |
|
840 |
|
841 /*! \internal |
|
842 |
|
843 Returns true if the table confirms deletes, otherwise returns |
|
844 false. |
|
845 */ |
|
846 |
|
847 bool Q3DataManager::confirmDelete() const |
|
848 { |
|
849 return d->confEdits[QSql::Delete]; |
|
850 } |
|
851 |
|
852 /*! \internal |
|
853 |
|
854 If \a confirm is true, all cancels will be confirmed by the user |
|
855 through a message box. If \a confirm is false (the default), all |
|
856 cancels occur immediately. |
|
857 */ |
|
858 |
|
859 void Q3DataManager::setConfirmCancels(bool confirm) |
|
860 { |
|
861 d->confCancs = confirm; |
|
862 } |
|
863 |
|
864 /*! \internal |
|
865 |
|
866 Returns true if the table confirms cancels, otherwise returns false. |
|
867 */ |
|
868 |
|
869 bool Q3DataManager::confirmCancels() const |
|
870 { |
|
871 return d->confCancs; |
|
872 } |
|
873 |
|
874 /*! \internal |
|
875 |
|
876 Virtual function which returns a confirmation for an edit of mode \a |
|
877 m. Derived classes can reimplement this function and provide their |
|
878 own confirmation dialog. The default implementation uses a message |
|
879 box which prompts the user to confirm the edit action. The dialog |
|
880 is centered over \a parent. |
|
881 |
|
882 */ |
|
883 |
|
884 QSql::Confirm Q3DataManager::confirmEdit(QWidget* parent, QSql::Op m) |
|
885 { |
|
886 int ans = 2; |
|
887 if (m == QSql::Delete) { |
|
888 #ifndef QT_NO_MESSAGEBOX |
|
889 ans = QMessageBox::information(parent, |
|
890 qApp->translate("QSql", "Delete"), |
|
891 qApp->translate("QSql", "Delete this record?"), |
|
892 qApp->translate("QSql", "Yes"), |
|
893 qApp->translate("QSql", "No"), |
|
894 QString(), 0, 1); |
|
895 #else |
|
896 ans = QSql::No; |
|
897 #endif // QT_NO_MESSAGEBOX |
|
898 } else if (m != QSql::None) { |
|
899 QString caption; |
|
900 if (m == QSql::Insert) { |
|
901 caption = qApp->translate("QSql", "Insert"); |
|
902 } else { // QSql::Update |
|
903 caption = qApp->translate("QSql", "Update"); |
|
904 } |
|
905 #ifndef QT_NO_MESSAGEBOX |
|
906 ans = QMessageBox::information(parent, caption, |
|
907 qApp->translate("QSql", "Save edits?"), |
|
908 qApp->translate("QSql", "Yes"), |
|
909 qApp->translate("QSql", "No"), |
|
910 qApp->translate("QSql", "Cancel"), |
|
911 0, 2); |
|
912 #else |
|
913 ans = QSql::No; |
|
914 #endif // QT_NO_MESSAGEBOX |
|
915 } |
|
916 |
|
917 switch (ans) { |
|
918 case 0: |
|
919 return QSql::Yes; |
|
920 case 1: |
|
921 return QSql::No; |
|
922 default: |
|
923 return QSql::Cancel; |
|
924 } |
|
925 } |
|
926 |
|
927 /*! \internal |
|
928 |
|
929 Virtual function which returns a confirmation for canceling an edit |
|
930 mode \a m. Derived classes can reimplement this function and |
|
931 provide their own confirmation dialog. The default implementation |
|
932 uses a message box which prompts the user to confirm the edit |
|
933 action. The dialog is centered over \a parent. |
|
934 |
|
935 |
|
936 */ |
|
937 |
|
938 QSql::Confirm Q3DataManager::confirmCancel(QWidget* parent, QSql::Op) |
|
939 { |
|
940 #ifndef QT_NO_MESSAGEBOX |
|
941 switch (QMessageBox::information(parent, |
|
942 qApp->translate("QSql", "Confirm"), |
|
943 qApp->translate("QSql", "Cancel your edits?"), |
|
944 qApp->translate("QSql", "Yes"), |
|
945 qApp->translate("QSql", "No"), |
|
946 QString(), 0, 1)) { |
|
947 case 0: |
|
948 return QSql::Yes; |
|
949 case 1: |
|
950 return QSql::No; |
|
951 default: |
|
952 return QSql::Cancel; |
|
953 } |
|
954 #else |
|
955 return QSql::Yes; |
|
956 #endif // QT_NO_MESSAGEBOX |
|
957 } |
|
958 |
|
959 QT_END_NAMESPACE |
|
960 |
|
961 #endif |