$search
00001 /* 00002 Aseba - an event-based framework for distributed robot control 00003 Copyright (C) 2007--2012: 00004 Stephane Magnenat <stephane at magnenat dot net> 00005 (http://stephane.magnenat.net) 00006 and other contributors, see authors.txt for details 00007 00008 This program is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU Lesser General Public License as published 00010 by the Free Software Foundation, version 3 of the License. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include "NamedValuesVectorModel.h" 00022 #include <QtDebug> 00023 #include <QtGui> 00024 00025 #include <NamedValuesVectorModel.moc> 00026 00027 namespace Aseba 00028 { 00031 00032 NamedValuesVectorModel::NamedValuesVectorModel(NamedValuesVector* namedValues, const QString &tooltipText, QObject *parent) : 00033 QAbstractTableModel(parent), 00034 namedValues(namedValues), 00035 wasModified(false), 00036 tooltipText(tooltipText), 00037 editable(false) 00038 { 00039 Q_ASSERT(namedValues); 00040 } 00041 00042 NamedValuesVectorModel::NamedValuesVectorModel(NamedValuesVector* namedValues, QObject *parent) : 00043 QAbstractTableModel(parent), 00044 namedValues(namedValues), 00045 wasModified(false), 00046 editable(false) 00047 { 00048 Q_ASSERT(namedValues); 00049 } 00050 00051 int NamedValuesVectorModel::rowCount(const QModelIndex & parent) const 00052 { 00053 Q_UNUSED(parent) 00054 return namedValues->size(); 00055 } 00056 00057 int NamedValuesVectorModel::columnCount(const QModelIndex & parent) const 00058 { 00059 Q_UNUSED(parent) 00060 return 2; 00061 } 00062 00063 QVariant NamedValuesVectorModel::data(const QModelIndex &index, int role) const 00064 { 00065 if (!index.isValid()) 00066 return QVariant(); 00067 00068 if (role == Qt::DisplayRole) 00069 { 00070 if (index.column() == 0) 00071 return QString::fromStdWString(namedValues->at(index.row()).name); 00072 else 00073 return namedValues->at(index.row()).value; 00074 } 00075 else if (role == Qt::ToolTipRole && !tooltipText.isEmpty()) 00076 { 00077 return tooltipText.arg(index.row()); 00078 } 00079 else 00080 return QVariant(); 00081 } 00082 00083 QVariant NamedValuesVectorModel::headerData(int section, Qt::Orientation orientation, int role) const 00084 { 00085 Q_UNUSED(section) 00086 Q_UNUSED(orientation) 00087 Q_UNUSED(role) 00088 return QVariant(); 00089 } 00090 00091 Qt::ItemFlags NamedValuesVectorModel::flags(const QModelIndex & index) const 00092 { 00093 if (!index.isValid()) 00094 return Qt::ItemIsDropEnabled; 00095 00096 Qt::ItemFlags commonFlags = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled; 00097 if (index.column() == 0) 00098 { 00099 if (editable) 00100 return commonFlags | Qt::ItemIsEditable; 00101 else 00102 return commonFlags; 00103 } 00104 else 00105 return commonFlags | Qt::ItemIsEditable; 00106 } 00107 00108 QStringList NamedValuesVectorModel::mimeTypes () const 00109 { 00110 QStringList types; 00111 types << "text/plain"; 00112 if (privateMimeType != "") 00113 types << privateMimeType; 00114 return types; 00115 } 00116 00117 QMimeData * NamedValuesVectorModel::mimeData ( const QModelIndexList & indexes ) const 00118 { 00119 QMimeData *mimeData = new QMimeData(); 00120 00121 // "text/plain" 00122 QString texts; 00123 foreach (QModelIndex index, indexes) 00124 { 00125 if (index.isValid() && (index.column() == 0)) 00126 { 00127 QString text = data(index, Qt::DisplayRole).toString(); 00128 texts += text; 00129 } 00130 } 00131 mimeData->setText(texts); 00132 00133 if (privateMimeType == "") 00134 return mimeData; 00135 00136 // privateMimeType 00137 QByteArray itemData; 00138 QDataStream dataStream(&itemData, QIODevice::WriteOnly); 00139 foreach (QModelIndex itemIndex, indexes) 00140 { 00141 if (!itemIndex.isValid()) 00142 continue; 00143 QString name = data(index(itemIndex.row(), 0), Qt::DisplayRole).toString(); 00144 int nbArgs = data(index(itemIndex.row(), 1), Qt::DisplayRole).toInt(); 00145 dataStream << name << nbArgs; 00146 } 00147 mimeData->setData(privateMimeType, itemData); 00148 00149 return mimeData; 00150 } 00151 00152 bool NamedValuesVectorModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent) 00153 { 00154 if (action == Qt::IgnoreAction) 00155 return true; 00156 00157 if (!data->hasFormat(privateMimeType)) 00158 return false; 00159 00160 // decode mime data 00161 QByteArray itemData = data->data(privateMimeType); 00162 QDataStream dataStream(&itemData, QIODevice::ReadOnly); 00163 QString name; 00164 int value; 00165 dataStream >> name >> value; 00166 00167 // search for this element 00168 int oldIndex = 0; 00169 for (NamedValuesVector::iterator it = namedValues->begin(); it != namedValues->end(); it++, oldIndex++) 00170 if ((*it).name == name.toStdWString() && (*it).value == value) 00171 { 00172 // found! move it 00173 moveRow(oldIndex, row); 00174 return true; 00175 } 00176 00177 // element not found 00178 return false; 00179 } 00180 00181 Qt::DropActions NamedValuesVectorModel::supportedDragActions() 00182 { 00183 return Qt::CopyAction | Qt::MoveAction; 00184 } 00185 00186 Qt::DropActions NamedValuesVectorModel::supportedDropActions() const 00187 { 00188 return Qt::CopyAction | Qt::MoveAction; 00189 } 00190 00191 bool NamedValuesVectorModel::setData(const QModelIndex &index, const QVariant &value, int role) 00192 { 00193 Q_ASSERT(namedValues); 00194 if (index.isValid() && role == Qt::EditRole) 00195 { 00196 if (index.column() == 0) 00197 { 00198 namedValues->at(index.row()).name = value.toString().toStdWString(); 00199 emit dataChanged(index, index); 00200 wasModified = true; 00201 return true; 00202 } 00203 if (index.column() == 1) 00204 { 00205 namedValues->at(index.row()).value = value.toInt(); 00206 emit dataChanged(index, index); 00207 wasModified = true; 00208 return true; 00209 } 00210 } 00211 return false; 00212 } 00213 00214 void NamedValuesVectorModel::setEditable(bool editable) 00215 { 00216 this->editable = editable; 00217 } 00218 00219 void NamedValuesVectorModel::addNamedValue(const NamedValue &namedValue, int index) 00220 { 00221 Q_ASSERT(namedValues); 00222 Q_ASSERT(index < (int)namedValues->size()); 00223 00224 if (index < 0) 00225 { 00226 // insert at the end 00227 beginInsertRows(QModelIndex(), namedValues->size(), namedValues->size()); 00228 namedValues->push_back(namedValue); 00229 endInsertRows(); 00230 } 00231 else 00232 { 00233 beginInsertRows(QModelIndex(), index, index); 00234 NamedValuesVector::iterator it = namedValues->begin() + index; 00235 namedValues->insert(it, namedValue); 00236 endInsertRows(); 00237 } 00238 00239 wasModified = true; 00240 emit publicRowsInserted(); 00241 } 00242 00243 void NamedValuesVectorModel::delNamedValue(int index) 00244 { 00245 Q_ASSERT(namedValues); 00246 Q_ASSERT(index < (int)namedValues->size()); 00247 00248 beginRemoveRows(QModelIndex(), index, index); 00249 00250 namedValues->erase(namedValues->begin() + index); 00251 wasModified = true; 00252 00253 endRemoveRows(); 00254 emit publicRowsRemoved(); 00255 } 00256 00257 bool NamedValuesVectorModel::moveRow(int oldRow, int& newRow) 00258 { 00259 if (oldRow == newRow || namedValues->size() <= 1) 00260 return false; 00261 00262 // get values 00263 NamedValue value = namedValues->at(oldRow); 00264 00265 delNamedValue(oldRow); 00266 00267 // update index for the new model 00268 if (newRow > oldRow && newRow > 0) 00269 newRow--; 00270 00271 addNamedValue(value, newRow); 00272 00273 return true; 00274 } 00275 00276 void NamedValuesVectorModel::clear() 00277 { 00278 Q_ASSERT(namedValues); 00279 00280 if (namedValues->size() == 0) 00281 return; 00282 00283 beginRemoveRows(QModelIndex(), 0, namedValues->size()-1); 00284 00285 namedValues->clear(); 00286 wasModified = true; 00287 00288 endRemoveRows(); 00289 } 00290 00291 // ****************************************************************************** // 00292 00293 MaskableNamedValuesVectorModel::MaskableNamedValuesVectorModel(NamedValuesVector* namedValues, const QString &tooltipText, QObject *parent) : 00294 NamedValuesVectorModel(namedValues, tooltipText, parent), 00295 viewEvent() 00296 { 00297 } 00298 00299 MaskableNamedValuesVectorModel::MaskableNamedValuesVectorModel(NamedValuesVector* namedValues, QObject *parent) : 00300 NamedValuesVectorModel(namedValues, parent), 00301 viewEvent() 00302 { 00303 } 00304 00305 int MaskableNamedValuesVectorModel::columnCount(const QModelIndex & parent) const 00306 { 00307 return 3; 00308 } 00309 00310 QVariant MaskableNamedValuesVectorModel::data(const QModelIndex &index, int role) const 00311 { 00312 if (index.column() != 2) 00313 return NamedValuesVectorModel::data(index, role); 00314 00315 if (role == Qt::DisplayRole) 00316 { 00317 return QVariant(); 00318 } 00319 else if (role == Qt::DecorationRole) 00320 { 00321 return viewEvent[index.row()] ? 00322 QPixmap(QString(":/images/eye.png")) : 00323 QPixmap(QString(":/images/eyeclose.png")); 00324 } 00325 else if (role == Qt::ToolTipRole) 00326 { 00327 return viewEvent[index.row()] ? 00328 tr("Hide") : 00329 tr("View"); 00330 } 00331 else 00332 return QVariant(); 00333 } 00334 00335 Qt::ItemFlags MaskableNamedValuesVectorModel::flags(const QModelIndex & index) const 00336 { 00337 if (index.column() == 2) 00338 return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDropEnabled; 00339 else 00340 return NamedValuesVectorModel::flags(index); 00341 00342 } 00343 00344 bool MaskableNamedValuesVectorModel::isVisible(const unsigned id) 00345 { 00346 if (id >= viewEvent.size() || viewEvent[id]) 00347 return true; 00348 00349 return false; 00350 } 00351 00352 void MaskableNamedValuesVectorModel::addNamedValue(const NamedValue& namedValue) 00353 { 00354 NamedValuesVectorModel::addNamedValue(namedValue); 00355 viewEvent.push_back(true); 00356 } 00357 00358 void MaskableNamedValuesVectorModel::delNamedValue(int index) 00359 { 00360 viewEvent.erase(viewEvent.begin() + index); 00361 NamedValuesVectorModel::delNamedValue(index); 00362 } 00363 00364 bool MaskableNamedValuesVectorModel::moveRow(int oldRow, int& newRow) 00365 { 00366 if (!NamedValuesVectorModel::moveRow(oldRow, newRow)) 00367 return false; 00368 00369 // get value 00370 bool value = viewEvent.at(oldRow); 00371 00372 viewEvent.erase(viewEvent.begin() + oldRow); 00373 00374 if (newRow < 0) 00375 viewEvent.push_back(value); 00376 else 00377 viewEvent.insert(viewEvent.begin() + newRow, value); 00378 00379 return true; 00380 } 00381 00382 void MaskableNamedValuesVectorModel::toggle(const QModelIndex &index) 00383 { 00384 Q_ASSERT(namedValues); 00385 Q_ASSERT(index.row() < (int)namedValues->size()); 00386 00387 viewEvent[index.row()] = !viewEvent[index.row()]; 00388 wasModified = true; 00389 } 00390 00392 }; // Aseba