Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <limits>
00020
00021 #include <QHeaderView>
00022 #include <QSpinBox>
00023
00024 #include <variant_topic_tools/MessageVariable.h>
00025
00026 #include "rqt_multiplot/MessageFieldTreeWidget.h"
00027
00028 Q_DECLARE_METATYPE(variant_topic_tools::DataType)
00029
00030 namespace rqt_multiplot {
00031
00032
00033
00034
00035
00036 MessageFieldTreeWidget::MessageFieldTreeWidget(QWidget* parent) :
00037 QTreeWidget(parent) {
00038 setColumnCount(2);
00039 headerItem()->setText(0, "Name");
00040 headerItem()->setText(1, "Type");
00041
00042 #if QT_VERSION >= 0x050000
00043 header()->setSectionResizeMode(QHeaderView::ResizeToContents);
00044 #else
00045 header()->setResizeMode(QHeaderView::ResizeToContents);
00046 #endif
00047
00048 connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem*,
00049 QTreeWidgetItem*)), this, SLOT(currentItemChanged(QTreeWidgetItem*,
00050 QTreeWidgetItem*)));
00051 }
00052
00053 MessageFieldTreeWidget::~MessageFieldTreeWidget() {
00054 }
00055
00056
00057
00058
00059
00060 void MessageFieldTreeWidget::setMessageDataType(const variant_topic_tools::
00061 MessageDataType& dataType) {
00062 clear();
00063
00064 blockSignals(true);
00065 invisibleRootItem()->setData(1, Qt::UserRole, QVariant::
00066 fromValue<variant_topic_tools::DataType>(dataType));
00067 for (size_t i = 0; i < dataType.getNumVariableMembers(); ++i)
00068 addField(dataType.getVariableMember(i));
00069 blockSignals(false);
00070
00071 if (!currentField_.isEmpty())
00072 setCurrentItem(currentField_);
00073 }
00074
00075 variant_topic_tools::MessageDataType MessageFieldTreeWidget::
00076 getMessageDataType() const {
00077 QTreeWidgetItem* item = invisibleRootItem();
00078
00079 if (item)
00080 return item->data(1, Qt::UserRole).value<variant_topic_tools::DataType>();
00081 else
00082 return variant_topic_tools::DataType();
00083 }
00084
00085 void MessageFieldTreeWidget::setCurrentField(const QString& field) {
00086 if (field != currentField_) {
00087 currentField_ = field;
00088
00089 setCurrentItem(field);
00090
00091 emit currentFieldChanged(field);
00092 }
00093 }
00094
00095 QString MessageFieldTreeWidget::getCurrentField() const {
00096 return currentField_;
00097 }
00098
00099 variant_topic_tools::DataType MessageFieldTreeWidget::
00100 getCurrentFieldDataType() const {
00101 QTreeWidgetItem* item = currentItem();
00102
00103 if (item)
00104 return item->data(1, Qt::UserRole).value<variant_topic_tools::DataType>();
00105 else
00106 return variant_topic_tools::DataType();
00107 }
00108
00109 bool MessageFieldTreeWidget::isCurrentFieldDefined() const {
00110 return getCurrentFieldDataType().isValid();
00111 }
00112
00113 void MessageFieldTreeWidget::setCurrentItem(const QString& field) {
00114 QTreeWidgetItem* item = invisibleRootItem();
00115 QStringList fields = field.split("/");
00116
00117 while (item && !fields.isEmpty()) {
00118 QVariant itemData = item->data(1, Qt::UserRole);
00119
00120 if (itemData.isValid()) {
00121 variant_topic_tools::DataType fieldType = itemData.
00122 value<variant_topic_tools::DataType>();
00123
00124 if (fieldType.isMessage()) {
00125 QTreeWidgetItem* childItem = findChild(item, 0, fields.front());
00126
00127 if (childItem) {
00128 item = childItem;
00129 fields.removeFirst();
00130
00131 continue;
00132 }
00133 }
00134 else if (fieldType.isArray()) {
00135 bool indexOkay = false;
00136 size_t index = fields.front().toUInt(&indexOkay);
00137 QSpinBox* spinBoxIndex = static_cast<QSpinBox*>(
00138 itemWidget(item->child(0), 0));
00139
00140 if (indexOkay && (index < spinBoxIndex->maximum())) {
00141 spinBoxIndex->blockSignals(true);
00142 spinBoxIndex->setValue(index);
00143 spinBoxIndex->blockSignals(false);
00144
00145 item = item->child(0);
00146 fields.removeFirst();
00147
00148 continue;
00149 }
00150 }
00151 }
00152
00153 item = invisibleRootItem();
00154 break;
00155 }
00156
00157 blockSignals(true);
00158 QTreeWidget::setCurrentItem(item);
00159 blockSignals(false);
00160 }
00161
00162
00163
00164
00165
00166 void MessageFieldTreeWidget::addField(const variant_topic_tools::
00167 MessageVariable& variable, QTreeWidgetItem* parent) {
00168 QTreeWidgetItem* item = new QTreeWidgetItem();
00169
00170 item->setText(0, QString::fromStdString(variable.getName()));
00171 item->setText(1, QString::fromStdString(variable.getType().
00172 getIdentifier()));
00173 item->setData(1, Qt::UserRole, QVariant::fromValue(variable.getType()));
00174 item->setFlags(Qt::ItemIsEnabled);
00175
00176 QFont typeFont = item->font(1);
00177 typeFont.setItalic(true);
00178 item->setFont(1, typeFont);
00179
00180 if (parent)
00181 parent->addChild(item);
00182 else
00183 addTopLevelItem(item);
00184
00185 if (variable.getType().isMessage()) {
00186 variant_topic_tools::MessageDataType messageType = variable.getType();
00187
00188 for (size_t i = 0; i < messageType.getNumVariableMembers(); ++i)
00189 addField(messageType.getVariableMember(i), item);
00190 }
00191 else if (variable.getType().isArray()) {
00192 variant_topic_tools::ArrayDataType arrayType = variable.getType();
00193
00194 QSpinBox* spinBoxIndex = new QSpinBox(this);
00195 spinBoxIndex->setMinimum(0);
00196 if (!arrayType.isDynamic())
00197 spinBoxIndex->setMaximum(arrayType.getNumMembers()-1);
00198 else
00199 spinBoxIndex->setMaximum(std::numeric_limits<int>::max());
00200 spinBoxIndex->setFrame(false);
00201
00202 connect(spinBoxIndex, SIGNAL(valueChanged(int)), this,
00203 SLOT(spinBoxIndexValueChanged(int)));
00204
00205 QTreeWidgetItem* memberItem = new QTreeWidgetItem();
00206 memberItem->setText(1, QString::fromStdString(arrayType.getMemberType().
00207 getIdentifier()));
00208 memberItem->setData(1, Qt::UserRole, QVariant::fromValue(arrayType.
00209 getMemberType()));
00210 memberItem->setFlags(Qt::ItemIsEnabled);
00211
00212 QFont memberTypeFont = memberItem->font(1);
00213 memberTypeFont.setItalic(true);
00214 memberItem->setFont(1, memberTypeFont);
00215
00216 item->addChild(memberItem);
00217 setItemWidget(memberItem, 0, spinBoxIndex);
00218
00219 if (arrayType.getMemberType().isMessage()) {
00220 variant_topic_tools::MessageDataType messageMemberType = arrayType.
00221 getMemberType();
00222
00223 for (size_t i = 0; i < messageMemberType.getNumVariableMembers(); ++i)
00224 addField(messageMemberType.getVariableMember(i), memberItem);
00225 }
00226 else if (arrayType.getMemberType().isBuiltin()) {
00227 variant_topic_tools::BuiltinDataType builtinMemberType = arrayType.
00228 getMemberType();
00229
00230 if (builtinMemberType.isNumeric())
00231 memberItem->setFlags(memberItem->flags() | Qt::ItemIsSelectable);
00232 }
00233 }
00234 else if (variable.getType().isBuiltin()) {
00235 variant_topic_tools::BuiltinDataType builtinType = variable.getType();
00236
00237 if (builtinType.isNumeric())
00238 item->setFlags(item->flags() | Qt::ItemIsSelectable);
00239 }
00240 }
00241
00242 QTreeWidgetItem* MessageFieldTreeWidget::findChild(QTreeWidgetItem* item,
00243 int column, const QString& text) const {
00244 for (size_t i = 0; i < item->childCount(); ++i) {
00245 if (item->child(i)->text(column) == text)
00246 return item->child(i);
00247 }
00248
00249 return 0;
00250 }
00251
00252
00253
00254
00255
00256 void MessageFieldTreeWidget::currentItemChanged(QTreeWidgetItem* current,
00257 QTreeWidgetItem* previous) {
00258 QString field;
00259
00260 while (current) {
00261 QString text = current->text(0);
00262
00263 if (text.isEmpty()) {
00264 QSpinBox* spinBoxIndex = static_cast<QSpinBox*>(
00265 itemWidget(current, 0));
00266
00267 text = QString::number(spinBoxIndex->value());
00268 }
00269
00270 if (!field.isEmpty())
00271 field = text+"/"+field;
00272 else
00273 field = text;
00274
00275 current = current->parent();
00276 }
00277
00278 setCurrentField(field);
00279 }
00280
00281 void MessageFieldTreeWidget::spinBoxIndexValueChanged(int value) {
00282 currentItemChanged(currentItem(), currentItem());
00283 }
00284
00285 }