diff --git a/bt_editor/graphic_container.cpp b/bt_editor/graphic_container.cpp index 3dfce1b6..5a9872c2 100644 --- a/bt_editor/graphic_container.cpp +++ b/bt_editor/graphic_container.cpp @@ -11,6 +11,7 @@ #include #include #include +#include using namespace QtNodes; @@ -162,6 +163,18 @@ void GraphicContainer::nodeReorder() emit undoableChange(); } +void GraphicContainer::saveSvgFile(const QString path) +{ + QSvgGenerator generator; + QRectF rect = _scene->itemsBoundingRect(); + generator.setFileName(path); + generator.setSize(QSize(rect.width(), rect.height())); + generator.setViewBox(rect); + QPainter painter; + painter.begin(&generator); + _scene->render(&painter, rect, rect); +} + void GraphicContainer::zoomHomeView() { QRectF rect = _scene->itemsBoundingRect(); @@ -720,5 +733,3 @@ void GraphicContainer::loadFromJson(const QByteArray &data) clearScene(); scene()->loadFromMemory( data ); } - - diff --git a/bt_editor/graphic_container.h b/bt_editor/graphic_container.h index b725e8bf..eb3ee3c6 100644 --- a/bt_editor/graphic_container.h +++ b/bt_editor/graphic_container.h @@ -33,6 +33,8 @@ class GraphicContainer : public QObject void nodeReorder(); + void saveSvgFile(const QString path); + void zoomHomeView(); bool containsValidTree() const; diff --git a/bt_editor/main.cpp b/bt_editor/main.cpp index d80e92ee..ebc10458 100644 --- a/bt_editor/main.cpp +++ b/bt_editor/main.cpp @@ -56,6 +56,16 @@ main(int argc, char *argv[]) "Autoconnect to monitor"); parser.addOption(autoconnect_option); + QCommandLineOption file_option(QStringList() << "file", + "Load a file (only in editor mode)", + "tree.xml"); + parser.addOption(file_option); + + QCommandLineOption output_svg_option(QStringList() << "output-svg", + "Save the input file to an svg", + "output.svg"); + parser.addOption(output_svg_option); + parser.process( app ); QFile styleFile( ":/stylesheet.qss" ); @@ -92,7 +102,7 @@ main(int argc, char *argv[]) else{ std::cout << "wrong mode passed to --mode. Use on of these: editor / monitor /replay" << std::endl; - return 0; + return 1; } } else{ @@ -114,6 +124,52 @@ main(int argc, char *argv[]) // Start the main application. MainWindow win( mode, monitor_address, monitor_pub_port, monitor_srv_port, monitor_autoconnect ); + + if( parser.isSet(file_option) ) + { + if ( mode != GraphicMode::EDITOR ) + { + std::cout << "--file can only be passed in editor mode" << std::endl; + return 1; + } + + QString fileName = parser.value(file_option); + std::cout << "Loading file: " << fileName.toStdString() << std::endl; + + // Open file + QFile file(fileName); + if (!file.open(QIODevice::ReadOnly)) + { + std::cout << "Cannot open file" << std::endl; + return 1; + } + + // Read file to xml + QString xml_text; + QTextStream in(&file); + while (!in.atEnd()) { + xml_text += in.readLine(); + } + + // Show xml + win.loadFromXML( xml_text ); + } + + + if( parser.isSet(output_svg_option) ) + { + if ( !parser.isSet(file_option)) + { + std::cout << "--output-svg needs the --file" << std::endl; + return 1; + } + QString svgFile = parser.value(output_svg_option); + + std::cout << "Writing to: " << svgFile.toStdString() << std::endl; + win.currentTabInfo()->saveSvgFile(svgFile); + return 0; + } + win.show(); return app.exec(); } diff --git a/bt_editor/mainwindow.cpp b/bt_editor/mainwindow.cpp index 865a5fae..56b02ba1 100644 --- a/bt_editor/mainwindow.cpp +++ b/bt_editor/mainwindow.cpp @@ -683,13 +683,30 @@ void MainWindow::onAutoArrange() currentTabInfo()->nodeReorder(); } +void MainWindow::onSaveSvg() +{ + QSettings settings; + QString last_load_path = settings.value("MainWindow.lastLoadDirectory", + QDir::homePath() ).toString(); + QString directory_path = settings.value("MainWindow.lastSaveSvgDirectory", + last_load_path ).toString(); + + QString fileName = QFileDialog::getSaveFileName(this, + tr("Save BehaviorTree to svg"), directory_path, + tr("SVG files (*.svg)")); + currentTabInfo()->saveSvgFile(fileName); + + directory_path = QFileInfo(fileName).absolutePath(); + settings.setValue("SidepanelEditor.lastSaveSvgDirectory", directory_path); +} + void MainWindow::onSceneChanged() { const bool valid_BT = currentTabInfo()->containsValidTree(); ui->toolButtonLayout->setEnabled(valid_BT); ui->toolButtonReorder->setEnabled(valid_BT); - ui->toolButtonReorder->setEnabled(valid_BT); + ui->toolButtonSaveSvg->setEnabled(valid_BT); ui->actionSave->setEnabled(valid_BT); QPixmap pix; @@ -1167,6 +1184,11 @@ void MainWindow::on_toolButtonReorder_pressed() onAutoArrange(); } +void MainWindow::on_toolButtonSaveSvg_pressed() +{ + onSaveSvg(); +} + void MainWindow::on_toolButtonCenterView_pressed() { currentTabInfo()->zoomHomeView(); @@ -1313,6 +1335,7 @@ void MainWindow::updateCurrentMode() ui->toolButtonSaveFile->setHidden( NOT_EDITOR ); ui->toolButtonReorder->setHidden( NOT_EDITOR ); + ui->toolButtonSaveSvg->setHidden( NOT_EDITOR ); if( _current_mode == GraphicMode::EDITOR ) { diff --git a/bt_editor/mainwindow.h b/bt_editor/mainwindow.h index 0bb39ba1..56af8823 100644 --- a/bt_editor/mainwindow.h +++ b/bt_editor/mainwindow.h @@ -71,6 +71,8 @@ public slots: void onAutoArrange(); + void onSaveSvg(); + void onSceneChanged(); void onPushUndo(); @@ -102,6 +104,8 @@ public slots: void on_toolButtonReorder_pressed(); + void on_toolButtonSaveSvg_pressed(); + void on_toolButtonCenterView_pressed(); void onCreateAbsBehaviorTree(const AbsBehaviorTree &tree, diff --git a/bt_editor/mainwindow.ui b/bt_editor/mainwindow.ui index 80594ee2..8410449b 100644 --- a/bt_editor/mainwindow.ui +++ b/bt_editor/mainwindow.ui @@ -511,8 +511,7 @@ QToolButton:disabled{ true - - + false @@ -577,6 +576,71 @@ QToolButton:disabled{ + + + + false + + + + 80 + 70 + + + + + 80 + 70 + + + + + 9 + + + + Qt::NoFocus + + + QToolButton { + color:white; +} + +QToolButton:hover{ + background-color: rgb(110, 110, 110); +} + +QToolButton:pressed{ + background-color: rgb(50, 150, 0) +} + +QToolButton:disabled{ + color:gray; + background-color: rgb(50, 50, 50) +} + + + + Save svg + + + + :/icons/svg/save_white.svg:/icons/svg/save_white.svg + + + + 32 + 32 + + + + Qt::ToolButtonTextUnderIcon + + + true + + +