diff --git a/Applications/ParaView/Testing/XML/SpreadSheet3.xml b/Applications/ParaView/Testing/XML/SpreadSheet3.xml
index 75c49e54862333012213501ad360cbaeab217446..1b28fc0776fe8c6129d3f150ef61e4c5e84cd304 100644
--- a/Applications/ParaView/Testing/XML/SpreadSheet3.xml
+++ b/Applications/ParaView/Testing/XML/SpreadSheet3.xml
@@ -47,16 +47,13 @@
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
@@ -68,4 +65,5 @@
+
diff --git a/ParaViewCore/ServerManager/Core/vtkSMCompositeTreeDomain.cxx b/ParaViewCore/ServerManager/Core/vtkSMCompositeTreeDomain.cxx
index 40d4b1044c442fad09f69e36a77c5ec2ad67061d..5fee068a3afdd613beb220f27bc5c19674233599 100644
--- a/ParaViewCore/ServerManager/Core/vtkSMCompositeTreeDomain.cxx
+++ b/ParaViewCore/ServerManager/Core/vtkSMCompositeTreeDomain.cxx
@@ -141,13 +141,20 @@ int vtkSMCompositeTreeDomain::ReadXMLAttributes(vtkSMProperty* prop, vtkPVXMLEle
{
this->Mode = LEAVES;
}
+ else if (strcmp(mode, "amr") == 0)
+ {
+ this->Mode = AMR;
+ }
else if (strcmp(mode, "non-leaves") == 0)
{
- this->Mode = NON_LEAVES;
+ vtkWarningMacro("Obsolete 'non-leaves' mode detected. Using 'all' instead.");
+ this->Mode = ALL;
}
else if (strcmp(mode, "none") == 0)
{
- this->Mode = NONE;
+ // not sure why this mode was ever added or what it stood for <|:0).
+ vtkWarningMacro("Obsolete 'none' mode detected. Using 'all' instead.");
+ this->Mode = ALL;
}
else
{
@@ -155,6 +162,7 @@ int vtkSMCompositeTreeDomain::ReadXMLAttributes(vtkSMProperty* prop, vtkPVXMLEle
return 0;
}
}
+
if (const char* default_mode = element->GetAttribute("default_mode"))
{
if (strcmp(default_mode, "nonempty-leaf") == 0)
@@ -167,6 +175,18 @@ int vtkSMCompositeTreeDomain::ReadXMLAttributes(vtkSMProperty* prop, vtkPVXMLEle
return 0;
}
}
+
+ if (vtkPVXMLElement* hints = prop->GetHints())
+ {
+ vtkPVXMLElement* useFlatIndex = hints->FindNestedElementByName("UseFlatIndex");
+ if (useFlatIndex && useFlatIndex->GetAttribute("value") &&
+ strcmp(useFlatIndex->GetAttribute("value"), "0") == 0)
+ {
+ this->Mode = AMR;
+ vtkWarningMacro("'UseFlatIndex' index hint is deprecated. You may simply want "
+ "to set the 'mode' for the domain to 'amr' in the XML configuration.");
+ }
+ }
return 1;
}
@@ -231,8 +251,8 @@ void vtkSMCompositeTreeDomain::PrintSelf(ostream& os, vtkIndent indent)
case NON_LEAVES:
os << "NON_LEAVES";
break;
- case NONE:
- os << "NONE";
+ case AMR:
+ os << "AMR";
default:
os << "UNKNOWN";
}
diff --git a/ParaViewCore/ServerManager/Core/vtkSMCompositeTreeDomain.h b/ParaViewCore/ServerManager/Core/vtkSMCompositeTreeDomain.h
index d8a427239bd5a20dfa0b15ffb4d7896404257649..f8344faaaf429c5687bc1c6144313daf16d2b06c 100644
--- a/ParaViewCore/ServerManager/Core/vtkSMCompositeTreeDomain.h
+++ b/ParaViewCore/ServerManager/Core/vtkSMCompositeTreeDomain.h
@@ -21,20 +21,42 @@
* vtkSMCompositeTreeDomain can be added to a vtkSMIntVectorProperty. This
* domain requires a vtkSMInputProperty which is used to provide the input to
* the filter. This domain obtains data information from the input selected on
- * the required input property and then decides the range for the flat-index. A
- * flat index for a tree is obtained by performing a pre-order traversal of the
- * tree eg. A ( B ( D, E), C (F, G)) becomes: [A,B,D,E,C,F,G], so flat-index of A is
- * 0, while flat-index of C is 4.
+ * the required input property and then decides the range for values the
+ * property can have.
*
- * vtkSMCompositeTreeDomain can be used in multiple modes.
- * \li ALL : This mode is used if the property can accept any type of node index.
- * To select this mode in XML, use the `mode="all"`.
- * \li LEAVES: This mode is used if the property can only accept leaf nodes i.e.
- * indices for non-composite datasets. This is specified in XML
- * using `mode="leaves"`.
- * \li NON_LEAVES: This mode is used if the property can only accept non-leaf
- * node indices, specified using `mode="non-leaves"` in XML
- * configuration.
+ * Broadly speaking, there are two ways of identifying unique node in a
+ * composite dataset: `flat-index` (also called `composite-index`) and
+ * `level-block-index`. `flat-index` applies to all types of composite
+ * datasets while `level-block-index` (or just `level-index`) applies only to AMR
+ * datasets. `flat-index` for any node in an arbitrary composite-dataset
+ * is simply the index of that node in a pre-order traversal of the tree with
+ * the root composite-dataset getting the index 0. `level-index` for an AMR
+ * dataset is the AMR level number while `level-block-index` is a pair of
+ * the AMR level number and block number for the node in that level.
+ *
+ * The type of index the property expects, is defined by the domain's mode.
+ * Supported modes are:
+ * -# vtkSMCompositeTreeDomain::ALL: (default) \n
+ * The property uses `flat-index` and can accept index for any node (leaf or non-leaf).
+ * This can be specified in XML using the `mode="all"`.
+ *
+ * -# vtkSMCompositeTreeDomain::LEAVES:\n
+ * The property uses `flat-index` however can only accept flat-indices for
+ * leaf-nodes.
+ * This can be specified in XML using the `mode="leaves"`.
+ *
+ * -# vtkSMCompositeTreeDomain::AMR: \n
+ * The property uses `level-index` i.e. AMR level number or
+ * `level-block-index`. If the property has 2 elements (or for repeatable
+ * properties, if number of elements per command is 2) then
+ * `level-block-index` is used, otherwise simply the `level-index` is used.
+ * This only makes sense for filters dealing with AMR datasets.
+ * This can be specified in XML using the `mode="amr"`.
+ *
+ * -# vtkSMCompositeTreeDomain::NON_LEAVES: (deprecated)\n
+ * No longer supported (as of ParaView 5.4) and simply interpreted as
+ * vtkSMCompositeTreeDomain::ALL.
+ * This used to be specified in XML using the `mode="non-leaves"`.
*
* vtkSMCompositeTreeDomain also provides ability to set default value on the
* property. If mode is LEAVES, then the default value selected is the first
@@ -61,7 +83,6 @@ class vtkPVDataInformation;
class vtkSMInputProperty;
class vtkSMSourceProxy;
-// TODO: CHANGE NAME OF THIS CLASS
class VTKPVSERVERMANAGERCORE_EXPORT vtkSMCompositeTreeDomain : public vtkSMDomain
{
public:
@@ -119,7 +140,8 @@ public:
ALL = 0,
LEAVES = 1,
NON_LEAVES = 2,
- NONE = 3
+ NONE = 3,
+ AMR = 4,
};
enum DefaultModes
diff --git a/ParaViewCore/ServerManager/SMApplication/Resources/filters.xml b/ParaViewCore/ServerManager/SMApplication/Resources/filters.xml
index 173af097839bdb0977c60dd776e2b58d758d7cca..c070c36e80eb34a8997b53e2bec7b037430fe9c3 100644
--- a/ParaViewCore/ServerManager/SMApplication/Resources/filters.xml
+++ b/ParaViewCore/ServerManager/SMApplication/Resources/filters.xml
@@ -11146,16 +11146,8 @@ source.
number_of_elements_per_command="1"
panel_visibility="default"
repeat_command="1">
-
-
-
-
-
-
@@ -11317,7 +11309,7 @@ source.
name="SelectedDataSets"
number_of_elements_per_command="2"
repeat_command="1">
-
-
+
diff --git a/Plugins/LagrangianParticleTracker/Testing/LagrangianSurfaceHelperNone.xml b/Plugins/LagrangianParticleTracker/Testing/LagrangianSurfaceHelperNone.xml
index 6ca6e4375529299629e81efe8f88ea5429c18ec4..b977b68614ad799dc49b162ad4af85b80e7803ca 100644
--- a/Plugins/LagrangianParticleTracker/Testing/LagrangianSurfaceHelperNone.xml
+++ b/Plugins/LagrangianParticleTracker/Testing/LagrangianSurfaceHelperNone.xml
@@ -23,6 +23,7 @@
+
diff --git a/Plugins/LagrangianParticleTracker/pqIntegrationModelSurfaceHelperWidget.cxx b/Plugins/LagrangianParticleTracker/pqIntegrationModelSurfaceHelperWidget.cxx
index 9fb880279282a3ec4f9354d98bfebc344966c461..3d7b55fdbe1caf1aaab759fd389f37c80d7c513b 100644
--- a/Plugins/LagrangianParticleTracker/pqIntegrationModelSurfaceHelperWidget.cxx
+++ b/Plugins/LagrangianParticleTracker/pqIntegrationModelSurfaceHelperWidget.cxx
@@ -158,7 +158,7 @@ void pqIntegrationModelSurfaceHelperWidget::resetSurfaceWidget(bool force)
gb->setProperty("name", arrayName);
gb->setProperty("type", type);
QObject::connect(gb, SIGNAL(toggled(bool)), this, SIGNAL(arrayToGenerateChanged()));
- delete labelName;
+ delete[] labelName;
// And associated layout
QGridLayout* gbLayout = new QGridLayout(gb);
diff --git a/Qt/Components/CMakeLists.txt b/Qt/Components/CMakeLists.txt
index 6a42c13f888db574faab8e18fbf94abf5f9ff9dc..f95c83185c439ea5e9dfc348eeee6e08aa262940 100644
--- a/Qt/Components/CMakeLists.txt
+++ b/Qt/Components/CMakeLists.txt
@@ -62,8 +62,8 @@ set (Module_SRCS
pqColorChooserButtonWithPalettes.h
pqComboBoxDomain.cxx
pqComboBoxDomain.h
- pqCommandPropertyWidget.h
pqCommandPropertyWidget.cxx
+ pqCommandPropertyWidget.h
pqComparativeCueWidget.cxx
pqComparativeCueWidget.h
pqComparativeVisPanel.cxx
@@ -72,6 +72,10 @@ set (Module_SRCS
pqComponentsInit.h
pqComponentsTestUtility.cxx
pqComponentsTestUtility.h
+ pqCompositeDataInformationTreeModel.cxx
+ pqCompositeDataInformationTreeModel.h
+ pqCompositeTreePropertyWidget.cxx
+ pqCompositeTreePropertyWidget.h
pqCustomFilterDefinitionModel.cxx
pqCustomFilterDefinitionModel.h
pqCustomFilterDefinitionWizard.cxx
@@ -253,8 +257,6 @@ set (Module_SRCS
pqSetBreakpointDialog.h
pqSettingsDialog.cxx
pqSettingsDialog.h
- pqSignalAdaptorCompositeTreeWidget.cxx
- pqSignalAdaptorCompositeTreeWidget.h
pqSignalAdaptorKeyFrameType.cxx
pqSignalAdaptorKeyFrameType.h
pqSignalAdaptorSelectionTreeWidget.cxx
@@ -323,6 +325,8 @@ set (Module_MOC_HDRS
pqComparativeCueWidget.h
pqComparativeVisPanel.h
pqComponentsTestUtility.h
+ pqCompositeDataInformationTreeModel.h
+ pqCompositeTreePropertyWidget.h
pqCustomFilterDefinitionWizard.h
pqCustomFilterManager.h
pqCustomFilterManagerModel.h
@@ -410,7 +414,6 @@ set (Module_MOC_HDRS
pqServerLauncher.h
pqSetBreakpointDialog.h
pqSettingsDialog.h
- pqSignalAdaptorCompositeTreeWidget.h
pqSignalAdaptorKeyFrameType.h
pqSignalAdaptorSelectionTreeWidget.h
pqSignalAdaptorTreeWidget.h
diff --git a/Qt/Components/Resources/UI/pqQueryCompositeTreeDialog.ui b/Qt/Components/Resources/UI/pqQueryCompositeTreeDialog.ui
index a010b22cc491f1c1affae2d04454dfc11404d6bc..1a9088ef24de57192ebf92db2e9d7e18b791c833 100644
--- a/Qt/Components/Resources/UI/pqQueryCompositeTreeDialog.ui
+++ b/Qt/Components/Resources/UI/pqQueryCompositeTreeDialog.ui
@@ -15,15 +15,13 @@
-
-
+
false
-
-
- Structure (Flat Index)
-
-
+
+ true
+
-
@@ -40,9 +38,9 @@
- pqTreeWidget
- QTreeWidget
-
+ pqTreeView
+ QTreeView
+
diff --git a/Qt/Components/pqCompositeDataInformationTreeModel.cxx b/Qt/Components/pqCompositeDataInformationTreeModel.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a020e4fc6b317624b17e6f06699e993b25dcdc8e
--- /dev/null
+++ b/Qt/Components/pqCompositeDataInformationTreeModel.cxx
@@ -0,0 +1,661 @@
+/*=========================================================================
+
+ Program: ParaView
+ Module: pqCompositeDataInformationTreeModel.cxx
+
+ Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
+ All rights reserved.
+
+ ParaView is a free software; you can redistribute it and/or modify it
+ under the terms of the ParaView license version 1.2.
+
+ See License_v1.2.txt for the full ParaView license.
+ A copy of this license can be obtained by contacting
+ Kitware Inc.
+ 28 Corporate Drive
+ Clifton Park, NY 12065
+ USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================*/
+#include "pqCompositeDataInformationTreeModel.h"
+
+#include "vtkDataObjectTypes.h"
+#include "vtkPVCompositeDataInformation.h"
+#include "vtkPVDataInformation.h"
+
+#include
+#include
+
+#include
+
+namespace
+{
+inline bool isroot(const QModelIndex& idx)
+{
+ return (idx.isValid() && idx.internalId() == 0);
+}
+}
+
+class pqCompositeDataInformationTreeModel::pqInternals
+{
+public:
+ class CNode
+ {
+ typedef pqCompositeDataInformationTreeModel::pqInternals PType;
+ friend PType;
+
+ QString Name;
+ unsigned int Index;
+ int DataType;
+ int NumberOfPieces;
+ CNode* Parent;
+ std::vector Children;
+ bool Checked;
+ Qt::CheckState CheckState;
+
+ QModelIndex createIndex(pqCompositeDataInformationTreeModel* dmodel)
+ {
+ if (this->Parent)
+ {
+ return dmodel->createIndex(
+ this->Parent->childIndex(*this), 0, static_cast(this->flatIndex()));
+ }
+ else
+ {
+ return dmodel->createIndex(0, 0, static_cast(0));
+ }
+ }
+
+ void setChildrenCheckState(Qt::CheckState state, pqCompositeDataInformationTreeModel* dmodel)
+ {
+ for (auto iter = this->Children.begin(); iter != this->Children.end(); ++iter)
+ {
+ iter->CheckState = state;
+ iter->setChildrenCheckState(state, dmodel);
+ }
+ if (this->Children.size() > 0)
+ {
+ dmodel->dataChanged(
+ this->Children.front().createIndex(dmodel), this->Children.back().createIndex(dmodel));
+ }
+ }
+
+ void updateCheckState(pqCompositeDataInformationTreeModel* dmodel)
+ {
+ int state = 0;
+ for (auto iter = this->Children.begin(); iter != this->Children.end(); ++iter)
+ {
+ switch (iter->CheckState)
+ {
+ case Qt::Unchecked:
+ state |= 0x01;
+ break;
+
+ case Qt::PartiallyChecked:
+ state |= 0x02;
+ break;
+
+ case Qt::Checked:
+ state |= 0x04;
+ break;
+ }
+ }
+ Qt::CheckState target;
+ switch (state)
+ {
+ case 0x01:
+ case 0:
+ target = Qt::Unchecked;
+ break;
+ case 0x04:
+ target = Qt::Checked;
+ break;
+
+ case 0x02:
+ default:
+ target = Qt::PartiallyChecked;
+ }
+ if (this->CheckState != target)
+ {
+ this->CheckState = target;
+ if (this->Parent)
+ {
+ this->Parent->updateCheckState(dmodel);
+ }
+ QModelIndex idx = this->createIndex(dmodel);
+ dmodel->dataChanged(idx, idx);
+ }
+ }
+
+ CNode& find(unsigned int findex)
+ {
+ if (this->Index == findex)
+ {
+ return (*this);
+ }
+ for (auto iter = this->Children.begin(); iter != this->Children.end(); ++iter)
+ {
+ CNode& found = iter->find(findex);
+ if (found != PType::nullNode())
+ {
+ return found;
+ }
+ }
+ return PType::nullNode();
+ }
+
+ public:
+ CNode()
+ : Index(VTK_UNSIGNED_INT_MAX)
+ , DataType(0)
+ , NumberOfPieces(-1)
+ , Parent(nullptr)
+ , Checked(false)
+ , CheckState(Qt::Unchecked)
+ {
+ }
+ ~CNode() {}
+
+ bool operator==(const CNode& other) const
+ {
+ return this->Name == other.Name && this->Index == other.Index &&
+ this->DataType == other.DataType && this->NumberOfPieces == other.NumberOfPieces &&
+ this->Parent == other.Parent && this->Children == other.Children;
+ }
+ bool operator!=(const CNode& other) const { return !(*this == other); }
+
+ void reset() { (*this) = PType::nullNode(); }
+
+ int childrenCount() const
+ {
+ return this->NumberOfPieces >= 0 ? this->NumberOfPieces
+ : static_cast(this->Children.size());
+ }
+
+ unsigned int flatIndex() const { return this->Index; }
+ const QString& name() const { return this->Name; }
+ QString dataTypeAsString() const
+ {
+ return this->DataType == -1 ? "Unknown"
+ : vtkDataObjectTypes::GetClassNameFromTypeId(this->DataType);
+ }
+
+ CNode& child(int idx)
+ {
+ return idx < static_cast(this->Children.size()) ? this->Children[idx]
+ : PType::nullNode();
+ }
+ const CNode& child(int idx) const
+ {
+ return idx < static_cast(this->Children.size()) ? this->Children[idx]
+ : PType::nullNode();
+ }
+
+ int childIndex(const CNode& achild) const
+ {
+ for (size_t cc = 0, max = this->Children.size(); cc < max; ++cc)
+ {
+ if (this->Children[cc] == achild)
+ {
+ return cc;
+ }
+ }
+ }
+ const CNode& parent() const { return this->Parent ? *this->Parent : PType::nullNode(); }
+
+ Qt::CheckState checkState() const { return this->CheckState; }
+
+ bool setChecked(bool val, pqCompositeDataInformationTreeModel* dmodel)
+ {
+ if ((val == true && this->CheckState != Qt::Checked) ||
+ (val == false && this->CheckState != Qt::Unchecked))
+ {
+ this->CheckState = val ? Qt::Checked : Qt::Unchecked;
+ this->setChildrenCheckState(this->CheckState, dmodel);
+ if (this->Parent)
+ {
+ this->Parent->updateCheckState(dmodel);
+ }
+
+ QModelIndex idx = this->createIndex(dmodel);
+ dmodel->dataChanged(idx, idx);
+ return true;
+ }
+ return false;
+ }
+
+ void checkedNodes(QSet& set, bool leaves_only) const
+ {
+ if (this->checkState() == Qt::Unchecked)
+ {
+ // do nothing.
+ }
+ else if (this->checkState() == Qt::Checked && leaves_only == false)
+ {
+ set.insert(this->flatIndex());
+ }
+ else
+ {
+ // partially checked or leaves_only.
+ for (auto iter = this->Children.begin(); iter != this->Children.end(); ++iter)
+ {
+ iter->checkedNodes(set, leaves_only);
+ }
+ }
+ }
+ };
+
+ pqInternals() {}
+
+ ~pqInternals() {}
+
+ static CNode& nullNode() { return NullNode; }
+
+ CNode& find(const QModelIndex& idx)
+ {
+ if (!idx.isValid())
+ {
+ return nullNode();
+ }
+
+ vtkIdType findex = static_cast(idx.internalId());
+ return this->find(findex);
+ }
+
+ CNode& find(unsigned int findex)
+ {
+ if (findex == VTK_UNSIGNED_INT_MAX)
+ {
+ return nullNode();
+ }
+
+ if (findex == 0)
+ {
+ return this->Root;
+ }
+
+ return this->Root.find(findex);
+ }
+
+ /**
+ * Builds the data-structure using vtkPVDataInformation (may be null).
+ * @returns true if the info refers to a composite dataset otherwise returns
+ * false.
+ */
+ bool build(vtkPVDataInformation* info, bool expand_multi_piece = false)
+ {
+ unsigned int index = 0;
+ return this->build(info, expand_multi_piece, this->Root, index);
+ }
+
+ CNode& rootNode() { return this->Root; }
+
+private:
+ bool build(vtkPVDataInformation* info, bool expand_multi_piece, CNode& node, unsigned int& index)
+ {
+ node.reset();
+ node.Index = index++;
+ if (info == nullptr || info->GetCompositeDataClassName() == 0)
+ {
+ node.Name = info != nullptr ? info->GetPrettyDataTypeString() : "";
+ node.DataType = info != nullptr ? info->GetDataSetType() : -1;
+ return false;
+ }
+
+ node.Name = info->GetPrettyDataTypeString();
+ node.DataType = info->GetCompositeDataSetType();
+
+ vtkPVCompositeDataInformation* cinfo = info->GetCompositeDataInformation();
+
+ bool is_amr = (node.DataType == VTK_HIERARCHICAL_DATA_SET ||
+ node.DataType == VTK_HIERARCHICAL_BOX_DATA_SET || node.DataType == VTK_UNIFORM_GRID_AMR ||
+ node.DataType == VTK_NON_OVERLAPPING_AMR || node.DataType == VTK_OVERLAPPING_AMR);
+ bool is_multipiece = cinfo->GetDataIsMultiPiece() != 0;
+ if (!is_multipiece || expand_multi_piece)
+ {
+ node.Children.resize(cinfo->GetNumberOfChildren());
+ for (unsigned int cc = 0, max = cinfo->GetNumberOfChildren(); cc < max; ++cc)
+ {
+ CNode& childNode = node.Children[cc];
+ this->build(cinfo->GetDataInformation(cc), expand_multi_piece, childNode, index);
+ // note: build() will reset childNode, so don't set any ivars before calling it.
+ childNode.Parent = &node;
+ // if Name for block was provided, use that instead of the data type.
+ const char* name = cinfo->GetName(cc);
+ if (name && name[0])
+ {
+ childNode.Name = name;
+ }
+ else if (is_multipiece)
+ {
+ childNode.Name = QString("Dataset %1").arg(cc);
+ }
+ else if (is_amr)
+ {
+ childNode.Name = QString("Level %1").arg(cc);
+ }
+ }
+ }
+ return true;
+ }
+
+private:
+ CNode Root;
+ static CNode NullNode;
+};
+
+pqCompositeDataInformationTreeModel::pqInternals::CNode
+ pqCompositeDataInformationTreeModel::pqInternals::NullNode;
+
+//-----------------------------------------------------------------------------
+pqCompositeDataInformationTreeModel::pqCompositeDataInformationTreeModel(QObject* parentObject)
+ : Superclass(parentObject)
+ , Internals(new pqCompositeDataInformationTreeModel::pqInternals())
+ , UserCheckable(false)
+ , ExpandMultiPiece(false)
+ , Exclusivity(false)
+{
+}
+
+//-----------------------------------------------------------------------------
+pqCompositeDataInformationTreeModel::~pqCompositeDataInformationTreeModel()
+{
+}
+
+//-----------------------------------------------------------------------------
+int pqCompositeDataInformationTreeModel::columnCount(const QModelIndex&) const
+{
+ return 1;
+}
+
+//-----------------------------------------------------------------------------
+int pqCompositeDataInformationTreeModel::rowCount(const QModelIndex& parentIdx) const
+{
+ if (!parentIdx.isValid())
+ {
+ // return number of top-level items.
+ return 1;
+ }
+ pqInternals& internals = (*this->Internals);
+ const pqInternals::CNode& node = internals.find(parentIdx);
+ assert(node.childrenCount() >= 0);
+ return node.childrenCount();
+}
+
+//-----------------------------------------------------------------------------
+QModelIndex pqCompositeDataInformationTreeModel::index(
+ int row, int column, const QModelIndex& parentIdx) const
+{
+ if (!parentIdx.isValid() && row == 0 && column == 0)
+ {
+ return this->createIndex(0, 0, static_cast(0));
+ }
+
+ if (row < 0 || column < 0 || column >= this->columnCount())
+ {
+ return QModelIndex();
+ }
+
+ pqInternals& internals = (*this->Internals);
+ const pqInternals::CNode& node = internals.find(parentIdx);
+ const pqInternals::CNode& child = node.child(row);
+ return this->createIndex(row, column, static_cast(child.flatIndex()));
+}
+
+//-----------------------------------------------------------------------------
+QModelIndex pqCompositeDataInformationTreeModel::parent(const QModelIndex& idx) const
+{
+ if (!idx.isValid() || isroot(idx))
+ {
+ return QModelIndex();
+ }
+
+ pqInternals& internals = (*this->Internals);
+ const pqInternals::CNode& node = internals.find(idx);
+ const pqInternals::CNode& parentNode = node.parent();
+ if (parentNode == internals.nullNode())
+ {
+ return QModelIndex();
+ }
+
+ if (parentNode == internals.rootNode())
+ {
+ return this->createIndex(0, 0, static_cast(0));
+ }
+
+ const pqInternals::CNode& parentsParentNode = parentNode.parent();
+ return this->createIndex(parentsParentNode.childIndex(parentNode), idx.column(),
+ static_cast(parentNode.flatIndex()));
+}
+
+//-----------------------------------------------------------------------------
+QVariant pqCompositeDataInformationTreeModel::data(const QModelIndex& idx, int role) const
+{
+ if (!idx.isValid())
+ {
+ return QVariant();
+ }
+
+ pqInternals& internals = (*this->Internals);
+ const pqInternals::CNode& node = internals.find(idx);
+ if (node == internals.nullNode())
+ {
+ return QVariant();
+ }
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ return node.name();
+
+ case Qt::ToolTipRole:
+ return QString("Name: %1
Type: %2")
+ .arg(node.name())
+ .arg(node.dataTypeAsString());
+
+ case Qt::CheckStateRole:
+ return this->UserCheckable ? QVariant(node.checkState()) : QVariant();
+ }
+
+ return QVariant();
+}
+
+//-----------------------------------------------------------------------------
+Qt::ItemFlags pqCompositeDataInformationTreeModel::flags(const QModelIndex& idx) const
+{
+ Qt::ItemFlags pflags = this->Superclass::flags(idx);
+ if (this->UserCheckable)
+ {
+ pflags |= Qt::ItemIsUserCheckable | Qt::ItemIsTristate;
+ }
+
+ // can't use Qt::ItemIsAutoTristate till we drop support for Qt 4 :(.
+ return pflags;
+}
+
+//-----------------------------------------------------------------------------
+bool pqCompositeDataInformationTreeModel::setData(
+ const QModelIndex& idx, const QVariant& value, int role)
+{
+ if (!idx.isValid())
+ {
+ return false;
+ }
+
+ if (role != Qt::CheckStateRole)
+ {
+ return false;
+ }
+
+ pqInternals& internals = (*this->Internals);
+ pqInternals::CNode& node = internals.find(idx);
+ if (node == internals.nullNode())
+ {
+ return false;
+ }
+
+ Qt::CheckState checkState = value.value();
+ if (checkState == Qt::Checked && this->exclusivity())
+ {
+ internals.rootNode().setChecked(false, this);
+ }
+ node.setChecked(checkState == Qt::Checked, this);
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+QVariant pqCompositeDataInformationTreeModel::headerData(
+ int section, Qt::Orientation orientation, int role) const
+{
+ if (orientation == Qt::Horizontal && section == 0 && role == Qt::DisplayRole)
+ {
+ return this->HeaderLabel;
+ }
+ return this->Superclass::headerData(section, orientation, role);
+}
+
+//-----------------------------------------------------------------------------
+bool pqCompositeDataInformationTreeModel::setHeaderData(
+ int section, Qt::Orientation orientation, const QVariant& value, int role)
+{
+ if (orientation == Qt::Horizontal && section == 0 && role == Qt::DisplayRole)
+ {
+ this->HeaderLabel = value.toString();
+ emit this->headerDataChanged(orientation, section, section);
+ return true;
+ }
+ return this->Superclass::setHeaderData(section, orientation, value, role);
+}
+
+//-----------------------------------------------------------------------------
+bool pqCompositeDataInformationTreeModel::reset(vtkPVDataInformation* info)
+{
+ pqInternals& internals = (*this->Internals);
+
+ this->beginResetModel();
+ bool retVal = internals.build(info, this->ExpandMultiPiece);
+ this->endResetModel();
+ return retVal;
+}
+
+//-----------------------------------------------------------------------------
+void pqCompositeDataInformationTreeModel::setChecked(const QList& indices)
+{
+ pqInternals& internals = (*this->Internals);
+ pqInternals::CNode& root = internals.rootNode();
+ root.setChecked(false, this);
+
+ foreach (unsigned int findex, indices)
+ {
+ pqInternals::CNode& node = internals.find(findex);
+ node.setChecked(true, this);
+ }
+}
+
+//-----------------------------------------------------------------------------
+QList pqCompositeDataInformationTreeModel::checkedNodes() const
+{
+ QSet indices;
+ pqInternals& internals = (*this->Internals);
+ internals.rootNode().checkedNodes(indices, false);
+ return indices.toList();
+}
+
+//-----------------------------------------------------------------------------
+QList pqCompositeDataInformationTreeModel::checkedLeaves() const
+{
+ QSet indices;
+ pqInternals& internals = (*this->Internals);
+ internals.rootNode().checkedNodes(indices, true);
+ return indices.toList();
+}
+
+//-----------------------------------------------------------------------------
+QList pqCompositeDataInformationTreeModel::checkedLevels() const
+{
+ QList indices;
+ pqInternals& internals = (*this->Internals);
+ pqInternals::CNode& root = internals.rootNode();
+ for (int cc = 0; cc < root.childrenCount(); cc++)
+ {
+ if (root.child(cc).checkState() == Qt::Checked)
+ {
+ indices.push_back(static_cast(cc));
+ }
+ }
+ return indices;
+}
+
+//-----------------------------------------------------------------------------
+void pqCompositeDataInformationTreeModel::setCheckedLevels(const QList& indices)
+{
+ pqInternals& internals = (*this->Internals);
+ pqInternals::CNode& root = internals.rootNode();
+ root.setChecked(false, this);
+
+ int childrenCount = root.childrenCount();
+ foreach (unsigned int idx, indices)
+ {
+ if (idx < childrenCount)
+ {
+ root.child(idx).setChecked(true, this);
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------
+QList >
+pqCompositeDataInformationTreeModel::checkedLevelDatasets() const
+{
+ QList > indices;
+ pqInternals& internals = (*this->Internals);
+ pqInternals::CNode& root = internals.rootNode();
+ for (int level = 0; level < root.childrenCount(); ++level)
+ {
+ pqInternals::CNode& levelNode = root.child(level);
+ for (int ds = 0; ds < levelNode.childrenCount(); ++ds)
+ {
+ if (levelNode.child(ds).checkState() == Qt::Checked)
+ {
+ indices.push_back(QPair(level, ds));
+ }
+ }
+ }
+ return indices;
+}
+
+//-----------------------------------------------------------------------------
+void pqCompositeDataInformationTreeModel::setCheckedLevelDatasets(
+ const QList >& indices)
+{
+ pqInternals& internals = (*this->Internals);
+ pqInternals::CNode& root = internals.rootNode();
+ root.setChecked(false, this);
+
+ int numLevels = root.childrenCount();
+
+ typedef QPair IdxPair;
+ foreach (const IdxPair& idx, indices)
+ {
+ if (idx.first < numLevels)
+ {
+ pqInternals::CNode& level = root.child(idx.first);
+ if (idx.second < level.childrenCount())
+ {
+ level.child(idx.second).setChecked(true, this);
+ }
+ }
+ }
+}
diff --git a/Qt/Components/pqCompositeDataInformationTreeModel.h b/Qt/Components/pqCompositeDataInformationTreeModel.h
new file mode 100644
index 0000000000000000000000000000000000000000..2b76a79558d41ff2387f41d1a7b6b1f8d7b07ac4
--- /dev/null
+++ b/Qt/Components/pqCompositeDataInformationTreeModel.h
@@ -0,0 +1,178 @@
+/*=========================================================================
+
+ Program: ParaView
+ Module: pqCompositeDataInformationTreeModel.h
+
+ Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
+ All rights reserved.
+
+ ParaView is a free software; you can redistribute it and/or modify it
+ under the terms of the ParaView license version 1.2.
+
+ See License_v1.2.txt for the full ParaView license.
+ A copy of this license can be obtained by contacting
+ Kitware Inc.
+ 28 Corporate Drive
+ Clifton Park, NY 12065
+ USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================*/
+#ifndef pqCompositeDataInformationTreeModel_h
+#define pqCompositeDataInformationTreeModel_h
+
+#include "pqComponentsModule.h" // for exports.
+#include
+#include // for QPair.
+#include // for ivar.
+
+class vtkPVDataInformation;
+
+/**
+ * @class pqCompositeDataInformationTreeModel
+ * @brief Tree model that use vtkPVDataInformation to model composite data tree.
+ *
+ * pqCompositeDataInformationTreeModel is designed to map a data set hierarchy
+ * represented by vtkCompositeDataSet (and subclasses) to a Qt tree model.
+ *
+ * To use this model, one calls `pqCompositeDataInformationTreeModel::reset()` with
+ * the data information object to use to build the structure from.
+ *
+ * There are few properties on this model that should be set prior to calling
+ * reset that determine how the model behaves. To allow the user to check/uncheck nodes
+ * on the tree, set **userCheckable** to true (default: false). To expand datasets in a
+ * multipiece, set **expandMultiPiece** to true (default: false). Finally, if
+ * **userCheckable** is true, and you want to only allow the user to select one sub-tree
+ * at a time, set **exclusivity** to true (default: false).
+ */
+class PQCOMPONENTS_EXPORT pqCompositeDataInformationTreeModel : public QAbstractItemModel
+{
+ Q_OBJECT
+ Q_PROPERTY(bool userCheckable READ userCheckable WRITE setUserCheckable);
+ Q_PROPERTY(bool expandMultiPiece READ expandMultiPiece WRITE setExpandMultiPiece);
+ Q_PROPERTY(bool exclusivity READ exclusivity WRITE setExclusivity);
+
+ typedef QAbstractItemModel Superclass;
+
+public:
+ pqCompositeDataInformationTreeModel(QObject* parent = 0);
+ virtual ~pqCompositeDataInformationTreeModel();
+
+ //@{
+ /**
+ * QAbstractItemModel interface implementation.
+ */
+ int columnCount(const QModelIndex& parent = QModelIndex()) const override;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+ QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const override;
+ QModelIndex parent(const QModelIndex& index = QModelIndex()) const override;
+ QVariant data(const QModelIndex& index, int role) const override;
+ Qt::ItemFlags flags(const QModelIndex& index) const override;
+ bool setData(const QModelIndex& index, const QVariant& value, int role) override;
+ QVariant headerData(
+ int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant& value,
+ int role = Qt::DisplayRole) override;
+ //@}
+
+ //@{
+ /**
+ * Toggle whether the model allows user to change check state.
+ * Note: please call reset() after changing this.
+ */
+ void setUserCheckable(bool val) { this->UserCheckable = val; }
+ bool userCheckable() const { return this->UserCheckable; }
+ //@}
+
+ //@{
+ /**
+ * Toggle whether multipiece datasets are expanded (default false).
+ * Note: please call reset() after changing this.
+ */
+ void setExpandMultiPiece(bool val) { this->ExpandMultiPiece = val; }
+ bool expandMultiPiece() const { return this->ExpandMultiPiece; }
+ //@}
+
+ //@{
+ /**
+ * When set to true for a userCheckable model, if the user checks a node,
+ * the all other nodes that are not children of the checked node are unchecked.
+ */
+ void setExclusivity(bool val) { this->Exclusivity = val; }
+ bool exclusivity() const { return this->Exclusivity; }
+ //@}
+
+ /**
+ * API to get flat-indices for checked nodes. `checkedNodes` may return a
+ * combination of leaf and non-leaf nodes i.e. if all child nodes of a node
+ * are checked, then it will prefer the parent node's index rather than indices of
+ * each of the children.
+ */
+ QList checkedNodes() const;
+
+ /**
+ * API to get flat-indices for checked nodes. `checkedLeaves` returns indices for
+ * the leaf nodes. The flat-index for a non-leaf node is never returned by this method.
+ */
+ QList checkedLeaves() const;
+
+ /**
+ * API to set the flat-indices for checked nodes. This methods accepts indices for
+ * both non-leaf and leaf nodes. Note that if a non-leaf node is checked,
+ * then all its children are also considered as checked.
+ */
+ void setChecked(const QList& indices);
+
+ //@{
+ /**
+ * This is useful when dealing with AMR datasets. It sets/returns the level numbers for selected
+ * levels
+ * in the AMR dataset.
+ */
+ QList checkedLevels() const;
+ void setCheckedLevels(const QList& indices);
+ //@}
+
+ //@{
+ /**
+ * This is useful when dealing with AMR datasets. It sets/returns the level and dataset indices
+ * for AMR datasets.
+ */
+ QList > checkedLevelDatasets() const;
+ void setCheckedLevelDatasets(const QList >& indices);
+ //@}
+
+public slots:
+ /**
+ * Reset and rebuild the model using the data information object provided.
+ * The model does not maintain a reference to the vtkPVDataInformation
+ * instance. Hence it will not automatically update when \c info changes.
+ *
+ * @returns true is the data information refers to a composite dataset.
+ * Otherwise, returns false.
+ */
+ bool reset(vtkPVDataInformation* info = nullptr);
+
+private:
+ Q_DISABLE_COPY(pqCompositeDataInformationTreeModel);
+
+ class pqInternals;
+ QScopedPointer Internals;
+ QString HeaderLabel;
+ bool UserCheckable;
+ bool ExpandMultiPiece;
+ bool Exclusivity;
+};
+
+#endif
diff --git a/Qt/Components/pqCompositeTreePropertyWidget.cxx b/Qt/Components/pqCompositeTreePropertyWidget.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b006adc6e906f8fd75349d688b5cf2a93a2c97ad
--- /dev/null
+++ b/Qt/Components/pqCompositeTreePropertyWidget.cxx
@@ -0,0 +1,236 @@
+/*=========================================================================
+
+ Program: ParaView
+ Module: pqCompositeTreePropertyWidget.cxx
+
+ Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
+ All rights reserved.
+
+ ParaView is a free software; you can redistribute it and/or modify it
+ under the terms of the ParaView license version 1.2.
+
+ See License_v1.2.txt for the full ParaView license.
+ A copy of this license can be obtained by contacting
+ Kitware Inc.
+ 28 Corporate Drive
+ Clifton Park, NY 12065
+ USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================*/
+#include "pqCompositeTreePropertyWidget.h"
+
+#include "pqCompositeDataInformationTreeModel.h"
+#include "pqTreeView.h"
+#include "pqTreeViewSelectionHelper.h"
+#include "vtkEventQtSlotConnect.h"
+#include "vtkPVXMLElement.h"
+#include "vtkSMCompositeTreeDomain.h"
+#include "vtkSMIntVectorProperty.h"
+
+#include
+#include
+
+namespace
+{
+template
+void push_back(L& list, const T& item)
+{
+ list.push_back(item);
+}
+
+template
+void push_back(L& list, const QPair& item)
+{
+ list.push_back(item.first);
+ list.push_back(item.second);
+}
+
+template
+QList convertToVariantList(const QList& val)
+{
+ QList ret;
+ foreach (const T& avalue, val)
+ {
+ push_back(ret, avalue);
+ }
+ return ret;
+}
+
+QList convertToUIntList(const QList& val)
+{
+ QList ret;
+ foreach (const QVariant& avalue, val)
+ {
+ ret.push_back(avalue.value());
+ }
+ return ret;
+}
+
+QList > convertToUIntPairList(const QList& val)
+{
+ QList > ret;
+ for (int cc = 0, max = val.size(); cc + 1 < max; cc += 2)
+ {
+ ret.push_back(QPair(
+ val[cc].value(), val[cc + 1].value()));
+ }
+ return ret;
+}
+}
+
+//-----------------------------------------------------------------------------
+pqCompositeTreePropertyWidget::pqCompositeTreePropertyWidget(
+ vtkSMIntVectorProperty* smproperty, vtkSMProxy* smproxy, QWidget* parentObject)
+ : Superclass(smproxy, parentObject)
+ , Property(smproperty)
+{
+ this->setShowLabel(false);
+ this->setChangeAvailableAsChangeFinished(true);
+
+ vtkSMCompositeTreeDomain* ctd =
+ vtkSMCompositeTreeDomain::SafeDownCast(smproperty->FindDomain("vtkSMCompositeTreeDomain"));
+ Q_ASSERT(ctd);
+ this->Domain = ctd;
+
+ this->VTKConnect->Connect(ctd, vtkCommand::DomainModifiedEvent, &this->Timer, SLOT(start()));
+ this->connect(&this->Timer, SIGNAL(timeout()), SLOT(domainModified()));
+ this->Timer.setSingleShot(true);
+ this->Timer.setInterval(0);
+
+ pqTreeView* treeView = new pqTreeView(this);
+ this->TreeView = treeView;
+ treeView->setObjectName("TreeWidget");
+
+ QHBoxLayout* hbox = new QHBoxLayout(this);
+ hbox->setMargin(0);
+
+ pqCompositeDataInformationTreeModel* dmodel = new pqCompositeDataInformationTreeModel(this);
+ dmodel->setUserCheckable(true);
+ dmodel->setHeaderData(0, Qt::Horizontal, smproperty->GetXMLLabel());
+
+ // If property takes multiple values, then user can select multiple items at a
+ // time. If not, then tell the model that it should uncheck other subtrees
+ // when a user clicks on an item.
+ dmodel->setExclusivity(smproperty->GetRepeatCommand() == 0);
+
+ if (ctd->GetMode() == vtkSMCompositeTreeDomain::AMR &&
+ ((smproperty->GetRepeatCommand() == 1 && smproperty->GetNumberOfElementsPerCommand() == 2) ||
+ (smproperty->GetRepeatCommand() == 0 && smproperty->GetNumberOfElements() == 2)))
+ {
+ dmodel->setExpandMultiPiece(true);
+ }
+ this->Model = dmodel;
+ this->domainModified();
+
+ treeView->setUniformRowHeights(true);
+ treeView->header()->setStretchLastSection(true);
+ treeView->setRootIsDecorated(true);
+ treeView->setModel(dmodel);
+ treeView->expandToDepth(2);
+
+ if (vtkPVXMLElement* hints = smproperty->GetHints())
+ {
+ if (vtkPVXMLElement* elem = hints->FindNestedElementByName("WidgetHeight"))
+ {
+ int row_count = 0;
+ if (elem->GetScalarAttribute("number_of_rows", &row_count))
+ {
+ treeView->setMaximumRowCountBeforeScrolling(row_count);
+ }
+ }
+ }
+
+ pqTreeViewSelectionHelper* helper = new pqTreeViewSelectionHelper(treeView);
+ helper->setObjectName("CompositeTreeSelectionHelper");
+ hbox->addWidget(treeView);
+
+ this->addPropertyLink(this, "values", SIGNAL(valuesChanged()), smproperty);
+ this->connect(
+ dmodel, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), SIGNAL(valuesChanged()));
+
+ PV_DEBUG_PANELS() << "pqCompositeTreePropertyWidget for an IntVectorPropertyWidget with a "
+ << "CompositeTreeDomain";
+}
+
+//-----------------------------------------------------------------------------
+pqCompositeTreePropertyWidget::~pqCompositeTreePropertyWidget()
+{
+}
+
+//-----------------------------------------------------------------------------
+void pqCompositeTreePropertyWidget::domainModified()
+{
+ if (this->Model && this->Domain)
+ {
+ // this ensures that the widget is hidden if the data is not a composite
+ // dataset.
+ this->TreeView->setVisible(this->Model->reset(this->Domain->GetInformation()));
+ }
+}
+
+//-----------------------------------------------------------------------------
+QList pqCompositeTreePropertyWidget::values() const
+{
+ Q_ASSERT(this->Model && this->Property && this->Domain);
+ switch (this->Domain->GetMode())
+ {
+ case vtkSMCompositeTreeDomain::ALL:
+ case vtkSMCompositeTreeDomain::NON_LEAVES:
+ return convertToVariantList(this->Model->checkedNodes());
+
+ case vtkSMCompositeTreeDomain::LEAVES:
+ return convertToVariantList(this->Model->checkedLeaves());
+
+ case vtkSMCompositeTreeDomain::AMR:
+ if ((this->Property->GetRepeatCommand() == 1 &&
+ this->Property->GetNumberOfElementsPerCommand() == 2) ||
+ (this->Property->GetRepeatCommand() == 0 && this->Property->GetNumberOfElements() == 2))
+ {
+ return convertToVariantList(this->Model->checkedLevelDatasets());
+ }
+ else
+ {
+ return convertToVariantList(this->Model->checkedLevels());
+ }
+ }
+ return QList();
+}
+
+//-----------------------------------------------------------------------------
+void pqCompositeTreePropertyWidget::setValues(const QList& values)
+{
+ Q_ASSERT(this->Model && this->Property && this->Domain);
+ switch (this->Domain->GetMode())
+ {
+ case vtkSMCompositeTreeDomain::ALL:
+ case vtkSMCompositeTreeDomain::NON_LEAVES:
+ case vtkSMCompositeTreeDomain::LEAVES:
+ this->Model->setChecked(convertToUIntList(values));
+ break;
+
+ case vtkSMCompositeTreeDomain::AMR:
+ if ((this->Property->GetRepeatCommand() &&
+ this->Property->GetNumberOfElementsPerCommand() == 2) ||
+ this->Property->GetNumberOfElements() == 2)
+ {
+ this->Model->setCheckedLevelDatasets(convertToUIntPairList(values));
+ }
+ else
+ {
+ this->Model->setCheckedLevels(convertToUIntList(values));
+ }
+ break;
+ }
+}
diff --git a/Qt/Components/pqCompositeTreePropertyWidget.h b/Qt/Components/pqCompositeTreePropertyWidget.h
new file mode 100644
index 0000000000000000000000000000000000000000..74401e41a3ea352a448791ece85cdcf5b31dd55d
--- /dev/null
+++ b/Qt/Components/pqCompositeTreePropertyWidget.h
@@ -0,0 +1,96 @@
+/*=========================================================================
+
+ Program: ParaView
+ Module: pqCompositeTreePropertyWidget.h
+
+ Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
+ All rights reserved.
+
+ ParaView is a free software; you can redistribute it and/or modify it
+ under the terms of the ParaView license version 1.2.
+
+ See License_v1.2.txt for the full ParaView license.
+ A copy of this license can be obtained by contacting
+ Kitware Inc.
+ 28 Corporate Drive
+ Clifton Park, NY 12065
+ USA
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+========================================================================*/
+#ifndef pqCompositeTreePropertyWidget_h
+#define pqCompositeTreePropertyWidget_h
+
+#include "pqPropertyWidget.h"
+#include "pqTimer.h" // needed for pqTimer.
+#include "vtkNew.h" // needed for vtkNew.
+#include "vtkWeakPointer.h" // needed for vtkWeakPointer.
+
+class vtkSMIntVectorProperty;
+class vtkEventQtSlotConnect;
+class vtkSMCompositeTreeDomain;
+class pqCompositeDataInformationTreeModel;
+class pqTreeView;
+
+/**
+ * @class pqCompositeDataInformationTreeModel
+ * @brief property widget for a vtkSMIntVectorProperty with vtkSMCompositeTreeDomain.
+ *
+ * pqCompositeDataInformationTreeModel is a subclass of pqPropertyWidget that is
+ * created by default for any vtkSMIntVectorProperty having a
+ * vtkSMCompositeTreeDomain. This widgets creates a tree view which shows the
+ * composite-dataset hierarchy. It supports both multiblock and AMR datasets
+ * with ability to select blocks either using flat or composite index or
+ * AMR-specific, level number or level number and block number.
+ *
+ * Internally, it uses pqCompositeDataInformationTreeModel and keeps it updated
+ * as the vtkSMCompositeTreeDomain changes.
+ */
+class PQCOMPONENTS_EXPORT pqCompositeTreePropertyWidget : public pqPropertyWidget
+{
+ Q_OBJECT
+ typedef pqPropertyWidget Superclass;
+ Q_PROPERTY(QList values READ values WRITE setValues NOTIFY valuesChanged);
+
+public:
+ pqCompositeTreePropertyWidget(
+ vtkSMIntVectorProperty* smproperty, vtkSMProxy* smproxy, QWidget* parent = nullptr);
+ virtual ~pqCompositeTreePropertyWidget();
+
+ /**
+ * API to get/set the selected values. What there values represents depends on
+ * the domain and the property e.g. it can represent flat indices or amr-level
+ * number or (amr-level, amr-block) pairs.
+ */
+ QList values() const;
+ void setValues(const QList& values);
+
+signals:
+ void valuesChanged();
+
+private slots:
+ void domainModified();
+
+private:
+ Q_DISABLE_COPY(pqCompositeTreePropertyWidget);
+
+ pqTimer Timer;
+ vtkNew VTKConnect;
+ vtkWeakPointer Domain;
+ vtkWeakPointer Property;
+ QPointer Model;
+ QPointer TreeView;
+};
+
+#endif
diff --git a/Qt/Components/pqIntVectorPropertyWidget.cxx b/Qt/Components/pqIntVectorPropertyWidget.cxx
index 039fbb465cfe7e21d9bc70dbf1090a547331711b..cc81c85e223722e70ab99b591345b0fd3a585e48 100644
--- a/Qt/Components/pqIntVectorPropertyWidget.cxx
+++ b/Qt/Components/pqIntVectorPropertyWidget.cxx
@@ -45,14 +45,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "vtkSmartPointer.h"
#include "pqComboBoxDomain.h"
+#include "pqCompositeTreePropertyWidget.h"
#include "pqIntRangeWidget.h"
#include "pqLabel.h"
#include "pqLineEdit.h"
#include "pqProxyWidget.h"
#include "pqScalarValueListPropertyWidget.h"
-#include "pqSignalAdaptorCompositeTreeWidget.h"
#include "pqSignalAdaptorSelectionTreeWidget.h"
#include "pqSignalAdaptors.h"
+#include "pqTreeView.h"
#include "pqTreeWidget.h"
#include "pqTreeWidgetSelectionHelper.h"
@@ -61,6 +62,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include
+//-----------------------------------------------------------------------------
pqIntVectorPropertyWidget::pqIntVectorPropertyWidget(
vtkSMProperty* smproperty, vtkSMProxy* smProxy, QWidget* parentObject)
: pqPropertyWidget(smProxy, parentObject)
@@ -178,29 +180,10 @@ pqIntVectorPropertyWidget::pqIntVectorPropertyWidget(
<< "(with non-repeatable command)";
}
}
- else if (vtkSMCompositeTreeDomain::SafeDownCast(domain))
+ else if (vtkSMCompositeTreeDomain* ctd = vtkSMCompositeTreeDomain::SafeDownCast(domain))
{
- pqTreeWidget* treeWidget = new pqTreeWidget(this);
- treeWidget->setObjectName("TreeWidget");
- treeWidget->setHeaderLabel(smproperty->GetXMLLabel());
- treeWidget->setMaximumRowCountBeforeScrolling(smproperty);
-
- pqSignalAdaptorCompositeTreeWidget* adaptor =
- new pqSignalAdaptorCompositeTreeWidget(treeWidget, ivp,
- /*autoUpdateVisibility=*/true);
- adaptor->setObjectName("CompositeTreeAdaptor");
-
- pqTreeWidgetSelectionHelper* helper = new pqTreeWidgetSelectionHelper(treeWidget);
- helper->setObjectName("CompositeTreeSelectionHelper");
-
- this->addPropertyLink(adaptor, "values", SIGNAL(valuesChanged()), ivp);
- this->setChangeAvailableAsChangeFinished(true);
-
- layoutLocal->addWidget(treeWidget);
- this->setShowLabel(false);
-
- PV_DEBUG_PANELS() << "pqTreeWidget for an IntVectorPropertyWidget with a "
- << "CompositeTreeDomain";
+ // Should have been handled by pqCompositeTreePropertyWidget.
+ abort();
}
else if (vtkSMIntRangeDomain* range = vtkSMIntRangeDomain::SafeDownCast(domain))
{
@@ -301,3 +284,20 @@ pqIntVectorPropertyWidget::pqIntVectorPropertyWidget(
this->setLayout(layoutLocal);
}
+
+//-----------------------------------------------------------------------------
+pqIntVectorPropertyWidget::~pqIntVectorPropertyWidget()
+{
+}
+
+//-----------------------------------------------------------------------------
+pqPropertyWidget* pqIntVectorPropertyWidget::createWidget(
+ vtkSMIntVectorProperty* smproperty, vtkSMProxy* smproxy, QWidget* parent)
+{
+ if (smproperty != nullptr && smproperty->FindDomain("vtkSMCompositeTreeDomain") != nullptr)
+ {
+ return new pqCompositeTreePropertyWidget(smproperty, smproxy, parent);
+ }
+
+ return new pqIntVectorPropertyWidget(smproperty, smproxy, parent);
+}
diff --git a/Qt/Components/pqIntVectorPropertyWidget.h b/Qt/Components/pqIntVectorPropertyWidget.h
index 2f4b0ef478aa3a8bf373e40ee74f2a9318741ebc..ababd18b28d0f66632a348eb4d8e42a60fc3ebba 100644
--- a/Qt/Components/pqIntVectorPropertyWidget.h
+++ b/Qt/Components/pqIntVectorPropertyWidget.h
@@ -35,7 +35,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "pqPropertyWidget.h"
-#include "pqPropertyLinks.h"
+class vtkSMIntVectorProperty;
class PQCOMPONENTS_EXPORT pqIntVectorPropertyWidget : public pqPropertyWidget
{
@@ -43,6 +43,16 @@ class PQCOMPONENTS_EXPORT pqIntVectorPropertyWidget : public pqPropertyWidget
public:
pqIntVectorPropertyWidget(vtkSMProperty* property, vtkSMProxy* proxy, QWidget* parent = 0);
+ virtual ~pqIntVectorPropertyWidget();
+
+ /**
+ * Creates known pqPropertyWidget subclasses for vtkSMIntVectorProperty property.
+ */
+ static pqPropertyWidget* createWidget(
+ vtkSMIntVectorProperty* smproperty, vtkSMProxy* smproxy, QWidget* parent);
+
+private:
+ Q_DISABLE_COPY(pqIntVectorPropertyWidget);
};
#endif // _pqIntVectorPropertyWidget_h
diff --git a/Qt/Components/pqProxyWidget.cxx b/Qt/Components/pqProxyWidget.cxx
index b7745fe4ded59fa06c41aeaafce07f83de435bde..30d33e9fa0ceca7978b4466d89debceee936ab74 100644
--- a/Qt/Components/pqProxyWidget.cxx
+++ b/Qt/Components/pqProxyWidget.cxx
@@ -1047,7 +1047,7 @@ pqPropertyWidget* pqProxyWidget::createWidgetForProperty(
}
else if (vtkSMIntVectorProperty* ivp = vtkSMIntVectorProperty::SafeDownCast(smproperty))
{
- widget = new pqIntVectorPropertyWidget(ivp, smproxy, parentObj);
+ widget = pqIntVectorPropertyWidget::createWidget(ivp, smproxy, parentObj);
}
else if (vtkSMStringVectorProperty* svp = vtkSMStringVectorProperty::SafeDownCast(smproperty))
{
diff --git a/Qt/Components/pqQueryClauseWidget.cxx b/Qt/Components/pqQueryClauseWidget.cxx
index 5dafeccf1238f347b769b58e77f9667b700f285a..d681103b01b899ba5a658d1b9bdfd652a542beba 100644
--- a/Qt/Components/pqQueryClauseWidget.cxx
+++ b/Qt/Components/pqQueryClauseWidget.cxx
@@ -33,11 +33,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ui_pqQueryClauseWidget.h"
#include "ui_pqQueryCompositeTreeDialog.h"
+#include "pqCompositeDataInformationTreeModel.h"
#include "pqHelpWindow.h"
#include "pqOutputPort.h"
#include "pqPipelineSource.h"
#include "pqServer.h"
-#include "pqSignalAdaptorCompositeTreeWidget.h"
#include "vtkDataObject.h"
#include "vtkPVArrayInformation.h"
#include "vtkPVDataInformation.h"
@@ -79,6 +79,25 @@ public:
}
}
};
+
+bool isAMR(vtkPVDataInformation* dinfo)
+{
+ switch (dinfo->GetCompositeDataSetType())
+ {
+ case VTK_HIERARCHICAL_BOX_DATA_SET:
+ case VTK_HIERARCHICAL_DATA_SET:
+ case VTK_UNIFORM_GRID_AMR:
+ case VTK_NON_OVERLAPPING_AMR:
+ case VTK_OVERLAPPING_AMR:
+ return true;
+ }
+ return false;
+}
+
+bool isMultiBlock(vtkPVDataInformation* dinfo)
+{
+ return dinfo->GetCompositeDataSetType() == VTK_MULTIBLOCK_DATA_SET;
+}
}
// BUG #13806, remove collective operations temporarily since they don't work
@@ -258,14 +277,14 @@ void pqQueryClauseWidget::populateSelectionCriteria(pqQueryClauseWidget::Criteri
this->Internals->criteria->addItem("Query", QUERY);
}
- if (dataInfo->GetCompositeDataSetType() == VTK_MULTIBLOCK_DATA_SET)
+ if (isMultiBlock(dataInfo))
{
if (type_flags & BLOCK)
{
this->Internals->criteria->addItem("Block ID", BLOCK);
}
}
- else if (dataInfo->GetCompositeDataSetType() == VTK_HIERARCHICAL_BOX_DATA_SET)
+ else if (isAMR(dataInfo))
{
if (type_flags & AMR_LEVEL)
{
@@ -415,14 +434,8 @@ void pqQueryClauseWidget::updateDependentClauseWidgets()
#endif
vtkPVDataInformation* dataInfo = this->producer()->getDataInformation();
- if (dataInfo->GetCompositeDataSetType() == VTK_MULTIBLOCK_DATA_SET)
- {
- multi_block = true;
- }
- else if (dataInfo->GetCompositeDataSetType() == VTK_HIERARCHICAL_BOX_DATA_SET)
- {
- amr = true;
- }
+ multi_block = isMultiBlock(dataInfo);
+ amr = isAMR(dataInfo);
QVBoxLayout* vbox = qobject_cast(this->layout());
@@ -513,53 +526,74 @@ void pqQueryClauseWidget::showCompositeTree()
ui.Blocks->setSelectionMode(QAbstractItemView::ExtendedSelection);
}
- pqSignalAdaptorCompositeTreeWidget adaptor(
- ui.Blocks, this->producer()->getOutputPortProxy(), vtkSMCompositeTreeDomain::NONE);
+ pqCompositeDataInformationTreeModel dmodel;
+ if (criteria_type == AMR_BLOCK)
+ {
+ // if selecting AMR_BLOCK, we need to expand multipiece nodes.
+ dmodel.setExpandMultiPiece(true);
+ }
+
+ ui.Blocks->setModel(&dmodel);
+ dmodel.reset(this->producer()->getDataInformation());
+ ui.Blocks->expandAll();
if (dialog.exec() != QDialog::Accepted)
{
return;
}
- QStringList values;
- QList selItems = ui.Blocks->selectedItems();
- foreach (QTreeWidgetItem* item, selItems)
+ // to convert selected indexes to flat or amr ids, we use a trick. We make the
+ // model check the selected indexes and then use existing API on the model to
+ // access the indexes for the checked nodes.
+ QModelIndexList selIndexes = ui.Blocks->selectionModel()->selectedIndexes();
+ foreach (const QModelIndex& idx, selIndexes)
{
- int current_flat_index = adaptor.flatIndex(item);
- switch (criteria_type)
+ if (idx.isValid())
{
- case BLOCK:
- if (this->Internals->criteria->currentText() == "Block ID")
- {
- values << QString("%1").arg(current_flat_index);
- }
- else
- {
- // name.
- QString blockName = adaptor.blockName(item);
- if (blockName.isEmpty())
- {
- qWarning("Data block doesn't have a name assigned to it. Query may"
- " not work. Use 'Block ID' based criteria instead.");
- }
- else
- {
- values << blockName;
- }
- }
- break;
-
- case AMR_LEVEL:
- values << QString("%1").arg(adaptor.hierarchicalLevel(item));
- break;
-
- case AMR_BLOCK:
- values << QString("%1").arg(adaptor.hierarchicalBlockIndex(item));
- break;
+ dmodel.setData(idx, Qt::Checked, Qt::CheckStateRole);
+ }
+ }
- default:
- qCritical("Invalid criteria_type.");
+ QStringList values;
+ switch (criteria_type)
+ {
+ case BLOCK:
+ {
+ const QList findexes = dmodel.checkedNodes();
+ foreach (unsigned int idx, findexes)
+ {
+ values << QString::number(idx);
+ }
+ }
+ break;
+ case AMR_LEVEL:
+ {
+ const QList levels = dmodel.checkedLevels();
+ foreach (unsigned int idx, levels)
+ {
+ values << QString::number(idx);
+ }
}
+ break;
+ case AMR_BLOCK:
+ {
+ typedef QPair UIPair;
+ const QList amrIndexes = dmodel.checkedLevelDatasets();
+ QSet uniq;
+ foreach (const UIPair& idx, amrIndexes)
+ {
+ uniq.insert(idx.second);
+ }
+ foreach (unsigned int idx, uniq)
+ {
+ values << QString::number(idx);
+ }
+ }
+ break;
+
+ default:
+ qCritical("Invalid criteria_type.");
}
+
this->Internals->value_block->setText(values.join(","));
}
diff --git a/Qt/Components/pqSignalAdaptorCompositeTreeWidget.cxx b/Qt/Components/pqSignalAdaptorCompositeTreeWidget.cxx
deleted file mode 100644
index 8ac96722e2c5496adf9b2eefb324a00945be7701..0000000000000000000000000000000000000000
--- a/Qt/Components/pqSignalAdaptorCompositeTreeWidget.cxx
+++ /dev/null
@@ -1,874 +0,0 @@
-/*=========================================================================
-
- Program: ParaView
- Module: pqSignalAdaptorCompositeTreeWidget.cxx
-
- Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
- All rights reserved.
-
- ParaView is a free software; you can redistribute it and/or modify it
- under the terms of the ParaView license version 1.2.
-
- See License_v1.2.txt for the full ParaView license.
- A copy of this license can be obtained by contacting
- Kitware Inc.
- 28 Corporate Drive
- Clifton Park, NY 12065
- USA
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-========================================================================*/
-#include "pqSignalAdaptorCompositeTreeWidget.h"
-
-// Server Manager Includes.
-#include "vtkEventQtSlotConnect.h"
-#include "vtkPVCompositeDataInformation.h"
-#include "vtkPVDataInformation.h"
-#include "vtkPVXMLElement.h"
-#include "vtkSMCompositeTreeDomain.h"
-#include "vtkSMDomainIterator.h"
-#include "vtkSMIntVectorProperty.h"
-#include "vtkSMOutputPort.h"
-#include "vtkSMSourceProxy.h"
-#include "vtkSmartPointer.h"
-
-// Qt Includes.
-#include
-#include
-#include
-
-// ParaView Includes.
-#include "pqSMAdaptor.h"
-#include "pqTreeWidgetItem.h"
-
-//-----------------------------------------------------------------------------
-class pqSignalAdaptorCompositeTreeWidget::pqInternal
-{
-public:
- QPointer TreeWidget;
- vtkSmartPointer Property;
- vtkSmartPointer OutputPort;
- vtkSmartPointer Domain;
- vtkSmartPointer VTKConnect;
- vtkSmartPointer VTKConnectSelection;
-
- QList Items;
- int DomainMode;
-};
-
-//-----------------------------------------------------------------------------
-class pqSignalAdaptorCompositeTreeWidget::pqCallbackAdaptor
- : public pqTreeWidgetItem::pqCallbackHandler
-{
- int ChangeDepth; // used to avoid repeated valuesChanged() signal firing when
- // check states are being changed as a consequence of toggle
- // the check state for a non-leaf node.
- bool BlockCallbacks;
- bool PrevBlockSignals;
- pqSignalAdaptorCompositeTreeWidget* Adaptor;
-
-public:
- pqCallbackAdaptor(pqSignalAdaptorCompositeTreeWidget* adaptor)
- {
- this->Adaptor = adaptor;
- this->BlockCallbacks = false;
- this->ChangeDepth = 0;
- }
- bool blockCallbacks(bool val)
- {
- bool old = this->BlockCallbacks;
- this->BlockCallbacks = val;
- return old;
- }
- virtual void checkStateChanged(pqTreeWidgetItem* item, int column)
- {
- // When a non-leaf node is toggled, Qt changes the check state of all child
- // nodes. When that's happening we don't want to repeatedly fire
- // valuesChanged() signal. Hence we use this ChangeDepth magic.
- this->ChangeDepth--;
- if (this->ChangeDepth == 0)
- {
- this->Adaptor->blockSignals(this->PrevBlockSignals);
- }
- if (this->BlockCallbacks == false)
- {
- this->Adaptor->updateCheckState(item, column);
- }
- }
-
- virtual void checkStateAboutToChange(pqTreeWidgetItem* /*item*/, int /*column*/)
- {
- // When a non-leaf node is toggled, Qt changes the check state of all child
- // nodes. When that's happening we don't want to repeatedly fire
- // valuesChanged() signal. Hence we use this ChangeDepth magic.
- this->ChangeDepth++;
- if (this->ChangeDepth == 1)
- {
- this->PrevBlockSignals = this->Adaptor->blockSignals(true);
- }
- }
-
- virtual bool acceptChange(pqTreeWidgetItem* item, const QVariant& curValue,
- const QVariant& newValue, int column, int role)
- {
- if (this->BlockCallbacks == false)
- {
- // * In SINGLE_ITEM, it's an error to not have any item checked. Hence if
- // the user is un-checking an item, we ensure that atleast one other item
- // is checked.
- if (this->Adaptor->CheckMode == pqSignalAdaptorCompositeTreeWidget::SINGLE_ITEM &&
- role == Qt::CheckStateRole && curValue.toInt() == Qt::Checked &&
- newValue.toInt() == Qt::Unchecked && (item->flags() & Qt::ItemIsTristate) == 0)
- {
- // ensure that at least one item is always checked.
- foreach (pqTreeWidgetItem* curitem, this->Adaptor->Internal->Items)
- {
- if (item != curitem && curitem->checkState(column) == Qt::Checked)
- {
- return true;
- }
- }
- return false;
- }
- }
- return true;
- }
-};
-
-// This TreeItem specialization needs some explanation.
-// Default Qt behavior for tristate items:
-// - If all immediate children are checked or partially checked
-// then the item becomes fully checked.
-// This is not appropriate for this widget. A parent item should never be fully
-// checked unless the user explicitly checked it, since otherwise, the behavior
-// of the filter is to pass the entire subtree through.
-// This class fixes that issue.
-class pqCompositeTreeWidgetItem : public pqTreeWidgetItem
-{
- typedef pqTreeWidgetItem Superclass;
- int triStateCheckState;
- bool inSetData;
-
-public:
- pqCompositeTreeWidgetItem(QTreeWidget* tree, QStringList _values)
- : Superclass(tree, _values)
- , triStateCheckState(-1)
- , inSetData(false)
-
- {
- }
-
- pqCompositeTreeWidgetItem(QTreeWidgetItem* item, QStringList _values)
- : Superclass(item, _values)
- , triStateCheckState(-1)
- , inSetData(false)
- {
- }
-
- virtual QVariant data(int column, int role) const
- {
- if (role == Qt::CheckStateRole && this->triStateCheckState != -1 && this->childCount() > 0 &&
- (this->flags() & Qt::ItemIsTristate))
- {
- // superclass implementation of this method only checks the immediate
- // children.
- QVariant vSuggestedValue = this->Superclass::data(column, role);
- int suggestedValue = vSuggestedValue.toInt();
- if (this->triStateCheckState == Qt::PartiallyChecked)
- {
- if (suggestedValue == Qt::Checked || suggestedValue == Qt::PartiallyChecked)
- {
- return Qt::PartiallyChecked;
- }
- // suggestedValue == Qt:Unchecked
- return Qt::Unchecked;
- }
- return this->triStateCheckState;
- }
-
- return this->Superclass::data(column, role);
- }
-
- virtual void setData(int column, int role, const QVariant& in_value)
- {
- this->inSetData = true;
- this->triStateCheckState = -1;
-
- // Superclass will also mark all children checked or unchecked.
- this->Superclass::setData(column, role, in_value);
-
- if (role == Qt::CheckStateRole && column == 0)
- {
- QVariant value = this->data(column, role);
-
- if (this->flags() & Qt::ItemIsTristate)
- {
- this->triStateCheckState = value.toInt();
- }
-
- // tell my parent it is partially checked (at best).
- pqCompositeTreeWidgetItem* itemParent =
- dynamic_cast(static_cast(this)->parent());
- while (itemParent && !itemParent->inSetData)
- {
- itemParent->triStateCheckState = Qt::PartiallyChecked;
- itemParent = static_cast(
- static_cast(itemParent)->parent());
- }
- }
- this->inSetData = false;
- }
-};
-
-//-----------------------------------------------------------------------------
-void pqSignalAdaptorCompositeTreeWidget::constructor(QTreeWidget* tree, bool autoUpdateVisibility)
-{
- this->Internal = new pqInternal();
- this->Internal->TreeWidget = tree;
- this->Internal->VTKConnect = vtkSmartPointer::New();
- this->Internal->VTKConnectSelection = vtkSmartPointer::New();
- this->AutoUpdateWidgetVisibility = autoUpdateVisibility;
-
- this->Internal->DomainMode = vtkSMCompositeTreeDomain::ALL;
- this->CheckMode = SINGLE_ITEM;
- this->IndexMode = INDEX_MODE_FLAT;
-
- this->ShowFlatIndex = false;
- this->ShowDatasetsInMultiPiece = false;
- this->ShowSelectedElementCounts = false;
-
- this->CallbackAdaptor = new pqCallbackAdaptor(this);
-}
-
-//-----------------------------------------------------------------------------
-pqSignalAdaptorCompositeTreeWidget::pqSignalAdaptorCompositeTreeWidget(QTreeWidget* tree,
- vtkSMIntVectorProperty* smproperty, bool autoUpdateVisibility /*=false*/,
- bool showSelectedElementCounts /*false*/)
- : Superclass(tree)
-{
- this->constructor(tree, autoUpdateVisibility);
- this->ShowSelectedElementCounts = showSelectedElementCounts;
- this->Internal->Property = smproperty;
- if (!smproperty)
- {
- qCritical() << "Property cannot be NULL.";
- return;
- }
-
- // * Determine CheckMode.
- this->CheckMode = smproperty->GetRepeatCommand() ? MULTIPLE_ITEMS : SINGLE_ITEM;
-
- // * Determine IndexMode.
- this->IndexMode = INDEX_MODE_FLAT;
- if (smproperty->GetNumberOfElementsPerCommand() == 2)
- {
- this->IndexMode = INDEX_MODE_LEVEL_INDEX; // (level, index) pairs.
- }
-
- // IndexMode defaults may be overridden by some hints.
- // If hints are provided, we use those to determine the IndexMode for this
- // property.
- vtkPVXMLElement* hints = smproperty->GetHints();
- if (hints)
- {
- vtkPVXMLElement* useFlatIndex = hints->FindNestedElementByName("UseFlatIndex");
- if (useFlatIndex && useFlatIndex->GetAttribute("value") &&
- strcmp(useFlatIndex->GetAttribute("value"), "0") == 0 && this->IndexMode == INDEX_MODE_FLAT)
- {
- this->IndexMode = INDEX_MODE_LEVEL;
- }
- }
-
- /// * Locate the Domain.
- vtkSMDomainIterator* iter = smproperty->NewDomainIterator();
- iter->Begin();
- while (!iter->IsAtEnd() && !this->Internal->Domain)
- {
- vtkSMDomain* domain = iter->GetDomain();
- this->Internal->Domain = vtkSMCompositeTreeDomain::SafeDownCast(domain);
- iter->Next();
- }
- iter->Delete();
-
- if (this->Internal->Domain)
- {
- this->Internal->VTKConnect->Connect(
- this->Internal->Domain, vtkCommand::DomainModifiedEvent, this, SLOT(domainChanged()));
- this->domainChanged();
- }
-
- // * Initialize the widget using the current value.
- bool prev = this->blockSignals(true);
- QList curValues = pqSMAdaptor::getMultipleElementProperty(smproperty);
- this->setValues(curValues);
- this->blockSignals(prev);
-}
-
-//-----------------------------------------------------------------------------
-pqSignalAdaptorCompositeTreeWidget::pqSignalAdaptorCompositeTreeWidget(QTreeWidget* tree,
- vtkSMOutputPort* port, int domainMode, IndexModes indexMode, bool selectMultiple,
- bool autoUpdateVisibility, bool showSelectedElementCounts)
- : Superclass(tree)
-{
- this->constructor(tree, autoUpdateVisibility);
-
- if (!port)
- {
- qCritical() << "Output port cannot be NULL.";
- return;
- }
-
- this->ShowFlatIndex = true;
- this->ShowDatasetsInMultiPiece = true;
- this->ShowSelectedElementCounts = showSelectedElementCounts;
- this->CheckMode = selectMultiple ? MULTIPLE_ITEMS : SINGLE_ITEM;
- this->IndexMode = indexMode;
- this->Internal->DomainMode = domainMode;
- this->Internal->OutputPort = port;
- this->Internal->VTKConnect->Connect(
- port, vtkCommand::UpdateDataEvent, this, SLOT(portInformationChanged()));
- this->portInformationChanged();
-}
-
-//-----------------------------------------------------------------------------
-pqSignalAdaptorCompositeTreeWidget::~pqSignalAdaptorCompositeTreeWidget()
-{
- delete this->Internal;
- delete this->CallbackAdaptor;
- this->CallbackAdaptor = 0;
-}
-
-//-----------------------------------------------------------------------------
-void pqSignalAdaptorCompositeTreeWidget::select(unsigned int flat_index)
-{
- QList selItems = this->Internal->TreeWidget->selectedItems();
- foreach (QTreeWidgetItem* item, selItems)
- {
- item->setSelected(false);
- }
- QList treeitems = this->Internal->Items;
- foreach (pqTreeWidgetItem* item, treeitems)
- {
- QVariant metadata = item->data(0, FLAT_INDEX);
- if (metadata.isValid() && metadata.toUInt() == flat_index)
- {
- item->setSelected(true);
- break;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-unsigned int pqSignalAdaptorCompositeTreeWidget::getCurrentFlatIndex(bool* valid)
-{
- if (valid)
- {
- *valid = false;
- }
-
- QList selItems = this->Internal->TreeWidget->selectedItems();
- if (selItems.size() > 0)
- {
- if (valid)
- {
- *valid = true;
- }
- return this->flatIndex(selItems[0]);
- }
- return 0;
-}
-
-//-----------------------------------------------------------------------------
-unsigned int pqSignalAdaptorCompositeTreeWidget::flatIndex(const QTreeWidgetItem* item) const
-{
- return item->data(0, FLAT_INDEX).toUInt();
-}
-
-//-----------------------------------------------------------------------------
-unsigned int pqSignalAdaptorCompositeTreeWidget::hierarchicalLevel(
- const QTreeWidgetItem* item) const
-{
- QVariant val = item->data(0, AMR_LEVEL_NUMBER).toUInt();
- return val.toUInt();
-}
-
-//-----------------------------------------------------------------------------
-unsigned int pqSignalAdaptorCompositeTreeWidget::hierarchicalBlockIndex(
- const QTreeWidgetItem* item) const
-{
- QVariant val = item->data(0, AMR_BLOCK_INDEX).toUInt();
- return val.toUInt();
-}
-
-//-----------------------------------------------------------------------------
-QString pqSignalAdaptorCompositeTreeWidget::blockName(const QTreeWidgetItem* item) const
-{
- QString block_name = item->data(0, BLOCK_NAME).toString();
- return block_name;
-}
-
-//-----------------------------------------------------------------------------
-QList pqSignalAdaptorCompositeTreeWidget::values() const
-{
- QList reply;
-
- QList treeitems = this->Internal->Items;
- foreach (pqTreeWidgetItem* item, treeitems)
- {
- QVariant nodeType = item->data(0, NODE_TYPE);
- if (!nodeType.isValid())
- {
- continue;
- }
-
- if ((this->Internal->DomainMode == vtkSMCompositeTreeDomain::LEAVES &&
- nodeType.toInt() != LEAF) ||
- (this->Internal->DomainMode == vtkSMCompositeTreeDomain::NON_LEAVES &&
- nodeType.toInt() != NON_LEAF))
- {
- // Skip nodes the filter is not interested in.
- continue;
- }
-
- if (this->IndexMode == INDEX_MODE_FLAT)
- {
- QVariant metadata = item->data(0, FLAT_INDEX);
- // cout << metadata.toInt() << ": " << item->checkState(0) << endl;
- if (metadata.isValid() && item->checkState(0) == Qt::Checked)
- {
- // metadata has the flat index for the node.
- reply.push_back(metadata);
- // cout << metadata.toInt() << endl;
- }
- }
- else if (this->IndexMode == INDEX_MODE_LEVEL_INDEX)
- {
- QVariant metadata0 = item->data(0, AMR_LEVEL_NUMBER);
- QVariant metadata1 = item->data(0, AMR_BLOCK_INDEX);
- if (metadata0.isValid() && metadata1.isValid() && item->checkState(0) == Qt::Checked)
- {
- reply.push_back(metadata0);
- reply.push_back(metadata1);
- // cout << metadata0.toInt() << ", " << metadata1.toInt() << endl;
- }
- }
- else if (this->IndexMode == INDEX_MODE_LEVEL)
- {
- QVariant metadata0 = item->data(0, AMR_LEVEL_NUMBER);
- if (metadata0.isValid() && item->checkState(0) == Qt::Checked)
- {
- reply.push_back(metadata0);
- // cout << metadata0.toInt() << endl;
- }
- }
- }
-
- return reply;
-}
-
-//-----------------------------------------------------------------------------
-inline bool pqItemIsCheckable(QTreeWidgetItem* item)
-{
- return ((item->flags() & Qt::ItemIsUserCheckable) == Qt::ItemIsUserCheckable);
-}
-
-//-----------------------------------------------------------------------------
-void pqSignalAdaptorCompositeTreeWidget::setValues(const QList& new_values)
-{
- bool prev = this->blockSignals(true);
- QList treeitems = this->Internal->Items;
- bool changed = false;
-
- if (this->IndexMode == INDEX_MODE_FLAT)
- {
- foreach (pqTreeWidgetItem* item, treeitems)
- {
- QVariant metadata = item->data(0, FLAT_INDEX);
- Qt::CheckState cstate =
- (metadata.isValid() && new_values.contains(metadata)) ? Qt::Checked : Qt::Unchecked;
- if (::pqItemIsCheckable(item) && item->checkState(0) != cstate)
- {
- item->setCheckState(0, cstate);
- changed = true;
- }
- }
- }
- else if (this->IndexMode == INDEX_MODE_LEVEL)
- {
- foreach (pqTreeWidgetItem* item, treeitems)
- {
- QVariant metadata = item->data(0, AMR_LEVEL_NUMBER);
- Qt::CheckState cstate =
- (metadata.isValid() && new_values.contains(metadata)) ? Qt::Checked : Qt::Unchecked;
- if (pqItemIsCheckable(item) && item->checkState(0) != cstate)
- {
- item->setCheckState(0, cstate);
- changed = true;
- }
- }
- }
- else if (this->IndexMode == INDEX_MODE_LEVEL_INDEX)
- {
- QSet > pairs;
- for (int cc = 0; (cc + 1) < new_values.size(); cc += 2)
- {
- unsigned int level = new_values[cc].toUInt();
- unsigned int index = new_values[cc + 1].toUInt();
- pairs.insert(QPair(level, index));
- }
-
- foreach (pqTreeWidgetItem* item, treeitems)
- {
- QVariant metadata0 = item->data(0, AMR_LEVEL_NUMBER);
- QVariant metadata1 = item->data(0, AMR_BLOCK_INDEX);
- Qt::CheckState cstate =
- (metadata0.isValid() && metadata1.isValid() &&
- pairs.contains(QPair(metadata0.toUInt(), metadata1.toUInt())))
- ? Qt::Checked
- : Qt::Unchecked;
- if (pqItemIsCheckable(item) && item->checkState(0) != cstate)
- {
- item->setCheckState(0, cstate);
- changed = true;
- }
- }
- }
- this->blockSignals(prev);
- if (changed)
- {
- emit this->valuesChanged();
- }
-}
-
-//-----------------------------------------------------------------------------
-void pqSignalAdaptorCompositeTreeWidget::domainChanged()
-{
- bool prev = this->blockSignals(true);
- QList widgetvalues = this->values();
- this->Internal->Items.clear();
- this->Internal->TreeWidget->clear();
-
- this->Internal->DomainMode = this->Internal->Domain->GetMode();
- vtkPVDataInformation* dInfo = this->Internal->Domain->GetInformation();
-
- this->FlatIndex = 0;
- this->LevelNo = 0;
-
- pqTreeWidgetItem* root =
- new pqCompositeTreeWidgetItem(this->Internal->TreeWidget, QStringList("Root"));
- root->setCallbackHandler(this->CallbackAdaptor);
- root->setData(0, ORIGINAL_LABEL, "Root");
- root->setData(0, BLOCK_NAME, QString());
- root->setToolTip(0, root->text(0));
- this->buildTree(root, dInfo);
- this->updateItemFlags();
- this->updateSelectionCounts();
-
- // now update check state.
- this->setValues(widgetvalues);
- this->blockSignals(prev);
-
- if (this->AutoUpdateWidgetVisibility)
- {
- this->Internal->TreeWidget->setVisible(
- dInfo ? dInfo->GetCompositeDataInformation()->GetDataIsComposite() == 1 : 0);
- }
-
- if (this->ShowSelectedElementCounts)
- {
- this->setupSelectionUpdatedCallback(
- this->Internal->Domain->GetSource(), this->Internal->Domain->GetSourcePort());
- }
- else
- {
- this->setupSelectionUpdatedCallback(NULL, 0);
- }
-}
-
-//-----------------------------------------------------------------------------
-void pqSignalAdaptorCompositeTreeWidget::portInformationChanged()
-{
- bool prev = this->blockSignals(true);
- QList widgetvalues = this->values();
- this->Internal->Items.clear();
- this->Internal->TreeWidget->clear();
-
- vtkPVDataInformation* dInfo = this->Internal->OutputPort->GetDataInformation();
-
- this->FlatIndex = 0;
- this->LevelNo = 0;
-
- pqTreeWidgetItem* root =
- new pqCompositeTreeWidgetItem(this->Internal->TreeWidget, QStringList("Root"));
- root->setCallbackHandler(this->CallbackAdaptor);
- root->setData(0, ORIGINAL_LABEL, "Root");
- root->setData(0, BLOCK_NAME, QString());
- root->setToolTip(0, root->text(0));
- this->buildTree(root, dInfo);
- this->updateItemFlags();
- this->updateSelectionCounts();
-
- // now update check state.
- this->setValues(widgetvalues);
- this->blockSignals(prev);
-
- if (this->AutoUpdateWidgetVisibility)
- {
- this->Internal->TreeWidget->setVisible(
- dInfo->GetCompositeDataInformation()->GetDataIsComposite() == 1);
- }
-
- this->setupSelectionUpdatedCallback(NULL, 0);
-}
-
-//-----------------------------------------------------------------------------
-// For all elements in the tree, this method determines if the item is checkable
-// (given the current mode).
-void pqSignalAdaptorCompositeTreeWidget::updateItemFlags()
-{
- if (this->Internal->DomainMode == vtkSMCompositeTreeDomain::NONE)
- {
- // no item is checkable.
- return;
- }
-
- foreach (pqTreeWidgetItem* item, this->Internal->Items)
- {
- QVariant vNodeType = item->data(0, NODE_TYPE);
- if (!vNodeType.isValid() || !vNodeType.canConvert())
- {
- continue;
- }
-
- int nodeType = vNodeType.toInt();
- if (nodeType == LEAF)
- {
- // leaves are always checkable.
- item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
- item->setCheckState(0, Qt::Unchecked);
- }
- else if (nodeType == NON_LEAF)
- {
- // If domainMode == LEAVES and CheckMode == SINGLE_ITEM, then non-leaf are
- // not checkable.
- if (this->Internal->DomainMode != vtkSMCompositeTreeDomain::LEAVES ||
- this->CheckMode != SINGLE_ITEM)
- {
- item->setFlags(item->flags() | Qt::ItemIsUserCheckable | Qt::ItemIsTristate);
- item->setCheckState(0, Qt::Unchecked);
- }
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-/// Called when an item check state is toggled. This is used only when
-/// this->CheckMode == SINGLE_ITEM. We uncheck all other items.
-void pqSignalAdaptorCompositeTreeWidget::updateCheckState(pqTreeWidgetItem* item, int column)
-{
- this->CallbackAdaptor->blockCallbacks(true);
- bool checked = item->checkState(column) == Qt::Checked;
- if (item && checked && this->CheckMode == SINGLE_ITEM)
- {
- foreach (pqTreeWidgetItem* curitem, this->Internal->Items)
- {
- if (curitem != item && (curitem->flags() & Qt::ItemIsUserCheckable) &&
- (curitem->checkState(0) != Qt::Unchecked) && (curitem->flags() & Qt::ItemIsTristate) == 0)
- {
- curitem->setCheckState(0, Qt::Unchecked);
- }
- }
- }
- this->CallbackAdaptor->blockCallbacks(false);
- emit this->valuesChanged();
-}
-
-//-----------------------------------------------------------------------------
-void pqSignalAdaptorCompositeTreeWidget::buildTree(
- pqTreeWidgetItem* item, vtkPVDataInformation* info)
-{
- this->Internal->Items.push_back(item);
- item->setData(0, FLAT_INDEX, this->FlatIndex);
- item->setData(0, NODE_TYPE, LEAF);
- this->FlatIndex++;
- if (!info)
- {
- return;
- }
-
- vtkPVCompositeDataInformation* cinfo = info->GetCompositeDataInformation();
- if (!cinfo->GetDataIsComposite())
- {
- return;
- }
-
- if (cinfo->GetDataIsMultiPiece())
- {
- if (this->ShowDatasetsInMultiPiece ||
- (this->IndexMode == INDEX_MODE_LEVEL_INDEX &&
- this->Internal->DomainMode != vtkSMCompositeTreeDomain::NON_LEAVES))
- {
- // multi-piece is treated as a leaf node, unless the IndexMode is
- // INDEX_MODE_LEVEL_INDEX, in which case the pieces in the multi-piece are
- // further expanded.
- item->setData(0, NODE_TYPE, NON_LEAF);
- // user should be able to select individual pieces.
- for (unsigned int cc = 0; cc < cinfo->GetNumberOfChildren(); cc++)
- {
- // We don't fetch the names for each piece in a vtkMultiPieceDataSet
- // hence we just make up a name,
- QString childLabel = QString("DataSet %1").arg(cc);
- if (this->ShowFlatIndex)
- {
- childLabel = QString("DataSet (%1)").arg(this->FlatIndex);
- }
-
- pqTreeWidgetItem* child = new pqCompositeTreeWidgetItem(item, QStringList(childLabel));
- child->setCallbackHandler(this->CallbackAdaptor);
- child->setToolTip(0, child->text(0));
- child->setData(0, ORIGINAL_LABEL, childLabel);
- child->setData(0, BLOCK_NAME, QString());
- this->buildTree(child, NULL);
- child->setData(0, AMR_BLOCK_INDEX, cc);
- child->setData(0, AMR_LEVEL_NUMBER, this->LevelNo);
- }
- }
- else
- {
- this->FlatIndex += cinfo->GetNumberOfChildren();
- }
- item->setExpanded(false); // multipieces are not expanded by default.
- return;
- }
-
- // A composite dataset (non-multipiece) is always a non-leaf node.
- item->setExpanded(true);
- item->setData(0, NODE_TYPE, NON_LEAF);
-
- this->LevelNo = 0;
- bool is_hierarchical =
- (strcmp(info->GetCompositeDataClassName(), "vtkHierarchicalBoxDataSet") == 0);
-
- for (unsigned int cc = 0; cc < cinfo->GetNumberOfChildren(); cc++)
- {
- vtkPVDataInformation* childInfo = cinfo->GetDataInformation(cc);
- QString childLabel = QString("DataSet %1").arg(cc);
- QString block_name;
-
- bool is_leaf = true;
- if (childInfo && childInfo->GetCompositeDataInformation()->GetDataIsComposite())
- {
- childLabel = is_hierarchical ? QString("Level %1").arg(cc) : QString("Block %1").arg(cc);
- is_leaf = false;
- }
- if (const char* cname = cinfo->GetName(cc))
- {
- if (cname[0])
- {
- childLabel = cname;
- block_name = cname;
- }
- }
-
- if (this->ShowFlatIndex)
- {
- childLabel = QString("%1 (%2)").arg(childLabel).arg(this->FlatIndex);
- }
-
- if (this->Internal->DomainMode != vtkSMCompositeTreeDomain::NON_LEAVES || !is_leaf)
- {
- pqTreeWidgetItem* child = new pqCompositeTreeWidgetItem(item, QStringList(childLabel));
- child->setCallbackHandler(this->CallbackAdaptor);
- child->setData(0, ORIGINAL_LABEL, childLabel);
- child->setData(0, BLOCK_NAME, block_name);
- child->setToolTip(0, child->text(0));
- this->buildTree(child, cinfo->GetDataInformation(cc));
- child->setData(0, AMR_LEVEL_NUMBER, this->LevelNo);
- this->LevelNo++;
- }
- else
- {
- // don't add leaf nodes, when non-leaves alone are selectable.
- this->FlatIndex++;
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-void pqSignalAdaptorCompositeTreeWidget::updateSelectionCounts()
-{
- if (!this->ShowSelectedElementCounts)
- {
- // Nothing to do.
- return;
- }
-
- if (!this->Internal->Domain)
- {
- return;
- }
-
- // Iterate over the selection data information and then update the labels.
- vtkSMSourceProxy* sourceProxy = this->Internal->Domain->GetSource();
- if (!sourceProxy || !sourceProxy->GetSelectionOutput(this->Internal->Domain->GetSourcePort()))
- {
- return;
- }
-
- vtkPVDataInformation* info =
- sourceProxy->GetSelectionOutput(this->Internal->Domain->GetSourcePort())->GetDataInformation();
-
- foreach (pqTreeWidgetItem* item, this->Internal->Items)
- {
- if (item->data(0, NODE_TYPE).toInt() != LEAF)
- {
- continue;
- }
-
- unsigned int flat_index = item->data(0, FLAT_INDEX).toUInt();
- vtkPVDataInformation* subInfo =
- info->GetDataInformationForCompositeIndex(static_cast(flat_index));
- if (subInfo)
- {
- item->setText(0, QString("%1 (%2, %3)")
- .arg(item->data(0, ORIGINAL_LABEL).toString())
- .arg(subInfo->GetNumberOfPoints())
- .arg(subInfo->GetNumberOfCells()));
- item->setToolTip(0, item->text(0));
- }
- else
- {
- item->setText(0, QString("%1").arg(item->data(0, ORIGINAL_LABEL).toString()));
- item->setToolTip(0, item->text(0));
- }
- }
-}
-
-//-----------------------------------------------------------------------------
-/// Set up the callback to know when the selection changes, so that we can
-/// update the selected cells/points counts.
-void pqSignalAdaptorCompositeTreeWidget::setupSelectionUpdatedCallback(
- vtkSMSourceProxy* source, unsigned int port)
-{
- this->Internal->VTKConnectSelection->Disconnect();
- if (source)
- {
- vtkSMSourceProxy* selProxy = source->GetSelectionOutput(port);
- if (selProxy)
- {
- this->Internal->VTKConnectSelection->Connect(
- selProxy, vtkCommand::UpdateDataEvent, this, SLOT(updateSelectionCounts()));
- }
- }
-}
diff --git a/Qt/Components/pqSignalAdaptorCompositeTreeWidget.h b/Qt/Components/pqSignalAdaptorCompositeTreeWidget.h
deleted file mode 100644
index cb0d1b5c633084689944c82b047e835ce643a0b5..0000000000000000000000000000000000000000
--- a/Qt/Components/pqSignalAdaptorCompositeTreeWidget.h
+++ /dev/null
@@ -1,262 +0,0 @@
-/*=========================================================================
-
- Program: ParaView
- Module: pqSignalAdaptorCompositeTreeWidget.h
-
- Copyright (c) 2005-2008 Sandia Corporation, Kitware Inc.
- All rights reserved.
-
- ParaView is a free software; you can redistribute it and/or modify it
- under the terms of the ParaView license version 1.2.
-
- See License_v1.2.txt for the full ParaView license.
- A copy of this license can be obtained by contacting
- Kitware Inc.
- 28 Corporate Drive
- Clifton Park, NY 12065
- USA
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
-CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-========================================================================*/
-#ifndef pqSignalAdaptorCompositeTreeWidget_h
-#define pqSignalAdaptorCompositeTreeWidget_h
-
-#include "pqComponentsModule.h"
-#include
-#include
-
-class pqTreeWidgetItem;
-class QTreeWidget;
-class QTreeWidgetItem;
-class vtkPVDataInformation;
-class vtkSMIntVectorProperty;
-class vtkSMOutputPort;
-class vtkSMSourceProxy;
-
-/**
-* pqSignalAdaptorCompositeTreeWidget is used to connect a property with
-* vtkSMCompositeTreeDomain as its domain to a Tree widget. It updates the tree
-* to show composite data tree.
-* Caveats: This widget does not handle SINGLE_ITEM selection where non-leaves
-* are acceptable.
-*/
-class PQCOMPONENTS_EXPORT pqSignalAdaptorCompositeTreeWidget : public QObject
-{
- Q_OBJECT
- typedef QObject Superclass;
-
- Q_PROPERTY(QList values READ values WRITE setValues)
-public:
- enum IndexModes
- {
- INDEX_MODE_FLAT,
- INDEX_MODE_LEVEL_INDEX, // this mode works only for 1 level deep trees.
- INDEX_MODE_LEVEL, // this mode works only for 1 level deep trees.
- };
-
- /**
- * Constructor. \c domain is used to build the tree layout to show in the
- * widget.
- * \c autoUpdateWidgetVisibility - is true, the tree widget is hidden if the
- * data information says that the data is
- * not composite.
- * \c showSelectedElementCounts - when true, next to each leaf node, an entry
- * will be added showing the number of
- * selected elements (cells|points).
- */
- pqSignalAdaptorCompositeTreeWidget(QTreeWidget*, vtkSMIntVectorProperty* smproperty,
- bool autoUpdateWidgetVisibility = false, bool showSelectedElementCounts = false);
-
- /**
- * Alternate constructor.
- * \c outputport - the output port producing the composite dataset to show.
- * \c domainMode - vtkSMCompositeTreeDomain::ALL|LEAVES|NON_LEAVES|NONE.
- * Indicates what types of nodes in the composite tree
- * are selectable.
- * \c indexMode - indicates how the values are set/get (using
- * composite-flat-index, using level-dataset-index or using
- * only the level number.
- * \c selectMultiple - true if possible to select multiple nodes.
- * \c autoUpdateWidgetVisibility - is true, the tree widget is hidden if the
- * data information says that the data is
- * not composite.
- * \c showSelectedElementCounts - when true, next to each leaf node, an entry
- * will be added showing the number of
- * selected elements (cells|points).
- */
- pqSignalAdaptorCompositeTreeWidget(QTreeWidget*, vtkSMOutputPort* outputport, int domainMode,
- IndexModes indexMode = INDEX_MODE_FLAT, bool selectMultiple = false,
- bool autoUpdateWidgetVisibility = false, bool showSelectedElementCounts = false);
-
- /**
- * Destructor
- */
- virtual ~pqSignalAdaptorCompositeTreeWidget();
-
- /**
- * Returns the current value.
- * This is a QList of unsigned ints.
- */
- QList values() const;
-
- /**
- * When set, the adaptor will update the visibility of the widget depending
- * on whether the data is composite or not.
- */
- void setAutoUpdateWidgetVisibility(bool val) { this->AutoUpdateWidgetVisibility = val; }
- bool autoUpdateWidgetVisibility() const { return this->AutoUpdateWidgetVisibility; }
-
- /**
- * Select the item with the given flat index.
- */
- void select(unsigned int flatIndex);
-
- /**
- * API to get information about the currently selected item.
- * Returns the flat index for the current item.
- */
- unsigned int getCurrentFlatIndex(bool* valid = NULL);
-
- /**
- * API to get information about an item.
- * Returns the block name for the item.
- */
- QString blockName(const QTreeWidgetItem* item) const;
-
- /**
- * API to get information about an item.
- * Returns the AMR level for the item if valid.
- */
- unsigned int hierarchicalLevel(const QTreeWidgetItem* item) const;
-
- /**
- * API to get information about an item.
- * Returns the AMR block number for the item if valid.
- */
- unsigned int hierarchicalBlockIndex(const QTreeWidgetItem* item) const;
-
- /**
- * API to get information about an item.
- * Returns the flat index for the item.
- */
- unsigned int flatIndex(const QTreeWidgetItem* item) const;
-
-public slots:
- /**
- * Set the values.
- */
- void setValues(const QList& values);
-
- /**
- * Called when domain changes.
- */
- void domainChanged();
-
- /**
- * Called when the output port says that the data information has been
- * updated.
- */
- void portInformationChanged();
-
-signals:
- /**
- * Fired when the widget value changes.
- */
- void valuesChanged();
-
-private slots:
-
- /**
- * Called to update the labels to show the current selected elements
- * information.
- */
- void updateSelectionCounts();
-
-private:
- Q_DISABLE_COPY(pqSignalAdaptorCompositeTreeWidget)
-
- /**
- * Set up the callback to know when the selection changes, so that we can
- * update the selected cells/points counts.
- */
- void setupSelectionUpdatedCallback(vtkSMSourceProxy* source, unsigned int port);
-
- void buildTree(pqTreeWidgetItem* item, vtkPVDataInformation* info);
-
- /**
- * updates the check flags for all the items.
- */
- void updateItemFlags();
-
- class pqInternal;
- pqInternal* Internal;
-
- enum MetaData
- {
- FLAT_INDEX = Qt::UserRole,
- AMR_LEVEL_NUMBER = Qt::UserRole + 1,
- AMR_BLOCK_INDEX = Qt::UserRole + 2,
- NODE_TYPE = Qt::UserRole + 3,
- ORIGINAL_LABEL = Qt::UserRole + 4,
- BLOCK_NAME = Qt::UserRole + 5
- };
-
- enum NodeTypes
- {
- LEAF = 21,
- NON_LEAF = 22,
- };
-
- enum CheckModes
- {
- SINGLE_ITEM,
- MULTIPLE_ITEMS
- };
-
- IndexModes IndexMode;
-
- // Determines if the widget should allow checking only 1 item at a time or
- // multiple items should be check-able.
- CheckModes CheckMode;
-
- // These are used by buildTree() to determin indices for the nodes.
- unsigned int FlatIndex;
- unsigned int LevelNo;
-
- bool AutoUpdateWidgetVisibility;
-
- bool ShowFlatIndex;
-
- bool ShowSelectedElementCounts;
-
- // When set to true, all pieces within a multipiece are shown.
- bool ShowDatasetsInMultiPiece;
-
- /**
- * Code common to both variants of the constructor.
- */
- void constructor(QTreeWidget* tree, bool autoUpdateVisibility);
-
- /**
- * Called when an item check state is toggled. This is used only when
- * this->CheckMode == SINGLE_ITEM. We uncheck all other items.
- */
- void updateCheckState(pqTreeWidgetItem* item, int column);
-
- friend class pqCallbackAdaptor;
- class pqCallbackAdaptor;
- pqCallbackAdaptor* CallbackAdaptor;
-};
-
-#endif
diff --git a/Qt/Widgets/pqTreeView.cxx b/Qt/Widgets/pqTreeView.cxx
index 5ae2c059dd14a53632838c09b2bb7ae6948ce7a6..ca67fc805c7bd3c802b27f14818bb37f24a416f8 100644
--- a/Qt/Widgets/pqTreeView.cxx
+++ b/Qt/Widgets/pqTreeView.cxx
@@ -43,6 +43,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include
#include
+namespace
+{
+int pqCountItems(QAbstractItemModel* model, const QModelIndex& idx, int max)
+{
+ int numItems = model->rowCount(idx);
+ int count = numItems;
+ for (int cc = 0; cc < numItems; ++cc)
+ {
+ if (count >= max)
+ {
+ return count;
+ }
+ count += pqCountItems(model, model->index(cc, 0, idx), max - numItems);
+ }
+ return count;
+}
+}
+
pqTreeView::pqTreeView(QWidget* widgetParent)
: QTreeView(widgetParent)
, ScrollPadding(0)
@@ -52,6 +70,7 @@ pqTreeView::pqTreeView(QWidget* widgetParent)
// Change the default header view to a checkable one.
pqCheckableHeaderView* checkable = new pqCheckableHeaderView(Qt::Horizontal, this);
+ checkable->setStretchLastSection(this->header()->stretchLastSection());
this->setHeader(checkable);
this->installEventFilter(checkable);
#if QT_VERSION >= 0x050000
@@ -121,13 +140,9 @@ QSize pqTreeView::sizeHint() const
// add padding for the scrollbar
int extra = this->ScrollPadding;
- int num = 0;
- QAbstractItemModel* current = this->model();
- if (current)
- {
- num = current->rowCount(this->rootIndex());
- }
-
+ QAbstractItemModel* dmodel = this->model();
+ QModelIndex idx = this->rootIndex();
+ int num = pqCountItems(dmodel, idx, maxItemHint);
if (num >= maxItemHint)
{
extra = 0;
diff --git a/Testing/Data/Baseline/SpreadSheet3.png.md5 b/Testing/Data/Baseline/SpreadSheet3.png.md5
index c79763d491c54bdf73f7958162e5e083f26f46ee..4640b0a8c250e163e31c2533b813cc46ab164a64 100644
--- a/Testing/Data/Baseline/SpreadSheet3.png.md5
+++ b/Testing/Data/Baseline/SpreadSheet3.png.md5
@@ -1 +1 @@
-044dca08db93e83b1f09bf4c4a440b8d
+305ae44caff67b97e798d1a71b3475ae