tuchulcha  0.10.1
Graphical Workflow Configuration Editor
ParameterFileModel.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2009 Jens-Malte Gottfried
2 
3  This file is part of Tuchulcha.
4 
5  Tuchulcha is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  Tuchulcha is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with Tuchulcha. If not, see <http://www.gnu.org/licenses/>.
17  */
24 #include "ParameterFileModel.h"
25 #include "QParameterFile.h"
26 #include "PrefixValidator.h"
27 #include "VarTypeMap.h"
28 #include "MetaData.h"
29 #include "FileManager.h"
30 #include "LogDialog.h"
31 #include "LogDecorators.h"
32 #include <QFileDialog>
33 #include <QDir>
34 #include <QSet>
35 #include <QSettings>
36 #include <QMessageBox>
37 #include <QIcon>
38 #include <QMimeData>
39 #include <QUrl>
40 #include <QTimer>
41 #include <QApplication>
42 #include <QMutex>
43 
45  QString fName, QObject* myParent, QString metaFile) :
46  QAbstractTableModel(myParent),
47  _resetMutex(new QMutex()),
48  _parameterFile(new QParameterFile()),
49  _fileName(fName),
50  _prefix(""),
51  _metaInfos(0),
52  _useMetaInfo(false),
53  _onlyParams(false),
54  _minPriority(0),
55  _handleDynamics(true)
56 {
57  // this ParameterFile stores the description of classes.
58  if (!metaFile.isEmpty()) {
59  loadMetaInfo(metaFile);
60  setOnlyParams(true);
61  }
62  if (!_fileName.isEmpty())
63  _load();
64 
65  connect(this, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
66  SLOT(_updatePriority(QModelIndex,QModelIndex)));
67 }
68 
70  if (_metaInfos) {
71  delete _metaInfos;
72  _metaInfos = 0;
73  }
74  delete _parameterFile;
75  delete _resetMutex;
76 }
77 
78 int ParameterFileModel::rowCount(const QModelIndex& /*parent*/) const {
79  return _keys.size();
80 }
81 
82 int ParameterFileModel::columnCount(const QModelIndex& /*parent*/) const {
83  return 3;
84 }
85 
86 QVariant ParameterFileModel::data(const QModelIndex& ind, int role) const {
87  // mapper to convert parameter.type into QVariant::Type
88  const VarTypeMap& mapper = VarTypeMap::instance();
89  int row = ind.row();
90  int col = ind.column();
91  QString key = _keys[row];
92  QString val;
93  QVariant res;
94 
95  switch (role) {
96 
97  case Qt::EditRole:
98  case Qt::DisplayRole:
99  if ((row >= 0) && (row < _keys.size())) {
100  switch (col) {
101  case 0:
102  // parameter name (without prefix)
103  if (!_prefix.isEmpty())
104  key.remove(0, _prefix.length());
105 
106  // remove dot after valid prefix
107  if (key[0] == '.')
108  key.remove(0, 1);
109  return key;
110 
111  case 1:
112  if (_parameterFile->isSet(_keys[row])) {
113  val = _parameterFile->get(_keys[row]);
114  }
115  else if (_onlyParams) {
116  val = getDefault(_keys[row]);
117  }
118 
119  // handle parameter links
120  if (val.startsWith('@')) {
121  QString ref = val.mid(1);
122  if(_parameterFile->isSet(ref)) {
123  val = _parameterFile->get(ref);
124  }
125  else if(role == Qt::DisplayRole) {
126  val = tr("[invalid reference to %1]").arg(ref);
127  }
128  }
129 
130  // handle QVariant type
131  res = val;
132  if (_useMetaInfo && isParameter(key)) {
133  QString typestring = getType(key);
134  QVariant::Type type = mapper[typestring];
135  Q_ASSERT(res.canConvert(type));
136  res.convert(type);
137  }
138  return res;
139 
140  case 2:
141  if (role == Qt::DisplayRole) {
142  return QVariant();
143  }
144  return getValue(key + ".editorpriority").toUInt();
145  }
146  }
147  break;
148 
149  case Qt::ToolTipRole:
150  if (_useMetaInfo) {
151  QString ret = _metaInfos->getDocString(key, getClass(key));
152  return ret.isEmpty() ? QVariant() : ret;
153  }
154  break;
155 
156  case Qt::ForegroundRole:
157  if (_onlyParams && !isSet(key)) {
158  return QColor(Qt::lightGray);
159  }
160  break;
161 
162  case Qt::BackgroundRole:
163  switch (getValue(key+".editorpriority").toInt()) {
164  case 1:
165  return QColor("#8f8");
166  case 2:
167  return QColor("#ff8");
168  case 3:
169  return QColor("#f80");
170  default:
171  break;
172  }
173  break;
174 
175  case Qt::CheckStateRole:
176  if (_useMetaInfo && col == 1 &&
177  isParameter(key) && getType(key) == "bool") {
178  const bool& checked = isSet(key) ?
179  QVariant(getValue(key)).toBool() :
180  QVariant(getDefault(key)).toBool();
181  return checked ? Qt::Checked : Qt::Unchecked;
182  }
183  break;
184 
185  case Qt::StatusTipRole:
186  if(col == 1) {
187  if (isSet(key)) {
188  QString ret = getValue(key);
189  if(ret.startsWith('@')) {
190  return tr("link to: %1").arg(ret.mid(1));
191  }
192  }
193  }
194  break;
195 
196  case Qt::DecorationRole:
197  if(col == 1) {
198  if (isSet(key)) {
199  QString ret = getValue(key);
200  if(ret.startsWith('@')) {
201  return QIcon(":/icons/symlink.png");
202  }
203  }
204  }
205  break;
206 
207  } // role switch
208 
209  return QVariant();
210 }
211 
213  const QModelIndex& ind, const QVariant& value, int role) {
214 
215  if (!prefixValid())
216  return false;
217 
218  switch (role) {
219  case Qt::EditRole:
220  case Qt::DisplayRole:
221  if ((ind.row() >= 0) && (ind.row() < _keys.size())) {
222  switch (ind.column()) {
223  case 0:
224  if (_onlyParams)
225  return false;
226 
227  if (value.canConvert(QVariant::String)) {
228  QString oldName = _keys[ind.row()];
229  QString newName;
230  // do not forget the prefix at the beginning of the name
231  if (!_prefix.isEmpty())
232  newName = _prefix + ".";
233  newName += value.toString();
234  if (oldName == newName)
235  return true; // nothing to do
236  if (_parameterFile->isSet(newName))
237  return false; // don't overwrite existing value
238 
239  // save value
240  QString val = getValue(oldName);
241  erase(oldName);
242  setValue(newName, val);
243  emit dataChanged(ind, ind);
244  return true;
245  }
246  break;
247  case 1:
248  if (value.canConvert(QVariant::String)) {
249  QString valueStr = value.toString();
250  QString keyStr = _keys[ind.row()];
251  if (valueStr == getValue(keyStr))
252  return true; // nothing to do
253 
254  setValue(keyStr, valueStr);
255  if (_onlyParams && _metaInfos->isDynamic(getClass(keyStr))) {
256  save();
257  _updateDynamics();
258  QTimer::singleShot(0, this, SLOT(_update()));
259  emit dynamicUpdate();
260  }
261  emit dataChanged(index(ind.row(), 0), ind);
262  return true;
263  }
264  break;
265  case 2:
266  if (value.canConvert(QVariant::Int)) {
267  // check if value is allowed
268  int valueInt = value.toInt();
269  QString valueStr = QVariant(valueInt).toString();
270  if (valueInt < 0 || valueInt > 3) {
271  return false;
272  }
273 
274  if (valueInt == 0) {
275  // 0 is default value -> no entry needed
276  if (isSet(_keys[ind.row()] + ".editorpriority")) {
277  // check if value exists to prevent exceptions
278  erase(_keys[ind.row()] + ".editorpriority");
279  emit dataChanged(index(ind.row(), 0), ind);
280  }
281  return true;
282  }
283 
284  if (valueStr ==
285  getValue(_keys[ind.row()] + ".editorpriority")) {
286  return true; // nothing to do
287  }
288 
289  setValue(_keys[ind.row()] + ".editorpriority", valueStr);
290  emit dataChanged(index(ind.row(), 0), ind);
291  return true;
292  }
293  break;
294  }
295  }
296  break;
297 
298  case Qt::CheckStateRole:
299  if (_useMetaInfo && ind.column()==1 && isParameter(_keys[ind.row()])) {
300  Q_ASSERT(getType(_keys[ind.row()]) == "bool");
301  bool checked (value.toBool());
302  setValue (_keys[ind.row()], checked ? "true" : "false");
303  emit dataChanged(index(ind.row(),0),ind);
304  if (_keys[ind.row()].contains("active") && checked == true){
306  }
307  // additional check whether the changed Parameter is the ActiveInactive
308  if (_keys[ind.row()].contains("active") && checked == false){
309  deactivate();
310  }
311  }
312  break;
313  }
314  return false;
315 }
316 
318  QString tmpPrefix = _prefix;
319  QStringList inputsOfOneSlot;
320  int parameterIndex = 0;
321  for (int p = 0; p < _keys.size(); p++){
322  if (_keys[p].contains("active")){
323  parameterIndex = p;
324  break;
325  }
326  }
327  for (int i = 0; i < tmpPrefix.size(); i++){
328  if (tmpPrefix.at(i) == '.'){
329  tmpPrefix.truncate(i);
330  }
331  }
332  for (int i = 0; i < getInputs(tmpPrefix).size(); i++){
333  if (getValue(tmpPrefix + "."+ getInputs(tmpPrefix).at(i)).contains(";")){
334  inputsOfOneSlot = getValue(tmpPrefix + "."+ getInputs(tmpPrefix).at(i)).split(";");
335  for (int o = 0; o < inputsOfOneSlot.size(); o++){
336  setPrefix(inputsOfOneSlot.at(o));
337  for (int p = 0; p < _keys.size(); p++){
338  if (_keys[p].contains("active")){
339  parameterIndex = p;
340  break;
341  }
342  }
343  setValue(_keys[parameterIndex], "true");
345  }
346  }
347  else if (getValue(tmpPrefix + "."+ getInputs(tmpPrefix).at(i)) != ""){
348  setPrefix(getValue(tmpPrefix + "."+ getInputs(tmpPrefix).at(i)));
349  for (int p = 0; p < _keys.size(); p++){
350  if (_keys[p].contains("active")){
351  parameterIndex = p;
352  break;
353  }
354  }
355  setValue(_keys[parameterIndex], "true");
357  }
358  }
359 
360 }
361 
362 // Deactivates following Plugins
364  QString tmpPrefix = _prefix;
365  QStringList outputsOfOneSlot;
366  int parameterIndex = 0;
367  for (int p = 0; p < _keys.size(); p++){
368  if (_keys[p].contains("active")){
369  parameterIndex = p;
370  break;
371  }
372  }
373  for (int i = 0; i < tmpPrefix.size(); i++){
374  if (tmpPrefix.at(i) == '.'){
375  tmpPrefix.truncate(i);
376  }
377  }
378  for (int i = 0; i < getOutputs(tmpPrefix).size(); i++){
379  if (getValue(tmpPrefix + "."+ getOutputs(tmpPrefix).at(i)).contains(";")){
380  outputsOfOneSlot = getValue(tmpPrefix + "."+ getOutputs(tmpPrefix).at(i)).split(";");
381  for (int o = 0; o < outputsOfOneSlot.size(); o++){
382  setPrefix(outputsOfOneSlot.at(o));
383  for (int p = 0; p < _keys.size(); p++){
384  if (_keys[p].contains("active")){
385  parameterIndex = p;
386  break;
387  }
388  }
389  setValue(_keys[parameterIndex], "false");
390  deactivate();
391  }
392  }
393  else if (getValue(tmpPrefix + "."+ getOutputs(tmpPrefix).at(i)) != ""){
394  setPrefix(getValue(tmpPrefix + "."+ getOutputs(tmpPrefix).at(i)));
395  for (int p = 0; p < _keys.size(); p++){
396  if (_keys[p].contains("active")){
397  parameterIndex = p;
398  break;
399  }
400  }
401  setValue(_keys[parameterIndex], "false");
402  deactivate();
403  }
404  }
405 }
406 
407 // Reactivates all following Plugins
409  QString tmpPrefix = _prefix;
410  QStringList outputsOfOneSlot;
411  int parameterIndex = 0;
412  for (int p = 0; p < _keys.size(); p++){
413  if (_keys[p].contains("active")){
414  parameterIndex = p;
415  break;
416  }
417  }
418  if (getValue(_keys[parameterIndex]) == "false"){
419  setValue(_keys[parameterIndex], "true");
420  for (int i = 0; i < tmpPrefix.size(); i++){
421  if (tmpPrefix.at(i) == '.'){
422  tmpPrefix.truncate(i);
423  }
424  }
425  for (int i = 0; i < getOutputs(tmpPrefix).size(); i++){
426  if (getValue(tmpPrefix + "."+ getOutputs(tmpPrefix).at(i)).contains(";")){
427  outputsOfOneSlot = getValue(tmpPrefix + "."+ getOutputs(tmpPrefix).at(i)).split(";");
428  for (int o = 0; o < outputsOfOneSlot.size(); o++){
429  setPrefix(outputsOfOneSlot.at(o));
430  reactivate();
431  }
432  }
433  else if (getValue(tmpPrefix + "."+ getOutputs(tmpPrefix).at(i)) != ""){
434  setPrefix(getValue(tmpPrefix + "."+ getOutputs(tmpPrefix).at(i)));
435  reactivate();
436  }
437  }
438 
439  }
440 }
441 
443  int parameterIndex=0;
444  for (int p = 0; p < _keys.size(); p++){
445  if (_keys[p].contains("active")){
446  parameterIndex = p;
447  break;
448  }
449  }
450  if (getValue(_keys[parameterIndex]) == "false"){
451  return false;
452  }
453  else {
454  return true;
455  }
456 }
457 
458 
459 
460 Qt::ItemFlags ParameterFileModel::flags(const QModelIndex& ind) const {
461  if (!prefixValid() || ind.row() < 0 || ind.row() >= _keys.size()) {
462  return Qt::NoItemFlags;
463  }
464  Q_ASSERT(ind.row() >= 0);
465  Q_ASSERT(ind.row() < _keys.size());
466 
467  Qt::ItemFlags res = Qt::NoItemFlags;
468  QString paramType;
469  QVariant::Type dataType;
470 
471  switch (ind.column()) {
472  case 0:
473  // parameter names editable, if _onlyParams is not selected
474  res = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
475  if (!_onlyParams) {
476  res = res | Qt::ItemIsEditable;
477  }
478  break;
479 
480  case 1:
481  res = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
482 
483  paramType = getType(_keys[ind.row()]);
484  dataType = data(ind).type();
485  if (_useMetaInfo && isParameter(_keys[ind.row()])
486  && paramType == "bool") {
487  // bool parameters are user checkable
488  res = res | Qt::ItemIsUserCheckable;
489  }
490  else {
491  // all non-bool parameters allow editing (delegate)
492  res = res | Qt::ItemIsEditable;
493 
494  if (dataType == QVariant::String &&
495  !paramType.contains(QRegExp("^\\{\\s*\\w.*\\}\\s*$"))) {
496  // string entries that do not represent a selection
497  // may be entered by dropping some values
498  res = res | Qt::ItemIsDropEnabled;
499  }
500  }
501  break;
502 
503  case 2:
504  res = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable;
505  break;
506 
507  default:
508  break;
509  }
510 
511  return res;
512 }
513 
514 QVariant ParameterFileModel::headerData(int section,
515  Qt::Orientation orientation, int role) const {
516 
517  if (role == Qt::DisplayRole && orientation == Qt::Horizontal) {
518  switch (section) {
519  case 0:
520  return tr("Parameter");
521  case 1:
522  return tr("Value");
523  case 2:
524  return tr("Priority");
525  }
526  }
527  return QAbstractTableModel::headerData(section,orientation,role);
528 }
529 
530 bool ParameterFileModel::insertRows(int row, int count,
531  const QModelIndex& parentInd) {
532 
533  // only appending is allowed!
534  if (!_onlyParams && prefixValid()
535  && (row >= 0) && (row == _keys.size()) && (count > 0)) {
536  beginInsertRows(parentInd, row, row + count - 1);
537  int offset = 0;
538  int i = 1;
539 
540  // append new values
541  while (i <= count) {
542  // get temp name for new parameter
543  QString name;
544  if (!_prefix.isEmpty())
545  name += _prefix + ".";
546  name += QString("new%1").arg(i + offset);
547  if (_parameterFile->isSet(name)) {
548  offset++;
549  continue;
550  }
551  setValue(name, "");
552  if (_minPriority > 0) {
553  setValue(name + ".editorpriority",
554  QVariant(_minPriority).toString());
555  }
556  i++;
557  }
559 
560  // apply modificators
561  if (!_prefix.isEmpty())
565 
566  // check new number of elements
567  Q_ASSERT(_keys.size() == (row + count));
568  endInsertRows();
569  return true;
570  }
571  else
572  return false;
573 }
574 
575 bool ParameterFileModel::removeRows(int row, int count,
576  const QModelIndex& parentInd) {
577 
578  // forbid modifications on invalid prefix
579  if (!prefixValid())
580  return false;
581 
582  // check row and count dimensions (have to fit into table)
583  if ((count > 0) && (row >= 0) && ((row + count) <= _keys.size())) {
584  // when onlyparams is set, values are not really removed, but
585  // reset to their default values
586  if (!_onlyParams)
587  beginRemoveRows(parentInd, row, row + count - 1);
588 
589  for (int i = row; i < row + count; i++) {
590  if (isSet(_keys[i])) {
592  }
593  }
594 
595  // keys have not to be changed on onlyparam mode
596  if (!_onlyParams) {
598  endRemoveRows();
599  return true;
600  } else {
601  emit dataChanged(index(row, 0), index(row + count, 1));
602  }
603  }
604  return false;
605 }
606 
608  if (_parameterFile->getKeyList().size() > 0) {
609  bool lock = _resetMutex->tryLock();
610  if (lock) {
611  beginResetModel();
612  }
614  _keys.clear();
615  setPrefix("");
616  if (lock) {
617  endResetModel();
618  _resetMutex->unlock();
619  }
620  }
621 }
622 
624  _handleDynamics = val;
625 }
626 
628  if (!_handleDynamics) {
629  qDebug("(DD) disabled dynamic-update");
630  return;
631  }
632  else if (QApplication::instance()) {
633  LogDialog dialog(
635  bool finished = dialog.waitForFinished(5000);
636  if (!finished || dialog.hasErrorLines()) {
637  dialog.show();
638  dialog.exec();
639  }
640  }
641  else {
642  qDebug("(WW) no qapplication, skipping dynamic loading");
643  }
644 }
645 
647  QMutexLocker locker(_resetMutex);
648  beginResetModel();
649  clear();
651  _updateDynamics();
652  _update();
653  endResetModel();
654  locker.unlock();
655  emit statusMessage(tr("File %1 loaded.").arg(_fileName));
656  return true;
657 }
658 
660  // remove keys
661  bool lock = _resetMutex->tryLock();
662  if (lock) {
663  beginResetModel();
664  }
665  _keys.clear();
666 
667  // load all keys
668  QStringList tempList = _parameterFile->getKeyList();
669  if (tempList.size() > 0) {
670  // apply modificators
671  tempList = _prefixFilter(tempList);
672  tempList = _paramFilter(tempList);
673  tempList = _priorityTagFilter(tempList);
674  tempList = _priorityFilter(tempList);
675 
676  // show selected parameters
677  _keys = tempList;
678  }
679  if (lock) {
680  endResetModel();
681  _resetMutex->unlock();
682  }
683 }
684 
686  const QModelIndex&, const QModelIndex &bottomRight) {
687  // check if filter active and priority changed
688  if (_minPriority > 0 && bottomRight.column() >= 2) {
689  _update();
690  }
691 }
692 
693 bool ParameterFileModel::load(const QString& fName) {
694  // determine which file to load
695  // (file dialog if fName is empty)
696  QString fromDialog = fName;
697  if (fromDialog.isEmpty()) {
698  QString guess = _fileName;
699  if (guess.isEmpty()) {
700  QSettings settings;
701  QStringList files =
702  settings.value("recentFileList").toStringList();
703  if (files.size() > 0)
704  guess = files[0];
705  else
706  guess = QDir::homePath();
707  }
708  fromDialog = QFileDialog::getOpenFileName(0, tr("Open File"),
709  guess, tr("ParameterFiles (*.wrp);;All Files (*.*)"));
710  }
711  if (fromDialog.isEmpty()) {
712  emit statusMessage(tr("no file selected"));
713  }
714  else if (!QFileInfo(fromDialog).isFile()) {
715  QMessageBox::warning(0, tr("Error loading file"),
716  tr("File <em>%1</em> does not exist or is no file!")
717  .arg(fromDialog));
718  }
719  else if (!QFileInfo(fromDialog).isReadable()) {
720  QMessageBox::warning(0, tr("Error loading file"),
721  tr("File <em>%1</em> is not readable!").arg(fromDialog));
722  }
723  else {
724  // fromDialog is a readable file now
725  setFileName(fromDialog);
726  return _load();
727  }
728  return false;
729 }
730 
731 void ParameterFileModel::save(const QString& fName) {
732  QString name;
733  //default to old filename if defined
734  if ((!_fileName.isEmpty()) && (_fileName != QDir::homePath()))
735  name = _fileName;
736  //overwrite with new filename if provided
737  if (!fName.isEmpty())
738  name = fName;
739  if (!name.isEmpty()) {
740  setFileName(name);
741  _parameterFile->save(name);
742  emit statusMessage(QString("File %1 saved.").arg(name));
743  emit modified(false);
744  } else
745  emit statusMessage("File not saved! (no filename given)");
746 }
747 
748 void ParameterFileModel::setFileName(const QString& fName) {
749  if (fName.isEmpty() || fName == _fileName)
750  return;
751  _fileName = fName;
753 }
754 
755 QString ParameterFileModel::setPrefix(const QString& newPrefix) {
756  if (newPrefix == _prefix)
757  return _prefix;
758  QString old = _prefix;
759  _prefix = newPrefix;
760  _update();
761  emit prefixChanged(_prefix);
762  return old;
763 }
764 
766  return *_parameterFile;
767 }
768 
770  return _fileName;
771 }
772 
773 QString ParameterFileModel::prefix() const {
774  return _prefix;
775 }
776 
778  return _prefix.isEmpty() ? true :
779  (_parameterFile->getKeyList(_prefix+".").size() > 0);
780 }
781 
782 void ParameterFileModel::loadMetaInfo(const QString& fName) {
783  if (_metaInfos) {
784  setUseMetaInfo(false);
785  delete _metaInfos;
786  _metaInfos = 0;
787  }
788  if (fName.isEmpty()) {
789  _metaInfos = 0;
790  emit metaInfoChanged(false);
791  } else {
792  _metaInfos = new MetaData(fName);
793  // update class case map
794  _classCaseMap.clear();
795  const QStringList& classes = _metaInfos->getClasses();
796  foreach (const QString& cur, classes) {
797  _classCaseMap.insert(cur.toLower(), cur);
798  }
799 
800  emit metaInfoChanged(true);
801  }
802 }
803 
805  return _useMetaInfo;
806 }
807 
809  if (value == _useMetaInfo)
810  return;
811 
812  if ((!value) && _onlyParams)
813  setOnlyParams(false);
814  _useMetaInfo = value;
815 
816  // let view reread information about clomumn 1 (values)
817  if (rowCount() > 0) {
818  emit dataChanged(index(0,1),index(rowCount()-1,1));
819  }
820 
821  emit useMetaInfoChanged(value);
822 }
823 
825  return _onlyParams;
826 }
827 
829  return _minPriority;
830 }
831 
833  if (_onlyParams == on)
834  return;
835  if ((!_useMetaInfo) && on)
836  setUseMetaInfo(on);
837  _onlyParams = on;
838  _update();
840 }
841 
842 QString ParameterFileModel::getClass(QString name, bool fixCase) const {
843  name = name.section(".",0,0);
844  QString cName = getValue(name + ".type").toLower();
845  if (fixCase) {
846  cName = _classCaseMap.value(cName,cName);
847  }
848  return cName;
849 }
850 
851 QStringList ParameterFileModel::_prefixFilter(QStringList list) const {
852  if (_prefix.isEmpty()) {
853  return list;
854  }
855  else if (prefixValid()) {
856  return list.filter(QRegExp("^\\s*"+_prefix+"\\.",Qt::CaseInsensitive));
857  }
858  else {
859  return list.filter(QRegExp("^\\s*"+_prefix,Qt::CaseInsensitive));
860  }
861 }
862 
863 QStringList ParameterFileModel::_collectObjects(QStringList list) const {
864  QSet<QString> result;
865  for (int ii = 0; ii < list.size(); ii++) {
866  QString cur = list[ii].section(".",0,0);
867  result << cur;
868  }
869  return result.toList();
870 }
871 
872 QStringList ParameterFileModel::_paramFilter(QStringList list) const {
873  if (_onlyParams) {
874  QStringList result;
875  QStringList objects = _collectObjects(list);
876 
877  // append all possible parameters for all objects
878  for (int ii = 0; ii < objects.size(); ii++) {
879  QStringList tmp;
880  tmp << getParameters(objects[ii]);
881  tmp.replaceInStrings(QRegExp("(^.*$)"), objects[ii]+".\\1");
882  result << tmp;
883  }
884  return result;
885  }
886  else {
887  return list;
888  }
889 }
890 
891 QStringList ParameterFileModel::_priorityTagFilter(QStringList list) const {
892  QStringList result;
893  foreach (const QString& cur, list) {
894  if (!cur.endsWith(".editorpriority", Qt::CaseInsensitive)) {
895  result << cur;
896  }
897  }
898  return result;
899 }
900 
901 QStringList ParameterFileModel::_priorityFilter(QStringList list) const {
902  if (_minPriority <= 0) {
903  return list;
904  }
905  QStringList result;
906  foreach (const QString& cur, list) {
907  if (getValue(cur+".editorpriority").toInt() >= _minPriority) {
908  result << cur;
909  }
910  }
911  return result;
912 }
913 
914 QString ParameterFileModel::getType(QString parName, bool tmplType) const {
915  if(!_useMetaInfo)
916  return QString();
917  QString cName = getClass(parName);
918  QString res;
919 
920  if (_metaInfos->isDynamic(cName)) {
921  QFileInfo fileInfo(_getDynamicMetaFile(parName.section(".",0,0)));
922  if (fileInfo.exists()) {
923  QParameterFile pFile(fileInfo.absoluteFilePath());
924  res = pFile.get(cName + "." + parName.section(".",1) + ".type");
925  }
926  }
927  if (res.isEmpty()) {
928  res = _metaInfos->getType(parName, cName);
929  }
930  if (tmplType && res.contains(
931  QRegExp("^\\s*(.*<\\s*T\\s*>.*|T)\\s*$",Qt::CaseInsensitive))) {
932  parName = parName.section(".",0,0);
933  QString tType = getValue(parName + ".templatetype");
934  if(tType.isEmpty()) {
935  tType = getDefault(parName + ".templatetype");
936  }
937  res.replace(
938  QRegExp("<\\s*T\\s*>",Qt::CaseInsensitive),
939  QString("<%1>").arg(tType));
940  res.replace(
941  QRegExp("^\\s*T\\s*$",Qt::CaseInsensitive),tType);
942  }
943  return res;
944 }
945 
946 QString ParameterFileModel::getValue(QString parName) const {
947  return _parameterFile -> get(parName);
948 }
949 
950 bool ParameterFileModel::isSet(QString parName) const {
951  return _parameterFile->isSet(parName);
952 }
953 
954 void ParameterFileModel::setValue(QString parName, QString value) {
955  if (isSet(parName) && getValue(parName) == value) {
956  return;
957  }
958 
959  // write value to parameter file
960  bool existed = isSet(parName);
961  _parameterFile -> set(parName, value);
962 
963  if (parName.endsWith(".editorcomment", Qt::CaseInsensitive)) {
964  emit commentChanged(value);
965  }
966 
967  if (existed) {
968  // parameter existed before, so inform about change,
969  // if parameter is visible
970  const QStringList& keys = _parameterFile -> getKeyList();
971  int i = keys.indexOf(parName);
972  if ( i >= 0) {
973  emit dataChanged(index(i, 1), index(i, 1));
974  }
975  }
976  else {
977  // parameter did not exist before,
978  // so perhaps it would appear and an update run is neccessary
979  _update();
980  }
981  emit modified(true);
982 }
983 
984 void ParameterFileModel::erase(QString parName) {
985  if (_parameterFile->isSet(parName)) {
986  int pos = _keys.indexOf(parName);
987  if (pos >= 0) {
988  beginRemoveRows(QModelIndex(),pos,pos);
989  }
990  _parameterFile -> erase(parName);
991  if (pos >= 0) {
992  endRemoveRows();
993  }
994  emit modified(true);
995  }
996 }
997 
998 bool ParameterFileModel::rename(QString oldPrefix, QString newPrefix) {
999  bool lock = _resetMutex->tryLock();
1000  if (lock) {
1001  beginResetModel();
1002  }
1003  setPrefix("");
1004  bool res = _parameterFile->rename(oldPrefix,newPrefix);
1005  if (lock) {
1006  endResetModel();
1007  _resetMutex->unlock();
1008  }
1009  if (res) {
1010  setPrefix(newPrefix);
1011  emit modified(true);
1012  }
1013  return res;
1014 }
1015 
1017  if (value < 0 || value > 3) {
1018  return;
1019  }
1020 
1021  _minPriority = value;
1022  _update();
1023 
1024  emit minPriorityChanged(value);
1025 }
1026 
1027 Qt::DropActions ParameterFileModel::supportedDropActions() const {
1028  return Qt::CopyAction | Qt::MoveAction;
1029 }
1030 
1031 QStringList ParameterFileModel::mimeTypes() const {
1032  QStringList list;
1033  list << "text/plain";
1034  list << "text/uri-list";
1035  return list;
1036 }
1037 
1038 bool ParameterFileModel::dropMimeData(const QMimeData* mData,
1039  Qt::DropAction action, int row, int column, const QModelIndex& pInd) {
1040 
1041  // only accept text and files
1042  QString content;
1043  if (mData->hasUrls()) {
1044  QList<QUrl> urlList = mData->urls();
1045  if (urlList.size() >= 1) {
1046  content = urlList.at(0).path();
1047  }
1048  for (int ii = 1; ii < urlList.size(); ii += 1) {
1049  content += ";" + urlList.at(ii).path();
1050  }
1051  } else if (mData->hasText()) {
1052  content = mData->text();
1053  } else {
1054  return QAbstractTableModel::dropMimeData(mData, action,
1055  row, column, pInd);
1056  }
1057 
1058  setData(pInd, content);
1059 
1060  return true;
1061 }
1062 
1063 QString ParameterFileModel::_getDynamicMetaFile(QString objName) const {
1064  const FileManager& fm = FileManager::instance();
1065  return fm.configDir().absoluteFilePath("dynamics/"
1066  + QFileInfo(_fileName).baseName() + "_" + objName + ".wrp");
1067 }
1068 
1069 QStringList ParameterFileModel::getInputs(QString objName) const {
1070  objName = objName.section(".",0,0);
1071  QString className = getClass(objName);
1072  if (_metaInfos->isDynamic(className)) {
1073  QFileInfo fileInfo(_getDynamicMetaFile(objName));
1074  if (fileInfo.exists()) {
1075  MetaData tmp(fileInfo.absoluteFilePath());
1076  return tmp.getInputs(className);
1077  }
1078  }
1079  return _metaInfos->getInputs(className);
1080 }
1081 
1082 QStringList ParameterFileModel::getInputDisplayNames(QString objName) const {
1083  objName = objName.section(".",0,0);
1084  QString className = getClass(objName);
1085  if (_metaInfos->isDynamic(className)) {
1086  QFileInfo fileInfo(_getDynamicMetaFile(objName));
1087  if (fileInfo.exists()) {
1088  MetaData tmp(fileInfo.absoluteFilePath());
1089  return tmp.getInputDisplayNames(className);
1090  }
1091  }
1092  return _metaInfos->getInputDisplayNames(className);
1093 }
1094 
1095 QStringList ParameterFileModel::getOutputs(QString objName) const {
1096  objName = objName.section(".",0,0);
1097  QString className = getClass(objName);
1098  if (_metaInfos->isDynamic(className)) {
1099  QFileInfo fileInfo(_getDynamicMetaFile(objName));
1100  if (fileInfo.exists()) {
1101  MetaData tmp(fileInfo.absoluteFilePath());
1102  return tmp.getOutputs(className);
1103  }
1104  }
1105  return _metaInfos->getOutputs(className);
1106 }
1107 
1108 QStringList ParameterFileModel::getOutputDisplayNames(QString objName) const {
1109  objName = objName.section(".",0,0);
1110  QString className = getClass(objName);
1111  if (_metaInfos->isDynamic(className)) {
1112  QFileInfo fileInfo(_getDynamicMetaFile(objName));
1113  if (fileInfo.exists()) {
1114  MetaData tmp(fileInfo.absoluteFilePath());
1115  return tmp.getOutputDisplayNames(className);
1116  }
1117  }
1118  return _metaInfos->getOutputDisplayNames(className);
1119 }
1120 
1121 
1122 QStringList ParameterFileModel::getParameters(QString objName) const {
1123  objName = objName.section(".",0,0);
1124  QString className = getClass(objName);
1125  if (_metaInfos->isDynamic(className)) {
1126  QFileInfo fileInfo(_getDynamicMetaFile(objName));
1127  if (fileInfo.exists()) {
1128  MetaData tmp(fileInfo.absoluteFilePath());
1129  return tmp.getParameters(className);
1130  }
1131  }
1132  return _metaInfos->getParameters(className);
1133 }
1134 
1135 bool ParameterFileModel::isParameter(QString name) const {
1136  QString obj = name.section(".",0,0);
1137  name = name.section(".",-1);
1138  QStringList list = getParameters(obj);
1139  return (list.indexOf(QRegExp(name,Qt::CaseInsensitive)) >= 0);
1140 }
1141 
1142 bool ParameterFileModel::isInputSlot(QString name) const {
1143  QString obj = name.section(".",0,0);
1144  name = name.section(".",-1);
1145  QStringList list = getInputs(obj);
1146  return (list.indexOf(QRegExp(name,Qt::CaseInsensitive)) >= 0);
1147 }
1148 
1149 bool ParameterFileModel::isOutputSlot(QString name) const {
1150  QString obj = name.section(".",0,0);
1151  name = name.section(".",-1);
1152  QStringList list = getOutputs(obj);
1153  return (list.indexOf(QRegExp(name,Qt::CaseInsensitive)) >= 0);
1154 }
1155 
1156 bool ParameterFileModel::isMultiSlot(QString slotName) const {
1157  QString className = getClass(slotName);
1158  QString objName = slotName.section(".",0,0);
1159  if (_metaInfos->isDynamic(className)) {
1160  QFileInfo fileInfo(_getDynamicMetaFile(objName));
1161  if (fileInfo.exists()) {
1162  MetaData tmp(fileInfo.absoluteFilePath());
1163  return tmp.isMultiSlot(slotName,className);
1164  }
1165  }
1166  return _metaInfos->isMultiSlot(slotName,className);
1167 }
1168 
1169 QString ParameterFileModel::getDoc(QString parName) const {
1170  QString className = getClass(parName);
1171  QString objName = parName.section(".",0,0);
1172  if (_metaInfos->isDynamic(className)) {
1173  QFileInfo fileInfo(_getDynamicMetaFile(objName));
1174  if (fileInfo.exists()) {
1175  MetaData tmp(fileInfo.absoluteFilePath());
1176  return tmp.getDocString(parName,className);
1177  }
1178  }
1179  return _metaInfos->getDocString(parName,className);
1180 }
1181 
1182 QStringList ParameterFileModel::getClasses() const {
1183  return _metaInfos->getClasses();
1184 }
1185 
1186 QString ParameterFileModel::getDefault(QString parName) const {
1187  QString className = getClass(parName);
1188  QString objName = parName.section(".",0,0);
1189 
1190  // handle default template type
1191  QRegExp ttype("(.*\\.)?templatetype",Qt::CaseInsensitive);
1192  QString defaultTmplType = getValue("global.templatetype");
1193  if (ttype.exactMatch(parName) && !defaultTmplType.isEmpty()) {
1194  return defaultTmplType;
1195  }
1196 
1197  if (_metaInfos->isDynamic(className)) {
1198  QFileInfo fileInfo(_getDynamicMetaFile(objName));
1199  if (fileInfo.exists()) {
1200  MetaData tmp(fileInfo.absoluteFilePath());
1201  return tmp.getDefault(parName,className);
1202  }
1203  }
1204  return _metaInfos->getDefault(parName,className);
1205 }
1206 
1208  return _metaInfos;
1209 }
bool _handleDynamics
handle dynamics by calling update-dynamics process
class for logging display and communication with external processes
Definition: LogDialog.h:47
void setOnlyParams(bool value)
Set property _onlyparams.
void reactivate()
Reactivate all following plugins.
void commentChanged(QString comment)
inform about editor comment change
void statusMessage(const QString &msg)
send status message
QString get(QString parameter) const
get parameter value
Declaration of class FileManager.
void erase(QString parName)
Delete a parameter from the the underlying parameter file.
virtual void save(const QString &fileName="")
Save model content to a text file.
void setMinPriority(int value)
Set property _minPriority.
Declaration of class PrefixValidator.
bool isMultiSlot(QString slotName, QString className) const
Check if some slot is a multi slot.
Definition: MetaData.cpp:125
virtual void _update()
Update content (e.g. when prefix has changed)
QParameterFile * _parameterFile
Pointer to the ParameterFile instance storing the model content.
virtual QString setPrefix(const QString &prefix)
Change prefix.
void setHandleDynamics(bool)
set _handleDynamics
bool rename(QString oldPrefix, QString newPrefix)
rename prefix
virtual ~ParameterFileModel()
Default destructor.
Declaration of class ParameterFileModel.
bool _useMetaInfo
toggle usage of metadata
void dynamicUpdate()
inform about dynamic plugin update
QStringList getClasses() const
get classes contained in metadata file
QString getType(QString parName, QString className) const
Get type of some parameter or slot.
Definition: MetaData.cpp:77
bool metaInfoValid() const
check for available metaInfos
QString getValue(QString parName) const
Get a parameter from the underlying parameter file.
static const FileManager & instance()
get a reference to the file Manager instance
Definition: FileManager.cpp:70
void fileNameChanged(QString fileName)
Property _fileName has changed.
Implementation of class ParameterFileModel.
QString _fileName
Store filename of the model data file.
const QParameterFile & parameterFile() const
Get const pointer of ParameterFile.
QMutex * _resetMutex
avoid multiple reset model calls
QString getDefault(QString parName) const
pass to metaInfo, use dynamic metadata if needed
bool isSet(QString parameter) const
check if a given parameter has been set
QStringList getParameters(QString className) const
get parameters of some given object
Definition: MetaData.cpp:72
Handle metadata management for ParameterFileModel classes.
Definition: MetaData.h:31
Mapping of types given as string to QVariant::type.
int _minPriority
minimum priority to be listed
QString getDefault(QString parName, QString className) const
get default value for some editable parameter
Definition: MetaData.cpp:86
QDir configDir() const
get config directory
Definition: FileManager.cpp:77
void _updateDynamics()
update dynamic objects
QStringList getInputs(QString objName) const
Get input slots of object.
Declaration of class QParameterFile.
QString prefix() const
Get property _prefix.
void load(QString fileName, QString encoding=QString())
load parameter file
QMap< QString, QString > _classCaseMap
map to fix class name cases
QString getDocString(QString parName, QString className) const
get docstring for some parameter or some class.
Definition: MetaData.cpp:93
QStringList getOutputs(QString objName) const
Get output slots of object.
QStringList getOutputDisplayNames(QString objName) const
Get output slots of object.
virtual void loadMetaInfo(const QString &fileName)
load metaFile
QStringList _keys
Cache stored parameter names.
Declaration of classes in the LogDecorators namespace.
Common config file information and handling.
Definition: FileManager.h:37
virtual void _updatePriority(const QModelIndex &topLeft, const QModelIndex &bottomRight)
Update filter if priority changed.
Declaration of class LogDialog.
QString getClass(QString objName, bool fixCase=false) const
get class of some given object
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const
Return number of table rows.
virtual bool insertRows(int row, int count, const QModelIndex &parent=QModelIndex())
Add data to the model.
bool isMultiSlot(QString name) const
Check if some slot is a multi slot.
const MetaData * _metaInfos
ParameterFile describing classes and in-/output slots.
QStringList getInputDisplayNames(QString objName) const
Get input slots of object.
bool isParameter(QString name) const
Check if some parameter/slot is a parameter.
Qt implementation for ParameterFile class.
bool hasErrorLines()
query for possible error lines in logfile
Definition: LogDialog.cpp:317
virtual QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const
Access to item content.
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const
Data for the table headers.
bool isSet(QString parName) const
pass to QParameterFile::isSet
bool _onlyParams
only show configurable parameters
bool prefixValid() const
Check prefix.
void deactivate()
Deactivate all following plugins.
QStringList getInputs(QString className) const
get output slots of some given object
Definition: MetaData.cpp:65
void useMetaInfoChanged(bool value)
Property _useMetadata changed.
virtual void setFileName(const QString &fileName)
Set new value for Property _fileName.
QStringList _prefixFilter(QStringList list) const
filter keys starting with the given prefix
void erase(QString parameter)
remove parameter from file
void prefixChanged(const QString &prefix)
Property _prefix has changed.
virtual bool load(const QString &fName="")
Load model content from parameterFile.
QString fileName() const
Get property _fileName.
QString getDoc(QString parName) const
pass to metaInfo, use dynamic metadata if needed
bool active() const
Returns the bool value of the Active Parameter.
bool rename(QString oldPrefix, QString newPrefix)
rename prefix
QStringList _collectObjects(QStringList list) const
Return set of objects contained in given parameter list.
virtual Qt::ItemFlags flags(const QModelIndex &index) const
Item flags (editable etc).
bool isOutputSlot(QString name) const
Check if some parameter/slot is an output slot.
void minPriorityChanged(int value)
Property _minPriority changed.
Convert parameter types into Qt versions.
Definition: VarTypeMap.h:36
static VarTypeMap & instance()
return reference to an VarTypeMap instance
Definition: VarTypeMap.cpp:46
void save(QString fileName) const
save to given plain text file
void reactivatePreviousPlugins()
Reactivates all previous plugins.
charon_core_DLL_PUBLIC std::string type(const std::string &typeInfo)
bool isDynamic(QString className) const
Check if module is dynamic.
Definition: MetaData.cpp:133
void setValue(QString parName, QString value)
Set a parameter in the underlying parameter file.
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const
Return number of table columns.
bool useMetaInfo() const
Get property _useMetadata;.
void metaInfoChanged(bool valid)
New metadata have been loaded.
QStringList getKeyList(QString beginsWith="") const
Look for parameters beginning with a given string.
void modified(bool val)
inform about modifications
virtual bool _load()
Load data without showing OpenFile Dialog.
bool onlyParams() const
Get property _onlyparams.
void setUseMetaInfo(bool value)
Set property _useMetadata.
void onlyParamsChanged(bool value)
Property _onlyParams changed.
decorator for update dynamics dialog
virtual void clear()
Clear ParameterFile content.
QString _getDynamicMetaFile(QString objName) const
creates path to dynamic meta info file for object
QStringList _paramFilter(QStringList list) const
filter keys listed in the classes parameter section
QStringList getOutputDisplayNames(QString className) const
get input slots of some given object
Definition: MetaData.cpp:159
QString getType(QString parName, bool applyTmplType=true) const
Get type of some parameter or slot.
QStringList getParameters(QString objName) const
Get parameters of object.
ParameterFileModel(QString fileName="", QObject *parent=0, QString metaFile="")
Constructor initializing the model with the given file.
QStringList getInputDisplayNames(QString className) const
get output slots of some given object
Definition: MetaData.cpp:142
QStringList getClasses() const
get classes contained in this metadata file
Definition: MetaData.cpp:55
void clear()
clear content
QStringList getOutputs(QString className) const
get input slots of some given object
Definition: MetaData.cpp:59
virtual bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex())
Remove data from the model.
bool waitForFinished(int msecs=1500)
wait for process to finish
Definition: LogDialog.cpp:237
int minPriority() const
Get property _minPriority.
bool isInputSlot(QString name) const
Check if some parameter/slot is an input slot.
virtual bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Set item content.
QStringList _priorityTagFilter(QStringList list) const
filter keys containing priority information
QStringList _priorityFilter(QStringList list) const
filter keys depending on their priority
QString _prefix
Parameter prefix.