MessageFieldTreeWidget.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  * Copyright (C) 2015 by Ralf Kaestner                                        *
00003  * ralf.kaestner@gmail.com                                                    *
00004  *                                                                            *
00005  * This program is free software; you can redistribute it and/or modify       *
00006  * it under the terms of the Lesser GNU General Public License as published by*
00007  * the Free Software Foundation; either version 3 of the License, or          *
00008  * (at your option) any later version.                                        *
00009  *                                                                            *
00010  * This program is distributed in the hope that it will be useful,            *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               *
00013  * Lesser GNU General Public License for more details.                        *
00014  *                                                                            *
00015  * You should have received a copy of the Lesser GNU General Public License   *
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>.       *
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 /* Constructors and Destructor                                               */
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 /* Accessors                                                                 */
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 /* Methods                                                                   */
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 /* Slots                                                                     */
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 }


rqt_multiplot
Author(s): Ralf Kaestner
autogenerated on Tue May 9 2017 02:16:02