function_editor.cpp
Go to the documentation of this file.
1 #include "function_editor.h"
2 #include "custom_function.h"
3 #include "plotwidget.h"
4 #include <QDebug>
5 #include <QMessageBox>
6 #include <QFont>
7 #include <QDomDocument>
8 #include <QDomElement>
9 #include <QFontDatabase>
10 #include <QFile>
11 #include <QMenu>
12 #include <QAction>
13 #include <QDir>
14 #include <QFileDialog>
15 #include <QFileInfo>
16 #include <QSettings>
17 #include <QByteArray>
18 #include <QInputDialog>
19 
21  const CustomPlotMap &mapped_custom_plots,
22  QWidget *parent) :
23  QDialog(parent),
24  _plot_map_data(plotMapData),
25  _custom_plots(mapped_custom_plots),
26  ui(new Ui::FunctionEditor),
27  _v_count(1)
28 {
29  ui->setupUi(this);
30 
31  this->setWindowTitle("Create a custom timeseries");
32  ui->mathEquation->setPlainText("return value*2");
33 
34  const QFont fixedFont = QFontDatabase::systemFont(QFontDatabase::FixedFont);
35  ui->globalVarsTextField->setFont(fixedFont);
36  ui->mathEquation->setFont(fixedFont);
37  ui->snippetTextEdit->setFont(fixedFont);
38 
39  QStringList numericPlotNames;
40  for(const auto &p : _plot_map_data.numeric)
41  {
42  QString name = QString::fromStdString(p.first);
43  numericPlotNames.push_back(name);
44  }
45  numericPlotNames.sort(Qt::CaseInsensitive);
46  for(const QString& name : numericPlotNames)
47  {
48  ui->combo_linkedChannel->addItem(name);
49  ui->curvesListWidget->addItem(name);
50  }
51 
52  QSettings settings;
53  QByteArray saved_xml = settings.value("AddCustomPlotDialog.savedXML", QByteArray() ).toByteArray();
54  restoreGeometry(settings.value("AddCustomPlotDialog.geometry").toByteArray());
55 
56  if( saved_xml.isEmpty() )
57  {
58  QFile file("://resources/default.snippets.xml");
59  if(!file.open(QIODevice::ReadOnly))
60  {
61  throw std::runtime_error( "problem with default.snippets.xml" );
62  }
63  saved_xml = file.readAll();
64  }
65 
66  importSnippets(saved_xml);
67 
68  ui->snippetsListRecent->setContextMenuPolicy(Qt::CustomContextMenu);
69 
70  connect(ui->snippetsListRecent, &QListWidget::customContextMenuRequested,
72 
73  ui->snippetsListSaved->setContextMenuPolicy(Qt::CustomContextMenu);
74 
75  connect(ui->snippetsListSaved, &QListWidget::customContextMenuRequested,
77 
78  ui->splitter->setStretchFactor(0,3);
79  ui->splitter->setStretchFactor(1,2);
80 }
81 
83 {
84  QSettings settings;
85  settings.setValue("AddCustomPlotDialog.savedXML", exportSnippets() );
86  settings.setValue("AddCustomPlotDialog.geometry", saveGeometry());
87  delete ui;
88 }
89 
90 void AddCustomPlotDialog::setLinkedPlotName(const QString &linkedPlotName)
91 {
92 
93  int idx = ui->combo_linkedChannel->findText(linkedPlotName);
94  if (idx == -1)
95  {
96  idx = 0;
97  ui->combo_linkedChannel->insertItem(idx, linkedPlotName);
98  }
99  ui->combo_linkedChannel->setCurrentIndex(idx);
100 }
101 
103 {
104  ui->label_linkeChannel->setVisible( mode != FUNCTION_ONLY );
105  ui->combo_linkedChannel->setVisible( mode != FUNCTION_ONLY );
106  ui->pushButtonCreate->setVisible( mode != FUNCTION_ONLY );
107  ui->pushButtonSave->setVisible( mode != TIMESERIES_ONLY );
108 }
109 
111 {
112  return ui->combo_linkedChannel->currentText();
113 }
114 
116 {
117  return ui->globalVarsTextField->toPlainText();
118 }
119 
121 {
122  return ui->mathEquation->toPlainText();
123 }
124 
126 {
127  return ui->nameLineEdit->text();
128 }
129 
131 {
132  ui->globalVarsTextField->setPlainText(data->globalVars());
133  ui->mathEquation->setPlainText(data->function());
134  setLinkedPlotName(QString::fromStdString(data->linkedPlotName()));
135  ui->pushButtonCreate->setText("Update");
136  ui->nameLineEdit->setText(QString::fromStdString(data->name()));
137  ui->nameLineEdit->setEnabled(false);
138 
139  _is_new = false;
140 }
141 
143 {
144  return _plot;
145 }
146 
148 {
149  QString appendString = QString("V%1 = $$%2$$\n")
150  .arg(_v_count++)
151  .arg(ui->curvesListWidget->item(index.row())->text());
152 
153  QPlainTextEdit* edit = ui->mathEquation;
154 
155  if(ui->globalVarsTextField->hasFocus())
156  {
157  edit = ui->globalVarsTextField;
158  }
159 
160  if( !edit->toPlainText().endsWith("\n") )
161  {
162  edit->insertPlainText("\n");
163  }
164  edit->insertPlainText(appendString);
165 }
166 
167 void AddCustomPlotDialog::importSnippets(const QByteArray& xml_text)
168 {
169  ui->snippetsListSaved->clear();
170 
172 
173  for(const auto &it : _snipped_saved)
174  {
175  ui->snippetsListSaved->addItem( it.first );
176  }
177 
178  for( const auto& custom_it: _custom_plots)
179  {
180  const auto& math_plot = custom_it.second;
181  SnippetData snippet;
182  snippet.name = QString::fromStdString(math_plot->name());
183 
184  if( _snipped_saved.count( snippet.name ) > 0 )
185  {
186  continue;
187  }
188 
189  snippet.globalVars = math_plot->globalVars();
190  snippet.equation = math_plot->function();
191  _snipped_recent.insert( {snippet.name, snippet } );
192  ui->snippetsListRecent->addItem( snippet.name );
193  }
194  ui->snippetsListRecent->sortItems();
195  ui->snippetsListSaved->sortItems();
196 }
197 
199 {
200  QDomDocument doc;
201  auto root = ExportSnippets( _snipped_saved, doc);
202  doc.appendChild( root );
203  return doc.toByteArray(2);
204 }
205 
206 
208 {
209  if( current_row < 0 )
210  {
211  ui->snippetTextEdit->setPlainText("");
212  return;
213  }
214  const auto& name = ui->snippetsListSaved->currentItem()->text();
215  const SnippetData& snippet = _snipped_saved.at(name);
216  QString desc = QString("%1\n\nfunction calc(time,value)\n{\n%2\n}").arg(snippet.globalVars).arg(snippet.equation);
217  ui->snippetTextEdit->setPlainText(desc);
218 }
219 
221 {
222  const auto& name = ui->snippetsListSaved->item( index.row() )->text();
223  const SnippetData& snippet = _snipped_saved.at(name);
224 
225  ui->globalVarsTextField->setPlainText(snippet.globalVars);
226  ui->mathEquation->setPlainText(snippet.equation);
227 }
228 
230 {
231  if( current_row < 0 )
232  {
233  ui->snippetTextEdit->setPlainText("");
234  return;
235  }
236  const auto& name = ui->snippetsListRecent->currentItem()->text();
237  const SnippetData& snippet = _snipped_recent.at(name);
238 
239  QString desc = QString("%1\n\nfunction calc(time,value)\n{\n%2\n}")
240  .arg(snippet.globalVars)
241  .arg(snippet.equation);
242  ui->snippetTextEdit->setPlainText(desc);
243 }
244 
246 {
247  const auto& name = ui->snippetsListRecent->item( index.row() )->text();
248  const SnippetData& snippet = _snipped_recent.at(name);
249 
250  ui->globalVarsTextField->setPlainText(snippet.globalVars);
251  ui->mathEquation->setPlainText(snippet.equation);
252 }
253 
255 {
256  auto list_recent = ui->snippetsListRecent;
257 
258  if( list_recent->selectedItems().size() != 1)
259  {
260  return;
261  }
262 
263  auto list_saved = ui->snippetsListSaved;
264 
265  auto item = list_recent->selectedItems().first();
266  const auto& name = item->text();
267 
268  QMenu menu;
269  QAction* move_item = new QAction("Move to Saved", this);
270  menu.addAction( move_item );
271 
272  connect(move_item, &QAction::triggered,
273  this, [=]()
274  {
275  auto snippet_it = _snipped_recent.find(name);
276 
277  if( addToSaved( name, snippet_it->second ) )
278  {
279  _snipped_recent.erase( snippet_it );
280  delete list_recent->takeItem( list_recent->row(item) );
281  }
282  });
283 
284  menu.exec( list_recent->mapToGlobal(pos) );
285 }
286 
288 {
289  auto list_saved = ui->snippetsListSaved;
290 
291  if( list_saved->selectedItems().size() != 1)
292  {
293  return;
294  }
295 
296  QMenu menu;
297 
298  QAction* rename_item = new QAction("Rename...", this);
299  menu.addAction( rename_item );
300 
301  connect(rename_item, &QAction::triggered, this, &AddCustomPlotDialog::onRenameSaved);
302 
303  QAction* remove_item = new QAction("Remove", this);
304  menu.addAction( remove_item );
305 
306  connect(remove_item, &QAction::triggered,
307  this, [list_saved, this]()
308  {
309  const auto& item = list_saved->selectedItems().first();
310  _snipped_saved.erase( item->text() );
311  delete list_saved->takeItem( list_saved->row(item) );
312  });
313 
314  menu.exec( list_saved->mapToGlobal(pos) );
315 }
316 
318 {
319  ui->pushButtonCreate->setEnabled( !name.isEmpty() );
320  ui->pushButtonSave->setEnabled( !name.isEmpty() );
321 
322  if( _plot_map_data.numeric.count( name.toStdString() ) == 0)
323  {
324  ui->pushButtonCreate->setText("Create New Timeseries");
325  }
326  else{
327  ui->pushButtonCreate->setText("Modify Timeseries");
328  }
329 }
330 
332 {
333  QSettings settings;
334  QString directory_path = settings.value("AddCustomPlotDialog.loadDirectory",
335  QDir::currentPath() ).toString();
336 
337  QString fileName = QFileDialog::getOpenFileName(this, tr("Open Snippet Library"),
338  directory_path,
339  tr("Snippets (*.snippets.xml)"));
340  if (fileName.isEmpty()){
341  return;
342  }
343 
344  QFile file(fileName);
345 
346  if ( !file.open(QIODevice::ReadOnly)) {
347  QMessageBox::critical(this, "Error", QString("Failed to open the file [%1]").arg(fileName) );
348  return;
349  }
350 
351  directory_path = QFileInfo(fileName).absolutePath();
352  settings.setValue("AddCustomPlotDialog.loadDirectory", directory_path );
353 
354  importSnippets( file.readAll() );
355 }
356 
358 {
359  QSettings settings;
360  QString directory_path = settings.value("AddCustomPlotDialog.loadDirectory",
361  QDir::currentPath() ).toString();
362 
363  QString fileName = QFileDialog::getSaveFileName(this, tr("Open Snippet Library"),
364  directory_path,
365  tr("Snippets (*.snippets.xml)"));
366 
367  if (fileName.isEmpty()){
368  return;
369  }
370  if( !fileName.endsWith(".snippets.xml") )
371  {
372  fileName.append(".snippets.xml");
373  }
374 
375  QFile file(fileName);
376  if ( !file.open(QIODevice::WriteOnly)) {
377  QMessageBox::critical(this, "Error", QString("Failed to open the file [%1]").arg(fileName));
378  return;
379  }
380  auto data = exportSnippets();
381 
382  file.write(data);
383  file.close();
384 }
385 
387 {
388  QString name = ui->nameLineEdit->text();
389 
390  SnippetData snippet;
391  snippet.name = name;
392  snippet.globalVars = ui->globalVarsTextField->toPlainText();
393  snippet.equation = ui->mathEquation->toPlainText();
394 
395  addToSaved( name, snippet);
396 
397  on_snippetsListSaved_currentRowChanged( ui->snippetsListSaved->currentRow() );
398 }
399 
400 bool AddCustomPlotDialog::addToSaved(const QString& name, const SnippetData& snippet)
401 {
402  if( _snipped_saved.count(name) )
403  {
404  QMessageBox msgBox(this);
405  msgBox.setWindowTitle("Warning");
406  msgBox.setText(tr("A function with the same name exists already in the list of saved functions.\n"));
407  msgBox.addButton(QMessageBox::Cancel);
408  QPushButton* button = msgBox.addButton(tr("Overwrite"), QMessageBox::YesRole);
409  msgBox.setDefaultButton(button);
410 
411  int res = msgBox.exec();
412 
413  if( res < 0 || res == QMessageBox::Cancel) {
414  return false;
415  }
416  }
417  else{
418  ui->snippetsListSaved->addItem(name);
419  ui->snippetsListSaved->sortItems();
420  }
421  _snipped_saved[name] = snippet;
422  return true;
423 }
424 
426 {
427  auto list_saved = ui->snippetsListSaved;
428  auto item = list_saved->selectedItems().first();
429  const auto& name = item->text();
430 
431  bool ok;
432  QString new_name = QInputDialog::getText(this, tr("Change the name of the function"),
433  tr("New name:"), QLineEdit::Normal,
434  name, &ok);
435 
436  if (!ok || new_name.isEmpty() || new_name == name)
437  {
438  return;
439  }
440 
441  SnippetData snippet = _snipped_saved[ name ];
442  _snipped_saved.erase( name );
443  snippet.name = new_name;
444 
445  _snipped_saved.insert( {new_name, snippet} );
446  item->setText( new_name );
447  ui->snippetsListSaved->sortItems();
448 }
449 
450 
452 {
453  try {
454  std::string plotName = getName().toStdString();
455 
456  // check if name is unique (except if is custom_plot)
457  if(_plot_map_data.numeric.count(plotName) != 0 &&
458  _custom_plots.count(plotName) == 0 )
459  {
460  throw std::runtime_error("plot name already exists and can't be modified");
461  }
462 
463  _plot = std::make_shared<CustomFunction>(getLinkedData().toStdString(),
464  plotName,
465  getGlobalVars(),
466  getEquation());
467  QDialog::accept();
468  }
469  catch (const std::runtime_error &e) {
470  _plot.reset();
471  QMessageBox::critical(this, "Error", "Failed to create math plot : "
472  + QString::fromStdString(e.what()));
473  QDialog::reject();
474  }
475 }
476 
477 void AddCustomPlotDialog::on_lineEditFilter_textChanged(const QString &search_string)
478 {
479  QStringList spaced_items = search_string.split(' ');
480 
481  for (int row=0; row < ui->curvesListWidget->count(); row++)
482  {
483  auto item = ui->curvesListWidget->item(row);
484  QString name = item->text();
485  bool toHide = false;
486 
487  for (const auto& item: spaced_items)
488  {
489  if( !name.contains(item) )
490  {
491  toHide = true;
492  break;
493  }
494  }
495  ui->curvesListWidget->setRowHidden(row, toHide );
496  }
497 }
QByteArray exportSnippets() const
Ui::FunctionEditor * ui
std::unordered_map< std::string, PlotData > numeric
Definition: plotdata.h:144
void on_snippetsListSaved_currentRowChanged(int currentRow)
SnippetsMap _snipped_recent
QString globalVars
void setLinkedPlotName(const QString &linkedPlotName)
void setEditorMode(EditorMode mode)
QString equation
QDomElement ExportSnippets(const SnippetsMap &snippets, QDomDocument &doc)
void on_snippetsListSaved_doubleClicked(const QModelIndex &index)
const CustomPlotMap & _custom_plots
void recentContextMenu(const QPoint &pos)
void on_lineEditFilter_textChanged(const QString &arg1)
void on_nameLineEdit_textChanged(const QString &arg1)
CustomPlotPtr getCustomPlotData() const
QString getGlobalVars() const
std::shared_ptr< CustomFunction > CustomPlotPtr
QString getLinkedData() const
AddCustomPlotDialog(PlotDataMapRef &plotMapData, const CustomPlotMap &mapped_custom_plots, QWidget *parent)
bool addToSaved(const QString &name, const SnippetData &snippet)
SnippetsMap GetSnippetsFromXML(const QString &xml_text)
char name[1]
PlotDataMapRef & _plot_map_data
QString getEquation() const
std::unordered_map< std::string, CustomPlotPtr > CustomPlotMap
void editExistingPlot(CustomPlotPtr data)
CustomPlotPtr _plot
void on_curvesListWidget_doubleClicked(const QModelIndex &index)
void on_snippetsListRecent_currentRowChanged(int currentRow)
void * arg
void importSnippets(const QByteArray &xml_text)
virtual ~AddCustomPlotDialog() override
SnippetsMap _snipped_saved
QString getName() const
empty_struct data[sizeof(T)/sizeof(empty_struct)]
void on_snippetsListRecent_doubleClicked(const QModelIndex &index)
void savedContextMenu(const QPoint &pos)


plotjuggler
Author(s): Davide Faconti
autogenerated on Sat Jul 6 2019 03:44:17