$search
00001 /* 00002 * Copyright (c) 2011, 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 "rxparamedit/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