Salome HOME
The bathymetry is changed to their base altitude class for geometry objects (Bug...
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_CalculationDlg.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_CalculationDlg.h"
24
25 #include "HYDROGUI_ObjSelector.h"
26 #include "HYDROGUI_Tool.h"
27 #include "HYDROGUI_DataBrowser.h"
28 #include "HYDROGUI_DataModel.h"
29 #include "HYDROGUI_Module.h"
30 #include "HYDROGUI_DataObject.h"
31 #include "HYDROGUI_NameValidator.h"
32 #include "HYDROGUI_Region.h"
33 #include "HYDROGUI_Zone.h"
34
35 #include <HYDROData_Document.h>
36 #include <HYDROData_Entity.h>
37
38 #include <CAM_Application.h>
39 #include <LightApp_DataObject.h>
40
41 #include <SUIT_DataObject.h>
42 #include <SUIT_FileDlg.h>
43 #include <SUIT_ResourceMgr.h>
44 #include <SUIT_Session.h>
45 #include <SUIT_Study.h>
46
47 #include <LightApp_Application.h>
48 #include <SUIT_Desktop.h>
49 #include <SUIT_MessageBox.h>
50
51 #include <QGroupBox>
52 #include <QLabel>
53 #include <QLayout>
54 #include <QLineEdit>
55 #include <QListWidget>
56 #include <QPicture>
57 #include <QPushButton>
58 #include <QToolButton>
59 #include <QWizardPage>
60 #include <QComboBox>
61 #include <QStackedWidget>
62
63 HYDROGUI_CalculationDlg::HYDROGUI_CalculationDlg( HYDROGUI_Module* theModule, const QString& theTitle )
64 : HYDROGUI_Wizard( theModule, theTitle )
65 {
66   addPage( createObjectsPage() );
67   addPage( createGroupsPage() );
68   addPage( createZonesPage() );
69 }
70
71 HYDROGUI_CalculationDlg::~HYDROGUI_CalculationDlg()
72 {
73 }
74
75 void HYDROGUI_CalculationDlg::reset()
76 {
77   myObjectName->clear();
78   myGeomObjects->clear();
79   myPolylineName->clear();
80   myAvailableGeomObjects->clear();
81 }
82
83 QWizardPage* HYDROGUI_CalculationDlg::createObjectsPage() {
84   QWizardPage* aPage = new QWizardPage( mainFrame() );
85   QFrame* aFrame = new QFrame( aPage );
86
87   // Calculation name
88   myObjectName = new QLineEdit( aPage );
89   myValidator = new HYDROGUI_NameValidator(module(), myObjectName);
90   myObjectName->setValidator( myValidator );
91
92   connect( myValidator, SIGNAL( emptyName() ), SLOT( onEmptyName() ) );
93   connect( myValidator, SIGNAL( alreadyExists( QString ) ), SLOT( onAlreadyExists( QString ) ) );
94
95   myPolylineName = new QComboBox( aPage );
96   connect( myPolylineName, SIGNAL( activated( const QString & ) ), 
97     SIGNAL( boundarySelected( const QString & ) ) );
98
99   myGeomObjects = new QListWidget( aPage );
100   myGeomObjects->setSelectionMode( QListWidget::ExtendedSelection );
101   myGeomObjects->setEditTriggers( QListWidget::NoEditTriggers );
102   myGeomObjects->setViewMode( QListWidget::ListMode );
103   myGeomObjects->setSortingEnabled( true );
104
105   myAvailableGeomObjects = new QListWidget( aPage );
106   myAvailableGeomObjects->setSelectionMode( QListWidget::ExtendedSelection );
107   myAvailableGeomObjects->setEditTriggers( QListWidget::NoEditTriggers );
108   myAvailableGeomObjects->setViewMode( QListWidget::ListMode );
109   myAvailableGeomObjects->setSortingEnabled( true );
110
111   connect( myGeomObjects, SIGNAL( itemSelectionChanged() ), 
112     SIGNAL( objectsSelected() ) );
113
114   QFrame* anObjectsFrame = new QFrame( aPage );
115   QGridLayout* anObjsLayout = new QGridLayout( anObjectsFrame );
116   anObjsLayout->setMargin( 5 );
117   anObjsLayout->setSpacing( 5 );
118   anObjectsFrame->setLayout( anObjsLayout );
119
120   QFrame* aBtnsFrame = new QFrame( anObjectsFrame );
121   QVBoxLayout* aBtnsLayout = new QVBoxLayout( aBtnsFrame );
122   aBtnsLayout->setMargin( 5 );
123   aBtnsLayout->setSpacing( 5 );
124   aBtnsFrame->setLayout( aBtnsLayout );
125   QPushButton* anAddBtn = new QPushButton( tr("INCLUDE"), aBtnsFrame );
126   QPushButton* aRemoveBtn = new QPushButton( tr("EXCLUDE"), aBtnsFrame );
127
128   // Fill the butons frame with two buttons
129   aBtnsLayout->addWidget( anAddBtn );
130   aBtnsLayout->addWidget( aRemoveBtn );
131   aBtnsLayout->addStretch( 1 );
132
133   QLabel* anIncludedLabel = new QLabel( tr( "INCLUDED_OBJECTS" ), anObjectsFrame );
134   QLabel* anObjectsLabel = new QLabel( tr( "CALCULATION_REFERENCE_OBJECTS" ), anObjectsFrame );
135
136   // Fill the objects frame with two lists, two labels and with buttons frame
137   anObjsLayout->addWidget( anObjectsLabel, 0, 0, Qt::AlignHCenter );
138   anObjsLayout->addWidget( anIncludedLabel, 0, 2, Qt::AlignHCenter );
139   anObjsLayout->addWidget( myAvailableGeomObjects, 1, 0, Qt::AlignHCenter );
140   anObjsLayout->addWidget( aBtnsFrame, 1, 1, Qt::AlignHCenter );
141   anObjsLayout->addWidget( myGeomObjects, 1, 2, Qt::AlignHCenter );
142
143
144   QLabel* aNameLabel = new QLabel( tr( "NAME" ), aPage );
145   QLabel* aLimitsLabel = new QLabel( tr( "LIMITS" ), aPage );
146
147   // Fill the page
148   QGridLayout* aPageLayout = new QGridLayout( aPage );
149   aPageLayout->setMargin( 5 );
150   aPageLayout->setSpacing( 5 );
151   aPageLayout->setVerticalSpacing( 10 );
152   aPageLayout->addWidget( aNameLabel,     0, 0, Qt::AlignHCenter );
153   aPageLayout->addWidget( myObjectName,   0, 1 );
154   aPageLayout->addWidget( aLimitsLabel,   1, 0, Qt::AlignHCenter );
155   aPageLayout->addWidget( myPolylineName, 1, 1 );
156   aPageLayout->addWidget( anObjectsFrame, 2, 0, 1, 2, Qt::AlignHCenter );
157
158   aPage->setLayout( aPageLayout );
159
160   connect( anAddBtn, SIGNAL( clicked() ), SIGNAL( addObjects() ) );
161   connect( aRemoveBtn, SIGNAL( clicked() ), SIGNAL( removeObjects() ) );
162
163   return aPage;
164 }
165
166 QWizardPage* HYDROGUI_CalculationDlg::createGroupsPage() {
167   QWizardPage* aPage = new QWizardPage( mainFrame() );
168   QFrame* aFrame = new QFrame( aPage );
169
170   myGroups = new QListWidget( aPage );
171   myGroups->setSelectionMode( QListWidget::ExtendedSelection );
172   myGroups->setEditTriggers( QListWidget::NoEditTriggers );
173   myGroups->setViewMode( QListWidget::ListMode );
174   myGroups->setSortingEnabled( true );
175
176   myAvailableGroups = new QListWidget( aPage );
177   myAvailableGroups->setSelectionMode( QListWidget::ExtendedSelection );
178   myAvailableGroups->setEditTriggers( QListWidget::NoEditTriggers );
179   myAvailableGroups->setViewMode( QListWidget::ListMode );
180   myAvailableGroups->setSortingEnabled( true );
181
182   connect( myGroups, SIGNAL( itemSelectionChanged() ), 
183     SIGNAL( groupsSelected() ) );
184
185   QFrame* aGroupsFrame = new QFrame( aPage );
186   QGridLayout* aGroupsLayout = new QGridLayout( aGroupsFrame );
187   aGroupsLayout->setMargin( 5 );
188   aGroupsLayout->setSpacing( 5 );
189   aGroupsFrame->setLayout( aGroupsLayout );
190
191   QFrame* aBtnsFrame = new QFrame( aGroupsFrame );
192   QVBoxLayout* aBtnsLayout = new QVBoxLayout( aBtnsFrame );
193   aBtnsLayout->setMargin( 5 );
194   aBtnsLayout->setSpacing( 5 );
195   aBtnsFrame->setLayout( aBtnsLayout );
196   QPushButton* anAddBtn = new QPushButton( tr("INCLUDE"), aBtnsFrame );
197   QPushButton* aRemoveBtn = new QPushButton( tr("EXCLUDE"), aBtnsFrame );
198
199   // Fill the butons frame with two buttons
200   aBtnsLayout->addWidget( anAddBtn );
201   aBtnsLayout->addWidget( aRemoveBtn );
202   aBtnsLayout->addStretch( 1 );
203
204   QLabel* anIncludedLabel = new QLabel( tr( "INCLUDED_GROUPS" ), aGroupsFrame );
205   QLabel* anAvailableLabel = new QLabel( tr( "AVAILABLE_GROUPS" ), aGroupsFrame );
206
207   // Fill the objects frame with two lists, two labels and with buttons frame
208   aGroupsLayout->addWidget( anAvailableLabel, 0, 0, Qt::AlignHCenter );
209   aGroupsLayout->addWidget( anIncludedLabel, 0, 2, Qt::AlignHCenter );
210   aGroupsLayout->addWidget( myAvailableGroups, 1, 0, Qt::AlignHCenter );
211   aGroupsLayout->addWidget( aBtnsFrame, 1, 1, Qt::AlignHCenter );
212   aGroupsLayout->addWidget( myGroups, 1, 2, Qt::AlignHCenter );
213
214   // Fill the page
215   QGridLayout* aPageLayout = new QGridLayout( aPage );
216   aPageLayout->setMargin( 5 );
217   aPageLayout->setSpacing( 5 );
218   aPageLayout->setVerticalSpacing( 10 );
219   aPageLayout->addWidget( aGroupsFrame, 0, 0, Qt::AlignHCenter );
220
221   aPage->setLayout( aPageLayout );
222
223   connect( anAddBtn, SIGNAL( clicked() ), SIGNAL( addGroups() ) );
224   connect( aRemoveBtn, SIGNAL( clicked() ), SIGNAL( removeGroups() ) );
225
226   return aPage;
227 }
228
229 QWizardPage* HYDROGUI_CalculationDlg::createZonesPage() {
230   QWizardPage* aPage = new QWizardPage( mainFrame() );
231   QFrame* aFrame = new QFrame( aPage );
232
233   QGridLayout* aLayout = new QGridLayout( aPage );
234   
235   myBrowser = new HYDROGUI_DataBrowser( module(), NULL, aPage );
236   myBrowser->setAutoOpenLevel( 3 );
237   aLayout->setMargin( 5 );
238   aLayout->setSpacing( 5 );
239
240   aLayout->addWidget( myBrowser, 0, 0, 1, 2 );
241
242   myBatimetryLabel = new QLabel( tr( "BATHYMETRY" ), aFrame );
243   myBathymetryChoice = new QComboBox( aFrame );
244
245   myBathymetryChoice->setVisible( false );
246   myBatimetryLabel->setVisible( false );
247
248   aLayout->addWidget( myBatimetryLabel, 1, 0 );
249   aLayout->addWidget( myBathymetryChoice, 1, 1 );
250
251   aPage->setLayout( aLayout );
252
253   connect( myBrowser, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
254   connect( myBrowser, SIGNAL( clicked( SUIT_DataObject* ) ), SIGNAL( clickedInZonesBrowser( SUIT_DataObject* ) ) );
255   connect( myBrowser, SIGNAL( clicked( SUIT_DataObject* ) ), SLOT( onSelected( SUIT_DataObject* ) ) );
256   connect( myBathymetryChoice, SIGNAL( activated( int ) ), SLOT( onMergeTypeSelected( int ) ) );
257   connect( myBrowser, 
258       SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
259       SLOT( onZonesDropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
260
261   return aPage;
262 }
263
264
265 bool HYDROGUI_CalculationDlg::acceptCurrent() const
266 {
267   QString anErrorMsg;
268
269   if ( myGeomObjects->count() == 0 )
270   {
271     anErrorMsg = tr( "EMPTY_GEOMETRY_OBJECTS" );
272   }
273
274   if ( !anErrorMsg.isEmpty() )
275   {
276     anErrorMsg += "\n" + tr( "INPUT_VALID_DATA" );
277     
278     QString aTitle = tr( "INSUFFICIENT_INPUT_DATA" );
279     SUIT_MessageBox::critical( module()->getApp()->desktop(), aTitle, anErrorMsg );
280   }
281
282   return anErrorMsg.isEmpty();
283 }
284
285 void HYDROGUI_CalculationDlg::onEmptyName()
286 {
287   QString aTitle = tr( "INSUFFICIENT_INPUT_DATA" );
288   QString aMessage = tr( "INCORRECT_OBJECT_NAME" ) + "\n" + tr( "INPUT_VALID_DATA" );
289   SUIT_MessageBox::critical( module()->getApp()->desktop(), aTitle, aMessage );
290 }
291
292 void HYDROGUI_CalculationDlg::onAlreadyExists( QString theName )
293 {
294   QString aTitle = tr( "INSUFFICIENT_INPUT_DATA" );
295   QString aMessage = QObject::tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( theName ) +
296                      "\n" + tr( "INPUT_VALID_DATA" );
297   SUIT_MessageBox::critical( module()->getApp()->desktop(), aTitle, aMessage );
298 }
299
300 void HYDROGUI_CalculationDlg::onZonesDropped( const QList<SUIT_DataObject*>& theList, 
301     SUIT_DataObject* theTargetParent, int theTargetRow, Qt::DropAction theDropAction )
302 {
303   QList<SUIT_DataObject*> aZonesList;
304   HYDROGUI_Zone* aZone;
305   // Get a list of dropped zones
306   for ( int i = 0; i < theList.length(); i++ )
307   {
308     aZone = dynamic_cast<HYDROGUI_Zone*>( theList.at( i ) );
309     if ( aZone )
310     {
311       aZonesList.append( aZone );
312     }
313   }
314   if ( aZonesList.length() > 0 )
315   {
316     // Get the target region
317     HYDROGUI_NamedObject* aRegionsRoot = dynamic_cast<HYDROGUI_NamedObject*>(theTargetParent);
318     if ( aRegionsRoot )
319     {
320       // Create a new region
321       emit createRegion( aZonesList );
322     }
323     else
324     {
325       HYDROGUI_Region* aRegion = dynamic_cast<HYDROGUI_Region*>(theTargetParent);
326       if ( aRegion )
327       {
328         emit moveZones( theTargetParent, aZonesList );
329       }
330     }
331   }
332 }
333
334 void HYDROGUI_CalculationDlg::onMergeTypeSelected( int theIndex )
335 {
336   int aType = myBathymetryChoice->itemData( theIndex ).toInt();
337   QString aText = myBathymetryChoice->itemText( theIndex );
338   emit setMergeType( aType, aText );
339 }
340
341 void HYDROGUI_CalculationDlg::onSelected( SUIT_DataObject* theObject )
342 {
343   bool doShow = false;
344   HYDROGUI_Zone* aZone = dynamic_cast<HYDROGUI_Zone*>( theObject );
345   if ( aZone )
346   {
347     doShow = aZone->isMergingNeed();
348   }
349
350   if ( doShow )
351   {
352     // Fill the merge type combo box
353     bool prevBlock = myBathymetryChoice->blockSignals( true );
354     myCurrentZone = aZone;
355     myBathymetryChoice->clear();
356     myBathymetryChoice->addItem( tr("MERGE_UNKNOWN"), HYDROData_Zone::Merge_UNKNOWN );
357     myBathymetryChoice->addItem( tr("MERGE_ZMIN"), HYDROData_Zone::Merge_ZMIN );
358     myBathymetryChoice->addItem( tr("MERGE_ZMAX"), HYDROData_Zone::Merge_ZMAX );
359     QStringList aList = aZone->getAltitudes();
360     for ( int i = 0; i < aList.length(); i++ )
361     {
362       myBathymetryChoice->addItem( aList.at( i ), HYDROData_Zone::Merge_Object );
363     }
364     // Select the current choice if any
365     int aCurIndex = 0;
366     switch ( aZone->getMergeType() )
367     {
368       case HYDROData_Zone::Merge_ZMIN:
369         aCurIndex = 1;
370         break;
371       case HYDROData_Zone::Merge_ZMAX:
372         aCurIndex = 2;
373         break;
374       case HYDROData_Zone::Merge_Object:
375         aCurIndex = 3 + aList.indexOf( aZone->text( HYDROGUI_DataObject::AltitudeObjId ) );
376         break;
377       default:
378         aCurIndex = 0; // Select unknown by default
379     }
380     myBathymetryChoice->setCurrentIndex( aCurIndex );
381     myBathymetryChoice->blockSignals( prevBlock );
382   }
383
384   myBathymetryChoice->setVisible( doShow );
385   myBatimetryLabel->setVisible( doShow );
386 }
387
388 void HYDROGUI_CalculationDlg::setObjectName( const QString& theName )
389 {
390   myObjectName->setText( theName );
391 }
392
393 QString HYDROGUI_CalculationDlg::getObjectName() const
394 {
395   return myObjectName->text();
396 }
397
398 void moveItems( QListWidget* theSource, QListWidget* theDest, const QStringList& theObjects )
399 {
400   QList<QListWidgetItem*> aFoundItems;
401   int anIdx;
402   QListWidgetItem* anItem;
403
404   for ( int i = 0, n = theObjects.length(); i < n; ++i )
405   {
406     QString anObjName = theObjects.at( i );
407     aFoundItems = theSource->findItems( anObjName, Qt::MatchExactly );
408     for ( anIdx = 0; anIdx < aFoundItems.length(); anIdx++ )
409     {
410       anItem = aFoundItems.at( anIdx );
411       // Remove this object from available objects list
412       anItem = theSource->takeItem( theSource->row( anItem ) );
413       // Add the item to the included objects list
414       theDest->addItem( anItem );
415     }
416   }
417 }
418
419 void HYDROGUI_CalculationDlg::includeGeomObjects( const QStringList& theObjects )
420 {
421   moveItems( myAvailableGeomObjects, myGeomObjects, theObjects );
422 }
423
424 void HYDROGUI_CalculationDlg::excludeGeomObjects( const QStringList& theObjects )
425 {
426   moveItems( myGeomObjects, myAvailableGeomObjects, theObjects );
427 }
428
429 void HYDROGUI_CalculationDlg::setBoundary( const QString& theObjName )
430 {
431   bool isBlocked = myPolylineName->blockSignals( true );
432   myPolylineName->setCurrentIndex( myPolylineName->findText( theObjName ) );
433   myPolylineName->blockSignals( isBlocked );
434 }
435
436 void HYDROGUI_CalculationDlg::setPolylineNames( const QStringList& theObjects, const QStringList& theObjectsEntries )
437 {
438   myPolylineName->clear();
439   myPolylineName->addItem( "", "" ); // No boundary item
440
441   for ( int i = 0, n = theObjects.length(); i < n; ++i )
442   {
443     myPolylineName->addItem( theObjects.at( i ), theObjectsEntries.at( i ) );
444   }
445 }
446 void HYDROGUI_CalculationDlg::setAllGeomObjects( const QStringList& theObjects, const QStringList& theObjectsEntries )
447 {
448   myAvailableGeomObjects->clear();
449
450   for ( int i = 0, n = theObjects.length(); i < n; ++i )
451   {
452     QString anObjName = theObjects.at( i );
453
454     QListWidgetItem* aListItem = new QListWidgetItem( anObjName, myAvailableGeomObjects );
455     aListItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
456     aListItem->setData( Qt::UserRole, theObjectsEntries.at( i ) );
457   }
458 }
459
460 QStringList getSelected( QListWidget* theWidget )
461 {
462   QStringList aResList;
463   QList<QListWidgetItem*> aList = theWidget->selectedItems();
464   for ( int i = 0, n = aList.length(); i < n; ++i )
465   {
466     aResList.append( aList.at( i )->text() );
467   }
468   return aResList;
469 }
470
471 QStringList HYDROGUI_CalculationDlg::getSelectedGeomObjects() const
472 {
473   return getSelected( myGeomObjects );
474 }
475
476 QStringList HYDROGUI_CalculationDlg::getSelectedAvailableGeomObjects() const
477 {
478   return getSelected( myAvailableGeomObjects );
479 }
480
481 void HYDROGUI_CalculationDlg::setEditedObject( const Handle(HYDROData_CalculationCase) theCase )
482 {
483   myEditedObject = theCase;
484   myValidator->setEditedObject( theCase );
485
486   // Build the calculation case subtree
487   module()->getDataModel()->buildCaseTree( myBrowser->root(), myEditedObject );
488
489   myBrowser->updateTree();
490   myBrowser->openLevels();
491   myBrowser->adjustColumnsWidth();
492   myBrowser->setAutoUpdate( true );
493   myBrowser->setUpdateModified( true );
494
495 }
496
497 HYDROGUI_Zone* HYDROGUI_CalculationDlg::getCurrentZone() const
498 {
499   return myCurrentZone;
500 }
501
502 void HYDROGUI_CalculationDlg::refreshZonesBrowser()
503 {
504   SUIT_DataObject* aRoot = myBrowser->root();
505   module()->getDataModel()->updateObjectTree( myEditedObject );
506   module()->getDataModel()->buildCaseTree( aRoot, myEditedObject );
507   myBrowser->updateTree( aRoot );
508 }
509
510 void HYDROGUI_CalculationDlg::onDataChanged()
511 {
512   SUIT_DataObject* aRoot = myBrowser->root();
513   module()->getDataModel()->buildCaseTree( aRoot, myEditedObject );
514   myBrowser->updateTree( aRoot );
515 }
516
517 void HYDROGUI_CalculationDlg::setAvailableGroups( const QStringList& theGroups )
518 {
519   myAvailableGroups->clear();
520   myGroups->clear();
521   foreach( QString aGroup, theGroups )
522     myAvailableGroups->addItem( aGroup );
523 }
524
525 QStringList HYDROGUI_CalculationDlg::getSelectedGroups() const
526 {
527   return getSelected( myGroups );
528 }
529
530 QStringList HYDROGUI_CalculationDlg::getSelectedAvailableGroups() const
531 {
532   return getSelected( myAvailableGroups );
533 }
534
535 void HYDROGUI_CalculationDlg::includeGroups( const QStringList& theObjects )
536 {
537   moveItems( myAvailableGroups, myGroups, theObjects );
538 }
539
540 void HYDROGUI_CalculationDlg::excludeGroups( const QStringList& theObjects )
541 {
542   moveItems( myGroups, myAvailableGroups, theObjects );
543 }