1 // Copyright (C) 2005-2013 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
20 ///////////////////////////////////////////////////////////
21 // File : SierpinskyGUI_RunDlg.cxx
22 // Author : Vadim SANDLER (OCN)
24 ///////////////////////////////////////////////////////////
26 #include "SierpinskyGUI_RunDlg.h"
27 #include "SierpinskyGUI.h"
28 #include "SALOME_LifeCycleCORBA.hxx"
29 #include "SalomeApp_Application.h"
34 #include <QPushButton>
39 #include <QProgressBar>
40 #include <QApplication>
42 #include <SUIT_Application.h>
43 #include <SUIT_Desktop.h>
44 #include <SUIT_FileDlg.h>
45 #include <QtxDoubleSpinBox.h>
46 #include <SUIT_MessageBox.h>
48 #include <SALOMEconfig.h>
49 #include CORBA_SERVER_HEADER(Sierpinsky)
50 #include CORBA_CLIENT_HEADER(Randomizer)
51 #include CORBA_CLIENT_HEADER(SALOMEDS)
53 #include CORBA_CLIENT_HEADER(VISU_Gen)
57 * Get Randomizer component engine
59 static RANDOMIZER_ORB::RANDOMIZER_var getRandomizerEngine()
61 static RANDOMIZER_ORB::RANDOMIZER_var aGen;
62 if( CORBA::is_nil( aGen ) ) {
64 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
65 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServerPy","RANDOMIZER");
66 aGen = RANDOMIZER_ORB::RANDOMIZER::_narrow( aComponent );
68 catch (CORBA::Exception&){
69 MESSAGE("Caught CORBA::Exception.");
72 MESSAGE("Caught unknown exception.");
79 * Get Sierpinsky component engine
81 static SIERPINSKY_ORB::SIERPINSKY_var getSierpinskyEngine()
83 static SIERPINSKY_ORB::SIERPINSKY_var aGen;
84 if( CORBA::is_nil( aGen ) ) {
86 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
87 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","SIERPINSKY");
88 aGen = SIERPINSKY_ORB::SIERPINSKY::_narrow( aComponent );
90 catch (CORBA::Exception&){
91 MESSAGE("Caught CORBA::Exception.");
94 MESSAGE("Caught unknown exception.");
102 * Get VISU component engine
104 static VISU::VISU_Gen_var getVisuEngine()
106 static VISU::VISU_Gen_var aGen;
107 if( CORBA::is_nil( aGen ) ) {
109 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
110 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
111 aGen = VISU::VISU_Gen::_narrow( aComponent );
113 catch (CORBA::Exception&){
114 MESSAGE("Caught CORBA::Exception.");
117 MESSAGE("Caught unknown exception.");
125 #define MY_EVENT QEvent::User + 555
126 class MyEvent : public QEvent
129 MyEvent( const int iter ) : QEvent( (QEvent::Type)(MY_EVENT) ), myIter( iter ) {}
130 int iter() const { return myIter; }
137 * Progress thread class
139 class MyThread : public QThread
142 MyThread( SierpinskyGUI_RunDlg* parent, const double x, const double y, const int nbIter ) :
143 myParent( parent ), myStopped( false ), myX( x ), myY( y ), myNbIter( nbIter ) { start(); }
145 void init( const double x, const double y, const int nbIter )
152 void stop() { myStopped = true; }
157 while ( !myStopped && myNbIter-- ) {
158 int ni = getRandomizerEngine()->NextIteration();
159 getSierpinskyEngine()->NextPoint( myX, myY, ni, myX, myY );
160 QApplication::postEvent( myParent, new MyEvent( myNbIter ) );
166 SierpinskyGUI_RunDlg* myParent;
173 #define MARGIN_SIZE 11
174 #define SPACING_SIZE 6
179 SierpinskyGUI_RunDlg::SierpinskyGUI_RunDlg( QWidget* parent, SierpinskyGUI* module )
180 : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
181 myThread( 0 ), myModule( module )
183 setAttribute( Qt::WA_DeleteOnClose );
185 setObjectName("SierpinskyGUI_RunDlg");
188 setWindowTitle( tr( "CAPTION" ) );
189 setSizeGripEnabled( true );
191 QGridLayout* topLayout = new QGridLayout( this );
192 topLayout->setMargin( MARGIN_SIZE ); topLayout->setSpacing( SPACING_SIZE );
195 box1 = new QGroupBox( tr( "START_POINT" ), this );
196 QGridLayout* box1Layout = new QGridLayout( box1 );
197 box1Layout->setAlignment( Qt::AlignTop );
198 box1Layout->setMargin( MARGIN_SIZE );
199 box1Layout->setSpacing( SPACING_SIZE );
201 QLabel* labX = new QLabel( "X:", box1 );
202 myStartX = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 ,box1);
203 myStartX->setMinimumWidth( 150 );
205 QLabel* labY = new QLabel( "Y:", box1 );
206 myStartY = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 ,box1);
207 myStartY->setMinimumWidth( 150 );
209 myStartRandom = new QCheckBox( tr( "RANDOM" ), box1 );
211 box1Layout->addWidget( labX, 0, 0 );
212 box1Layout->addWidget( myStartX, 0, 1 );
213 box1Layout->addWidget( labY, 0, 2 );
214 box1Layout->addWidget( myStartY, 0, 3 );
215 box1Layout->addWidget( myStartRandom, 1, 1 );
218 box2 = new QGroupBox( tr( "BASE_POINTS" ), this );
219 QGridLayout* box2Layout = new QGridLayout( box2 );
220 box2Layout->setAlignment( Qt::AlignTop );
221 box2Layout->setMargin( MARGIN_SIZE );
222 box2Layout->setSpacing( SPACING_SIZE );
224 QLabel* labX1 = new QLabel( "X1:", box2 );
225 myX1 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
226 myX1->setMinimumWidth( 150 );
228 QLabel* labY1 = new QLabel( "Y1:", box2 );
229 myY1 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
230 myY1->setMinimumWidth( 150 );
232 QLabel* labX2 = new QLabel( "X2:", box2 );
233 myX2 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
234 myX2->setMinimumWidth( 150 );
236 QLabel* labY2 = new QLabel( "Y2:", box2 );
237 myY2 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
238 myY2->setMinimumWidth( 150 );
240 QLabel* labX3 = new QLabel( "X3:", box2 );
241 myX3 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
242 myX3->setMinimumWidth( 150 );
244 QLabel* labY3 = new QLabel( "Y3:", box2 );
245 myY3 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
246 myY3->setMinimumWidth( 150 );
248 myBaseRandom = new QCheckBox( tr( "RANDOM" ), box2 );
249 myBaseDefault = new QCheckBox( tr( "DEFAULT" ), box2 );
251 box2Layout->addWidget( labX1, 0, 0 );
252 box2Layout->addWidget( myX1, 0, 1 );
253 box2Layout->addWidget( labY1, 0, 2 );
254 box2Layout->addWidget( myY1, 0, 3 );
255 box2Layout->addWidget( labX2, 1, 0 );
256 box2Layout->addWidget( myX2, 1, 1 );
257 box2Layout->addWidget( labY2, 1, 2 );
258 box2Layout->addWidget( myY2, 1, 3 );
259 box2Layout->addWidget( labX3, 2, 0 );
260 box2Layout->addWidget( myX3, 2, 1 );
261 box2Layout->addWidget( labY3, 2, 2 );
262 box2Layout->addWidget( myY3, 2, 3 );
263 box2Layout->addWidget( myBaseRandom, 3, 1 );
264 box2Layout->addWidget( myBaseDefault, 3, 3 );
266 // number of iterations
267 QLabel* labIter = new QLabel( tr( "NB_ITERATIONS" ), this );
268 myIter = new QSpinBox( this );
269 myIter->setMinimum(1);
270 myIter->setMaximum(100000);
271 myIter->setSingleStep(1);
274 box3 = new QGroupBox( tr( "RESULTS" ), this );
275 QGridLayout* box3Layout = new QGridLayout( box3 );
276 box3Layout->setAlignment( Qt::AlignTop );
277 box3Layout->setMargin( MARGIN_SIZE );
278 box3Layout->setSpacing( SPACING_SIZE );
280 myJpegCheck = new QCheckBox( tr( "EXPORT_2_JPEG" ), box3 );
281 myJpegFile = new QLineEdit( box3 );
282 myJpegFile->setMinimumWidth( 300 );
284 myJpegBtn = new QPushButton( "...", box3 );
285 myJpegBtn->setFixedSize( 20, 20 );
287 QLabel* labJpeg = new QLabel( tr( "IMAGE_SIZE" ), box3 );
288 myJpegSize = new QSpinBox( box3 );
289 myJpegSize->setMinimum(0);
290 myJpegSize->setMaximum(1280);
291 myJpegSize->setSingleStep(10);
292 myJpegSize->setMinimumWidth( 150 );
294 QFrame* line = new QFrame( box3 );
295 line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
297 myMedCheck = new QCheckBox( tr( "EXPORT_2_MED" ), box3 );
298 myMedFile = new QLineEdit( box3 );
299 myMedFile->setMinimumWidth( 300 );
301 myMedBtn = new QPushButton( "...", box3 );
302 myMedBtn->setFixedSize( 20, 20 );
304 QLabel* labMed = new QLabel( tr( "MESH_SIZE" ), box3 );
305 myMedSize = new QtxDoubleSpinBox( 0.0, 1000, 1.0, box3);
306 myMedSize->setMinimumWidth( 150 );
308 myVisuCheck = new QCheckBox( tr( "IMPORT_MED_2_VISU" ), box3 );
310 box3Layout->addWidget( myJpegCheck, 0, 0, 1, 4 );
311 box3Layout->addWidget( myJpegFile, 1, 0, 1, 3 );
312 box3Layout->addWidget( myJpegBtn, 1, 3 );
313 box3Layout->addWidget( labJpeg, 2, 0 );
314 box3Layout->addWidget( myJpegSize, 2, 1 );
315 box3Layout->addWidget( line, 3, 0, 1, 4 );
316 box3Layout->addWidget( myMedCheck, 4, 0, 1, 4 );
317 box3Layout->addWidget( myMedFile, 5, 0, 1, 3 );
318 box3Layout->addWidget( myMedBtn, 5, 3 );
319 box3Layout->addWidget( labMed, 6, 0 );
320 box3Layout->addWidget( myMedSize, 6, 1 );
321 box3Layout->addWidget( myVisuCheck, 7, 0, 1, 4 );
324 myProgress = new QProgressBar( this );
325 myProgress->setTextVisible( false );
326 myProgress->setFixedHeight( 10 );
329 myStartBtn = new QPushButton( tr( "START_BTN" ), this );
330 myCancelBtn = new QPushButton( tr( "CANCEL_BTN" ), this );
331 QHBoxLayout* btnLayout = new QHBoxLayout;
332 btnLayout->addWidget( myStartBtn );
333 btnLayout->addStretch();
334 btnLayout->addWidget( myCancelBtn );
336 topLayout->addWidget( box1, 0, 0, 1, 2 );
337 topLayout->addWidget( box2, 1, 0, 1, 2 );
338 topLayout->addWidget( labIter, 2, 0 );
339 topLayout->addWidget( myIter, 2, 1 );
340 topLayout->addWidget( box3, 3, 0, 1, 2 );
341 topLayout->addWidget( myProgress, 4, 0, 1, 2 );
342 topLayout->addLayout( btnLayout, 5, 0, 1, 2 );
344 // signals and slots connections
345 connect( myJpegBtn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
346 connect( myMedBtn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
347 connect( myStartRandom, SIGNAL( clicked() ), this, SLOT( updateState() ) );
348 connect( myBaseRandom, SIGNAL( clicked() ), this, SLOT( toggled() ) );
349 connect( myBaseDefault, SIGNAL( clicked() ), this, SLOT( toggled() ) );
350 connect( myJpegCheck, SIGNAL( clicked() ), this, SLOT( updateState() ) );
351 connect( myMedCheck, SIGNAL( clicked() ), this, SLOT( updateState() ) );
352 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
353 connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( close() ) );
356 myStartX->setValue( 0.0 ); myStartY->setValue( 0.0 );
357 myStartRandom->setChecked( true );
358 myX1->setValue( 0.5 ); myY1->setValue( 1.0 );
359 myX2->setValue( 0.0 ); myY2->setValue( 0.0 );
360 myX3->setValue( 1.0 ); myY3->setValue( 0.0 );
361 myBaseRandom->setChecked( false );
362 myBaseDefault->setChecked( true );
363 myIter->setValue( 1000 );
364 myJpegCheck->setChecked( false );
365 myJpegSize->setValue( 200 );
366 myMedCheck->setChecked( false );
367 myMedSize->setValue( 100 );
368 myVisuCheck->setChecked( true );
370 myVisuCheck->setVisible( false );
378 SierpinskyGUI_RunDlg::~SierpinskyGUI_RunDlg()
390 void SierpinskyGUI_RunDlg::onBrowse()
392 const QObject* snd = sender();
393 bool jpg = snd == myJpegBtn;
394 QString aFileName = SUIT_FileDlg::getFileName( this,
395 jpg ? myJpegFile->text() : myMedFile->text(),
396 (jpg ? tr( "JPEG_FILES") : tr( "MED_FILES" )).split( ":", QString::SkipEmptyParts ),
397 jpg ? tr( "EXPORT_JPEG_FILE" ) : tr( "EXPORT_MED_FILE" ),
399 if ( !aFileName.isEmpty() ) {
400 jpg ? myJpegFile->setText( aFileName ) : myMedFile->setText( aFileName );
405 * Update widgets state
407 void SierpinskyGUI_RunDlg::updateState()
409 myStartX->setEnabled( !myStartRandom->isChecked() );
410 myStartY->setEnabled( !myStartRandom->isChecked() );
412 myX1->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
413 myY1->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
414 myX2->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
415 myY2->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
416 myX3->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
417 myY3->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
419 myJpegFile->setEnabled( myJpegCheck->isChecked() );
420 myJpegBtn->setEnabled( myJpegCheck->isChecked() );
421 myJpegSize->setEnabled( myJpegCheck->isChecked() );
423 myMedFile->setEnabled( myMedCheck->isChecked() );
424 myMedBtn->setEnabled( myMedCheck->isChecked() );
425 myMedSize->setEnabled( myMedCheck->isChecked() );
426 myVisuCheck->setEnabled( myMedCheck->isChecked() );
430 * Toggle 'Base points' mode
432 void SierpinskyGUI_RunDlg::toggled()
434 const QObject* snd = sender();
435 if ( snd == myBaseRandom && myBaseRandom->isChecked() ) myBaseDefault->setChecked( false );
436 if ( snd == myBaseDefault && myBaseDefault->isChecked() ) myBaseRandom->setChecked( false );
441 * Called when user presses 'Start' button
443 void SierpinskyGUI_RunDlg::accept()
445 RANDOMIZER_ORB::RANDOMIZER_var aRandGen = getRandomizerEngine();
446 SIERPINSKY_ORB::SIERPINSKY_var aSierpGen = getSierpinskyEngine();
448 if( CORBA::is_nil( aRandGen ) || CORBA::is_nil( aSierpGen ) ) {
449 SUIT_MessageBox::critical( this,
459 if ( myJpegCheck->isChecked() ) {
460 aJPEGFile = myJpegFile->text().trimmed();
461 aJPEGSize = myJpegSize->value();
462 if ( aJPEGFile.isEmpty() || aJPEGSize <= 0 ) {
463 int res = SUIT_MessageBox::warning( this,
465 tr( "JPEG_PARAMETERS_ERROR" ),
466 tr( "YES_BTN"), tr( "NO_BTN" ), 0, 1, 0 );
474 if ( myMedCheck->isChecked() ) {
475 aMEDFile = myMedFile->text().trimmed();
476 aMEDSize = myMedSize->value();
477 if ( aMEDFile.isEmpty() || aMEDSize <= 0 ) {
478 int res = SUIT_MessageBox::warning( this,
480 tr( "MED_PARAMETERS_ERROR" ),
481 tr( "YES_BTN"), tr( "NO_BTN" ), 0, 1, 0 );
487 double x = myStartX->value();
488 double y = myStartY->value();
489 if ( myStartRandom->isChecked() )
490 aRandGen->InitPoint( x, y );
493 if ( myBaseDefault->isChecked() ) {
494 aSierpGen->Reset(); // use default values from engine
497 double x1 = myX1->value();
498 double y1 = myY1->value();
499 double x2 = myX2->value();
500 double y2 = myY2->value();
501 double x3 = myX3->value();
502 double y3 = myY3->value();
503 if ( myBaseRandom->isChecked() ) {
504 aRandGen->InitPoint( x1, y1 );
505 aRandGen->InitPoint( x2, y2 );
506 aRandGen->InitPoint( x3, y3 );
508 aSierpGen->Init( x1, y1, x2, y2, x3, y3 );
512 int iter = myIter->value();
515 myProgress->setMaximum( iter );
516 myProgress->setValue( 0 );
518 myThread = new MyThread( this, x, y, iter );
520 myThread->init( x, y, iter );
521 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
522 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
523 myStartBtn->setText( tr( "STOP_BTN" ) );
524 box1->setEnabled( false );
525 box2->setEnabled( false );
526 box3->setEnabled( false );
527 myIter->setEnabled( false );
531 * Called when user presses 'Stop' button
533 void SierpinskyGUI_RunDlg::stop()
536 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
537 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
538 myStartBtn->setText( tr( "START_BTN" ) );
539 myProgress->setValue( 0 );
540 box1->setEnabled( true );
541 box2->setEnabled( true );
542 box3->setEnabled( true );
543 myIter->setEnabled( true );
547 * Progress thread calls this method to update progress bar state
549 void SierpinskyGUI_RunDlg::nextStep( const int step )
552 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
553 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
554 myStartBtn->setText( tr( "START_BTN" ) );
555 myProgress->setValue( 0 );
556 box1->setEnabled( true );
557 box2->setEnabled( true );
558 box3->setEnabled( true );
559 myIter->setEnabled( true );
562 if ( myJpegCheck->isChecked() ) {
563 QString aJPEGFile = myJpegFile->text().trimmed();
564 int aJPEGSize = myJpegSize->value();
565 if ( !aJPEGFile.isEmpty() && aJPEGSize > 0 ) {
566 bool res = getSierpinskyEngine()->ExportToJPEG( aJPEGFile.toLatin1().data(), aJPEGSize );
568 // error: can't create JPEG image
573 if ( myMedCheck->isChecked() ) {
574 QString aMEDFile = myMedFile->text().trimmed();
575 double aMEDSize = myMedSize->value();
576 if ( !aMEDFile.isEmpty() && aMEDSize > 0 ) {
577 bool res = getSierpinskyEngine()->ExportToMED( aMEDFile.toLatin1().data(), aMEDSize );
579 if ( res && myVisuCheck->isChecked() ) {
580 VISU::VISU_Gen_var aVisuGen = getVisuEngine();
581 if ( !CORBA::is_nil( aVisuGen ) ) {
582 VISU::Result_var aResult = aVisuGen->ImportFile( aMEDFile.toLatin1().data() );
583 if ( !CORBA::is_nil( aResult ) )
584 aVisuGen->MeshOnEntity( aResult, "Sierpinsky", VISU::NODE );
585 myModule->getApp()->updateObjectBrowser( true );
593 myProgress->setValue( myProgress->maximum() - step );
598 * Process progress event
600 void SierpinskyGUI_RunDlg::customEvent( QEvent* e )
602 if ( e->type() == MY_EVENT ) {
603 MyEvent* me = (MyEvent*)e;
604 nextStep( me->iter() );