src/qt3support/dialogs/q3wizard.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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