Salome HOME
Addition of information of available geo types in tooltip common support section.
[modules/paravis.git] / src / Plugins / MEDReader / ParaViewPlugin / pqMEDReaderPanel.cxx
1 // Copyright (C) 2010-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 // Author : Anthony Geay
20
21 #include "pqMEDReaderPanel.h"
22 #include "ui_MEDReaderPanel.h"
23 #include "VectBoolWidget.h"
24
25 #include "vtkProcessModule.h"
26 #include "vtkMultiBlockDataSet.h"
27 #include "vtkInformation.h"
28 #include "vtkIntArray.h"
29 #include "vtkSMDoubleVectorProperty.h"
30 #include "vtkSMIntVectorProperty.h"
31 #include "vtkSMStringVectorProperty.h"
32 #include "vtkSMProxy.h"
33 #include "vtkEventQtSlotConnect.h"
34 #include "vtkPVSILInformation.h"
35 #include "vtkGraph.h"
36 #include "vtkMutableDirectedGraph.h"
37 #include "vtkAdjacentVertexIterator.h"
38 #include "vtkSMPropertyHelper.h"
39 #include "vtkStringArray.h"
40 #include "vtkDataSetAttributes.h"
41 #include "vtkMEDReader.h"
42
43 #include "pqTreeWidgetItemObject.h"
44 #include "pqSMAdaptor.h"
45 #include "pqProxy.h"
46 #include "pqPropertyManager.h"
47 #include "pqSILModel.h"
48 #include "pqProxySILModel.h"
49 #include "pqTreeViewSelectionHelper.h"
50 #include "pqTreeWidgetSelectionHelper.h"
51
52 #include <QHeaderView>
53
54 static const char ZE_SEP[]="@@][@@";
55
56 class PixSingle
57 {
58 public:
59   static const PixSingle &GetInstance();
60   QPixmap getPixFromStr(const std::string& st) const;
61   QPixmap getWholeMeshPix() const;
62   PixSingle();
63 private:
64   static const int NB_OF_DISCR=4;
65   static PixSingle *UNIQUE_PIX_SINGLE;
66   QPixmap _pixmaps[NB_OF_DISCR];
67   std::map<std::string,int> _ze_map;
68   QPixmap _whole_mesh;
69 };
70
71 PixSingle *PixSingle::UNIQUE_PIX_SINGLE=0;
72
73 const PixSingle &PixSingle::GetInstance()
74 {
75   if(!UNIQUE_PIX_SINGLE)
76     UNIQUE_PIX_SINGLE=new PixSingle;
77   return *UNIQUE_PIX_SINGLE;
78 }
79
80 PixSingle::PixSingle()
81 {
82   _pixmaps[0]=QPixmap(":/ParaViewResources/Icons/pqCellData16.png");
83   _pixmaps[1]=QPixmap(":/ParaViewResources/Icons/pqPointData16.png");
84   _pixmaps[2]=QPixmap(":/ParaViewResources/Icons/pqQuadratureData16.png");
85   _pixmaps[3]=QPixmap(":/ParaViewResources/Icons/pqElnoData16.png");
86   _ze_map[std::string("P0")]=0;
87   _ze_map[std::string("P1")]=1;
88   _ze_map[std::string("GAUSS")]=2;
89   _ze_map[std::string("GSSNE")]=3;
90   _whole_mesh=QPixmap(":/ParaViewResources/Icons/pqCellDataForWholeMesh16.png");
91 }
92
93 QPixmap PixSingle::getPixFromStr(const std::string& st) const
94 {
95   std::map<std::string,int>::const_iterator it(_ze_map.find(st));
96   if(it!=_ze_map.end())
97     return _pixmaps[(*it).second];
98   else
99     return QPixmap();
100 }
101
102 QPixmap PixSingle::getWholeMeshPix() const
103 {
104   return _whole_mesh;
105 }
106
107 class pqMEDReaderPanel::pqUI: public QObject, public Ui::MEDReaderPanel
108 {
109 public:
110   pqUI(pqMEDReaderPanel *p):QObject(p)
111   {
112     this->VTKConnect = vtkSmartPointer<vtkEventQtSlotConnect>::New();
113   }
114
115   ~pqUI() { }
116   
117   vtkSmartPointer<vtkEventQtSlotConnect> VTKConnect;
118   QMap<QTreeWidgetItem*, QString> TreeItemToPropMap;
119 };
120
121 pqMEDReaderPanel::pqMEDReaderPanel(pqProxy *object_proxy, QWidget *p):Superclass(object_proxy,p),_reload_req(false),_optional_widget(0)
122 {
123   initAll();
124 }
125
126 void pqMEDReaderPanel::initAll()
127 {
128   _all_lev4.clear();
129   this->UI=new pqUI(this);
130   this->UI->setupUi(this);
131   this->UI->Fields->setHeaderHidden(true);
132   this->updateSIL();
133   ////////////////////
134   vtkSMProxy *reader(this->referenceProxy()->getProxy());
135   vtkPVSILInformation *info(vtkPVSILInformation::New());
136   reader->GatherInformation(info);
137   vtkGraph *g(info->GetSIL());
138   vtkMutableDirectedGraph *g2(vtkMutableDirectedGraph::SafeDownCast(g));
139   int idNames(0);
140   vtkAbstractArray *verticesNames(g2->GetVertexData()->GetAbstractArray("Names",idNames));
141   vtkStringArray *verticesNames2(vtkStringArray::SafeDownCast(verticesNames));
142   vtkIdType id0;
143   bool found(false);
144   for(int i=0;i<verticesNames2->GetNumberOfValues();i++)
145     {
146       vtkStdString &st(verticesNames2->GetValue(i));
147       if(st=="FieldsStatusTree")
148         {
149           id0=i;
150           found=true;
151         }
152     }
153   if(!found)
154     std::cerr << "There is an internal error ! The tree on server side has not the expected look !" << std::endl;
155   vtkAdjacentVertexIterator *it0(vtkAdjacentVertexIterator::New());
156   g2->GetAdjacentVertices(id0,it0);
157   int kk(0),ll(0);
158   while(it0->HasNext())
159     {
160       vtkIdType idToolTipForTS(it0->Next());
161       QString toolTipName0(QString::fromStdString((const char *)verticesNames2->GetValue(idToolTipForTS)));
162       QString nbTS;
163       QList<QString> dts,its,tts;
164       {
165         vtkAdjacentVertexIterator *itForTS(vtkAdjacentVertexIterator::New());
166         g2->GetAdjacentVertices(idToolTipForTS,itForTS);
167         vtkIdType idForNbTS(itForTS->Next());
168         nbTS=QString::fromStdString((const char *)verticesNames2->GetValue(idForNbTS));
169         itForTS->Delete();
170         int nbTSInt(nbTS.toInt());
171         for(int ii=0;ii<nbTSInt;ii++)
172           {
173             dts.push_back(QString::fromStdString((const char *)verticesNames2->GetValue(idForNbTS+3*ii+1)));
174             its.push_back(QString::fromStdString((const char *)verticesNames2->GetValue(idForNbTS+3*ii+2)));
175             tts.push_back(QString::fromStdString((const char *)verticesNames2->GetValue(idForNbTS+3*ii+3)));
176           }
177       }
178       vtkIdType id1(it0->Next());
179       //
180       vtkSMProperty *SMProperty(this->proxy()->GetProperty("FieldsStatus"));
181       SMProperty->ResetToDefault();//this line is very important !
182       //
183       QString name0(QString::fromStdString((const char *)verticesNames2->GetValue(id1))); QList<QString> strs0; strs0.append(name0);
184       pqTreeWidgetItemObject *item0(new pqTreeWidgetItemObject(this->UI->Fields,strs0));
185       item0->setData(0,Qt::UserRole,name0);
186       item0->setData(0,Qt::ToolTipRole,toolTipName0);
187       //
188       QList<QVariant> modulesAct;
189       for(int i=0;i<nbTS.toInt();i++)
190         modulesAct.push_back(QVariant(true));
191       item0->setProperty("NbOfTS",nbTS);
192       item0->setProperty("DTS",QVariant(dts));
193       item0->setProperty("ITS",QVariant(its));
194       item0->setProperty("TTS",QVariant(tts));
195       item0->setProperty("ChosenTS",QVariant(modulesAct));
196       //
197       vtkAdjacentVertexIterator *it1(vtkAdjacentVertexIterator::New());//mesh
198       g2->GetAdjacentVertices(id1,it1);
199       while(it1->HasNext())
200         {
201           vtkIdType id2(it1->Next());
202           QString name1(QString::fromStdString((const char *)verticesNames2->GetValue(id2))); QList<QString> strs1; strs1.append(name1);
203           QString toolTipName1(name1);
204           pqTreeWidgetItemObject *item1(new pqTreeWidgetItemObject(item0,strs1));
205           item1->setData(0,Qt::UserRole,name1);
206           item1->setData(0,Qt::ToolTipRole,toolTipName1);
207           vtkAdjacentVertexIterator *it2(vtkAdjacentVertexIterator::New());//common support
208           g2->GetAdjacentVertices(id2,it2);
209           while(it2->HasNext())
210             {
211               vtkIdType id3(it2->Next());
212               QString name2(QString::fromStdString((const char *)verticesNames2->GetValue(id3))); QList<QString> strs2; strs2.append(name2);
213               pqTreeWidgetItemObject *item2(new pqTreeWidgetItemObject(item1,strs2));
214               item2->setData(0,Qt::UserRole,name2);
215               item2->setData(0,Qt::CheckStateRole,0);
216               vtkAdjacentVertexIterator *it3(vtkAdjacentVertexIterator::New());//fields !
217               g2->GetAdjacentVertices(id3,it3);
218               vtkIdType id3Arrs(it3->Next());
219               vtkAdjacentVertexIterator *it3Arrs(vtkAdjacentVertexIterator::New());//arrs in fields !
220               g2->GetAdjacentVertices(id3Arrs,it3Arrs);
221               while(it3Arrs->HasNext())
222                 {
223                   vtkIdType id4(it3Arrs->Next());
224                   std::string name3CppFull((const char *)verticesNames2->GetValue(id4));
225                   std::size_t pos(name3CppFull.find_first_of(ZE_SEP));
226                   std::string name3Only(name3CppFull.substr(0,pos)); std::string spatialDiscr(name3CppFull.substr(pos+sizeof(ZE_SEP)-1));
227                   QString name3(QString::fromStdString(name3Only)); QList<QString> strs3; strs3.append(name3);
228                   QString toolTipName3(name3+QString(" (")+spatialDiscr.c_str()+QString(")"));
229                   //
230                   vtkAdjacentVertexIterator *it4(vtkAdjacentVertexIterator::New());// is it a special field ? A field mesh ?
231                   g2->GetAdjacentVertices(id4,it4);
232                   bool isSpecial(it4->HasNext());
233                   it4->Delete();
234                   //
235                   pqTreeWidgetItemObject *item3(new pqTreeWidgetItemObject(item2,strs3));
236                   _all_lev4.push_back(item3);
237                   item3->setData(0,Qt::UserRole,name3);
238                   item3->setData(0,Qt::CheckStateRole,0);
239                   if(isSpecial)
240                     {
241                       QFont font; font.setItalic(true); font.setUnderline(true);
242                       item3->setData(0,Qt::FontRole,QVariant(font));
243                       item3->setData(0,Qt::ToolTipRole,QString("Whole \"%1\" mesh").arg(name3));
244                       item3->setData(0,Qt::DecorationRole,PixSingle::GetInstance().getWholeMeshPix());
245                     }
246                   else
247                     {
248                       item3->setData(0,Qt::ToolTipRole,toolTipName3);
249                       item3->setData(0,Qt::DecorationRole,PixSingle::GetInstance().getPixFromStr(spatialDiscr));
250                     }
251                   this->propertyManager()->registerLink(item3,"checked",SIGNAL(checkedStateChanged(bool)),this->proxy(),SMProperty,ll);
252                   _leaves.insert(std::pair<pqTreeWidgetItemObject *,int>(item3,ll));
253                   connect(item2,SIGNAL(checkedStateChanged(bool)),item3,SLOT(setChecked(bool)));
254                   connect(item3,SIGNAL(checkedStateChanged(bool)),this,SLOT(aLev4HasBeenFired()));
255                   ll++;
256                 }
257               vtkIdType id3Gts(it3->Next());
258               vtkAdjacentVertexIterator *it3Gts(vtkAdjacentVertexIterator::New());//geo types in fields !
259               g2->GetAdjacentVertices(id3Gts,it3Gts);
260               QString toolTipName2(name2);
261               while(it3Gts->HasNext())
262                 {
263                   vtkIdType idGt(it3Gts->Next());
264                   std::string gtName((const char *)verticesNames2->GetValue(idGt));
265                   toolTipName2=QString("%1\n- %2").arg(toolTipName2).arg(QString(gtName.c_str()));
266                 }
267               item2->setData(0,Qt::ToolTipRole,toolTipName2);
268               it3Gts->Delete();
269               it3->Delete();
270               it3Arrs->Delete();
271               if(kk==0)
272                 item2->setChecked(true);
273               kk++;
274             }
275           it2->Delete();
276         }
277       it1->Delete();
278     }
279   it0->Delete();
280   this->UI->Fields->header()->setStretchLastSection(true);
281   this->UI->Fields->expandAll();
282   info->Delete();
283   this->UI->stdMode->setChecked(true);
284   this->UI->VTKConnect->Connect(this->proxy(),vtkCommand::UpdateInformationEvent, this, SLOT(updateSIL()));
285   ///
286   this->UI->Reload->setProperty("NbOfReloadDynProp",QVariant(1));
287   vtkSMProperty *SMProperty(this->proxy()->GetProperty("ReloadReq"));
288   connect(this->UI->Reload,SIGNAL(pressed()),this,SLOT(reloadFired()));
289   this->propertyManager()->registerLink(this->UI->Reload,"NbOfReloadDynProp",SIGNAL(pressed()),this->proxy(),SMProperty);
290   ///
291   vtkSMProperty *SMProperty0(this->proxy()->GetProperty("GenerateVectors"));
292   this->propertyManager()->registerLink(this->UI->GenerateVects,"checked",SIGNAL(stateChanged(int)),this->proxy(),SMProperty0);
293   ///
294   vtkSMProperty *SMProperty2(this->proxy()->GetProperty("TimeOrModal"));
295   SMProperty2->ResetToDefault();//this line is very important !
296   this->propertyManager()->registerLink(this->UI->modeMode,"checked",SIGNAL(toggled(bool)),this->proxy(),SMProperty2);
297   ///
298   delete _optional_widget;
299   _optional_widget=new VectBoolWidget(this->UI->timeStepsInspector,getMaxNumberOfTS());
300   _optional_widget->hide();
301   this->UI->timeStepsInspector->setMinimumSize(QSize(0,0));
302   connect(this->UI->modeMode,SIGNAL(toggled(bool)),this,SLOT(vectOfBoolWidgetRequested(bool)));
303   vtkSMProperty *SMProperty3(this->proxy()->GetProperty("TimesFlagsStatus"));
304   SMProperty3->ResetToDefault();
305   const QVector<VectBoolItem *>& items(_optional_widget->getItems());
306   int itt(0);
307   foreach(VectBoolItem *item,items)
308     {
309       this->propertyManager()->registerLink(item,"activated",SIGNAL(changed()),this->proxy(),SMProperty3,itt++);
310     }
311 }
312
313 pqMEDReaderPanel::~pqMEDReaderPanel()
314 {
315   delete _optional_widget;
316 }
317
318 void pqMEDReaderPanel::linkServerManagerProperties()
319 {
320   this->Superclass::linkServerManagerProperties();
321 }
322
323 void pqMEDReaderPanel::updateSIL()
324 {
325   if(_reload_req)
326     {
327       _reload_req=false;
328       this->UI->geometryGroupBox->hide();
329       delete this->UI;
330       foreach(QObject *child,children())
331         {
332           QLayout *layout(qobject_cast<QLayout *>(child));
333           if(layout)
334             delete layout;
335         }
336       initAll();
337     }
338 }
339
340 void pqMEDReaderPanel::aLev4HasBeenFired()
341 {
342   pqTreeWidgetItemObject *zeItem(qobject_cast<pqTreeWidgetItemObject *>(sender()));
343   if(!zeItem)
344     return;
345   pqTreeWidgetItemObject *father(dynamic_cast<pqTreeWidgetItemObject *>(zeItem->QTreeWidgetItem::parent()));
346   QTreeWidgetItem *godFather(father->QTreeWidgetItem::parent()->parent());
347   if(!father)
348     return ;
349   if(zeItem->isChecked())
350     {
351       bool isActivatedTSChanged(false);
352       // This part garantees that all leaves having not the same father than zeItem are desactivated
353       foreach(pqTreeWidgetItemObject* elt,this->_all_lev4)
354         {
355           QTreeWidgetItem *testFath(elt->QTreeWidgetItem::parent());
356           if(testFath!=father)
357             if(elt->isChecked())
358               {
359                 elt->setChecked(false);
360                 if(godFather!=testFath->parent()->parent())
361                   isActivatedTSChanged=true;
362               }
363         }
364       //If all leaves are checked the father is check too
365       bool allItemsAreChked(true);
366       for(int i=0;i<father->childCount() && allItemsAreChked;i++)
367         {
368           pqTreeWidgetItemObject *elt(dynamic_cast<pqTreeWidgetItemObject *>(father->child(i)));
369           if(elt && !elt->isChecked())
370             allItemsAreChked=false;
371         }
372       if(allItemsAreChked && !father->isChecked())
373         father->setChecked(true);
374       // the user by clicking to a new entry has changed of TimeStepSeries -> notify it to thee time step selector widget
375       if(isActivatedTSChanged)
376         {
377           QStringList its,dts,tts;
378           getCurrentTS(its,dts,tts);
379           _optional_widget->setItems(its,dts,tts);
380         }
381     }
382   else
383     {
384       // if all are unchecked - check it again
385       bool allItemsAreUnChked(true);
386       foreach(pqTreeWidgetItemObject* elt,this->_all_lev4)
387         {
388           if(elt && elt->isChecked())
389             allItemsAreUnChked=false;
390         }
391       if(allItemsAreUnChked)
392         zeItem->setChecked(true);// OK zeItem was required to be unchecked but as it is the last one. Recheck it !
393       else
394         {// if all items are uncheked inside a same parent - uncheck the parent
395           allItemsAreUnChked=true;
396           for(int i=0;i<father->childCount() && allItemsAreUnChked;i++)
397             {
398               pqTreeWidgetItemObject *elt(dynamic_cast<pqTreeWidgetItemObject *>(father->child(i)));
399               if(elt && elt->isChecked())
400             allItemsAreUnChked=false;
401             }
402           if(allItemsAreUnChked && father->isChecked())
403             father->setChecked(false);
404         } 
405     }
406 }
407
408 void pqMEDReaderPanel::reloadFired()
409 {
410   static int iii(1);
411   QVariant v(iii++);
412   this->UI->Reload->setProperty("NbOfReloadDynProp",v);
413   _reload_req=true;
414   for(std::set<std::pair<pqTreeWidgetItemObject *,int> >::const_iterator it=_leaves.begin();it!=_leaves.end();it++)
415     ((*it).first)->disconnect(SIGNAL(checkedStateChanged(bool)));
416   //
417   vtkSMProperty *SMProperty(this->proxy()->GetProperty("FieldsStatus"));
418   for(std::set<std::pair<pqTreeWidgetItemObject *,int> >::const_iterator it=_leaves.begin();it!=_leaves.end();it++)
419     this->propertyManager()->unregisterLink((*it).first,"checked",SIGNAL(checkedStateChanged(bool)),this->proxy(),SMProperty,(*it).second);
420   this->propertyManager()->propertyChanged();
421   vtkSMProperty *SMProperty3(this->proxy()->GetProperty("TimeOrModal"));
422   this->propertyManager()->unregisterLink(this->UI->modeMode,"checked",SIGNAL(toggled(bool)),this->proxy(),SMProperty3);
423 }
424
425 void pqMEDReaderPanel::vectOfBoolWidgetRequested(bool isMode)
426 {
427   if(isMode)
428     {
429       this->UI->timeStepsInspector->setMinimumSize(QSize(200,250));
430       _optional_widget->show();
431       QStringList its,dts,tts;
432       getCurrentTS(its,dts,tts);
433       _optional_widget->setItems(its,dts,tts);
434     }
435   else
436     {
437       _optional_widget->hide();
438       this->UI->timeStepsInspector->setMinimumSize(QSize(0,0));
439     }
440 }
441
442 void pqMEDReaderPanel::getCurrentTS(QStringList& its, QStringList& dts, QStringList& tts) const
443 {
444   
445   for(std::vector<pqTreeWidgetItemObject *>::const_iterator it=_all_lev4.begin();it!=_all_lev4.end();it++)
446     {
447       if((*it)->property("checked").toInt())
448         {
449           QTreeWidgetItem *obj((*it)->QTreeWidgetItem::parent()->QTreeWidgetItem::parent()->QTreeWidgetItem::parent());
450           pqTreeWidgetItemObject *objC(dynamic_cast<pqTreeWidgetItemObject *>(obj));
451           its=objC->property("ITS").toStringList();
452           dts=objC->property("DTS").toStringList();
453           tts=objC->property("TTS").toStringList();
454           return;
455         }
456     }
457   std::cerr << "pqMEDReaderPanel::getCurrentTS : internal error ! Something is going wrong !" << std::endl;
458 }
459
460 int pqMEDReaderPanel::getMaxNumberOfTS() const
461 {
462   int ret(0);
463   for(std::vector<pqTreeWidgetItemObject *>::const_iterator it=_all_lev4.begin();it!=_all_lev4.end();it++)
464     {
465       if((*it)->property("checked").toInt())
466         {
467           QTreeWidgetItem *obj((*it)->QTreeWidgetItem::parent()->QTreeWidgetItem::parent()->QTreeWidgetItem::parent());
468           pqTreeWidgetItemObject *objC(dynamic_cast<pqTreeWidgetItemObject *>(obj));
469           ret=std::max(ret,objC->property("NbOfTS").toInt());
470         }
471     }
472   return ret;
473 }