Salome HOME
487e04bbdced4d586a278f0ff2f2b3324244c406
[modules/paravis.git] / src / Plugins / MEDReader / plugin / ParaViewPlugin / pqMEDReaderFieldsWidget.cxx
1 // Copyright (C) 2010-2023  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, or (at your option) any later version.
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 "pqMEDReaderFieldsWidget.h"
22
23 #include "vtkMEDReader.h"
24 #include "vtkPVMetaDataInformation.h"
25
26 #include "pqTreeWidget.h"
27 #include "pqTreeWidgetItemObject.h"
28 #include "vtkDataSetAttributes.h"
29 #include "vtkGraph.h"
30 #include "vtkNew.h"
31 #include "vtkStringArray.h"
32 #include "vtkTree.h"
33
34 #include <QStringList>
35 #include <QHeaderView>
36
37 //-----------------------------------------------------------------------------
38 pqMEDReaderFieldsWidget::pqMEDReaderFieldsWidget(
39   vtkSMProxy *smproxy, vtkSMProperty *smproperty, QWidget *parentObject)
40 : Superclass(smproxy, smproperty, parentObject)
41 {
42   this->TreeWidget->header()->hide();
43   this->visibleHeader = false;
44   this->TransmitToParent = true;
45   this->initializeTreeWidget(smproxy, smproperty);
46 }
47
48 //-----------------------------------------------------------------------------
49 pqMEDReaderFieldsWidget::~pqMEDReaderFieldsWidget()
50 {
51 }
52
53 //-----------------------------------------------------------------------------
54 void pqMEDReaderFieldsWidget::loadTreeWidgetItems()
55 {
56   //Clear Item Map
57   this->ItemMap.clear();
58
59   // Clear tree
60   this->TreeWidget->clear();
61
62   // Clear unique checked item vector
63   this->UniqueCheckedItems.clear();
64
65   // Recover meta data graph
66   vtkPVMetaDataInformation *info(vtkPVMetaDataInformation::New());
67   this->proxy()->GatherInformation(info);
68   vtkGraph* graph = vtkGraph::SafeDownCast(info->GetInformationData());
69
70   // Create a tree
71   vtkNew<vtkTree> tree;
72   tree->CheckedShallowCopy(graph);
73   vtkStringArray* names =
74     vtkStringArray::SafeDownCast(tree->GetVertexData()->GetAbstractArray("Names"));
75
76   if(!names)// In case of error right at the begining of loading process (empty MED file)
77     return ;
78
79   vtkIdType root = tree->GetRoot();
80   vtkIdType fst = tree->GetChild(root, 0); // FieldsStatusTree
81
82   this->NItems = 0;
83   int nLeaves = 0;
84   for (int i = 1; i < tree->GetNumberOfChildren(fst); i += 2)
85     {
86     // Browse all interessting tree node
87
88     // TSX Node
89     vtkIdType tsxId = tree->GetChild(fst, i);
90     vtkIdType tsId = tree->GetChild(fst, i - 1);
91     pqTreeWidgetItemObject *ts = new pqTreeWidgetItemObject(this->TreeWidget, QStringList());
92     this->NItems++;
93     QString tsxName = QString(names->GetValue(tsxId));
94     ts->setText(0, tsxName);
95     ts->setData(0, Qt::ToolTipRole, QString(names->GetValue(tsId)));
96
97     // MAIL Node
98     for (int maili = 0; maili < tree->GetNumberOfChildren(tsxId); maili++)
99       {
100       vtkIdType mailId = tree->GetChild(tsxId, maili);
101       pqTreeWidgetItemObject *mail = new pqTreeWidgetItemObject(ts, QStringList());
102       this->NItems++;
103       QString mailName = QString(names->GetValue(mailId));
104       mail->setText(0, mailName);
105       mail->setData(0, Qt::ToolTipRole, QString(names->GetValue(mailId)));
106
107       QString propertyBaseName = tsxName + "/" + mailName + "/";
108
109       // ComsupX node
110       for (int comsupi = 0; comsupi < tree->GetNumberOfChildren(mailId); comsupi++)
111         {
112         vtkIdType comSupId = tree->GetChild(mailId, comsupi);
113         pqTreeWidgetItemObject *comsup = new pqTreeWidgetItemObject(mail, QStringList());
114         this->NItems++;
115         QString comsupName = QString(names->GetValue(comSupId));
116         comsup->setText(0, comsupName);
117
118         // ComSup tooltip
119         vtkIdType geoTypeId = tree->GetChild(comSupId, 1);
120         QString comSupToolTipName(names->GetValue(comSupId));
121         for (int geoi = 0; geoi < tree->GetNumberOfChildren(geoTypeId); geoi++)
122           {
123           comSupToolTipName += QString("\n- %1").arg(
124             QString(names->GetValue(tree->GetChild(geoTypeId, geoi))));
125           }
126         comsup->setData(0, Qt::ToolTipRole, comSupToolTipName);
127
128         comsup->setFlags(comsup->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsSelectable);
129         comsup->setChecked(false);
130         QObject::connect(comsup, SIGNAL(checkedStateChanged(bool)), this, SLOT(updateChecks()));
131         this->UniqueCheckedItems.push_back(comsup);
132
133         QString fullComsupName = propertyBaseName + comsupName + "/";
134         // Arrs node
135         vtkIdType arrId = tree->GetChild(comSupId, 0);
136         for (int arri = 0; arri < tree->GetNumberOfChildren(arrId); arri++)
137           {
138           pqTreeWidgetItemObject *array = new pqTreeWidgetItemObject(comsup, QStringList());
139           this->NItems++;
140
141           vtkIdType arrayId = tree->GetChild(arrId, arri);
142           std::string str = names->GetValue(arrayId);
143           this->ItemMap[fullComsupName + QString(str.c_str())] = array;
144
145           const char* separator = vtkMEDReader::GetSeparator();
146           size_t pos = str.find(separator);
147           std::string name = str.substr(0, pos);
148
149           array->setText(0, QString(name.c_str()));
150           array->setFlags(array->flags() | Qt::ItemIsUserCheckable);
151           array->setChecked(false);
152
153           // Special Field
154           if (tree->GetNumberOfChildren(arrayId) != 0)
155             {
156             QFont font;
157             font.setItalic(true);
158             font.setUnderline(true);
159             array->setData(0, Qt::FontRole, QVariant(font));
160
161   array->setData(0, Qt::ToolTipRole,
162     QString("Whole \" %1\" mesh").arg(name.c_str()));
163   array->setData(0, Qt::DecorationRole,
164     QPixmap(":/ParaViewResources/Icons/pqCellDataForWholeMesh16.png"));
165             }
166           // Standard Field
167           else
168             {
169             std::string spatialDiscr = str.substr(pos + strlen(separator));
170             QString tooltip = QString(name.c_str() + QString(" (") +
171               spatialDiscr.c_str() + QString(")"));
172             array->setData(0, Qt::ToolTipRole, tooltip);
173
174             QPixmap pix;
175             if (spatialDiscr == "P0")
176               {
177               pix.load(":/ParaViewResources/Icons/pqCellData16.png");
178               }
179             else if (spatialDiscr == "P1")
180               {
181               pix.load(":/ParaViewResources/Icons/pqPointData16.png");
182               }
183             else if (spatialDiscr == "GAUSS")
184               {
185               pix.load(":/ParaViewResources/Icons/pqQuadratureData16.png");
186               }
187             else if (spatialDiscr == "GSSNE")
188               {
189               pix.load(":/ParaViewResources/Icons/pqElnoData16.png");
190               }
191             array->setData(0, Qt::DecorationRole, pix);
192             }
193
194           // Connection and updating checks for each item
195           QObject::connect(array, SIGNAL(checkedStateChanged(bool)), this, SLOT(updateChecks()));
196           nLeaves++;
197           }
198         }
199       }
200     }
201   // Expand tree
202   this->TreeWidget->expandAll();
203 }
204
205 //-----------------------------------------------------------------------------
206 void pqMEDReaderFieldsWidget::uncheckOtherUniqueItems(pqTreeWidgetItemObject* item)
207 {
208   // Uncheck all other items in vector
209   foreach (pqTreeWidgetItemObject* otherItems, this->UniqueCheckedItems)
210     {
211     if (otherItems != item)
212       {
213       otherItems->setCheckState(0, Qt::Unchecked);
214       }
215     }
216 }
217
218 //-----------------------------------------------------------------------------
219 void pqMEDReaderFieldsWidget::updateChecks()
220 {
221   // Call updateCheck on the sender
222   pqTreeWidgetItemObject* item = qobject_cast<pqTreeWidgetItemObject*>(QObject::sender());
223   this->updateChecks(item);
224 }
225
226 //-----------------------------------------------------------------------------
227 void pqMEDReaderFieldsWidget::updateChecks(pqTreeWidgetItemObject* item)
228 {
229   // When a Leaf item is checked, the parent will be checked (partially or not).
230   // Then other parents will be unchecked using uncheckOtherUniqueItems
231   // Then other parent leaf will be unchecked using updateChecks(parent)
232   //
233   // When a Parent item is checked, the leaf will be checked
234   // Then other parents will be unchecked using uncheckOtherUniqueItems
235   // Then other parent leaf will be unchecked using updateChecks(parent)
236
237   if (item->childCount() == 0)
238     {
239     // Only first level leaf will transmit checks to parent
240     if (this->TransmitToParent)
241       {
242       // Recover correct parent state
243       Qt::CheckState state = item->checkState(0);
244       pqTreeWidgetItemObject* parent =
245         dynamic_cast<pqTreeWidgetItemObject*>(item->QTreeWidgetItem::parent());
246       for (int i = 0; i < parent->childCount(); i++)
247         {
248         if (parent->child(i)->checkState(0) != state)
249           {
250           state = Qt::PartiallyChecked;
251           }
252         }
253       // Set Parent State
254       parent->setCheckState(0, state);
255       }
256     }
257   else
258     {
259     // Check/Uncheck childs, blocking looped call to slot
260     if (item->checkState(0) != Qt::PartiallyChecked)
261       {
262       this->TransmitToParent = false;
263       for (int i = 0; i < item->childCount(); i++)
264         {
265         pqTreeWidgetItemObject* leaf =
266           dynamic_cast<pqTreeWidgetItemObject*>(item->child(i));
267         leaf->setCheckState(0, item->checkState(0));
268         }
269       this->TransmitToParent = true;
270       }
271
272     // Uncheck other unique checked items
273     if (item->checkState(0) != Qt::Unchecked)
274       {
275       this->uncheckOtherUniqueItems(item);
276       }
277     }
278 }