28 #define YUILogComponent "qt-wizard"
29 #include <yui/YUILog.h>
32 #include <yui/YShortcut.h>
35 #include <QSvgRenderer>
37 #include <QStackedWidget>
42 #include <qmenudata.h>
45 #include <qpushbutton.h>
47 #include <qtabwidget.h>
48 #include <qtoolbutton.h>
49 #include <QGraphicsDropShadowEffect>
51 #include "QY2ListView.h"
52 #include "QY2Styler.h"
53 #include "QY2HelpDialog.h"
54 #include <QGridLayout>
55 #include <QHeaderView>
61 #include "YQApplication.h"
63 #include "YQAlignment.h"
64 #include "YQReplacePoint.h"
67 #include "YQWizardButton.h"
68 #include "YQWidgetFactory.h"
69 #include "YQSignalBlocker.h"
70 #include <yui/YEvent.h>
71 #include "YQMainWinDock.h"
80 #define TEXTDOMAIN "qt"
82 #define USE_ICON_ON_HELP_BUTTON 0
87 const std::string & backButtonLabel,
88 const std::string & abortButtonLabel,
89 const std::string & nextButtonLabel,
90 YWizardMode wizardMode )
91 : QSplitter( Qt::Horizontal, (QWidget *) parent->widgetRep() )
98 , _backButtonLabel( backButtonLabel )
99 , _abortButtonLabel( abortButtonLabel )
100 , _nextButtonLabel( nextButtonLabel )
103 setObjectName(
"wizard" );
104 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
106 QHBoxLayout* layout =
new QHBoxLayout(
this );
107 layout->setSpacing( 0 );
108 layout->setMargin( 0 );
110 setWidgetRep(
this );
113 _stepsEnabled = ( (wizardMode == YWizardMode_Steps) || main_wizard );
114 _treeEnabled = (wizardMode == YWizardMode_Tree);
116 _stepsRegistered =
false;
118 _direction = YQWizard::Forward;
125 _releaseNotesButton = 0;
137 _sendButtonEvents =
true;
138 _contentsReplacePoint = 0;
140 _previousWindowIcon = topLevelWidget()->windowIcon();
146 if( topLevelWidget()->windowTitle().isEmpty() )
149 QPixmap pixmap ( YUI::app()->applicationIcon().c_str() );
150 if ( !pixmap.isNull() )
151 setWindowIcon ( QIcon ( pixmap ) );
154 layout->addLayout( layoutSideBar(
this ) );
155 layout->addWidget( layoutWorkArea(
this ) );
157 setStretchFactor(indexOf(_sideBar),0);
158 setStretchFactor(indexOf(_workArea),1);
162 if ( !_stepsEnabled )
163 QY2Styler::styler()->registerWidget(
this );
165 if ( !main_wizard && _stepsEnabled )
169 else if ( main_wizard )
181 if (
this == main_wizard )
185 else if ( main_wizard )
188 main_wizard->setSizes( sizes() );
193 QY2Styler::styler()->unregisterWidget(
this );
194 topLevelWidget()->setWindowIcon( _previousWindowIcon );
200 return this != main_wizard;
204 void YQWizard::layoutTitleBar( QWidget * parent )
206 QFrame * titleBar =
new QFrame( parent );
207 YUI_CHECK_NEW( titleBar );
209 QHBoxLayout *layout =
new QHBoxLayout( titleBar );
210 titleBar->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
216 QLabel * left =
new QLabel( titleBar );
217 layout->addWidget( left );
218 left->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) );
219 left->setObjectName(
"titleBar-left" );
225 layout->addStretch( 10 );
232 QLabel * right =
new QLabel( titleBar );
233 YUI_CHECK_NEW( right );
235 layout->addWidget( right );
236 right->setObjectName(
"titleBar-right" );
240 QLayout *YQWizard::layoutSideBar( QWidget * parent )
242 _sideBar =
new QStackedWidget( parent );
243 YUI_CHECK_NEW( _sideBar );
245 _sideBar->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) );
246 _sideBar->setObjectName( QString(
"_sideBar-%1" ).arg(
long(
this ) ) );
247 _sideBar->installEventFilter(
this );
249 QVBoxLayout *vbox =
new QVBoxLayout( );
250 vbox->addWidget( _sideBar );
257 else if ( _stepsEnabled )
269 void YQWizard::layoutStepsPanel()
272 _stepsPanel =
new QFrame( _sideBar );
273 _sideBar->addWidget( _stepsPanel );
274 _stepsPanel->setObjectName(
"steps" );
275 QY2Styler::styler()->registerChildWidget(
this, _stepsPanel );
276 _stepsPanel->setProperty(
"class",
"steps QFrame" );
282 _releaseNotesButton =
new QPushButton( _(
"Release Notes..." ), _stepsPanel );
283 _releaseNotesButton->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum ) );
285 connect( _releaseNotesButton, SIGNAL( clicked() ),
288 _releaseNotesButton->hide();
296 QString qId = fromUTF8(
id );
298 if ( _stepsIDs[ qId ] )
300 yuiError() <<
"Step ID \"" <<
id <<
"\" (\"" << text
301 <<
"\") already used for \"" << _stepsIDs[ qId ]->name() <<
"\""
306 if ( !_stepsList.empty() && _stepsList.last()->name() == fromUTF8( text ) )
314 _stepsList.last()->addID( qId );
322 _stepsIDs.insert( qId, _stepsList.last() );
325 if ( _currentStepID.isNull() )
326 _currentStepID = qId;
342 yuiDebug() <<
"updateSteps" << std::endl;
344 if ( !_stepsRegistered )
345 setUpdatesEnabled(
false);
348 delete _stepsPanel->layout();
349 _stepsPanel->setMaximumWidth( 65000 );
351 QVBoxLayout *_stepsVBox =
new QVBoxLayout( _stepsPanel );
353 QGridLayout *_stepsGrid =
new QGridLayout( );
354 _stepsGrid->setObjectName( QString(
"_stepsGrid_%1" ).arg(
long(
this ) ) );
355 YUI_CHECK_NEW( _stepsGrid );
356 _stepsVBox->addLayout( _stepsGrid );
357 _stepsGrid->setColumnMinimumWidth( 0, 10 );
358 _stepsGrid->setRowStretch( 0, 1 );
359 _stepsGrid->setRowStretch( 1, 1 );
360 _stepsGrid->setRowStretch( 2, 99 );
362 const int statusCol = 1;
363 const int nameCol = 2;
371 for ( QList<Step*>::iterator i = _stepsList.begin(); i != _stepsList.end(); ++i)
375 step->deleteLabels();
377 if ( step->isHeading() )
383 yuiDebug() <<
"Adding StepHeading \"" << step->name() <<
"\"" << std::endl;
384 QLabel * label =
new QLabel( step->name(), _stepsPanel );
385 YUI_CHECK_NEW( label );
386 label->setObjectName( step->name() );
387 label->setAlignment( Qt::AlignLeft | Qt::AlignTop );
388 label->setProperty(
"class",
"steps_heading" );
390 step->setNameLabel( label );
391 _stepsGrid->addWidget( label,
393 1, nameCol - statusCol + 1);
401 yuiDebug() <<
"Adding Step \"" << step->name() <<
"\"" << std::endl;
403 QLabel * statusLabel =
new QLabel( _stepsPanel );
404 YUI_CHECK_NEW( statusLabel );
406 step->setStatusLabel( statusLabel );
407 statusLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
408 _stepsGrid->addWidget( statusLabel, row, statusCol );
414 QLabel * nameLabel =
new QLabel( step->name(), _stepsPanel );
415 YUI_CHECK_NEW( nameLabel );
416 nameLabel->setAlignment( Qt::AlignLeft | Qt::AlignTop );
417 nameLabel->setObjectName( step->name() );
419 step->setNameLabel( nameLabel );
420 _stepsGrid->addWidget( nameLabel, row, nameCol );
427 _stepsVBox->addStretch( 99 );
428 QVBoxLayout *rbl =
new QVBoxLayout();
429 rbl->addWidget( _releaseNotesButton, 0, Qt::AlignCenter );
431 _stepsVBox->addLayout( rbl );
432 _stepsVBox->addStretch( 29 );
436 if ( !_stepsRegistered )
438 QY2Styler::styler()->registerWidget(
this );
439 setUpdatesEnabled(
true );
440 QY2Styler::styler()->updateRendering(
this );
441 _stepsRegistered =
true;
448 yuiDebug() <<
"steps dirty: " << _stepsDirty << std::endl;
454 QList<YQWizard::Step*>::iterator step = _stepsList.begin();
465 while ( step != _stepsList.end() && *step !=
currentStep )
467 ( *step )->setStatus( Step::Done );
473 if ( step != _stepsList.end() )
481 while ( step != _stepsList.end() )
483 ( *step )->setStatus( Step::Todo );
491 yuiDebug() <<
"Setting current step to \"" <<
id <<
"\"" << std::endl;
493 _currentStepID = fromUTF8(
id );
499 QList<Step*> _oldSteps = wizard->
stepsList();
501 if (_oldSteps.empty())
504 foreach(
Step *oldStep, _oldSteps)
508 if( !oldStep->isHeading() )
509 newStep =
new Step( oldStep->name());
513 foreach( QString oneId, oldStep->id())
515 newStep->addID( oneId);
516 _stepsIDs.insert( oneId, newStep );
519 newStep->setEnabled( oldStep->isEnabled());
520 _stepsList.append(newStep);
525 setSizes( main_wizard->sizes());
531 yuiDebug() <<
"Deleting steps" << std::endl;
534 _stepsPanel->setFixedWidth( _stepsPanel->width() );
536 qDeleteAll(_stepsList);
539 _currentStepID = QString::null;
549 return _stepsIDs[ id ];
553 void YQWizard::layoutTreePanel()
555 _treePanel =
new QFrame( _sideBar );
556 YUI_CHECK_NEW( _treePanel );
557 QHBoxLayout *layout =
new QHBoxLayout( _treePanel );
558 _sideBar->addWidget( _treePanel );
560 QVBoxLayout * vbox =
new QVBoxLayout();
561 YUI_CHECK_NEW( vbox );
562 layout->addLayout( vbox );
567 YUI_CHECK_NEW( _tree );
568 vbox->addWidget( _tree );
570 _tree->header()->hide();
571 _tree->header()->setResizeMode( 0, QHeaderView::Stretch );
573 _tree->setRootIsDecorated(
true );
576 connect( _tree, SIGNAL( itemSelectionChanged (
void ) ),
579 connect( _tree, SIGNAL( itemDoubleClicked ( QTreeWidgetItem *,
int ) ),
587 QString qId = fromUTF8(
id );
591 yuiError() <<
"YQWizard widget not created with `opt(`treeEnabled) !" << std::endl;
598 if ( ! parentID.empty() )
606 YUI_CHECK_NEW( item );
611 YUI_CHECK_NEW( item );
614 if ( ! qId.isEmpty() )
615 _treeIDs.insert( qId, item );
635 return _treeIDs[ fromUTF8(
id ) ];
649 _tree->setCurrentItem(item);
650 _tree->scrollToItem(item);
662 if ( item && ! item->id().isEmpty() )
679 QTreeWidgetItem * sel = _tree->currentItem();
685 if ( item && ! item->id().isEmpty() )
686 return toUTF8( item->id() );
690 return std::string();
695 QWidget *YQWizard::layoutWorkArea( QWidget * parent )
697 _workArea =
new QFrame( parent );
698 _workArea->setObjectName(
"work_area" );
700 QY2Styler::styler()->registerChildWidget(
this, _workArea );
702 QVBoxLayout *vbox =
new QVBoxLayout( _workArea );
703 YUI_CHECK_NEW( vbox );
709 _menuBar =
new QMenuBar( _workArea );
710 YUI_CHECK_NEW( _menuBar );
713 vbox->addWidget( _menuBar );
716 QVBoxLayout *innerbox =
new QVBoxLayout( _workArea );
717 YUI_CHECK_NEW( innerbox );
719 innerbox->setMargin ( YQWidgetMargin );
721 vbox->addLayout(innerbox);
722 vbox->setMargin( 0 );
729 QHBoxLayout * headingHBox =
new QHBoxLayout();
730 YUI_CHECK_NEW( headingHBox );
732 innerbox->addLayout( headingHBox );
734 _dialogIcon =
new QLabel( _workArea );
735 YUI_CHECK_NEW( _dialogIcon );
736 headingHBox->addWidget( _dialogIcon );
737 _dialogIcon->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) );
738 _dialogIcon->setObjectName(
"DialogIcon" );
740 _dialogHeading =
new QLabel( _workArea );
741 YUI_CHECK_NEW( _dialogHeading );
742 headingHBox->addWidget( _dialogHeading );
743 _dialogHeading->setAlignment( Qt::AlignLeft );
744 _dialogHeading->setWordWrap(
true );
745 _dialogHeading->setTextFormat( Qt::PlainText );
746 _dialogHeading->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) );
747 _dialogHeading->setObjectName(
"DialogHeading" );
754 layoutClientArea( _workArea );
755 innerbox->addWidget( _clientArea );
761 QLayout *bb = layoutButtonBox( _workArea );
762 innerbox->addLayout( bb );
769 void YQWizard::layoutClientArea( QWidget * parent )
771 _clientArea =
new QFrame( parent );
772 YUI_CHECK_NEW( _clientArea );
773 _clientArea->setObjectName(
"_clientArea");
774 QVBoxLayout *layout =
new QVBoxLayout( _clientArea );
775 layout->setMargin( 0 );
781 _contents =
new YQAlignment(
this, _clientArea, YAlignCenter, YAlignCenter );
782 YUI_CHECK_NEW( _contents );
783 layout->addWidget( _contents );
784 _contents->QObject::setProperty(
"class",
"Contents" );
786 _contents->setStretchable( YD_HORIZ,
true );
787 _contents->setStretchable( YD_VERT,
true );
788 _contents->installEventFilter(
this );
789 _contents->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
795 _contentsReplacePoint = YUI::widgetFactory()->createReplacePoint( _contents );
801 YUI::widgetFactory()->createEmpty( _contentsReplacePoint );
802 _contentsReplacePoint->showChild();
808 QLayout *YQWizard::layoutButtonBox( QWidget * parent )
814 QHBoxLayout * hbox =
new QHBoxLayout();
815 YUI_CHECK_NEW( hbox );
817 hbox->setSpacing( 0 );
818 hbox->setMargin( 0 );
821 _helpButton =
new QPushButton( _(
"Help" ), parent );
822 YUI_CHECK_NEW( _helpButton );
823 _helpButton->setShortcut( Qt::Key_F1 );
825 connect( _helpButton, SIGNAL( clicked() ),
828 hbox->addWidget( _helpButton );
830 hbox->addStretch( 10 );
836 _abortButton =
new YQWizardButton(
this, parent, _abortButtonLabel );
837 YUI_CHECK_NEW( _abortButton );
839 hbox->addWidget( (QWidget *) _abortButton->widgetRep() );
840 connect( _abortButton, SIGNAL( clicked() ),
843 hbox->addSpacing( 10 );
849 _backButton =
new YQWizardButton(
this, parent, _backButtonLabel );
850 YUI_CHECK_NEW( _backButton );
852 hbox->addWidget( (QWidget *) _backButton->widgetRep() );
853 connect( _backButton, SIGNAL( clicked() ),
856 if ( _backButton->
text().isEmpty() )
863 hbox->addSpacing( 5 );
865 _nextButton =
new YQWizardButton(
this, parent, _nextButtonLabel );
866 YUI_CHECK_NEW( _nextButton );
868 hbox->addWidget( (QWidget *) _nextButton->widgetRep() );
869 connect( _nextButton, SIGNAL( clicked() ),
891 if ( QString( signal ).contains(
"nextClicked()" ) )
893 yuiDebug() <<
"nextClicked connected, no longer directly sending button events" << std::endl;
894 _sendButtonEvents =
false;
901 if ( QString( signal ).contains(
"nextClicked()" ) )
903 yuiDebug() <<
"nextClicked disconnected, directly sending button events again" << std::endl;
904 _sendButtonEvents =
true;
913 if ( ! iconName.empty() )
915 QPixmap icon( iconName.c_str() );
918 yuiWarning() <<
"Couldn't load dialog icon \"" << iconName <<
"\"" << std::endl;
921 _dialogIcon->setPixmap( icon );
922 topLevelWidget()->setWindowIcon( icon );
927 _dialogIcon->clear();
928 topLevelWidget()->setWindowIcon( QIcon() );
936 QString title = fromUTF8( titleText.c_str() );
938 if ( !title.isEmpty() )
947 if ( _dialogHeading )
949 if ( ! headingText.empty() )
950 _dialogHeading->setText( fromUTF8( headingText ) );
952 _dialogHeading->clear();
958 if ( _dialogHeading )
960 QString label = _dialogHeading->text();
961 label = label.simplified();
963 if ( ! label.isEmpty() )
964 return toUTF8( label );
967 return "untitled YQWizard";
973 _qHelpText = fromUTF8( helpText );
974 _qHelpText.replace(
"&product;", fromUTF8( YUI::app()->productName() ) );
982 if ( _sendButtonEvents )
985 _direction = YQWizard::Backward;
993 if ( _sendButtonEvents )
1002 if ( _sendButtonEvents )
1005 _direction = YQWizard::Forward;
1016 _helpDlg->setHelpText( _qHelpText );
1022 _helpDlg->activateWindow();
1030 if ( ! _releaseNotesButtonId.empty() )
1032 yuiMilestone() <<
"Release Notes button clicked" << std::endl;
1040 if ( _sideBar && _stepsPanel )
1042 _sideBar->setCurrentWidget( _stepsPanel );
1049 if ( _sideBar && _treePanel )
1051 _sideBar->setCurrentWidget( _treePanel );
1057 const std::string &
id )
1061 QMenu * menu =
new QMenu( _menuBar );
1062 YUI_CHECK_NEW( menu );
1064 _menuIDs.insert( fromUTF8(
id ), menu );
1065 _menuBar->addMenu( menu );
1066 menu->setTitle( fromUTF8( text ) );
1068 connect( menu, SIGNAL( triggered ( QAction * ) ),
1077 const std::string & text,
1078 const std::string &
id )
1080 QMenu* parentMenu = _menuIDs[ fromUTF8( parentMenuID ) ];
1084 QMenu * menu =
new QMenu( _menuBar );
1085 YUI_CHECK_NEW( menu );
1087 _menuIDs.insert( fromUTF8(
id ), menu );
1090 connect( menu, SIGNAL( triggered ( QAction * ) ),
1095 yuiError() <<
"Can't find menu with ID " << parentMenuID << std::endl;
1101 const std::string & text,
1102 const std::string & idString )
1104 QMenu * parentMenu = _menuIDs[ fromUTF8( parentMenuID ) ];
1109 int id = _menuEntryIDs.size();
1112 action = parentMenu->addAction( fromUTF8( text ) );
1113 _menuEntryIDs[ action ] = idString ;
1118 yuiError() <<
"Can't find menu with ID " << parentMenuID << std::endl;
1125 QMenu * parentMenu = _menuIDs[ fromUTF8( parentMenuID ) ];
1129 parentMenu->addSeparator();
1133 yuiError() <<
"Can't find menu with ID " << parentMenuID << std::endl;
1145 _menuEntryIDs.clear();
1152 if ( _menuEntryIDs.contains( action ) )
1158 yuiError() <<
"Invalid menu ID " << std::endl;
1171 return sizeHint().width();
1177 return sizeHint().height();
1183 resize( newWidth, newHeight );
1189 QSize contentsRect = _clientArea->contentsRect().size();
1190 _contents->
setSize( contentsRect.width(), contentsRect.height() );
1195 if ( ev->type() == QEvent::Resize && obj == _contents )
1201 if ( ev->type() == QEvent::Resize && obj == _sideBar && main_wizard ==
this && _stepsPanel )
1207 return QWidget::eventFilter( obj, ev );
1213 button->setLabel( newLabel );
1214 YDialog::currentDialog()->checkShortcuts();
1218 if ( wizardButton ) {
1220 if ( newLabel.empty() )
1221 wizardButton->
hide();
1223 wizardButton->
show();
1232 if ( ! _releaseNotesButton )
1234 yuiError() <<
"NULL Release Notes button" << std::endl;
1236 if ( ! _stepsPanel )
1237 yuiError() <<
"This works only if there is a \"steps\" panel!" << std::endl;
1243 _releaseNotesButton->setText( fromUTF8( YShortcut::cleanShortcutString( label ) ) );
1244 _releaseNotesButtonId = id;
1246 _releaseNotesButton->show();
1252 if ( _releaseNotesButton && !_releaseNotesButton->isHidden() )
1253 _releaseNotesButton->hide();
1263 _helpButton->setText( _(
"Help" ) );
1267 _stepsButton->setText( _(
"Steps" ) );
1271 _treeButton->setText( _(
"Tree" ) );
1274 _helpDlg->retranslate();
1279 void YQWizard::Step::deleteLabels()
1281 delete _statusLabel;
1296 if ( !_statusLabel || !_nameLabel || _status == s )
1303 _statusLabel->setProperty(
"class",
"todo-step-status QLabel" );
1304 _nameLabel->setProperty (
"class",
"todo-step-name QLabel" );
1309 _statusLabel->setProperty(
"class",
"done-step-status QLabel" );
1310 _nameLabel->setProperty (
"class",
"done-step-name QLabel" );
1315 _statusLabel->setProperty(
"class",
"current-step-status QLabel" );
1316 _nameLabel->setProperty (
"class",
"current-step-name QLabel" );
1319 _statusLabel->style()->unpolish( _statusLabel );
1320 _statusLabel->style()->polish( _statusLabel );
1321 _nameLabel->style()->unpolish( _nameLabel );
1322 _nameLabel->style()->polish( _nameLabel );
1325 #include "YQWizard.moc"
virtual std::string currentTreeSelection()
virtual void setSortByInsertionSequence(bool sortByInsertionSequence)
virtual void setCurrentStep(const std::string &id)
virtual void setDialogIcon(const std::string &iconName)
void setSideBarWidth(int width)
virtual void deleteTreeItems()
void sendTreeEvent(QTreeWidgetItem *item)
virtual std::string debugLabel() const
virtual void setHelpText(const std::string &helpText)
virtual void setButtonLabel(YPushButton *button, const std::string &newLabel)
void releaseNotesClicked()
virtual void setSize(int newWidth, int newHeight)
void connectNotify(const char *signal)
virtual void deleteSteps()
QString applicationTitle()
virtual void showReleaseNotesButton(const std::string &label, const std::string &id)
virtual bool eventFilter(QObject *obj, QEvent *ev)
virtual void selectTreeItem(const std::string &id)
YQWizard(YWidget *parent, const std::string &backButtonLabel, const std::string &abortButtonLabel, const std::string &nextButtonLabel, YWizardMode wizardMode=YWizardMode_Standard)
void copySteps(YQWizard *wizard)
virtual void addStepHeading(const std::string &text)
void treeSelectionChanged()
virtual void setDialogHeading(const std::string &headingText)
void resizeVisibleChild()
virtual void setDialogTitle(const std::string &titleText)
virtual void addMenuEntry(const std::string &parentMenuID, const std::string &text, const std::string &id)
static YQMainWinDock * mainWinDock()
YQWizard::TreeItem * findTreeItem(const std::string &id)
virtual void hideReleaseNotesButton()
void sendEvent(YEvent *event)
virtual void retranslateInternalButtons()
virtual void addMenuSeparator(const std::string &parentMenuID)
virtual void addStep(const std::string &text, const std::string &id)
virtual void deleteMenus()
virtual void addSubMenu(const std::string &parentMenuID, const std::string &text, const std::string &id)
YQWizard::Step * findStep(const QString &id)
virtual int preferredHeight()
void sendEvent(const std::string &id)
virtual void addMenu(const std::string &text, const std::string &id)
QList< YQWizard::Step * > stepsList()
virtual void addTreeItem(const std::string &parentID, const std::string &text, const std::string &id)
void disconnectNotify(const char *signal)
void sendMenuEvent(QAction *action)
virtual int preferredWidth()
static void setTextdomain(const char *domain)
virtual void setSize(int newWidth, int newHeight)
virtual void updateSteps()