]> SALOME platform Git repositories - samples/sierpinsky.git/blob - src/SierpinskyGUI/SierpinskyGUI_RunDlg.cxx
Salome HOME
146bea94e7d2a9241b7e998009e484c735826a01
[samples/sierpinsky.git] / src / SierpinskyGUI / SierpinskyGUI_RunDlg.cxx
1 ///////////////////////////////////////////////////////////
2 // File    : SierpinskyGUI_RunDlg.cxx
3 // Author  : Vadim SANDLER (OCN)
4 // Created : 13/07/05
5 // Copyright (C) 2005 Open CASCADE
6 ///////////////////////////////////////////////////////////
7
8 #include "SierpinskyGUI_RunDlg.h"
9
10 #include <qlabel.h>
11 #include <qlineedit.h>
12 #include <qlayout.h>
13 #include <qpushbutton.h>
14 #include <qgroupbox.h>
15 #include <qcheckbox.h>
16 #include <qspinbox.h>
17 #include <qthread.h>
18 #include <qprogressbar.h>
19 #include <qapplication.h>
20
21 #include <QAD_Application.h>
22 #include <QAD_Desktop.h>
23 #include <QAD_FileDlg.h>
24 #include <QAD_SpinBoxDbl.h>
25 #include <QAD_MessageBox.h>
26
27 #include <SALOMEconfig.h>
28 #include CORBA_SERVER_HEADER(Sierpinsky)
29 #include CORBA_CLIENT_HEADER(Randomizer)
30 #include CORBA_CLIENT_HEADER(SALOMEDS)
31 #include CORBA_CLIENT_HEADER(VISU_Gen)
32
33 /*!
34  * Get Randomizer component engine
35  */
36 static RANDOMIZER_ORB::RANDOMIZER_var getRandomizerEngine()
37 {
38   static RANDOMIZER_ORB::RANDOMIZER_var aGen;
39   if( CORBA::is_nil( aGen ) ) {
40     if( QAD_Desktop* aDesktop = QAD_Application::getDesktop() ) {
41       Engines::Component_var aComponent = aDesktop->getEngine( "FactoryServerPy","RANDOMIZER" );
42       aGen = RANDOMIZER_ORB::RANDOMIZER::_narrow( aComponent );
43     }
44   }
45   return aGen;
46 }
47
48 /*!
49  * Get Sierpinsky component engine
50  */
51 static SIERPINSKY_ORB::SIERPINSKY_var getSierpinskyEngine()
52 {
53   static SIERPINSKY_ORB::SIERPINSKY_var aGen;
54   if( CORBA::is_nil( aGen ) ) {
55     if( QAD_Desktop* aDesktop = QAD_Application::getDesktop() ) {
56       Engines::Component_var aComponent = aDesktop->getEngine( "FactoryServer","SIERPINSKY" );
57       aGen = SIERPINSKY_ORB::SIERPINSKY::_narrow( aComponent );
58     }
59   }
60   return aGen;
61 }
62
63 /*!
64  * Get VISU component engine
65  */
66 static VISU::VISU_Gen_var getVisuEngine()
67 {
68   static VISU::VISU_Gen_var aGen;
69   if( CORBA::is_nil( aGen ) ) {
70     if( QAD_Desktop* aDesktop = QAD_Application::getDesktop() ) {
71       Engines::Component_var aComponent = aDesktop->getEngine( "FactoryServer","VISU" );
72       aGen = VISU::VISU_Gen::_narrow( aComponent );
73     }
74   }
75   return aGen;
76 }
77
78 #define MY_EVENT QEvent::User + 555
79 class MyEvent : public QCustomEvent
80 {
81 public:
82   MyEvent( const int iter ) : QCustomEvent( MY_EVENT ), myIter( iter ) {}
83   int iter() const { return myIter; }
84
85 private:
86   int myIter;
87 };
88
89 /*!
90  * Progress thread class
91  */
92 class MyThread : public QThread
93 {
94 public:
95   MyThread( SierpinskyGUI_RunDlg* parent, const double x, const double y, const int nbIter ) :
96     myParent( parent ), myStopped( false ), myX( x ), myY( y ), myNbIter( nbIter ) { start(); }
97
98   void init( const double x, const double y, const int nbIter ) 
99   {
100     myX = x; myY = y;
101     myNbIter = nbIter;
102     myStopped = false;
103     start();
104   }
105   void stop() { myStopped = true; }
106
107 protected:
108   void run() 
109   {
110     while ( !myStopped && myNbIter-- ) {
111       int ni = getRandomizerEngine()->NextIteration();
112       getSierpinskyEngine()->NextPoint( myX, myY, ni, myX, myY );
113       QApplication::postEvent( myParent, new MyEvent( myNbIter ) );
114       msleep( 50 );
115     }
116   }
117
118 private:
119   SierpinskyGUI_RunDlg* myParent;
120   bool                  myStopped;
121   double                myX;
122   double                myY;
123   int                   myNbIter;
124 };
125
126 #define MARGIN_SIZE  11
127 #define SPACING_SIZE  6
128
129 /*!
130  * Constructor
131  */
132 SierpinskyGUI_RunDlg::SierpinskyGUI_RunDlg( QWidget* parent )
133      : QDialog( parent, "SierpinskyGUI_RunDlg", true, 
134                 WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu | WDestructiveClose ),
135        myThread( 0 )
136 {
137   setCaption( tr( "CAPTION" ) );
138   setSizeGripEnabled( true );
139   
140   QGridLayout* topLayout = new QGridLayout( this ); 
141   topLayout->setMargin( MARGIN_SIZE ); topLayout->setSpacing( SPACING_SIZE );
142
143   // start point group
144   box1 = new QGroupBox( tr( "START_POINT" ), this );
145   box1->setColumnLayout( 0, Qt::Vertical );
146   box1->layout()->setMargin( 0 ); box1->layout()->setSpacing( 0 );
147   QGridLayout* box1Layout = new QGridLayout( box1->layout() );
148   box1Layout->setAlignment( Qt::AlignTop );
149   box1Layout->setMargin( MARGIN_SIZE ); box1Layout->setSpacing( SPACING_SIZE );
150
151   QLabel* labX = new QLabel( "X:", box1 );
152   myStartX = new QAD_SpinBoxDbl( box1, 0.0, 1.0, 0.1 );
153   myStartX->setMinimumWidth( 150 );
154
155   QLabel* labY = new QLabel( "Y:", box1 );
156   myStartY = new QAD_SpinBoxDbl( box1, 0.0, 1.0, 0.1 );
157   myStartY->setMinimumWidth( 150 );
158
159   myStartRandom = new QCheckBox( tr( "RANDOM" ), box1 );
160
161   box1Layout->addWidget( labX,          0, 0 );
162   box1Layout->addWidget( myStartX,      0, 1 );
163   box1Layout->addWidget( labY,          0, 2 );
164   box1Layout->addWidget( myStartY,      0, 3 );
165   box1Layout->addWidget( myStartRandom, 1, 1 );
166
167   // base points group
168   box2 = new QGroupBox( tr( "BASE_POINTS" ), this );
169   box2->setColumnLayout( 0, Qt::Vertical );
170   box2->layout()->setMargin( 0 ); box2->layout()->setSpacing( 0 );
171   QGridLayout* box2Layout = new QGridLayout( box2->layout() );
172   box2Layout->setAlignment( Qt::AlignTop );
173   box2Layout->setMargin( MARGIN_SIZE ); box2Layout->setSpacing( SPACING_SIZE );
174
175   QLabel* labX1 = new QLabel( "X1:", box2 );
176   myX1 = new QAD_SpinBoxDbl( box2, 0.0, 1.0, 0.1 );
177   myX1->setMinimumWidth( 150 );
178
179   QLabel* labY1 = new QLabel( "Y1:", box2 );
180   myY1 = new QAD_SpinBoxDbl( box2, 0.0, 1.0, 0.1 );
181   myY1->setMinimumWidth( 150 );
182
183   QLabel* labX2 = new QLabel( "X2:", box2 );
184   myX2 = new QAD_SpinBoxDbl( box2, 0.0, 1.0, 0.1 );
185   myX2->setMinimumWidth( 150 );
186
187   QLabel* labY2 = new QLabel( "Y2:", box2 );
188   myY2 = new QAD_SpinBoxDbl( box2, 0.0, 1.0, 0.1 );
189   myY2->setMinimumWidth( 150 );
190
191   QLabel* labX3 = new QLabel( "X3:", box2 );
192   myX3 = new QAD_SpinBoxDbl( box2, 0.0, 1.0, 0.1 );
193   myX3->setMinimumWidth( 150 );
194
195   QLabel* labY3 = new QLabel( "Y3:", box2 );
196   myY3 = new QAD_SpinBoxDbl( box2, 0.0, 1.0, 0.1 );
197   myY3->setMinimumWidth( 150 );
198
199   myBaseRandom  = new QCheckBox( tr( "RANDOM" ), box2 );
200   myBaseDefault = new QCheckBox( tr( "DEFAULT" ), box2 );
201
202   box2Layout->addWidget( labX1,         0, 0 );
203   box2Layout->addWidget( myX1,          0, 1 );
204   box2Layout->addWidget( labY1,         0, 2 );
205   box2Layout->addWidget( myY1,          0, 3 );
206   box2Layout->addWidget( labX2,         1, 0 );
207   box2Layout->addWidget( myX2,          1, 1 );
208   box2Layout->addWidget( labY2,         1, 2 );
209   box2Layout->addWidget( myY2,          1, 3 );
210   box2Layout->addWidget( labX3,         2, 0 );
211   box2Layout->addWidget( myX3,          2, 1 );
212   box2Layout->addWidget( labY3,         2, 2 );
213   box2Layout->addWidget( myY3,          2, 3 );
214   box2Layout->addWidget( myBaseRandom,  3, 1 );
215   box2Layout->addWidget( myBaseDefault, 3, 3 );
216
217   // number of iterations
218   QLabel* labIter = new QLabel( tr( "NB_ITERATIONS" ), this );
219   myIter = new QSpinBox( 1, 100000, 1, this );
220
221   // results
222   box3 = new QGroupBox( tr( "RESULTS" ), this );
223   box3->setColumnLayout( 0, Qt::Vertical );
224   box3->layout()->setMargin( 0 ); box3->layout()->setSpacing( 0 );
225   QGridLayout* box3Layout = new QGridLayout( box3->layout() );
226   box3Layout->setAlignment( Qt::AlignTop );
227   box3Layout->setMargin( MARGIN_SIZE ); box3Layout->setSpacing( SPACING_SIZE );
228
229   myJpegCheck = new QCheckBox( tr( "EXPORT_2_JPEG" ), box3 );
230   myJpegFile = new QLineEdit( box3 );
231   myJpegFile->setMinimumWidth( 300 );
232
233   myJpegBtn = new QPushButton( "...", box3 );
234   myJpegBtn->setFixedSize( 20, 20 );
235
236   QLabel* labJpeg = new QLabel( tr( "IMAGE_SIZE" ), box3 );
237   myJpegSize = new QSpinBox( 0, 1280, 10, box3 );
238   myJpegSize->setMinimumWidth( 150 );
239
240   QFrame* line = new QFrame( box3 );
241   line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
242
243   myMedCheck = new QCheckBox( tr( "EXPORT_2_MED" ), box3 );
244   myMedFile = new QLineEdit( box3 );
245   myMedFile->setMinimumWidth( 300 );
246
247   myMedBtn = new QPushButton( "...", box3 );
248   myMedBtn->setFixedSize( 20, 20 );
249
250   QLabel* labMed = new QLabel( tr( "MESH_SIZE" ), box3 );
251   myMedSize = new QAD_SpinBoxDbl( box3, 0.0, 1000, 1.0 );
252   myMedSize->setMinimumWidth( 150 );
253
254   myVisuCheck = new QCheckBox( tr( "IMPORT_MED_2_VISU" ), box3 );
255
256   box3Layout->addMultiCellWidget( myJpegCheck, 0, 0, 0, 3 );
257   box3Layout->addMultiCellWidget( myJpegFile,  1, 1, 0, 2 );
258   box3Layout->addWidget(          myJpegBtn,      1,    3 );
259   box3Layout->addWidget(          labJpeg,        2,    0 );
260   box3Layout->addWidget(          myJpegSize,     2,    1 );
261   box3Layout->addMultiCellWidget( line,        3, 3, 0, 3 );
262   box3Layout->addMultiCellWidget( myMedCheck,  4, 4, 0, 3 );
263   box3Layout->addMultiCellWidget( myMedFile,   5, 5, 0, 2 );
264   box3Layout->addWidget(          myMedBtn,       5,    3 );
265   box3Layout->addWidget(          labMed,         6,    0 );
266   box3Layout->addWidget(          myMedSize,      6,    1 );
267   box3Layout->addMultiCellWidget( myVisuCheck,    7, 7, 0, 3 );
268
269   // progress bar
270   myProgress = new QProgressBar( this );
271   myProgress->setPercentageVisible( false );
272   myProgress->setFixedHeight( 10 );
273  
274   // common buttons
275   myStartBtn  = new QPushButton( tr( "START_BTN" ),  this );
276   myCancelBtn = new QPushButton( tr( "CANCEL_BTN" ), this );
277   QHBoxLayout* btnLayout = new QHBoxLayout;
278   btnLayout->addWidget( myStartBtn ); 
279   btnLayout->addStretch();
280   btnLayout->addWidget( myCancelBtn );
281
282   topLayout->addMultiCellWidget( box1,      0, 0, 0, 1 );
283   topLayout->addMultiCellWidget( box2,      1, 1, 0, 1 );
284   topLayout->addWidget(          labIter,      2,    0 );
285   topLayout->addWidget(          myIter,       2,    1 );
286   topLayout->addMultiCellWidget( box3,      3, 3, 0, 1 );
287   topLayout->addMultiCellWidget( myProgress,4, 4, 0, 1 );
288   topLayout->addMultiCellLayout( btnLayout, 5, 5, 0, 1 );
289
290   // signals and slots connections
291   connect( myJpegBtn,     SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
292   connect( myMedBtn,      SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
293   connect( myStartRandom, SIGNAL( clicked() ), this, SLOT( updateState() ) );
294   connect( myBaseRandom,  SIGNAL( clicked() ), this, SLOT( toggled() ) );
295   connect( myBaseDefault, SIGNAL( clicked() ), this, SLOT( toggled() ) );
296   connect( myJpegCheck,   SIGNAL( clicked() ), this, SLOT( updateState() ) );
297   connect( myMedCheck,    SIGNAL( clicked() ), this, SLOT( updateState() ) );
298   connect( myStartBtn,    SIGNAL( clicked() ), this, SLOT( accept() ) );
299   connect( myCancelBtn,   SIGNAL( clicked() ), this, SLOT( close() ) );
300
301   // initial state
302   myStartX->setValue( 0.0 ); myStartY->setValue( 0.0 );
303   myStartRandom->setChecked( true );
304   myX1->setValue( 0.5 ); myY1->setValue( 1.0 );
305   myX2->setValue( 0.0 ); myY2->setValue( 0.0 );
306   myX3->setValue( 1.0 ); myY3->setValue( 0.0 );
307   myBaseRandom->setChecked( false );
308   myBaseDefault->setChecked( true );
309   myIter->setValue( 1000 );
310   myJpegCheck->setChecked( false );
311   myJpegSize->setValue( 200 );
312   myMedCheck->setChecked( false );
313   myMedSize->setValue( 100 );
314   myVisuCheck->setChecked( true );
315   updateState();
316 }
317
318 /*!
319  * Destructor
320  */
321 SierpinskyGUI_RunDlg::~SierpinskyGUI_RunDlg()
322 {
323   if ( myThread ) {
324     myThread->stop();
325     myThread->wait();
326     delete myThread;
327   }
328 }
329
330 /*!
331  * Browse file 
332  */
333 void SierpinskyGUI_RunDlg::onBrowse()
334 {
335   const QObject* snd = sender();
336   bool jpg = snd == myJpegBtn;
337   QString aFileName = QAD_FileDlg::getFileName( this, 
338                                                 jpg ? myJpegFile->text() : myMedFile->text(), 
339                                                 QStringList::split( ":", jpg ? tr( "JPEG_FILES") : tr( "MED_FILES" ) ),
340                                                 jpg ? tr( "EXPORT_JPEG_FILE" ) : tr( "EXPORT_MED_FILE" ),
341                                                 false );
342   if ( !aFileName.isEmpty() ) {
343     jpg ? myJpegFile->setText( aFileName ) : myMedFile->setText( aFileName );
344   }
345 }
346
347 /*!
348  * Update widgets state
349  */
350 void SierpinskyGUI_RunDlg::updateState()
351 {
352   myStartX->setEnabled( !myStartRandom->isChecked() );
353   myStartY->setEnabled( !myStartRandom->isChecked() );
354
355   myX1->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
356   myY1->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
357   myX2->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
358   myY2->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
359   myX3->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
360   myY3->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
361
362   myJpegFile->setEnabled( myJpegCheck->isChecked() );
363   myJpegBtn->setEnabled( myJpegCheck->isChecked() );
364   myJpegSize->setEnabled( myJpegCheck->isChecked() );
365
366   myMedFile->setEnabled( myMedCheck->isChecked() );
367   myMedBtn->setEnabled( myMedCheck->isChecked() );
368   myMedSize->setEnabled( myMedCheck->isChecked() );
369   myVisuCheck->setEnabled( myMedCheck->isChecked() );
370 }
371
372 /*!
373  * Toggle 'Base points' mode
374  */
375 void SierpinskyGUI_RunDlg::toggled()
376 {
377   const QObject* snd = sender();
378   if ( snd == myBaseRandom  &&  myBaseRandom->isChecked() ) myBaseDefault->setChecked( false );
379   if ( snd == myBaseDefault && myBaseDefault->isChecked() ) myBaseRandom->setChecked( false );
380   updateState();
381 }
382
383 /*!
384  * Called when user presses 'Start' button
385  */
386 void SierpinskyGUI_RunDlg::accept()
387 {
388   RANDOMIZER_ORB::RANDOMIZER_var aRandGen  = getRandomizerEngine();
389   SIERPINSKY_ORB::SIERPINSKY_var aSierpGen = getSierpinskyEngine();
390
391   if( CORBA::is_nil( aRandGen ) || CORBA::is_nil( aSierpGen ) ) {
392     QAD_MessageBox::error1( this,
393                             tr( "ERR_ERROR" ),
394                             tr( "EXEC_ERROR" ),
395                             tr( "OK_BTN") );
396     return;
397   }
398
399   // JPEG file
400   QString aJPEGFile;
401   int aJPEGSize = 0;
402   if ( myJpegCheck->isChecked() ) {
403     aJPEGFile = myJpegFile->text().stripWhiteSpace();
404     aJPEGSize = myJpegSize->value();
405     if ( aJPEGFile.isEmpty() || aJPEGSize <= 0 ) {
406       int res = QAD_MessageBox::warn2( this,
407                                        tr( "WRN_WARNING" ),
408                                        tr( "JPEG_PARAMETERS_ERROR" ),
409                                        tr( "YES_BTN"), tr( "NO_BTN" ), 0, 1, 0 );
410       if ( res ) return;
411     }
412   }
413
414   // MED file
415   QString aMEDFile;
416   double aMEDSize = 0;
417   if ( myMedCheck->isChecked() ) {
418     aMEDFile = myMedFile->text().stripWhiteSpace();
419     aMEDSize = myMedSize->value();
420     if ( aMEDFile.isEmpty() || aMEDSize <= 0 ) {
421       int res = QAD_MessageBox::warn2( this,
422                                        tr( "WRN_WARNING" ),
423                                        tr( "MED_PARAMETERS_ERROR" ),
424                                        tr( "YES_BTN"), tr( "NO_BTN" ), 0, 1, 0 );
425       if ( res ) return;
426     }
427   }
428
429   // start point
430   double x = myStartX->value();
431   double y = myStartY->value();
432   if ( myStartRandom->isChecked() )
433     aRandGen->InitPoint( x, y );
434
435   // base points
436   if ( myBaseDefault->isChecked() ) {
437     aSierpGen->Reset();  // use default values from engine
438   }
439   else { 
440     double x1 = myX1->value();
441     double y1 = myY1->value();
442     double x2 = myX2->value();
443     double y2 = myY2->value();
444     double x3 = myX3->value();
445     double y3 = myY3->value();
446     if ( myBaseRandom->isChecked() ) {
447       aRandGen->InitPoint( x1, y1 );
448       aRandGen->InitPoint( x2, y2 );
449       aRandGen->InitPoint( x3, y3 );
450     }
451     aSierpGen->Init( x1, y1, x2, y2, x3, y3 );
452   }
453
454   // nb of iterations
455   int iter = myIter->value();
456
457   // start execution
458   myProgress->setTotalSteps( iter );
459   myProgress->setProgress( 0 );
460   if ( !myThread )
461     myThread = new MyThread( this, x, y, iter );
462   else
463     myThread->init( x, y, iter );
464   disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
465   connect(    myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
466   myStartBtn->setText( tr( "STOP_BTN" ) );
467   box1->setEnabled( false );
468   box2->setEnabled( false );
469   box3->setEnabled( false );
470   myIter->setEnabled( false );
471 }
472
473 /*!
474  * Called when user presses 'Stop' button
475  */
476 void SierpinskyGUI_RunDlg::stop()
477 {
478   myThread->stop();
479   disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
480   connect(    myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
481   myStartBtn->setText( tr( "START_BTN" ) );
482   myProgress->setProgress( 0 );
483   box1->setEnabled( true );
484   box2->setEnabled( true );
485   box3->setEnabled( true );
486   myIter->setEnabled( true );
487 }
488
489 /*!
490  * Progress thread calls this method to update progress bar state
491  */
492 void SierpinskyGUI_RunDlg::nextStep( const int step )
493 {
494   if ( !step ) {
495     disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
496     connect(    myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
497     myStartBtn->setText( tr( "START_BTN" ) );
498     myProgress->setProgress( 0 );
499     box1->setEnabled( true );
500     box2->setEnabled( true );
501     box3->setEnabled( true );
502     myIter->setEnabled( true );
503
504     // export to JPEG
505     if ( myJpegCheck->isChecked() ) {
506       QString aJPEGFile = myJpegFile->text().stripWhiteSpace();
507       int aJPEGSize = myJpegSize->value();
508       if ( !aJPEGFile.isEmpty() && aJPEGSize > 0 ) {
509         bool res = getSierpinskyEngine()->ExportToJPEG( aJPEGFile.latin1(), aJPEGSize );
510       }
511     }
512     // export to MED
513     if ( myMedCheck->isChecked() ) {
514       QString aMEDFile = myMedFile->text().stripWhiteSpace();
515       double aMEDSize = myMedSize->value();
516       if ( !aMEDFile.isEmpty() && aMEDSize > 0 ) {
517         bool res = getSierpinskyEngine()->ExportToMED( aMEDFile.latin1(), aMEDSize );
518         if ( res && myVisuCheck->isChecked() ) {
519           VISU::VISU_Gen_var aVisuGen = getVisuEngine();
520           if ( !CORBA::is_nil( aVisuGen ) ) {
521             VISU::Result_var aResult = aVisuGen->ImportFile( aMEDFile.latin1() );
522             if ( !CORBA::is_nil( aResult ) )
523               aVisuGen->MeshOnEntity( aResult, "Sierpinsky", VISU::NODE );
524             QAD_Application::getDesktop()->getActiveStudy()->updateObjBrowser( true );
525           }
526         }
527       }
528     }
529   }
530   else {
531     myProgress->setProgress( myProgress->totalSteps() - step );
532   }
533 }
534
535 /*!
536  *  Process progress event
537  */
538 void SierpinskyGUI_RunDlg::customEvent( QCustomEvent* e )
539 {
540   if ( e->type() == MY_EVENT ) {
541     MyEvent* me = (MyEvent*)e;
542     nextStep( me->iter() );
543   }
544 }