diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 5fe780edb38cd7d6f04514953ab6ab1716ccc732..43423d7a50b343a68ccc0d984c206e6df56ee6a3 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -260,7 +260,10 @@ FORMS += src/ui/MainWindow.ui \ src/ui/configuration/ParamWidget.ui \ src/ui/configuration/ArduPlanePidConfig.ui \ src/ui/configuration/AdvParameterList.ui \ - src/ui/configuration/ArduRoverPidConfig.ui + src/ui/configuration/ArduRoverPidConfig.ui \ + src/ui/configuration/terminalconsole.ui \ + src/ui/configuration/SerialSettingsDialog.ui + INCLUDEPATH += src \ src/ui \ src/ui/linechart \ @@ -371,7 +374,6 @@ HEADERS += src/MG.h \ src/ui/map/Waypoint2DIcon.h \ src/ui/map/QGCMapTool.h \ src/ui/map/QGCMapToolBar.h \ -# libs/qextserialport/qextserialenumerator.h \ src/QGCGeo.h \ src/ui/QGCToolBar.h \ src/ui/QGCStatusBar.h \ @@ -447,7 +449,11 @@ HEADERS += src/MG.h \ src/ui/configuration/ParamWidget.h \ src/ui/configuration/ArduPlanePidConfig.h \ src/ui/configuration/AdvParameterList.h \ - src/ui/configuration/ArduRoverPidConfig.h + src/ui/configuration/ArduRoverPidConfig.h \ + src/ui/configuration/console.h \ + src/ui/configuration/SerialSettingsDialog.h \ + src/ui/configuration/terminalconsole.h \ + src/ui/configuration/ApmHighlighter.h # Google Earth is only supported on Mac OS and Windows with Visual Studio Compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::HEADERS += src/ui/map3D/QGCGoogleEarthView.h @@ -652,7 +658,11 @@ SOURCES += src/main.cc \ src/ui/configuration/ParamWidget.cc \ src/ui/configuration/ArduPlanePidConfig.cc \ src/ui/configuration/AdvParameterList.cc \ - src/ui/configuration/ArduRoverPidConfig.cc + src/ui/configuration/ArduRoverPidConfig.cc \ + src/ui/configuration/terminalconsole.cpp \ + src/ui/configuration/console.cpp \ + src/ui/configuration/SerialSettingsDialog.cc \ + src/ui/configuration/ApmHighlighter.cc # Enable Google Earth only on Mac OS and Windows with Visual Studio compiler macx|macx-g++|macx-g++42|win32-msvc2008|win32-msvc2010|win32-msvc2012::SOURCES += src/ui/map3D/QGCGoogleEarthView.cc diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index cf1a72ca3d2bc9311eb86cf0b3ce0e65882fa03b..1d4c2aa6ac7b59cfde9658a358e25acefefb3fc9 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -65,6 +65,8 @@ This file is part of the QGROUNDCONTROL project #include "UASRawStatusView.h" #include "PrimaryFlightDisplay.h" #include "apmtoolbar.h" +#include "SerialSettingsDialog.h" +#include "terminalconsole.h" #ifdef QGC_OSG_ENABLED #include "Q3DWidgetFactory.h" @@ -224,7 +226,7 @@ MainWindow::MainWindow(QWidget *parent): apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); apmToolBar->setSimulationViewAction(ui.actionSimulation_View); - apmToolBar->setTerminalViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionTerminalView); QDockWidget *widget = new QDockWidget(tr("APM Tool Bar"),this); widget->setWidget(apmToolBar); @@ -475,56 +477,67 @@ void MainWindow::buildCommonWidgets() if (!plannerView) { plannerView = new SubMainWindow(this); + plannerView->setObjectName("VIEW_MISSION"); plannerView->setCentralWidget(new QGCMapTool(this)); - //mapWidget = new QGCMapTool(this); - addCentralWidget(plannerView, "Maps"); + addToCentralStackedWidget(plannerView, VIEW_MISSION, "Maps"); } - //pilotView + //pilotView (aka Flight or Mission View) if (!pilotView) { pilotView = new SubMainWindow(this); pilotView->setObjectName("VIEW_FLIGHT"); pilotView->setCentralWidget(new QGCMapTool(this)); - addCentralWidget(pilotView, "Pilot"); + addToCentralStackedWidget(pilotView, VIEW_FLIGHT, "Pilot"); } + if (!configView) { configView = new SubMainWindow(this); configView->setObjectName("VIEW_HARDWARE_CONFIG"); configView->setCentralWidget(new ApmHardwareConfig(this)); - addCentralWidget(configView,"Hardware"); - centralWidgetToDockWidgetsMap[VIEW_HARDWARE_CONFIG] = QMap(); - + addToCentralStackedWidget(configView,VIEW_HARDWARE_CONFIG, tr("Hardware")); } + if (!softwareConfigView) { softwareConfigView = new SubMainWindow(this); softwareConfigView->setObjectName("VIEW_SOFTWARE_CONFIG"); softwareConfigView->setCentralWidget(new ApmSoftwareConfig(this)); - addCentralWidget(softwareConfigView,"Software"); - centralWidgetToDockWidgetsMap[VIEW_SOFTWARE_CONFIG] = QMap(); + addToCentralStackedWidget(softwareConfigView, VIEW_SOFTWARE_CONFIG, tr("Software")); } + if (!engineeringView) { engineeringView = new SubMainWindow(this); engineeringView->setObjectName("VIEW_ENGINEER"); engineeringView->setCentralWidget(new QGCDataPlot2D(this)); - addCentralWidget(engineeringView,tr("Logfile Plot")); + addToCentralStackedWidget(engineeringView, VIEW_ENGINEER, tr("Logfile Plot")); } + if (!mavlinkView) { mavlinkView = new SubMainWindow(this); mavlinkView->setObjectName("VIEW_MAVLINK"); mavlinkView->setCentralWidget(new XMLCommProtocolWidget(this)); - addCentralWidget(mavlinkView,tr("Mavlink Generator")); + addToCentralStackedWidget(mavlinkView, VIEW_MAVLINK, tr("Mavlink Generator")); } + if (!simView) { simView = new SubMainWindow(this); simView->setObjectName("VIEW_SIMULATOR"); simView->setCentralWidget(new QGCMapTool(this)); - addCentralWidget(simView,tr("Simulation View")); + addToCentralStackedWidget(simView, VIEW_SIMULATION, tr("Simulation View")); + } + + if (!terminalView) + { + terminalView = new SubMainWindow(this); + terminalView->setObjectName("VIEW_TERMINAL"); + TerminalConsole *terminalConsole = new TerminalConsole(this); + terminalView->setCentralWidget(terminalConsole); + addToCentralStackedWidget(terminalView, VIEW_TERMINAL, tr("Terminal View")); } // Dock widgets @@ -682,18 +695,20 @@ void MainWindow::buildCommonWidgets() }*/ #ifdef QGC_OSG_ENABLED - if (!_3DWidget) + if (q3DWidget) { - _3DWidget = Q3DWidgetFactory::get("PIXHAWK", this); - addCentralWidget(_3DWidget, tr("Local 3D")); + q3DWidget = Q3DWidgetFactory::get("PIXHAWK", this); + q3DWidget->setObjectName("VIEW_3DWIDGET"); + + addToCentralStackedWidget(q3DWidget, VIEW_3DWIDGET, tr("Local 3D")); } #endif -#if (defined _MSC_VER) | (defined Q_OS_MAC) - if (!gEarthWidget) +#if (defined _MSC_VER) /*| (defined Q_OS_MAC_OFF)*/ + if (!earthWidget) { - gEarthWidget = new QGCGoogleEarthView(this); - addCentralWidget(gEarthWidget, tr("Google Earth")); + earthWidget = new QGCGoogleEarthView(this); + addToCentralStackedWidget(earthWidget,VIEW_GOOGLEEARTH, tr("Google Earth")); } #endif } @@ -918,25 +933,16 @@ void MainWindow::showTool(bool show) addTool(parent,VIEW_SIMULATION,widget,tr("Control"),area); } }*/ -void MainWindow::addCentralWidget(QWidget* widget, const QString& title) +void MainWindow::addToCentralStackedWidget(QWidget* widget, VIEW_SECTIONS viewSection, const QString& title) { Q_UNUSED(title); + Q_ASSERT(widget->objectName().length() != 0); // Check if this widget already has been added if (centerStack->indexOf(widget) == -1) { centerStack->addWidget(widget); - - // QAction* tempAction = ui.menuMain->addAction(title); - - // tempAction->setCheckable(true); - // QVariant var; - // var.setValue((QWidget*)widget); - // tempAction->setData(var); - // centerStackActionGroup->addAction(tempAction); - // connect(tempAction,SIGNAL(triggered()),this, SLOT(showCentralWidget())); - //connect(widget, SIGNAL(visibilityChanged(bool)), tempAction, SLOT(setChecked(bool))); - // tempAction->setChecked(widget->isVisible()); + centralWidgetToDockWidgetsMap[viewSection] = QMap(); } } @@ -1448,6 +1454,7 @@ void MainWindow::connectCommonActions() perspectives->addAction(ui.actionHardwareConfig); perspectives->addAction(ui.actionSoftwareConfig); perspectives->addAction(ui.actionFirmwareUpdateView); + perspectives->addAction(ui.actionTerminalView); perspectives->addAction(ui.actionUnconnectedView); perspectives->setExclusive(true); @@ -1492,6 +1499,11 @@ void MainWindow::connectCommonActions() ui.actionFirmwareUpdateView->setChecked(true); ui.actionFirmwareUpdateView->activate(QAction::Trigger); } + if (currentView == VIEW_TERMINAL) + { + ui.actionTerminalView->setChecked(true); + ui.actionTerminalView->activate(QAction::Trigger); + } if (currentView == VIEW_UNCONNECTED) { ui.actionUnconnectedView->setChecked(true); @@ -1529,6 +1541,7 @@ void MainWindow::connectCommonActions() connect(ui.actionUnconnectedView, SIGNAL(triggered()), this, SLOT(loadUnconnectedView())); connect(ui.actionHardwareConfig,SIGNAL(triggered()),this,SLOT(loadHardwareConfigView())); connect(ui.actionSoftwareConfig,SIGNAL(triggered()),this,SLOT(loadSoftwareConfigView())); + connect(ui.actionTerminalView,SIGNAL(triggered()),this,SLOT(loadTerminalView())); connect(ui.actionFirmwareUpdateView, SIGNAL(triggered()), this, SLOT(loadFirmwareUpdateView())); connect(ui.actionMavlinkView, SIGNAL(triggered()), this, SLOT(loadMAVLinkView())); @@ -1625,7 +1638,7 @@ void MainWindow::showSettings() settings->show(); } -void MainWindow::addLink() +LinkInterface* MainWindow::addLink() { SerialLink* link = new SerialLink(); // TODO This should be only done in the dialog itself @@ -1647,6 +1660,8 @@ void MainWindow::addLink() break; } } + + return link; } @@ -2050,6 +2065,10 @@ void MainWindow::loadViewState() centerStack->setCurrentWidget(simView); break; + case VIEW_TERMINAL: + centerStack->setCurrentWidget(terminalView); + break; + case VIEW_UNCONNECTED: case VIEW_FULL: default: @@ -2161,6 +2180,18 @@ void MainWindow::loadSoftwareConfigView() } } +void MainWindow::loadTerminalView() +{ + if (currentView != VIEW_TERMINAL) + { + storeViewState(); + currentView = VIEW_TERMINAL; + ui.actionTerminalView->setChecked(true); + loadViewState(); + } +} + + void MainWindow::loadUnconnectedView() { if (currentView != VIEW_UNCONNECTED) diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index b51dba6b2086b9b2b75a6faa4791c3951f9c96f4..5fe4de6269d9582b047711687755d359b7a22a03 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -148,7 +148,7 @@ public slots: /** @brief Show the application settings */ void showSettings(); /** @brief Add a communication link */ - void addLink(); + LinkInterface* addLink(); void addLink(LinkInterface* link); bool configLink(LinkInterface *link); void configure(); @@ -184,6 +184,8 @@ public slots: void loadMAVLinkView(); /** @brief Load firmware update view */ void loadFirmwareUpdateView(); + /** @brief Load Terminal Console views */ + void loadTerminalView(); /** @brief Show the online help for users */ void showHelp(); @@ -288,6 +290,9 @@ protected: VIEW_FIRMWAREUPDATE, VIEW_HARDWARE_CONFIG, VIEW_SOFTWARE_CONFIG, + VIEW_TERMINAL, + VIEW_3DWIDGET, + VIEW_GOOGLEEARTH, VIEW_UNCONNECTED, ///< View in unconnected mode, when no UAS is available VIEW_FULL ///< All widgets shown at once } VIEW_SECTIONS; @@ -317,7 +322,7 @@ protected: * @param widget The QWidget being added * @param title The entry that will appear in the Menu */ - void addCentralWidget(QWidget* widget, const QString& title); + void addToCentralStackedWidget(QWidget* widget, VIEW_SECTIONS viewSection, const QString& title); /** @brief Catch window resize events */ void resizeEvent(QResizeEvent * event); @@ -358,6 +363,7 @@ protected: QPointer mavlinkView; QPointer engineeringView; QPointer simView; + QPointer terminalView; // Center widgets QPointer linechartWidget; @@ -367,10 +373,10 @@ protected: //QPointer protocolWidget; //QPointer dataplotWidget; #ifdef QGC_OSG_ENABLED - QPointer _3DWidget; + QPointer q3DWidget; #endif #if (defined _MSC_VER) || (defined Q_OS_MAC) - QPointer gEarthWidget; + QPointer earthWidget; #endif QPointer firmwareUpdateWidget; diff --git a/src/ui/MainWindow.ui b/src/ui/MainWindow.ui index d0ba091980b39e69a9d39098e7e4ea9d4a4f9df9..ff45d55834df148e8447a5de05fc744fd6979099 100644 --- a/src/ui/MainWindow.ui +++ b/src/ui/MainWindow.ui @@ -107,6 +107,7 @@ + @@ -491,11 +492,21 @@ + + true + + + + :/files/images/apps/accessories-calculator.svg:/files/images/apps/accessories-calculator.svg + Simulation + + true + :/files/images/categories/applications-system.svg:/files/images/categories/applications-system.svg @@ -504,6 +515,18 @@ Software + + + true + + + + :/files/images/apps/utilities-terminal.svg:/files/images/apps/utilities-terminal.svg + + + Terminal + + diff --git a/src/ui/configuration/ApmHighlighter.cc b/src/ui/configuration/ApmHighlighter.cc new file mode 100644 index 0000000000000000000000000000000000000000..8e09ac6f0e3d75a7a8e0ee919cdc50681e39c12e --- /dev/null +++ b/src/ui/configuration/ApmHighlighter.cc @@ -0,0 +1,53 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief APM Highligther for ArduPilot Console. + * + * @author Bill Bonney + * + */ + +#include "ApmHighlighter.h" + +APMHighlighter::APMHighlighter(QObject *parent) : + QSyntaxHighlighter(parent) +{ +} + +void APMHighlighter::highlightBlock(const QString &text) + { + QTextCharFormat myClassFormat; + myClassFormat.setFontWeight(QFont::Bold); + myClassFormat.setForeground(Qt::darkMagenta); + QString pattern = "^\\Ardu[A-Za-z]+\\b"; + + QRegExp expression(pattern); + int index = text.indexOf(expression); + while (index >= 0) { + int length = expression.matchedLength(); + setFormat(index, length, myClassFormat); + index = text.indexOf(expression, index + length); + } + } diff --git a/src/ui/configuration/ApmHighlighter.h b/src/ui/configuration/ApmHighlighter.h new file mode 100644 index 0000000000000000000000000000000000000000..e4f9b645f129995ff257bb3cf36d13b6c888abd4 --- /dev/null +++ b/src/ui/configuration/ApmHighlighter.h @@ -0,0 +1,51 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief APM Highligther for ArduPilot Console. + * + * @author Bill Bonney + * + */ + +#ifndef APMHIGHLIGHTER_H +#define APMHIGHLIGHTER_H + +#include "ApmHighlighter.h" +#include + +class APMHighlighter : public QSyntaxHighlighter +{ + Q_OBJECT +public: + explicit APMHighlighter(QObject *parent = 0); + void highlightBlock(const QString &text); + +signals: + +public slots: + +}; + +#endif // APMHIGHLIGHTER_H diff --git a/src/ui/configuration/SerialSettingsDialog.cc b/src/ui/configuration/SerialSettingsDialog.cc new file mode 100644 index 0000000000000000000000000000000000000000..40c317068d417d7ebf78b2eef89a644276f53050 --- /dev/null +++ b/src/ui/configuration/SerialSettingsDialog.cc @@ -0,0 +1,189 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Serial Settings View. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#include "SerialSettingsDialog.h" +#include "terminalconsole.h" +#include "ui_settingsdialog.h" + +#include +#include +#include +#include + +QT_USE_NAMESPACE + +SettingsDialog::SettingsDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::SettingsDialog) +{ + ui->setupUi(this); + + m_intValidator = new QIntValidator(0, 4000000, this); + + ui->baudRateBox->setInsertPolicy(QComboBox::NoInsert); + + connect(ui->applyButton, SIGNAL(clicked()), + this, SLOT(apply())); + connect(ui->serialPortInfoListBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(showPortInfo(int))); + connect(ui->baudRateBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(checkCustomBaudRatePolicy(int))); + + fillPortsParameters(); + fillPortsInfo(); + + updateSettings(); +} + +SettingsDialog::~SettingsDialog() +{ + delete ui; +} + +const SerialSettings& SettingsDialog::settings() const +{ + return m_currentSettings; +} + +void SettingsDialog::showPortInfo(int idx) +{ + if (idx != -1) { + QStringList list = ui->serialPortInfoListBox->itemData(idx).toStringList(); + ui->descriptionLabel->setText(tr("Description: %1").arg(list.at(1))); + ui->manufacturerLabel->setText(tr("Manufacturer: %1").arg(list.at(2))); + ui->locationLabel->setText(tr("Location: %1").arg(list.at(3))); + ui->vidLabel->setText(tr("Vendor Identifier: %1").arg(list.at(4))); + ui->pidLabel->setText(tr("Product Identifier: %1").arg(list.at(5))); + } +} + +void SettingsDialog::apply() +{ + updateSettings(); + hide(); +} + +void SettingsDialog::checkCustomBaudRatePolicy(int idx) +{ + bool isCustomBaudRate = !ui->baudRateBox->itemData(idx).isValid(); + ui->baudRateBox->setEditable(isCustomBaudRate); + if (isCustomBaudRate) { + ui->baudRateBox->clearEditText(); + QLineEdit *edit = ui->baudRateBox->lineEdit(); + edit->setValidator(m_intValidator); + } +} + +void SettingsDialog::fillPortsParameters() +{ + // fill baud rate (is not the entire list of available values, + // desired values??, add your independently) + ui->baudRateBox->addItem(QLatin1String("115200"), QSerialPort::Baud115200); + ui->baudRateBox->addItem(QLatin1String("57600"), QSerialPort::Baud57600); + ui->baudRateBox->addItem(QLatin1String("38400"), QSerialPort::Baud38400); + ui->baudRateBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); + ui->baudRateBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); + ui->baudRateBox->addItem(QLatin1String("9600"), QSerialPort::Baud9600); + ui->baudRateBox->addItem(QLatin1String("Custom")); + + // fill data bits + ui->dataBitsBox->addItem(QLatin1String("5"), QSerialPort::Data5); + ui->dataBitsBox->addItem(QLatin1String("6"), QSerialPort::Data6); + ui->dataBitsBox->addItem(QLatin1String("7"), QSerialPort::Data7); + ui->dataBitsBox->addItem(QLatin1String("8"), QSerialPort::Data8); + ui->dataBitsBox->setCurrentIndex(3); + + // fill parity + ui->parityBox->addItem(QLatin1String("None"), QSerialPort::NoParity); + ui->parityBox->addItem(QLatin1String("Even"), QSerialPort::EvenParity); + ui->parityBox->addItem(QLatin1String("Odd"), QSerialPort::OddParity); + ui->parityBox->addItem(QLatin1String("Mark"), QSerialPort::MarkParity); + ui->parityBox->addItem(QLatin1String("Space"), QSerialPort::SpaceParity); + + // fill stop bits + ui->stopBitsBox->addItem(QLatin1String("1"), QSerialPort::OneStop); +#ifdef Q_OS_WIN + ui->stopBitsBox->addItem(QLatin1String("1.5"), QSerialPort::OneAndHalfStop); +#endif + ui->stopBitsBox->addItem(QLatin1String("2"), QSerialPort::TwoStop); + + // fill flow control + ui->flowControlBox->addItem(QLatin1String("None"), QSerialPort::NoFlowControl); + ui->flowControlBox->addItem(QLatin1String("RTS/CTS"), QSerialPort::HardwareControl); + ui->flowControlBox->addItem(QLatin1String("XON/XOFF"), QSerialPort::SoftwareControl); +} + +void SettingsDialog::fillPortsInfo() +{ + ui->serialPortInfoListBox->clear(); + foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { + QStringList list; + list << info.portName() + << info.description() + << info.manufacturer() + << info.systemLocation() + << (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) + << (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : QString()); + + ui->serialPortInfoListBox->insertItem(0, list.first(), list); + } +} + +void SettingsDialog::updateSettings() +{ + m_currentSettings.name = ui->serialPortInfoListBox->currentText(); + + // Baud Rate + if (ui->baudRateBox->currentIndex() == 4) { + // custom baud rate + m_currentSettings.baudRate = ui->baudRateBox->currentText().toInt(); + } else { + // standard baud rate + m_currentSettings.baudRate = static_cast( + ui->baudRateBox->itemData(ui->baudRateBox->currentIndex()).toInt()); + } + // Data bits + m_currentSettings.dataBits = static_cast( + ui->dataBitsBox->itemData(ui->dataBitsBox->currentIndex()).toInt()); + // Parity + m_currentSettings.parity = static_cast( + ui->parityBox->itemData(ui->parityBox->currentIndex()).toInt()); + // Stop bits + m_currentSettings.stopBits = static_cast( + ui->stopBitsBox->itemData(ui->stopBitsBox->currentIndex()).toInt()); + // Flow control + m_currentSettings.flowControl = static_cast( + ui->flowControlBox->itemData(ui->flowControlBox->currentIndex()).toInt()); +} diff --git a/src/ui/configuration/SerialSettingsDialog.h b/src/ui/configuration/SerialSettingsDialog.h new file mode 100644 index 0000000000000000000000000000000000000000..5b1586fdf2ffe3f55830639a3e8b8f556209a513 --- /dev/null +++ b/src/ui/configuration/SerialSettingsDialog.h @@ -0,0 +1,91 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Serial Settings View. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#ifndef SETTINGSDIALOG_H +#define SETTINGSDIALOG_H + +#include +#include + +namespace Ui { +class SettingsDialog; +} + +class QIntValidator; + +class SerialSettings { +public: + SerialSettings() : name(""), + baudRate(115200), + dataBits(QSerialPort::Data8), + parity(QSerialPort::NoParity), + stopBits(QSerialPort::OneStop), + flowControl(QSerialPort::NoFlowControl){} +public: + QString name; + qint32 baudRate; + QSerialPort::DataBits dataBits; + QSerialPort::Parity parity; + QSerialPort::StopBits stopBits; + QSerialPort::FlowControl flowControl; +}; + +class SettingsDialog : public QDialog +{ + Q_OBJECT + +public: + explicit SettingsDialog(QWidget *parent = 0); + ~SettingsDialog(); + + const SerialSettings &settings() const; + +private slots: + void showPortInfo(int idx); + void apply(); + void checkCustomBaudRatePolicy(int idx); + +private: + void fillPortsParameters(); + void fillPortsInfo(); + void updateSettings(); + +private: + Ui::SettingsDialog *ui; + SerialSettings m_currentSettings; + QIntValidator *m_intValidator; +}; + +#endif // SETTINGSDIALOG_H diff --git a/src/ui/configuration/SerialSettingsDialog.ui b/src/ui/configuration/SerialSettingsDialog.ui new file mode 100644 index 0000000000000000000000000000000000000000..5f2706fa2868f99f6775ea2375668e9fa54f5fa5 --- /dev/null +++ b/src/ui/configuration/SerialSettingsDialog.ui @@ -0,0 +1,151 @@ + + + SettingsDialog + + + + 0 + 0 + 401 + 250 + + + + Settings + + + + + + Select Serial Port + + + + + + + + + Description: + + + + + + + Manufacturer: + + + + + + + Location: + + + + + + + Vendor ID: + + + + + + + Product ID: + + + + + + + + + + + + Qt::Horizontal + + + + 96 + 20 + + + + + + + + Apply + + + + + + + + + Select Parameters + + + + + + BaudRate: + + + + + + + + + + Data bits: + + + + + + + + + + Parity: + + + + + + + + + + Stop bits: + + + + + + + + + + Flow control: + + + + + + + + + + + + + + diff --git a/src/ui/configuration/TerminalConsole.cc b/src/ui/configuration/TerminalConsole.cc new file mode 100644 index 0000000000000000000000000000000000000000..1c5233e6308e15147a664309b4e533286c2df0f2 --- /dev/null +++ b/src/ui/configuration/TerminalConsole.cc @@ -0,0 +1,14 @@ +#include "terminalconsole.h" +#include "ui_terminalconsole.h" + +TerminalConsole::TerminalConsole(QWidget *parent) : + QWidget(parent), + ui(new Ui::TerminalConsole) +{ + ui->setupUi(this); +} + +TerminalConsole::~TerminalConsole() +{ + delete ui; +} diff --git a/src/ui/configuration/console.cpp b/src/ui/configuration/console.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c530af0e6c6460ae7db9c1c390a0a554951774a7 --- /dev/null +++ b/src/ui/configuration/console.cpp @@ -0,0 +1,101 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Text Console. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#include "console.h" +#include "ApmHighlighter.h" + +#include + +#include + +Console::Console(QWidget *parent) + : QPlainTextEdit(parent) + , localEchoEnabled(false) +{ + document()->setMaximumBlockCount(100); + QPalette p = palette(); + p.setColor(QPalette::Base, Qt::black); + p.setColor(QPalette::Text, Qt::green); + setPalette(p); + + m_highlighter = new APMHighlighter(document()); + +} + +void Console::putData(const QByteArray &data) +{ + insertPlainText(QString(data)); + + QScrollBar *bar = verticalScrollBar(); + bar->setValue(bar->maximum()); +} + +void Console::setLocalEchoEnabled(bool set) +{ + localEchoEnabled = set; +} + +void Console::keyPressEvent(QKeyEvent *e) +{ + switch (e->key()) { + case Qt::Key_Backspace: + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Up: + case Qt::Key_Down: + // skip processing + break; + default: + if (localEchoEnabled) + QPlainTextEdit::keyPressEvent(e); + emit getData(e->text().toLocal8Bit()); + } +} + +void Console::mousePressEvent(QMouseEvent *e) +{ + Q_UNUSED(e) + setFocus(); +} + +void Console::mouseDoubleClickEvent(QMouseEvent *e) +{ + Q_UNUSED(e) +} + +void Console::contextMenuEvent(QContextMenuEvent *e) +{ + Q_UNUSED(e) +} diff --git a/src/ui/configuration/console.h b/src/ui/configuration/console.h new file mode 100644 index 0000000000000000000000000000000000000000..28a1135ded8584453f11e5a1487a90a4ebc23210 --- /dev/null +++ b/src/ui/configuration/console.h @@ -0,0 +1,69 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Text Console. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#ifndef CONSOLE_H +#define CONSOLE_H + +#include + +class APMHighlighter; + +class Console : public QPlainTextEdit +{ + Q_OBJECT + +signals: + void getData(const QByteArray &data); + +public: + explicit Console(QWidget *parent = 0); + + void putData(const QByteArray &data); + + void setLocalEchoEnabled(bool set); + +protected: + virtual void keyPressEvent(QKeyEvent *e); + virtual void mousePressEvent(QMouseEvent *e); + virtual void mouseDoubleClickEvent(QMouseEvent *e); + virtual void contextMenuEvent(QContextMenuEvent *e); + +private: + bool localEchoEnabled; + APMHighlighter* m_highlighter; + +}; + +#endif // CONSOLE_H diff --git a/src/ui/configuration/terminalconsole.cpp b/src/ui/configuration/terminalconsole.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0e5330355e1392184521251606959dd591317657 --- /dev/null +++ b/src/ui/configuration/terminalconsole.cpp @@ -0,0 +1,264 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Terminal Console display View. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#include "SerialSettingsDialog.h" +#include "terminalconsole.h" +#include "ui_terminalconsole.h" +#include "console.h" +#include "configuration.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +TerminalConsole::TerminalConsole(QWidget *parent) : + QWidget(parent), + ui(new Ui::TerminalConsole) +{ + ui->setupUi(this); + + // create the cosole and add it to the centralwidget + m_console = new Console; + m_console->setEnabled(false); + + m_statusBar = new QStatusBar; + + QLayout* layout = ui->terminalGroupBox->layout(); + layout->addWidget(m_console); + layout->addWidget(m_statusBar); + + m_serial = new QSerialPort(this); + m_settingsDialog = new SettingsDialog; + + ui->connectButton->setEnabled(true); + ui->disconnectButton->setEnabled(false); + ui->settingsButton->setEnabled(true); + + addBaudComboBoxConfig(); + fillPortsInfo(*ui->linkComboBox); + + loadSettings(); + + if (m_settings.name == "") { + setLink(ui->linkComboBox->currentIndex()); + } else { + ui->linkComboBox->setCurrentIndex(0); + } + + //setUiControls(m_settingsDialog); + + initConnections(); +} + +void TerminalConsole::addBaudComboBoxConfig() +{ + ui->baudComboBox->addItem(QLatin1String("115200"), QSerialPort::Baud115200); + ui->baudComboBox->addItem(QLatin1String("57600"), QSerialPort::Baud57600); + ui->baudComboBox->addItem(QLatin1String("38400"), QSerialPort::Baud38400); + ui->baudComboBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); + ui->baudComboBox->addItem(QLatin1String("19200"), QSerialPort::Baud19200); + ui->baudComboBox->addItem(QLatin1String("9600"), QSerialPort::Baud9600); +} + +void TerminalConsole::fillPortsInfo(QComboBox &comboxBox) +{ + comboxBox.clear(); + foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { + QStringList list; + list << info.portName() + << info.description() + << info.manufacturer() + << info.systemLocation() + << (info.vendorIdentifier() ? QString::number(info.vendorIdentifier(), 16) : QString()) + << (info.productIdentifier() ? QString::number(info.productIdentifier(), 16) : QString()); + + comboxBox.insertItem(0,list.first(), list); + qDebug() << "Inserting " << list.first(); + } +} + +TerminalConsole::~TerminalConsole() +{ + delete m_console; + delete m_statusBar; + delete m_settingsDialog; + delete ui; +} + +void TerminalConsole::openSerialPort() +{ + openSerialPort(m_settings); +} + +void TerminalConsole::openSerialPort(const SerialSettings &settings) +{ + m_serial->setPortName(settings.name); + if (m_serial->open(QIODevice::ReadWrite)) { + if (m_serial->setBaudRate(settings.baudRate) + && m_serial->setDataBits(settings.dataBits) + && m_serial->setParity(settings.parity) + && m_serial->setStopBits(settings.stopBits) + && m_serial->setFlowControl(settings.flowControl)) { + + m_console->setEnabled(true); + m_console->setLocalEchoEnabled(false); + ui->connectButton->setEnabled(false); + ui->disconnectButton->setEnabled(true); + ui->settingsButton->setEnabled(false); + m_statusBar->showMessage(tr("Connected to %1 : baud %2z") + .arg(settings.name).arg(QString::number(settings.baudRate))); + qDebug() << "Open Terminal Console Serial Port"; + + } else { + m_serial->close(); + QMessageBox::critical(this, tr("Error"), m_serial->errorString()); + + m_statusBar->showMessage(tr("Open error")); + } + } else { + QMessageBox::critical(this, tr("Error"), m_serial->errorString()); + + m_statusBar->showMessage(tr("Configure error")); + } +} + +void TerminalConsole::closeSerialPort() +{ + m_serial->close(); + m_console->setEnabled(false); + ui->connectButton->setEnabled(true); + ui->disconnectButton->setEnabled(false); + ui->settingsButton->setEnabled(true); + m_statusBar->showMessage(tr("Disconnected")); +} + +void TerminalConsole::writeData(const QByteArray &data) +{ +// qDebug() << "writeData:" << data; + m_serial->write(data); +} + +void TerminalConsole::readData() +{ + QByteArray data = m_serial->readAll(); +// qDebug() << "readData:" << data; + m_console->putData(data); +} + +void TerminalConsole::handleError(QSerialPort::SerialPortError error) +{ + if (error == QSerialPort::ResourceError) { + QMessageBox::critical(this, tr("Critical Error"), m_serial->errorString()); + closeSerialPort(); + } +} + +void TerminalConsole::initConnections() +{ + // Ui Connections + connect(ui->connectButton, SIGNAL(released()), this, SLOT(openSerialPort())); + connect(ui->disconnectButton, SIGNAL(released()), this, SLOT(closeSerialPort())); + connect(ui->settingsButton, SIGNAL(released()), m_settingsDialog, SLOT(show())); + connect(ui->clearButton, SIGNAL(released()), m_console, SLOT(clear())); + + connect(ui->baudComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setBaudRate(int))); + connect(ui->linkComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(setLink(int))); +// connect(ui->linkComboBox, SIGNAL()), this, SLOT(setLink(int))); + + // Serial Port Connections + connect(m_serial, SIGNAL(error(QSerialPort::SerialPortError)), this, + SLOT(handleError(QSerialPort::SerialPortError))); + + connect(m_serial, SIGNAL(readyRead()), this, SLOT(readData())); + connect(m_console, SIGNAL(getData(QByteArray)), this, SLOT(writeData(QByteArray))); +} + +void TerminalConsole::setBaudRate(int index) +{ + m_settings.baudRate = static_cast( + ui->baudComboBox->itemData(index).toInt()); + qDebug() << "Changed Baud to:" << m_settings.baudRate; + +} + +void TerminalConsole::setLink(int index) +{ + m_settings.name = ui->linkComboBox->currentText(); + qDebug() << "Changed Link to:" << m_settings.name; + +} + +void TerminalConsole::loadSettings() +{ + // Load defaults from settings + QSettings settings(QGC::COMPANYNAME, QGC::APPNAME); + settings.sync(); + if (settings.contains("TERMINALCONSOLE_COMM_PORT")) + { + m_settings.name = settings.value("TERMINALCONSOLE_COMM_PORT").toString(); + m_settings.baudRate = settings.value("TERMINALCONSOLE_COMM_BAUD").toInt(); + m_settings.parity = static_cast + (settings.value("TERMINALCONSOLE_COMM_PARITY").toInt()); + m_settings.stopBits = static_cast + (settings.value("TERMINALCONSOLE_COMM_STOPBITS").toInt()); + m_settings.dataBits = static_cast + (settings.value("TERMINALCONSOLE_COMM_DATABITS").toInt()); + m_settings.flowControl = static_cast + (settings.value("TERMINALCONSOLE_COMM_FLOW_CONTROL").toInt()); + } else { + // init the structure + } +} + +void TerminalConsole::writeSettings() +{ + // Store settings + QSettings settings(QGC::COMPANYNAME, QGC::APPNAME); + settings.setValue("TERMINALCONSOLE_COMM_PORT", m_settings.name); + settings.setValue("TERMINALCONSOLE_COMM_BAUD", m_settings.baudRate); + settings.setValue("TERMINALCONSOLE_COMM_PARITY", m_settings.parity); + settings.setValue("TERMINALCONSOLE_COMM_STOPBITS", m_settings.stopBits); + settings.setValue("TERMINALCONSOLE_COMM_DATABITS", m_settings.dataBits); + settings.setValue("TERMINALCONSOLE_COMM_FLOW_CONTROL", m_settings.flowControl); + settings.sync(); +} + + + diff --git a/src/ui/configuration/terminalconsole.h b/src/ui/configuration/terminalconsole.h new file mode 100644 index 0000000000000000000000000000000000000000..5c8a91182b07aa0dc7bee526ae2a319f6d16296f --- /dev/null +++ b/src/ui/configuration/terminalconsole.h @@ -0,0 +1,92 @@ +/*===================================================================== + +APM_PLANNER Open Source Ground Control Station + +(c) 2013, Bill Bonney + +This file is part of the APM_PLANNER project + + APM_PLANNER is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + APM_PLANNER is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with APM_PLANNER. If not, see . + +======================================================================*/ + +/** + * @file + * @brief Terminal Console display View. + * + * @author Bill Bonney + * + * Influenced from Qt examples by :- + * Copyright (C) 2012 Denis Shienkov + * Copyright (C) 2012 Laszlo Papp + * + */ + +#ifndef TERMINALCONSOLE_H +#define TERMINALCONSOLE_H + +#include "SerialSettingsDialog.h" + +#include +#include + +namespace Ui { +class TerminalConsole; +} + +class Console; +class SettingsDialog; +class QStatusBar; +class QComboBox; + +class TerminalConsole : public QWidget +{ + Q_OBJECT + +public: + explicit TerminalConsole(QWidget *parent = 0); + ~TerminalConsole(); + +private slots: + void openSerialPort(); + void openSerialPort(const SerialSettings &settings); + void closeSerialPort(); + void writeData(const QByteArray &data); + void readData(); + + void handleError(QSerialPort::SerialPortError error); + +private slots: + void setBaudRate(int index); + void setLink(int index); + +private: + void initConnections(); + void addBaudComboBoxConfig(); + void fillPortsInfo(QComboBox &comboxBox); + void writeSettings(); + void loadSettings(); + + +private: + Ui::TerminalConsole *ui; + + Console *m_console; + QStatusBar *m_statusBar; + SettingsDialog *m_settingsDialog; + QSerialPort *m_serial; + SerialSettings m_settings; +}; + +#endif // TERMINALCONSOLE_H diff --git a/src/ui/configuration/terminalconsole.ui b/src/ui/configuration/terminalconsole.ui new file mode 100644 index 0000000000000000000000000000000000000000..1ee9ec87cce830b679d6595a36ffad6f2b08ff81 --- /dev/null +++ b/src/ui/configuration/terminalconsole.ui @@ -0,0 +1,187 @@ + + + TerminalConsole + + + + 0 + 0 + 889 + 531 + + + + Form + + + + + + + 0 + 0 + + + + Terminal Output + + + + + + + + QLayout::SetMinAndMaxSize + + + + + + 100 + 0 + + + + + 131 + 0 + + + + CONNECT + + + + + + + + 0 + 0 + + + + + 131 + 0 + + + + DISCONNECT + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 20 + + + + + + + + + 0 + 0 + + + + + 123 + 0 + + + + + 220 + 32 + + + + + + + + + 0 + 0 + + + + + 123 + 0 + + + + + + + + + 0 + 0 + + + + + 123 + 0 + + + + + APM + + + + + PX4 + + + + + + + + Qt::Vertical + + + + 91 + 23 + + + + + + + + Adv. Settings + + + + + + + Clear + + + + + + + + + +