libyui-qt  2.44.0
 All Classes Functions Variables
YQWizard.cc
1 /*
2  Copyright (C) 2000-2012 Novell, Inc
3  This library is free software; you can redistribute it and/or modify
4  it under the terms of the GNU Lesser General Public License as
5  published by the Free Software Foundation; either version 2.1 of the
6  License, or (at your option) version 3.0 of the License. This library
7  is distributed in the hope that it will be useful, but WITHOUT ANY
8  WARRANTY; without even the implied warranty of MERCHANTABILITY or
9  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10  License for more details. You should have received a copy of the GNU
11  Lesser General Public License along with this library; if not, write
12  to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
13  Floor, Boston, MA 02110-1301 USA
14 */
15 
16 
17 /*-/
18 
19  File: YQWizard.cc
20 
21  Author: Stefan Hundhammer <sh@suse.de>
22 
23  Textdomain "qt"
24 
25 /-*/
26 
27 #include "YQWizard.h"
28 #define YUILogComponent "qt-wizard"
29 #include <yui/YUILog.h>
30 
31 #include <string>
32 #include <yui/YShortcut.h>
33 
34 #include <QDialog>
35 #include <QSvgRenderer>
36 #include <QPainter>
37 #include <QStackedWidget>
38 #include <qimage.h>
39 #include <qlabel.h>
40 #include <qlayout.h>
41 #include <qmenubar.h>
42 #include <qmenudata.h>
43 #include <qobject.h>
44 #include <qpixmap.h>
45 #include <qpushbutton.h>
46 #include <qregexp.h>
47 #include <qtabwidget.h>
48 #include <qtoolbutton.h>
49 #include <QGraphicsDropShadowEffect>
50 
51 #include "QY2ListView.h"
52 #include "QY2Styler.h"
53 #include "QY2HelpDialog.h"
54 #include <QGridLayout>
55 #include <QHeaderView>
56 #include <qevent.h>
57 
58 #include "utf8.h"
59 #include "YQi18n.h"
60 #include "YQUI.h"
61 #include "YQApplication.h"
62 #include "YQDialog.h"
63 #include "YQAlignment.h"
64 #include "YQReplacePoint.h"
65 #include "YQEmpty.h"
66 #include "YQLabel.h"
67 #include "YQWizardButton.h"
68 #include "YQWidgetFactory.h"
69 #include "YQSignalBlocker.h"
70 #include <yui/YEvent.h>
71 #include "YQMainWinDock.h"
72 
73 
74 using std::string;
75 
76 #ifdef TEXTDOMAIN
77 # undef TEXTDOMAIN
78 #endif
79 
80 #define TEXTDOMAIN "qt"
81 
82 #define USE_ICON_ON_HELP_BUTTON 0
83 
84 YQWizard *YQWizard::main_wizard = 0;
85 
86 YQWizard::YQWizard( YWidget * parent,
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() )
92 
93  , YWizard( parent,
94  backButtonLabel,
95  abortButtonLabel,
96  nextButtonLabel,
97  wizardMode )
98  , _backButtonLabel( backButtonLabel )
99  , _abortButtonLabel( abortButtonLabel )
100  , _nextButtonLabel( nextButtonLabel )
101  , _helpDlg ( NULL )
102 {
103  setObjectName( "wizard" );
104  setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
105 
106  QHBoxLayout* layout = new QHBoxLayout( this );
107  layout->setSpacing( 0 );
108  layout->setMargin( 0 );
109 
110  setWidgetRep( this );
111 
112  //either main wizard with `opt(`stepsEnabled), or sub-wizard of steps-enabled wizard
113  _stepsEnabled = ( (wizardMode == YWizardMode_Steps) || main_wizard );
114  _treeEnabled = (wizardMode == YWizardMode_Tree);
115 
116  _stepsRegistered = false;
117  _stepsDirty = false;
118  _direction = YQWizard::Forward;
119 
120  _sideBar = 0;
121  _stepsPanel = 0;
122  _helpButton = 0;
123  _stepsButton = 0;
124  _treeButton = 0;
125  _releaseNotesButton = 0;
126  _treePanel = 0;
127  _tree = 0;
128  _workArea = 0;
129  _clientArea = 0;
130  _menuBar = 0;
131  _dialogIcon = 0;
132  _dialogHeading = 0;
133  _contents = 0;
134  _backButton = 0;
135  _abortButton = 0;
136  _nextButton = 0;
137  _sendButtonEvents = true;
138  _contentsReplacePoint = 0;
139 
140  _previousWindowIcon = topLevelWidget()->windowIcon();
141 
142  YQUI::setTextdomain( TEXTDOMAIN );
143 
144  //layoutTitleBar( this );
145 
146  if( topLevelWidget()->windowTitle().isEmpty() )
147  {
148  topLevelWidget()->setWindowTitle ( YQUI::ui()->applicationTitle() );
149  QPixmap pixmap ( YUI::app()->applicationIcon().c_str() );
150  if ( !pixmap.isNull() )
151  setWindowIcon ( QIcon ( pixmap ) );
152  }
153 
154  layout->addLayout( layoutSideBar( this ) );
155  layout->addWidget( layoutWorkArea( this ) );
156 
157  setStretchFactor(indexOf(_sideBar),0);
158  setStretchFactor(indexOf(_workArea),1);
159 
160  /* If steps are enabled, we want to delay
161  the registering for after we have steps registered */
162  if ( !_stepsEnabled )
163  QY2Styler::styler()->registerWidget( this );
164 
165  if ( !main_wizard && _stepsEnabled )
166  {
167  main_wizard = this;
168  }
169  else if ( main_wizard )
170  {
171  copySteps( main_wizard );
173  }
174 
175 }
176 
177 
179 {
180  deleteSteps();
181  if ( this == main_wizard )
182  {
183  main_wizard = 0;
184  }
185  else if ( main_wizard )
186  {
187  //transfer the widget ratio to the main wizard
188  main_wizard->setSizes( sizes() );
189  }
190 
191  delete _helpDlg;
192 
193  QY2Styler::styler()->unregisterWidget( this );
194  topLevelWidget()->setWindowIcon( _previousWindowIcon );
195 }
196 
197 
199 {
200  return this != main_wizard;
201 }
202 
203 
204 void YQWizard::layoutTitleBar( QWidget * parent )
205 {
206  QFrame * titleBar = new QFrame( parent );
207  YUI_CHECK_NEW( titleBar );
208 
209  QHBoxLayout *layout = new QHBoxLayout( titleBar );
210  titleBar->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) ); // hor/vert
211 
212  //
213  // Left logo
214  //
215 
216  QLabel * left = new QLabel( titleBar );
217  layout->addWidget( left );
218  left->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed ) ); // hor/vert
219  left->setObjectName( "titleBar-left" );
220 
221  //
222  // Center stretch space
223  //
224 
225  layout->addStretch( 10 );
226 
227 
228  //
229  // Right logo
230  //
231 
232  QLabel * right = new QLabel( titleBar );
233  YUI_CHECK_NEW( right );
234 
235  layout->addWidget( right );
236  right->setObjectName( "titleBar-right" );
237 }
238 
239 
240 QLayout *YQWizard::layoutSideBar( QWidget * parent )
241 {
242  _sideBar = new QStackedWidget( parent );
243  YUI_CHECK_NEW( _sideBar );
244  // _sideBar->setMinimumWidth( YQUI::ui()->defaultSize( YD_HORIZ ) / 5 );
245  _sideBar->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Preferred ) ); // hor/vert
246  _sideBar->setObjectName( QString( "_sideBar-%1" ).arg( long( this ) ) );
247  _sideBar->installEventFilter( this );
248 
249  QVBoxLayout *vbox = new QVBoxLayout( );
250  vbox->addWidget( _sideBar );
251 
252  if ( _treeEnabled )
253  {
254  layoutTreePanel();
255  showTree();
256  }
257  else if ( _stepsEnabled )
258  {
259  layoutStepsPanel();
260  showSteps();
261  } else {
262  _sideBar->hide();
263  }
264 
265  return vbox;
266 }
267 
268 
269 void YQWizard::layoutStepsPanel()
270 {
271  // Steps
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" );
277 
278  _stepsDirty = true; // no layout yet
279 }
280 
281 
282 void YQWizard::addStep( const std::string & text, const std::string & id )
283 {
284  QString qId = fromUTF8( id );
285 
286  if ( _stepsIDs[ qId ] )
287  {
288  yuiError() << "Step ID \"" << id << "\" (\"" << text
289  <<"\") already used for \"" << _stepsIDs[ qId ]->name() <<"\""
290  << std::endl;
291  return;
292  }
293 
294  if ( !_stepsList.empty() && _stepsList.last()->name() == fromUTF8( text ) )
295  {
296  // Consecutive steps with the same name will be shown as one single step.
297  //
298  // Since steps are always added at the end of the list, it is
299  // sufficient to check the last step of the list. If the texts are the
300  // same, the other with the same text needs to get another (additional)
301  // ID to make sure setCurrentStep() works as it should.
302  _stepsList.last()->addID( qId );
303  }
304  else
305  {
306  _stepsList.append( new YQWizard::Step( fromUTF8( text ), qId ) );
307  _stepsDirty = true;
308  }
309 
310  _stepsIDs.insert( qId, _stepsList.last() );
311 
312  // make sure we always have a current step if we have steps
313  if ( _currentStepID.isNull() )
314  _currentStepID = qId;
315 }
316 
317 
318 void YQWizard::addStepHeading( const std::string & text )
319 {
320  _stepsList.append( new YQWizard::StepHeading( fromUTF8( text ) ) );
321  _stepsDirty = true;
322 }
323 
324 
326 {
327  if ( ! _stepsPanel )
328  return;
329 
330  yuiDebug() << "updateSteps" << std::endl;
331 
332  if ( !_stepsRegistered )
333  setUpdatesEnabled(false);
334 
335  // Create a grid layout for the steps
336  delete _stepsPanel->layout();
337  _stepsPanel->setMaximumWidth( 65000 );
338 
339  QVBoxLayout *_stepsVBox = new QVBoxLayout( _stepsPanel );
340 
341  QGridLayout *_stepsGrid = new QGridLayout( );
342  _stepsGrid->setObjectName( QString( "_stepsGrid_%1" ).arg( long( this ) ) );
343  YUI_CHECK_NEW( _stepsGrid );
344  _stepsVBox->addLayout( _stepsGrid );
345  _stepsGrid->setColumnMinimumWidth( 0, 10 );
346  _stepsGrid->setRowStretch( 0, 1 );
347  _stepsGrid->setRowStretch( 1, 1 );
348  _stepsGrid->setRowStretch( 2, 99 );
349 
350  const int statusCol = 1;
351  const int nameCol = 2;
352 
353  int row = 0;
354 
355  //
356  // Create widgets for all steps and step headings in the internal list
357  //
358 
359  for ( QList<Step*>::iterator i = _stepsList.begin(); i != _stepsList.end(); ++i)
360  {
361  YQWizard::Step * step = *i;
362 
363  step->deleteLabels();
364 
365  if ( step->isHeading() )
366  {
367  //
368  // Heading
369  //
370 
371  yuiDebug() << "Adding StepHeading \"" << step->name() << "\"" << std::endl;
372  QLabel * label = new QLabel( step->name(), _stepsPanel );
373  YUI_CHECK_NEW( label );
374  label->setObjectName( step->name() );
375  label->setAlignment( Qt::AlignLeft | Qt::AlignTop );
376  label->setProperty( "class", "steps_heading" );
377 
378  step->setNameLabel( label );
379  _stepsGrid->addWidget( label,
380  row, statusCol,
381  1, nameCol - statusCol + 1);
382  }
383  else // No heading - ordinary step
384  {
385  //
386  // Step status
387  //
388 
389  yuiDebug() << "Adding Step \"" << step->name() << "\"" << std::endl;
390 
391  QLabel * statusLabel = new QLabel( _stepsPanel );
392  YUI_CHECK_NEW( statusLabel );
393 
394  step->setStatusLabel( statusLabel );
395  statusLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
396  _stepsGrid->addWidget( statusLabel, row, statusCol );
397 
398  //
399  // Step name
400  //
401 
402  QLabel * nameLabel = new QLabel( step->name(), _stepsPanel );
403  YUI_CHECK_NEW( nameLabel );
404  nameLabel->setAlignment( Qt::AlignLeft | Qt::AlignTop );
405  nameLabel->setObjectName( step->name() );
406 
407  step->setNameLabel( nameLabel );
408  _stepsGrid->addWidget( nameLabel, row, nameCol );
409  }
410 
411  step->setStatus( Step::Todo );
412  row++;
413  }
414 
415  _stepsVBox->addStretch( 99 );
416  QVBoxLayout *rbl = new QVBoxLayout();
417  rbl->addWidget( _releaseNotesButton, 0, Qt::AlignCenter );
418 
419  _stepsVBox->addLayout( rbl );
420  _stepsVBox->addStretch( 29 );
421 
422  _stepsDirty = false;
423 
424  if ( !_stepsRegistered )
425  {
426  QY2Styler::styler()->registerWidget( this );
427  setUpdatesEnabled( true );
428  QY2Styler::styler()->updateRendering( this );
429  _stepsRegistered = true;
430  }
431 }
432 
433 
435 {
436  yuiDebug() << "steps dirty: " << _stepsDirty << std::endl;
437 
438  if ( _stepsDirty )
439  updateSteps();
440 
441  YQWizard::Step * currentStep = findStep( _currentStepID );
442  QList<YQWizard::Step*>::iterator step = _stepsList.begin();
443 
444  if ( currentStep )
445  {
446  // Set status icon and color for the current step
447  currentStep->setStatus( Step::Current );
448 
449  //
450  // Set all steps before the current to "done"
451  //
452 
453  while ( step != _stepsList.end() && *step != currentStep )
454  {
455  ( *step )->setStatus( Step::Done );
456  step++;
457  }
458 
459  // Skip the current step - continue with the step after it
460 
461  if ( step != _stepsList.end() )
462  step++;
463  }
464 
465  //
466  // Set all steps after the current to "to do"
467  //
468 
469  while ( step != _stepsList.end() )
470  {
471  ( *step )->setStatus( Step::Todo );
472  step++;
473  }
474 }
475 
476 
477 void YQWizard::setCurrentStep( const std::string & id )
478 {
479  yuiDebug() << "Setting current step to \"" << id << "\"" << std::endl;
480 
481  _currentStepID = fromUTF8( id );
483 }
484 
486 {
487  QList<Step*> _oldSteps = wizard->stepsList();
488 
489  if (_oldSteps.empty())
490  return;
491 
492  foreach( Step *oldStep, _oldSteps)
493  {
494  Step *newStep;
495 
496  if( !oldStep->isHeading() )
497  newStep = new Step( oldStep->name());
498  else
499  newStep = new StepHeading( oldStep->name());
500 
501  foreach( QString oneId, oldStep->id())
502  {
503  newStep->addID( oneId);
504  _stepsIDs.insert( oneId, newStep );
505  }
506 
507  newStep->setEnabled( oldStep->isEnabled());
508  _stepsList.append(newStep);
509 
510  }
511 
512  setCurrentStep( wizard->currentStep().toStdString() );
513  setSizes( main_wizard->sizes());
514 }
515 
516 
518 {
519  yuiDebug() << "Deleting steps" << std::endl;
520 
521  if ( _stepsPanel )
522  _stepsPanel->setFixedWidth( _stepsPanel->width() );
523 
524  qDeleteAll(_stepsList);
525  _stepsList.clear();
526  _stepsIDs.clear();
527  _currentStepID = QString::null;
528  _stepsDirty = true;
529 }
530 
531 
532 YQWizard::Step * YQWizard::findStep( const QString & id )
533 {
534  if ( id.isEmpty() )
535  return 0;
536 
537  return _stepsIDs[ id ];
538 }
539 
540 
541 void YQWizard::layoutTreePanel()
542 {
543  _treePanel = new QFrame( _sideBar );
544  YUI_CHECK_NEW( _treePanel );
545  QHBoxLayout *layout = new QHBoxLayout( _treePanel );
546  _sideBar->addWidget( _treePanel );
547 
548  QVBoxLayout * vbox = new QVBoxLayout();
549  YUI_CHECK_NEW( vbox );
550  layout->addLayout( vbox );
551 
552  // Selection tree
553 
554  _tree = new QY2ListView( _treePanel );
555  YUI_CHECK_NEW( _tree );
556  vbox->addWidget( _tree );
557 
558  _tree->header()->hide();
559  _tree->header()->setResizeMode( 0, QHeaderView::Stretch );
560 
561  _tree->setRootIsDecorated( true );
562  _tree->setSortByInsertionSequence( true );
563 
564  connect( _tree, SIGNAL( itemSelectionChanged ( void ) ),
565  this, SLOT ( treeSelectionChanged ( void ) ) );
566 
567  connect( _tree, SIGNAL( itemDoubleClicked ( QTreeWidgetItem *, int ) ),
568  this, SLOT ( sendTreeEvent ( QTreeWidgetItem * ) ) );
569 
570 }
571 
572 
573 void YQWizard::addTreeItem( const std::string & parentID, const std::string & text, const std::string & id )
574 {
575  QString qId = fromUTF8( id );
576 
577  if ( ! _tree )
578  {
579  yuiError() << "YQWizard widget not created with `opt(`treeEnabled) !" << std::endl;
580  return;
581  }
582 
583  YQWizard::TreeItem * item = 0;
584  YQWizard::TreeItem * parent = 0;
585 
586  if ( ! parentID.empty() )
587  {
588  parent = findTreeItem( parentID );
589  }
590 
591  if ( parent )
592  {
593  item = new YQWizard::TreeItem( parent, fromUTF8( text ), qId );
594  YUI_CHECK_NEW( item );
595  }
596  else
597  {
598  item = new YQWizard::TreeItem( _tree, fromUTF8( text ), qId );
599  YUI_CHECK_NEW( item );
600  }
601 
602  if ( ! qId.isEmpty() )
603  _treeIDs.insert( qId, item );
604 }
605 
606 
607 
609 {
610  if ( _tree )
611  _tree->clear();
612 
613  _treeIDs.clear();
614 }
615 
616 
617 
618 YQWizard::TreeItem * YQWizard::findTreeItem( const std::string & id )
619 {
620  if ( id.empty() )
621  return 0;
622 
623  return _treeIDs[ fromUTF8( id ) ];
624 }
625 
626 
627 void YQWizard::selectTreeItem( const std::string & id )
628 {
629  if ( _tree )
630  {
631  YQWizard::TreeItem * item = findTreeItem( id );
632 
633  if ( item )
634  {
635  YQSignalBlocker sigBlocker( _tree );
636 
637  _tree->setCurrentItem(item);
638  _tree->scrollToItem(item);
639  }
640  }
641 }
642 
643 
644 void YQWizard::sendTreeEvent( QTreeWidgetItem * listViewItem )
645 {
646  if ( listViewItem )
647  {
648  YQWizard::TreeItem * item = dynamic_cast<YQWizard::TreeItem *> ( listViewItem );
649 
650  if ( item && ! item->id().isEmpty() )
651  sendEvent( toUTF8( item->id() ) );
652  }
653 }
654 
655 
657 { //FIXME is currentItem correct or selected.first
658  if ( _tree )
659  sendTreeEvent( _tree->currentItem() );
660 }
661 
662 
664 {
665  if ( _tree )
666  {
667  QTreeWidgetItem * sel = _tree->currentItem();
668 
669  if ( sel )
670  {
671  YQWizard::TreeItem * item = dynamic_cast<YQWizard::TreeItem *> (sel);
672 
673  if ( item && ! item->id().isEmpty() )
674  return toUTF8( item->id() );
675  }
676  }
677 
678  return std::string();
679 }
680 
681 
682 
683 QWidget *YQWizard::layoutWorkArea( QWidget * parent )
684 {
685  _workArea = new QFrame( parent );
686  _workArea->setObjectName( "work_area" );
687 
688  QY2Styler::styler()->registerChildWidget( this, _workArea );
689 
690  QVBoxLayout *vbox = new QVBoxLayout( _workArea );
691  YUI_CHECK_NEW( vbox );
692 
693  //
694  // Menu bar
695  //
696 
697  _menuBar = new QMenuBar( _workArea );
698  YUI_CHECK_NEW( _menuBar );
699 
700  _menuBar->hide(); // will be made visible when menus are added
701  vbox->addWidget( _menuBar );
702 
703 
704  QVBoxLayout *innerbox = new QVBoxLayout( _workArea );
705  YUI_CHECK_NEW( innerbox );
706 
707  innerbox->setMargin ( YQWidgetMargin );
708 
709  vbox->addLayout(innerbox);
710  vbox->setMargin( 0 );
711 
712 
713  //
714  // Dialog icon and heading
715  //
716 
717  QHBoxLayout * headingHBox = new QHBoxLayout();
718  YUI_CHECK_NEW( headingHBox );
719  //headingHBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); // hor/vert
720  innerbox->addLayout( headingHBox );
721 
722  _dialogIcon = new QLabel( _workArea );
723  YUI_CHECK_NEW( _dialogIcon );
724  headingHBox->addWidget( _dialogIcon );
725  _dialogIcon->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum ) ); // hor/vert
726  _dialogIcon->setObjectName( "DialogIcon" );
727 
728  _dialogHeading = new QLabel( _workArea );
729  YUI_CHECK_NEW( _dialogHeading );
730  headingHBox->addWidget( _dialogHeading );
731  _dialogHeading->setAlignment( Qt::AlignLeft );
732  _dialogHeading->setWordWrap( true );
733  _dialogHeading->setTextFormat( Qt::PlainText );
734  _dialogHeading->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Minimum ) ); // hor/vert
735  _dialogHeading->setObjectName( "DialogHeading" );
736 
737  _releaseNotesButton = new QPushButton( _( "Release Notes..." ), _workArea );
738  YUI_CHECK_NEW( _workArea );
739  headingHBox->addWidget( _releaseNotesButton );
740  _releaseNotesButton->setSizePolicy( QSizePolicy( QSizePolicy::Preferred, QSizePolicy::Minimum ) ); // hor/vert
741 
742  connect( _releaseNotesButton, SIGNAL( clicked() ),
743  this, SLOT ( showReleaseNotes() ) );
744 
745  _releaseNotesButton->hide(); // hidden until showReleaseNotesButton() is called
746 
747  //
748  // Client area (the part that belongs to the YCP application)
749  //
750 
751  layoutClientArea( _workArea );
752  innerbox->addWidget( _clientArea );
753 
754  //
755  // Button box
756  //
757 
758  QLayout *bb = layoutButtonBox( _workArea );
759  innerbox->addLayout( bb );
760 
761  return _workArea;
762 }
763 
764 
765 
766 void YQWizard::layoutClientArea( QWidget * parent )
767 {
768  _clientArea = new QFrame( parent );
769  YUI_CHECK_NEW( _clientArea );
770  _clientArea->setObjectName("_clientArea");
771  QVBoxLayout *layout = new QVBoxLayout( _clientArea );
772  layout->setMargin( 0 );
773 
774  //
775  // HVCenter for wizard contents
776  //
777 
778  _contents = new YQAlignment( this, _clientArea, YAlignCenter, YAlignCenter );
779  YUI_CHECK_NEW( _contents );
780  layout->addWidget( _contents );
781  _contents->QObject::setProperty( "class", "Contents" );
782 
783  _contents->setStretchable( YD_HORIZ, true );
784  _contents->setStretchable( YD_VERT, true );
785  _contents->installEventFilter( this );
786  _contents->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) ); // hor/vert
787 
788  //
789  // Replace point for wizard contents
790  //
791 
792  _contentsReplacePoint = YUI::widgetFactory()->createReplacePoint( _contents );
793 
794  //
795  // Initial YEmpty widget contents of replace point
796  //
797 
798  YUI::widgetFactory()->createEmpty( _contentsReplacePoint );
799  _contentsReplacePoint->showChild();
800 
801 }
802 
803 
804 
805 QLayout *YQWizard::layoutButtonBox( QWidget * parent )
806 {
807  //
808  // QHBoxLayout for the buttons
809  //
810 
811  QHBoxLayout * hbox = new QHBoxLayout(); // parent, spacing
812  YUI_CHECK_NEW( hbox );
813 
814  hbox->setSpacing( 0 );
815  hbox->setMargin( 0 );
816 
817  // Help button - intentionally without keyboard shortcut
818  _helpButton = new QPushButton( _( "Help" ), parent );
819  YUI_CHECK_NEW( _helpButton );
820  _helpButton->setShortcut( Qt::Key_F1 );
821 
822  connect( _helpButton, SIGNAL( clicked() ),
823  this, SLOT ( showHelp() ) );
824 
825  hbox->addWidget( _helpButton );
826 
827  hbox->addStretch( 10 );
828 
829  //
830  // "Abort" button
831  //
832 
833  _abortButton = new YQWizardButton( this, parent, _abortButtonLabel );
834  YUI_CHECK_NEW( _abortButton );
835 
836  hbox->addWidget( (QWidget *) _abortButton->widgetRep() );
837  connect( _abortButton, SIGNAL( clicked() ),
838  this, SLOT ( slotAbortClicked() ) );
839 
840  hbox->addSpacing( 10 );
841 
842  //
843  // "Back" button
844  //
845 
846  _backButton = new YQWizardButton( this, parent, _backButtonLabel );
847  YUI_CHECK_NEW( _backButton );
848 
849  hbox->addWidget( (QWidget *) _backButton->widgetRep() );
850  connect( _backButton, SIGNAL( clicked() ),
851  this, SLOT ( slotBackClicked() ) );
852 
853  if ( _backButton->text().isEmpty() )
854  _backButton->hide();
855 
856  //
857  // "Next" button
858  //
859 
860  hbox->addSpacing( 5 );
861 
862  _nextButton = new YQWizardButton( this, parent, _nextButtonLabel );
863  YUI_CHECK_NEW( _nextButton );
864 
865  hbox->addWidget( (QWidget *) _nextButton->widgetRep() );
866  connect( _nextButton, SIGNAL( clicked() ),
867  this, SLOT ( slotNextClicked() ) );
868 
869  return hbox;
870 }
871 
872 
874 {
875  delete _backButton;
876  _backButton = 0;
877 
878  delete _abortButton;
879  _abortButton = 0;
880 
881  delete _nextButton;
882  _nextButton = 0;
883 }
884 
885 
886 void YQWizard::connectNotify ( const char * signal )
887 {
888  if ( QString( signal ).contains( "nextClicked()" ) )
889  {
890  yuiDebug() << "nextClicked connected, no longer directly sending button events" << std::endl;
891  _sendButtonEvents = false;
892  }
893 }
894 
895 
896 void YQWizard::disconnectNotify ( const char * signal )
897 {
898  if ( QString( signal ).contains( "nextClicked()" ) )
899  {
900  yuiDebug() << "nextClicked disconnected, directly sending button events again" << std::endl;
901  _sendButtonEvents = true;
902  }
903 }
904 
905 
906 void YQWizard::setDialogIcon( const std::string & iconName )
907 {
908  if ( _dialogIcon )
909  {
910  if ( ! iconName.empty() )
911  {
912  QPixmap icon( iconName.c_str() );
913 
914  if ( icon.isNull() )
915  yuiWarning() << "Couldn't load dialog icon \"" << iconName << "\"" << std::endl;
916  else
917  {
918  _dialogIcon->setPixmap( icon );
919  topLevelWidget()->setWindowIcon( icon );
920  }
921  }
922  else
923  {
924  _dialogIcon->clear();
925  topLevelWidget()->setWindowIcon( QIcon() );
926  }
927  }
928 }
929 
930 
931 void YQWizard::setDialogTitle( const std::string & titleText )
932 {
933  QString title = fromUTF8( titleText.c_str() );
934 
935  if ( !title.isEmpty() )
936  topLevelWidget()->setWindowTitle( YQUI::ui()->applicationTitle() + QString(" - ") + title );
937  else
938  topLevelWidget()->setWindowTitle( YQUI::ui()->applicationTitle() );
939 }
940 
941 
942 void YQWizard::setDialogHeading( const std::string & headingText )
943 {
944  if ( _dialogHeading )
945  {
946  if ( ! headingText.empty() )
947  _dialogHeading->setText( fromUTF8( headingText ) );
948  else
949  _dialogHeading->clear();
950  }
951 }
952 
953 string YQWizard::debugLabel() const
954 {
955  if ( _dialogHeading )
956  {
957  QString label = _dialogHeading->text();
958  label = label.simplified(); // Replace any embedded newline with a single blank
959 
960  if ( ! label.isEmpty() )
961  return toUTF8( label );
962  }
963 
964  return "untitled YQWizard";
965 }
966 
967 
968 void YQWizard::setHelpText( const std::string & helpText )
969 {
970  _qHelpText = fromUTF8( helpText );
971  _qHelpText.replace( "&product;", fromUTF8( YUI::app()->productName() ) );
972 }
973 
974 
976 {
977  emit backClicked();
978 
979  if ( _sendButtonEvents )
980  YQUI::ui()->sendEvent( new YWidgetEvent( _backButton, YEvent::Activated ) );
981 
982  _direction = YQWizard::Backward;
983 }
984 
985 
987 {
988  emit abortClicked();
989 
990  if ( _sendButtonEvents )
991  YQUI::ui()->sendEvent( new YWidgetEvent( _abortButton, YEvent::Activated ) );
992 }
993 
994 
996 {
997  emit nextClicked();
998 
999  if ( _sendButtonEvents )
1000  YQUI::ui()->sendEvent( new YWidgetEvent( _nextButton, YEvent::Activated ) );
1001 
1002  _direction = YQWizard::Forward;
1003 }
1004 
1005 
1007 {
1008 
1009  if (!_helpDlg)
1010  _helpDlg = new QY2HelpDialog ( _qHelpText, NULL );
1011  else
1012  {
1013  _helpDlg->setHelpText( _qHelpText );
1014  _helpDlg->hide(); // workaround for icewm (see: bnc #397083)
1015  }
1016 
1017  _helpDlg->show();
1018  _helpDlg->raise();
1019  _helpDlg->activateWindow();
1020 }
1021 
1022 
1024 {
1025  // TODO: QT-specific implementation if necessary from UX POV
1026  YDialog::showRelNotesText();
1027 }
1028 
1029 
1031 {
1032  if ( _sideBar && _stepsPanel )
1033  {
1034  _sideBar->setCurrentWidget( _stepsPanel );
1035  }
1036 }
1037 
1038 
1040 {
1041  if ( _sideBar && _treePanel )
1042  {
1043  _sideBar->setCurrentWidget( _treePanel );
1044  }
1045 }
1046 
1047 
1048 void YQWizard::addMenu( const std::string & text,
1049  const std::string & id )
1050 {
1051  if ( _menuBar )
1052  {
1053  QMenu * menu = new QMenu( _menuBar );
1054  YUI_CHECK_NEW( menu );
1055 
1056  _menuIDs.insert( fromUTF8( id ), menu );
1057  _menuBar->addMenu( menu );
1058  menu->setTitle( fromUTF8( text ) );
1059 
1060  connect( menu, SIGNAL( triggered ( QAction * ) ),
1061  this, SLOT ( sendMenuEvent( QAction * ) ) );
1062 
1063  _menuBar->show();
1064  }
1065 }
1066 
1067 
1068 void YQWizard::addSubMenu( const std::string & parentMenuID,
1069  const std::string & text,
1070  const std::string & id )
1071 {
1072  QMenu* parentMenu = _menuIDs[ fromUTF8( parentMenuID ) ];
1073 
1074  if ( parentMenu )
1075  {
1076  QMenu * menu = new QMenu( _menuBar );
1077  YUI_CHECK_NEW( menu );
1078 
1079  _menuIDs.insert( fromUTF8( id ), menu );
1080  //FIXME parentMenu->insertItem( fromUTF8( text ), menu );
1081 
1082  connect( menu, SIGNAL( triggered ( QAction * ) ),
1083  this, SLOT ( sendMenuEvent( QAction * ) ) );
1084  }
1085  else
1086  {
1087  yuiError() << "Can't find menu with ID " << parentMenuID << std::endl;
1088  }
1089 }
1090 
1091 
1092 void YQWizard::addMenuEntry( const std::string & parentMenuID,
1093  const std::string & text,
1094  const std::string & idString )
1095 {
1096  QMenu * parentMenu = _menuIDs[ fromUTF8( parentMenuID ) ];
1097 
1098  if ( parentMenu )
1099  {
1100 #if 0
1101  int id = _menuEntryIDs.size();
1102 #endif
1103  QAction *action;
1104  action = parentMenu->addAction( fromUTF8( text ) );
1105  _menuEntryIDs[ action ] = idString ;
1106 
1107  }
1108  else
1109  {
1110  yuiError() << "Can't find menu with ID " << parentMenuID << std::endl;
1111  }
1112 }
1113 
1114 
1115 void YQWizard::addMenuSeparator( const std::string & parentMenuID )
1116 {
1117  QMenu * parentMenu = _menuIDs[ fromUTF8( parentMenuID ) ];
1118 
1119  if ( parentMenu )
1120  {
1121  parentMenu->addSeparator();
1122  }
1123  else
1124  {
1125  yuiError() << "Can't find menu with ID " << parentMenuID << std::endl;
1126  }
1127 }
1128 
1129 
1131 {
1132  if ( _menuBar )
1133  {
1134  _menuBar->hide();
1135  _menuBar->clear();
1136  _menuIDs.clear();
1137  _menuEntryIDs.clear();
1138  }
1139 }
1140 
1141 
1142 void YQWizard::sendMenuEvent( QAction *action )
1143 {
1144  if ( _menuEntryIDs.contains( action ) )
1145  {
1146  sendEvent( _menuEntryIDs[ action ] );
1147  }
1148  else
1149  {
1150  yuiError() << "Invalid menu ID " << std::endl;
1151  }
1152 }
1153 
1154 
1155 void YQWizard::sendEvent( const std::string & id )
1156 {
1157  YQUI::ui()->sendEvent( new YMenuEvent( id ) );
1158 }
1159 
1160 
1162 {
1163  return sizeHint().width();
1164 }
1165 
1166 
1168 {
1169  return sizeHint().height();
1170 }
1171 
1172 
1173 void YQWizard::setSize( int newWidth, int newHeight )
1174 {
1175  resize( newWidth, newHeight );
1176  resizeClientArea();
1177 }
1178 
1180 {
1181  QSize contentsRect = _clientArea->contentsRect().size();
1182  _contents->setSize( contentsRect.width(), contentsRect.height() );
1183 }
1184 
1185 bool YQWizard::eventFilter( QObject * obj, QEvent * ev )
1186 {
1187  if ( ev->type() == QEvent::Resize && obj == _contents )
1188  {
1189  resizeClientArea();
1190  return true; // Event handled
1191  }
1192 
1193  if ( ev->type() == QEvent::Resize && obj == _sideBar && main_wizard == this && _stepsPanel )
1194  {
1195  YQMainWinDock::mainWinDock()->setSideBarWidth( _sideBar->width() );
1196  return true; // Event handled
1197  }
1198 
1199  return QWidget::eventFilter( obj, ev );
1200 }
1201 
1202 
1203 void YQWizard::setButtonLabel( YPushButton * button, const std::string & newLabel )
1204 {
1205  button->setLabel( newLabel );
1206  YDialog::currentDialog()->checkShortcuts();
1207 
1208  YQWizardButton * wizardButton = dynamic_cast<YQWizardButton *> (button);
1209 
1210  if ( wizardButton ) {
1211  // QWizardButton only implements hide and show, not setVisible
1212  if ( newLabel.empty() )
1213  wizardButton->hide();
1214  else
1215  wizardButton->show();
1216  }
1217 }
1218 
1219 
1220 void YQWizard::showReleaseNotesButton( const std::string & label, const std::string & id )
1221 {
1222  if ( ! _releaseNotesButton )
1223  {
1224  yuiError() << "NULL Release Notes button" << std::endl;
1225 
1226  if ( ! _stepsPanel )
1227  yuiError() << "This works only if there is a \"steps\" panel!" << std::endl;
1228 
1229  return;
1230  }
1231 
1232  // no way to check the shortcut, so strip it
1233  _releaseNotesButton->setText( fromUTF8( YShortcut::cleanShortcutString( label ) ) );
1234  _releaseNotesButtonId = id;
1235 
1236  _releaseNotesButton->show();
1237 }
1238 
1239 
1241 {
1242  if ( _releaseNotesButton && !_releaseNotesButton->isHidden() )
1243  _releaseNotesButton->hide();
1244 }
1245 
1246 
1248 {
1249  YQUI::setTextdomain( TEXTDOMAIN );
1250 
1251  if ( _helpButton )
1252  // "Help" button - intentionally without keyboard shortcut
1253  _helpButton->setText( _( "Help" ) );
1254 
1255  if ( _stepsButton )
1256  // "Steps" button - intentionally without keyboard shortcut
1257  _stepsButton->setText( _( "Steps" ) );
1258 
1259  if ( _treeButton )
1260  // "Tree" button - intentionally without keyboard shortcut
1261  _treeButton->setText( _( "Tree" ) );
1262 
1263  if ( _helpDlg )
1264  _helpDlg->retranslate();
1265 
1266 }
1267 
1268 
1269 void YQWizard::Step::deleteLabels()
1270 {
1271  delete _statusLabel;
1272  _statusLabel = 0;
1273  delete _nameLabel;
1274  _nameLabel = 0;
1275 }
1276 
1277 
1279 {
1280  deleteLabels();
1281 }
1282 
1283 
1285 {
1286  if ( !_statusLabel || !_nameLabel || _status == s )
1287  return;
1288 
1289  _status = s;
1290 
1291  if ( s == Todo )
1292  {
1293  _statusLabel->setProperty( "class", "todo-step-status QLabel" );
1294  _nameLabel->setProperty ( "class", "todo-step-name QLabel" );
1295  }
1296 
1297  if ( s == Done )
1298  {
1299  _statusLabel->setProperty( "class", "done-step-status QLabel" );
1300  _nameLabel->setProperty ( "class", "done-step-name QLabel" );
1301  }
1302 
1303  if ( s == Current )
1304  {
1305  _statusLabel->setProperty( "class", "current-step-status QLabel" );
1306  _nameLabel->setProperty ( "class", "current-step-name QLabel" );
1307  }
1308 
1309  _statusLabel->style()->unpolish( _statusLabel );
1310  _statusLabel->style()->polish( _statusLabel );
1311  _nameLabel->style()->unpolish( _nameLabel );
1312  _nameLabel->style()->polish( _nameLabel );
1313 }
1314 
1315 #include "YQWizard.moc"
virtual std::string currentTreeSelection()
Definition: YQWizard.cc:663
void showReleaseNotes()
Definition: YQWizard.cc:1023
bool isSecondary() const
Definition: YQWizard.cc:198
virtual void setSortByInsertionSequence(bool sortByInsertionSequence)
Definition: QY2ListView.cc:354
virtual void setCurrentStep(const std::string &id)
Definition: YQWizard.cc:477
void resizeClientArea()
Definition: YQWizard.cc:1179
virtual ~Step()
Definition: YQWizard.cc:1278
virtual void setDialogIcon(const std::string &iconName)
Definition: YQWizard.cc:906
void setSideBarWidth(int width)
void destroyButtons()
Definition: YQWizard.cc:873
virtual void deleteTreeItems()
Definition: YQWizard.cc:608
void sendTreeEvent(QTreeWidgetItem *item)
Definition: YQWizard.cc:644
void showSteps()
Definition: YQWizard.cc:1030
virtual std::string debugLabel() const
Definition: YQWizard.cc:953
virtual void setHelpText(const std::string &helpText)
Definition: YQWizard.cc:968
virtual void setButtonLabel(YPushButton *button, const std::string &newLabel)
Definition: YQWizard.cc:1203
virtual void setSize(int newWidth, int newHeight)
Definition: YQWizard.cc:1173
void connectNotify(const char *signal)
Definition: YQWizard.cc:886
virtual void clear()
Definition: QY2ListView.cc:101
virtual void deleteSteps()
Definition: YQWizard.cc:517
QString applicationTitle()
Definition: YQUI.h:291
virtual void showReleaseNotesButton(const std::string &label, const std::string &id)
Definition: YQWizard.cc:1220
virtual bool eventFilter(QObject *obj, QEvent *ev)
Definition: YQWizard.cc:1185
void slotAbortClicked()
Definition: YQWizard.cc:986
virtual void selectTreeItem(const std::string &id)
Definition: YQWizard.cc:627
YQWizard(YWidget *parent, const std::string &backButtonLabel, const std::string &abortButtonLabel, const std::string &nextButtonLabel, YWizardMode wizardMode=YWizardMode_Standard)
Definition: YQWizard.cc:86
void copySteps(YQWizard *wizard)
Definition: YQWizard.cc:485
virtual void addStepHeading(const std::string &text)
Definition: YQWizard.cc:318
void treeSelectionChanged()
Definition: YQWizard.cc:656
virtual void setDialogHeading(const std::string &headingText)
Definition: YQWizard.cc:942
void resizeVisibleChild()
virtual void setDialogTitle(const std::string &titleText)
Definition: YQWizard.cc:931
virtual ~YQWizard()
Definition: YQWizard.cc:178
virtual void addMenuEntry(const std::string &parentMenuID, const std::string &text, const std::string &id)
Definition: YQWizard.cc:1092
static YQMainWinDock * mainWinDock()
YQWizard::TreeItem * findTreeItem(const std::string &id)
Definition: YQWizard.cc:618
void abortClicked()
void setStatus(Status s)
Definition: YQWizard.cc:1284
virtual void hideReleaseNotesButton()
Definition: YQWizard.cc:1240
void sendEvent(YEvent *event)
Definition: YQUI.cc:476
void slotBackClicked()
Definition: YQWizard.cc:975
virtual void retranslateInternalButtons()
Definition: YQWizard.cc:1247
virtual void addMenuSeparator(const std::string &parentMenuID)
Definition: YQWizard.cc:1115
QString currentStep()
Definition: YQWizard.h:210
virtual void addStep(const std::string &text, const std::string &id)
Definition: YQWizard.cc:282
virtual void deleteMenus()
Definition: YQWizard.cc:1130
Enhanced QTreeWidget.
Definition: QY2ListView.h:47
void showHelp()
Definition: YQWizard.cc:1006
virtual void addSubMenu(const std::string &parentMenuID, const std::string &text, const std::string &id)
Definition: YQWizard.cc:1068
void slotNextClicked()
Definition: YQWizard.cc:995
YQWizard::Step * findStep(const QString &id)
Definition: YQWizard.cc:532
virtual int preferredHeight()
Definition: YQWizard.cc:1167
void showTree()
Definition: YQWizard.cc:1039
void sendEvent(const std::string &id)
Definition: YQWizard.cc:1155
virtual void addMenu(const std::string &text, const std::string &id)
Definition: YQWizard.cc:1048
QList< YQWizard::Step * > stepsList()
Definition: YQWizard.h:182
virtual void addTreeItem(const std::string &parentID, const std::string &text, const std::string &id)
Definition: YQWizard.cc:573
void nextClicked()
void disconnectNotify(const char *signal)
Definition: YQWizard.cc:896
void updateStepStates()
Definition: YQWizard.cc:434
void sendMenuEvent(QAction *action)
Definition: YQWizard.cc:1142
virtual int preferredWidth()
Definition: YQWizard.cc:1161
static void setTextdomain(const char *domain)
Definition: YQUI.cc:496
QString text() const
void backClicked()
virtual void setSize(int newWidth, int newHeight)
Definition: YQAlignment.cc:70
static YQUI * ui()
Definition: YQUI.h:74
virtual void updateSteps()
Definition: YQWizard.cc:325