property_tree_widget.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, Willow Garage, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * * Neither the name of the Willow Garage, Inc. nor the names of its
14  * contributors may be used to endorse or promote products derived from
15  * this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include <QTimer>
31 #include <QHash>
32 #include <QSet>
33 
38 
40 #include <ros/console.h>
41 
42 namespace rviz
43 {
44 PropertySelectionModel::PropertySelectionModel(QAbstractItemModel* model) : QItemSelectionModel(model)
45 {
46 }
47 
48 void PropertySelectionModel::setCurrentIndex(const QModelIndex& index,
49  QItemSelectionModel::SelectionFlags command)
50 {
51  QModelIndex property_index = index.sibling(index.row(), 1);
52  if (index.flags() & Qt::ItemIsEditable || !property_index.isValid())
53  {
54  QItemSelectionModel::setCurrentIndex(index, command);
55  }
56  else
57  {
58  QItemSelectionModel::setCurrentIndex(property_index, command);
59  }
60 }
61 
63  : QTreeView(parent), model_(nullptr), splitter_handle_(new SplitterHandle(this))
64 {
65  setItemDelegateForColumn(1, new PropertyTreeDelegate(this));
66  setDropIndicatorShown(true);
67  setUniformRowHeights(true);
68  setHeaderHidden(true);
69  setDragEnabled(true);
70  setAcceptDrops(true);
71  setAnimated(true);
72  setAllColumnsShowFocus(true);
73  setSelectionMode(QAbstractItemView::ExtendedSelection);
74  setEditTriggers(QAbstractItemView::AllEditTriggers);
75 
76  QTimer* timer = new QTimer(this);
77  connect(timer, &QTimer::timeout, this, [this] { update(); });
78  timer->start(100);
79 }
80 
81 void PropertyTreeWidget::currentChanged(const QModelIndex& new_current_index,
82  const QModelIndex& previous_current_index)
83 {
84  QTreeView::currentChanged(new_current_index, previous_current_index);
85  Q_EMIT currentPropertyChanged(static_cast<const Property*>(new_current_index.internalPointer()));
86 }
87 
88 void PropertyTreeWidget::selectionChanged(const QItemSelection& selected,
89  const QItemSelection& deselected)
90 {
91  QTreeView::selectionChanged(selected, deselected);
92  Q_EMIT selectionHasChanged();
93 }
94 
96 {
97  if (model_)
98  {
101  disconnect(model_, &PropertyTreeModel::expand, this, &PropertyTreeWidget::expand);
102  disconnect(model_, &PropertyTreeModel::collapse, this, &PropertyTreeWidget::collapse);
103  }
104  model_ = model;
105  QTreeView::setModel(model_);
106  if (model_)
107  {
108  QItemSelectionModel* m = selectionModel();
109  setSelectionModel(new PropertySelectionModel(model_));
110  m->deleteLater();
111 
114  connect(model_, &PropertyTreeModel::expand, this, &PropertyTreeWidget::expand);
115  connect(model_, &PropertyTreeModel::collapse, this, &PropertyTreeWidget::collapse);
116 
117  // this will trigger all hiddenChanged events to get re-fired
119  }
120 }
121 
123 {
124  if (model_)
125  {
126  const auto& parent_index = model_->parentIndex(property);
127  if (parent_index.isValid())
128  setRowHidden(property->rowNumberInParent(), parent_index, property->getHidden());
129  else
130  ROS_WARN_STREAM("Trying to hide property '" << qPrintable(property->getName())
131  << "' that is not part of the model.");
132  }
133 }
134 
136 {
137  saveExpandedEntries(config.mapMakeChild("Expanded"), QModelIndex(), "");
138 
139  config.mapSetValue("Splitter Ratio", splitter_handle_->getRatio());
140 }
141 
143  const QModelIndex& parent_index,
144  const QString& prefix) const
145 {
146  int num_children = model_->rowCount(parent_index);
147  if (num_children > 0)
148  {
149  QHash<QString, int> name_counts;
150  for (int i = 0; i < num_children; i++)
151  {
152  QModelIndex child_index = model_->index(i, 0, parent_index);
153  Property* child = model_->getProp(child_index);
154  QString child_name = child->getName();
155  if (qobject_cast<StatusList*>(child))
156  {
157  // StatusList objects change their name dynamically, so
158  // normalize to a standard string.
159  child_name = "Status";
160  }
161  int name_occurrence = ++(name_counts[child_name]);
162  QString full_name = prefix + "/" + child_name + QString::number(name_occurrence);
163  if (isExpanded(child_index))
164  {
165  config.listAppendNew().setValue(full_name);
166  }
167  saveExpandedEntries(config, child_index, full_name);
168  }
169  }
170 }
171 
172 void PropertyTreeWidget::load(const Config& config)
173 {
174  Config expanded_list_config = config.mapGetChild("Expanded");
175  QSet<QString> expanded_full_names;
176  int num_expanded = expanded_list_config.listLength();
177  for (int i = 0; i < num_expanded; i++)
178  {
179  expanded_full_names.insert(expanded_list_config.listChildAt(i).getValue().toString());
180  }
181  expandEntries(expanded_full_names, QModelIndex(), "");
182 
183  float ratio;
184  if (config.mapGetFloat("Splitter Ratio", &ratio))
185  {
186  splitter_handle_->setRatio(ratio);
187  }
188 }
189 
190 void PropertyTreeWidget::expandEntries(const QSet<QString>& expanded_full_names,
191  const QModelIndex& parent_index,
192  const QString& prefix)
193 {
194  int num_children = model_->rowCount(parent_index);
195  if (num_children > 0)
196  {
197  QHash<QString, int> name_counts;
198  for (int i = 0; i < num_children; i++)
199  {
200  QModelIndex child_index = model_->index(i, 0, parent_index);
201  Property* child = model_->getProp(child_index);
202  QString child_name = child->getName();
203  if (qobject_cast<StatusList*>(child))
204  {
205  child_name = "Status";
206  }
207  int name_occurrence = ++(name_counts[child_name]);
208  QString full_name = prefix + "/" + child_name + QString::number(name_occurrence);
209  if (expanded_full_names.contains(full_name))
210  {
211  setExpanded(child_index, true);
212  }
213  expandEntries(expanded_full_names, child_index, full_name);
214  }
215  }
216 }
217 
218 } // end namespace rviz
rviz::PropertySelectionModel::setCurrentIndex
void setCurrentIndex(const QModelIndex &index, QItemSelectionModel::SelectionFlags command) override
Definition: property_tree_widget.cpp:48
rviz::PropertyTreeModel::expand
void expand(const QModelIndex &index)
Emitted when a Property wants to expand (display its children).
rviz::PropertyTreeDelegate
Definition: property_tree_delegate.h:36
rviz::PropertyTreeModel::collapse
void collapse(const QModelIndex &index)
Emitted when a Property wants to collapse (hide its children).
rviz::SplitterHandle::setRatio
void setRatio(float ratio)
Set the ratio of the parent's left column to the parent widget width.
Definition: splitter_handle.cpp:97
rviz::PropertyTreeModel
Definition: property_tree_model.h:38
rviz::PropertyTreeWidget::load
void load(const Config &config)
Read state from the given Config.
Definition: property_tree_widget.cpp:172
status_list.h
property.h
command
ROSLIB_DECL std::string command(const std::string &cmd)
rviz::PropertyTreeWidget::propertyHiddenChanged
virtual void propertyHiddenChanged(const Property *property)
Definition: property_tree_widget.cpp:122
rviz::PropertyTreeWidget::selectionChanged
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override
Called whenever selection changes. Calls QTreeView implementation then emits selectionHasChanged().
Definition: property_tree_widget.cpp:88
rviz::PropertyTreeModel::getProp
Property * getProp(const QModelIndex &index) const
return the Property at the given index, or the root property if the index is invalid.
Definition: property_tree_model.cpp:53
rviz::PropertyTreeWidget::model_
PropertyTreeModel * model_
Definition: property_tree_widget.h:135
rviz::PropertyTreeWidget::PropertyTreeWidget
PropertyTreeWidget(QWidget *parent=nullptr)
Definition: property_tree_widget.cpp:62
rviz::PropertyTreeWidget::currentPropertyChanged
void currentPropertyChanged(const Property *new_current_property)
rviz::PropertySelectionModel
Definition: property_tree_widget.h:46
rviz::Config::listLength
int listLength() const
Returns the length of the List in this Node, or 0 if this Node does not have type List.
Definition: config.cpp:324
rviz::PropertyTreeModel::parentIndex
QModelIndex parentIndex(const Property *child) const
Same as parent() but taking a Property pointer instead of an index.
Definition: property_tree_model.cpp:105
rviz::PropertyTreeWidget::expandEntries
void expandEntries(const QSet< QString > &expanded_full_names, const QModelIndex &parent_index, const QString &prefix)
Recursively expand entries whose full names appear in expanded_full_names.
Definition: property_tree_widget.cpp:190
rviz::PropertyTreeWidget::splitter_handle_
SplitterHandle * splitter_handle_
Definition: property_tree_widget.h:136
rviz::PropertyTreeModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Return the number of rows under the given parent index.
Definition: property_tree_model.cpp:115
rviz::PropertyTreeModel::propertyHiddenChanged
void propertyHiddenChanged(const Property *property)
Emitted when a property within the model is hidden or shown.
rviz::Property
A single element of a property tree, with a name, value, description, and possibly children.
Definition: property.h:100
console.h
ROS_WARN_STREAM
#define ROS_WARN_STREAM(args)
update
void update(const std::string &key, const XmlRpc::XmlRpcValue &v)
rviz
Definition: add_display_dialog.cpp:54
property_tree_delegate.h
rviz::SplitterHandle
A tall skinny invisible widget providing left-right sliding column separator adjustment for a two-col...
Definition: splitter_handle.h:44
rviz::SplitterHandle::getRatio
float getRatio()
Get the ratio of the parent's left column to the parent widget width.
Definition: splitter_handle.cpp:103
rviz::Property::getHidden
virtual bool getHidden() const
Return the hidden/shown state. True means hidden, false means visible.
Definition: property.h:485
rviz::PropertyTreeWidget::setModel
void setModel(PropertyTreeModel *model)
Set the data model this widget should view.
Definition: property_tree_widget.cpp:95
rviz::PropertyTreeModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
Definition: property_tree_model.cpp:76
rviz::PropertyTreeModel::getRoot
Property * getRoot() const
Definition: property_tree_model.h:114
property_tree_widget.h
rviz::PropertyTreeWidget::selectionHasChanged
void selectionHasChanged()
rviz::PropertyTreeWidget::save
void save(Config config) const
Write state to the given Config.
Definition: property_tree_widget.cpp:135
rviz::Property::rowNumberInParent
int rowNumberInParent() const
Return the row number of this property within its parent, or -1 if it has no parent.
Definition: property.cpp:424
rviz::Property::getName
virtual QString getName() const
Return the name of this Property as a QString.
Definition: property.cpp:164
rviz::Config::listChildAt
Config listChildAt(int i) const
Return the i'th child in the list, if the referenced Node has type List. Returns an Invalid Config if...
Definition: config.cpp:329
rviz::PropertyTreeWidget::saveExpandedEntries
void saveExpandedEntries(Config config, const QModelIndex &parent_index, const QString &prefix) const
Recursively write full names of properties which are expanded in this view to the given Config.
Definition: property_tree_widget.cpp:142
splitter_handle.h
rviz::PropertyTreeWidget::currentChanged
void currentChanged(const QModelIndex &current, const QModelIndex &previous) override
Called whenever current item changes. Calls QTreeView implementation then emits currentPropertyChange...
Definition: property_tree_widget.cpp:81
config
config
rviz::Property::getModel
PropertyTreeModel * getModel() const
Return the model managing this Property and its childrent.
Definition: property.h:416
rviz::Config
Configuration data storage class.
Definition: config.h:124
rviz::Property::setModel
void setModel(PropertyTreeModel *model)
Set the model managing this Property and all its child properties, recursively.
Definition: property.cpp:394
rviz::Config::getValue
QVariant getValue() const
If this config object is valid and is a Value type, this returns its value. Otherwise it returns an i...
Definition: config.cpp:319
rviz::PropertySelectionModel::PropertySelectionModel
PropertySelectionModel(QAbstractItemModel *model=nullptr)
Definition: property_tree_widget.cpp:44


rviz
Author(s): Dave Hershberger, David Gossow, Josh Faust, William Woodall
autogenerated on Thu May 16 2024 02:30:49