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
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)
52 #include CORBA_CLIENT_HEADER(VISU_Gen)
55 * Get Randomizer component engine
57 static RANDOMIZER_ORB::RANDOMIZER_var getRandomizerEngine()
59 static RANDOMIZER_ORB::RANDOMIZER_var aGen;
60 if( CORBA::is_nil( aGen ) ) {
62 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
63 Engines::Component_var aComponent = aLCC.FindOrLoad_Component("FactoryServerPy","RANDOMIZER");
64 aGen = RANDOMIZER_ORB::RANDOMIZER::_narrow( aComponent );
66 catch (CORBA::Exception&){
67 MESSAGE("Caught CORBA::Exception.");
70 MESSAGE("Caught unknown exception.");
77 * Get Sierpinsky component engine
79 static SIERPINSKY_ORB::SIERPINSKY_var getSierpinskyEngine()
81 static SIERPINSKY_ORB::SIERPINSKY_var aGen;
82 if( CORBA::is_nil( aGen ) ) {
84 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
85 Engines::Component_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","SIERPINSKY");
86 aGen = SIERPINSKY_ORB::SIERPINSKY::_narrow( aComponent );
88 catch (CORBA::Exception&){
89 MESSAGE("Caught CORBA::Exception.");
92 MESSAGE("Caught unknown exception.");
99 * Get VISU component engine
101 static VISU::VISU_Gen_var getVisuEngine()
103 static VISU::VISU_Gen_var aGen;
104 if( CORBA::is_nil( aGen ) ) {
106 SALOME_LifeCycleCORBA aLCC(SalomeApp_Application::namingService());
107 Engines::Component_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
108 aGen = VISU::VISU_Gen::_narrow( aComponent );
110 catch (CORBA::Exception&){
111 MESSAGE("Caught CORBA::Exception.");
114 MESSAGE("Caught unknown exception.");
121 #define MY_EVENT QEvent::User + 555
122 class MyEvent : public QEvent
125 MyEvent( const int iter ) : QEvent( (QEvent::Type)(MY_EVENT) ), myIter( iter ) {}
126 int iter() const { return myIter; }
133 * Progress thread class
135 class MyThread : public QThread
138 MyThread( SierpinskyGUI_RunDlg* parent, const double x, const double y, const int nbIter ) :
139 myParent( parent ), myStopped( false ), myX( x ), myY( y ), myNbIter( nbIter ) { start(); }
141 void init( const double x, const double y, const int nbIter )
148 void stop() { myStopped = true; }
153 while ( !myStopped && myNbIter-- ) {
154 int ni = getRandomizerEngine()->NextIteration();
155 getSierpinskyEngine()->NextPoint( myX, myY, ni, myX, myY );
156 QApplication::postEvent( myParent, new MyEvent( myNbIter ) );
162 SierpinskyGUI_RunDlg* myParent;
169 #define MARGIN_SIZE 11
170 #define SPACING_SIZE 6
175 SierpinskyGUI_RunDlg::SierpinskyGUI_RunDlg( QWidget* parent, SierpinskyGUI* module )
176 : QDialog( parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint ),
177 myThread( 0 ), myModule( module )
179 setAttribute( Qt::WA_DeleteOnClose );
181 setObjectName("SierpinskyGUI_RunDlg");
184 setWindowTitle( tr( "CAPTION" ) );
185 setSizeGripEnabled( true );
187 QGridLayout* topLayout = new QGridLayout( this );
188 topLayout->setMargin( MARGIN_SIZE ); topLayout->setSpacing( SPACING_SIZE );
191 box1 = new QGroupBox( tr( "START_POINT" ), this );
192 QGridLayout* box1Layout = new QGridLayout( box1 );
193 box1Layout->setAlignment( Qt::AlignTop );
194 box1Layout->setMargin( MARGIN_SIZE );
195 box1Layout->setSpacing( SPACING_SIZE );
197 QLabel* labX = new QLabel( "X:", box1 );
198 myStartX = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 ,box1);
199 myStartX->setMinimumWidth( 150 );
201 QLabel* labY = new QLabel( "Y:", box1 );
202 myStartY = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 ,box1);
203 myStartY->setMinimumWidth( 150 );
205 myStartRandom = new QCheckBox( tr( "RANDOM" ), box1 );
207 box1Layout->addWidget( labX, 0, 0 );
208 box1Layout->addWidget( myStartX, 0, 1 );
209 box1Layout->addWidget( labY, 0, 2 );
210 box1Layout->addWidget( myStartY, 0, 3 );
211 box1Layout->addWidget( myStartRandom, 1, 1 );
214 box2 = new QGroupBox( tr( "BASE_POINTS" ), this );
215 QGridLayout* box2Layout = new QGridLayout( box2 );
216 box2Layout->setAlignment( Qt::AlignTop );
217 box2Layout->setMargin( MARGIN_SIZE );
218 box2Layout->setSpacing( SPACING_SIZE );
220 QLabel* labX1 = new QLabel( "X1:", box2 );
221 myX1 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
222 myX1->setMinimumWidth( 150 );
224 QLabel* labY1 = new QLabel( "Y1:", box2 );
225 myY1 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
226 myY1->setMinimumWidth( 150 );
228 QLabel* labX2 = new QLabel( "X2:", box2 );
229 myX2 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1 , box2);
230 myX2->setMinimumWidth( 150 );
232 QLabel* labY2 = new QLabel( "Y2:", box2 );
233 myY2 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
234 myY2->setMinimumWidth( 150 );
236 QLabel* labX3 = new QLabel( "X3:", box2 );
237 myX3 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
238 myX3->setMinimumWidth( 150 );
240 QLabel* labY3 = new QLabel( "Y3:", box2 );
241 myY3 = new QtxDoubleSpinBox( 0.0, 1.0, 0.1, box2);
242 myY3->setMinimumWidth( 150 );
244 myBaseRandom = new QCheckBox( tr( "RANDOM" ), box2 );
245 myBaseDefault = new QCheckBox( tr( "DEFAULT" ), box2 );
247 box2Layout->addWidget( labX1, 0, 0 );
248 box2Layout->addWidget( myX1, 0, 1 );
249 box2Layout->addWidget( labY1, 0, 2 );
250 box2Layout->addWidget( myY1, 0, 3 );
251 box2Layout->addWidget( labX2, 1, 0 );
252 box2Layout->addWidget( myX2, 1, 1 );
253 box2Layout->addWidget( labY2, 1, 2 );
254 box2Layout->addWidget( myY2, 1, 3 );
255 box2Layout->addWidget( labX3, 2, 0 );
256 box2Layout->addWidget( myX3, 2, 1 );
257 box2Layout->addWidget( labY3, 2, 2 );
258 box2Layout->addWidget( myY3, 2, 3 );
259 box2Layout->addWidget( myBaseRandom, 3, 1 );
260 box2Layout->addWidget( myBaseDefault, 3, 3 );
262 // number of iterations
263 QLabel* labIter = new QLabel( tr( "NB_ITERATIONS" ), this );
264 myIter = new QSpinBox( this );
265 myIter->setMinimum(1);
266 myIter->setMaximum(100000);
267 myIter->setSingleStep(1);
270 box3 = new QGroupBox( tr( "RESULTS" ), this );
271 QGridLayout* box3Layout = new QGridLayout( box3 );
272 box3Layout->setAlignment( Qt::AlignTop );
273 box3Layout->setMargin( MARGIN_SIZE );
274 box3Layout->setSpacing( SPACING_SIZE );
276 myJpegCheck = new QCheckBox( tr( "EXPORT_2_JPEG" ), box3 );
277 myJpegFile = new QLineEdit( box3 );
278 myJpegFile->setMinimumWidth( 300 );
280 myJpegBtn = new QPushButton( "...", box3 );
281 myJpegBtn->setFixedSize( 20, 20 );
283 QLabel* labJpeg = new QLabel( tr( "IMAGE_SIZE" ), box3 );
284 myJpegSize = new QSpinBox( box3 );
285 myJpegSize->setMinimum(0);
286 myJpegSize->setMaximum(1280);
287 myJpegSize->setSingleStep(10);
288 myJpegSize->setMinimumWidth( 150 );
290 QFrame* line = new QFrame( box3 );
291 line->setFrameStyle( QFrame::HLine | QFrame::Sunken );
293 myMedCheck = new QCheckBox( tr( "EXPORT_2_MED" ), box3 );
294 myMedFile = new QLineEdit( box3 );
295 myMedFile->setMinimumWidth( 300 );
297 myMedBtn = new QPushButton( "...", box3 );
298 myMedBtn->setFixedSize( 20, 20 );
300 QLabel* labMed = new QLabel( tr( "MESH_SIZE" ), box3 );
301 myMedSize = new QtxDoubleSpinBox( 0.0, 1000, 1.0, box3);
302 myMedSize->setMinimumWidth( 150 );
304 myVisuCheck = new QCheckBox( tr( "IMPORT_MED_2_VISU" ), box3 );
306 box3Layout->addWidget( myJpegCheck, 0, 0, 1, 4 );
307 box3Layout->addWidget( myJpegFile, 1, 0, 1, 3 );
308 box3Layout->addWidget( myJpegBtn, 1, 3 );
309 box3Layout->addWidget( labJpeg, 2, 0 );
310 box3Layout->addWidget( myJpegSize, 2, 1 );
311 box3Layout->addWidget( line, 3, 0, 1, 4 );
312 box3Layout->addWidget( myMedCheck, 4, 0, 1, 4 );
313 box3Layout->addWidget( myMedFile, 5, 0, 1, 3 );
314 box3Layout->addWidget( myMedBtn, 5, 3 );
315 box3Layout->addWidget( labMed, 6, 0 );
316 box3Layout->addWidget( myMedSize, 6, 1 );
317 box3Layout->addWidget( myVisuCheck, 7, 0, 1, 4 );
320 myProgress = new QProgressBar( this );
321 myProgress->setTextVisible( false );
322 myProgress->setFixedHeight( 10 );
325 myStartBtn = new QPushButton( tr( "START_BTN" ), this );
326 myCancelBtn = new QPushButton( tr( "CANCEL_BTN" ), this );
327 QHBoxLayout* btnLayout = new QHBoxLayout;
328 btnLayout->addWidget( myStartBtn );
329 btnLayout->addStretch();
330 btnLayout->addWidget( myCancelBtn );
332 topLayout->addWidget( box1, 0, 0, 1, 2 );
333 topLayout->addWidget( box2, 1, 0, 1, 2 );
334 topLayout->addWidget( labIter, 2, 0 );
335 topLayout->addWidget( myIter, 2, 1 );
336 topLayout->addWidget( box3, 3, 0, 1, 2 );
337 topLayout->addWidget( myProgress, 4, 0, 1, 2 );
338 topLayout->addLayout( btnLayout, 5, 0, 1, 2 );
340 // signals and slots connections
341 connect( myJpegBtn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
342 connect( myMedBtn, SIGNAL( clicked() ), this, SLOT( onBrowse() ) );
343 connect( myStartRandom, SIGNAL( clicked() ), this, SLOT( updateState() ) );
344 connect( myBaseRandom, SIGNAL( clicked() ), this, SLOT( toggled() ) );
345 connect( myBaseDefault, SIGNAL( clicked() ), this, SLOT( toggled() ) );
346 connect( myJpegCheck, SIGNAL( clicked() ), this, SLOT( updateState() ) );
347 connect( myMedCheck, SIGNAL( clicked() ), this, SLOT( updateState() ) );
348 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
349 connect( myCancelBtn, SIGNAL( clicked() ), this, SLOT( close() ) );
352 myStartX->setValue( 0.0 ); myStartY->setValue( 0.0 );
353 myStartRandom->setChecked( true );
354 myX1->setValue( 0.5 ); myY1->setValue( 1.0 );
355 myX2->setValue( 0.0 ); myY2->setValue( 0.0 );
356 myX3->setValue( 1.0 ); myY3->setValue( 0.0 );
357 myBaseRandom->setChecked( false );
358 myBaseDefault->setChecked( true );
359 myIter->setValue( 1000 );
360 myJpegCheck->setChecked( false );
361 myJpegSize->setValue( 200 );
362 myMedCheck->setChecked( false );
363 myMedSize->setValue( 100 );
364 myVisuCheck->setChecked( true );
371 SierpinskyGUI_RunDlg::~SierpinskyGUI_RunDlg()
383 void SierpinskyGUI_RunDlg::onBrowse()
385 const QObject* snd = sender();
386 bool jpg = snd == myJpegBtn;
387 QString aFileName = SUIT_FileDlg::getFileName( this,
388 jpg ? myJpegFile->text() : myMedFile->text(),
389 (jpg ? tr( "JPEG_FILES") : tr( "MED_FILES" )).split( ":", QString::SkipEmptyParts ),
390 jpg ? tr( "EXPORT_JPEG_FILE" ) : tr( "EXPORT_MED_FILE" ),
392 if ( !aFileName.isEmpty() ) {
393 jpg ? myJpegFile->setText( aFileName ) : myMedFile->setText( aFileName );
398 * Update widgets state
400 void SierpinskyGUI_RunDlg::updateState()
402 myStartX->setEnabled( !myStartRandom->isChecked() );
403 myStartY->setEnabled( !myStartRandom->isChecked() );
405 myX1->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
406 myY1->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
407 myX2->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
408 myY2->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
409 myX3->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
410 myY3->setEnabled( !myBaseRandom->isChecked() && !myBaseDefault->isChecked() );
412 myJpegFile->setEnabled( myJpegCheck->isChecked() );
413 myJpegBtn->setEnabled( myJpegCheck->isChecked() );
414 myJpegSize->setEnabled( myJpegCheck->isChecked() );
416 myMedFile->setEnabled( myMedCheck->isChecked() );
417 myMedBtn->setEnabled( myMedCheck->isChecked() );
418 myMedSize->setEnabled( myMedCheck->isChecked() );
419 myVisuCheck->setEnabled( myMedCheck->isChecked() );
423 * Toggle 'Base points' mode
425 void SierpinskyGUI_RunDlg::toggled()
427 const QObject* snd = sender();
428 if ( snd == myBaseRandom && myBaseRandom->isChecked() ) myBaseDefault->setChecked( false );
429 if ( snd == myBaseDefault && myBaseDefault->isChecked() ) myBaseRandom->setChecked( false );
434 * Called when user presses 'Start' button
436 void SierpinskyGUI_RunDlg::accept()
438 RANDOMIZER_ORB::RANDOMIZER_var aRandGen = getRandomizerEngine();
439 SIERPINSKY_ORB::SIERPINSKY_var aSierpGen = getSierpinskyEngine();
441 if( CORBA::is_nil( aRandGen ) || CORBA::is_nil( aSierpGen ) ) {
442 SUIT_MessageBox::critical( this,
452 if ( myJpegCheck->isChecked() ) {
453 aJPEGFile = myJpegFile->text().trimmed();
454 aJPEGSize = myJpegSize->value();
455 if ( aJPEGFile.isEmpty() || aJPEGSize <= 0 ) {
456 int res = SUIT_MessageBox::warning( this,
458 tr( "JPEG_PARAMETERS_ERROR" ),
459 tr( "YES_BTN"), tr( "NO_BTN" ), 0, 1, 0 );
467 if ( myMedCheck->isChecked() ) {
468 aMEDFile = myMedFile->text().trimmed();
469 aMEDSize = myMedSize->value();
470 if ( aMEDFile.isEmpty() || aMEDSize <= 0 ) {
471 int res = SUIT_MessageBox::warning( this,
473 tr( "MED_PARAMETERS_ERROR" ),
474 tr( "YES_BTN"), tr( "NO_BTN" ), 0, 1, 0 );
480 double x = myStartX->value();
481 double y = myStartY->value();
482 if ( myStartRandom->isChecked() )
483 aRandGen->InitPoint( x, y );
486 if ( myBaseDefault->isChecked() ) {
487 aSierpGen->Reset(); // use default values from engine
490 double x1 = myX1->value();
491 double y1 = myY1->value();
492 double x2 = myX2->value();
493 double y2 = myY2->value();
494 double x3 = myX3->value();
495 double y3 = myY3->value();
496 if ( myBaseRandom->isChecked() ) {
497 aRandGen->InitPoint( x1, y1 );
498 aRandGen->InitPoint( x2, y2 );
499 aRandGen->InitPoint( x3, y3 );
501 aSierpGen->Init( x1, y1, x2, y2, x3, y3 );
505 int iter = myIter->value();
508 myProgress->setMaximum( iter );
509 myProgress->setValue( 0 );
511 myThread = new MyThread( this, x, y, iter );
513 myThread->init( x, y, iter );
514 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
515 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
516 myStartBtn->setText( tr( "STOP_BTN" ) );
517 box1->setEnabled( false );
518 box2->setEnabled( false );
519 box3->setEnabled( false );
520 myIter->setEnabled( false );
524 * Called when user presses 'Stop' button
526 void SierpinskyGUI_RunDlg::stop()
529 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
530 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
531 myStartBtn->setText( tr( "START_BTN" ) );
532 myProgress->setValue( 0 );
533 box1->setEnabled( true );
534 box2->setEnabled( true );
535 box3->setEnabled( true );
536 myIter->setEnabled( true );
540 * Progress thread calls this method to update progress bar state
542 void SierpinskyGUI_RunDlg::nextStep( const int step )
545 disconnect( myStartBtn, SIGNAL( clicked() ), this, SLOT( stop() ) );
546 connect( myStartBtn, SIGNAL( clicked() ), this, SLOT( accept() ) );
547 myStartBtn->setText( tr( "START_BTN" ) );
548 myProgress->setValue( 0 );
549 box1->setEnabled( true );
550 box2->setEnabled( true );
551 box3->setEnabled( true );
552 myIter->setEnabled( true );
555 if ( myJpegCheck->isChecked() ) {
556 QString aJPEGFile = myJpegFile->text().trimmed();
557 int aJPEGSize = myJpegSize->value();
558 if ( !aJPEGFile.isEmpty() && aJPEGSize > 0 ) {
559 bool res = getSierpinskyEngine()->ExportToJPEG( aJPEGFile.toLatin1().data(), aJPEGSize );
561 // error: can't create JPEG image
566 if ( myMedCheck->isChecked() ) {
567 QString aMEDFile = myMedFile->text().trimmed();
568 double aMEDSize = myMedSize->value();
569 if ( !aMEDFile.isEmpty() && aMEDSize > 0 ) {
570 bool res = getSierpinskyEngine()->ExportToMED( aMEDFile.toLatin1().data(), aMEDSize );
571 if ( res && myVisuCheck->isChecked() ) {
572 VISU::VISU_Gen_var aVisuGen = getVisuEngine();
573 if ( !CORBA::is_nil( aVisuGen ) ) {
574 VISU::Result_var aResult = aVisuGen->ImportFile( aMEDFile.toLatin1().data() );
575 if ( !CORBA::is_nil( aResult ) )
576 aVisuGen->MeshOnEntity( aResult, "Sierpinsky", VISU::NODE );
577 myModule->getApp()->updateObjectBrowser( true );
584 myProgress->setValue( myProgress->maximum() - step );
589 * Process progress event
591 void SierpinskyGUI_RunDlg::customEvent( QEvent* e )
593 if ( e->type() == MY_EVENT ) {
594 MyEvent* me = (MyEvent*)e;
595 nextStep( me->iter() );