MessageFieldTreeWidget.cpp
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (C) 2015 by Ralf Kaestner *
3  * ralf.kaestner@gmail.com *
4  * *
5  * This program is free software; you can redistribute it and/or modify *
6  * it under the terms of the Lesser GNU General Public License as published by*
7  * the Free Software Foundation; either version 3 of the License, or *
8  * (at your option) any later version. *
9  * *
10  * This program is distributed in the hope that it will be useful, *
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13  * Lesser GNU General Public License for more details. *
14  * *
15  * You should have received a copy of the Lesser GNU General Public License *
16  * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17  ******************************************************************************/
18 
19 #include <limits>
20 
21 #include <QHeaderView>
22 #include <QSpinBox>
23 
24 #include <variant_topic_tools/MessageVariable.h>
25 
27 
28 Q_DECLARE_METATYPE(variant_topic_tools::DataType)
29 
30 namespace rqt_multiplot {
31 
32 /*****************************************************************************/
33 /* Constructors and Destructor */
34 /*****************************************************************************/
35 
36 MessageFieldTreeWidget::MessageFieldTreeWidget(QWidget* parent) :
37  QTreeWidget(parent) {
38  setColumnCount(2);
39  headerItem()->setText(0, "Name");
40  headerItem()->setText(1, "Type");
41 
42 #if QT_VERSION >= 0x050000
43  header()->setSectionResizeMode(QHeaderView::ResizeToContents);
44 #else
45  header()->setResizeMode(QHeaderView::ResizeToContents);
46 #endif
47 
48  connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,
49  QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*,
50  QTreeWidgetItem*)));
51 }
52 
54 }
55 
56 /*****************************************************************************/
57 /* Accessors */
58 /*****************************************************************************/
59 
60 void MessageFieldTreeWidget::setMessageDataType(const variant_topic_tools::
61  MessageDataType& dataType) {
62  clear();
63 
64  blockSignals(true);
65  invisibleRootItem()->setData(1, Qt::UserRole, QVariant::
66  fromValue<variant_topic_tools::DataType>(dataType));
67  for (size_t i = 0; i < dataType.getNumVariableMembers(); ++i)
68  addField(dataType.getVariableMember(i));
69  blockSignals(false);
70 
71  if (!currentField_.isEmpty())
73 }
74 
75 variant_topic_tools::MessageDataType MessageFieldTreeWidget::
77  QTreeWidgetItem* item = invisibleRootItem();
78 
79  if (item)
80  return item->data(1, Qt::UserRole).value<variant_topic_tools::DataType>();
81  else
82  return variant_topic_tools::DataType();
83 }
84 
85 void MessageFieldTreeWidget::setCurrentField(const QString& field) {
86  if (field != currentField_) {
87  currentField_ = field;
88 
89  setCurrentItem(field);
90 
91  emit currentFieldChanged(field);
92  }
93 }
94 
96  return currentField_;
97 }
98 
99 variant_topic_tools::DataType MessageFieldTreeWidget::
101  QTreeWidgetItem* item = currentItem();
102 
103  if (item)
104  return item->data(1, Qt::UserRole).value<variant_topic_tools::DataType>();
105  else
106  return variant_topic_tools::DataType();
107 }
108 
110  return getCurrentFieldDataType().isValid();
111 }
112 
113 void MessageFieldTreeWidget::setCurrentItem(const QString& field) {
114  QTreeWidgetItem* item = invisibleRootItem();
115  QStringList fields = field.split("/");
116 
117  while (item && !fields.isEmpty()) {
118  QVariant itemData = item->data(1, Qt::UserRole);
119 
120  if (itemData.isValid()) {
121  variant_topic_tools::DataType fieldType = itemData.
122  value<variant_topic_tools::DataType>();
123 
124  if (fieldType.isMessage()) {
125  QTreeWidgetItem* childItem = findChild(item, 0, fields.front());
126 
127  if (childItem) {
128  item = childItem;
129  fields.removeFirst();
130 
131  continue;
132  }
133  }
134  else if (fieldType.isArray()) {
135  bool indexOkay = false;
136  size_t index = fields.front().toUInt(&indexOkay);
137  QSpinBox* spinBoxIndex = static_cast<QSpinBox*>(
138  itemWidget(item->child(0), 0));
139 
140  if (indexOkay && (index < spinBoxIndex->maximum())) {
141  spinBoxIndex->blockSignals(true);
142  spinBoxIndex->setValue(index);
143  spinBoxIndex->blockSignals(false);
144 
145  item = item->child(0);
146  fields.removeFirst();
147 
148  continue;
149  }
150  }
151  }
152 
153  item = invisibleRootItem();
154  break;
155  }
156 
157  blockSignals(true);
158  QTreeWidget::setCurrentItem(item);
159  blockSignals(false);
160 }
161 
162 /*****************************************************************************/
163 /* Methods */
164 /*****************************************************************************/
165 
166 void MessageFieldTreeWidget::addField(const variant_topic_tools::
167  MessageVariable& variable, QTreeWidgetItem* parent) {
168  QTreeWidgetItem* item = new QTreeWidgetItem();
169 
170  item->setText(0, QString::fromStdString(variable.getName()));
171  item->setText(1, QString::fromStdString(variable.getType().
172  getIdentifier()));
173  item->setData(1, Qt::UserRole, QVariant::fromValue(variable.getType()));
174  item->setFlags(Qt::ItemIsEnabled);
175 
176  QFont typeFont = item->font(1);
177  typeFont.setItalic(true);
178  item->setFont(1, typeFont);
179 
180  if (parent)
181  parent->addChild(item);
182  else
183  addTopLevelItem(item);
184 
185  if (variable.getType().isMessage()) {
186  variant_topic_tools::MessageDataType messageType = variable.getType();
187 
188  for (size_t i = 0; i < messageType.getNumVariableMembers(); ++i)
189  addField(messageType.getVariableMember(i), item);
190  }
191  else if (variable.getType().isArray()) {
192  variant_topic_tools::ArrayDataType arrayType = variable.getType();
193 
194  QSpinBox* spinBoxIndex = new QSpinBox(this);
195  spinBoxIndex->setMinimum(0);
196  if (!arrayType.isDynamic())
197  spinBoxIndex->setMaximum(arrayType.getNumMembers()-1);
198  else
199  spinBoxIndex->setMaximum(std::numeric_limits<int>::max());
200  spinBoxIndex->setFrame(false);
201 
202  connect(spinBoxIndex, SIGNAL(valueChanged(int)), this,
203  SLOT(spinBoxIndexValueChanged(int)));
204 
205  QTreeWidgetItem* memberItem = new QTreeWidgetItem();
206  memberItem->setText(1, QString::fromStdString(arrayType.getMemberType().
207  getIdentifier()));
208  memberItem->setData(1, Qt::UserRole, QVariant::fromValue(arrayType.
209  getMemberType()));
210  memberItem->setFlags(Qt::ItemIsEnabled);
211 
212  QFont memberTypeFont = memberItem->font(1);
213  memberTypeFont.setItalic(true);
214  memberItem->setFont(1, memberTypeFont);
215 
216  item->addChild(memberItem);
217  setItemWidget(memberItem, 0, spinBoxIndex);
218 
219  if (arrayType.getMemberType().isMessage()) {
220  variant_topic_tools::MessageDataType messageMemberType = arrayType.
221  getMemberType();
222 
223  for (size_t i = 0; i < messageMemberType.getNumVariableMembers(); ++i)
224  addField(messageMemberType.getVariableMember(i), memberItem);
225  }
226  else if (arrayType.getMemberType().isBuiltin()) {
227  variant_topic_tools::BuiltinDataType builtinMemberType = arrayType.
228  getMemberType();
229 
230  if (builtinMemberType.isNumeric())
231  memberItem->setFlags(memberItem->flags() | Qt::ItemIsSelectable);
232  }
233  }
234  else if (variable.getType().isBuiltin()) {
235  variant_topic_tools::BuiltinDataType builtinType = variable.getType();
236 
237  if (builtinType.isNumeric())
238  item->setFlags(item->flags() | Qt::ItemIsSelectable);
239  }
240 }
241 
242 QTreeWidgetItem* MessageFieldTreeWidget::findChild(QTreeWidgetItem* item,
243  int column, const QString& text) const {
244  for (size_t i = 0; i < item->childCount(); ++i) {
245  if (item->child(i)->text(column) == text)
246  return item->child(i);
247  }
248 
249  return 0;
250 }
251 
252 /*****************************************************************************/
253 /* Slots */
254 /*****************************************************************************/
255 
256 void MessageFieldTreeWidget::currentItemChanged(QTreeWidgetItem* current,
257  QTreeWidgetItem* previous) {
258  QString field;
259 
260  while (current) {
261  QString text = current->text(0);
262 
263  if (text.isEmpty()) {
264  QSpinBox* spinBoxIndex = static_cast<QSpinBox*>(
265  itemWidget(current, 0));
266 
267  text = QString::number(spinBoxIndex->value());
268  }
269 
270  if (!field.isEmpty())
271  field = text+"/"+field;
272  else
273  field = text;
274 
275  current = current->parent();
276  }
277 
278  setCurrentField(field);
279 }
280 
282  currentItemChanged(currentItem(), currentItem());
283 }
284 
285 }
void currentFieldChanged(const QString &field)
void setMessageDataType(const variant_topic_tools::MessageDataType &dataType)
void addField(const variant_topic_tools::MessageVariable &variable, QTreeWidgetItem *parent=0)
variant_topic_tools::DataType getCurrentFieldDataType() const
variant_topic_tools::MessageDataType getMessageDataType() const
QTreeWidgetItem * findChild(QTreeWidgetItem *item, int column, const QString &text) const
const std::string header
void currentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)


rqt_multiplot
Author(s): Ralf Kaestner
autogenerated on Wed Jul 10 2019 03:49:44