1 // Copyright (C) 2005-2010 OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 ///////////////////////////////////////////////////////////
20 // File : SierpinskyGUI_RunDlg.cxx
21 // Author : Vadim SANDLER (OCN)
23 ///////////////////////////////////////////////////////////
25 #include "SierpinskyGUI_RunDlg.h"
26 #include "SierpinskyGUI.h"
27 #include "SALOME_LifeCycleCORBA.hxx"
28 #include "SalomeApp_Application.h"
33 #include <QPushButton>
38 #include <QProgressBar>
39 #include <QApplication>
41 #include <SUIT_Application.h>
42 #include <SUIT_Desktop.h>
43 #include <SUIT_FileDlg.h>
44 #include <QtxDoubleSpinBox.h>
45 #include <SUIT_MessageBox.h>
47 #include <SALOMEconfig.h>
48 #include CORBA_SERVER_HEADER(Sierpinsky)
49 #include CORBA_CLIENT_HEADER(Randomizer)
50 #include CORBA_CLIENT_HEADER(SALOMEDS)
51 #include CORBA_CLIENT_HEADER(VISU_Gen)
54 * Get Randomizer component engine
56 static RANDOMIZER_ORB::RANDOMIZER_var getRandomizerEngine()
58 static RANDOMIZER_ORB::RANDOMIZER_var aGen;
59 if( CORBA::is_nil( aGen ) ) {
61 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
62 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServerPy","RANDOMIZER");
63 aGen = RANDOMIZER_ORB::RANDOMIZER::_narrow( aComponent );
65 catch (CORBA::Exception&){
66 MESSAGE("Caught CORBA::Exception.");
69 MESSAGE("Caught unknown exception.");
76 * Get Sierpinsky component engine
78 static SIERPINSKY_ORB::SIERPINSKY_var getSierpinskyEngine()
80 static SIERPINSKY_ORB::SIERPINSKY_var aGen;
81 if( CORBA::is_nil( aGen ) ) {
83 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
84 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","SIERPINSKY");
85 aGen = SIERPINSKY_ORB::SIERPINSKY::_narrow( aComponent );
87 catch (CORBA::Exception&){
88 MESSAGE("Caught CORBA::Exception.");
91 MESSAGE("Caught unknown exception.");
98 * Get VISU component engine
100 static VISU::VISU_Gen_var getVisuEngine()
102 static VISU::VISU_Gen_var aGen;
103 if( CORBA::is_nil( aGen ) ) {
105 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
106 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
107 aGen = VISU::VISU_Gen::_narrow( aComponent );
109 catch (CORBA::Exception&){
110 MESSAGE("Caught CORBA::Exception.");
113 MESSAGE("Caught unknown exception.");
120 #define MY_EVENT QEvent::User + 555
121 class MyEvent : public QEvent
124 MyEvent( const int iter ) : QEvent( (QEvent::Type)(MY_EVENT) ), myIter( iter ) {}
125 int iter() const { return myIter; }
132 * Progress thread class
134 class MyThread : public QThread
137 MyThread( SierpinskyGUI_RunDlg* parent, const double x, const double y, const int nbIter ) :
138 myParent( parent ), myStopped( false ), myX( x ), myY( y ), myNbIter( nbIter ) { start(); }
140 void init( const double x, const double y, const int nbIter )
147 void stop() { myStopped = true; }
152 while ( !myStopped && myNbIter-- ) {
153 int ni = getRandomizerEngine()->NextIteration();
154 getSierpinskyEngine()->NextPoint( myX, myY, ni, myX, myY );
155 QApplication::postEvent( myParent, new MyEvent( myNbIter ) );
161 SierpinskyGUI_RunDlg* myParent;
168 #define MARGIN_SIZE 11
169 #define SPACING_SIZE 6
174 SierpinskyGUI_RunDlg::SierpinskyGUI_RunDlg( QWidget* parent, SierpinskyGUI* module )
175 : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
176 myThread( 0 ), myModule( module )
178 setAttribute( Qt::WA_DeleteOnClose );
180 setObjectName("SierpinskyGUI_RunDlg");
183 setWindowTitle( tr( "CAPTION" ) );
184 setSizeGripEnabled( true );
186 QGridLayout* topLayout = new QGridLayout( this );
187 topLayout->setMargin( MARGIN_SIZE ); topLayout->setSpacing( SPACING_SIZE );
190 box1 = new QGroupBox( tr( "START_POINT" ), this );
191 QGridLayout* box1Layout = new QGridLayout( box1 );
192 box1Layout->setAlignment( Qt::AlignTop );
193 box1Layout->setMargin( MARGIN_SIZE );
194 box1Layout->setSpacing( SPACING_SIZE );
196 QLabel* labX = new QLabel( "X:", box1 );
197 myStartX = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 ,box1);
198 myStartX->setMinimumWidth( 150 );
200 QLabel* labY = new QLabel( "Y:", box1 );
201 myStartY = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 ,box1);
202 myStartY->setMinimumWidth( 150 );
204 myStartRandom = new QCheckBox( tr( "RANDOM" ), box1 );
206 box1Layout->addWidget( labX, 0, 0 );
207 box1Layout->addWidget( myStartX, 0, 1 );
208 box1Layout->addWidget( labY, 0, 2 );
209 box1Layout->addWidget( myStartY, 0, 3 );
210 box1Layout->addWidget( myStartRandom, 1, 1 );
213 box2 = new QGroupBox( tr( "BASE_POINTS" ), this );
214 QGridLayout* box2Layout = new QGridLayout( box2 );
215 box2Layout->setAlignment( Qt::AlignTop );
216 box2Layout->setMargin( MARGIN_SIZE );
217 box2Layout->setSpacing( SPACING_SIZE );
219 QLabel* labX1 = new QLabel( "X1:", box2 );
220 myX1 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
221 myX1->setMinimumWidth( 150 );
223 QLabel* labY1 = new QLabel( "Y1:", box2 );
224 myY1 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
225 myY1->setMinimumWidth( 150 );
227 QLabel* labX2 = new QLabel( "X2:", box2 );
228 myX2 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
229 myX2->setMinimumWidth( 150 );
231 QLabel* labY2 = new QLabel( "Y2:", box2 );
232 myY2 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
233 myY2->setMinimumWidth( 150 );
235 QLabel* labX3 = new QLabel( "X3:", box2 );
236 myX3 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
237 myX3->setMinimumWidth( 150 );
239 QLabel* labY3 = new QLabel( "Y3:", box2 );
240 myY3 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
241 myY3->setMinimumWidth( 150 );
243 myBaseRandom = new QCheckBox( tr( "RANDOM" ), box2 );
244 myBaseDefault = new QCheckBox( tr( "DEFAULT" ), box2 );
246 box2Layout->addWidget( labX1, 0, 0 );
247 box2Layout->addWidget( myX1, 0, 1 );
248 box2Layout->addWidget( labY1, 0, 2 );
249 box2Layout->addWidget( myY1, 0, 3 );
250 box2Layout->addWidget( labX2, 1, 0 );
251 box2Layout->addWidget( myX2, 1, 1 );
252 box2Layout->addWidget( labY2, 1, 2 );
253 box2Layout->addWidget( myY2, 1, 3 );
254 box2Layout->addWidget( labX3, 2, 0 );
255 box2Layout->addWidget( myX3, 2, 1 );
256 box2Layout->addWidget( labY3, 2, 2 );
257 box2Layout->addWidget( myY3, 2, 3 );
258 box2Layout->addWidget( myBaseRandom, 3, 1 );
259 box2Layout->addWidget( myBaseDefault, 3, 3 );
261 // number of iterations
262 QLabel* labIter = new QLabel( tr( "NB_ITERATIONS" ), this );
263 myIter = new QSpinBox( this );
264 myIter->setMinimum(1);
265 myIter->setMaximum(100000);
266 myIter->setSingleStep(1);
269 box3 = new QGroupBox( tr( "RESULTS" ), this );
270 QGridLayout* box3Layout = new QGridLayout( box3 );
271 box3Layout->setAlignment( Qt::AlignTop );
272 box3Layout->setMargin( MARGIN_SIZE );
273 box3Layout->setSpacing( SPACING_SIZE );
275 myJpegCheck = new QCheckBox( tr( "EXPORT_2_JPEG" ), box3 );
276 myJpegFile = new QLineEdit( box3 );
277 myJpegFile->setMinimumWidth( 300 );
279 myJpegBtn = new QPushButton( "...", box3 );
280 myJpegBtn->setFixedSize( 20, 20 );
282 QLabel* labJpeg = new QLabel( tr( "IMAGE_SIZE" ), box3 );
283 myJpegSize = new QSpinBox( box3 );
284 myJpegSize->setMinimum(0);
285 myJpegSize->setMaximum(1280);
286 myJpegSize->setSingleStep(10);
287 myJpegSize->setMinimumWidth( 150 );
289 QFrame* line = new QFrame( box3 );
290 line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
292 myMedCheck = new QCheckBox( tr( "EXPORT_2_MED" ), box3 );
293 myMedFile = new QLineEdit( box3 );
294 myMedFile->setMinimumWidth( 300 );
296 myMedBtn = new QPushButton( "...", box3 );
297 myMedBtn->setFixedSize( 20, 20 );
299 QLabel* labMed = new QLabel( tr( "MESH_SIZE" ), box3 );
300 myMedSize = new QtxDoubleSpinBox( 0.0, 1000, 1.0, box3);
301 myMedSize->setMinimumWidth( 150 );
303 myVisuCheck = new QCheckBox( tr( "IMPORT_MED_2_VISU" ), box3 );
305 box3Layout->addWidget( myJpegCheck, 0, 0, 1, 4 );
306 box3Layout->addWidget( myJpegFile, 1, 0, 1, 3 );
307 box3Layout->addWidget( myJpegBtn, 1, 3 );
308 box3Layout->addWidget( labJpeg, 2, 0 );
309 box3Layout->addWidget( myJpegSize, 2, 1 );
310 box3Layout->addWidget( line, 3, 0, 1, 4 );
311 box3Layout->addWidget( myMedCheck, 4, 0, 1, 4 );
312 box3Layout->addWidget( myMedFile, 5, 0, 1, 3 );
313 box3Layout->addWidget( myMedBtn, 5, 3 );
314 box3Layout->addWidget( labMed, 6, 0 );
315 box3Layout->addWidget( myMedSize, 6, 1 );
316 box3Layout->addWidget( myVisuCheck, 7, 0, 1, 4 );
319 myProgress = new QProgressBar( this );
320 myProgress->setTextVisible( false );
321 myProgress->setFixedHeight( 10 );
324 myStartBtn = new QPushButton( tr( "START_BTN" ), this );
325 myCancelBtn = new QPushButton( tr( "CANCEL_BTN" ), this );
326 QHBoxLayout* btnLayout = new QHBoxLayout;
327 btnLayout->addWidget( myStartBtn );
328 btnLayout->addStretch();
329 btnLayout->addWidget( myCancelBtn );
331 topLayout->addWidget( box1, 0, 0, 1, 2 );
332 topLayout->addWidget( box2, 1, 0, 1, 2 );
333 topLayout->addWidget( labIter, 2, 0 );
334 topLayout->addWidget( myIter, 2, 1 );
335 topLayout->addWidget( box3, 3, 0, 1, 2 );
336 topLayout->addWidget( myProgress, 4, 0, 1, 2 );
337 topLayout->addLayout( btnLayout, 5, 0, 1, 2 );
339 // signals and slots connections
340 connect( myJpegBtn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
341 connect( myMedBtn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
342 connect( myStartRandom, SIGNAL( clicked() ), this, SLOT( updateState() ) );
343 connect( myBaseRandom, SIGNAL( clicked() ), this, SLOT( toggled() ) );
344 connect( myBaseDefault, SIGNAL( clicked() ), this, SLOT( toggled() ) );
345 connect( myJpegCheck, SIGNAL( clicked() ), this, SLOT( updateState() ) );
346 connect( myMedCheck, SIGNAL( clicked() ), this, SLOT( updateState() ) );
347 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
348 connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( close() ) );
351 myStartX->setValue( 0.0 ); myStartY->setValue( 0.0 );
352 myStartRandom->setChecked( true );
353 myX1->setValue( 0.5 ); myY1->setValue( 1.0 );
354 myX2->setValue( 0.0 ); myY2->setValue( 0.0 );
355 myX3->setValue( 1.0 ); myY3->setValue( 0.0 );
356 myBaseRandom->setChecked( false );
357 myBaseDefault->setChecked( true );
358 myIter->setValue( 1000 );
359 myJpegCheck->setChecked( false );
360 myJpegSize->setValue( 200 );
361 myMedCheck->setChecked( false );
362 myMedSize->setValue( 100 );
363 myVisuCheck->setChecked( true );
370 SierpinskyGUI_RunDlg::~SierpinskyGUI_RunDlg()
382 void SierpinskyGUI_RunDlg::onBrowse()
384 const QObject* snd = sender();
385 bool jpg = snd == myJpegBtn;
386 QString aFileName = SUIT_FileDlg::getFileName( this,
387 jpg ? myJpegFile->text() : myMedFile->text(),
388 (jpg ? tr( "JPEG_FILES") : tr( "MED_FILES" )).split( ":", QString::SkipEmptyParts ),
389 jpg ? tr( "EXPORT_JPEG_FILE" ) : tr( "EXPORT_MED_FILE" ),
391 if ( !aFileName.isEmpty() ) {
392 jpg ? myJpegFile->setText( aFileName ) : myMedFile->setText( aFileName );
397 * Update widgets state
399 void SierpinskyGUI_RunDlg::updateState()
401 myStartX->setEnabled( !myStartRandom->isChecked() );
402 myStartY->setEnabled( !myStartRandom->isChecked() );
404 myX1->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
405 myY1->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
406 myX2->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
407 myY2->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
408 myX3->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
409 myY3->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
411 myJpegFile->setEnabled( myJpegCheck->isChecked() );
412 myJpegBtn->setEnabled( myJpegCheck->isChecked() );
413 myJpegSize->setEnabled( myJpegCheck->isChecked() );
415 myMedFile->setEnabled( myMedCheck->isChecked() );
416 myMedBtn->setEnabled( myMedCheck->isChecked() );
417 myMedSize->setEnabled( myMedCheck->isChecked() );
418 myVisuCheck->setEnabled( myMedCheck->isChecked() );
422 * Toggle 'Base points' mode
424 void SierpinskyGUI_RunDlg::toggled()
426 const QObject* snd = sender();
427 if ( snd == myBaseRandom && myBaseRandom->isChecked() ) myBaseDefault->setChecked( false );
428 if ( snd == myBaseDefault && myBaseDefault->isChecked() ) myBaseRandom->setChecked( false );
433 * Called when user presses 'Start' button
435 void SierpinskyGUI_RunDlg::accept()
437 RANDOMIZER_ORB::RANDOMIZER_var aRandGen = getRandomizerEngine();
438 SIERPINSKY_ORB::SIERPINSKY_var aSierpGen = getSierpinskyEngine();
440 if( CORBA::is_nil( aRandGen ) || CORBA::is_nil( aSierpGen ) ) {
441 SUIT_MessageBox::critical( this,
451 if ( myJpegCheck->isChecked() ) {
452 aJPEGFile = myJpegFile->text().trimmed();
453 aJPEGSize = myJpegSize->value();
454 if ( aJPEGFile.isEmpty() || aJPEGSize <= 0 ) {
455 int res = SUIT_MessageBox::warning( this,
457 tr( "JPEG_PARAMETERS_ERROR" ),
458 tr( "YES_BTN"), tr( "NO_BTN" ), 0, 1, 0 );
466 if ( myMedCheck->isChecked() ) {
467 aMEDFile = myMedFile->text().trimmed();
468 aMEDSize = myMedSize->value();
469 if ( aMEDFile.isEmpty() || aMEDSize <= 0 ) {
470 int res = SUIT_MessageBox::warning( this,
472 tr( "MED_PARAMETERS_ERROR" ),
473 tr( "YES_BTN"), tr( "NO_BTN" ), 0, 1, 0 );
479 double x = myStartX->value();
480 double y = myStartY->value();
481 if ( myStartRandom->isChecked() )
482 aRandGen->InitPoint( x, y );
485 if ( myBaseDefault->isChecked() ) {
486 aSierpGen->Reset(); // use default values from engine
489 double x1 = myX1->value();
490 double y1 = myY1->value();
491 double x2 = myX2->value();
492 double y2 = myY2->value();
493 double x3 = myX3->value();
494 double y3 = myY3->value();
495 if ( myBaseRandom->isChecked() ) {
496 aRandGen->InitPoint( x1, y1 );
497 aRandGen->InitPoint( x2, y2 );
498 aRandGen->InitPoint( x3, y3 );
500 aSierpGen->Init( x1, y1, x2, y2, x3, y3 );
504 int iter = myIter->value();
507 myProgress->setMaximum( iter );
508 myProgress->setValue( 0 );
510 myThread = new MyThread( this, x, y, iter );
512 myThread->init( x, y, iter );
513 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
514 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
515 myStartBtn->setText( tr( "STOP_BTN" ) );
516 box1->setEnabled( false );
517 box2->setEnabled( false );
518 box3->setEnabled( false );
519 myIter->setEnabled( false );
523 * Called when user presses 'Stop' button
525 void SierpinskyGUI_RunDlg::stop()
528 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
529 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
530 myStartBtn->setText( tr( "START_BTN" ) );
531 myProgress->setValue( 0 );
532 box1->setEnabled( true );
533 box2->setEnabled( true );
534 box3->setEnabled( true );
535 myIter->setEnabled( true );
539 * Progress thread calls this method to update progress bar state
541 void SierpinskyGUI_RunDlg::nextStep( const int step )
544 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
545 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
546 myStartBtn->setText( tr( "START_BTN" ) );
547 myProgress->setValue( 0 );
548 box1->setEnabled( true );
549 box2->setEnabled( true );
550 box3->setEnabled( true );
551 myIter->setEnabled( true );
554 if ( myJpegCheck->isChecked() ) {
555 QString aJPEGFile = myJpegFile->text().trimmed();
556 int aJPEGSize = myJpegSize->value();
557 if ( !aJPEGFile.isEmpty() && aJPEGSize > 0 ) {
558 bool res = getSierpinskyEngine()->ExportToJPEG( aJPEGFile.toLatin1().data(), aJPEGSize );
560 // error: can't create JPEG image
565 if ( myMedCheck->isChecked() ) {
566 QString aMEDFile = myMedFile->text().trimmed();
567 double aMEDSize = myMedSize->value();
568 if ( !aMEDFile.isEmpty() && aMEDSize > 0 ) {
569 bool res = getSierpinskyEngine()->ExportToMED( aMEDFile.toLatin1().data(), aMEDSize );
570 if ( res && myVisuCheck->isChecked() ) {
571 VISU::VISU_Gen_var aVisuGen = getVisuEngine();
572 if ( !CORBA::is_nil( aVisuGen ) ) {
573 VISU::Result_var aResult = aVisuGen->ImportFile( aMEDFile.toLatin1().data() );
574 if ( !CORBA::is_nil( aResult ) )
575 aVisuGen->MeshOnEntity( aResult, "Sierpinsky", VISU::NODE );
576 myModule->getApp()->updateObjectBrowser( true );
583 myProgress->setValue( myProgress->maximum() - step );
588 * Process progress event
590 void SierpinskyGUI_RunDlg::customEvent( QEvent* e )
592 if ( e->type() == MY_EVENT ) {
593 MyEvent* me = (MyEvent*)e;
594 nextStep( me->iter() );