Salome HOME
lot 10 - warnings for DTM - untested
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ProfileOp.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include <HYDROGUI_Module.h>
20 #include <HYDROGUI_ProfileOp.h>
21 #include <HYDROGUI_ProfileDlg.h>
22 #include <HYDROGUI_Tool2.h>
23 #include <HYDROGUI_UpdateFlags.h>
24 #include <HYDROGUI_DataObject.h>
25 #include <HYDROData_Document.h>
26 #include <HYDROData_Profile.h>
27 #include <HYDROGUI_CurveCreatorProfile.h>
28 #include <HYDROGUI_DeleteOp.h>
29 #include <HYDROData_Tool.h>
30 #include <CurveCreator_Displayer.hxx>
31 #include <HYDROData_Entity.h>
32 #include <QSet>
33 #include <set>
34
35 #include <LightApp_Application.h>
36 #include <LightApp_SelectionMgr.h>
37 #include <LightApp_UpdateFlags.h>
38
39 #include <OCCViewer_ViewManager.h>
40 #include <OCCViewer_ViewModel.h>
41 #include <OCCViewer_ViewWindow.h>
42 #include <SUIT_MessageBox.h>
43 #include <SUIT_Desktop.h>
44 #include <OCCViewer_AISSelector.h>
45
46 #include <Precision.hxx>
47
48 //static int ZValueIncrement = 0;
49
50 static void ProfileUZToCurveCrProfile(const Handle(HYDROData_ProfileUZ)& aProfileUZ, 
51   HYDROGUI_CurveCreatorProfile* outProfile)
52 {
53   CurveCreator::Coordinates aCurveCoords;
54   CurveCreator::SectionsMap aSectionsMap;
55
56   HYDROData_ProfileUZ::PointsList aSectPointsList = aProfileUZ->GetPoints();
57   CurveCreator::PosPointsList aPoints;
58   for ( int k = 1, aNbPoints = aSectPointsList.Size(); k <= aNbPoints; ++k )
59   {
60     const HYDROData_ProfileUZ::Point& aSectPoint = aSectPointsList.Value( k );
61     aCurveCoords.clear();
62     aCurveCoords.push_back( aSectPoint.X() );
63     aCurveCoords.push_back( aSectPoint.Y() );
64
65     CurveCreator_PosPoint* aPosPoint = new CurveCreator_PosPoint( k, aCurveCoords );
66     aPoints.push_back( aPosPoint );
67   }
68
69   aSectionsMap[0] = aPoints;
70   outProfile->addPointsInternal( aSectionsMap );
71
72   HYDROData_ProfileUZ::SectionType aSectType = aProfileUZ->GetSectionType( 0 );
73
74   CurveCreator::SectionType aCurveType = CurveCreator::Polyline;
75   if( aSectType == HYDROData_ProfileUZ::SECTION_SPLINE )
76     aCurveType = CurveCreator::Spline;
77
78   outProfile->setSectionType( 0, aCurveType );
79 }
80
81 static int CurveCrProfileToHProfile(const HYDROGUI_CurveCreatorProfile* outProfile, 
82   Handle(HYDROData_Profile) theProfileObj,
83   const QString theProfileName,
84   bool IsEdit)
85 {
86   if( theProfileObj.IsNull() )
87     return 0;
88
89   Handle(HYDROData_ProfileUZ) aProfileUZ = theProfileObj->GetProfileUZ();
90   if ( aProfileUZ.IsNull() )
91     return 0;
92
93   theProfileObj->SetName(theProfileName);
94
95   HYDROData_ProfileUZ::PointsList aProfileParamPoints;
96
97   Handle(TColgp_HArray1OfPnt) aCurveCoords = outProfile->GetDifferentPoints( 0 );
98   if ( aCurveCoords.IsNull() || aCurveCoords->Size() <= 2 )
99     return -1;
100
101   for ( int k = aCurveCoords->Lower(); k <= aCurveCoords->Upper() ; k++ )
102   {
103     HYDROData_ProfileUZ::Point aProfileParamPoint;
104
105     aProfileParamPoint.SetX( aCurveCoords->Value( k ).X() );
106     aProfileParamPoint.SetY( aCurveCoords->Value( k ).Y() );
107
108     aProfileParamPoints.Append( aProfileParamPoint );
109   }
110   theProfileObj->SetParametricPoints( aProfileParamPoints );
111
112   HYDROData_ProfileUZ::SectionType aSectType = HYDROData_ProfileUZ::SECTION_POLYLINE;
113   if ( outProfile->getSectionType( 0 ) == CurveCreator::Spline )
114     aSectType = HYDROData_ProfileUZ::SECTION_SPLINE;
115
116   aProfileUZ->SetSectionType( 0, aSectType );
117
118   if ( !IsEdit )
119     theProfileObj->SetBorderColor( theProfileObj->DefaultBorderColor() );
120
121   // At first we update the child u,z profile object
122   aProfileUZ->Changed( HYDROData_Entity::Geom_2d );
123   aProfileUZ->Update();
124
125   // And now we update our edited object
126   theProfileObj->Update();
127   return 1;
128 }
129
130 HYDROGUI_ProfileOp::HYDROGUI_ProfileOp( HYDROGUI_Module* theModule, bool theIsEdit )
131 : HYDROGUI_Operation( theModule ), myIsEdit(theIsEdit), 
132    myDisplayer (NULL)
133 {
134   setName( theIsEdit ? tr( "EDIT_PROFILE" ) : tr( "CREATE_PROFILE" ) );
135 }
136
137 HYDROGUI_ProfileOp::~HYDROGUI_ProfileOp()
138 {
139   erasePreview();
140 }
141
142 /**
143  * Redirect the delete action to input panel
144  */
145 void HYDROGUI_ProfileOp::deleteSelected()
146 {
147   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();
148   aPanel->deleteSelected();
149 }
150
151 /**
152  * Checks whether there are some to delete
153  */
154 #include <CurveCreator_Widget.h>
155 bool HYDROGUI_ProfileOp::deleteEnabled()
156 {
157   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();
158   return aPanel->deleteEnabled();
159 }
160
161 void HYDROGUI_ProfileOp::startOperation()
162 {
163   if (!myProfiles.empty())
164   {
165     for (int i = 0; i < myProfiles.size(); i++)
166     {
167       delete myProfiles[i];
168       myProfiles[i] = NULL;
169     }
170     myProfiles.clear();
171   }
172
173   if (!myIsEdit)
174     myEditedObjects.Clear();
175
176   if (myCurveToProfile.IsEmpty())
177     myCurveToProfile.Clear();
178
179   if( myIsEdit && isApplyAndClose() )
180     myEditedObjects = HYDROGUI_Tool::GetSelectedObjects(module());
181
182   int lenP = myEditedObjects.Length();  
183   myProfiles.resize(lenP == 0 ? 1 : myEditedObjects.Length());
184   for (int i = 0; i < myProfiles.size(); i++)
185     myProfiles[i] = new HYDROGUI_CurveCreatorProfile();
186
187   //mySingleProfileMode = myEditedObjects.IsEmpty();  
188   HYDROGUI_Operation::startOperation();
189
190   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();
191   aPanel->myEditorWidget->setCurve(NULL);
192   aPanel->reset();
193   setPreviewManager( aPanel->viewManager() );
194   setCursor();
195
196   //aPanel->SetSingleProfileMode(mySingleProfileMode); 
197   QMap<HYDROGUI_CurveCreatorProfile*, QColor> CurveToColor;
198   if( lenP )
199   {
200     for (int i = 1; i <= lenP; i++)
201     {
202       Handle(HYDROData_Profile) aCProfile = Handle(HYDROData_Profile)::DownCast(myEditedObjects(i)); 
203       QString aProfileName;
204       if( !aCProfile.IsNull() )
205       {
206         Handle(HYDROData_ProfileUZ) aProfileUZ = aCProfile->GetProfileUZ( false );
207         if ( !aProfileUZ.IsNull() )
208         {
209           HYDROGUI_CurveCreatorProfile* CP = new HYDROGUI_CurveCreatorProfile();
210           myProfiles[i-1] = CP;
211           ProfileUZToCurveCrProfile(aProfileUZ, CP);
212           myCurveToProfile.Bind(CP, aCProfile);
213         }
214       }
215     }
216     int ext = myCurveToProfile.Extent(); //ext should be equal to lenP
217     QVector<QColor> PColors;
218     if (myIsEdit)
219       HYDROData_Tool::GenerateRepeatableRandColors(ext, PColors);
220     else
221       PColors << QColor(0,0,255); //default color
222
223     for (int i = 0; i < myProfiles.size(); i++)
224     {
225       HYDROGUI_CurveCreatorProfile* CC = myProfiles[i];
226       const Handle(HYDROData_Profile)& CP = myCurveToProfile.Find(CC);
227       QColor CurCol = PColors[i]; 
228       CP->GetProfileColor(CurCol);
229       CurveToColor[CC] = CurCol;
230       const QString& profName = CP->GetName();
231       const QColor& PColor = CurCol;
232       if (myIsEdit)
233         aPanel->addProfileName(profName, PColor);
234       else
235         aPanel->setProfileName(profName);
236     }
237   }
238
239   if (!myIsEdit)
240   {
241     QString aProfileName = HYDROGUI_Tool::GenerateObjectName( module(), tr( "DEFAULT_PROFILE_NAME" ) );
242     aPanel->setProfileName( aProfileName );
243   }
244
245   if (!myProfiles.empty())
246   {
247     aPanel->setProfile( myProfiles[0] );
248     aPanel->setProfilesPointer( &myProfiles );
249   }
250   displayPreviews(CurveToColor, 0, myProfiles.size(), true, true );
251 }
252
253 void HYDROGUI_ProfileOp::onAddProfiles()
254 {
255   if( !myIsEdit )
256     return;
257
258   QSet<QString> edObjNamesMap;
259   for (int i = 1; i <= myEditedObjects.Length(); i++)
260     edObjNamesMap.insert( myEditedObjects(i)->GetName());
261
262   HYDROData_SequenceOfObjects aSelectedObj = HYDROGUI_Tool::GetSelectedObjects( module() );;
263   int ExistingProfLen = myEditedObjects.Length();
264   for (int i = 1; i <= aSelectedObj.Length(); i++)
265   {
266     Handle(HYDROData_Profile) CurProf = Handle(HYDROData_Profile)::DownCast(aSelectedObj.Value(i));
267     if (CurProf.IsNull())
268       continue;
269     if (!edObjNamesMap.contains(CurProf->GetName()))
270       myEditedObjects.Append(CurProf);
271   }
272
273   int NewLen = myEditedObjects.Length();
274   bool IsNewPoly = NewLen - ExistingProfLen;
275   if (aSelectedObj.IsEmpty())
276   {
277     SUIT_MessageBox::warning( module()->getApp()->desktop(), tr( "PROFILEOP_WARNING" ), tr ("PROFILES_ARE_NOT_SELECTED") );
278     return;
279   }
280   if (!IsNewPoly)
281   {
282     SUIT_MessageBox::warning( module()->getApp()->desktop(), tr( "PROFILEOP_WARNING" ), tr ("PROFILES_ALREADY_PRESENT") );
283     return;
284   }
285   myProfiles.resize(myEditedObjects.Length());
286   for (int i = myProfiles.size() - 1; i < myEditedObjects.Length(); i++)
287     myProfiles[i] = new HYDROGUI_CurveCreatorProfile();
288     
289   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();  
290   QMap<HYDROGUI_CurveCreatorProfile*, QColor> CurveToColor;
291   if( IsNewPoly )
292   {
293     //TODO move to ext func!
294     for (int i = ExistingProfLen + 1; i <= NewLen; i++)
295     {
296       Handle(HYDROData_Profile) aCProfile = Handle(HYDROData_Profile)::DownCast(myEditedObjects(i)); 
297
298       QString aProfileName;
299       if( !aCProfile.IsNull() )
300       {
301         Handle(HYDROData_ProfileUZ) aProfileUZ = aCProfile->GetProfileUZ( false );
302         if ( !aProfileUZ.IsNull() )
303         {
304           HYDROGUI_CurveCreatorProfile* CP = new HYDROGUI_CurveCreatorProfile();
305           myProfiles[i-1] = CP;
306           ProfileUZToCurveCrProfile(aProfileUZ, CP);
307           myCurveToProfile.Bind(CP, aCProfile);            
308         }
309       }
310     }
311     //int ext = myCurveToProfile.Extent(); //ext should be equal to lenP
312     QVector<QColor> PColors;
313     HYDROData_Tool::GenerateRepeatableRandColors(NewLen - ExistingProfLen, PColors);
314
315     for (int i = ExistingProfLen; i < NewLen; i++)
316     {
317       HYDROGUI_CurveCreatorProfile* CC = myProfiles[i];
318       const Handle(HYDROData_Profile)& CP = myCurveToProfile.Find(CC);
319       QColor CurCol = PColors[i-ExistingProfLen]; 
320       CP->GetProfileColor(CurCol);
321       CurveToColor[CC] = CurCol;
322       const QString& profName = CP->GetName();
323       const QColor& PColor = CurCol;
324       if (myIsEdit)
325         aPanel->addProfileName(profName, PColor);
326       else
327         aPanel->setProfileName(profName);
328     }
329   }
330   displayPreviews(CurveToColor, ExistingProfLen, NewLen, false, false);
331 }
332
333 void HYDROGUI_ProfileOp::abortOperation()
334 {
335   erasePreview();
336   restoreCursor();
337
338   HYDROGUI_Operation::abortOperation();
339 }
340
341 void HYDROGUI_ProfileOp::commitOperation()
342 {
343   erasePreview();
344   restoreCursor();
345
346   HYDROGUI_Operation::commitOperation();
347 }
348
349 HYDROGUI_InputPanel* HYDROGUI_ProfileOp::createInputPanel() const
350 {
351   HYDROGUI_ProfileDlg* aDlg = new HYDROGUI_ProfileDlg( module(), getName(), myIsEdit );
352   connect( aDlg, SIGNAL( AddProfiles() ), this, 
353     SLOT( onAddProfiles() ) );
354   connect( aDlg, SIGNAL( RemoveProfile(int) ), this, 
355     SLOT( onRemoveProfile(int) ) );  
356   return aDlg;
357 }
358
359
360 bool HYDROGUI_ProfileOp::processApply( int& theUpdateFlags,
361                                        QString& theErrorMsg,
362                                        QStringList& theBrowseObjectsEntries )
363 {
364   HYDROGUI_ProfileDlg* aPanel = ::qobject_cast<HYDROGUI_ProfileDlg*>( inputPanel() );
365   if ( !aPanel )
366     return false;
367
368   QStringList aProfileNames = aPanel->getProfileNames();
369   QVector<QString> aProfileNamesFiltered;
370   int i = 0;
371  // QSet<QString> edObjStrMap = aProfileNames.toSet();
372   QSet<QString> ObjStrMapNE ;
373   HYDROData_SequenceOfObjects allobj = doc()->CollectAllObjects();
374   for (int i=1;i<=allobj.Size();i++ )
375     ObjStrMapNE.insert(allobj(i)->GetName());
376   for (int i=1; i<=myEditedObjects.Size();i++)
377     ObjStrMapNE.remove(myEditedObjects(i)->GetName());
378   bool warn = false;
379   QString title = tr( "PROFILEOP_WARNING" );
380   QString mes = tr("PROFILE_RENAMING_NOTIF") + "\n";
381   foreach (QString profName, aProfileNames)
382   {
383     i++;
384     if( !myIsEdit || ObjStrMapNE.contains(profName) || profName.isEmpty() )
385     {
386       QString newName = HYDROData_Tool::GenerateObjectName(doc(), "Profile");
387       mes += profName + " => " + newName + "\n";
388       profName = newName;
389       warn = true;
390     }
391     aProfileNamesFiltered.append(profName);
392   }
393   if (myIsEdit && warn)
394 #ifndef TEST_MODE
395     SUIT_MessageBox::warning( module()->getApp()->desktop(), title, mes );
396 #endif
397   //  
398   theUpdateFlags = UF_Model;
399   if (myIsEdit)
400   {
401     for (int i = 1; i <= myEditedObjects.Size(); i++)
402     {
403       Handle(HYDROData_Profile) HProf = Handle(HYDROData_Profile)::DownCast(myEditedObjects(i));
404       int stat = CurveCrProfileToHProfile(myProfiles[i-1], HProf, aProfileNamesFiltered[i-1], true);
405       HProf->SetProfileColor(HYDROData_Tool::toQtColor(myProfiles[i-1]->getColorSection(0)));
406       if (stat == 0)
407         continue;
408       else if (stat == -1)
409       {    
410         theErrorMsg = tr( "NUMBER_OF_PROFILE_POINTS_INCORRECT" ); //TODO resolve this
411         continue;
412       }    
413       module()->setIsToUpdate( HProf );
414     }
415     theUpdateFlags |= UF_OCCViewer | UF_OCC_Forced | UF_VTKViewer;
416   }
417   else
418   {
419     Handle(HYDROData_Profile) aNewProfileObj = Handle(HYDROData_Profile)::DownCast( doc()->CreateObject( KIND_PROFILE ) ); 
420     int stat = CurveCrProfileToHProfile(myProfiles[0], aNewProfileObj, aProfileNamesFiltered[0], false);
421     aNewProfileObj->SetProfileColor(HYDROData_Tool::toQtColor(myProfiles[0]->getColorSection(0)));
422     if (stat == 0)
423       return false;
424     else if (stat == -1)
425     {    
426       theErrorMsg = tr( "NUMBER_OF_PROFILE_POINTS_INCORRECT" );
427       return false;
428     }    
429     module()->setIsToUpdate( aNewProfileObj );
430     QString anEntry = HYDROGUI_DataObject::dataObjectEntry( aNewProfileObj );
431     theBrowseObjectsEntries.append( anEntry );
432   }
433
434   return true;
435 }
436
437 void HYDROGUI_ProfileOp::displayPreviews(const QMap<HYDROGUI_CurveCreatorProfile*, QColor>& CurveToColor,
438   int firstIndProf, int lastIndProf, bool createNewDisplayer, bool SwitchToFirstProf)
439 {
440   HYDROGUI_ProfileDlg* aPanel = dynamic_cast<HYDROGUI_ProfileDlg*>( inputPanel() );
441   if( aPanel )
442   {
443     Handle(AIS_InteractiveContext) aCtx = aPanel->getAISContext();
444     if( !aCtx.IsNull() )
445     {
446       if (myDisplayer)
447       {
448         //delete myDisplayer;
449         //myDisplayer = NULL;
450       }
451       if (createNewDisplayer)
452         myDisplayer = new CurveCreator_Displayer( aCtx );
453       for (int i = firstIndProf; i < lastIndProf; i++ )
454       {
455         HYDROGUI_CurveCreatorProfile* CC = myProfiles[i];
456         QColor QCurCol = QColor(0,0,255); //def color
457         if (myIsEdit)
458           QCurCol = CurveToColor[CC];
459         Quantity_Color CurOCCCol = HYDROData_Tool::toOccColor(QCurCol);
460         CC->setDisplayer( myDisplayer );
461         CC->myPointAspectColor = CurOCCCol;
462         CC->setColorSectionInternal(0, CurOCCCol);
463         CC->myLineWidth = 1;
464         myDisplayer->display( CC->getAISObject( true ), true );
465       }
466     }
467     if (SwitchToFirstProf && myProfiles.size() > 1)
468       aPanel->switchToFirstProfile();
469   }
470 }
471
472 void HYDROGUI_ProfileOp::erasePreview()
473 {
474   HYDROGUI_ProfileDlg* aPanel = dynamic_cast<HYDROGUI_ProfileDlg*>( inputPanel() );
475   //CurveCreator_Displayer* aDisplayer = myProfiles[0] ? myProfile[0]->getDisplayer() : 0;
476   if( aPanel && myDisplayer )
477   {
478     Handle(AIS_InteractiveContext) aCtx = aPanel->getAISContext();
479     if( !aCtx.IsNull() )
480     {
481       myDisplayer->eraseAll( true );
482     }
483   }
484   myCurveToProfile.Clear();
485 }
486
487 void HYDROGUI_ProfileOp::onRemoveProfile(int index)
488 {
489   if (index >= myProfiles.size() )
490     return;
491
492   if (!myIsEdit)
493     return;
494
495   HYDROGUI_CurveCreatorProfile* CP = myProfiles[index];
496   myProfiles.erase (myProfiles.begin()+index);
497   myEditedObjects.Remove(index+1);
498   myCurveToProfile.UnBind(CP);
499
500   HYDROGUI_ProfileDlg* aPanel = (HYDROGUI_ProfileDlg*)inputPanel();
501   //aPanel->reset();
502   //setPreviewManager( aPanel->viewManager() );
503   //setCursor();
504
505   aPanel->BlockProfileNameSignals(true);
506   aPanel->eraseProfile(index);
507
508   Handle(AIS_InteractiveContext) aCtx = aPanel->getAISContext();
509   if( !aCtx.IsNull() && myDisplayer)
510     myDisplayer->erase( CP->getAISObject(false), true);
511   CP->SetEraseAllState(false);
512   delete CP;
513   int selectedInd = aPanel->GetProfileSelectionIndex();
514   if (selectedInd > -1)
515     aPanel->SwitchToProfile(selectedInd);
516   aPanel->BlockProfileNameSignals(false);
517 }
518
519 bool HYDROGUI_ProfileOp::isValid( SUIT_Operation* theOtherOp ) const
520 {
521   HYDROGUI_DeleteOp* aDelOp = dynamic_cast<HYDROGUI_DeleteOp*>( theOtherOp );
522   if( aDelOp )
523     return true;
524   else
525     return false;
526 }