Salome HOME
95c1a1bcb13321d095c8427b6a12a211401c4d0a
[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
32 #include <HYDROData_Profile.h>
33
34 #include <SUIT_Desktop.h>
35 #include <SUIT_FileDlg.h>
36 #include <LightApp_Application.h>
37
38 #include <QApplication>
39 #include <QFile>
40 #include <QFileInfo>
41 #include <SUIT_MessageBox.h>
42
43
44 HYDROGUI_ImportPolylineOp::HYDROGUI_ImportPolylineOp( HYDROGUI_Module* theModule )
45 : HYDROGUI_Operation( theModule )
46 {
47   setName( tr( "IMPORT_POLYLINE" ) );
48 }
49
50 HYDROGUI_ImportPolylineOp::~HYDROGUI_ImportPolylineOp()
51 {
52 }
53
54 void HYDROGUI_ImportPolylineOp::startOperation()
55 {
56   HYDROGUI_Operation::startOperation();
57
58   myFileDlg = new SUIT_FileDlg( module()->getApp()->desktop(), true );
59   myFileDlg->setWindowTitle( getName() );
60   myFileDlg->setFileMode( SUIT_FileDlg::ExistingFiles );
61   myFileDlg->setNameFilter( tr("POLYLINE_FILTER") );
62
63   connect( myFileDlg, SIGNAL( accepted() ), this, SLOT( onApply() ) );
64   connect( myFileDlg, SIGNAL( rejected() ), this, SLOT( onCancel() ) );
65
66   myFileDlg->exec();
67 }
68
69 NCollection_Sequence<Handle(HYDROData_Entity)> HYDROGUI_ImportPolylineOp::ImportPolyOp(
70   const QStringList& aFileNames, Handle(HYDROData_Document) theDocument,
71   HYDROGUI_Module* module, HYDROData_ShapeFile::ImportShapeType theShapeTypesToImport)
72 {
73   NCollection_Sequence<Handle(HYDROData_Entity)> importedEntities;
74   foreach (QString aFileName, aFileNames) 
75   {
76     if ( aFileName.isEmpty() )
77       continue;
78
79     QString anExt = aFileName.split('.', QString::SkipEmptyParts).back();
80
81     if (anExt == "shp")
82     {
83       HYDROData_ShapeFile anImporter;
84       NCollection_Sequence<Handle(HYDROData_Entity)> theEntities;
85       int aShapeTypeOfFile = -1;
86       int aStat = anImporter.ImportPolylines(theDocument, aFileName, theEntities, 
87         aShapeTypeOfFile, theShapeTypesToImport ); 
88       if (aStat == 1 || aStat == 2)
89       {
90         //try to import DBF
91         QString aDBFFileName;
92         aDBFFileName = aFileName.simplified().replace( aFileName.simplified().size() - 4, 4, ".dbf");
93         bool DBF_Stat = anImporter.DBF_OpenDBF(aDBFFileName);
94         if (DBF_Stat)
95         {
96           QStringList aFieldList = anImporter.DBF_GetFieldList();
97           int nbRecords = anImporter.DBF_GetNbRecords();
98           assert (theEntities.Length() == nbRecords);
99           if (theEntities.Length() == nbRecords)
100           {
101             int indNameAttrFound = -1;
102             int k = 0;
103             bool bUseNameAttrFound = false;
104             for (QStringList::iterator it = aFieldList.begin(); it != aFieldList.end(); it++, k++)
105               if (QString::compare(*it, "name", Qt::CaseInsensitive) == 0)
106               {
107                 indNameAttrFound = k;
108                 break;
109               }
110
111               if (indNameAttrFound != -1)
112                 bUseNameAttrFound = SUIT_MessageBox::question( module->getApp()->desktop(),
113                                tr( "IMPORT_POLYLINE" ),
114                                tr( "IMPORT_POLYLINE_USE_NAME_ATTR" ),
115                                QMessageBox::Yes | QMessageBox::No, 
116                                SUIT_MessageBox::Yes) == SUIT_MessageBox::Yes;
117   
118             std::vector<std::vector<HYDROData_ShapeFile::DBF_AttrValue>> anAttrVV;
119             for (int i = 0; i < aFieldList.size(); i++)
120             {
121               std::vector<HYDROData_ShapeFile::DBF_AttrValue> anAttrV;
122               anAttrVV.push_back(anAttrV);
123               anImporter.DBF_GetAttributeList(i, anAttrVV[i] );
124             }
125
126             int indNULL = 1;
127             for (int i = 1; i <= theEntities.Length(); i++)
128             {
129               Handle(HYDROData_PolylineXY) aPolylineXY = Handle(HYDROData_PolylineXY)::DownCast( theEntities(i) );
130               QStringList aDBFinfo;
131               aDBFinfo << aFieldList; //first, the table header
132               for (int j = 0; j < aFieldList.size(); j++)
133               {
134                 QString attr;
135                 const HYDROData_ShapeFile::DBF_AttrValue& attrV = anAttrVV[j][i-1];
136                 if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_String)
137                   aDBFinfo << attrV.myStrVal;
138                 else if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_Integer)
139                   aDBFinfo << QString::number(attrV.myIntVal);
140                 else if (attrV.myFieldType == HYDROData_ShapeFile::DBF_FieldType_Double)
141                   aDBFinfo << QString::number(attrV.myDoubleVal);
142                 else 
143                   aDBFinfo << "";
144               }
145               assert (aDBFinfo.size() / 2 == aFieldList.size());
146               aPolylineXY->SetDBFInfo(aDBFinfo);
147               if (bUseNameAttrFound)
148               {
149                 QString nameOfPoly = aDBFinfo[aDBFinfo.size() / 2 + indNameAttrFound];
150                 if (!nameOfPoly.isEmpty())
151                   aPolylineXY->SetName(nameOfPoly);
152                 else
153                 {
154                   aPolylineXY->SetName("null_name_" + QString::number(indNULL));
155                   indNULL++;
156                 }
157               }
158             }
159           }
160         }        
161       }
162       if (aStat == 1)
163         UpdateView(module, theEntities);
164       else if (aStat == 2)
165       {
166         UpdateView(module, theEntities);
167         if (theShapeTypesToImport == HYDROData_ShapeFile::ImportShapeType_All) //if other flag = > no need to show this messagebox
168           SUIT_MessageBox::information(module->getApp()->desktop(), 
169             tr( "IMPORT_POLYLINE" ), "Contour of the polygon(s) have been imported as polyline(s)");
170       }
171       else
172       {
173         QString aMess = "Cannot import content of this file as polyline;\n";
174         if (aStat == -1)
175           aMess += "Cannot open SHP file";
176         else if (aStat == -2)
177           aMess += "Cannot open SHX file";
178         else 
179           aMess += "The shape type of file is " + anImporter.GetShapeTypeName(aShapeTypeOfFile);
180         SUIT_MessageBox::warning( module->getApp()->desktop(), tr( "IMPORT_POLYLINE" ), aMess);
181       }
182       importedEntities.Append(theEntities);
183     }
184   }
185   return importedEntities;
186 }
187
188 void HYDROGUI_ImportPolylineOp::onApply()
189 {
190   if ( !myFileDlg )
191   {
192     abort();
193     return;
194   }
195
196   QStringList aFileNames = myFileDlg->selectedFiles();
197   
198   QApplication::setOverrideCursor( Qt::WaitCursor );  
199   startDocOperation();
200
201   ImportPolyOp(aFileNames, doc(), module(), HYDROData_ShapeFile::ImportShapeType_All);
202  
203   if (!aFileNames.empty())
204   {
205     commitDocOperation();
206     commit();
207     module()->update( UF_Model | UF_VTKViewer | UF_VTK_Forced | UF_VTK_Init | UF_OCCViewer );
208   }
209   else
210     abort();
211   
212   QApplication::restoreOverrideCursor();
213 }
214
215 void HYDROGUI_ImportPolylineOp::UpdateView( HYDROGUI_Module* module, NCollection_Sequence<Handle(HYDROData_Entity)>& anEntities)
216 {
217   size_t anActiveViewId = HYDROGUI_Tool::GetActiveGraphicsViewId( module );
218   if ( anActiveViewId == 0 )
219     anActiveViewId = HYDROGUI_Tool::GetActiveOCCViewId( module );
220
221   for (int i = 1; i <= anEntities.Size() ; i++)
222   {
223     anEntities(i)->Update();
224     module->setObjectVisible( anActiveViewId, anEntities(i), true );
225     module->setIsToUpdate( anEntities(i) );
226   }
227 }