TargetModels.cpp
Go to the documentation of this file.
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 "TargetModels.h"
00022 #include <QtDebug>
00023 #include <QtGui>
00024 
00025 #include <TargetModels.moc>
00026 
00027 namespace Aseba
00028 {
00031         
00032         VariableListener::VariableListener(TargetVariablesModel* variablesModel) :
00033                 variablesModel(variablesModel)
00034         {
00035                 
00036         }
00037         
00038         VariableListener::~VariableListener()
00039         {
00040                 if (variablesModel)
00041                         variablesModel->unsubscribeViewPlugin(this);
00042         }
00043         
00044         bool VariableListener::subscribeToVariableOfInterest(const QString& name)
00045         {
00046                 return variablesModel->subscribeToVariableOfInterest(this, name);
00047         }
00048         
00049         void VariableListener::unsubscribeToVariableOfInterest(const QString& name)
00050         {
00051                 variablesModel->unsubscribeToVariableOfInterest(this, name);
00052         }
00053         
00054         void VariableListener::unsubscribeToVariablesOfInterest()
00055         {
00056                 variablesModel->unsubscribeToVariablesOfInterest(this);
00057         }
00058         
00059         void VariableListener::invalidateVariableModel()
00060         {
00061                 variablesModel = 0;
00062         }
00063         
00064         
00065         TargetVariablesModel::~TargetVariablesModel()
00066         {
00067                 for (VariableListenersNameMap::iterator it = variableListenersMap.begin(); it != variableListenersMap.end(); ++it)
00068                 {
00069                         it.key()->invalidateVariableModel();
00070                 }
00071         }
00072         
00073         int TargetVariablesModel::rowCount(const QModelIndex &parent) const
00074         {
00075                 if (parent.isValid())
00076                 {
00077                         if (parent.parent().isValid() || (variables.at(parent.row()).value.size() == 1))
00078                                 return 0;
00079                         else
00080                                 return variables.at(parent.row()).value.size();
00081                 }
00082                 else
00083                         return variables.size();
00084         }
00085         
00086         int TargetVariablesModel::columnCount(const QModelIndex & parent) const
00087         {
00088                 return 2;
00089         }
00090         
00091         QModelIndex TargetVariablesModel::index(int row, int column, const QModelIndex &parent) const
00092         {
00093                 if (parent.isValid())
00094                         return createIndex(row, column, parent.row());
00095                 else
00096                 {
00097                         // top-level indices shall not point outside the variable array
00098                         if (row < 0 || row >= variables.length())
00099                                 return QModelIndex();
00100                         else
00101                                 return createIndex(row, column, -1);
00102                 }
00103         }
00104         
00105         QModelIndex TargetVariablesModel::parent(const QModelIndex &index) const
00106         {
00107                 if (index.isValid() && (index.internalId() != -1))
00108                         return createIndex(index.internalId(), 0, -1);
00109                 else
00110                         return QModelIndex();
00111         }
00112         
00113         QVariant TargetVariablesModel::data(const QModelIndex &index, int role) const
00114         {
00115                 if (index.parent().isValid())
00116                 {
00117                         if (role != Qt::DisplayRole)
00118                                 return QVariant();
00119                         
00120                         if (index.column() == 0)
00121                                 return index.row();
00122                         else
00123                                 return variables.at(index.parent().row()).value[index.row()];
00124                 }
00125                 else
00126                 {
00127                         QString name = variables.at(index.row()).name;
00128                         // hidden variable
00129                         if (name.left(1) == "_")
00130                         {
00131                                 if (role == Qt::ForegroundRole)
00132                                         return QApplication::palette().color(QPalette::Disabled, QPalette::Text);
00133                                 else if (role == Qt::FontRole)
00134                                 {
00135                                         QFont font;
00136                                         font.setItalic(true);
00137                                         return font;
00138                                 }
00139                         }
00140                         if (index.column() == 0)
00141                         {
00142                                 if (role == Qt::DisplayRole)
00143                                         return name;
00144                                 return QVariant();
00145                         }
00146                         else
00147                         {
00148                                 if (role == Qt::DisplayRole)
00149                                 {
00150                                         if (variables.at(index.row()).value.size() == 1)
00151                                                 return variables.at(index.row()).value[0];
00152                                         else
00153                                                 return QString("(%0)").arg(variables.at(index.row()).value.size());
00154                                 }
00155                                 else if (role == Qt::ForegroundRole)
00156                                 {
00157                                         if (variables.at(index.row()).value.size() == 1)
00158                                                 return QVariant();
00159                                         else
00160                                                 return QApplication::palette().color(QPalette::Disabled, QPalette::Text);
00161                                 }
00162                                 else
00163                                         return QVariant();
00164                         }
00165                 }
00166         }
00167         
00168         QVariant TargetVariablesModel::headerData(int section, Qt::Orientation orientation, int role) const
00169         {
00170                 //Q_UNUSED(section)
00171                 Q_UNUSED(orientation)
00172                 Q_UNUSED(role)
00173                 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
00174                 {
00175                         if (section == 0)
00176                                 return tr("names");
00177                         else
00178                                 return tr("values");
00179                 }
00180                 return QVariant();
00181         }
00182         
00183         Qt::ItemFlags TargetVariablesModel::flags(const QModelIndex &index) const
00184         {
00185                 if (!index.isValid())
00186                         return 0;
00187                 
00188                 if (index.column() == 1)
00189                 {
00190                         if (index.parent().isValid())
00191                                 return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
00192                         else if (variables.at(index.row()).value.size() == 1)
00193                                 return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
00194                         else
00195                                 return 0;
00196                 }
00197                 else
00198                 {
00199                         if (index.parent().isValid())
00200                                 return Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable;
00201                         else
00202                                 return Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsSelectable;
00203                 }
00204         }
00205         
00206         bool TargetVariablesModel::setData(const QModelIndex &index, const QVariant &value, int role)
00207         {
00208                 if (index.isValid() && role == Qt::EditRole)
00209                 {
00210                         if (index.parent().isValid())
00211                         {
00212                                 int variableValue;
00213                                 bool ok;
00214                                 variableValue = value.toInt(&ok);
00215                                 Q_ASSERT(ok);
00216                                 
00217                                 variables[index.parent().row()].value[index.row()] = variableValue;
00218                                 emit variableValuesChanged(variables[index.parent().row()].pos + index.row(), VariablesDataVector(1, variableValue));
00219                                 
00220                                 return true;
00221                         }
00222                         else if (variables.at(index.row()).value.size() == 1)
00223                         {
00224                                 int variableValue;
00225                                 bool ok;
00226                                 variableValue = value.toInt(&ok);
00227                                 Q_ASSERT(ok);
00228                                 
00229                                 variables[index.row()].value[0] = variableValue;
00230                                 emit variableValuesChanged(variables[index.row()].pos, VariablesDataVector(1, variableValue));
00231                                 
00232                                 return true;
00233                         }
00234                 }
00235                 return false;
00236         }
00237         
00238         QStringList TargetVariablesModel::mimeTypes () const
00239         {
00240                 QStringList types;
00241                 types << "text/plain";
00242                 return types;
00243         }
00244         
00245         QMimeData * TargetVariablesModel::mimeData ( const QModelIndexList & indexes ) const
00246         {
00247                 QString texts;
00248                 foreach (QModelIndex index, indexes)
00249                 {
00250                         if (index.isValid())
00251                         {
00252                                 const QString text = data(index, Qt::DisplayRole).toString();
00253                                 if (index.parent().isValid())
00254                                 {
00255                                         const QString varName = data(index.parent(), Qt::DisplayRole).toString();
00256                                         texts += varName + "[" + text + "]";
00257                                 }
00258                                 else
00259                                         texts += text;
00260                         }
00261                 }
00262                 
00263                 QMimeData *mimeData = new QMimeData();
00264                 mimeData->setText(texts);
00265                 return mimeData;
00266         }
00267         
00268         unsigned TargetVariablesModel::getVariablePos(const QString& name) const
00269         {
00270                 for (int i = 0; i < variables.size(); ++i)
00271                 {
00272                         const Variable& variable(variables[i]);
00273                         if (variable.name == name)
00274                                 return variable.pos;
00275                 }
00276                 return 0;
00277         }
00278         
00279         unsigned TargetVariablesModel::getVariableSize(const QString& name) const
00280         {
00281                 for (int i = 0; i < variables.size(); ++i)
00282                 {
00283                         const Variable& variable(variables[i]);
00284                         if (variable.name == name)
00285                                 return variable.value.size();
00286                 }
00287                 return 0;
00288         }
00289         
00290         VariablesDataVector TargetVariablesModel::getVariableValue(const QString& name) const
00291         {
00292                 for (int i = 0; i < variables.size(); ++i)
00293                 {
00294                         const Variable& variable(variables[i]);
00295                         if (variable.name == name)
00296                                 return variable.value;
00297                 }
00298                 return VariablesDataVector();
00299         }
00300         
00301         void TargetVariablesModel::updateVariablesStructure(const Compiler::VariablesMap *variablesMap)
00302         {
00303                 // Build a new list of variables
00304                 QList<Variable> newVariables;
00305                 for (Compiler::VariablesMap::const_iterator it = variablesMap->begin(); it != variablesMap->end(); ++it)
00306                 {
00307                         // create new variable
00308                         Variable var;
00309                         var.name = QString::fromStdWString(it->first);
00310                         var.pos = it->second.first;
00311                         var.value.resize(it->second.second);
00312                         
00313                         // find its right place in the array
00314                         int i;
00315                         for (i = 0; i < newVariables.size(); ++i)
00316                         {
00317                                 if (var.pos < newVariables[i].pos)
00318                                         break;
00319                         }
00320                         newVariables.insert(i, var);
00321                 }
00322                 
00323                 // compute the difference
00324                 int i(0);
00325                 int count(std::min(variables.length(), newVariables.length()));
00326                 while (
00327                         i < count && 
00328                         variables[i].name == newVariables[i].name && 
00329                         variables[i].pos == newVariables[i].pos &&
00330                         variables[i].value.size() == newVariables[i].value.size()
00331                 )
00332                         ++i;
00333                 
00334                 // update starting from the first change point
00335                 //qDebug() << "change from " << i << " to " << variables.length();
00336                 if (i != variables.length())
00337                 {
00338                         beginRemoveRows(QModelIndex(), i, variables.length()-1);
00339                         int removeCount(variables.length() - i);
00340                         for (int j = 0; j < removeCount; ++j)
00341                                 variables.removeLast();
00342                         endRemoveRows();
00343                 }
00344                 
00345                 //qDebug() << "size: " << variables.length();
00346                 
00347                 if (i != newVariables.length())
00348                 {
00349                         beginInsertRows(QModelIndex(), i, newVariables.length()-1);
00350                         for (int j = i; j < newVariables.length(); ++j)
00351                                 variables.append(newVariables[j]);
00352                         endInsertRows();
00353                 }
00354 
00355                 /*variables.clear();
00356                 for (Compiler::VariablesMap::const_iterator it = variablesMap->begin(); it != variablesMap->end(); ++it)
00357                 {
00358                         // create new variable
00359                         Variable var;
00360                         var.name = QString::fromStdWString(it->first);
00361                         var.pos = it->second.first;
00362                         var.value.resize(it->second.second);
00363                         
00364                         // find its right place in the array
00365                         int i;
00366                         for (i = 0; i < variables.size(); ++i)
00367                         {
00368                                 if (var.pos < variables[i].pos)
00369                                         break;
00370                         }
00371                         variables.insert(i, var);
00372                 }
00373                 
00374                 reset();*/
00375         }
00376         
00377         void TargetVariablesModel::setVariablesData(unsigned start, const VariablesDataVector &data)
00378         {
00379                 size_t dataLength = data.size();
00380                 for (int i = 0; i < variables.size(); ++i)
00381                 {
00382                         Variable &var = variables[i];
00383                         int varLen = (int)var.value.size();
00384                         int varStart = (int)start - (int)var.pos;
00385                         int copyLen = (int)dataLength;
00386                         int copyStart = 0;
00387                         // crop data before us
00388                         if (varStart < 0)
00389                         {
00390                                 copyLen += varStart;
00391                                 copyStart -= varStart;
00392                                 varStart = 0;
00393                         }
00394                         // if nothing to copy, continue
00395                         if (copyLen <= 0)
00396                                 continue;
00397                         // crop data after us
00398                         if (varStart + copyLen > varLen)
00399                         {
00400                                 copyLen = varLen - varStart;
00401                         }
00402                         // if nothing to copy, continue
00403                         if (copyLen <= 0)
00404                                 continue;
00405                         
00406                         // copy
00407                         copy(data.begin() + copyStart, data.begin() + copyStart + copyLen, var.value.begin() + varStart);
00408                         
00409                         // notify gui
00410                         QModelIndex parentIndex = index(i, 0);
00411                         emit dataChanged(index(varStart, 0, parentIndex), index(varStart + copyLen, 0, parentIndex));
00412                         
00413                         // and notify view plugins
00414                         for (VariableListenersNameMap::iterator it = variableListenersMap.begin(); it != variableListenersMap.end(); ++it)
00415                         {
00416                                 QStringList &list = it.value();
00417                                 for (int v = 0; v < list.size(); v++)
00418                                 {
00419                                         if (list[v] == var.name)
00420                                                 it.key()->variableValueUpdated(var.name, var.value);
00421                                 }
00422                         }
00423                 }
00424         }
00425         
00426         bool TargetVariablesModel::setVariableValues(const QString& name, const VariablesDataVector& values)
00427         {
00428                 for (int i = 0; i < variables.size(); ++i)
00429                 {
00430                         Variable& variable(variables[i]);
00431                         if (variable.name == name)
00432                         {
00433 //                              setVariablesData(variable.pos, values);
00434                                 emit variableValuesChanged(variable.pos, values);
00435                                 return true;
00436                         }
00437                 }
00438                 return false;
00439         }
00440         
00441         void TargetVariablesModel::unsubscribeViewPlugin(VariableListener* listener)
00442         {
00443                 variableListenersMap.remove(listener);
00444         }
00445         
00446         bool TargetVariablesModel::subscribeToVariableOfInterest(VariableListener* listener, const QString& name)
00447         {
00448                 QStringList &list = variableListenersMap[listener];
00449                 list.push_back(name);
00450                 for (int i = 0; i < variables.size(); i++)
00451                         if (variables[i].name == name)
00452                                 return true;
00453                 return false;
00454         }
00455         
00456         void TargetVariablesModel::unsubscribeToVariableOfInterest(VariableListener* listener, const QString& name)
00457         {
00458                 QStringList &list = variableListenersMap[listener];
00459                 list.removeAll(name);
00460         }
00461         
00462         void TargetVariablesModel::unsubscribeToVariablesOfInterest(VariableListener* plugin)
00463         {
00464                 if (variableListenersMap.contains(plugin))
00465                         variableListenersMap.remove(plugin);
00466         }
00467         
00468         struct TargetFunctionsModel::TreeItem
00469         {
00470                 TreeItem* parent;
00471                 QList<TreeItem*> children;
00472                 QString name;
00473                 QString toolTip;
00474                 bool enabled;
00475                 bool draggable;
00476                 
00477                 TreeItem() :
00478                         parent(0),
00479                         name("root"),
00480                         enabled(true),
00481                         draggable(false)
00482                 { }
00483                 
00484                 TreeItem(TreeItem* parent, const QString& name, bool enabled, bool draggable) :
00485                         parent(parent),
00486                         name(name),
00487                         enabled(enabled),
00488                         draggable(draggable)
00489                 { }
00490                 
00491                 TreeItem(TreeItem* parent, const QString& name, const QString& toolTip, bool enabled, bool draggable) :
00492                         parent(parent),
00493                         name(name),
00494                         toolTip(toolTip),
00495                         enabled(enabled),
00496                         draggable(draggable)
00497                 { }
00498                 
00499                 ~TreeItem()
00500                 {
00501                         for (int i = 0; i < children.size(); i++)
00502                                 delete children[i];
00503                 }
00504                 
00505                 TreeItem *getEntry(const QString& name, bool enabled = true)
00506                 {
00507                         for (int i = 0; i < children.size(); i++)
00508                                 if (children[i]->name == name)
00509                                         return children[i];
00510                         
00511                         children.push_back(new TreeItem(this, name, enabled, draggable));
00512                         return children.last();
00513                 }
00514         };
00515         
00516         
00517         
00518         TargetFunctionsModel::TargetFunctionsModel(const TargetDescription *descriptionRead, QObject *parent) :
00519                 QAbstractItemModel(parent),
00520                 root(0),
00521                 descriptionRead(descriptionRead),
00522                 regExp("\\b")
00523         {
00524                 Q_ASSERT(descriptionRead);
00525                 setSupportedDragActions(Qt::CopyAction);
00526                 recreateTreeFromDescription(false);
00527         }
00528         
00529         TargetFunctionsModel::~TargetFunctionsModel()
00530         {
00531                 delete root;
00532         }
00533         
00534         TargetFunctionsModel::TreeItem *TargetFunctionsModel::getItem(const QModelIndex &index) const
00535         {
00536                 if (index.isValid())
00537                 {
00538                         TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
00539                         if (item)
00540                                 return item;
00541                 }
00542                 return root;
00543         }
00544         
00545         QString TargetFunctionsModel::getToolTip(const TargetDescription::NativeFunction& function) const
00546         {
00547                 // tooltip, display detailed information with pretty print of template parameters
00548                 QString text;
00549                 QSet<QString> variablesNames;
00550                 
00551                 text += QString("<b>%1</b>(").arg(QString::fromStdWString(function.name));
00552                 for (size_t i = 0; i < function.parameters.size(); i++)
00553                 {
00554                         QString variableName(QString::fromStdWString(function.parameters[i].name));
00555                         variablesNames.insert(variableName);
00556                         text += variableName;
00557                         if (function.parameters[i].size > 1)
00558                                 text += QString("[%1]").arg(function.parameters[i].size);
00559                         else if (function.parameters[i].size < 0)
00560                         {
00561                                 text += QString("[&lt;T%1&gt;]").arg(-function.parameters[i].size);
00562                         }
00563                         
00564                         if (i + 1 < function.parameters.size())
00565                                 text += QString(", ");
00566                 }
00567                 
00568                 QString description = QString::fromStdWString(function.description);
00569                 QStringList descriptionWords = description.split(regExp);
00570                 for (int i = 0; i < descriptionWords.size(); ++i)
00571                         if (variablesNames.contains(descriptionWords.at(i)))
00572                                 descriptionWords[i] = QString("<tt>%1</tt>").arg(descriptionWords[i]);
00573                 
00574                 text += QString(")<br/>") + descriptionWords.join(" ");
00575                 
00576                 return text;
00577         }
00578         
00579         int TargetFunctionsModel::rowCount(const QModelIndex & parent) const
00580         {
00581                 return getItem(parent)->children.count();
00582         }
00583         
00584         int TargetFunctionsModel::columnCount(const QModelIndex & /* parent */) const
00585         {
00586                 return 1;
00587         }
00588         
00589         void TargetFunctionsModel::recreateTreeFromDescription(bool showHidden)
00590         {
00591                 if (root)
00592                         delete root;
00593                 root = new TreeItem;
00594                 
00595                 if (showHidden)
00596                         root->getEntry(tr("hidden"), false);
00597                 
00598                 for (size_t i = 0; i < descriptionRead->nativeFunctions.size(); i++)
00599                 {
00600                         // get the name, split it, and managed hidden
00601                         QString name = QString::fromStdWString(descriptionRead->nativeFunctions[i].name);
00602                         QStringList splittedName = name.split(".", QString::SkipEmptyParts);
00603                         
00604                         // ignore functions with no name at all
00605                         if (splittedName.isEmpty())
00606                                 continue;
00607                         
00608                         // get first, check whether hidden, and then iterate
00609                         TreeItem* entry = root;
00610                         Q_ASSERT(!splittedName[0].isEmpty());
00611                         if (name.at(0) == '_' || name.contains(QString("._")))
00612                         {
00613                                 if (!showHidden)
00614                                         continue;
00615                                 entry = entry->getEntry(tr("hidden"), false);
00616                         }
00617                         
00618                         for (int j = 0; j < splittedName.size() - 1; ++j)
00619                                 entry = entry->getEntry(splittedName[j], entry->enabled);
00620                         
00621                         // for last entry
00622                         entry->children.push_back(new TreeItem(entry, name, getToolTip(descriptionRead->nativeFunctions[i]), entry->enabled, true));
00623                 }
00624                 
00625                 reset();
00626         }
00627         
00628         QModelIndex TargetFunctionsModel::parent(const QModelIndex &index) const
00629         {
00630                 if (!index.isValid())
00631                         return QModelIndex();
00632         
00633                 TreeItem *childItem = getItem(index);
00634                 TreeItem *parentItem = childItem->parent;
00635         
00636                 if (parentItem == root)
00637                         return QModelIndex();
00638                 
00639                 if (parentItem->parent)
00640                         return createIndex(parentItem->parent->children.indexOf(const_cast<TreeItem*>(parentItem)), 0, parentItem);
00641                 else
00642                         return createIndex(0, 0, parentItem);
00643         }
00644         
00645         QModelIndex TargetFunctionsModel::index(int row, int column, const QModelIndex &parent) const
00646         {
00647                 TreeItem *parentItem = getItem(parent);
00648                 TreeItem *childItem = parentItem->children.value(row);
00649                 Q_ASSERT(childItem);
00650                 
00651                 if (childItem)
00652                         return createIndex(row, column, childItem);
00653                 else
00654                         return QModelIndex();
00655         }
00656         
00657         QVariant TargetFunctionsModel::data(const QModelIndex &index, int role) const
00658         {
00659                 if (!index.isValid() ||
00660                         (role != Qt::DisplayRole && role != Qt::ToolTipRole && role != Qt::WhatsThisRole))
00661                         return QVariant();
00662                 
00663                 if (role == Qt::DisplayRole)
00664                 {
00665                         return getItem(index)->name;
00666                 }
00667                 else
00668                 {
00669                         return getItem(index)->toolTip;
00670                 }
00671         }
00672         
00673         QVariant TargetFunctionsModel::headerData(int section, Qt::Orientation orientation, int role) const
00674         {
00675                 Q_UNUSED(section)
00676                 Q_UNUSED(orientation)
00677                 Q_UNUSED(role)
00678                 return QVariant();
00679         }
00680         
00681         Qt::ItemFlags TargetFunctionsModel::flags(const QModelIndex & index) const
00682         {
00683                 TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
00684                 if (item)
00685                 {
00686                         QFlags<Qt::ItemFlag> flags;
00687                         flags |= item->enabled ? Qt::ItemIsEnabled : QFlags<Qt::ItemFlag>();
00688                         flags |= item->draggable ? Qt::ItemIsDragEnabled | Qt::ItemIsSelectable : QFlags<Qt::ItemFlag>();
00689                         return flags;
00690                 }
00691                 else
00692                         return Qt::ItemIsEnabled;
00693         }
00694         
00695         QStringList TargetFunctionsModel::mimeTypes () const
00696         {
00697                 QStringList types;
00698                 types << "text/plain";
00699                 return types;
00700         }
00701         
00702         QMimeData * TargetFunctionsModel::mimeData ( const QModelIndexList & indexes ) const
00703         {
00704                 QString texts;
00705                 foreach (QModelIndex index, indexes)
00706                 {
00707                         if (index.isValid())
00708                         {
00709                                 QString text = data(index, Qt::DisplayRole).toString();
00710                                 texts += text;
00711                         }
00712                 }
00713                 
00714                 QMimeData *mimeData = new QMimeData();
00715                 mimeData->setText(texts);
00716                 return mimeData;
00717         }
00718         
00719         
00721 }; // Aseba


aseba
Author(s): Stéphane Magnenat
autogenerated on Thu Jan 2 2014 11:17:17