|
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 "q3wizard.h" |
|
43 |
|
44 #include "qlayout.h" |
|
45 #include "qpushbutton.h" |
|
46 #include "qcursor.h" |
|
47 #include "qlabel.h" |
|
48 #include "qapplication.h" |
|
49 #include "qlist.h" |
|
50 #include "qpainter.h" |
|
51 #include "q3accel.h" |
|
52 |
|
53 QT_BEGIN_NAMESPACE |
|
54 |
|
55 using namespace Qt; |
|
56 |
|
57 /*! |
|
58 \class Q3Wizard |
|
59 \compat |
|
60 \brief The Q3Wizard class provides a framework for wizard dialogs. |
|
61 |
|
62 A wizard is a special type of input dialog that consists of a |
|
63 sequence of dialog pages. A wizard's purpose is to walk the user |
|
64 through a process step by step. Wizards are useful for complex or |
|
65 infrequently occurring tasks that people may find difficult to |
|
66 learn or do. |
|
67 |
|
68 Q3Wizard provides page titles and displays Next, Back, Finish, |
|
69 Cancel, and Help push buttons, as appropriate to the current |
|
70 position in the page sequence. These buttons can be |
|
71 enabled/disabled using setBackEnabled(), setNextEnabled(), |
|
72 setFinishEnabled() and setHelpEnabled(). |
|
73 |
|
74 Create and populate dialog pages that inherit from QWidget and add |
|
75 them to the wizard using addPage(). Use insertPage() to add a |
|
76 dialog page at a certain position in the page sequence. Use |
|
77 removePage() to remove a page from the page sequence. |
|
78 |
|
79 Use currentPage() to retrieve a pointer to the currently displayed |
|
80 page. page() returns a pointer to the page at a certain position |
|
81 in the page sequence. |
|
82 |
|
83 Use pageCount() to retrieve the total number of pages in the page |
|
84 sequence. indexOf() will return the index of a page in the page |
|
85 sequence. |
|
86 |
|
87 Q3Wizard provides functionality to mark pages as appropriate (or |
|
88 not) in the current context with setAppropriate(). The idea is |
|
89 that a page may be irrelevant and should be skipped depending on |
|
90 the data entered by the user on a preceding page. |
|
91 |
|
92 It is generally considered good design to provide a greater number |
|
93 of simple pages with fewer choices rather than a smaller number of |
|
94 complex pages. |
|
95 */ |
|
96 |
|
97 |
|
98 class Q3WizardPrivate |
|
99 { |
|
100 public: |
|
101 |
|
102 virtual ~Q3WizardPrivate() |
|
103 { |
|
104 foreach(Page *page, pages) |
|
105 delete page; |
|
106 } |
|
107 |
|
108 struct Page { |
|
109 Page( QWidget * widget, const QString & title ): |
|
110 w( widget ), t( title ), |
|
111 backEnabled( true ), nextEnabled( true ), finishEnabled( false ), |
|
112 helpEnabled( true ), |
|
113 appropriate( true ) |
|
114 {} |
|
115 QWidget * w; |
|
116 QString t; |
|
117 bool backEnabled; |
|
118 bool nextEnabled; |
|
119 bool finishEnabled; |
|
120 bool helpEnabled; |
|
121 bool appropriate; |
|
122 }; |
|
123 |
|
124 QVBoxLayout * v; |
|
125 Page * current; |
|
126 QList<Page *> pages; |
|
127 QLabel * title; |
|
128 QPushButton * backButton; |
|
129 QPushButton * nextButton; |
|
130 QPushButton * finishButton; |
|
131 QPushButton * cancelButton; |
|
132 QPushButton * helpButton; |
|
133 |
|
134 QFrame * hbar1, * hbar2; |
|
135 |
|
136 #ifndef QT_NO_ACCEL |
|
137 Q3Accel * accel; |
|
138 int backAccel; |
|
139 int nextAccel; |
|
140 #endif |
|
141 |
|
142 Page * page( const QWidget * w ) |
|
143 { |
|
144 if ( !w ) |
|
145 return 0; |
|
146 int i = pages.count(); |
|
147 while( --i >= 0 && pages.at( i ) && pages.at( i )->w != w ) { } |
|
148 return i >= 0 ? pages.at( i ) : 0; |
|
149 } |
|
150 |
|
151 }; |
|
152 |
|
153 |
|
154 /*! |
|
155 Constructs an empty wizard dialog. The \a parent, \a name, \a |
|
156 modal and \a f arguments are passed to the QDialog constructor. |
|
157 */ |
|
158 |
|
159 Q3Wizard::Q3Wizard(QWidget *parent, const char *name, bool modal, Qt::WindowFlags f ) |
|
160 : QDialog( parent, name, modal, f ) |
|
161 { |
|
162 d = new Q3WizardPrivate(); |
|
163 d->current = 0; // not quite true, but... |
|
164 d->title = new QLabel( this, "title label" ); |
|
165 |
|
166 // create in nice tab order |
|
167 d->nextButton = new QPushButton( this, "next" ); |
|
168 d->finishButton = new QPushButton( this, "finish" ); |
|
169 d->helpButton = new QPushButton( this, "help" ); |
|
170 d->backButton = new QPushButton( this, "back" ); |
|
171 d->cancelButton = new QPushButton( this, "cancel" ); |
|
172 |
|
173 d->v = 0; |
|
174 d->hbar1 = 0; |
|
175 d->hbar2 = 0; |
|
176 |
|
177 d->cancelButton->setText( tr( "&Cancel" ) ); |
|
178 d->backButton->setText( tr( "< &Back" ) ); |
|
179 d->nextButton->setText( tr( "&Next >" ) ); |
|
180 d->finishButton->setText( tr( "&Finish" ) ); |
|
181 d->helpButton->setText( tr( "&Help" ) ); |
|
182 |
|
183 d->nextButton->setDefault( true ); |
|
184 |
|
185 connect( d->backButton, SIGNAL(clicked()), |
|
186 this, SLOT(back()) ); |
|
187 connect( d->nextButton, SIGNAL(clicked()), |
|
188 this, SLOT(next()) ); |
|
189 connect( d->finishButton, SIGNAL(clicked()), |
|
190 this, SLOT(accept()) ); |
|
191 connect( d->cancelButton, SIGNAL(clicked()), |
|
192 this, SLOT(reject()) ); |
|
193 connect( d->helpButton, SIGNAL(clicked()), |
|
194 this, SLOT(help()) ); |
|
195 |
|
196 #ifndef QT_NO_ACCEL |
|
197 d->accel = new Q3Accel( this, "arrow-key accel" ); |
|
198 d->backAccel = d->accel->insertItem( Qt::ALT + Qt::Key_Left ); |
|
199 d->accel->connectItem( d->backAccel, this, SLOT(back()) ); |
|
200 d->nextAccel = d->accel->insertItem( Qt::ALT + Qt::Key_Right ); |
|
201 d->accel->connectItem( d->nextAccel, this, SLOT(next()) ); |
|
202 #endif |
|
203 } |
|
204 |
|
205 |
|
206 /*! |
|
207 Destroys the object and frees any allocated resources, including |
|
208 all pages and controllers. |
|
209 */ |
|
210 |
|
211 Q3Wizard::~Q3Wizard() |
|
212 { |
|
213 delete d; |
|
214 } |
|
215 |
|
216 |
|
217 /*! |
|
218 \internal |
|
219 */ |
|
220 |
|
221 void Q3Wizard::setVisible(bool show) |
|
222 { |
|
223 if ( show && !d->current ) { |
|
224 // No page yet |
|
225 if ( pageCount() > 0 ) |
|
226 showPage( d->pages.at( 0 )->w ); |
|
227 else |
|
228 showPage( 0 ); |
|
229 } |
|
230 |
|
231 QDialog::setVisible(show); |
|
232 } |
|
233 |
|
234 |
|
235 /*! |
|
236 \internal |
|
237 */ |
|
238 |
|
239 void Q3Wizard::setFont( const QFont & font ) |
|
240 { |
|
241 QApplication::postEvent( this, new QEvent( QEvent::LayoutHint ) ); |
|
242 QDialog::setFont( font ); |
|
243 } |
|
244 |
|
245 /*! |
|
246 Adds \a page to the end of the page sequence, with the title, \a |
|
247 title. |
|
248 */ |
|
249 |
|
250 void Q3Wizard::addPage( QWidget * page, const QString & title ) |
|
251 { |
|
252 if ( !page ) |
|
253 return; |
|
254 if ( d->page( page ) ) { |
|
255 #if defined(QT_CHECK_STATE) |
|
256 qWarning( "Q3Wizard::addPage(): already added %s/%s to %s/%s", |
|
257 page->className(), page->name(), |
|
258 className(), name() ); |
|
259 #endif |
|
260 return; |
|
261 } |
|
262 int i = d->pages.count(); |
|
263 |
|
264 if( i > 0 ) |
|
265 d->pages.at( i - 1 )->nextEnabled = true; |
|
266 |
|
267 Q3WizardPrivate::Page * p = new Q3WizardPrivate::Page( page, title ); |
|
268 p->backEnabled = ( i > 0 ); |
|
269 d->pages.append( p ); |
|
270 } |
|
271 |
|
272 /*! |
|
273 Inserts \a page at position \a index into the page sequence, with |
|
274 title \a title. If \a index is -1, the page will be appended to |
|
275 the end of the wizard's page sequence. |
|
276 */ |
|
277 |
|
278 void Q3Wizard::insertPage( QWidget * page, const QString & title, int index ) |
|
279 { |
|
280 if ( !page ) |
|
281 return; |
|
282 if ( d->page( page ) ) { |
|
283 #if defined(QT_CHECK_STATE) |
|
284 qWarning( "Q3Wizard::insertPage(): already added %s/%s to %s/%s", |
|
285 page->className(), page->name(), |
|
286 className(), name() ); |
|
287 #endif |
|
288 return; |
|
289 } |
|
290 |
|
291 if ( index < 0 || index > (int)d->pages.count() ) |
|
292 index = d->pages.count(); |
|
293 |
|
294 if( index > 0 && ( index == (int)d->pages.count() ) ) |
|
295 d->pages.at( index - 1 )->nextEnabled = true; |
|
296 |
|
297 Q3WizardPrivate::Page * p = new Q3WizardPrivate::Page( page, title ); |
|
298 p->backEnabled = ( index > 0 ); |
|
299 p->nextEnabled = ( index < (int)d->pages.count() ); |
|
300 |
|
301 d->pages.insert( index, p ); |
|
302 } |
|
303 |
|
304 /*! |
|
305 \fn void Q3Wizard::selected(const QString &title) |
|
306 |
|
307 This signal is emitted when the current page changes. The |
|
308 \a title parameter contains the title of the selected page. |
|
309 */ |
|
310 |
|
311 |
|
312 /*! |
|
313 Makes \a page the current page and emits the selected() signal. |
|
314 |
|
315 This virtual function is called whenever a different page is to |
|
316 be shown, including the first time the Q3Wizard is shown. |
|
317 By reimplementing it (and calling Q3Wizard::showPage()), |
|
318 you can prepare each page prior to it being shown. |
|
319 */ |
|
320 |
|
321 void Q3Wizard::showPage( QWidget * page ) |
|
322 { |
|
323 Q3WizardPrivate::Page * p = d->page( page ); |
|
324 if ( p ) { |
|
325 int i; |
|
326 for( i = 0; i < (int)d->pages.count() && d->pages.at( i ) != p; i++ ) {} |
|
327 bool notFirst( false ); |
|
328 |
|
329 if( i ) { |
|
330 i--; |
|
331 while( ( i >= 0 ) && !notFirst ) { |
|
332 notFirst |= appropriate( d->pages.at( i )->w ); |
|
333 i--; |
|
334 } |
|
335 } |
|
336 setBackEnabled( notFirst ); |
|
337 setNextEnabled( true ); |
|
338 |
|
339 page->show(); |
|
340 foreach(Q3WizardPrivate::Page *ppage, d->pages) { |
|
341 if (ppage->w != page) |
|
342 ppage->w->hide(); |
|
343 } |
|
344 |
|
345 d->current = p; |
|
346 } |
|
347 |
|
348 layOut(); |
|
349 updateButtons(); |
|
350 emit selected( p ? p->t : QString() ); |
|
351 } |
|
352 |
|
353 |
|
354 /*! |
|
355 Returns the number of pages in the wizard. |
|
356 */ |
|
357 |
|
358 int Q3Wizard::pageCount() const |
|
359 { |
|
360 return d->pages.count(); |
|
361 } |
|
362 |
|
363 /*! |
|
364 Returns the position of page \a page. If the page is not part of |
|
365 the wizard -1 is returned. |
|
366 */ |
|
367 |
|
368 int Q3Wizard::indexOf( QWidget* page ) const |
|
369 { |
|
370 Q3WizardPrivate::Page * p = d->page( page ); |
|
371 if ( !p ) return -1; |
|
372 |
|
373 return d->pages.indexOf( p ); |
|
374 } |
|
375 |
|
376 /*! |
|
377 Called when the user clicks the Back button; this function shows |
|
378 the preceding relevant page in the sequence. |
|
379 |
|
380 \sa appropriate() |
|
381 */ |
|
382 void Q3Wizard::back() |
|
383 { |
|
384 int i = 0; |
|
385 |
|
386 while( i < (int)d->pages.count() && d->pages.at( i ) && |
|
387 d->current && d->pages.at( i )->w != d->current->w ) |
|
388 i++; |
|
389 |
|
390 i--; |
|
391 while( i >= 0 && ( !d->pages.at( i ) || !appropriate( d->pages.at( i )->w ) ) ) |
|
392 i--; |
|
393 |
|
394 if( i >= 0 ) |
|
395 if( d->pages.at( i ) ) |
|
396 showPage( d->pages.at( i )->w ); |
|
397 } |
|
398 |
|
399 |
|
400 /*! |
|
401 Called when the user clicks the Next button, this function shows |
|
402 the next relevant page in the sequence. |
|
403 |
|
404 \sa appropriate() |
|
405 */ |
|
406 void Q3Wizard::next() |
|
407 { |
|
408 int i = 0; |
|
409 while( i < (int)d->pages.count() && d->pages.at( i ) && |
|
410 d->current && d->pages.at( i )->w != d->current->w ) |
|
411 i++; |
|
412 i++; |
|
413 while( i <= (int)d->pages.count()-1 && |
|
414 ( !d->pages.at( i ) || !appropriate( d->pages.at( i )->w ) ) ) |
|
415 i++; |
|
416 // if we fell of the end of the world, step back |
|
417 while ( i > 0 && (i >= (int)d->pages.count() || !d->pages.at( i ) ) ) |
|
418 i--; |
|
419 if ( d->pages.at( i ) ) |
|
420 showPage( d->pages.at( i )->w ); |
|
421 } |
|
422 |
|
423 |
|
424 /*! |
|
425 \fn void Q3Wizard::helpClicked() |
|
426 |
|
427 This signal is emitted when the user clicks on the Help button. |
|
428 */ |
|
429 |
|
430 /*! |
|
431 Called when the user clicks the Help button, this function emits |
|
432 the helpClicked() signal. |
|
433 */ |
|
434 |
|
435 void Q3Wizard::help() |
|
436 { |
|
437 QWidget *page = d->current ? d->current->w : 0; |
|
438 if ( !page ) |
|
439 return; |
|
440 |
|
441 #if 0 |
|
442 Q3WizardPage *wpage = qobject_cast<Q3WizardPage*>(page); |
|
443 if ( wpage ) |
|
444 emit wpage->helpClicked(); |
|
445 #endif |
|
446 emit helpClicked(); |
|
447 } |
|
448 |
|
449 |
|
450 void Q3Wizard::setBackEnabled( bool enable ) |
|
451 { |
|
452 d->backButton->setEnabled( enable ); |
|
453 #ifndef QT_NO_ACCEL |
|
454 d->accel->setItemEnabled( d->backAccel, enable ); |
|
455 #endif |
|
456 } |
|
457 |
|
458 |
|
459 void Q3Wizard::setNextEnabled( bool enable ) |
|
460 { |
|
461 d->nextButton->setEnabled( enable ); |
|
462 #ifndef QT_NO_ACCEL |
|
463 d->accel->setItemEnabled( d->nextAccel, enable ); |
|
464 #endif |
|
465 } |
|
466 |
|
467 |
|
468 void Q3Wizard::setHelpEnabled( bool enable ) |
|
469 { |
|
470 d->helpButton->setEnabled( enable ); |
|
471 } |
|
472 |
|
473 |
|
474 /*! |
|
475 \fn void Q3Wizard::setFinish(QWidget *widget, bool finish) |
|
476 \obsolete |
|
477 |
|
478 Use setFinishEnabled() instead. |
|
479 */ |
|
480 |
|
481 /*! |
|
482 If \a enable is true, page \a page has a Back button; otherwise \a |
|
483 page has no Back button. By default all pages have this button. |
|
484 */ |
|
485 void Q3Wizard::setBackEnabled( QWidget * page, bool enable ) |
|
486 { |
|
487 Q3WizardPrivate::Page * p = d->page( page ); |
|
488 if ( !p ) |
|
489 return; |
|
490 |
|
491 p->backEnabled = enable; |
|
492 updateButtons(); |
|
493 } |
|
494 |
|
495 |
|
496 /*! |
|
497 If \a enable is true, page \a page has a Next button; otherwise |
|
498 the Next button on \a page is disabled. By default all pages have |
|
499 this button. |
|
500 */ |
|
501 |
|
502 void Q3Wizard::setNextEnabled( QWidget * page, bool enable ) |
|
503 { |
|
504 Q3WizardPrivate::Page * p = d->page( page ); |
|
505 if ( !p ) |
|
506 return; |
|
507 |
|
508 p->nextEnabled = enable; |
|
509 updateButtons(); |
|
510 } |
|
511 |
|
512 |
|
513 /*! |
|
514 If \a enable is true, page \a page has a Finish button; otherwise |
|
515 \a page has no Finish button. By default \e no page has this |
|
516 button. |
|
517 */ |
|
518 void Q3Wizard::setFinishEnabled( QWidget * page, bool enable ) |
|
519 { |
|
520 Q3WizardPrivate::Page * p = d->page( page ); |
|
521 if ( !p ) |
|
522 return; |
|
523 |
|
524 p->finishEnabled = enable; |
|
525 updateButtons(); |
|
526 } |
|
527 |
|
528 |
|
529 /*! |
|
530 If \a enable is true, page \a page has a Help button; otherwise \a |
|
531 page has no Help button. By default all pages have this button. |
|
532 */ |
|
533 void Q3Wizard::setHelpEnabled( QWidget * page, bool enable ) |
|
534 { |
|
535 Q3WizardPrivate::Page * p = d->page( page ); |
|
536 if ( !p ) |
|
537 return; |
|
538 |
|
539 p->helpEnabled = enable; |
|
540 updateButtons(); |
|
541 } |
|
542 |
|
543 |
|
544 /*! |
|
545 Called when the Next button is clicked; this virtual function |
|
546 returns true if \a page is relevant for display in the current |
|
547 context; otherwise it is ignored by Q3Wizard and returns false. The |
|
548 default implementation returns the value set using |
|
549 setAppropriate(). The ultimate default is true. |
|
550 |
|
551 \warning The last page of the wizard will be displayed if no page |
|
552 is relevant in the current context. |
|
553 */ |
|
554 |
|
555 bool Q3Wizard::appropriate( QWidget * page ) const |
|
556 { |
|
557 Q3WizardPrivate::Page * p = d->page( page ); |
|
558 return p ? p->appropriate : true; |
|
559 } |
|
560 |
|
561 |
|
562 /*! |
|
563 If \a appropriate is true then page \a page is considered relevant |
|
564 in the current context and should be displayed in the page |
|
565 sequence; otherwise \a page should not be displayed in the page |
|
566 sequence. |
|
567 |
|
568 \sa appropriate() |
|
569 */ |
|
570 void Q3Wizard::setAppropriate( QWidget * page, bool appropriate ) |
|
571 { |
|
572 Q3WizardPrivate::Page * p = d->page( page ); |
|
573 if ( p ) |
|
574 p->appropriate = appropriate; |
|
575 } |
|
576 |
|
577 |
|
578 void Q3Wizard::updateButtons() |
|
579 { |
|
580 if ( !d->current ) |
|
581 return; |
|
582 |
|
583 int i; |
|
584 for( i = 0; i < (int)d->pages.count() && d->pages.at( i ) != d->current; i++ ) {} |
|
585 bool notFirst( false ); |
|
586 if( i ) { |
|
587 i--; |
|
588 while( ( i >= 0 ) && !notFirst ) { |
|
589 notFirst |= appropriate( d->pages.at( i )->w ); |
|
590 i--; |
|
591 } |
|
592 } |
|
593 setBackEnabled( d->current->backEnabled && notFirst ); |
|
594 setNextEnabled( d->current->nextEnabled ); |
|
595 d->finishButton->setEnabled( d->current->finishEnabled ); |
|
596 d->helpButton->setEnabled( d->current->helpEnabled ); |
|
597 |
|
598 if ( ( d->current->finishEnabled && !d->finishButton->isVisible() ) || |
|
599 ( d->current->backEnabled && !d->backButton->isVisible() ) || |
|
600 ( d->current->nextEnabled && !d->nextButton->isVisible() ) || |
|
601 ( d->current->helpEnabled && !d->helpButton->isVisible() ) ) |
|
602 layOut(); |
|
603 } |
|
604 |
|
605 |
|
606 /*! |
|
607 Returns a pointer to the current page in the sequence. Although |
|
608 the wizard does its best to make sure that this value is never 0, |
|
609 it can be if you try hard enough. |
|
610 */ |
|
611 |
|
612 QWidget * Q3Wizard::currentPage() const |
|
613 { |
|
614 return d->current ? d->current->w : 0; |
|
615 } |
|
616 |
|
617 |
|
618 /*! |
|
619 Returns the title of page \a page. |
|
620 */ |
|
621 |
|
622 QString Q3Wizard::title( QWidget * page ) const |
|
623 { |
|
624 Q3WizardPrivate::Page * p = d->page( page ); |
|
625 return p ? p->t : QString(); |
|
626 } |
|
627 |
|
628 /*! |
|
629 Sets the title for page \a page to \a title. |
|
630 */ |
|
631 |
|
632 void Q3Wizard::setTitle( QWidget *page, const QString &title ) |
|
633 { |
|
634 Q3WizardPrivate::Page * p = d->page( page ); |
|
635 if ( p ) |
|
636 p->t = title; |
|
637 if ( page == currentPage() ) |
|
638 d->title->setText( title ); |
|
639 } |
|
640 |
|
641 /*! |
|
642 \property Q3Wizard::titleFont |
|
643 \brief the font used for page titles |
|
644 |
|
645 The default is QApplication::font(). |
|
646 */ |
|
647 QFont Q3Wizard::titleFont() const |
|
648 { |
|
649 return d->title->font(); |
|
650 } |
|
651 |
|
652 void Q3Wizard::setTitleFont( const QFont & font ) |
|
653 { |
|
654 d->title->setFont( font ); |
|
655 } |
|
656 |
|
657 |
|
658 /*! |
|
659 Returns a pointer to the dialog's Back button |
|
660 |
|
661 By default, this button is connected to the back() slot, which is |
|
662 virtual so you can reimplement it in a Q3Wizard subclass. Use |
|
663 setBackEnabled() to enable/disable this button. |
|
664 */ |
|
665 QPushButton * Q3Wizard::backButton() const |
|
666 { |
|
667 return d->backButton; |
|
668 } |
|
669 |
|
670 |
|
671 /*! |
|
672 Returns a pointer to the dialog's Next button |
|
673 |
|
674 By default, this button is connected to the next() slot, which is |
|
675 virtual so you can reimplement it in a Q3Wizard subclass. Use |
|
676 setNextEnabled() to enable/disable this button. |
|
677 */ |
|
678 QPushButton * Q3Wizard::nextButton() const |
|
679 { |
|
680 return d->nextButton; |
|
681 } |
|
682 |
|
683 |
|
684 /*! |
|
685 Returns a pointer to the dialog's Finish button |
|
686 |
|
687 By default, this button is connected to the QDialog::accept() |
|
688 slot, which is virtual so you can reimplement it in a Q3Wizard |
|
689 subclass. Use setFinishEnabled() to enable/disable this button. |
|
690 */ |
|
691 QPushButton * Q3Wizard::finishButton() const |
|
692 { |
|
693 return d->finishButton; |
|
694 } |
|
695 |
|
696 |
|
697 /*! |
|
698 Returns a pointer to the dialog's Cancel button |
|
699 |
|
700 By default, this button is connected to the QDialog::reject() |
|
701 slot, which is virtual so you can reimplement it in a Q3Wizard |
|
702 subclass. |
|
703 */ |
|
704 QPushButton * Q3Wizard::cancelButton() const |
|
705 { |
|
706 return d->cancelButton; |
|
707 } |
|
708 |
|
709 |
|
710 /*! |
|
711 Returns a pointer to the dialog's Help button |
|
712 |
|
713 By default, this button is connected to the help() slot, which is |
|
714 virtual so you can reimplement it in a Q3Wizard subclass. Use |
|
715 setHelpEnabled() to enable/disable this button. |
|
716 */ |
|
717 QPushButton * Q3Wizard::helpButton() const |
|
718 { |
|
719 return d->helpButton; |
|
720 } |
|
721 |
|
722 |
|
723 /*! |
|
724 This virtual function is responsible for adding the buttons below |
|
725 the bottom divider. |
|
726 |
|
727 \a layout is the horizontal layout of the entire wizard. |
|
728 */ |
|
729 |
|
730 void Q3Wizard::layOutButtonRow( QHBoxLayout * layout ) |
|
731 { |
|
732 bool hasHelp = false; |
|
733 bool hasEarlyFinish = false; |
|
734 |
|
735 int i = d->pages.count() - 2; |
|
736 while ( !hasEarlyFinish && i >= 0 ) { |
|
737 if ( d->pages.at( i ) && d->pages.at( i )->finishEnabled ) |
|
738 hasEarlyFinish = true; |
|
739 i--; |
|
740 } |
|
741 i = 0; |
|
742 while ( !hasHelp && i < (int)d->pages.count() ) { |
|
743 if ( d->pages.at( i ) && d->pages.at( i )->helpEnabled ) |
|
744 hasHelp = true; |
|
745 i++; |
|
746 } |
|
747 |
|
748 QBoxLayout * h = new QBoxLayout( QBoxLayout::LeftToRight ); |
|
749 layout->addLayout( h ); |
|
750 |
|
751 if ( hasHelp ) |
|
752 h->addWidget( d->helpButton ); |
|
753 else |
|
754 d->helpButton->hide(); |
|
755 |
|
756 h->addStretch( 42 ); |
|
757 |
|
758 h->addWidget( d->backButton ); |
|
759 |
|
760 h->addSpacing( 6 ); |
|
761 |
|
762 if (d->current == d->pages.at( d->pages.count()-1 )) |
|
763 hasEarlyFinish = false; |
|
764 |
|
765 if ( hasEarlyFinish ) { |
|
766 d->nextButton->show(); |
|
767 d->finishButton->show(); |
|
768 h->addWidget( d->nextButton ); |
|
769 h->addSpacing( 12 ); |
|
770 h->addWidget( d->finishButton ); |
|
771 } else if ( d->pages.count() == 0 || |
|
772 (d->current && d->current->finishEnabled) || |
|
773 d->current == d->pages.at( d->pages.count()-1 ) ) { |
|
774 d->nextButton->hide(); |
|
775 d->finishButton->show(); |
|
776 h->addWidget( d->finishButton ); |
|
777 } else { |
|
778 d->nextButton->show(); |
|
779 d->finishButton->hide(); |
|
780 h->addWidget( d->nextButton ); |
|
781 } |
|
782 |
|
783 // if last page is disabled - show finished btn. at lastpage-1 |
|
784 i = d->pages.count()-1; |
|
785 if ( i >= 0 && !appropriate( d->pages.at( i )->w ) && |
|
786 d->current == d->pages.at( d->pages.count()-2 ) ) { |
|
787 d->nextButton->hide(); |
|
788 d->finishButton->show(); |
|
789 h->addWidget( d->finishButton ); |
|
790 } |
|
791 |
|
792 h->addSpacing( 12 ); |
|
793 h->addWidget( d->cancelButton ); |
|
794 } |
|
795 |
|
796 |
|
797 /*! |
|
798 This virtual function is responsible for laying out the title row. |
|
799 |
|
800 \a layout is the horizontal layout for the wizard, and \a |
|
801 title is the title for this page. This function is called every |
|
802 time \a title changes. |
|
803 */ |
|
804 |
|
805 void Q3Wizard::layOutTitleRow( QHBoxLayout * layout, const QString & title ) |
|
806 { |
|
807 d->title->setText( title ); |
|
808 layout->addWidget( d->title, 10 ); |
|
809 } |
|
810 |
|
811 |
|
812 /* |
|
813 |
|
814 */ |
|
815 |
|
816 void Q3Wizard::layOut() |
|
817 { |
|
818 delete d->v; |
|
819 d->v = new QVBoxLayout( this, 6, 0, "top-level layout" ); |
|
820 |
|
821 QHBoxLayout * l; |
|
822 l = new QHBoxLayout( 6 ); |
|
823 d->v->addLayout( l, 0 ); |
|
824 layOutTitleRow( l, d->current ? d->current->t : QString() ); |
|
825 |
|
826 if ( ! d->hbar1 ) { |
|
827 d->hbar1 = new QFrame( this, "<hr>", 0 ); |
|
828 d->hbar1->setFrameStyle( QFrame::Sunken + QFrame::HLine ); |
|
829 d->hbar1->setFixedHeight( 12 ); |
|
830 } |
|
831 |
|
832 d->v->addWidget( d->hbar1 ); |
|
833 |
|
834 if (d->current) |
|
835 d->v->addWidget(d->current->w, 10); |
|
836 |
|
837 if ( ! d->hbar2 ) { |
|
838 d->hbar2 = new QFrame( this, "<hr>", 0 ); |
|
839 d->hbar2->setFrameStyle( QFrame::Sunken + QFrame::HLine ); |
|
840 d->hbar2->setFixedHeight( 12 ); |
|
841 } |
|
842 d->v->addWidget( d->hbar2 ); |
|
843 |
|
844 l = new QHBoxLayout( 6 ); |
|
845 d->v->addLayout( l ); |
|
846 layOutButtonRow( l ); |
|
847 d->v->activate(); |
|
848 } |
|
849 |
|
850 |
|
851 /*! |
|
852 \reimp |
|
853 */ |
|
854 |
|
855 bool Q3Wizard::eventFilter( QObject * o, QEvent * e ) |
|
856 { |
|
857 return QDialog::eventFilter( o, e ); |
|
858 } |
|
859 |
|
860 |
|
861 /*! |
|
862 Removes \a page from the page sequence but does not delete the |
|
863 page. If \a page is currently being displayed, Q3Wizard will |
|
864 display the page that precedes it, or the first page if this was |
|
865 the first page. |
|
866 */ |
|
867 |
|
868 void Q3Wizard::removePage( QWidget * page ) |
|
869 { |
|
870 if ( !page ) |
|
871 return; |
|
872 |
|
873 int i = d->pages.count(); |
|
874 QWidget* cp = currentPage(); |
|
875 while( --i >= 0 && d->pages.at( i ) && d->pages.at( i )->w != page ) { } |
|
876 if ( i < 0 ) |
|
877 return; |
|
878 delete d->pages.takeAt(i); |
|
879 page->hide(); |
|
880 |
|
881 if( cp == page ) { |
|
882 i--; |
|
883 if( i < 0 ) |
|
884 i = 0; |
|
885 if ( pageCount() > 0 ) |
|
886 showPage( Q3Wizard::page( i ) ); |
|
887 } else if (pageCount() > 0) { |
|
888 showPage(cp); |
|
889 } |
|
890 } |
|
891 |
|
892 |
|
893 /*! |
|
894 Returns a pointer to the page at position \a index in the |
|
895 sequence, or 0 if \a index is out of range. The first page has |
|
896 index 0. |
|
897 */ |
|
898 |
|
899 QWidget* Q3Wizard::page( int index ) const |
|
900 { |
|
901 if ( index >= pageCount() || index < 0 ) |
|
902 return 0; |
|
903 return d->pages.at( index )->w; |
|
904 } |
|
905 |
|
906 QT_END_NAMESPACE |