1 /*---------------------------------------------------------------------\
3 | __ __ ____ _____ ____ |
4 | \ \ / /_ _/ ___|_ _|___ \ |
5 | \ V / _` \___ \ | | __) | |
6 | | | (_| |___) || | / __/ |
7 | |_|\__,_|____/ |_| |_____| |
11 \----------------------------------------------------------------------/
15 Author: Stefan Hundhammer <sh@suse.de>
17 Textdomain "packages-qt"
23 #define y2log_component "qt-wizard"
24 #include <ycp/y2log.h>
25 #include "YCPValueWidgetID.h"
27 // For the command parser
31 #include <ycp/YCPBoolean.h>
32 #include <ycp/YCPCode.h>
33 #include <ycp/YCPInteger.h>
34 #include "ycp/YCPInteger.h"
35 #include <ycp/YCPList.h>
36 #include <ycp/YCPMap.h>
37 #include <ycp/YCPString.h>
38 #include <ycp/YCPSymbol.h>
39 #include <ycp/YCPTerm.h>
40 #include <ycp/YCPValue.h>
41 #include <ycp/YCPVoid.h>
42 #include <YShortcut.h>
50 #include <qmenudata.h>
51 #include <qobjectlist.h>
53 #include <qpopupmenu.h>
54 #include <qpushbutton.h>
56 #include <qtabwidget.h>
57 #include <qtextbrowser.h>
58 #include <qtoolbutton.h>
59 #include <qwidgetstack.h>
61 #include "QY2ListView.h"
66 #include "YQApplication.h"
68 #include "YQAlignment.h"
69 #include "YQReplacePoint.h"
72 #include "YQWizardButton.h"
73 #include "YQIconPool.h"
74 #include "YQWidgetFactory.h"
75 #include "YQSignalBlocker.h"
76 #include "QY2LayoutUtils.h"
82 #define PIXMAP_DIR THEMEDIR "/wizard/"
88 #define TEXTDOMAIN "packages-qt"
90 #define ENABLE_GRADIENTS 1
92 #define USE_SEPARATOR 1
94 #define WORK_AREA_TOP_MARGIN 10
97 # define WORK_AREA_BOTTOM_MARGIN 8
98 # define WORK_AREA_RIGHT_MARGIN 8
100 # define WORK_AREA_BOTTOM_MARGIN 8
101 # define WORK_AREA_RIGHT_MARGIN 6
104 #define BUTTON_BOX_TOP_MARGIN 10
106 #define SEPARATOR_MARGIN 6
107 #define STEPS_MARGIN 10
108 #define STEPS_SPACING 2
109 #define STEPS_HEADING_SPACING 8
110 #define MENU_BAR_MARGIN 8
112 #define USE_FIXED_STEP_FONTS 0
113 #define STEPS_FONT_FAMILY "Sans Serif"
114 #define STEPS_FONT_SIZE 11
115 #define STEPS_HEADING_FONT_SIZE 11
117 #define USE_ICON_ON_HELP_BUTTON 0
120 YQWizard::YQWizard( YWidget * parent,
121 YWidgetID * backButtonId, const string & backButtonLabel,
122 YWidgetID * abortButtonId, const string & abortButtonLabel,
123 YWidgetID * nextButtonId, const string & nextButtonLabel,
124 YWizardMode wizardMode )
125 : QVBox( (QWidget *) parent->widgetRep() )
127 backButtonId, backButtonLabel,
128 abortButtonId, abortButtonLabel,
129 nextButtonId, nextButtonLabel,
132 setWidgetRep( this );
134 _stepsEnabled = (wizardMode == YWizardMode_Steps);
135 _treeEnabled = (wizardMode == YWizardMode_Tree);
137 _verboseCommands = false;
138 _protectNextButton = false;
140 _direction = YQWizard::Forward;
149 _releaseNotesButton = 0;
161 _backButtonSpacer = 0;
164 _sendButtonEvents = true;
166 _stepsList.setAutoDelete( true );
167 _stepsIDs.setAutoDelete( false ); // Only for one of both!
169 YQUI::setTextdomain( TEXTDOMAIN );
177 loadGradientPixmaps();
189 if ( ! _titleBarGradientPixmap.isNull() )
191 layoutTitleBar( this );
195 QWidget * spacer = addVSpacing( this, WORK_AREA_TOP_MARGIN );
198 # if ENABLE_GRADIENTS
199 spacer->setPaletteBackgroundColor( _gradientTopColor );
203 QHBox * hBox = new QHBox( this );
204 YUI_CHECK_NEW( hBox );
206 layoutSideBar( hBox );
207 layoutWorkArea( hBox );
209 y2debug( "Constructor finished." );
214 YQWizard::~YQWizard()
221 void YQWizard::layoutTitleBar( QWidget * parent )
223 if ( ! highColorDisplay() ) // 8 bit display or worse?
225 // No colorful title bar, just a spacing to match the one at the bottom.
226 addVSpacing( parent, WORK_AREA_BOTTOM_MARGIN );
232 QHBox * titleBar = new QHBox( parent );
233 YUI_CHECK_NEW( titleBar );
236 setGradient( titleBar, _titleBarGradientPixmap );
239 titleBar->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); // hor/vert
245 QLabel * left = new QLabel( titleBar );
246 left->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
248 QPixmap leftLogo( PIXMAP_DIR "title-bar-left.png" );
250 if ( ! leftLogo.isNull() )
252 left->setPixmap( leftLogo );
253 left->setFixedSize( leftLogo.size() );
254 left->setBackgroundOrigin( QWidget::ParentOrigin );
259 // Center stretch space
262 addHStretch( titleBar );
269 QLabel * right = new QLabel( titleBar );
270 YUI_CHECK_NEW( right );
272 QPixmap rightLogo( PIXMAP_DIR "title-bar-right.png" );
274 if ( ! rightLogo.isNull() )
276 right->setPixmap( rightLogo );
277 right->setFixedSize( rightLogo.size() );
278 right->setBackgroundOrigin( QWidget::ParentOrigin );
284 void YQWizard::layoutSideBar( QWidget * parent )
286 _sideBar = new QWidgetStack( parent );
287 YUI_CHECK_NEW( _sideBar );
288 _sideBar->setMinimumWidth( YQUI::ui()->defaultSize( YD_HORIZ ) / 5 );
289 _sideBar->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) ); // hor/vert
290 _sideBar->setMargin( 0 );
300 else if ( _stepsEnabled )
309 void YQWizard::layoutStepsPanel()
311 _stepsPanel = new QVBox( _sideBar );
312 YUI_CHECK_NEW( _stepsPanel );
316 if ( ! _titleBarGradientPixmap.isNull() )
320 QLabel * topGradient = new QLabel( _stepsPanel );
321 CHECK_PTR( topGradient );
322 setGradient( topGradient, _topGradientPixmap );
329 _sideBar->addWidget( _stepsPanel );
331 _stepsBox = new QVBox( _stepsPanel );
332 YUI_CHECK_NEW( _stepsBox );
334 _stepsBox->setPaletteBackgroundColor( _gradientCenterColor );
336 _stepsBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred ) ); // hor/vert
338 QWidget * stretch = addVStretch( _stepsPanel );
339 YUI_CHECK_NEW( stretch );
341 stretch->setPaletteBackgroundColor( _gradientCenterColor );
345 // Steps panel bottom buttons ("Help", "Release Notes")
347 QLabel * helpButtonBox = new QLabel( _stepsPanel );
350 YUI_CHECK_NEW( helpButtonBox );
351 setGradient( helpButtonBox, _bottomGradientPixmap );
356 // Layouts for the buttons
358 QVBoxLayout * vbox = new QVBoxLayout( helpButtonBox, 0, 0 ); // parent, margin, spacing
359 YUI_CHECK_NEW( vbox );
360 vbox->addStretch( 99 );
363 QHBoxLayout * hbox = new QHBoxLayout( vbox, 0 ); // parent, spacing
364 hbox->addStretch( 99 );
366 _releaseNotesButton = new QPushButton( _( "Release Notes..." ), helpButtonBox );
367 hbox->addWidget( _releaseNotesButton );
370 connect( _releaseNotesButton, SIGNAL( clicked() ),
371 this, SLOT ( releaseNotesClicked() ) );
373 _releaseNotesButton->hide(); // hidden until showReleaseNotesButton() is called
375 hbox->addStretch( 99 );
376 vbox->addStretch( 99 );
378 hbox = new QHBoxLayout( vbox, 0 ); // parent, spacing
379 hbox->addStretch( 99 );
381 // Help button - intentionally without keyboard shortcut
382 _helpButton = new QPushButton( _( "Help" ), helpButtonBox );
383 YUI_CHECK_NEW( _helpButton );
385 hbox->addWidget( _helpButton );
386 hbox->addStretch( 99 );
388 connect( _helpButton, SIGNAL( clicked() ),
389 this, SLOT ( showHelp() ) );
391 #if USE_ICON_ON_HELP_BUTTON
392 QPixmap pixmap = QPixmap( PIXMAP_DIR "help-button.png" );
394 if ( ! pixmap.isNull() )
395 _helpButton->setPixmap( pixmap );
399 vbox->addSpacing( WORK_AREA_BOTTOM_MARGIN );
404 void YQWizard::addStep( const QString & text, const QString & id )
406 if ( _stepsIDs[ id ] )
408 y2error( "Step ID \"%s\" (\"%s\") already used for \"%s\"",
411 (const char *) _stepsIDs[ id ]->name() );
415 if ( _stepsList.last() && _stepsList.last()->name() == text )
417 // Consecutive steps with the same name will be shown as one single step.
419 // Since steps are always added at the end of the list, it is
420 // sufficient to check the last step of the list. If the texts are the
421 // same, the other with the same text needs to get another (additional)
422 // ID to make sure setCurrentStep() works as it should.
423 _stepsList.last()->addID( id );
427 _stepsList.append( new YQWizard::Step( text, id ) );
431 _stepsIDs.insert( id, _stepsList.last() );
436 void YQWizard::addStepHeading( const QString & text )
438 _stepsList.append( new YQWizard::StepHeading( text ) );
444 void YQWizard::updateSteps()
450 // Delete any previous step widgets
455 delete _stepsGrid->mainWidget();
461 // Create a new parent widget for the steps
464 QWidget * stepsParent = new QWidget( _stepsBox );
465 YUI_CHECK_NEW( stepsParent );
466 stepsParent->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ) ); // hor/vert
468 stepsParent->setPaletteBackgroundColor( _gradientCenterColor );
471 // Create a grid layout for the steps
473 _stepsGrid = new QGridLayout( stepsParent, // parent
474 _stepsList.count(), 4, // rows, cols
475 0, STEPS_SPACING ); // margin, spacing
476 YUI_CHECK_NEW( _stepsGrid );
478 const int statusCol = 1;
479 const int nameCol = 2;
481 _stepsGrid->setColStretch( 0, 99 ); // Left margin column - stretch
482 _stepsGrid->setColStretch( statusCol, 0 ); // Status column - don't stretch
483 _stepsGrid->setColStretch( nameCol, 0 ); // Name column - don't stretch
484 _stepsGrid->setColStretch( 3, 99 ); // Left margin column - stretch
487 // Work around Qt bug: Grid layout only works right if the parent widget isn't visible.
491 // Add left and right (but not top and bottom) margins
496 QWidget * leftSpacer = addHSpacing( stepsParent, STEPS_MARGIN );
497 YUI_CHECK_NEW( leftSpacer );
498 _stepsGrid->addWidget( leftSpacer, row, 0 );
500 QWidget * rightSpacer = addHSpacing( stepsParent, STEPS_MARGIN );
501 YUI_CHECK_NEW( rightSpacer );
502 _stepsGrid->addWidget( rightSpacer, row, 3 );
506 // Create widgets for all steps and step headings in the internal list
509 YQWizard::Step * step = _stepsList.first();
513 if ( step->isHeading() )
519 QWidget * spacer = addVSpacing( stepsParent, STEPS_HEADING_SPACING );
520 YUI_CHECK_NEW( spacer );
521 _stepsGrid->addWidget( spacer, row++, nameCol );
528 QLabel * label = new QLabel( step->name(), stepsParent );
529 YUI_CHECK_NEW( label );
530 label->setAlignment( Qt::AlignLeft | Qt::AlignTop );
532 #if USE_FIXED_STEP_FONTS
533 QFont font( STEPS_FONT_FAMILY, STEPS_HEADING_FONT_SIZE );
534 font.setWeight( QFont::Bold );
535 label->setFont( font );
537 QFont font = YQUI::yqApp()->currentFont();
539 int size = font.pointSize();
542 font.setPointSize( size + 2 );
544 font.setBold( true );
545 label->setFont( font );
548 step->setNameLabel( label );
549 _stepsGrid->addMultiCellWidget( label,
550 row, row, // from_row, to_row
551 statusCol, nameCol ); // from_col, to_col
553 else // No heading - ordinary step
559 QLabel * statusLabel = new QLabel( stepsParent );
560 YUI_CHECK_NEW( statusLabel );
562 step->setStatusLabel( statusLabel );
563 _stepsGrid->addWidget( statusLabel, row, statusCol );
570 QLabel * nameLabel = new QLabel( step->name(), stepsParent );
571 YUI_CHECK_NEW( nameLabel );
572 nameLabel->setAlignment( Qt::AlignLeft | Qt::AlignTop );
574 #if USE_FIXED_STEP_FONTS
575 nameLabel->setFont( QFont( STEPS_FONT_FAMILY, STEPS_FONT_SIZE ) );
577 nameLabel->setFont( YQUI::yqApp()->currentFont() );
580 step->setNameLabel( nameLabel );
581 _stepsGrid->addWidget( nameLabel, row, nameCol );
584 step = _stepsList.next();
588 _stepsGrid->activate();
594 void YQWizard::updateStepStates()
599 YQWizard::Step * currentStep = findStep( _currentStepID );
600 YQWizard::Step * step = _stepsList.first();
604 // Set status icon and color for the current step
605 setStepStatus( currentStep, _stepCurrentIcon, _stepCurrentColor );
609 // Set all steps before the current to "done"
612 while ( step && step != currentStep )
614 setStepStatus( step, _stepDoneIcon, _stepDoneColor );
615 step = _stepsList.next();
618 // Skip the current step - continue with the step after it
621 step = _stepsList.next();
625 // Set all steps after the current to "to do"
630 setStepStatus( step, _stepToDoIcon, _stepToDoColor );
631 step = _stepsList.next();
636 void YQWizard::setStepStatus( YQWizard::Step * step, const QPixmap & icon, const QColor & color )
640 if ( step->nameLabel() )
641 step->nameLabel()->setPaletteForegroundColor( color );
643 if ( step->statusLabel() )
644 step->statusLabel()->setPixmap( icon );
649 void YQWizard::setCurrentStep( const QString & id )
656 void YQWizard::deleteSteps()
663 YQWizard::Step * YQWizard::findStep( const QString & id )
668 return _stepsIDs[ id ];
672 void YQWizard::layoutHelpPanel()
674 _helpPanel = new QHBox( _sideBar );
675 YUI_CHECK_NEW( _helpPanel );
676 _sideBar->addWidget( _helpPanel );
678 addGradientColumn( _helpPanel );
680 QVBox * vbox = new QVBox( _helpPanel );
681 YUI_CHECK_NEW( vbox );
686 _helpBrowser = new QTextBrowser( vbox );
687 YUI_CHECK_NEW( _helpBrowser );
689 _helpBrowser->setMimeSourceFactory( 0 );
690 _helpBrowser->installEventFilter( this );
691 _helpBrowser->setTextFormat( Qt::RichText );
692 _helpBrowser->setMargin( 4 );
693 _helpBrowser->setResizePolicy( QScrollView::Manual );
696 // Set help browser text color
697 QPixmap fgPixmap = QPixmap( PIXMAP_DIR "help-text-color.png" );
698 if (! fgPixmap.isNull() )
699 _helpBrowser->setPaletteForegroundColor( pixelColor( fgPixmap, 0, 0, paletteForegroundColor() ) );
702 if ( highColorDisplay() )
704 // Set fancy help browser background pixmap
706 QPixmap bgPixmap( PIXMAP_DIR "help-background.png" );
708 if ( ! bgPixmap.isNull() )
709 _helpBrowser->setPaletteBackgroundPixmap( bgPixmap );
715 // Button box with bottom gradient
719 QLabel * buttonBox = new QLabel( vbox );
720 YUI_CHECK_NEW( buttonBox );
722 QPushButton * button;
727 // "Tree" button - intentionally without keyboard shortcut
728 button = new QPushButton( _( "Tree" ), buttonBox );
729 YUI_CHECK_NEW( button );
730 _treeButton = button;
732 #if USE_ICON_ON_HELP_BUTTON
733 pixmap = QPixmap( PIXMAP_DIR "tree-button.png" );
739 // "Steps" button - intentionally without keyboard shortcut
740 button = new QPushButton( _( "Steps" ), buttonBox );
741 YUI_CHECK_NEW( button );
742 _stepsButton = button;
744 #if USE_ICON_ON_HELP_BUTTON
745 pixmap = QPixmap( PIXMAP_DIR "steps-button.png" );
750 // Create a dummy button just to find out how high it would become
751 button = new QPushButton( "Dummy", buttonBox );
752 YUI_CHECK_NEW( button );
756 if ( ! pixmap.isNull() )
757 button->setPixmap( pixmap );
759 layoutSideBarButtonBox( buttonBox, button );
763 connect( button, SIGNAL( clicked() ),
764 this, SLOT ( showTree() ) );
766 else if ( _stepsEnabled )
768 connect( button, SIGNAL( clicked() ),
769 this, SLOT ( showSteps() ) );
773 // Hide the dummy button - the button box height is fixed now.
777 addGradientColumn( _helpPanel );
782 void YQWizard::layoutSideBarButtonBox( QWidget * parent, QPushButton * button )
784 QVBoxLayout * vbox = new QVBoxLayout( parent, 0, 0 ); // parent, margin, spacing
785 YUI_CHECK_NEW( vbox );
786 vbox->addSpacing( BUTTON_BOX_TOP_MARGIN );
788 QHBoxLayout * hbox = new QHBoxLayout( vbox, 0 ); // parent, spacing
789 YUI_CHECK_NEW( hbox );
791 hbox->addStretch( 99 );
792 hbox->addWidget( button );
793 hbox->addStretch( 99 );
795 vbox->addSpacing( WORK_AREA_BOTTOM_MARGIN );
797 // For whatever strange reason, parent->sizeHint() does not return anything
798 // meaningful yet - not even after vbox->activate() or parent->adjustSize()
799 int height = button->sizeHint().height() + BUTTON_BOX_TOP_MARGIN + WORK_AREA_BOTTOM_MARGIN;
802 if ( ! _bottomGradientPixmap.isNull() )
803 setBottomCroppedGradient( parent, _bottomGradientPixmap, height );
806 parent->setFixedHeight( height );
811 void YQWizard::layoutTreePanel()
813 _treePanel = new QHBox( _sideBar );
814 YUI_CHECK_NEW( _treePanel );
815 _sideBar->addWidget( _treePanel );
817 // Left margin (with gradients)
818 addGradientColumn( _treePanel );
820 QVBox * vbox = new QVBox( _treePanel );
821 YUI_CHECK_NEW( vbox );
826 _tree = new QY2ListView( vbox );
827 YUI_CHECK_NEW( _tree );
829 _tree->addColumn( "" );
830 _tree->header()->hide();
831 _tree->setRootIsDecorated( true );
832 _tree->setSortByInsertionSequence( true );
834 connect( _tree, SIGNAL( selectionChanged ( void ) ),
835 this, SLOT ( treeSelectionChanged ( void ) ) );
837 connect( _tree, SIGNAL( spacePressed ( QListViewItem * ) ),
838 this, SLOT ( sendTreeEvent ( QListViewItem * ) ) );
840 connect( _tree, SIGNAL( doubleClicked ( QListViewItem * ) ),
841 this, SLOT ( sendTreeEvent ( QListViewItem * ) ) );
846 QLabel * buttonBox = new QLabel( vbox );
847 YUI_CHECK_NEW( buttonBox );
850 // "Help" button - intentionally without keyboard shortcut
851 QPushButton * button = new QPushButton( _( "Help" ), buttonBox );
852 YUI_CHECK_NEW( button );
854 #if USE_ICON_ON_HELP_BUTTON
855 QPixmap pixmap( PIXMAP_DIR "help-button.png" );
857 if ( ! pixmap.isNull() )
858 button->setPixmap( pixmap );
861 layoutSideBarButtonBox( buttonBox, button );
863 connect( button, SIGNAL( clicked() ),
864 this, SLOT ( showHelp() ) );
867 // Right margin (with gradients)
868 addGradientColumn( _treePanel );
873 void YQWizard::addTreeItem( const QString & parentID, const QString & text, const QString & id )
877 y2error( "YQWizard widget not created with `opt(`treeEnabled) !" );
881 YQWizard::TreeItem * item = 0;
882 YQWizard::TreeItem * parent = 0;
884 if ( ! parentID.isEmpty() )
886 parent = findTreeItem( parentID );
891 item = new YQWizard::TreeItem( parent, text, id );
892 YUI_CHECK_NEW( item );
896 item = new YQWizard::TreeItem( _tree, text, id );
897 YUI_CHECK_NEW( item );
900 if ( ! id.isEmpty() )
901 _treeIDs.insert( id, item );
906 void YQWizard::deleteTreeItems()
916 YQWizard::TreeItem * YQWizard::findTreeItem( const QString & id )
921 return _treeIDs[ id ];
925 void YQWizard::selectTreeItem( const QString & id )
929 YQWizard::TreeItem * item = findTreeItem( id );
933 YQSignalBlocker sigBlocker( _tree );
935 _tree->setSelected( item, true );
936 _tree->ensureItemVisible( item );
942 void YQWizard::sendTreeEvent( QListViewItem * listViewItem )
946 YQWizard::TreeItem * item = dynamic_cast<YQWizard::TreeItem *> ( listViewItem );
948 if ( item && ! item->id().isEmpty() )
949 sendEvent( YCPString( toUTF8( item->id() ) ) );
954 void YQWizard::treeSelectionChanged()
957 sendTreeEvent( _tree->selectedItem() );
961 YCPString YQWizard::currentTreeSelection()
965 QListViewItem * sel = _tree->selectedItem();
969 YQWizard::TreeItem * item = dynamic_cast<YQWizard::TreeItem *> (sel);
971 if ( item && ! item->id().isEmpty() )
972 return YCPString( (const char *) item->id() );
976 return YCPString( "" );
982 void YQWizard::layoutWorkArea( QHBox * parentHBox )
984 QVBox * workAreaVBox = new QVBox( parentHBox );
985 YUI_CHECK_NEW( workAreaVBox );
987 // An extra QVBox inside the workAreaVBox is needed for frame and margin
989 QVBox * workArea = new QVBox( workAreaVBox );
990 YUI_CHECK_NEW( workArea );
993 workArea->setFrameStyle( QFrame::Box | QFrame::Plain );
994 workArea->setMargin( 4 );
996 workArea->setFrameStyle( QFrame::Box | QFrame::Sunken );
997 // workArea->setFrameStyle( QFrame::TabWidgetPanel | QFrame::Sunken );
1005 // Placed directly inside workArea the menu bar positions itself at (0,0)
1006 // and so obscures any kind of frame there might be.
1007 _menuBarBox = new QVBox( workArea );
1008 YUI_CHECK_NEW( _menuBarBox );
1010 _menuBar = new QMenuBar( _menuBarBox );
1011 YUI_CHECK_NEW( _menuBar );
1013 _menuBarBox->hide(); // will be made visible when menus are added
1017 // Dialog icon and heading
1020 QHBox * headingHBox = new QHBox( workArea );
1021 YUI_CHECK_NEW( headingHBox );
1022 headingHBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); // hor/vert
1024 addHSpacing( headingHBox, SEPARATOR_MARGIN );
1026 _dialogIcon = new QLabel( headingHBox );
1027 YUI_CHECK_NEW( _dialogIcon );
1028 _dialogIcon->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) ); // hor/vert
1030 addHSpacing( headingHBox );
1032 _dialogHeading = new QLabel( headingHBox );
1033 YUI_CHECK_NEW( _dialogHeading );
1034 _dialogHeading->setFont( YQUI::yqApp()->headingFont() );
1035 _dialogHeading->setAlignment( Qt::AlignLeft | Qt::WordBreak );
1036 _dialogHeading->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); // hor/vert
1039 addHStretch( headingHBox );
1041 addVSpacing( workArea );
1045 QHBox * hbox = new QHBox( workArea );
1047 addHSpacing( hbox, SEPARATOR_MARGIN );
1049 QFrame * separator = new QFrame( hbox );
1050 YUI_CHECK_NEW( separator );
1051 separator->setFrameStyle( QFrame::HLine | QFrame::Sunken );
1053 addHSpacing( hbox, SEPARATOR_MARGIN );
1054 addVSpacing( workArea );
1058 // Client area (the part that belongs to the YCP application)
1061 layoutClientArea( workArea );
1068 layoutButtonBox( workAreaVBox );
1072 // Spacer (purely decorative) at the right of the client area
1075 addGradientColumn( parentHBox, WORK_AREA_RIGHT_MARGIN );
1080 void YQWizard::layoutClientArea( QWidget * parent )
1082 _clientArea = new QVBox( parent );
1083 YUI_CHECK_NEW( _clientArea );
1084 _clientArea->setMargin( 4 );
1087 _clientArea->setPaletteBackgroundColor( QColor( 0x60, 0x60, 0x60 ) );
1092 // HVCenter for wizard contents
1095 _contents = new YQAlignment( this, _clientArea, YAlignCenter, YAlignCenter );
1096 YUI_CHECK_NEW( _contents );
1098 _contents->setStretchable( YD_HORIZ, true );
1099 _contents->setStretchable( YD_VERT, true );
1100 _contents->installEventFilter( this );
1101 _contents->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); // hor/vert
1105 // Replace point for wizard contents
1108 YReplacePoint * replacePoint = YUI::widgetFactory()->createReplacePoint( _contents );
1109 replacePoint->setId( new YCPValueWidgetID( YCPSymbol( YWizardContentsReplacePointID ) ) ); // `id(`contents)
1113 // Initial YEmpty widget contents of replace point
1116 YUI::widgetFactory()->createEmpty( replacePoint );
1117 replacePoint->showChild();
1122 void YQWizard::layoutButtonBox( QWidget * parent )
1125 // Button box and layout
1128 QWidget * buttonBox = new QWidget( parent );
1129 YUI_CHECK_NEW( buttonBox );
1131 // Using old-style layouts to enable a seamless background with the
1132 // gradient pixmap: Any sub-widgets (QVBox, QHBox) would have to get yet
1133 // another portion of that gradient as their backround pixmap, and it would
1134 // be very hard to cover all cases - resizing, hiding individual buttons, etc.
1136 QVBoxLayout * vbox = new QVBoxLayout( buttonBox, 0, 0 ); // parent, margin, spacing
1137 YUI_CHECK_NEW( vbox );
1139 vbox->addSpacing( BUTTON_BOX_TOP_MARGIN );
1143 // QHBoxLayout for the buttons
1146 QHBoxLayout * hbox = new QHBoxLayout( vbox, 2 ); // parent, spacing
1147 YUI_CHECK_NEW( hbox );
1154 _backButton = new YQWizardButton( this, buttonBox, backButtonLabel(), backButtonId() );
1155 YUI_CHECK_NEW( _backButton );
1157 hbox->addWidget( (QWidget *) _backButton->widgetRep() );
1158 connect( _backButton, SIGNAL( clicked() ),
1159 this, SLOT ( slotBackClicked() ) );
1161 _backButtonSpacer = new QSpacerItem( 0, 0, // width, height
1162 QSizePolicy::Expanding, // horizontal
1163 QSizePolicy::Minimum ); // vertical
1164 YUI_CHECK_NEW( _backButtonSpacer );
1165 hbox->addItem( _backButtonSpacer );
1168 if ( _backButton->text().isEmpty() )
1170 _backButton->hide();
1172 // Minimize _backButtonSpacer
1173 _backButtonSpacer->changeSize( 0, 0, // width, height
1174 QSizePolicy::Minimum, // horizontal
1175 QSizePolicy::Minimum ); // vertical
1183 _abortButton = new YQWizardButton( this, buttonBox, abortButtonLabel(), abortButtonId() );
1184 YUI_CHECK_NEW( _abortButton );
1186 hbox->addWidget( (QWidget *) _abortButton->widgetRep() );
1187 connect( _abortButton, SIGNAL( clicked() ),
1188 this, SLOT ( slotAbortClicked() ) );
1191 // Using spacer rather than addSpacing() since the default stretchability
1192 // of a QSpacerItem is undefined, i.e. centering the middle button could
1193 // not be guaranteed.
1195 QSpacerItem * spacer = new QSpacerItem( 0, 0, // width, height
1196 QSizePolicy::Expanding, // horizontal
1197 QSizePolicy::Minimum ); // vertical
1198 YUI_CHECK_NEW( spacer );
1199 hbox->addItem( spacer );
1206 _nextButton = new YQWizardButton( this, buttonBox, nextButtonLabel(), nextButtonId() );
1207 YUI_CHECK_NEW( _nextButton );
1209 hbox->addWidget( (QWidget *) _nextButton->widgetRep() );
1210 connect( _nextButton, SIGNAL( clicked() ),
1211 this, SLOT ( slotNextClicked() ) );
1215 // Bottom margin and gradient
1218 vbox->addSpacing( WORK_AREA_BOTTOM_MARGIN );
1220 #if ENABLE_GRADIENTS
1221 setBottomCroppedGradient( buttonBox, _bottomGradientPixmap, buttonBox->sizeHint().height() );
1224 buttonBox->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Fixed ) ); // hor/vert
1229 void YQWizard::loadGradientPixmaps()
1231 #if ENABLE_GRADIENTS
1232 if ( highColorDisplay() )
1234 _topGradientPixmap = QPixmap( PIXMAP_DIR "top-gradient.png" );
1235 _bottomGradientPixmap = QPixmap( PIXMAP_DIR "bottom-gradient.png" );
1236 _titleBarGradientPixmap = QPixmap( PIXMAP_DIR "title-bar-gradient.png" );
1237 _gradientCenterColor = pixelColor( _bottomGradientPixmap, 0, 0, paletteBackgroundColor() );
1238 _gradientTopColor = pixelColor( _topGradientPixmap, 0, 0 , paletteBackgroundColor() );
1240 else // 8 bit display or worse - don't use gradients
1242 // Gradient pixmaps remain empty. The respecive widgets will retain the
1243 // default widget background (grey, depending on the widget theme).
1245 // Use deault widget background (some shade of grey) for the center
1246 // stretchable part of the side bar.
1247 _gradientCenterColor = paletteBackgroundColor();
1248 _gradientTopColor = paletteBackgroundColor();
1254 void YQWizard::loadStepsIcons()
1256 _stepCurrentIcon = YQIconPool::stepCurrent();
1257 _stepToDoIcon = YQIconPool::stepToDo();
1258 _stepDoneIcon = YQIconPool::stepDone();
1260 if ( highColorDisplay() )
1262 _stepCurrentColor = pixelColor( QPixmap( PIXMAP_DIR "color-step-current.png" ), 0, 0, paletteForegroundColor() );
1263 _stepToDoColor = pixelColor( QPixmap( PIXMAP_DIR "color-step-todo.png" ), 0, 0, paletteForegroundColor() );
1264 _stepDoneColor = pixelColor( QPixmap( PIXMAP_DIR "color-step-done.png" ), 0, 0, paletteForegroundColor() );
1268 _stepCurrentColor = paletteForegroundColor();
1269 _stepToDoColor = paletteForegroundColor();
1270 _stepDoneColor = paletteForegroundColor();
1276 void YQWizard::setGradient( QWidget * widget, const QPixmap & pixmap )
1278 #if ENABLE_GRADIENTS
1279 if ( widget && ! pixmap.isNull() )
1281 widget->setFixedHeight( pixmap.height() );
1282 widget->setPaletteBackgroundPixmap( pixmap );
1289 void YQWizard::setBottomCroppedGradient( QWidget * widget, const QPixmap & pixmap, int croppedHeight )
1291 #if ENABLE_GRADIENTS
1292 setGradient( widget, bottomCropPixmap( pixmap, croppedHeight ) );
1298 QPixmap YQWizard::bottomCropPixmap( const QPixmap & full, int croppedHeight )
1302 #if ENABLE_GRADIENTS
1304 if ( full.height() > croppedHeight )
1306 pixmap = QPixmap( full.width(), croppedHeight );
1308 bitBlt( &pixmap, 0, 0, // dest, dest_x, dest_y
1309 &full, 0, full.height() - croppedHeight - 1, // src, src_x, src_y
1310 full.width(), croppedHeight ); // src_width, src_height
1323 QColor YQWizard::pixelColor( const QPixmap & pixmap, int x, int y, const QColor & defaultColor )
1325 if ( pixmap.isNull() )
1326 return defaultColor;
1328 // QPixmap doesn't allow direct access to pixel values (which makes some
1329 // sense since this requires a round-trip to the X server - pixmaps are X
1330 // server resources), so we need to convert the QPixmap to a QImage to get
1331 // that information. But since this conversion is expensive, we might save
1332 // some performance if we only convert the part we really need - so let's
1333 // cut out a tiny portion of the original pixmap and convert only that tiny
1337 QPixmap tiny( 1, 1 );
1339 bitBlt( &tiny, 0, 0, // dest, dest_x, dest_y
1340 &pixmap, x, y, // src, src_x, src_y
1341 1, 1 ); // src_width, src_height
1343 QImage image = tiny.convertToImage();
1346 return QColor( image.pixel( 0, 0 ) );
1351 void YQWizard::addGradientColumn( QWidget * parent, int width )
1356 QVBox * vbox = new QVBox( parent );
1357 YUI_CHECK_NEW( vbox );
1359 #if ENABLE_GRADIENTS
1360 QWidget * topGradient = addHSpacing( vbox, width );
1361 YUI_CHECK_NEW( topGradient );
1362 setGradient( topGradient, _topGradientPixmap );
1364 QWidget * centerStretch = new QWidget( vbox );
1365 YUI_CHECK_NEW( centerStretch );
1366 centerStretch->setPaletteBackgroundColor( _gradientCenterColor );
1369 QWidget * bottomGradient = new QWidget( vbox );
1370 YUI_CHECK_NEW( bottomGradient );
1371 setGradient( bottomGradient, _bottomGradientPixmap );
1373 vbox->setFixedWidth( width );
1379 void YQWizard::destroyButtons()
1389 delete _abortButton;
1402 bool YQWizard::highColorDisplay() const
1404 return QColor::numBitPlanes() > 8;
1408 void YQWizard::connectNotify ( const char * signal )
1410 if ( QString( signal ).contains( "nextClicked()" ) )
1412 y2debug( "nextClicked connected, no longer directly sending button events" );
1413 _sendButtonEvents = false;
1418 void YQWizard::disconnectNotify ( const char * signal )
1420 if ( QString( signal ).contains( "nextClicked()" ) )
1422 y2debug( "nextClicked disconnected, directly sending button events again" );
1423 _sendButtonEvents = true;
1428 void YQWizard::setDialogIcon( const char * iconName )
1432 if ( iconName && *iconName )
1434 QPixmap icon( iconName );
1436 if ( icon.isNull() )
1437 y2warning( "Couldn't load dialog icon \"%s\"", iconName );
1440 _dialogIcon->setPixmap( icon );
1441 topLevelWidget()->setIcon( icon );
1446 _dialogIcon->clear();
1447 topLevelWidget()->setIcon( QPixmap() );
1453 void YQWizard::setDialogHeading( const QString & headingText )
1455 if ( _dialogHeading )
1458 _dialogHeading->setText( headingText );
1460 _dialogHeading->clear();
1464 string YQWizard::debugLabel()
1466 if ( _dialogHeading )
1468 QString label = _dialogHeading->text();
1469 label.simplifyWhiteSpace(); // Replace any embedded newline with a single blank
1471 if ( ! label.isEmpty() )
1473 label.prepend( "YQWizard \"" );
1474 label.append( "\"" );
1476 return toUTF8( label );
1480 return "untitled YQWizard";
1483 void YQWizard::setHelpText( QString helpText )
1489 helpText.replace( "&product;", YQUI::ui()->productName() );
1490 _helpBrowser->setText( helpText );
1493 _helpBrowser->clear();
1498 void YQWizard::slotBackClicked()
1502 if ( _sendButtonEvents )
1503 sendEvent( _backButton->id() );
1505 _direction = YQWizard::Backward;
1509 void YQWizard::slotAbortClicked()
1511 emit abortClicked();
1513 if ( _sendButtonEvents )
1514 sendEvent( _abortButton->id() );
1518 void YQWizard::slotNextClicked()
1522 if ( _sendButtonEvents )
1523 sendEvent( _nextButton->id() );
1525 _direction = YQWizard::Forward;
1529 void YQWizard::showHelp()
1531 if ( _sideBar && _helpPanel )
1533 _sideBar->raiseWidget( _helpPanel );
1538 void YQWizard::releaseNotesClicked()
1540 if ( ! _releaseNotesButtonId.isNull() )
1542 y2milestone( "Release Notes button clicked" );
1543 sendEvent( _releaseNotesButtonId );
1548 void YQWizard::showSteps()
1550 if ( _sideBar && _stepsPanel )
1552 _sideBar->raiseWidget( _stepsPanel );
1557 void YQWizard::showTree()
1559 if ( _sideBar && _treePanel )
1561 _sideBar->raiseWidget( _treePanel );
1567 void YQWizard::addMenu( const QString & text,
1568 const QString & id )
1572 QPopupMenu * menu = new QPopupMenu( _menuBar );
1573 YUI_CHECK_NEW( menu );
1575 _menuIDs.insert( id, menu );
1576 _menuBar->insertItem( text, menu );
1578 connect( menu, SIGNAL( activated ( int ) ),
1579 this, SLOT ( sendMenuEvent( int ) ) );
1581 if ( _menuBarBox && _menuBarBox->isHidden() )
1583 _menuBarBox->show();
1584 _menuBarBox->setFixedHeight( _menuBar->sizeHint().height() + MENU_BAR_MARGIN );
1590 void YQWizard::addSubMenu( const QString & parentMenuID,
1591 const QString & text,
1592 const QString & id )
1594 QPopupMenu * parentMenu = _menuIDs[ parentMenuID ];
1598 QPopupMenu * menu = new QPopupMenu( _menuBar );
1599 YUI_CHECK_NEW( menu );
1601 _menuIDs.insert( id, menu );
1602 parentMenu->insertItem( text, menu );
1604 connect( menu, SIGNAL( activated ( int ) ),
1605 this, SLOT ( sendMenuEvent( int ) ) );
1609 y2error( "Can't find menu with ID %s", (const char *) parentMenuID );
1614 void YQWizard::addMenuEntry( const QString & parentMenuID,
1615 const QString & text,
1616 const QString & idString )
1618 QPopupMenu * parentMenu = _menuIDs[ parentMenuID ];
1622 int id = _menuEntryIDs.size();
1623 _menuEntryIDs.push_back( idString );
1624 parentMenu->insertItem( text, id );
1628 y2error( "Can't find menu with ID %s", (const char *) parentMenuID );
1633 void YQWizard::addMenuSeparator( const QString & parentMenuID )
1635 QPopupMenu * parentMenu = _menuIDs[ parentMenuID ];
1639 parentMenu->insertSeparator();
1643 y2error( "Can't find menu with ID %s", (const char *) parentMenuID );
1648 void YQWizard::deleteMenus()
1652 _menuBarBox->hide();
1655 _menuEntryIDs.clear();
1660 void YQWizard::sendMenuEvent( int numID )
1662 if ( numID >= 0 && numID < (int) _menuEntryIDs.size() )
1664 sendEvent( YCPString( toUTF8( _menuEntryIDs[ numID ] ) ) );
1668 y2error( "Invalid menu ID: %d", numID );
1673 void YQWizard::sendEvent( YWidgetID * rawId )
1677 YCPValueWidgetID * id = dynamic_cast<YCPValueWidgetID *> (rawId );
1680 sendEvent( id->value() );
1685 void YQWizard::sendEvent( YCPValue id )
1687 // Wizard events are sent as menu events - the semantics are similar.
1689 // Widget events wouldn't do since they use their widget's ID as the ID to
1690 // return (which would be inappropriate since that would be the ID of the
1691 // wizard widget). Another type of event (WizardEvent) could be introduced,
1692 // but it would add little more information (if any) than MenuEvent.
1694 // YQPackageSelector uses the same approach. After all, one widget that can
1695 // return multiple IDs is roughly the semantics of MenuEvents.
1697 YQUI::ui()->sendEvent( new YMenuEvent( id ) );
1702 int YQWizard::preferredWidth()
1704 return sizeHint().width();
1708 int YQWizard::preferredHeight()
1710 return sizeHint().height();
1714 void YQWizard::setSize( int newWidth, int newHeight )
1716 resize( newWidth, newHeight );
1722 void YQWizard::resizeClientArea()
1724 // y2debug( "resizing client area" );
1725 QRect contentsRect = _clientArea->contentsRect();
1726 _contents->setSize( contentsRect.width(), contentsRect.height() );
1731 bool YQWizard::eventFilter( QObject * obj, QEvent * ev )
1733 if ( ev->type() == QEvent::Resize && obj == _contents )
1736 return true; // Event handled
1739 return QWidget::eventFilter( obj, ev );
1743 void YQWizard::setButtonLabel( YQWizardButton * button, const QString & newLabel )
1747 button->setLabel( newLabel );
1748 YDialog::currentDialog()->checkShortcuts();
1750 if ( newLabel.isEmpty() )
1754 if ( button == _backButton && _backButtonSpacer )
1756 // Minimize _backButtonSpacer
1758 _backButtonSpacer->changeSize( 0, 0, // width, height
1759 QSizePolicy::Minimum, // horizontal
1760 QSizePolicy::Minimum ); // vertical
1767 if ( button == _backButton && _backButtonSpacer )
1769 // Restore _backButtonSpacer to normal size
1771 _backButtonSpacer->changeSize( 0, 0, // width, height
1772 QSizePolicy::Expanding, // horizontal
1773 QSizePolicy::Minimum ); // vertical
1780 void YQWizard::setButtonID( YQWizardButton * button, const YCPValue & id )
1784 button->setId( new YCPValueWidgetID( id ) );
1789 void YQWizard::enableButton( YQWizardButton * button, bool enabled )
1791 if ( button == _nextButton && _protectNextButton && ! enabled )
1795 button->setEnabled( enabled );
1799 void YQWizard::setButtonFocus( YQWizardButton * button )
1802 button->setKeyboardFocus();
1806 void YQWizard::showReleaseNotesButton( string label, const YCPValue & id )
1808 if ( ! _releaseNotesButton )
1810 y2error( "NULL Release Notes button" );
1812 y2error( "This works only if there is a \"steps\" panel!" );
1817 label = YShortcut::cleanShortcutString( label ); // no way to check the shortcut, so strip it
1818 _releaseNotesButton->setText( fromUTF8( label ) );
1819 _releaseNotesButtonId = id;
1822 if ( _releaseNotesButton->isHidden() )
1823 _releaseNotesButton->show();
1828 void YQWizard::hideReleaseNotesButton()
1830 if ( _releaseNotesButton && _releaseNotesButton->isShown() )
1831 _releaseNotesButton->hide();
1835 void YQWizard::retranslateInternalButtons()
1837 YQUI::setTextdomain( TEXTDOMAIN );
1840 // "Help" button - intentionally without keyboard shortcut
1841 _helpButton->setText( _( "Help" ) );
1844 // "Steps" button - intentionally without keyboard shortcut
1845 _stepsButton->setText( _( "Steps" ) );
1848 // "Tree" button - intentionally without keyboard shortcut
1849 _treeButton->setText( _( "Tree" ) );
1853 void YQWizard::ping()
1855 y2debug( "YQWizard is active" );
1859 bool YQWizard::isCommand( QString declaration, const YCPTerm & term )
1861 declaration = declaration.simplifyWhiteSpace();
1863 // Check command name
1865 QString command = declaration;
1866 command.remove( QRegExp( "\\s*\\(.*$" ) ); // remove arguments
1868 if ( term->name().c_str() != command )
1875 QString arg_decl = declaration;
1876 arg_decl.remove( QRegExp( "^.*\\(" ) ); // remove "command ("
1877 arg_decl.remove( QRegExp( "\\).*$" ) ); // remove ")"
1879 QStringList argDeclList = QStringList::split( ",", arg_decl );
1882 // Check number of arguments
1885 if ( argDeclList.size() != (unsigned) term->size() )
1887 y2error( "Bad arguments for wizard command %s : %s",
1888 (const char *) declaration, term->toString().c_str() );
1894 // Check each individual argument
1899 for ( unsigned i=0; i < argDeclList.size() && ok; i++ )
1901 QString wanted = argDeclList[ i ].stripWhiteSpace();
1902 YCPValue seen = term->value( i );
1904 if ( wanted == "string" ) ok = seen->isString();
1905 else if ( wanted == "boolean" ) ok = seen->isBoolean();
1906 else if ( wanted == "bool" ) ok = seen->isBoolean();
1907 else if ( wanted == "list" ) ok = seen->isList();
1908 else if ( wanted == "map" ) ok = seen->isMap();
1909 else if ( wanted == "integer" ) ok = seen->isInteger();
1910 else if ( wanted == "int" ) ok = seen->isInteger();
1911 else if ( wanted == "any" ) ok = true;
1914 y2error( "Bad declaration for wizard command %s : Unknown type \"%s\"",
1915 (const char *) declaration, (const char *) wanted );
1921 y2error( "Bad arguments for wizard command %s : %s",
1922 (const char *) declaration, term->toString().c_str() );
1925 if ( ok && _verboseCommands )
1927 // Intentionally logging as milestone because a YCP app just explicitly
1928 // requested this log level
1929 y2milestone( "Recognized wizard command %s : %s",
1930 (const char *) declaration, term->toString().c_str() );
1937 QString YQWizard::qStringArg( const YCPTerm & term, int argNo )
1939 return fromUTF8( stringArg( term, argNo ).c_str() );
1943 string YQWizard::stringArg( const YCPTerm & term, int argNo )
1945 if ( term->size() > argNo )
1947 YCPValue arg( term->value( argNo ) );
1949 if ( arg->isString() )
1950 return arg->asString()->value();
1953 y2error( "Couldn't convert arg #%d of '%s' to string", argNo, term->toString().c_str() );
1958 bool YQWizard::boolArg( const YCPTerm & term, int argNo )
1960 if ( term->size() > argNo )
1962 YCPValue arg( term->value( argNo ) );
1964 if ( arg->isBoolean() )
1965 return arg->asBoolean()->value();
1968 y2error( "Couldn't convert arg #%d of '%s' to bool", argNo, term->toString().c_str() );
1973 YCPValue YQWizard::anyArg( const YCPTerm & term, int argNo )
1975 if ( term->size() > argNo )
1977 return term->value( argNo );
1985 YCPValue YQWizard::command( const YCPTerm & cmd )
1987 #define OK YCPBoolean( true );
1990 if ( isCommand( "SetHelpText ( string )", cmd ) ) { setHelpText ( qStringArg( cmd, 0 ) ); return OK; }
1991 if ( isCommand( "SetDialogIcon ( string )", cmd ) ) { setDialogIcon ( qStringArg( cmd, 0 ) ); return OK; }
1992 if ( isCommand( "SetDialogHeading ( string )", cmd ) ) { setDialogHeading( qStringArg( cmd, 0 ) ); return OK; }
1994 if ( isCommand( "SetCurrentStep ( string )", cmd ) ) { setCurrentStep( qStringArg( cmd, 0 ) ); return OK; }
1995 if ( isCommand( "AddStep ( string, string )" , cmd ) ) { addStep( qStringArg( cmd, 0 ), qStringArg( cmd, 1 )); return OK; }
1996 if ( isCommand( "AddStepHeading ( string )", cmd ) ) { addStepHeading( qStringArg( cmd, 0 ) ); return OK; }
1997 if ( isCommand( "DeleteSteps()" , cmd ) ) { deleteSteps(); return OK; }
1998 if ( isCommand( "UpdateSteps()" , cmd ) ) { updateSteps(); return OK; }
2000 if ( isCommand( "SetAbortButtonLabel ( string )", cmd ) ) { setButtonLabel( _abortButton, qStringArg( cmd, 0 ) ); return OK; }
2001 if ( isCommand( "SetBackButtonLabel ( string )", cmd ) ) { setButtonLabel( _backButton, qStringArg( cmd, 0 ) ); return OK; }
2002 if ( isCommand( "SetNextButtonLabel ( string )", cmd ) ) { setButtonLabel( _nextButton, qStringArg( cmd, 0 ) ); return OK; }
2003 if ( isCommand( "SetCancelButtonLabel ( string )", cmd ) ) { setButtonLabel( _abortButton, qStringArg( cmd, 0 ) ); return OK; }
2004 if ( isCommand( "SetAcceptButtonLabel ( string )", cmd ) ) { setButtonLabel( _nextButton, qStringArg( cmd, 0 ) ); return OK; }
2006 if ( isCommand( "SetAbortButtonID ( any )" , cmd ) ) { setButtonID( _abortButton, anyArg( cmd, 0 ) ); return OK; }
2007 if ( isCommand( "SetBackButtonID ( any )" , cmd ) ) { setButtonID( _backButton, anyArg( cmd, 0 ) ); return OK; }
2008 if ( isCommand( "SetNextButtonID ( any )" , cmd ) ) { setButtonID( _nextButton, anyArg( cmd, 0 ) ); return OK; }
2010 if ( isCommand( "EnableBackButton ( bool )" , cmd ) ) { enableButton( _backButton, boolArg( cmd, 0 ) ); return OK; }
2011 if ( isCommand( "EnableNextButton ( bool )" , cmd ) ) { enableButton( _nextButton, boolArg( cmd, 0 ) ); return OK; }
2012 if ( isCommand( "EnableAbortButton ( bool )" , cmd ) ) { enableButton( _abortButton, boolArg( cmd, 0 ) ); return OK; }
2013 if ( isCommand( "ProtectNextButton ( bool )" , cmd ) ) { _protectNextButton = boolArg( cmd, 0 ); return OK; }
2015 if ( isCommand( "SetFocusToNextButton ()" , cmd ) ) { setButtonFocus( _nextButton ); return OK; }
2016 if ( isCommand( "SetFocusToBackButton ()" , cmd ) ) { setButtonFocus( _backButton ); return OK; }
2019 if ( isCommand( "SetVerboseCommands ( bool )" , cmd ) ) { setVerboseCommands( boolArg( cmd, 0 ) ); return OK; }
2021 if ( isCommand( "DeleteTreeItems()" , cmd ) ) { deleteTreeItems(); return OK; }
2022 if ( isCommand( "SelectTreeItem( string )" , cmd ) ) { selectTreeItem( qStringArg( cmd, 0 ) ); return OK; }
2023 if ( isCommand( "AddTreeItem( string, string, string )", cmd ) ) { addTreeItem ( qStringArg( cmd, 0 ),
2024 qStringArg( cmd, 1 ),
2025 qStringArg( cmd, 2 ) ); return OK; }
2027 if ( isCommand( "AddMenu ( string, string )" , cmd ) ) { addMenu ( qStringArg( cmd, 0 ),
2028 qStringArg( cmd, 1 ) ); return OK; }
2030 if ( isCommand( "AddSubMenu ( string, string, string )" , cmd ) ) { addSubMenu ( qStringArg( cmd, 0 ),
2031 qStringArg( cmd, 1 ),
2032 qStringArg( cmd, 2 ) ); return OK; }
2034 if ( isCommand( "AddMenuEntry ( string, string, string )" , cmd ) ) { addMenuEntry ( qStringArg( cmd, 0 ),
2035 qStringArg( cmd, 1 ),
2036 qStringArg( cmd, 2 ) ); return OK; }
2038 if ( isCommand( "AddMenuSeparator ( string )" , cmd ) ) { addMenuSeparator( qStringArg( cmd, 0 ) ); return OK; }
2039 if ( isCommand( "DeleteMenus ()" , cmd ) ) { deleteMenus(); return OK; }
2040 if ( isCommand( "ShowReleaseNotesButton( string, any )" , cmd ) ) { showReleaseNotesButton( stringArg( cmd, 0 ),
2041 anyArg ( cmd, 1 )); return OK; }
2042 if ( isCommand( "HideReleaseNotesButton()" , cmd ) ) { hideReleaseNotesButton(); return OK; }
2043 if ( isCommand( "RetranslateInternalButtons()" , cmd ) ) { retranslateInternalButtons() ; return OK; }
2044 if ( isCommand( "Ping()" , cmd ) ) { ping() ; return OK; }
2045 y2error( "Undefined wizard command: %s", cmd->toString().c_str() );
2046 return YCPBoolean( false );
2053 #include "YQWizard.moc"