Salome HOME
importPolylines must work with only one polyline in shape
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_ImportPolylineOp.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_ImportPolylineOp.h"
20
21 #include "HYDROGUI_DataModel.h"
22 #include "HYDROGUI_Module.h"
23 #include "HYDROGUI_UpdateFlags.h"
24 #include "HYDROGUI_Tool2.h"
25 #include <HYDROData_PolylineXY.h>
26 #include <HYDROData_Polyline3D.h>
27 #include <HYDROGUI_DataObject.h>
28 #include <HYDROData_Bathymetry.h>
29 #include <HYDROData_Iterator.h>
30 #include <HYDROData_ShapeFile.h>
31 #include <HYDROData_Tool.h>
32
33 #include <HYDROData_Profile.h>
34
35 #include <SUIT_Desktop.h>
36 #include <SUIT_FileDlg.h>
37 #include <LightApp_Application.h>
38
39 #include <QApplication>
40 #include <QFile>
41 #include <QFileInfo>
42 #include <SUIT_MessageBox.h>
43 #include <gp_XY.hxx>
44 #include <HYDROGUI_ImportPolylineDlg.h>
45 #include <HYDROGUI_Module.h>
46 #include <HYDROGUI_Operation.h>
47
48 HYDROGUI_ImportPolylineOp::HYDROGUI_ImportPolylineOp( HYDROGUI_Module* theModule )
49 : HYDROGUI_Operation( theModule )
50 {
51   setName( tr( "IMPORT_POLYLINE" ) );
52 }
53
54 HYDROGUI_ImportPolylineOp::~HYDROGUI_ImportPolylineOp()
55 {
56 }
57
58 void HYDROGUI_ImportPolylineOp::startOperation()
59 {
60   HYDROGUI_Operation::startOperation();
61
62   myFileDlg = new SUIT_FileDlg( module()->getApp()->desktop(), true );
63   myFileDlg->setWindowTitle( getName() );
64   myFileDlg->setFileMode( SUIT_FileDlg::ExistingFiles );
65   myFileDlg->setNameFilter( tr("POLYLINE_FILTER") );
66
67   connect( myFileDlg, SIGNAL( accepted() ), this, SLOT( onApply() ) );
68   connect( myFileDlg, SIGNAL( rejected() ), this, SLOT( onCancel() ) );
69
70   myFileDlg->exec();
71 }
72
73 NCollection_Sequence<Handle(HYDROData_Entity)> HYDROGUI_ImportPolylineOp::ImportPolyOp(
74   const QStringList& aFileNames, Handle(HYDROData_Document) theDocument,
75   HYDROGUI_Module* module, HYDROData_ShapeFile::ImportShapeType theShapeTypesToImport)
76 {
77   NCollection_Sequence<Handle(HYDROData_Entity)> importedEntities;
78   foreach (QString aFileName, aFileNames) 
79   {
80     if ( aFileName.isEmpty() )
81       continue;
82
83     QString anExt = aFileName.split('.', QString::SkipEmptyParts).back();
84     anExt.toLower();
85     bool importXY = false;
86     if (anExt == "xyz")
87     {
88       importXY = SUIT_MessageBox::question( module->getApp()->desktop(),
89         tr( "IMPORT_POLYLINE" ),
90         tr( "IMPORT_POLYLINE_XY_PART_ONLY" ),
91         QMessageBox::Yes | QMessageBox::No, 
92         SUIT_MessageBox::Yes) == SUIT_MessageBox::Yes;
93     }
94     if (anExt == "shp")
95     {
96       QApplication::setOverrideCursor( Qt::WaitCursor );
97       HYDROData_ShapeFile anImporter;
98       NCollection_IndexedDataMap<Handle(HYDROData_Entity), SHPObject*> theEntitiesToSHPObj;
99       NCollection_Sequence<Handle(HYDROData_Entity)> PolyEnt;
100       int aShapeTypeOfFile = -1;
101       int aStat = anImporter.OpenAndParse(aFileName);
102       QApplication::restoreOverrideCursor();
103       if (aStat == 1)
104       {
105         QApplication::setOverrideCursor( Qt::WaitCursor );
106         aStat = anImporter.ImportPolylines(theDocument, aFileName, theEntitiesToSHPObj, theShapeTypesToImport); 
107         QApplication::restoreOverrideCursor();
108         for (int k=1;k<=theEntitiesToSHPObj.Extent();k++)
109         {
110           PolyEnt.Append(theEntitiesToSHPObj.FindKey(k));
111         }
112       if (aStat == 1 || aStat == 2)
113       {
114         //try to import DBF
115         QString aDBFFileName;
116         aDBFFileName = aFileName.simplified().replace( aFileName.simplified().size() - 4, 4, ".dbf");
117         bool DBF_Stat = anImporter.DBF_OpenDBF(aDBFFileName);
118         if (DBF_Stat)
119         {
120           QStringList aFieldList = anImporter.DBF_GetFieldList();
121           int nbRecords = anImporter.DBF_GetNbRecords();
122             assert (theEntitiesToSHPObj.Extent() == nbRecords);
123             if (theEntitiesToSHPObj.Extent() == nbRecords)
124           {
125             int indNameAttrFound = -1;
126             int k = 0;
127             bool bUseNameAttrFound = false;
128             for (QStringList::iterator it = aFieldList.begin(); it != aFieldList.end(); it++, k++)
129               if (QString::compare(*it, "name", Qt::CaseInsensitive) == 0)
130               {
131                 indNameAttrFound = k;
132                 break;
133               }
134
135               if (indNameAttrFound != -1)
136                 bUseNameAttrFound = SUIT_MessageBox::question( module->getApp()->desktop(),
137                                tr( "IMPORT_POLYLINE" ),
138                                tr( "IMPORT_POLYLINE_USE_NAME_ATTR" ),
139                                QMessageBox::Yes | QMessageBox::No, 
140                                SUIT_MessageBox::Yes) == SUIT_MessageBox::Yes;
141   
142             std::vector<std::vector<HYDROData_ShapeFile::DBF_AttrValue>> anAttrVV;
143             for (int i = 0; i < aFieldList.size(); i++)
144             {
145               std::vector<HYDROData_ShapeFile::DBF_AttrValue> anAttrV;
146               anAttrVV.push_back(anAttrV);
147               anImporter.DBF_GetAttributeList(i, anAttrVV[i] );
148             }
149
150             int indNULL = 1;
151                 for (int i = 1; i <= theEntitiesToSHPObj.Extent(); i++)
152             {
153                   Handle(HYDROData_PolylineXY) aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( theEntitiesToSHPObj.FindKey(i) );
154               QStringList aDBFinfo;
155               aDBFinfo << aFieldList; //first, the table header
156               for (int j = 0; j < aFieldList.size(); j++)
157               {
158                 QString attr;
159                 const HYDROData_ShapeFile::DBF_AttrValue& attrV = anAttrVV[j][i-1];
160                 if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_String)
161                   aDBFinfo << attrV.myStrVal;
162                 else if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_Integer)
163                   aDBFinfo << QString::number(attrV.myIntVal);
164                 else if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_Double)
165                   aDBFinfo << QString::number(attrV.myDoubleVal);
166                 else 
167                   aDBFinfo << "";
168               }
169               assert (aDBFinfo.size() / 2 == aFieldList.size());
170               aPolylineXY->SetDBFInfo(aDBFinfo);
171               if (bUseNameAttrFound)
172               {
173                 QString nameOfPoly = aDBFinfo[aDBFinfo.size() / 2 + indNameAttrFound];
174                 if (!nameOfPoly.isEmpty())
175                   aPolylineXY->SetName(nameOfPoly);
176                 else
177                 {
178                   aPolylineXY->SetName("null_name_" + QString::number(indNULL));
179                   indNULL++;
180                 }
181               }
182             }
183           }
184         }        
185       }
186
187         if (anImporter.GetShapeType() == 13) //Polyline 3D
188         {
189           HYDROGUI_ImportPolylineDlg* aDLG = new HYDROGUI_ImportPolylineDlg( module->getApp()->desktop(), PolyEnt );
190           aDLG->setModal( true );
191           aDLG->setWindowTitle(tr("IMPORT_POLYLINE"));
192           //QApplication::restoreOverrideCursor();
193           if( aDLG->exec()==QDialog::Accepted )
194           {
195             NCollection_Sequence<Handle(HYDROData_Entity)> CheckedPolylines = aDLG->GetCheckedPolylines();
196             NCollection_IndexedDataMap<Handle(HYDROData_Entity), SHPObject*> CheckedEntitiesToSHPObj;
197             for (int k=1;k<=CheckedPolylines.Size();k++)
198             {
199               SHPObject* const* SHPObkP = theEntitiesToSHPObj.Seek(CheckedPolylines(k));
200               if (SHPObkP != NULL)
201                 CheckedEntitiesToSHPObj.Add(CheckedPolylines(k), *SHPObkP);
202             }
203             NCollection_Sequence<Handle(HYDROData_Entity)> theEntitiesPoly3D;
204             anImporter.ImportPolylines3D(theDocument, CheckedEntitiesToSHPObj, theEntitiesPoly3D, theShapeTypesToImport);          
205             PolyEnt.Append(theEntitiesPoly3D);
206           }
207         }
208         anImporter.Free();
209       }
210       if (aStat == 1)
211         UpdateView(module, PolyEnt);
212       else if (aStat == 2)
213       {
214         UpdateView(module, PolyEnt);
215         if (theShapeTypesToImport == HYDROData_ShapeFile::ImportShapeType_All) //if other flag = > no need to show this messagebox
216           SUIT_MessageBox::information(module->getApp()->desktop(), 
217             tr( "IMPORT_POLYLINE" ), tr ("POLYGON_IMPORTED_AS_POLYLINE"));
218       }
219       else
220       {
221         QString aMess;
222         if (theShapeTypesToImport == HYDROData_ShapeFile::ImportShapeType::ImportShapeType_Polygon)
223           aMess += tr ("POLYLINE_IMPORT_FAILED_AS_POLYGON") + ";\n";
224         else
225           aMess += tr ("POLYLINE_IMPORT_FAILED_AS_POLYLINE") + ";\n";
226
227         if (aStat == -1)
228           aMess += tr ("CANT_OPEN_SHP");
229         else if (aStat == -2)
230           aMess += tr ("CANT_OPEN_SHX");
231         else 
232           aMess += tr ("SHAPE_TYPE_IS") + anImporter.GetShapeTypeName(aShapeTypeOfFile);
233         SUIT_MessageBox::warning( module->getApp()->desktop(), tr( "IMPORT_POLYLINE" ), aMess);
234       }
235       importedEntities.Append(PolyEnt);
236     }
237     else if ( anExt == "xy" || (importXY && anExt == "xyz"))
238     {
239       if (!HYDROData_Tool::importPolylineFromXYZ(aFileName, theDocument, true, importedEntities))
240         SUIT_MessageBox::warning( module->getApp()->desktop(), tr( "IMPORT_POLYLINE" ), tr( "NO_ONE_POLYLINE_IMPORTED" ));
241     }
242     else if (anExt == "xyz")
243     {
244       if (!HYDROData_Tool::importPolylineFromXYZ(aFileName, theDocument, false, importedEntities))
245         SUIT_MessageBox::warning( module->getApp()->desktop(), tr( "IMPORT_POLYLINE" ), tr( "NO_ONE_POLYLINE_IMPORTED" ));
246     }
247   }
248   return importedEntities;
249 }
250
251 void HYDROGUI_ImportPolylineOp::onApply()
252 {
253   if ( !myFileDlg )
254   {
255     abort();
256     return;
257   }
258
259   QStringList aFileNames = myFileDlg->selectedFiles();
260   
261   //QApplication::setOverrideCursor( Qt::WaitCursor );  
262   startDocOperation();
263
264   ImportPolyOp(aFileNames, doc(), module(), HYDROData_ShapeFile::ImportShapeType_All);
265  
266   if (!aFileNames.empty())
267   {
268     commitDocOperation();
269     commit();
270     module()->update( UF_Model | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init | UF_OCCViewer );
271   }
272   else
273     abort();
274   
275   QApplication::restoreOverrideCursor();
276 }
277
278 void HYDROGUI_ImportPolylineOp::UpdateView( HYDROGUI_Module* module, NCollection_Sequence<Handle(HYDROData_Entity)>& anEntities)
279 {
280   size_t anActiveViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( module );
281   if ( anActiveViewId == 0 )
282     anActiveViewId = HYDROGUI_Tool::GetActiveOCCViewId( module );
283
284   for (int i = 1; i <= anEntities.Size() ; i++)
285   {
286     anEntities(i)->Update();
287     module->setObjectVisible( anActiveViewId, anEntities(i), true );
288     module->setIsToUpdate( anEntities(i) );
289   }
290 }