2 #include "ui_jsoneditormain.h"
7 #include <QInputDialog>
23 newInsertText(tr(
"Insert new data")),
24 treeViewColumnKey(tr(
"Node")),
25 treeViewColumnValue(tr(
"Value")),
26 treeViewColumnType(tr(
"Type"))
34 connect(
ui->menuInsertNode, SIGNAL(triggered()),
this, SLOT(
insertTreeNode()));
36 connect(
ui->menuDeleteNode, SIGNAL(triggered()),
this, SLOT(
deleteTreeNode()));
37 connect(
ui->jsonTree, SIGNAL(clicked(QModelIndex)),
this, SLOT(
updateActions()));
38 connect(
ui->menuFormat, SIGNAL(triggered()),
this, SLOT(
formatCode()));
39 connect(
ui->menuHelp, SIGNAL(triggered()),
this, SLOT(
showHelp()));
40 connect(
ui->jsonTree, SIGNAL(doubleClicked(QModelIndex)),
this, SLOT(
dataEdit(QModelIndex)));
44 connect(
ui->menuOpenFile, SIGNAL(triggered()),
this, SLOT(
open()));
45 connect(
ui->menuSaveFile, SIGNAL(triggered()),
this, SLOT(
save()));
46 connect(
ui->menuSaveAs, SIGNAL(triggered()),
this, SLOT(
saveAs()));
53 connect(
textEdit->document(), SIGNAL(contentsChanged()),
55 setUnifiedTitleAndToolBarOnMac(
true);
81 QMainWindow::changeEvent(e);
83 case QEvent::LanguageChange:
84 ui->retranslateUi(
this);
93 checked ?
ui->codeToolBar->show() :
ui->codeToolBar->hide();
98 checked ?
ui->editToolBar->show() :
ui->editToolBar->hide();
103 checked ?
ui->fileToolBar->show() :
ui->fileToolBar->hide();
108 checked ?
ui->findToolBar->show() :
ui->findToolBar->hide();
113 if (!
ui->jsonCode->document()->isEmpty())
116 std::string
json =
ui->jsonCode->toPlainText().toStdString();
127 QAbstractItemModel *oldModel =
ui->jsonTree->model();
128 if (oldModel != NULL)
129 oldModel->disconnect(SIGNAL(dataChanged(QModelIndex,QModelIndex)));
132 QItemSelectionModel *selectionModel =
ui->jsonTree->selectionModel();
133 connect(model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(
treeViewDataChanged()));
134 ui->jsonTree->setModel(model);
135 ui->jsonTree->reset();
136 delete selectionModel;
140 ui->jsonTree->expandAll();
142 for (
int i = 0; i <
ui->jsonTree->model()->columnCount(); i++)
143 ui->jsonTree->resizeColumnToContents(i);
150 if (dlg.exec() == QDialog::Accepted)
152 if(
ui->jsonTree->selectionModel() == 0)
154 QMessageBox::warning(
this,this->windowTitle(),
"Adding a node to an empty tree is not supported.");
158 QModelIndex index =
ui->jsonTree->selectionModel()->currentIndex();
159 QAbstractItemModel *model =
ui->jsonTree->model();
161 if (!model->insertRow(index.row()+1, index.parent()))
173 QModelIndex child = model->index(index.row()+1, 0, index.parent());
174 model->setData(child, QVariant(dlg.
getName()), Qt::EditRole);
176 child = model->index(index.row()+1, 1, index.parent());
177 model->setData(child, QVariant(dlg.
getValue()), Qt::EditRole);
179 child = model->index(index.row()+1, 2, index.parent());
180 model->setData(child, QVariant(dlg.
getType()), Qt::EditRole);
187 if (dlg.exec() == QDialog::Accepted)
189 QModelIndex index =
ui->jsonTree->selectionModel()->currentIndex();
192 if (index.column() != 0)
194 index = index.sibling(index.row(), 0);
199 if (!model->insertColumn(0, index))
203 if (!model->insertRow(0, index))
214 QModelIndex child = model->
index(0, 0, index);
217 child = model->
index(0, 1, index);
220 child = model->
index(0, 2, index);
223 ui->jsonTree->selectionModel()->setCurrentIndex(model->
index(0, 0, index),
224 QItemSelectionModel::ClearAndSelect);
231 QModelIndex index =
ui->jsonTree->selectionModel()->currentIndex();
232 QAbstractItemModel *model =
ui->jsonTree->model();
233 if (model->removeRow(index.row(), index.parent()))
239 bool hasSelection = !
ui->jsonTree->selectionModel()->selection().isEmpty();
240 ui->menuDeleteNode->setEnabled(hasSelection);
242 bool hasCurrent =
ui->jsonTree->selectionModel()->currentIndex().isValid();
243 ui->menuInsertNode->setEnabled(hasCurrent);
244 ui->menuInsertChild->setEnabled(hasCurrent);
249 for (
int i = 0; i <
ui->jsonTree->model()->columnCount(); i++)
251 ui->jsonTree->resizeColumnToContents(i);
252 ui->jsonTree->setColumnWidth(i,
ui->jsonTree->columnWidth(i) + 20);
258 if (
ui->jsonTree->model() != NULL)
260 ui->jsonCode->clear();
262 QString codeText =
"";
267 ui->jsonCode->setPlainText(codeText);
274 QString objectKey = treeItem->
data(0).toString();
275 QString objectValue = treeItem->
data(1).toString();
276 QString objectType = treeItem->
data(2).toString();
284 resultStr = indent + QString(
"\"") + objectKey +
"\": ";
287 if (objectType.compare(tr(
"object"), Qt::CaseInsensitive) == 0
292 for (
int i = 0; i < treeItem->
childCount(); i++)
294 subObjectItem = treeItem->
child(i);
295 resultStr +=
treeFormat(subObjectItem, indent +
" ");
298 resultStr.remove(resultStr.length() - 2, 1);
299 resultStr += indent +
"},\n";
301 else if (objectType.compare(tr(
"array"), Qt::CaseInsensitive) == 0)
305 for (
int i = 0; i < treeItem->
childCount(); i++)
307 subObjectItem = treeItem->
child(i);
308 resultStr +=
treeFormat(subObjectItem, indent +
" ",
true);
311 resultStr.remove(resultStr.length() - 2, 1);
312 resultStr += indent +
"],\n";
316 if (objectType.compare(tr(
"string"), Qt::CaseInsensitive) == 0 ||
319 resultStr +=
"\"" + objectValue +
"\",\n";
323 resultStr += objectValue +
",\n";
332 QMessageBox::information(
this, tr(
"Using Help"), tr(
333 "1 On the left side of the main interface to fill the JSON code \n"
334 "2 Click on the menu \" Generate code tree \", the right of the main interface will spanning tree \n"
335 "3 To insert or delete after the tree node or modify the value, click on the menu \" Generate Code \", will generate JSON code from the tree." ));
340 QString vType = editIndex.sibling(editIndex.row(), 2).data(Qt::EditRole).toString();
342 if (vType.compare(tr(
"object")) != 0
343 && vType.compare(tr(
"array")) != 0)
345 if (editIndex.column() >= 2)
347 QModelIndex newIndex = editIndex.sibling(editIndex.row(), 1);
348 ui->jsonTree->edit(newIndex);
353 QModelIndex newIndex = editIndex.sibling(editIndex.row(), 0);
354 ui->jsonTree->edit(newIndex);
360 setWindowModified(
textEdit->document()->isModified());
376 QString fileName = QFileDialog::getOpenFileName(
this,
"Open Json File",
lastFilePath);
377 if (!fileName.isEmpty())
379 QFileInfo info(fileName);
385 ui->menuRefresh->trigger();
399 QFileDialog dialog(
this);
400 dialog.setWindowModality(Qt::WindowModal);
401 dialog.setAcceptMode(QFileDialog::AcceptSave);
403 QStringList files = dialog.selectedFiles();
418 this->restoreGeometry(settings.value(
"geometry").toByteArray());
419 lastFilePath = (settings.value(
"file_path").toString());
420 curFile = settings.value(
"last_opened_file").toString();
421 if(this->
curFile.length() != 0)
424 ui->menuRefresh->trigger();
433 settings.setValue(
"geometry", this->saveGeometry());
435 settings.setValue(
"last_opened_file", this->
curFile);
440 if (
ui->jsonCode->document()->isModified()) {
441 QMessageBox::StandardButton ret;
442 ret = QMessageBox::warning(
this, this->windowTitle(),
443 tr(
"The document has been modified.\n"
444 "Do you want to save your changes?"),
445 QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
446 if (ret == QMessageBox::Save)
448 else if (ret == QMessageBox::Cancel)
456 QFile file(fileName);
457 if (!file.open(QFile::ReadOnly | QFile::Text)) {
458 QMessageBox::warning(
this, this->windowTitle(),
459 tr(
"Cannot read file %1:\n%2.")
461 .arg(file.errorString()));
465 QTextStream in(&file);
467 QApplication::setOverrideCursor(Qt::WaitCursor);
469 textEdit->setPlainText(in.readAll());
471 QApplication::restoreOverrideCursor();
475 statusBar()->showMessage(tr(
"File loaded"), 2000);
480 ui->menuFormat->trigger();
482 QFile file(fileName);
483 QFileInfo info(fileName);
485 if (!file.open(QFile::WriteOnly | QFile::Text)) {
486 QMessageBox::warning(
this, this->windowTitle(),
487 tr(
"Cannot write file %1:\n%2.")
489 .arg(file.errorString()));
493 QTextStream out(&file);
495 QApplication::setOverrideCursor(Qt::WaitCursor);
498 auto content =
textEdit->toPlainText();
499 content.remove(content.length() - 2, 2);
502 QApplication::restoreOverrideCursor();
506 statusBar()->showMessage(tr(
"File saved"), 2000);
513 ui->jsonCode->document()->setModified(
false);
514 setWindowModified(
false);
518 shownName =
"untitled.json";
519 setWindowFilePath(shownName);
524 return QFileInfo(fullFileName).fileName();
527 #ifdef COMPILE_WITH_ROS
529 void JsonEditorMain::set_node(std::shared_ptr<testSetupNode> p_nodeSPtr) {
530 if(p_nodeSPtr ==
nullptr) {
533 m_nodeSPtr = p_nodeSPtr;
540 std::shared_ptr<std::map<std::string, std::vector<rclcpp::Parameter>>> parameterMap = std::make_shared<std::map<std::string, std::vector<rclcpp::Parameter>>>();
544 if(model ==
nullptr) {
545 std::cout <<
"No file loaded. Abort sending." << std::endl;
550 if(rootItem ==
nullptr) {
551 std::cout <<
"No file loaded. Abort sending." << std::endl;
555 QString objectType = rootItem->
data(2).toString();
557 if (objectType.compare(tr(
"object"), Qt::CaseInsensitive) == 0
564 for (
int node_i = 0; node_i < rootItem->
childCount(); node_i++)
566 nodeObjectItem = rootItem->
child(node_i);
567 QString node_objectKey = nodeObjectItem->
data(0).toString();
568 std::string node_objectKey_str = node_objectKey.toStdString().c_str();
570 parameterMap->insert(std::make_pair(node_objectKey_str, std::vector<rclcpp::Parameter>()));
572 for (
int subsection_i = 0; subsection_i < nodeObjectItem->
childCount(); subsection_i++)
574 subsectionObjectItem = nodeObjectItem->
child(subsection_i);
575 QString subsection_objectKey = subsectionObjectItem->
data(0).toString();
576 std::string subsection_objectKey_str = subsection_objectKey.toStdString().c_str();
578 for (
int parameter_i = 0; parameter_i < subsectionObjectItem->
childCount(); parameter_i++)
580 parameterObjectItem = subsectionObjectItem->
child(parameter_i);
581 QString parameter_objectKey = parameterObjectItem->
data(0).toString();
582 std::string parameter_objectKey_str = parameter_objectKey.toStdString().c_str();
584 QString parameter_objectType = parameterObjectItem->
data(2).toString();
585 if(parameter_objectType ==
"unsigned integer") {
586 int parameter_objectValue_int = parameterObjectItem->
data(1).toInt();
587 (*parameterMap)[node_objectKey_str].push_back(rclcpp::Parameter(subsection_objectKey_str +
"." + parameter_objectKey_str, parameter_objectValue_int));
589 else if(parameter_objectType ==
"double") {
590 double parameter_objectValue_double = parameterObjectItem->
data(1).toDouble();
591 (*parameterMap)[node_objectKey_str].push_back(rclcpp::Parameter(subsection_objectKey_str +
"." + parameter_objectKey_str, parameter_objectValue_double));
594 RCLCPP_ERROR(m_nodeSPtr->get_logger(),
"[SYSTEM SETTINGS] Type of parameter %s %s.%s %s", node_objectKey.toLocal8Bit().data(), subsection_objectKey.toLocal8Bit().data(), parameter_objectKey.toLocal8Bit().data(),
" is NOT valid (INT or FLOAT/DOUBLE). Skipping.");