Salome HOME
Support #101: it is possible to start operation Obstacle - Create Box during creation...
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ImportGeomObjectOp.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_ImportGeomObjectOp.h"
24
25 #include "HYDROGUI_GeomObjectDlg.h"
26
27 #include "HYDROGUI_DataModel.h"
28 #include "HYDROGUI_Module.h"
29 #include "HYDROGUI_Tool.h"
30 #include "HYDROGUI_UpdateFlags.h"
31
32 #include <HYDROData_Obstacle.h>
33 #include <HYDROData_PolylineXY.h>
34 #include <HYDROData_Iterator.h>
35
36 #include <GEOMBase.h>
37
38 #include <SalomeApp_Study.h>
39
40 #include <LightApp_Application.h>
41 #include <LightApp_UpdateFlags.h>
42
43 #include <SUIT_Desktop.h>
44
45 #include <QDialog>
46
47 HYDROGUI_ImportGeomObjectOp::HYDROGUI_ImportGeomObjectOp( HYDROGUI_Module* theModule,  
48                                                           const int theOpType, 
49                                                           const int theGEOMOp )
50 : HYDROGUI_Operation( theModule ),
51   myOpType( theOpType ),
52   myGEOMOp( theGEOMOp ),
53   myGEOMOpName( "" ),
54   myIsToShowPanel( true )
55 {
56   if ( myOpType == ImportSelectedAsPolyline ) {
57     setName( tr( "IMPORT_GEOM_OBJECT_AS_POLYLINE" ) );
58   } else {
59     setName( tr( "IMPORT_GEOM_OBJECT_AS_OBSTACLE" ) );
60   }
61 }
62
63 HYDROGUI_ImportGeomObjectOp::~HYDROGUI_ImportGeomObjectOp()
64 {
65 }
66
67 void HYDROGUI_ImportGeomObjectOp::startOperation()
68 {
69   // Get GEOM objects to import
70   myGeomObjects.clear();
71
72   if ( myOpType == ImportSelectedAsObstacle ) {
73     myGeomObjects = 
74       HYDROGUI_Tool::GetSelectedGeomObjects( module(), getObstacleTypes() );
75   } else if ( myOpType == ImportSelectedAsPolyline ) {
76     myGeomObjects = 
77       HYDROGUI_Tool::GetSelectedGeomObjects( module(), getPolylineTypes() );
78   }
79
80   // Do not show the panel if more than one GEOM objects are selected
81   myIsToShowPanel = myIsToShowPanel && ( myGeomObjects.count() <= 1 );
82
83   HYDROGUI_Operation::startOperation();
84
85   HYDROGUI_GeomObjectDlg* aPanel = 0;
86
87   if ( myIsToShowPanel ) {
88     // Get panel
89     aPanel = ::qobject_cast<HYDROGUI_GeomObjectDlg*>( inputPanel() );
90
91     if ( aPanel ) {
92       // Reset the panel state
93       aPanel->reset();
94
95       // Set default name
96       updateDefaultName();
97
98       // Pass the existing object names to the panel
99       QStringList anExistingNames;
100       if ( myOpType == ImportCreatedAsObstacle || 
101            myOpType == ImportSelectedAsObstacle ) {
102         anExistingNames = HYDROGUI_Tool::FindExistingObjectsNames( doc(), KIND_OBSTACLE );
103       } else if ( myOpType == ImportSelectedAsPolyline ) {
104         anExistingNames = HYDROGUI_Tool::FindExistingObjectsNames( doc(), KIND_POLYLINEXY );
105       }
106
107       aPanel->setObjectNames( anExistingNames );
108     }
109   }
110
111   if ( !aPanel ) {
112     onApply();
113   }
114
115   // Activate GEOM module operation in case of the corresponding operation type
116   if ( myOpType == ImportCreatedAsObstacle && myGEOMOp > 0 ) {
117     LightApp_Application* anApp = module()->getApp();
118     if ( anApp ) {
119       connect( anApp, SIGNAL( operationFinished( const QString&, const QString&, const QStringList& ) ), 
120         this, SLOT( onExternalOperationFinished( const QString&, const QString&, const QStringList& ) ) );
121
122       module()->getApp()->activateOperation( "Geometry", myGEOMOp );
123     }
124   }
125 }
126
127 void HYDROGUI_ImportGeomObjectOp::abortOperation()
128 {
129   LightApp_Application* anApp = module()->getApp();
130   if ( anApp ) {
131     anApp->disconnect( this );
132   }
133
134   closeExternalOperationDlg();
135
136   HYDROGUI_Operation::abortOperation();
137 }
138
139 void HYDROGUI_ImportGeomObjectOp::commitOperation()
140 {
141   closeExternalOperationDlg();
142
143   HYDROGUI_Operation::commitOperation();
144 }
145
146 bool HYDROGUI_ImportGeomObjectOp::processApply( int& theUpdateFlags,
147                                                 QString& theErrorMsg )
148 {
149   // Get active SalomeApp_Study
150   SalomeApp_Study* aStudy = 
151     dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
152   if ( !aStudy ) {
153     return false;
154   }
155
156   // Check that GEOM objects list is not empty
157   if ( myGeomObjects.isEmpty() ) {
158     theErrorMsg = tr( "NO_GEOM_OBJECT_TO_IMPORT" );
159     return false;
160   }
161
162   QString anObjectName;
163   Handle(HYDROData_Entity) anObjectToEdit;  
164   ObjectKind anObjectKind = 
165     myOpType == ImportSelectedAsPolyline ? KIND_POLYLINEXY : KIND_OBSTACLE;
166
167   if ( myGeomObjects.count() == 1 ) {
168     // Get panel
169     HYDROGUI_GeomObjectDlg* aPanel = ::qobject_cast<HYDROGUI_GeomObjectDlg*>( inputPanel() );
170     if ( aPanel ) {
171       // Check object name
172       anObjectName = aPanel->getObjectName().simplified();
173       if ( anObjectName.isEmpty() ) {
174         theErrorMsg = tr( "INCORRECT_OBJECT_NAME" );
175         return false;
176       }
177
178       // Get object to edit
179       QString anEditedName = aPanel->getEditedObjectName().simplified();
180
181       if ( !anEditedName.isEmpty() ) {
182         anObjectToEdit = HYDROGUI_Tool::FindObjectByName( module(), anEditedName, anObjectKind );
183       }
184     }
185
186     if( anObjectToEdit.IsNull() || anObjectToEdit->GetName() != anObjectName ) {
187       // check that there are no other objects with the same name in the document
188       Handle(HYDROData_Entity) anObject = HYDROGUI_Tool::FindObjectByName( module(), anObjectName/*, anObjectKind*/ );
189       if( !anObject.IsNull() ) {
190         theErrorMsg = tr( "OBJECT_EXISTS_IN_DOCUMENT" ).arg( anObjectName );
191         return false;
192       }
193     }
194   }
195
196   bool anIsOk = false;
197
198   // Get the GEOM object as SObject
199   foreach ( const QString& anEntry, myGeomObjects ) {
200     _PTR(SObject) aSObject( aStudy->studyDS()->FindObjectID( qPrintable(anEntry)) );
201     if ( aSObject ) {
202       // Get the corresponding TopoDS_Shape
203       TopoDS_Shape aShape = GEOMBase::GetShapeFromIOR( aSObject->GetIOR().c_str() );
204       if ( aShape.IsNull() ) {
205         continue;
206       }
207       
208       // Create/edit an object
209       Handle(HYDROData_Entity) anObject; 
210
211       if ( anObjectToEdit.IsNull() ) {
212         if ( myOpType == ImportCreatedAsObstacle || myOpType == ImportSelectedAsObstacle ) {
213           anObject = 
214             Handle(HYDROData_Obstacle)::DownCast( doc()->CreateObject(KIND_OBSTACLE) );
215           Handle(HYDROData_Obstacle) anObstacle = Handle(HYDROData_Obstacle)::DownCast( anObject );
216           anObstacle->SetFillingColor( HYDROData_Obstacle::DefaultFillingColor() );
217           anObstacle->SetBorderColor( HYDROData_Obstacle::DefaultBorderColor() );
218         } else if ( myOpType == ImportSelectedAsPolyline ) {
219           anObject = 
220             Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject(KIND_POLYLINEXY) );
221         }
222       } else {
223         anObject = anObjectToEdit;
224       }
225
226       // Set name
227       if ( anObjectName.isEmpty() ) {
228         QString aName = QString::fromStdString( aSObject->GetName() );
229         anObjectName = HYDROGUI_Tool::GenerateObjectName( 
230           module(), aName, QStringList(), true );
231       }
232       if ( anObject->GetName() != anObjectName ) {
233         anObject->SetName( anObjectName );
234       }
235
236       anObjectName.clear();
237
238       // Set shape
239       if ( myOpType == ImportCreatedAsObstacle || myOpType == ImportSelectedAsObstacle ) {
240         Handle(HYDROData_Obstacle) anObstacle = Handle(HYDROData_Obstacle)::DownCast( anObject );
241         anObstacle->SetShape3D( aShape );
242         anIsOk = true;
243       } else if ( myOpType == ImportSelectedAsPolyline ) {
244         Handle(HYDROData_PolylineXY) aPolyline = Handle(HYDROData_PolylineXY)::DownCast( anObject );
245         // TODO ISSUE #228: set the shape ("aShape") to the polyline
246         // anIsOk = aPolyline->setShape( aShape );
247       }
248
249       // Check operation status
250       if ( anIsOk ) {
251         anObject->Update();
252         theUpdateFlags = UF_Model | UF_OCCViewer | UF_OCC_Forced;
253       }
254     }
255   }
256
257   return anIsOk;
258 }
259
260 HYDROGUI_InputPanel* HYDROGUI_ImportGeomObjectOp::createInputPanel() const
261 {
262   HYDROGUI_InputPanel* aPanel = 0;
263   if ( myIsToShowPanel ) {
264     QString anObjectTypeName = 
265       myOpType == ImportSelectedAsPolyline ? tr("DEFAULT_POLYLINE_NAME") :
266                   tr("DEFAULT_OBSTACLE_NAME");
267     aPanel = new HYDROGUI_GeomObjectDlg( module(), getName(), anObjectTypeName );
268   }
269
270   return aPanel;
271 }
272
273 void HYDROGUI_ImportGeomObjectOp::updateDefaultName()
274 {
275   // Get panel
276   HYDROGUI_GeomObjectDlg* aPanel = ::qobject_cast<HYDROGUI_GeomObjectDlg*>( inputPanel() );
277   if ( !aPanel ) {
278     return;
279   }
280
281   // Set the current GEOM object name to the panel
282   if ( myGeomObjects.count() == 1 ) {
283     SalomeApp_Study* aStudy = 
284       dynamic_cast<SalomeApp_Study*>( module()->getApp()->activeStudy() );
285     if ( aStudy ) {
286       QString anEntry = myGeomObjects.first();
287       _PTR(SObject) aSObject( aStudy->studyDS()->FindObjectID( qPrintable(anEntry) ) );
288       if ( aSObject ) {
289         aPanel->setDefaultName( QString::fromStdString(aSObject->GetName()) );
290       }
291     }
292   }
293 }
294
295 /**
296  * Called when the operation perfomed by another module is finished.
297  * \param theModuleName the name of the module which perfomed the operation
298  * \param theOperationName the operation name
299  * \param theEntryList the list of the created objects entries
300  */
301 void HYDROGUI_ImportGeomObjectOp::onExternalOperationFinished( 
302   const QString& theModuleName, const QString& theOperationName,
303   const QStringList& theEntryList )
304 {
305   // Process "Geometry" module operations with non-empty list of created objects only
306   if ( theModuleName != "Geometry" || theEntryList.isEmpty() ) {
307     return;
308   }
309   
310   // Store the operation name
311   myGEOMOpName = theOperationName;
312
313   // Store the geom objects entries list
314   myGeomObjects = theEntryList;
315
316   // Update the default name of the HYDRO object
317   updateDefaultName();
318 }
319
320 void HYDROGUI_ImportGeomObjectOp::closeExternalOperationDlg()
321 {
322   if ( myGEOMOpName.isEmpty() ) {
323     return;
324   }
325
326   SUIT_Desktop* aDesktop = module()->getApp()->desktop();
327   if ( aDesktop ) {
328     QList<QDialog*> aDialogs = aDesktop->findChildren<QDialog*>();
329     foreach ( QDialog* aDlg, aDialogs ) {
330       if ( typeid(*aDlg).name() == myGEOMOpName ) {
331         aDlg->close();
332         break;
333       }
334     }
335   }
336 }
337
338 QList<GEOM::shape_type> HYDROGUI_ImportGeomObjectOp::getObstacleTypes()
339 {
340   QList<GEOM::shape_type> aTypes;
341
342   aTypes << GEOM::COMPOUND << GEOM::COMPOUND << GEOM::SOLID << 
343             GEOM::SHELL << GEOM::FACE << GEOM::SHAPE;
344
345   return aTypes;
346 }
347
348 QList<GEOM::shape_type> HYDROGUI_ImportGeomObjectOp::getPolylineTypes()
349 {
350   QList<GEOM::shape_type> aTypes;
351
352   aTypes << GEOM::WIRE << GEOM::EDGE;
353
354   return aTypes;
355 }