Salome HOME
lot 12 GUI p.1
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ImportPolylineOp.cxx
index 1d02a454ce772bb972d0064c67b08a427a622b9d..e4ffa108ace36a5bfb39093e7f7561761c980a1a 100644 (file)
@@ -1,8 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2014-2015  EDF-R&D
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
 #include "HYDROGUI_DataModel.h"
 #include "HYDROGUI_Module.h"
 #include "HYDROGUI_UpdateFlags.h"
-#include "HYDROGUI_Tool.h"
+#include "HYDROGUI_Tool2.h"
 #include <HYDROData_PolylineXY.h>
 #include <HYDROData_Polyline3D.h>
 #include <HYDROGUI_DataObject.h>
 #include <HYDROData_Bathymetry.h>
 #include <HYDROData_Iterator.h>
+#include <HYDROData_ShapeFile.h>
+#include <HYDROData_Tool.h>
 
 #include <HYDROData_Profile.h>
 
 #include <QApplication>
 #include <QFile>
 #include <QFileInfo>
-#include <QMessageBox>
-
+#include <SUIT_MessageBox.h>
+#include <gp_XY.hxx>
+#include <HYDROGUI_ImportPolylineDlg.h>
+#include <HYDROGUI_Module.h>
+#include <HYDROGUI_Operation.h>
 
 HYDROGUI_ImportPolylineOp::HYDROGUI_ImportPolylineOp( HYDROGUI_Module* theModule )
 : HYDROGUI_Operation( theModule )
@@ -61,7 +62,7 @@ void HYDROGUI_ImportPolylineOp::startOperation()
   myFileDlg = new SUIT_FileDlg( module()->getApp()->desktop(), true );
   myFileDlg->setWindowTitle( getName() );
   myFileDlg->setFileMode( SUIT_FileDlg::ExistingFiles );
-  myFileDlg->setFilter( tr("POLYLINE_FILTER") );
+  myFileDlg->setNameFilter( tr("POLYLINE_FILTER") );
 
   connect( myFileDlg, SIGNAL( accepted() ), this, SLOT( onApply() ) );
   connect( myFileDlg, SIGNAL( rejected() ), this, SLOT( onCancel() ) );
@@ -69,229 +70,221 @@ void HYDROGUI_ImportPolylineOp::startOperation()
   myFileDlg->exec();
 }
 
-void HYDROGUI_ImportPolylineOp::onApply()
+NCollection_Sequence<Handle(HYDROData_Entity)> HYDROGUI_ImportPolylineOp::ImportPolyOp(
+  const QStringList& aFileNames, Handle(HYDROData_Document) theDocument,
+  HYDROGUI_Module* module, HYDROData_ShapeFile::ImportShapeType theShapeTypesToImport)
 {
-  if ( !myFileDlg )
-  {
-    abort();
-    return;
-  }
-
-  QString aFileName = myFileDlg->selectedFile();
-  if ( aFileName.isEmpty() )
+  NCollection_Sequence<Handle(HYDROData_Entity)> importedEntities;
+  foreach (QString aFileName, aFileNames) 
   {
-    abort();
-    return;
-  }
-
-  QString anExt = aFileName.split('.', QString::SkipEmptyParts).back();
-
-  if (anExt == "shp")
-  {
-    SHPHandle aHSHP;
-    aHSHP = SHPOpen( aFileName.toAscii().data(), "rb" );
-    Parse(aHSHP);
-    
-    QApplication::setOverrideCursor( Qt::WaitCursor );
-    
-    startDocOperation();
-
-    HYDROData_Iterator anIter( doc() );
-    int anInd = 0;
-    QStringList anExistingNames;
-    std::vector<int> anAllowedIndexes;
-    for( ; anIter.More(); anIter.Next() )
-      anExistingNames.push_back(anIter.Current()->GetName());
-
-    QFileInfo aFileInfo(aFileName);
-    QString aBaseFileName = aFileInfo.baseName();
+    if ( aFileName.isEmpty() )
+      continue;
 
-    if (aHSHP->nShapeType == 3 || aHSHP->nShapeType == 23)
+    QString anExt = aFileName.split('.', QString::SkipEmptyParts).back();
+    anExt.toLower();
+    bool importXY = false;
+    if (anExt == "xyz")
+    {
+      importXY = SUIT_MessageBox::question( module->getApp()->desktop(),
+        tr( "IMPORT_POLYLINE" ),
+        tr( "IMPORT_POLYLINE_XY_PART_ONLY" ),
+        QMessageBox::Yes | QMessageBox::No, 
+        SUIT_MessageBox::Yes) == SUIT_MessageBox::Yes;
+    }
+    if (anExt == "shp")
     {
-      anInd = 0;
-      for (;anAllowedIndexes.size() < mySHPObjects.size();)
+      QApplication::setOverrideCursor( Qt::WaitCursor );
+      HYDROData_ShapeFile anImporter;
+      NCollection_IndexedDataMap<Handle(HYDROData_Entity), SHPObject*> theEntitiesToSHPObj;
+      NCollection_Sequence<Handle(HYDROData_Entity)> PolyEnt;
+      int aShapeTypeOfFile = -1;
+      int aStat = anImporter.OpenAndParse(aFileName);
+      QApplication::restoreOverrideCursor();
+      if (aStat == 1)
       {
-        if (!anExistingNames.contains(aBaseFileName + "_PolyXY_" + QString::number(anInd)))
+        QApplication::setOverrideCursor( Qt::WaitCursor );
+        aStat = anImporter.ImportPolylines(theDocument, aFileName, theEntitiesToSHPObj, theShapeTypesToImport); 
+        QApplication::restoreOverrideCursor();
+        for (int k=1;k<=theEntitiesToSHPObj.Extent();k++)
         {
-          anAllowedIndexes.push_back(anInd);
-          anInd++;
+          PolyEnt.Append(theEntitiesToSHPObj.FindKey(k));
         }
-        else
-          anInd++;
-      }
-      
-      for (size_t i = 0; i < mySHPObjects.size(); i++ )
+      if (aStat == 1 || aStat == 2)
       {
-        ProcessSHPPolyXY(mySHPObjects[i], aBaseFileName, anAllowedIndexes[i]);
+        //try to import DBF
+        QString aDBFFileName;
+        aDBFFileName = aFileName.simplified().replace( aFileName.simplified().size() - 4, 4, ".dbf");
+        bool DBF_Stat = anImporter.DBF_OpenDBF(aDBFFileName);
+        if (DBF_Stat)
+        {
+          QStringList aFieldList = anImporter.DBF_GetFieldList();
+          int nbRecords = anImporter.DBF_GetNbRecords();
+            assert (theEntitiesToSHPObj.Extent() == nbRecords);
+            if (theEntitiesToSHPObj.Extent() == nbRecords)
+          {
+            int indNameAttrFound = -1;
+            int k = 0;
+            bool bUseNameAttrFound = false;
+            for (QStringList::iterator it = aFieldList.begin(); it != aFieldList.end(); it++, k++)
+              if (QString::compare(*it, "name", Qt::CaseInsensitive) == 0)
+              {
+                indNameAttrFound = k;
+                break;
+              }
+
+              if (indNameAttrFound != -1)
+                bUseNameAttrFound = SUIT_MessageBox::question( module->getApp()->desktop(),
+                               tr( "IMPORT_POLYLINE" ),
+                               tr( "IMPORT_POLYLINE_USE_NAME_ATTR" ),
+                               QMessageBox::Yes | QMessageBox::No, 
+                               SUIT_MessageBox::Yes) == SUIT_MessageBox::Yes;
+  
+            std::vector<std::vector<HYDROData_ShapeFile::DBF_AttrValue>> anAttrVV;
+            for (int i = 0; i < aFieldList.size(); i++)
+            {
+              std::vector<HYDROData_ShapeFile::DBF_AttrValue> anAttrV;
+              anAttrVV.push_back(anAttrV);
+              anImporter.DBF_GetAttributeList(i, anAttrVV[i] );
+            }
+
+            int indNULL = 1;
+                for (int i = 1; i <= theEntitiesToSHPObj.Extent(); i++)
+            {
+                  Handle(HYDROData_PolylineXY) aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( theEntitiesToSHPObj.FindKey(i) );
+              QStringList aDBFinfo;
+              aDBFinfo << aFieldList; //first, the table header
+              for (int j = 0; j < aFieldList.size(); j++)
+              {
+                QString attr;
+                const HYDROData_ShapeFile::DBF_AttrValue& attrV = anAttrVV[j][i-1];
+                if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_String)
+                  aDBFinfo << attrV.myStrVal;
+                else if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_Integer)
+                  aDBFinfo << QString::number(attrV.myIntVal);
+                else if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_Double)
+                  aDBFinfo << QString::number(attrV.myDoubleVal);
+                else 
+                  aDBFinfo << "";
+              }
+              assert (aDBFinfo.size() / 2 == aFieldList.size());
+              aPolylineXY->SetDBFInfo(aDBFinfo);
+              if (bUseNameAttrFound)
+              {
+                QString nameOfPoly = aDBFinfo[aDBFinfo.size() / 2 + indNameAttrFound];
+                if (!nameOfPoly.isEmpty())
+                  aPolylineXY->SetName(nameOfPoly);
+                else
+                {
+                  aPolylineXY->SetName("null_name_" + QString::number(indNULL));
+                  indNULL++;
+                }
+              }
+            }
+          }
+        }        
       }
-    }
-    else if (aHSHP->nShapeType == 13)
-    {
-      anInd = 0;
-      for (;anAllowedIndexes.size() < mySHPObjects.size();)
-      {
-        if (!anExistingNames.contains(aBaseFileName + "_PolyXY_" + QString::number(anInd)) &&
-            !anExistingNames.contains(aBaseFileName + "_Poly3D_" + QString::number(anInd)) &&
-            !anExistingNames.contains(aBaseFileName + "_Bath_" + QString::number(anInd)))
+
+        if (anImporter.GetShapeType() == 13) //Polyline 3D
         {
-          anAllowedIndexes.push_back(anInd);
-          anInd++;
+          HYDROGUI_ImportPolylineDlg* aDLG = new HYDROGUI_ImportPolylineDlg( module->getApp()->desktop(), PolyEnt );
+          aDLG->setModal( true );
+          aDLG->setWindowTitle(tr("IMPORT_POLYLINE"));
+          //QApplication::restoreOverrideCursor();
+          if( aDLG->exec()==QDialog::Accepted )
+          {
+            NCollection_Sequence<Handle(HYDROData_Entity)> CheckedPolylines = aDLG->GetCheckedPolylines();
+            NCollection_IndexedDataMap<Handle(HYDROData_Entity), SHPObject*> CheckedEntitiesToSHPObj;
+            for (int k=1;k<=CheckedPolylines.Size();k++)
+            {
+              SHPObject* const* SHPObkP = theEntitiesToSHPObj.Seek(CheckedPolylines(k));
+              if (SHPObkP != NULL)
+                CheckedEntitiesToSHPObj.Add(CheckedPolylines(k), *SHPObkP);
+            }
+            NCollection_Sequence<Handle(HYDROData_Entity)> theEntitiesPoly3D;
+            anImporter.ImportPolylines3D(theDocument, CheckedEntitiesToSHPObj, theEntitiesPoly3D, theShapeTypesToImport);          
+            PolyEnt.Append(theEntitiesPoly3D);
+          }
         }
+        anImporter.Free();
+      }
+      if (aStat == 1)
+        UpdateView(module, PolyEnt);
+      else if (aStat == 2)
+      {
+        UpdateView(module, PolyEnt);
+        if (theShapeTypesToImport == HYDROData_ShapeFile::ImportShapeType_All) //if other flag = > no need to show this messagebox
+          SUIT_MessageBox::information(module->getApp()->desktop(), 
+            tr( "IMPORT_POLYLINE" ), tr ("POLYGON_IMPORTED_AS_POLYLINE"));
+      }
+      else
+      {
+        QString aMess;
+        if (theShapeTypesToImport == HYDROData_ShapeFile::ImportShapeType::ImportShapeType_Polygon)
+          aMess += tr ("POLYLINE_IMPORT_FAILED_AS_POLYGON") + ";\n";
         else
-          anInd++;
+          aMess += tr ("POLYLINE_IMPORT_FAILED_AS_POLYLINE") + ";\n";
+
+        if (aStat == -1)
+          aMess += tr ("CANT_OPEN_SHP");
+        else if (aStat == -2)
+          aMess += tr ("CANT_OPEN_SHX");
+        else 
+          aMess += tr ("SHAPE_TYPE_IS") + anImporter.GetShapeTypeName(aShapeTypeOfFile);
+        SUIT_MessageBox::warning( module->getApp()->desktop(), tr( "IMPORT_POLYLINE" ), aMess);
       }
-      for (size_t i = 0; i < mySHPObjects.size(); i++ )
-        ProcessSHPPoly3D(mySHPObjects[i], aBaseFileName, anAllowedIndexes[i]);
+      importedEntities.Append(PolyEnt);
     }
-    commitDocOperation();
-    commit();
-    
-    for (size_t i = 0; i < mySHPObjects.size(); i++ )
-      free (mySHPObjects[i]);
-
-    mySHPObjects.clear();
-    SHPClose(aHSHP);
-  }
-  module()->update( UF_Model | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init );
-  
-  QApplication::restoreOverrideCursor();
-}
-
-void HYDROGUI_ImportPolylineOp::ProcessSHPPolyXY(SHPObject* anObj, QString theFileName, int theInd)
-{
-  //if (anObj->nSHPType != SHPT_ARC && anObj->nSHPType != SHPT_ARCM)
-  // return false;
-  Handle(HYDROData_PolylineXY) aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
-  
-  int nParts = anObj->nParts;
-  for ( int i = 0 ; i < nParts ; i++ )
-  {
-    int StartIndex = anObj->panPartStart[i];
-    int EndIndex;
-    if (i != nParts - 1)
-      EndIndex = anObj->panPartStart[i + 1];
-    else
-      EndIndex = anObj->nVertices;
-
-    bool IsClosed = false;
-    HYDROData_PolylineXY::SectionType aSectType = HYDROData_PolylineXY::SECTION_POLYLINE; 
-    if (anObj->padfX[StartIndex] == anObj->padfX[EndIndex - 1] &&
-        anObj->padfY[StartIndex] == anObj->padfY[EndIndex - 1] )
+    else if ( anExt == "xy" || (importXY && anExt == "xyz"))
     {
-      IsClosed = true;
-      aPolylineXY->AddSection( TCollection_AsciiString( ("poly_section_" + QString::number(i)).data()->toAscii()), aSectType, true);
+      if (!HYDROData_Tool::importPolylineFromXYZ(aFileName, theDocument, true, importedEntities))
+        SUIT_MessageBox::warning( module->getApp()->desktop(), tr( "IMPORT_POLYLINE" ), tr( "NO_ONE_POLYLINE_IMPORTED" ));
     }
-    else
-      aPolylineXY->AddSection( TCollection_AsciiString( ("poly_section_" + QString::number(i)).data()->toAscii()), aSectType, false);
-    
-    if (IsClosed)
-      EndIndex--;
-    for ( int k = StartIndex; k < EndIndex ; k++ )
+    else if (anExt == "xyz")
     {
-      HYDROData_PolylineXY::Point aSectPoint;
-      aSectPoint.SetX( anObj->padfX[k] );
-      aSectPoint.SetY( anObj->padfY[k] );
-      aPolylineXY->AddPoint( i, aSectPoint );
+      if (!HYDROData_Tool::importPolylineFromXYZ(aFileName, theDocument, false, importedEntities))
+        SUIT_MessageBox::warning( module->getApp()->desktop(), tr( "IMPORT_POLYLINE" ), tr( "NO_ONE_POLYLINE_IMPORTED" ));
     }
-
   }
-  
-  aPolylineXY->SetWireColor( HYDROData_PolylineXY::DefaultWireColor() );
-  aPolylineXY->SetName( theFileName + "_PolyXY_" + QString::number(theInd) );
-  
-  aPolylineXY->Update();
-  
-  size_t anActiveViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( module() );
-  if ( anActiveViewId == 0 )
-    anActiveViewId = HYDROGUI_Tool::GetActiveOCCViewId( module() );
-  
-  module()->setObjectVisible( anActiveViewId, aPolylineXY, true );
-  
-  module()->setIsToUpdate( aPolylineXY );
+  return importedEntities;
 }
 
-void HYDROGUI_ImportPolylineOp::ProcessSHPPoly3D(SHPObject* anObj, QString theFileName, int theInd)
+void HYDROGUI_ImportPolylineOp::onApply()
 {
-  Handle(HYDROData_PolylineXY) aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( doc()->CreateObject( KIND_POLYLINEXY ) );
-
-  Handle(HYDROData_Polyline3D) aPolylineObj = Handle(HYDROData_Polyline3D)::DownCast( doc()->CreateObject( KIND_POLYLINE ) );
-
-  Handle(HYDROData_Bathymetry) aBath = Handle(HYDROData_Bathymetry)::DownCast( doc()->CreateObject( KIND_BATHYMETRY ) );
-  HYDROData_Bathymetry::AltitudePoints aAPoints;
-
-  int nParts = anObj->nParts;
-  for ( int i = 0 ; i < nParts ; i++ )
+  if ( !myFileDlg )
   {
-    //bool aSectClosure = true;
-    int StartIndex = anObj->panPartStart[i];
-    int EndIndex;
-    if (i != nParts - 1)
-      EndIndex = anObj->panPartStart[i + 1];
-    else
-      EndIndex = anObj->nVertices;
-
-    bool IsClosed = false;
-    HYDROData_PolylineXY::SectionType aSectType = HYDROData_PolylineXY::SECTION_POLYLINE; 
-    if (anObj->padfX[StartIndex] == anObj->padfX[EndIndex - 1] &&
-        anObj->padfY[StartIndex] == anObj->padfY[EndIndex - 1] &&
-        anObj->padfZ[StartIndex] == anObj->padfZ[EndIndex - 1])
-    {
-      IsClosed = true;
-      aPolylineXY->AddSection( TCollection_AsciiString( ("poly_section_" + QString::number(i)).data()->toAscii()), aSectType, true );
-    }
-    else
-      aPolylineXY->AddSection( TCollection_AsciiString( ("poly_section_" + QString::number(i)).data()->toAscii()), aSectType, false  );
-    
-    if (IsClosed)
-      EndIndex--;
-    for ( int k = StartIndex ; k < EndIndex ; k++ )
-    {
-      HYDROData_PolylineXY::Point aSectPoint;
-      aSectPoint.SetX( anObj->padfX[k] );
-      aSectPoint.SetY( anObj->padfY[k] );
-      aPolylineXY->AddPoint( i, aSectPoint );
-      aAPoints.Append(gp_XYZ (anObj->padfX[k], anObj->padfY[k], anObj->padfZ[k]));
-    }
+    abort();
+    return;
   }
 
-
-  QString aBathName = theFileName + "_bath_" + QString::number(theInd);
-  QString aPolyXYName = theFileName + "_polyXY_" + QString::number(theInd);
-  QString aPoly3DName = theFileName + "_poly3D_" + QString::number(theInd);
-
-  aPolylineXY->SetName( aPolyXYName );
-  aPolylineXY->SetWireColor(HYDROData_PolylineXY::DefaultWireColor());
-  aPolylineXY->Update();
+  QStringList aFileNames = myFileDlg->selectedFiles();
   
-  aBath->SetAltitudePoints(aAPoints);
-  aBath->SetName( aBathName );
+  //QApplication::setOverrideCursor( Qt::WaitCursor );  
+  startDocOperation();
 
-  aPolylineObj->SetPolylineXY (aPolylineXY, false);
-  aPolylineObj->SetAltitudeObject(aBath);
-
-  aPolylineObj->SetBorderColor( HYDROData_Polyline3D::DefaultBorderColor() );
-  aPolylineObj->SetName( aPoly3DName );
+  ImportPolyOp(aFileNames, doc(), module(), HYDROData_ShapeFile::ImportShapeType_All);
+  if (!aFileNames.empty())
+  {
+    commitDocOperation();
+    commit();
+    module()->update( UF_Model | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init | UF_OCCViewer );
+  }
+  else
+    abort();
   
-  aPolylineObj->Update();
-
-  size_t anActiveViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( module() );
-  if ( anActiveViewId == 0 )
-    anActiveViewId = HYDROGUI_Tool::GetActiveOCCViewId( module() );
-
-  module()->setObjectVisible( anActiveViewId, aPolylineXY, true );
-  module()->setObjectVisible( anActiveViewId, aPolylineObj, true );
-
-  module()->setIsToUpdate( aPolylineObj );
+  QApplication::restoreOverrideCursor();
 }
 
-void HYDROGUI_ImportPolylineOp::Parse(SHPHandle theHandle)
+void HYDROGUI_ImportPolylineOp::UpdateView( HYDROGUI_Module* module, NCollection_Sequence<Handle(HYDROData_Entity)>& anEntities)
 {
-  int aShapeType;
-  mySHPObjects.clear();
-  SHPGetInfo( theHandle, NULL, &aShapeType, NULL, NULL );
-  if (aShapeType == 3 || aShapeType == 13 || aShapeType == 23) 
+  size_t anActiveViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( module );
+  if ( anActiveViewId == 0 )
+    anActiveViewId = HYDROGUI_Tool::GetActiveOCCViewId( module );
+
+  for (int i = 1; i <= anEntities.Size() ; i++)
   {
-    for (int i = 0; i < theHandle->nRecords; i++) 
-      mySHPObjects.push_back(SHPReadObject(theHandle, i));
+    anEntities(i)->Update();
+    module->setObjectVisible( anActiveViewId, anEntities(i), true );
+    module->setIsToUpdate( anEntities(i) );
   }
-}
\ No newline at end of file
+}