QSS Solver GUI  4.5.3
modeleditor.cpp
Go to the documentation of this file.
1 /*****************************************************************************
2 
3  This file is part of QSS Solver.
4 
5  QSS Solver is free software: you can redistribute it and/or modify
6  it under the terms of the GNU 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  QSS Solver 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 General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with QSS Solver. If not, see <http://www.gnu.org/licenses/>.
17 
18  ******************************************************************************/
19 
20 #include <QFileDialog>
21 #include <QMessageBox>
22 #include <Qt>
23 
24 #include <modeleditor.hpp>
25 #include <mmohighlight.hpp>
26 #include <modelinfo.hpp>
27 #include <codeeditor.hpp>
28 
29 ModelEditor::ModelEditor(QWidget *parent, QString name)
30  : QDialog(parent),
31  _annotations(),
32  _defaultValues(),
33  _startTime(),
34  _stopTime(),
35  _tolerance(),
36  _absTolerance(),
37  _solver(),
38  _output(),
39  _outputType(),
40  _period(),
41  _lps(),
42  _description(),
43  _minstep(),
44  _zchyst(),
45  _derdelta(),
46  _scheduler(),
47  _symdiff(),
48  _dtSynch(),
49  _dtPeriod(),
50  _dtStepLog(),
51  _dt(),
52  _parallel(),
53  _partitionMethod(),
54  _jacobian(),
55  _patohSettings(),
56  _scotchSettings(),
57  _metisSettings(),
58  _generateArch(),
59  _debugGraph(),
60  _reorderPartition(),
61  _imbalance(),
62  _BDFPart(),
63  _BDFPartitionDepth(),
64  _BDFMaxStep(),
65  _semiStaticPartitioning(false),
66  _hl(NULL)
67 {
68  setupUi(this);
69  _defaultValues["MMO_Description"] = "";
70  _defaultValues["MMO_Solver"] = "QSS3";
71  _defaultValues["StartTime"] = "0.0";
72  _defaultValues["StopTime"] = "1.0";
73  _defaultValues["Tolerance"] = "1e-3";
74  _defaultValues["AbsTolerance"] = "1e-3";
75  _defaultValues["MMO_SymDiff"] = "true";
76  _defaultValues["MMO_Output"] = "";
77  _defaultValues["MMO_BDF_Part"] = "";
78  _defaultValues["MMO_OutputType"] = "CI_Step";
79  _defaultValues["MMO_Period"] = "1e-2";
80  _defaultValues["MMO_DT_Synch"] = "SD_DT_Asynchronous";
81  _defaultValues["MMO_LPS"] = "1";
82  _defaultValues["MMO_MinStep"] = "1e-14";
83  _defaultValues["MMO_ZCHyst"] = "1e-12";
84  _defaultValues["MMO_DerDelta"] = "1e-8";
85  _defaultValues["MMO_Scheduler"] = "ST_Binary";
86  _defaultValues["MMO_NodeSize"] = "10000";
87  _defaultValues["MMO_StoreData"] = "SD_Memory";
88  _defaultValues["MMO_Parallel"] = "false";
89  _defaultValues["MMO_PartitionMethod"] = "MetisCut";
90  _defaultValues["MMO_DT_Min"] = "0";
91  _defaultValues["MMO_Imbalance"] = "0.01";
92  _defaultValues["MMO_ReorderPartition"] = "false";
93  _defaultValues["MMO_DebugGraph"] = "false";
94  _defaultValues["MMO_GenerateArch"] = "false";
95  _defaultValues["MMO_BDF_PDepth"] = "1";
96  _defaultValues["MMO_BDF_Max_Step"] = "0";
97  _model_editor_tab = new QTabWidget(this);
98  _model_editor_tab->setTabsClosable(true);
99  _models = new QList<ModelInfo>();
100  _utils = new Utils();
101  connect(_model_editor_tab, &QTabWidget::tabCloseRequested, this, &ModelEditor::tabCloseRequested);
102  connect(_model_editor_tab, &QTabWidget::currentChanged, this, &ModelEditor::currentChanged);
103  _model_editor_hl->addWidget(_model_editor_tab);
104  editModel(name);
105 }
106 
108 {
109  delete _model_editor_tab;
110  delete _models;
111  delete _utils;
112 }
113 
114 void ModelEditor::editModel(QString name)
115 {
116  CodeEditor *_textEditor = new CodeEditor(this);
117  QString _mname(tr("New Model"));
118  QFile file(name);
119  QSettings settings(QCoreApplication::applicationDirPath() + "/qss-solver.ini", QSettings::IniFormat);
120  int _tab = settings.value("Editor/tab", "Value not found in file qss-solver.ini").toInt();
121  _textEditor->setTabStopDistance(_tab);
122  if (!file.fileName().isEmpty()) {
123  QFileInfo fi(name);
124  _mname = fi.fileName();
125  QIODevice::OpenModeFlag om = QIODevice::ReadWrite;
126  if (file.open(om)) {
127  _textEditor->setPlainText(file.readAll());
128  } else {
129  QMessageBox::critical(this, QString(tr("Error")), QString(tr("Can't open file.")));
130  return;
131  }
132  }
133  QTextDocument *td = new QTextDocument(_textEditor->toPlainText(), this);
134 
135  QPlainTextDocumentLayout *layout = new QPlainTextDocumentLayout(td);
136  td->setDocumentLayout(layout);
137  _textEditor->setDocument(td);
138  if (name.endsWith(QString(".log"))) {
139  _hl = new MmoHighlighter(_textEditor->document(), MmoHighlighter::MMO_LOG);
140  } else {
141  _hl = new MmoHighlighter(_textEditor->document(), MmoHighlighter::MMO_MODEL);
142  }
143  connect(_textEditor, &CodeEditor::textChanged, this, &ModelEditor::textChanged);
144  setWindowTitle(_mname);
145  _models->append(ModelInfo(name));
146  _model_editor_tab->setCurrentIndex(_model_editor_tab->addTab(_textEditor, _mname));
147 }
148 
149 void ModelEditor::keyReleaseEvent(QKeyEvent *event)
150 {
151  int ci = _model_editor_tab->currentIndex();
152  if (event->nativeScanCode() == 117 && (event->nativeModifiers() & 4)) {
153  _model_editor_tab->setCurrentIndex((ci + 1) % _model_editor_tab->count());
154  } else if (event->nativeScanCode() == 112 && (event->nativeModifiers() & 4)) {
155  _model_editor_tab->setCurrentIndex(ci > 0 ? ci - 1 : _model_editor_tab->count() - 1);
156  } else {
157  QWidget::keyReleaseEvent(event);
158  }
159 }
160 
162 {
163  int idx = _model_editor_tab->currentIndex();
164  return fileName(idx);
165 }
166 
168 {
169  int idx = _model_editor_tab->currentIndex();
170  if (idx < 0) {
171  return false;
172  }
173  return _models->value(idx).dirty();
174 }
175 
176 QString ModelEditor::fileName(int idx)
177 {
178  if (idx < 0) {
179  return QString();
180  }
181  return _models->value(idx).name();
182 }
183 
185 {
186  int idx = _model_editor_tab->currentIndex();
187  return baseFileName(idx);
188 }
189 
191 {
192  if (idx < 0) {
193  return QString();
194  }
195  return _models->value(idx).baseName();
196 }
197 
199 {
200  int idx = _model_editor_tab->currentIndex();
201  return fullFileName(idx);
202 }
203 
205 {
206  if (idx < 0) return QString();
207  return _models->value(idx).fullname();
208 }
209 
211 {
212  int idx = _model_editor_tab->currentIndex();
213  ModelInfo mi = _models->value(idx);
214  if (mi.init()) {
215  mi.setInit(false);
216  _models->replace(idx, mi);
217  return;
218  }
219  if (!_models->value(idx).name().endsWith(".log")) {
220  if (!_models->value(idx).dirty()) {
221  mi.setDirty(true);
222  _models->replace(idx, mi);
223  _model_editor_tab->setTabText(idx, _model_editor_tab->tabText(idx) + QString("*"));
224  }
225  }
226 }
227 
229 {
230  if (index < 0) {
231  return;
232  }
233  setWindowTitle(_model_editor_tab->tabText(index));
234 }
235 
237 {
238  if (index < 0) {
239  return;
240  }
241  ModelInfo mi = _models->value(index);
242  if (!mi.isLogFile()) {
243  if (mi.dirty()) {
244  QMessageBox::StandardButton res = QMessageBox::question(this, "Save", QString("Save changes to file ") + mi.name() + QString("?"),
245  QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
246  if (res == QMessageBox::Save) {
247  save(index);
248  } else if (res == QMessageBox::Cancel) {
249  return;
250  }
251  }
252  } else {
253  _models->replace(index, mi);
254  }
255  remove(index);
256 }
257 
259 {
260  foreach (ModelInfo mi, *_models) {
262  }
263 }
264 
265 void ModelEditor::remove(int tab)
266 {
267  QString name = baseFileName(tab);
268  QString ext = fullFileName(tab);
269  _models->removeAt(tab);
270  QTextEdit *_textEditor = qobject_cast<QTextEdit *>(_model_editor_tab->widget(tab));
271  _model_editor_tab->removeTab(tab);
272  delete _textEditor;
273  emit done(name, ext);
274 }
275 
277 {
278  int idx = _model_editor_tab->currentIndex();
279  if (idx < 0) return;
280  if (checkPackage()) {
281  deletePackageFiles(idx);
282  }
283  save(idx);
284  emit clean(idx);
285 }
286 
287 void ModelEditor::saveAs(QString name)
288 {
289  int idx = _model_editor_tab->currentIndex();
290  if (idx < 0) {
291  return;
292  }
293  ModelInfo mi = _models->value(idx);
294  if (mi.fullname().isEmpty()) {
295  save(idx);
296  } else {
297  QFile file(mi.fullname());
298  file.copy(name);
299  file.close();
300  }
301  mi.setFullname(name);
302  mi.setDirty(false);
303  _models->replace(idx, mi);
304  _model_editor_tab->setTabText(idx, mi.name());
305 }
306 
308 {
309  int _tab = 0;
310  foreach (ModelInfo mi, *_models) {
311  if (mi.dirty()) {
312  save(_tab);
313  }
314  _tab++;
315  }
316 }
317 
319 {
320  QString fileName = QFileDialog::getSaveFileName(this, tr("Save"), _utils->appDir(MMOC_MODELS), "MicroModelica *.mo (*.mo)");
321  if (!fileName.isEmpty() && !fileName.endsWith(".mo")) {
322  fileName.append(".mo");
323  }
324  return fileName;
325 }
326 
327 void ModelEditor::save(int tab)
328 {
329  ModelInfo mi = _models->value(tab);
330  if (mi.fullname().isEmpty()) {
331  mi.setFullname(newFileName());
332  }
333  if (mi.fullname().isEmpty()) {
334  return;
335  }
336  QFile file(mi.fullname());
337  if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) {
338  QMessageBox::critical(this, QString(tr("Error")), QString(tr("Can't open file ")) + mi.name());
339  file.close();
340  return;
341  }
342  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
343  if (!_textEditor) {
344  QMessageBox::critical(this, QString(tr("Error")), QString(tr("Can't open text editor.")));
345  file.close();
346  return;
347  }
348  QString _data = _textEditor->toPlainText();
349  if (file.write(_data.toStdString().c_str()) == -1) {
350  QMessageBox::critical(this, QString(tr("Error")), QString(tr("Can't write data ")) + mi.name());
351  file.close();
352  return;
353  }
354  if (!file.flush()) {
355  QMessageBox::critical(this, QString(tr("Error")), QString(tr("Can't save file ")) + mi.name());
356  file.close();
357  return;
358  }
359  _model_editor_tab->setTabText(tab, mi.name());
360  _textEditor->document()->setModified(false);
361  mi.setDirty(false);
362  _models->replace(tab, mi);
363 }
364 
365 QString ModelEditor::getAnnotationValue(QString value, QString token)
366 {
367  QStringList values = value.split("=");
368  QString tmpValue;
369  if (token == "MMO_Output" || token == "MMO_BDF_Part") {
370  int index = value.indexOf("=");
371  for (int a = index + 1; a < value.size(); a++) {
372  tmpValue += value[a];
373  }
374  } else {
375  tmpValue = values[1];
376  }
377  if (tmpValue.size() == 1) {
378  return QString();
379  }
380  values = tmpValue.split("{");
381  if (values.size() > 1) {
382  return values[1].split("}")[0];
383  }
384  return tmpValue.split(",")[0];
385 }
386 
387 int ModelEditor::tokenPosition(QString token)
388 {
389  int tab = _model_editor_tab->currentIndex();
390  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
391  QTextCursor tc = _textEditor->textCursor();
392  tc.movePosition(QTextCursor::Start);
393  _textEditor->setTextCursor(tc);
394  if (_textEditor->find(token)) {
395  return _textEditor->textCursor().position();
396  }
397  return 0;
398 }
399 
401 {
402  QStringList ret;
403  for (int i = 0; i < _model_editor_tab->count(); i++) {
404  ret << baseFileName(i);
405  }
406  return ret;
407 }
408 
410 {
411  int tab = _model_editor_tab->currentIndex();
412  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
413  QTextCursor tc = _textEditor->textCursor();
414  tc.select(QTextCursor::LineUnderCursor);
415  QString line = tc.selection().toPlainText();
416  return line.isEmpty();
417 }
418 
419 void ModelEditor::setAnnotations(QString tag, QString value, bool separator)
420 {
421  QString add = value;
422  if (tag == "Tolerance" || tag == "AbsTolerance" || tag == "MMO_Output" || tag == "MMO_Period" || tag == "MMO_PatohSettings" ||
423  tag == "MMO_ScotchSettings" || tag == "MMO_BDF_Part" || tag == "MMO_MetisSettings") {
424  add.prepend("{");
425  add.append("}");
426  }
427  if (separator) {
428  addLine(QString("\t\t").append(tag).append("=").append(add).append(","));
429  } else {
430  addLine(QString("\t\t").append(tag).append("=").append(add));
431  }
432 }
433 
434 bool ModelEditor::checkToken(QString str)
435 {
436  int tab = _model_editor_tab->currentIndex();
437  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
438  QTextCursor tc = _textEditor->textCursor();
439  tc.movePosition(QTextCursor::Start);
440  _textEditor->setTextCursor(tc);
441  return _textEditor->find(str);
442 }
443 
445 {
446  QString mName = modelName();
447  int endModelPos = endModel();
448  int tab = _model_editor_tab->currentIndex();
449  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
450  QTextCursor tc = _textEditor->textCursor();
451  tc.movePosition(QTextCursor::Start);
452  _textEditor->setTextCursor(tc);
453  QString line;
454  QString end = "end ";
455  end.append(mName).append(";");
456  if (_textEditor->find("model ")) {
457  tc = _textEditor->textCursor();
458  int beginModel = tc.position();
459  int pos = checkFunctions(beginModel, endModelPos);
460  tc.setPosition(pos);
461  _textEditor->setTextCursor(tc);
462  if (_textEditor->find(QString("experiment"))) {
463  QString annotEnd("));");
464  tc = _textEditor->textCursor();
465  if (tc.position() > endModelPos) {
466  return true;
467  }
468  tc.select(QTextCursor::LineUnderCursor);
469  line = tc.selection().toPlainText();
470  if (!line.endsWith(annotEnd)) {
471  _textEditor->moveCursor(QTextCursor::Down);
472  tc = _textEditor->textCursor();
473  tc.select(QTextCursor::LineUnderCursor);
474  line = tc.selection().toPlainText();
475  int c = 0;
476  while (!line.endsWith(annotEnd) && c < 100) {
477  _textEditor->moveCursor(QTextCursor::Down);
478  tc = _textEditor->textCursor();
479  tc.select(QTextCursor::LineUnderCursor);
480  line = tc.selection().toPlainText();
481  c++;
482  }
483  }
484  _textEditor->moveCursor(QTextCursor::Down);
485  tc = _textEditor->textCursor();
486  tc.select(QTextCursor::LineUnderCursor);
487  line = tc.selection().toPlainText();
488  int c = 0;
489  while (line.isEmpty() && c < 100) {
490  _textEditor->moveCursor(QTextCursor::Down);
491  tc = _textEditor->textCursor();
492  tc.select(QTextCursor::LineUnderCursor);
493  line = tc.selection().toPlainText();
494  c++;
495  }
496  return line.contains(end);
497  }
498  }
499  return true;
500 }
501 
502 QString ModelEditor::getAnnotations(QString str)
503 {
504  int endModelPos = endModel();
505  QString mName = modelName();
506  int tab = _model_editor_tab->currentIndex();
507  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
508  QTextCursor tc = _textEditor->textCursor();
509  tc.movePosition(QTextCursor::Start);
510  _textEditor->setTextCursor(tc);
511  QString line;
512  QString end = "end ";
513  end.append(mName).append(";");
514  QString annotations;
515  if (_textEditor->find(end)) {
516  if (_textEditor->find("experiment", QTextDocument::FindBackward)) {
517  tc = _textEditor->textCursor();
518  if (_textEditor->find("annotation", QTextDocument::FindBackward)) {
519  tc = _textEditor->textCursor();
520  if (tc.position() > endModelPos) {
521  return QString();
522  }
523  int np = tc.position();
524  tc.select(QTextCursor::BlockUnderCursor);
525  line = tc.selection().toPlainText();
526  if (!line.contains("experiment")) {
527  _textEditor->moveCursor(QTextCursor::Down);
528  tc = _textEditor->textCursor();
529  int ep = controlEmptyLines(tc.position());
530  if (ep > endModelPos) {
531  return QString();
532  }
533  tc.setPosition(ep);
534  tc.select(QTextCursor::BlockUnderCursor);
535  line = tc.selection().toPlainText();
536  if (!line.contains("experiment")) {
537  return QString();
538  }
539  }
540  tc.setPosition(np);
541  tc.select(QTextCursor::BlockUnderCursor);
542  line = tc.selection().toPlainText();
543  if (line.contains(end)) return QString();
544  tc = _textEditor->textCursor();
545  tc.select(QTextCursor::BlockUnderCursor);
546  line = tc.selection().toPlainText();
547  int c = 0;
548  while (!line.contains(end) && c < 100) {
549  tc.select(QTextCursor::BlockUnderCursor);
550  _textEditor->moveCursor(QTextCursor::Down);
551  tc = _textEditor->textCursor();
552  tc.select(QTextCursor::BlockUnderCursor);
553  line = tc.selection().toPlainText();
554  annotations.append(line.trimmed());
555  c++;
556  }
557  } else {
558  _textEditor->moveCursor(QTextCursor::Down);
559  }
560  }
561  }
562  QStringList annotationValue = annotations.split(str);
563 
564  if (annotationValue.size() > 1) {
565  return getAnnotationValue(annotationValue[1], str);
566  } else if (_defaultValues.contains(str)) {
567  return _defaultValues[str];
568  }
569  return QString();
570 }
571 
572 QString ModelEditor::findValue(QString token, QString str)
573 {
574  if (_defaultValues.contains(token)) {
575  if (_defaultValues[token] == str) {
576  return QString();
577  }
578  }
579  return str;
580 }
581 
582 int ModelEditor::checkFunctions(int modelInit, int modelEnd)
583 {
584  int tab = _model_editor_tab->currentIndex();
585  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
586  QTextCursor tc = _textEditor->textCursor();
587  tc.setPosition(modelInit);
588  _textEditor->setTextCursor(tc);
589  if (_textEditor->find("function ")) {
590  QString fname;
591  tc = _textEditor->textCursor();
592  if (tc.position() <= modelEnd) {
593  tc.select(QTextCursor::LineUnderCursor);
594  fname = tc.selection().toPlainText().remove("function ").trimmed();
595  int lastFunction = tc.position();
596  _textEditor->moveCursor(QTextCursor::Down);
597  while (_textEditor->find("function ")) {
598  tc = _textEditor->textCursor();
599  if (tc.position() > modelEnd) {
600  break;
601  }
602  tc.select(QTextCursor::LineUnderCursor);
603  fname = tc.selection().toPlainText().remove("function ").trimmed();
604  lastFunction = tc.position();
605  _textEditor->moveCursor(QTextCursor::Down);
606  }
607  tc.setPosition(lastFunction);
608  _textEditor->setTextCursor(tc);
609  if (_textEditor->find("end " + fname)) {
610  return _textEditor->textCursor().position();
611  }
612  }
613  }
614  return modelInit;
615 }
616 
618 {
619  int tab = _model_editor_tab->currentIndex();
620  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
621  QTextCursor tc = _textEditor->textCursor();
622  tc.setPosition(position);
623  _textEditor->setTextCursor(tc);
624  tc.select(QTextCursor::LineUnderCursor);
625  QString line = tc.selection().toPlainText();
626  int c = 0;
627  while (line.isEmpty() && c < 100) {
628  _textEditor->moveCursor(QTextCursor::Down);
629  tc = _textEditor->textCursor();
630  tc.select(QTextCursor::LineUnderCursor);
631  line = tc.selection().toPlainText();
632  c++;
633  }
634  return tc.position();
635 }
636 
638 {
639  if (!checkAnnotations()) {
640  QMessageBox::information(this, "Simulation Settings", "Simulation annotations must be located at the end of the file.");
641  return;
642  }
643  int endModelPos = endModel();
644  QString mName = modelName();
645  int tab = _model_editor_tab->currentIndex();
646  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
647  QTextCursor tc = _textEditor->textCursor();
648  tc.movePosition(QTextCursor::Start);
649  _textEditor->setTextCursor(tc);
650  QString line;
651  QString end = "end ";
652  end.append(mName).append(";");
653  if (_textEditor->find(end)) {
654  if (_textEditor->find("experiment", QTextDocument::FindBackward)) {
655  tc = _textEditor->textCursor();
656  if (_textEditor->find("annotation", QTextDocument::FindBackward)) {
657  tc = _textEditor->textCursor();
658  if (tc.position() > endModelPos) {
659  return;
660  }
661  int np = tc.position();
662  tc.select(QTextCursor::BlockUnderCursor);
663  line = tc.selection().toPlainText();
664  if (!line.contains("experiment")) {
665  _textEditor->moveCursor(QTextCursor::Down);
666  tc = _textEditor->textCursor();
667  int ep = controlEmptyLines(tc.position());
668  if (ep > endModelPos) {
669  return;
670  }
671  tc.setPosition(ep);
672  tc.select(QTextCursor::BlockUnderCursor);
673  line = tc.selection().toPlainText();
674  if (!line.contains("experiment")) {
675  return;
676  }
677  }
678  tc.setPosition(np);
679  tc.select(QTextCursor::BlockUnderCursor);
680  line = tc.selection().toPlainText();
681  tc.removeSelectedText();
682  if (line.contains(end)) return;
683  tc = _textEditor->textCursor();
684  tc.select(QTextCursor::BlockUnderCursor);
685  line = tc.selection().toPlainText();
686  int c = 0;
687  while (!line.contains(end) && c < 100) {
688  tc.removeSelectedText();
689  tc.select(QTextCursor::BlockUnderCursor);
690  _textEditor->moveCursor(QTextCursor::Down);
691  tc = _textEditor->textCursor();
692  tc.select(QTextCursor::BlockUnderCursor);
693  line = tc.selection().toPlainText();
694  c++;
695  }
696  } else {
697  _textEditor->moveCursor(QTextCursor::Down);
698  }
699  QString text = _textEditor->toPlainText();
700  text = text.trimmed();
701  _textEditor->setPlainText(text);
702  }
703  }
704 }
705 
707 {
708  ModelInfo mi = _models->value(idx);
709  QString bfn = mi.baseName();
710  QString path = mi.path();
711  QFile file(path + "/" + "pkg_" + bfn + ".moo");
712  file.remove();
713 }
714 
716 {
717  int tab = _model_editor_tab->currentIndex();
718  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
719  QTextCursor tc = _textEditor->textCursor();
720  tc.movePosition(QTextCursor::Start);
721  _textEditor->setTextCursor(tc);
722  QString line;
723  if (_textEditor->find(QString("model "))) {
724  tc = _textEditor->textCursor();
725  tc.select(QTextCursor::LineUnderCursor);
726  line = tc.selection().toPlainText();
727  return line.remove("model ").trimmed();
728  }
729  return "";
730 }
731 
732 void ModelEditor::searchFixedAnnot(QStringList annotations)
733 {
734  for (const auto &annotation : annotations) {
735  QString annot_value = getAnnotations(annotation);
736  if (!annot_value.isEmpty()) {
737  _fixed_annotations.insert(annotation, annot_value);
738  }
739  }
740 }
741 
743 {
744  for (auto it = _fixed_annotations.begin(); it != _fixed_annotations.end(); ++it) {
745  setAnnotations(it.key(), it.value(), true);
746  }
747 }
748 
750 {
751  QString mName = modelName();
752  // Search and store fixed user annotations to write them back later.
753  searchFixedAnnot({"MMO_RandomSeed", "MMO_XOutput", "MMO_CVODEMaxOrder"});
754 
756  int tab = _model_editor_tab->currentIndex();
757  CodeEditor *_textEditor = qobject_cast<CodeEditor *>(_model_editor_tab->widget(tab));
758  QString end = "end ";
759  end.append(mName).append(";");
760  addLine(QString("\tannotation("));
761  addLine(QString("\texperiment("));
762  setAnnotations("MMO_Description", _description, true);
763  setAnnotations("MMO_Solver", _solver, true);
764  if (!_minstep.isEmpty()) setAnnotations("MMO_MinStep", _minstep, true);
765  if (!_zchyst.isEmpty()) setAnnotations("MMO_ZCHyst", _zchyst, true);
766  if (!_derdelta.isEmpty()) setAnnotations("MMO_DerDelta", _derdelta, true);
767  if (!_symdiff.isEmpty()) setAnnotations("MMO_SymDiff", _symdiff, true);
768  if (!_period.isEmpty()) setAnnotations("MMO_Period", _period, true);
769  if (!_parallel.isEmpty()) setAnnotations("MMO_Parallel", _parallel, true);
770  if (!_partitionMethod.isEmpty()) setAnnotations("MMO_PartitionMethod", _partitionMethod, true);
771  if (!_lps.isEmpty()) setAnnotations("MMO_LPS", _lps, true);
772  if (!_dtSynch.isEmpty()) setAnnotations("MMO_DT_Synch", _dtSynch, true);
773  if (!_dtPeriod.isEmpty()) setAnnotations("MMO_DT_SynchPeriod", _dtPeriod, true);
774  if (!_dtStepLog.isEmpty()) setAnnotations("MMO_DT_StepLog", _dtStepLog, true);
775  if (!_dt.isEmpty()) setAnnotations("MMO_DT_Min", _dt, true);
776  if (!_output.isEmpty()) setAnnotations("MMO_Output", _output, true);
777  if (!_outputType.isEmpty()) setAnnotations("MMO_OutputType", _outputType, true);
778  if (!_scheduler.isEmpty()) setAnnotations("MMO_Scheduler", _scheduler, true);
779  if (!_patohSettings.isEmpty()) setAnnotations("MMO_PatohSettings", _patohSettings, true);
780  if (!_scotchSettings.isEmpty()) setAnnotations("MMO_ScotchSettings", _scotchSettings, true);
781  if (!_metisSettings.isEmpty()) setAnnotations("MMO_MetisSettings", _metisSettings, true);
782  if (!_jacobian.isEmpty()) setAnnotations("Jacobian", _jacobian, true);
783  if (!_imbalance.isEmpty()) setAnnotations("MMO_Imbalance", _imbalance, true);
784  if (!_debugGraph.isEmpty()) setAnnotations("MMO_DebugGraph", _debugGraph, true);
785  if (!_reorderPartition.isEmpty()) setAnnotations("MMO_ReorderPartition", _reorderPartition, true);
786  if (!_generateArch.isEmpty()) setAnnotations("MMO_GenerateArch", _generateArch, true);
787  if (!_BDFPart.isEmpty()) setAnnotations("MMO_BDF_Part", _BDFPart, true);
788  if (!_BDFPartitionDepth.isEmpty()) setAnnotations("MMO_BDF_PDepth", _BDFPartitionDepth, true);
789  if (!_BDFMaxStep.isEmpty()) setAnnotations("MMO_BDF_Max_Step", _BDFMaxStep, true);
790  addFixedAnnot();
791  setAnnotations("StartTime", _startTime, true);
792  setAnnotations("StopTime", _stopTime, true);
793  setAnnotations("Tolerance", _tolerance, true);
794  setAnnotations("AbsTolerance", _absTolerance, false);
795  addLine(QString("\t));"));
796  QTextCursor tc = _textEditor->textCursor();
797  tc.movePosition(QTextCursor::Start);
798  _textEditor->setTextCursor(tc);
799  if (_textEditor->find(end)) {
800  tc = _textEditor->textCursor();
801  tc.select(QTextCursor::LineUnderCursor);
802  tc.removeSelectedText();
803  _textEditor->moveCursor(QTextCursor::Up);
804  tc = _textEditor->textCursor();
805  tc.select(QTextCursor::LineUnderCursor);
806  QString line = tc.selection().toPlainText();
807  int c = 0;
808  while (line.isEmpty() && c < 100) {
809  _textEditor->moveCursor(QTextCursor::Up);
810  tc = _textEditor->textCursor();
811  tc.select(QTextCursor::LineUnderCursor);
812  line = tc.selection().toPlainText();
813  c++;
814  }
815  _textEditor->moveCursor(QTextCursor::Down);
816  foreach (QString an, _annotations) {
817  tc = _textEditor->textCursor();
818  if (tc.atEnd()) {
819  _textEditor->insertPlainText("\n");
820  } else {
821  tc.select(QTextCursor::LineUnderCursor);
822  line = tc.selection().toPlainText();
823  if (!line.isEmpty()) {
824  _textEditor->moveCursor(QTextCursor::Up);
825  _textEditor->insertPlainText("\n");
826  }
827  }
828  _textEditor->insertPlainText(an);
829  _textEditor->moveCursor(QTextCursor::Down);
830  }
831  tc = _textEditor->textCursor();
832  if (tc.atEnd()) {
833  _textEditor->insertPlainText("\n");
834  } else {
835  tc.select(QTextCursor::LineUnderCursor);
836  line = tc.selection().toPlainText();
837  if (!line.isEmpty()) {
838  _textEditor->moveCursor(QTextCursor::Up);
839  _textEditor->insertPlainText("\n");
840  }
841  }
842  _textEditor->insertPlainText(end);
843  tc = _textEditor->textCursor();
844  if (tc.atEnd()) {
845  _textEditor->insertPlainText("\n");
846  }
847  }
848  _annotations.clear();
849  _fixed_annotations.clear();
850 }
ModelEditor::checkPackage
bool checkPackage()
Definition: modeleditor.hpp:44
ModelEditor::_parallel
QString _parallel
Definition: modeleditor.hpp:185
ModelEditor::_reorderPartition
QString _reorderPartition
Definition: modeleditor.hpp:193
ModelEditor::activeDirty
bool activeDirty()
Definition: modeleditor.cpp:167
ModelInfo::setInit
void setInit(bool d)
Definition: modelinfo.hpp:53
ModelEditor::_metisSettings
QString _metisSettings
Definition: modeleditor.hpp:190
ModelEditor::checkAnnotations
bool checkAnnotations()
Definition: modeleditor.cpp:444
ModelEditor::_generateArch
QString _generateArch
Definition: modeleditor.hpp:191
ModelEditor::_imbalance
QString _imbalance
Definition: modeleditor.hpp:194
ModelEditor::currentChanged
void currentChanged(int index)
Definition: modeleditor.cpp:228
ModelInfo
Definition: modelinfo.hpp:24
ModelEditor::_scheduler
QString _scheduler
Definition: modeleditor.hpp:179
ModelEditor::done
void done(QString name, QString ext)
ModelInfo::baseName
QString baseName()
Definition: modelinfo.cpp:31
ModelEditor::_annotations
QStringList _annotations
Definition: modeleditor.hpp:164
ModelInfo::setFullname
void setFullname(QString fn)
Definition: modelinfo.hpp:52
ModelEditor::addLine
void addLine(QString str)
Definition: modeleditor.hpp:142
ModelEditor::keyReleaseEvent
void keyReleaseEvent(QKeyEvent *event)
Definition: modeleditor.cpp:149
ModelEditor::_BDFMaxStep
QString _BDFMaxStep
Definition: modeleditor.hpp:197
MMOC_MODELS
@ MMOC_MODELS
Definition: utils.hpp:45
ModelEditor::activeFileName
QString activeFileName()
Definition: modeleditor.cpp:161
ModelEditor::_patohSettings
QString _patohSettings
Definition: modeleditor.hpp:188
ModelEditor::_dt
QString _dt
Definition: modeleditor.hpp:184
ModelEditor::tabCloseRequested
void tabCloseRequested(int index)
Definition: modeleditor.cpp:236
MmoHighlighter
Definition: mmohighlight.hpp:27
mmohighlight.hpp
ModelEditor::_outputType
QString _outputType
Definition: modeleditor.hpp:172
ModelEditor::_dtPeriod
QString _dtPeriod
Definition: modeleditor.hpp:182
modelinfo.hpp
ModelEditor::fileName
QString fileName(int idx)
Definition: modeleditor.cpp:176
ModelEditor::_hl
MmoHighlighter * _hl
Definition: modeleditor.hpp:203
ModelEditor::checkFunctions
int checkFunctions(int modelInit, int modelEnd)
Definition: modeleditor.cpp:582
Utils
Definition: utils.hpp:60
ModelInfo::path
QString path()
Definition: modelinfo.cpp:43
codeeditor.hpp
ModelEditor::_solver
QString _solver
Definition: modeleditor.hpp:170
ModelEditor::_fixed_annotations
QMap< QString, QString > _fixed_annotations
Definition: modeleditor.hpp:199
ModelEditor::_absTolerance
QString _absTolerance
Definition: modeleditor.hpp:169
ModelEditor::setAnnotations
void setAnnotations(QString str, QString value, bool separator)
Definition: modeleditor.cpp:419
ModelEditor::baseFileName
QString baseFileName(int idx)
Definition: modeleditor.cpp:190
ModelEditor::remove
void remove(int tab)
Definition: modeleditor.cpp:265
modeleditor.hpp
ModelEditor::_jacobian
QString _jacobian
Definition: modeleditor.hpp:187
ModelEditor::_lps
QString _lps
Definition: modeleditor.hpp:174
ModelEditor::modelName
QString modelName()
Definition: modeleditor.cpp:715
ModelEditor::_scotchSettings
QString _scotchSettings
Definition: modeleditor.hpp:189
ModelEditor::_output
QString _output
Definition: modeleditor.hpp:171
ModelInfo::fullname
QString fullname()
Definition: modelinfo.hpp:47
ModelEditor::_BDFPartitionDepth
QString _BDFPartitionDepth
Definition: modeleditor.hpp:196
ModelEditor::getAnnotations
QString getAnnotations(QString str)
Definition: modeleditor.cpp:502
ModelEditor::_partitionMethod
QString _partitionMethod
Definition: modeleditor.hpp:186
ModelEditor::findValue
QString findValue(QString token, QString str)
Definition: modeleditor.cpp:572
ModelEditor::checkToken
bool checkToken(QString str)
Definition: modeleditor.cpp:434
ModelEditor::_utils
Utils * _utils
Definition: modeleditor.hpp:202
ModelEditor::addFixedAnnot
void addFixedAnnot()
Definition: modeleditor.cpp:742
ModelEditor::_period
QString _period
Definition: modeleditor.hpp:173
ModelEditor::textChanged
void textChanged()
Definition: modeleditor.cpp:210
ModelEditor::closeFiles
void closeFiles()
Definition: modeleditor.cpp:258
ModelEditor::lineEmpty
bool lineEmpty()
Definition: modeleditor.cpp:409
ModelEditor::save
void save(void)
Definition: modeleditor.cpp:276
ModelEditor::controlEmptyLines
int controlEmptyLines(int position)
Definition: modeleditor.cpp:617
ModelEditor::deleteAnnotations
void deleteAnnotations()
Definition: modeleditor.cpp:637
ModelEditor::_description
QString _description
Definition: modeleditor.hpp:175
ModelEditor::_BDFPart
QString _BDFPart
Definition: modeleditor.hpp:195
ModelEditor::_debugGraph
QString _debugGraph
Definition: modeleditor.hpp:192
ModelInfo::init
bool init()
Definition: modelinfo.hpp:48
ModelEditor::_models
QList< ModelInfo > * _models
Definition: modeleditor.hpp:201
ModelEditor::saveAll
void saveAll(void)
Definition: modeleditor.cpp:307
ModelEditor::_dtStepLog
QString _dtStepLog
Definition: modeleditor.hpp:183
ModelEditor::beginModel
int beginModel()
Definition: modeleditor.hpp:143
ModelEditor::endModel
int endModel()
Definition: modeleditor.hpp:144
ModelInfo::isLogFile
bool isLogFile() const
Definition: modelinfo.cpp:49
ModelEditor::deletePackageFiles
void deletePackageFiles(int idx)
Definition: modeleditor.cpp:706
ModelEditor::_stopTime
QString _stopTime
Definition: modeleditor.hpp:167
ModelEditor::activeBaseFileName
QString activeBaseFileName()
Definition: modeleditor.cpp:184
ModelEditor::getAnnotationValue
QString getAnnotationValue(QString value, QString token)
Definition: modeleditor.cpp:365
ModelEditor::_minstep
QString _minstep
Definition: modeleditor.hpp:176
CodeEditor
Definition: codeeditor.hpp:80
ModelEditor::~ModelEditor
~ModelEditor()
Definition: modeleditor.cpp:107
ModelEditor::ModelEditor
ModelEditor(QWidget *parent=NULL, QString name=QString())
Definition: modeleditor.cpp:29
ModelInfo::name
QString name() const
Definition: modelinfo.cpp:37
ModelEditor::writeAnnotations
void writeAnnotations()
Definition: modeleditor.cpp:749
ModelEditor::_dtSynch
QString _dtSynch
Definition: modeleditor.hpp:181
ModelEditor::fullFileName
QString fullFileName(int idx)
Definition: modeleditor.cpp:204
ModelEditor::activeFullFileName
QString activeFullFileName()
Definition: modeleditor.cpp:198
ModelEditor::_zchyst
QString _zchyst
Definition: modeleditor.hpp:177
ModelEditor::_defaultValues
QMap< QString, QString > _defaultValues
Definition: modeleditor.hpp:165
ModelEditor::_symdiff
QString _symdiff
Definition: modeleditor.hpp:180
ModelEditor::fileNames
QStringList fileNames()
Definition: modeleditor.cpp:400
ModelEditor::_model_editor_tab
QTabWidget * _model_editor_tab
Definition: modeleditor.hpp:200
ModelEditor::_startTime
QString _startTime
Definition: modeleditor.hpp:166
ModelEditor::_derdelta
QString _derdelta
Definition: modeleditor.hpp:178
ModelEditor::_tolerance
QString _tolerance
Definition: modeleditor.hpp:168
ModelInfo::dirty
bool dirty()
Definition: modelinfo.hpp:46
ModelEditor::searchFixedAnnot
void searchFixedAnnot(QStringList annotations)
Definition: modeleditor.cpp:732
ModelEditor::clean
void clean(int)
ModelEditor::editModel
void editModel(QString name=QString())
Definition: modeleditor.cpp:114
ModelEditor::tokenPosition
int tokenPosition(QString token)
Definition: modeleditor.cpp:387
ModelEditor::saveAs
void saveAs(QString name=QString())
Definition: modeleditor.cpp:287
ModelEditor::newFileName
QString newFileName()
Definition: modeleditor.cpp:318
Utils::appDir
QString appDir(AppDirs d)
Definition: utils.cpp:28
ModelInfo::setDirty
void setDirty(bool d)
Definition: modelinfo.hpp:51