xmlRpcModel.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2015, C. Dornhege, University of Freiburg
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  *
00008  *  * Redistributions of source code must retain the above copyright notice, this
00009  *    list of conditions and the following disclaimer.
00010  *  * Redistributions in binary form must reproduce the above copyright notice, 
00011  *    this list of conditions and the following disclaimer in the documentation 
00012  *    and/or other materials provided with the distribution.
00013  *  * Neither the name of the University of Freiburg nor the names
00014  *    of its contributors may be used to endorse or promote products derived from
00015  *    this software without specific prior written permission.
00016  * 
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00023  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00024  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00025  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00026  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00029 #include "qt_paramedit/xmlRpcModel.h"
00030 
00031 XmlRpcModel::XmlRpcModel(XmlRpc::XmlRpcValue* rootData, const std::string & rootPath, ros::NodeHandle* nh)
00032 {
00033    _root = new XmlRpcTreeItem(rootData, NULL, rootPath, nh);
00034    _maxDisplayLength = 120;
00035 }
00036 
00037 XmlRpcModel::~XmlRpcModel()
00038 {
00039    delete _root;
00040 }
00041  
00042 QModelIndex XmlRpcModel::index(int row, int column, const QModelIndex & parent) const
00043 {
00044    if(!parent.isValid()) {
00045       return createIndex(row, column, _root);
00046    }
00047 
00048    XmlRpcTreeItem* parentItem = static_cast<XmlRpcTreeItem*>(parent.internalPointer());
00049    // parent points to the (parent.row, parent.column) child of parentItem and its corresponding tree node
00050    // We want to create a child of that.
00051    // First check if that (parent.row, parent.column) child of parentItem can be a parent for an index again
00052    // Only items in the first column can be parents
00053    if(parent.column() > 0)
00054       return QModelIndex();
00055    // Lookup that child item and use it as parent for the new index
00056    XmlRpcTreeItem* childItem = parentItem->child(parent.row());
00057    if(childItem) {
00058       // only items with children can be parents
00059       if(childItem->childCount() == 0)
00060          return QModelIndex();
00061       // create an index referring to the (row, column) child of childItem
00062       return createIndex(row, column, childItem);
00063    } else {
00064       return QModelIndex();
00065    }
00066 }
00067 
00068 QModelIndex XmlRpcModel::parent(const QModelIndex & index) const
00069 {
00070    if(!index.isValid())
00071       return QModelIndex();
00072 
00073    XmlRpcTreeItem* childItem = static_cast<XmlRpcTreeItem*>(index.internalPointer());
00074    XmlRpcTreeItem* parentItem = childItem->parent();
00075 
00076    // top level
00077    if(parentItem == NULL)
00078       return QModelIndex();
00079 
00080    return createIndex(childItem->row(), 0, parentItem);
00081 }
00082 
00083 Qt::ItemFlags XmlRpcModel::flags(const QModelIndex & index) const
00084 {
00085    if(!index.isValid())
00086       return 0;
00087 
00088    if(index.column() == 1) {     // right sides of inner nodes have no flags
00089       XmlRpcTreeItem *parentItem = static_cast<XmlRpcTreeItem*>(index.internalPointer());
00090       XmlRpcTreeItem *item = parentItem->child(index.row());
00091       // index points to index.rows child of parentItem
00092       if(item && item->childCount() > 0) {
00093          return 0;
00094       }
00095    }
00096 
00097    Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00098 
00099    if(index.column() == 1) {  // right side = value, editable
00100       // if the data is bool make it checkable
00101       XmlRpcTreeItem *item = static_cast<XmlRpcTreeItem*>(index.internalPointer());
00102       if(item->isBool(index.row(), index.column())) {
00103          flags |= Qt::ItemIsUserCheckable;
00104       } else {
00105          flags |= Qt::ItemIsEditable;
00106       }
00107    }
00108 
00109    return flags;
00110 }
00111 
00112 QVariant XmlRpcModel::data(const QModelIndex & index, int role) const
00113 {
00114    if (!index.isValid())
00115       return QVariant();
00116 
00117    //printf("data() Role is %d\n", role);
00118    if(role != Qt::DisplayRole && role != Qt::CheckStateRole && role != Qt::EditRole)
00119       return QVariant();
00120 
00121    XmlRpcTreeItem* item = static_cast<XmlRpcTreeItem*>(index.internalPointer());
00122 
00123    if(role == Qt::CheckStateRole) {    // only valid for bools
00124       if(!item->isBool(index.row(), index.column()))
00125          return QVariant();
00126       //printf("RET IS %d", item->data(index.row(), index.column()).toBool());
00127 
00128       // for bool values in CheckStateRole return Qt::Checked/Unchecked instead of true/false
00129       return item->data(index.row(), index.column()).toBool() ? Qt::Checked : Qt::Unchecked;
00130    }
00131 
00132    if(role == Qt::DisplayRole) { // no text for bools
00133       if(item->isBool(index.row(), index.column()))
00134          return QVariant();
00135       else {
00136         QVariant itemDisplay = item->data(index.row(), index.column());
00137         if(itemDisplay.type() != QVariant::String) {
00138           return itemDisplay;
00139         }
00140         // convert here to string to check _maxDisplayLength
00141         QString itemStr = itemDisplay.toString();
00142         unsigned int maxLength = _maxDisplayLength;
00143         if(maxLength < 3)
00144           maxLength = 3;
00145         if(itemStr.length() > (int)maxLength) {
00146           itemStr = itemStr.mid(0, maxLength - 3) + "...";
00147         }
00148         return itemStr;
00149       }
00150    }
00151 
00152    if(role == Qt::EditRole) {
00153       return item->data(index.row(), index.column());
00154    }
00155 
00156    // never called
00157    return QVariant();
00158 }
00159 
00160 bool XmlRpcModel::setData(const QModelIndex & index, const QVariant & value, int role)
00161 {
00162    if(!index.isValid())
00163       return false;
00164    if(role != Qt::EditRole && role != Qt::CheckStateRole)
00165       return false;
00166 
00167    if(index.column() != 1)
00168       return false;
00169 
00170    XmlRpcTreeItem* parentItem = static_cast<XmlRpcTreeItem*>(index.internalPointer());
00171    if(parentItem->isBool(index.row(), index.column())) {
00172       if(role == Qt::EditRole)
00173          return false;
00174    }
00175    if(!parentItem->isBool(index.row(), index.column())) {
00176       if(role == Qt::CheckStateRole)
00177          return false;
00178    }
00179 
00180    XmlRpcTreeItem* item = parentItem->child(index.row());
00181 
00182    // this should always be a leaf, never a struct!
00183    if(item->setData(value)) {
00184       Q_EMIT dataChanged(index, index);
00185       return true;
00186    }
00187 
00188    return false;
00189 }
00190 
00191 QVariant XmlRpcModel::headerData(int section, Qt::Orientation orientation, int role) const
00192 {
00193    if(role != Qt::DisplayRole || orientation != Qt::Horizontal)
00194       return QVariant();
00195 
00196    if(section == 0)
00197       return "Parameter";
00198    if(section == 1)
00199       return "Value";
00200 
00201    return QVariant();
00202 }
00203 
00204 int XmlRpcModel::rowCount(const QModelIndex & parent) const
00205 {
00206    if(!parent.isValid()) {
00207       return _root->childCount();
00208    } 
00209 
00210    if(parent.column() > 0)
00211       return 0;
00212 
00213    // parent refers to the parent.row'th child of parentItem
00214    // get that item
00215    XmlRpcTreeItem* parentItem = static_cast<XmlRpcTreeItem*>(parent.internalPointer());
00216    XmlRpcTreeItem* item = parentItem->child(parent.row());
00217 
00218    if(item == NULL)
00219       return 0;
00220    return item->childCount();
00221 }
00222 
00223 int XmlRpcModel::columnCount(const QModelIndex & parent) const
00224 {
00225    if(!parent.isValid()) {
00226       if(_root->childCount() > 0)
00227          return 2;
00228       return 0;
00229    }
00230 
00231    if(parent.column() > 0)
00232       return 0;
00233 
00234    // parent is the parent.row'th child of parentItem
00235    // get that item
00236    XmlRpcTreeItem* parentItem = static_cast<XmlRpcTreeItem*>(parent.internalPointer());
00237    XmlRpcTreeItem* item = parentItem->child(parent.row());
00238 
00239    if(item == NULL)
00240       return 0;
00241 
00242    // with children we address 0->name 1->value
00243    if(item->childCount() > 0)
00244       return 2;
00245    return 0;
00246 }
00247 


qt_paramedit
Author(s): Christian Dornhege
autogenerated on Fri Aug 28 2015 12:50:12