00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include "mythwizard.h"
00039
00040 #include "qlayout.h"
00041 #include "qpushbutton.h"
00042 #include "qcursor.h"
00043 #include "qlabel.h"
00044 #include "qwidgetstack.h"
00045 #include "qapplication.h"
00046 #include "qptrlist.h"
00047 #include "qpainter.h"
00048
00049 #include "mythcontext.h"
00050
00051 class MythWizardPrivate
00052 {
00053 public:
00054 struct Page {
00055 Page( QWidget * widget, const QString & title ):
00056 w( widget ), t( title ),
00057 backEnabled( TRUE ), nextEnabled( TRUE ), finishEnabled( FALSE ),
00058 appropriate( TRUE )
00059 {}
00060 QWidget * w;
00061 QString t;
00062 bool backEnabled;
00063 bool nextEnabled;
00064 bool finishEnabled;
00065 bool appropriate;
00066 };
00067
00068 QVBoxLayout * v;
00069 Page * current;
00070 QWidgetStack * ws;
00071 QPtrList<Page> pages;
00072 QLabel * title;
00073 MythPushButton * backButton;
00074 MythPushButton * nextButton;
00075 MythPushButton * finishButton;
00076 MythPushButton * cancelButton;
00077
00078 QGroupBox *helpgroup;
00079 QLabel *help;
00080
00081 QFrame * hbar1, * hbar2;
00082
00083 Page * page( const QWidget * w )
00084 {
00085 if ( !w )
00086 return 0;
00087 int i = pages.count();
00088 while( --i >= 0 && pages.at( i ) && pages.at( i )->w != w ) { }
00089 return i >= 0 ? pages.at( i ) : 0;
00090 }
00091
00092 };
00093
00094 MythWizard::MythWizard(MythMainWindow *parent, const char *name)
00095 : MythDialog(parent, name)
00096 {
00097 d = new MythWizardPrivate();
00098 d->current = 0;
00099 d->ws = new QWidgetStack( this, "qt_widgetstack" );
00100 d->pages.setAutoDelete( TRUE );
00101 d->title = new QLabel( this, "title label" );
00102 d->title->setBackgroundOrigin(QWidget::WindowOrigin);
00103
00104
00105 d->nextButton = new MythPushButton( this, "next" );
00106 d->finishButton = new MythPushButton( this, "finish" );
00107 d->backButton = new MythPushButton( this, "back" );
00108 d->cancelButton = new MythPushButton( this, "cancel" );
00109
00110 d->ws->installEventFilter( this );
00111
00112 d->helpgroup = 0;
00113 d->help = 0;
00114 d->v = 0;
00115 d->hbar1 = 0;
00116 d->hbar2 = 0;
00117
00118 d->cancelButton->setText( tr( "&Cancel" ) );
00119 d->backButton->setText( tr( "< &Back" ) );
00120 d->nextButton->setText( tr( "&Next >" ) );
00121 d->finishButton->setText( tr( "&Finish" ) );
00122
00123 d->nextButton->setDefault( TRUE );
00124
00125 connect( d->backButton, SIGNAL(clicked()),
00126 this, SLOT(back()) );
00127 connect( d->nextButton, SIGNAL(clicked()),
00128 this, SLOT(next()) );
00129 connect( d->finishButton, SIGNAL(clicked()),
00130 this, SLOT(accept()) );
00131 connect( d->cancelButton, SIGNAL(clicked()),
00132 this, SLOT(reject()) );
00133 }
00134
00135 MythWizard::~MythWizard()
00136 {
00137 delete d;
00138 }
00139
00140 void MythWizard::Show()
00141 {
00142 if ( d->current )
00143 showPage( d->current->w );
00144 else if ( pageCount() > 0 )
00145 showPage( d->pages.at( 0 )->w );
00146 else
00147 showPage( 0 );
00148
00149 MythDialog::Show();
00150 }
00151
00152 void MythWizard::setFont( const QFont & font )
00153 {
00154 QApplication::postEvent( this, new QEvent( QEvent::LayoutHint ) );
00155 setFont( font );
00156 }
00157
00158 void MythWizard::addPage( QWidget * page, const QString & title )
00159 {
00160 if ( !page )
00161 return;
00162 if ( d->page( page ) ) {
00163 qWarning( "MythWizard::addPage(): already added %s/%s to %s/%s",
00164 page->className(), page->name(),
00165 className(), name() );
00166 return;
00167 }
00168 int i = d->pages.count();
00169
00170 if ( i > 0 )
00171 d->pages.at( i - 1 )->nextEnabled = TRUE;
00172
00173 MythWizardPrivate::Page * p = new MythWizardPrivate::Page( page, title );
00174 p->backEnabled = ( i > 0 );
00175 d->ws->addWidget( page, i );
00176 d->pages.append( p );
00177 }
00178
00179 void MythWizard::insertPage( QWidget * page, const QString & title, int index )
00180 {
00181 if ( !page )
00182 return;
00183 if ( d->page( page ) ) {
00184 qWarning( "MythWizard::insertPage(): already added %s/%s to %s/%s",
00185 page->className(), page->name(),
00186 className(), name() );
00187 return;
00188 }
00189
00190 if ( index < 0 || index > (int)d->pages.count() )
00191 index = d->pages.count();
00192
00193 if ( index > 0 && ( index == (int)d->pages.count() ) )
00194 d->pages.at( index - 1 )->nextEnabled = TRUE;
00195
00196 MythWizardPrivate::Page * p = new MythWizardPrivate::Page( page, title );
00197 p->backEnabled = ( index > 0 );
00198 p->nextEnabled = ( index < (int)d->pages.count() );
00199
00200 d->ws->addWidget( page, index );
00201 d->pages.insert( index, p );
00202 }
00203
00204 void MythWizard::showPage( QWidget * page )
00205 {
00206 MythWizardPrivate::Page * p = d->page( page );
00207 if ( p ) {
00208 int i;
00209 for( i = 0; i < (int)d->pages.count() && d->pages.at( i ) != p; i++ );
00210 bool notFirst( FALSE );
00211
00212 if ( i ) {
00213 i--;
00214 while( ( i >= 0 ) && !notFirst ) {
00215 notFirst |= appropriate( d->pages.at( i )->w );
00216 i--;
00217 }
00218 }
00219 setBackEnabled( notFirst );
00220 setNextEnabled( TRUE );
00221 d->ws->raiseWidget( page );
00222 d->current = p;
00223 }
00224
00225 layOut();
00226 updateButtons();
00227 emit selected( p ? p->t : QString::null );
00228
00229 if (indexOf(page) == pageCount()-1) {
00230
00231 finishButton()->setEnabled(TRUE);
00232 finishButton()->setFocus();
00233 } else {
00234 nextButton()->setFocus();
00235 }
00236 }
00237
00238 int MythWizard::pageCount() const
00239 {
00240 return d->pages.count();
00241 }
00242
00243 int MythWizard::indexOf( QWidget* page ) const
00244 {
00245 MythWizardPrivate::Page * p = d->page( page );
00246 if ( !p ) return -1;
00247
00248 return d->pages.find( p );
00249 }
00250
00251 void MythWizard::back()
00252 {
00253 int i = 0;
00254
00255 while( i < (int)d->pages.count() && d->pages.at( i ) &&
00256 d->current && d->pages.at( i )->w != d->current->w )
00257 i++;
00258
00259 i--;
00260 while( i >= 0 &&
00261 ( !d->pages.at( i ) || !appropriate( d->pages.at( i )->w ) ) )
00262 i--;
00263
00264 if ( i >= 0 )
00265 if ( d->pages.at( i ) )
00266 showPage( d->pages.at( i )->w );
00267 }
00268
00269 void MythWizard::next()
00270 {
00271 int i = 0;
00272 while( i < (int)d->pages.count() && d->pages.at( i ) &&
00273 d->current && d->pages.at( i )->w != d->current->w )
00274 i++;
00275 i++;
00276 while( i <= (int)d->pages.count()-1 &&
00277 ( !d->pages.at( i ) || !appropriate( d->pages.at( i )->w ) ) )
00278 i++;
00279 while ( i > 0 && (i >= (int)d->pages.count() || !d->pages.at( i ) ) )
00280 i--;
00281 if ( d->pages.at( i ) )
00282 showPage( d->pages.at( i )->w );
00283 }
00284
00285 void MythWizard::setBackEnabled( bool enable )
00286 {
00287 d->backButton->setEnabled( enable );
00288 }
00289
00290 void MythWizard::setNextEnabled( bool enable )
00291 {
00292 d->nextButton->setEnabled( enable );
00293 }
00294
00295 void MythWizard::setBackEnabled( QWidget * page, bool enable )
00296 {
00297 MythWizardPrivate::Page * p = d->page( page );
00298 if ( !p )
00299 return;
00300
00301 p->backEnabled = enable;
00302 updateButtons();
00303 }
00304
00305 void MythWizard::setNextEnabled( QWidget * page, bool enable )
00306 {
00307 MythWizardPrivate::Page * p = d->page( page );
00308 if ( !p )
00309 return;
00310
00311 p->nextEnabled = enable;
00312 updateButtons();
00313 }
00314
00315 void MythWizard::setFinishEnabled( QWidget * page, bool enable )
00316 {
00317 MythWizardPrivate::Page * p = d->page( page );
00318 if ( !p )
00319 return;
00320
00321 p->finishEnabled = enable;
00322 updateButtons();
00323 }
00324
00325 bool MythWizard::appropriate( QWidget * page ) const
00326 {
00327 MythWizardPrivate::Page * p = d->page( page );
00328 return p ? p->appropriate : TRUE;
00329 }
00330
00331 void MythWizard::setAppropriate( QWidget * page, bool appropriate )
00332 {
00333 MythWizardPrivate::Page * p = d->page( page );
00334 if ( p )
00335 p->appropriate = appropriate;
00336 }
00337
00338 void MythWizard::updateButtons()
00339 {
00340 if ( !d->current )
00341 return;
00342
00343 int i;
00344 for( i = 0; i < (int)d->pages.count() && d->pages.at( i ) != d->current; i++ );
00345 bool notFirst( FALSE );
00346 if ( i ) {
00347 i--;
00348 while( ( i >= 0 ) && !notFirst ) {
00349 notFirst |= appropriate( d->pages.at( i )->w );
00350 i--;
00351 }
00352 }
00353 setBackEnabled( d->current->backEnabled && notFirst );
00354 setNextEnabled( d->current->nextEnabled );
00355 d->finishButton->setEnabled( d->current->finishEnabled );
00356
00357 if ( ( d->current->finishEnabled && !d->finishButton->isVisible() ) ||
00358 ( d->current->backEnabled && !d->backButton->isVisible() ) ||
00359 ( d->current->nextEnabled && !d->nextButton->isVisible() ) )
00360 layOut();
00361 }
00362
00363 QWidget * MythWizard::currentPage() const
00364 {
00365 return d->ws->visibleWidget();
00366 }
00367
00368 QString MythWizard::title( QWidget * page ) const
00369 {
00370 MythWizardPrivate::Page * p = d->page( page );
00371 return p ? p->t : QString::null;
00372 }
00373
00374 void MythWizard::setTitle( QWidget *page, const QString &title )
00375 {
00376 MythWizardPrivate::Page * p = d->page( page );
00377 if ( p )
00378 p->t = title;
00379 if ( page == currentPage() )
00380 d->title->setText( title );
00381 }
00382
00383 QFont MythWizard::titleFont() const
00384 {
00385 return d->title->font();
00386 }
00387
00388 void MythWizard::setTitleFont( const QFont & font )
00389 {
00390 d->title->setFont( font );
00391 }
00392
00393 MythPushButton * MythWizard::backButton() const
00394 {
00395 return d->backButton;
00396 }
00397
00398 MythPushButton * MythWizard::nextButton() const
00399 {
00400 return d->nextButton;
00401 }
00402
00403 MythPushButton * MythWizard::finishButton() const
00404 {
00405 return d->finishButton;
00406 }
00407
00408 MythPushButton * MythWizard::cancelButton() const
00409 {
00410 return d->cancelButton;
00411 }
00412
00413 void MythWizard::layOutButtonRow( QHBoxLayout * layout )
00414 {
00415 bool hasEarlyFinish = FALSE;
00416
00417 int i = d->pages.count() - 2;
00418 while ( !hasEarlyFinish && i >= 0 ) {
00419 if ( d->pages.at( i ) && d->pages.at( i )->finishEnabled )
00420 hasEarlyFinish = TRUE;
00421 i--;
00422 }
00423
00424 QBoxLayout * h = new QBoxLayout( QBoxLayout::LeftToRight );
00425 layout->addLayout( h );
00426
00427 h->addWidget( d->cancelButton );
00428
00429 h->addStretch( 42 );
00430
00431 h->addWidget( d->backButton );
00432
00433 h->addSpacing( 6 );
00434
00435 if ( hasEarlyFinish ) {
00436 d->nextButton->show();
00437 d->finishButton->show();
00438 h->addWidget( d->nextButton );
00439 h->addSpacing( 12 );
00440 h->addWidget( d->finishButton );
00441 } else if ( d->pages.count() == 0 ||
00442 d->current->finishEnabled ||
00443 d->current == d->pages.at( d->pages.count()-1 ) ) {
00444 d->nextButton->hide();
00445 d->finishButton->show();
00446 h->addWidget( d->finishButton );
00447 } else {
00448 d->nextButton->show();
00449 d->finishButton->hide();
00450 h->addWidget( d->nextButton );
00451 }
00452
00453
00454 i = d->pages.count()-1;
00455 if ( i >= 0 && !appropriate( d->pages.at( i )->w ) &&
00456 d->current == d->pages.at( d->pages.count()-2 ) ) {
00457 d->nextButton->hide();
00458 d->finishButton->show();
00459 h->addWidget( d->finishButton );
00460 }
00461 }
00462
00463 void MythWizard::layOutTitleRow( QHBoxLayout * layout, const QString & title )
00464 {
00465 d->title->setText( title );
00466 layout->addWidget( d->title, 10 );
00467 }
00468
00469 void MythWizard::layOut()
00470 {
00471 delete d->v;
00472 d->v = new QVBoxLayout( this, 6, 0, "top-level layout" );
00473
00474 QHBoxLayout * l;
00475 l = new QHBoxLayout( 6 );
00476 d->v->addLayout( l, 0 );
00477 layOutTitleRow( l, d->current ? d->current->t : QString::null );
00478
00479 if ( ! d->hbar1 ) {
00480 d->hbar1 = new QFrame( this, "<hr>", 0 );
00481 d->hbar1->setBackgroundOrigin(QWidget::WindowOrigin);
00482 d->hbar1->setFrameStyle( QFrame::Sunken + QFrame::HLine );
00483 d->hbar1->setFixedHeight( 12 );
00484 }
00485
00486 d->v->addWidget( d->hbar1 );
00487
00488 d->v->addWidget( d->ws, 10 );
00489
00490 if (!d->helpgroup)
00491 {
00492 d->helpgroup = new QGroupBox(this, "help-group-box");
00493 d->helpgroup->setBackgroundOrigin(QWidget::WindowOrigin);
00494
00495 d->help = new QLabel(d->helpgroup, "help text");
00496 d->help->setBackgroundOrigin(QWidget::WindowOrigin);
00497
00498 d->help->setAlignment(Qt::WordBreak | Qt::AlignLeft | Qt::AlignTop);
00499
00500 d->help->setMinimumWidth(screenwidth - (int)(40 * wmult));
00501 d->help->setMaximumHeight((int)(80 * hmult));
00502 d->help->setMinimumHeight((int)(80 * hmult));
00503
00504 QVBoxLayout *helplayout = new QVBoxLayout(d->helpgroup, 10);
00505 helplayout->add(d->help);
00506 }
00507 else
00508 {
00509 d->help->setText("");
00510 }
00511
00512 d->v->addWidget(d->helpgroup);
00513
00514 if ( ! d->hbar2 ) {
00515 d->hbar2 = new QFrame( this, "<hr>", 0 );
00516 d->hbar2->setBackgroundOrigin(QWidget::WindowOrigin);
00517 d->hbar2->setFrameStyle( QFrame::Sunken + QFrame::HLine );
00518 d->hbar2->setFixedHeight( 12 );
00519 }
00520 d->v->addWidget( d->hbar2 );
00521
00522 l = new QHBoxLayout( 6 );
00523 d->v->addLayout( l );
00524 layOutButtonRow( l );
00525 d->v->activate();
00526 }
00527
00528 bool MythWizard::eventFilter( QObject * o, QEvent * e )
00529 {
00530 if ( o == d->ws && e && e->type() == QEvent::ChildRemoved ) {
00531 QChildEvent * c = (QChildEvent*)e;
00532 if ( c->child() && c->child()->isWidgetType() )
00533 removePage( (QWidget *)c->child() );
00534 }
00535 return QWidget::eventFilter( o, e );
00536 }
00537
00538 void MythWizard::keyPressEvent(QKeyEvent* e)
00539 {
00540 bool handled = false;
00541 QStringList actions;
00542 if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
00543 {
00544 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00545 {
00546 QString action = actions[i];
00547 handled = true;
00548
00549 if (action == "SELECT")
00550 {
00551 if (indexOf(currentPage()) == pageCount()-1)
00552 accept();
00553 else
00554 next();
00555 }
00556 else if (action == "ESCAPE")
00557 {
00558 if (indexOf(currentPage()) == 0)
00559 reject();
00560 else
00561 {
00562 back();
00563 QApplication::postEvent(gContext->GetMainWindow(),
00564 new ExitToMainMenuEvent());
00565 }
00566 }
00567 else
00568 handled = false;
00569 }
00570 }
00571
00572 if (!handled)
00573 MythDialog::keyPressEvent(e);
00574 }
00575
00576 void MythWizard::removePage( QWidget * page )
00577 {
00578 if ( !page )
00579 return;
00580
00581 int i = d->pages.count();
00582 QWidget* cp = currentPage();
00583 while( --i >= 0 && d->pages.at( i ) && d->pages.at( i )->w != page ) { }
00584 if ( i < 0 )
00585 return;
00586 MythWizardPrivate::Page * p = d->pages.at( i );
00587 d->pages.removeRef( p );
00588 d->ws->removeWidget( page );
00589
00590 if ( cp == page ) {
00591 i--;
00592 if ( i < 0 )
00593 i = 0;
00594 if ( pageCount() > 0 )
00595 showPage( MythWizard::page( i ) );
00596 }
00597 }
00598
00599 QWidget* MythWizard::page( int index ) const
00600 {
00601 if ( index >= pageCount() || index < 0 )
00602 return 0;
00603
00604 return d->pages.at( index )->w;
00605 }
00606
00607 void MythWizard::setHelpText(QString helptext)
00608 {
00609 if (!d->help)
00610 return;
00611
00612 d->help->setText(helptext);
00613 d->help->setMinimumWidth(screenwidth - (int)(40 * wmult));
00614 d->help->setMaximumHeight((int)(80 * hmult));
00615 }
00616
00617 MythJumpWizard::MythJumpWizard(MythMainWindow *parent, const char *name) :
00618 MythWizard(parent, name)
00619 {
00620 }
00621
00622 MythJumpWizard::~MythJumpWizard()
00623 {
00624 }