diff --git a/QGCApplication.pro b/QGCApplication.pro index 740597c03bd70a18a60c28134288808d1ef077e5..886935bc4a5a75c1a719cff1747ee90421c7e6f7 100644 --- a/QGCApplication.pro +++ b/QGCApplication.pro @@ -167,7 +167,6 @@ FORMS += \ src/QGCQmlWidgetHolder.ui \ src/ui/configuration/SerialSettingsDialog.ui \ src/ui/configuration/terminalconsole.ui \ - src/ui/DebugConsole.ui \ src/ui/HDDisplay.ui \ src/ui/Linechart.ui \ src/ui/MainWindow.ui \ @@ -278,7 +277,6 @@ HEADERS += \ src/ui/configuration/console.h \ src/ui/configuration/SerialSettingsDialog.h \ src/ui/configuration/terminalconsole.h \ - src/ui/DebugConsole.h \ src/ui/flightdisplay/FlightDisplay.h \ src/ui/HDDisplay.h \ src/ui/HSIDisplay.h \ @@ -408,7 +406,6 @@ SOURCES += \ src/ui/configuration/console.cpp \ src/ui/configuration/SerialSettingsDialog.cc \ src/ui/configuration/terminalconsole.cpp \ - src/ui/DebugConsole.cc \ src/ui/flightdisplay/FlightDisplay.cc \ src/ui/HDDisplay.cc \ src/ui/HSIDisplay.cc \ diff --git a/src/ui/DebugConsole.cc b/src/ui/DebugConsole.cc deleted file mode 100644 index dfc2997475cba6b60ac3a5f664bd987727531d7d..0000000000000000000000000000000000000000 --- a/src/ui/DebugConsole.cc +++ /dev/null @@ -1,878 +0,0 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009, 2010 QGROUNDCONTROL PROJECT - -This file is part of the QGROUNDCONTROL project - - QGROUNDCONTROL 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. - - QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . - -======================================================================*/ - -/** - * @file - * @brief This file implements the Debug Console, a serial console built-in to QGC. - * - * @author Lorenz Meier - * - */ -#include -#include -#include -#include - -#include "DebugConsole.h" -#include "ui_DebugConsole.h" -#include "LinkManager.h" -#include "UASManager.h" -#include "protocol.h" -#include "QGC.h" - -const float DebugConsole::inDataRateThreshold = 0.4f; - -DebugConsole::DebugConsole(QWidget *parent) : - QWidget(parent), - currLink(NULL), - holdOn(false), - convertToAscii(true), - filterMAVLINK(true), - autoHold(true), - bytesToIgnore(0), - lastByte(-1), - escReceived(false), - escIndex(0), - sentBytes(), - holdBuffer(), - lineBuffer(""), - lastLineBuffer(0), - lineBufferTimer(), - snapShotTimer(), - lowpassInDataRate(0.0f), - lowpassOutDataRate(0.0f), - commandIndex(0), - m_ui(new Ui::DebugConsole) -{ - // Setup basic user interface - m_ui->setupUi(this); - // Hide sent text field - it is only useful after send has been hit - m_ui->sentText->setVisible(false); - // Hide auto-send checkbox - //m_ui->specialCheckBox->setVisible(false); - // Make text area not editable - m_ui->receiveText->setReadOnly(false); - // Limit to 500 lines - m_ui->receiveText->setMaximumBlockCount(500); - // Allow to wrap everywhere - m_ui->receiveText->setWordWrapMode(QTextOption::WrapAnywhere); - - // Load settings for this widget - loadSettings(); - - // Enable traffic measurements. We only start/stop the timer as our links change, as - // these calculations are dependent on the specific link. - connect(&snapShotTimer, SIGNAL(timeout()), this, SLOT(updateTrafficMeasurements())); - snapShotTimer.setInterval(snapShotInterval); - - // First connect management slots, then make sure to add all existing objects - // Connect to link manager to get notified about new links - connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*))); - // Connect to UAS manager to get notified about new UAS - connect(UASManager::instance(), SIGNAL(UASCreated(UASInterface*)), this, SLOT(uasCreated(UASInterface*))); - - // Add all existing links - foreach (LinkInterface* link, LinkManager::instance()->getLinks()) { - addLink(link); - } - - // Get a list of all existing UAS - foreach (UASInterface* uas, UASManager::instance()->getUASList()) { - uasCreated(uas); - } - - // Connect link combo box - connect(m_ui->linkComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(linkSelected(int))); - // Connect send button - connect(m_ui->transmitButton, SIGNAL(clicked()), this, SLOT(sendBytes())); - // Connect HEX conversion and MAVLINK filter checkboxes - connect(m_ui->mavlinkCheckBox, SIGNAL(clicked(bool)), this, SLOT(MAVLINKfilterEnabled(bool))); - connect(m_ui->hexCheckBox, SIGNAL(clicked(bool)), this, SLOT(hexModeEnabled(bool))); - connect(m_ui->holdCheckBox, SIGNAL(clicked(bool)), this, SLOT(setAutoHold(bool))); - // Connect hold button - connect(m_ui->holdButton, SIGNAL(toggled(bool)), this, SLOT(hold(bool))); - // Connect connect button - connect(m_ui->connectButton, SIGNAL(clicked()), this, SLOT(handleConnectButton())); - // Connect the special chars combo box - connect(m_ui->addSymbolButton, SIGNAL(clicked()), this, SLOT(appendSpecialSymbol())); - // Connect Checkbox - connect(m_ui->specialComboBox, SIGNAL(highlighted(QString)), this, SLOT(specialSymbolSelected(QString))); - // Allow to send via return - connect(m_ui->sendText, SIGNAL(returnPressed()), this, SLOT(sendBytes())); -} - -void DebugConsole::hideEvent(QHideEvent* event) -{ - Q_UNUSED(event); - storeSettings(); -} - -DebugConsole::~DebugConsole() -{ - storeSettings(); - delete m_ui; -} - -void DebugConsole::loadSettings() -{ - // Load defaults from settings - QSettings settings; - settings.beginGroup("QGC_DEBUG_CONSOLE"); - m_ui->specialComboBox->setCurrentIndex(settings.value("SPECIAL_SYMBOL", m_ui->specialComboBox->currentIndex()).toInt()); - m_ui->specialCheckBox->setChecked(settings.value("SPECIAL_SYMBOL_CHECKBOX_STATE", m_ui->specialCheckBox->isChecked()).toBool()); - hexModeEnabled(settings.value("HEX_MODE_ENABLED", m_ui->hexCheckBox->isChecked()).toBool()); - MAVLINKfilterEnabled(settings.value("MAVLINK_FILTER_ENABLED", filterMAVLINK).toBool()); - setAutoHold(settings.value("AUTO_HOLD_ENABLED", autoHold).toBool()); - settings.endGroup(); -} - -void DebugConsole::storeSettings() -{ - // Store settings - QSettings settings; - settings.beginGroup("QGC_DEBUG_CONSOLE"); - settings.setValue("SPECIAL_SYMBOL", m_ui->specialComboBox->currentIndex()); - settings.setValue("SPECIAL_SYMBOL_CHECKBOX_STATE", m_ui->specialCheckBox->isChecked()); - settings.setValue("HEX_MODE_ENABLED", m_ui->hexCheckBox->isChecked()); - settings.setValue("MAVLINK_FILTER_ENABLED", filterMAVLINK); - settings.setValue("AUTO_HOLD_ENABLED", autoHold); - settings.endGroup(); -} - -void DebugConsole::uasCreated(UASInterface* uas) -{ - connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), - this, SLOT(receiveTextMessage(int,int,int,QString)), Qt::UniqueConnection); -} - -/** - * Add a link to the debug console output - */ -void DebugConsole::addLink(LinkInterface* link) -{ - // Add link to list - - foreach (SharedLinkInterface sharedLink, _links) { - Q_ASSERT(sharedLink.data() != link); - } - _links.append(LinkManager::instance()->sharedPointerForLink(link)); - - m_ui->linkComboBox->insertItem(link->getMavlinkChannel(), link->getName()); - // Set new item as current - m_ui->linkComboBox->setCurrentIndex(qMax(0, _links.size() - 1)); - linkSelected(m_ui->linkComboBox->currentIndex()); - - // Register for name changes - connect(link, SIGNAL(nameChanged(QString)), this, SLOT(updateLinkName(QString)), Qt::UniqueConnection); - connect(LinkManager::instance(), &LinkManager::linkDisconnected, this, &DebugConsole::removeLink, Qt::UniqueConnection); -} - -void DebugConsole::removeLink(LinkInterface* const link) -{ - // Now if this was the current link, clean up some stuff. - if (link == currLink) - { - disconnect(currLink, &LinkInterface::bytesReceived, this, &DebugConsole::receiveBytes); - disconnect(currLink, &LinkInterface::connected, this, &DebugConsole::_linkConnected); - disconnect(currLink, &LinkInterface::communicationUpdate, this, &DebugConsole::linkStatusUpdate); - - // Like disable the update time for the UI. - snapShotTimer.stop(); - - currLink = NULL; - } - - bool found = false; - int linkIndex; - for (linkIndex=0; linkIndex<_links.count(); linkIndex++) { - if (_links[linkIndex].data() == link) { - found = true; - _links.removeAt(linkIndex); - break; - } - } - Q_UNUSED(found); - Q_ASSERT(found); - - m_ui->linkComboBox->removeItem(linkIndex); - -} -void DebugConsole::linkStatusUpdate(const QString& name,const QString& text) -{ - Q_UNUSED(name); - m_ui->receiveText->appendPlainText(text); - // Ensure text area scrolls correctly - m_ui->receiveText->ensureCursorVisible(); -} - -void DebugConsole::linkSelected(int linkIndex) -{ - // Clear data - m_ui->receiveText->clear(); - - // Connect new link - if (linkIndex != -1) { - currLink = _links[linkIndex].data(); - connect(currLink, SIGNAL(bytesReceived(LinkInterface*,QByteArray)), this, SLOT(receiveBytes(LinkInterface*, QByteArray))); - disconnect(currLink, &LinkInterface::connected, this, &DebugConsole::_linkConnected); - connect(currLink,SIGNAL(communicationUpdate(QString,QString)),this,SLOT(linkStatusUpdate(QString,QString))); - _setConnectionState(currLink->isConnected()); - snapShotTimer.start(); - } -} - -/** - * @param name new name for this link - the link is determined to the sender to this slot by QObject::sender() - */ -void DebugConsole::updateLinkName(QString name) -{ - LinkInterface* link = qobject_cast(sender()); - if (link != NULL) { - bool found = false; - int linkIndex; - for (linkIndex=0; linkIndex<_links.count(); linkIndex++) { - if (_links[linkIndex].data() == link) { - found = true; - break; - } - } - - if (found) { - m_ui->linkComboBox->setItemText(linkIndex, name); - } - } -} - -void DebugConsole::setAutoHold(bool hold) -{ - // Disable current hold if hold had been enabled - if (autoHold && holdOn && !hold) { - this->hold(false); - m_ui->holdButton->setChecked(false); - } - // Set auto hold checkbox - if (m_ui->holdCheckBox->isChecked() != hold) { - m_ui->holdCheckBox->setChecked(hold); - } - - if (!hold) - { - // Warn user about not activated hold - m_ui->receiveText->appendHtml(QString("%2\n").arg(QColor(Qt::red).name(), tr("WARNING: You have NOT enabled auto-hold (stops updating the console if huge amounts of serial data arrive). Updating the console consumes significant CPU load, so if you receive more than about 5 KB/s of serial data, make sure to enable auto-hold if not using the console."))); - } - else - { - m_ui->receiveText->clear(); - } - - // Set new state - autoHold = hold; -} - -/** - * Prints the message in the UAS color - */ -void DebugConsole::receiveTextMessage(int id, int component, int severity, QString text) -{ - Q_UNUSED(severity); - if (isVisible()) - { - QString name = UASManager::instance()->getUASForId(id)->getUASName(); - QString comp; - // Get a human readable name if possible - switch (component) { - // TODO: To be completed - case MAV_COMP_ID_IMU: - comp = tr("IMU"); - break; - case MAV_COMP_ID_MAPPER: - comp = tr("MAPPER"); - break; - case MAV_COMP_ID_MISSIONPLANNER: - comp = tr("MISSION"); - break; - case MAV_COMP_ID_SYSTEM_CONTROL: - comp = tr("SYS-CONTROL"); - break; - default: - comp = QString::number(component); - break; - } - - //turn off updates while we're appending content to avoid breaking the autoscroll behavior - m_ui->receiveText->setUpdatesEnabled(false); - QScrollBar *scroller = m_ui->receiveText->verticalScrollBar(); - - m_ui->receiveText->appendHtml(QString("(%2:%3) %4\n").arg(UASManager::instance()->getUASForId(id)->getColor().name(), name, comp, text)); - - // Ensure text area scrolls correctly - scroller->setValue(scroller->maximum()); - m_ui->receiveText->setUpdatesEnabled(true); - } -} - -/** - * This function updates the speed indicator text in the GUI. - * Additionally, if this speed is too high, the display of incoming characters is disabled. - */ -void DebugConsole::updateTrafficMeasurements() -{ - // Calculate the rate of incoming data, converting to - // kilobytes per second from the received bits per second. - qint64 inDataRate = currLink->getCurrentInDataRate() / 1000.0f; - lowpassInDataRate = lowpassInDataRate * 0.9f + (0.1f * inDataRate / 8.0f); - - // If the incoming data rate is faster than our threshold, don't display the data. - // We don't use the low-passed data rate as we want the true data rate. The low-passed data - // is just for displaying to the user to remove jitter. - if ((inDataRate > inDataRateThreshold) && autoHold) { - // Enable auto-hold - m_ui->holdButton->setChecked(true); - hold(true); - } - - // Update the incoming data rate label. - m_ui->downSpeedLabel->setText(tr("%L1 kB/s").arg(lowpassInDataRate, 4, 'f', 1, '0')); - - // Calculate the rate of outgoing data, converting to - // kilobytes per second from the received bits per second. - lowpassOutDataRate = lowpassOutDataRate * 0.9f + (0.1f * currLink->getCurrentOutDataRate() / 8.0f / 1000.0f); - - // Update the outoing data rate label. - m_ui->upSpeedLabel->setText(tr("%L1 kB/s").arg(lowpassOutDataRate, 4, 'f', 1, '0')); -} - -void DebugConsole::paintEvent(QPaintEvent *event) -{ - Q_UNUSED(event); -} - -void DebugConsole::receiveBytes(LinkInterface* link, QByteArray bytes) -{ - int len = bytes.size(); - int lastSpace = 0; - if ((this->bytesToIgnore > 260) || (this->bytesToIgnore < -2)) this->bytesToIgnore = 0; - // Only add data from current link - if (link == currLink && !holdOn) - { - // Parse all bytes - for (int j = 0; j < len; j++) - { - unsigned char byte = bytes.at(j); - // Filter MAVLink (http://qgroundcontrol.org/mavlink/) messages out of the stream. - if (filterMAVLINK) - { - if (this->bytesToIgnore > 0) - { - if ( (j + this->bytesToIgnore) < len ) - j += this->bytesToIgnore - 1, this->bytesToIgnore = 1; - else - this->bytesToIgnore -= (len - j - 1), j = len - 1; - } else - if (this->bytesToIgnore == -2) - { // Payload plus header - but we got STX already - this->bytesToIgnore = static_cast(byte) + MAVLINK_NUM_NON_PAYLOAD_BYTES - 1; - if ( (j + this->bytesToIgnore) < len ) - j += this->bytesToIgnore - 1, this->bytesToIgnore = 1; - else - this->bytesToIgnore -= (len - j - 1), j = len - 1; - } else - // Filtering is done by setting an ignore counter based on the MAVLINK packet length - if (static_cast(byte) == MAVLINK_STX) - { - this->bytesToIgnore = -1; - } else - this->bytesToIgnore = 0; - } else this->bytesToIgnore = 0; - - if ( (this->bytesToIgnore <= 0) && (this->bytesToIgnore != -1) ) - { - QString str; - // Convert to ASCII for readability - if (convertToAscii) - { - if (escReceived) - { - if (escIndex < static_cast(sizeof(escBytes))) - { - escBytes[escIndex] = byte; - if (/*escIndex == 1 && */escBytes[escIndex] == 0x48) - { - // Handle sequence - // for this one, clear all text - m_ui->receiveText->clear(); - escReceived = false; - } - else if (escBytes[escIndex] == 0x4b) - { - // Handle sequence - // for this one, do nothing - escReceived = false; - } - else if (byte == 0x5b) - { - // Do nothing, this is still a valid escape sequence - } - else - { - escReceived = false; - } - } - else - { - // Obviously something went wrong, reset - escReceived = false; - escIndex = 0; - } - } - else if ((byte <= 32) || (byte > 126)) - { - switch (byte) - { - case (unsigned char)'\n': // Accept line feed - if (lastByte != '\r') // Do not break line again for LF+CR - str.append(byte); // only break line for single LF or CR bytes - break; - case (unsigned char)' ': // space of any type means don't add another on hex output - case (unsigned char)'\t': // Accept tab - case (unsigned char)'\r': // Catch and carriage return - if (lastByte != '\n') // Do not break line again for CR+LF - str.append(byte); // only break line for single LF or CR bytes - lastSpace = 1; - break; - /* VT100 emulation (partially */ - case 0x1b: // ESC received - escReceived = true; - escIndex = 0; - //qDebug() << "GOT ESC"; - break; - case 0x08: // BS (backspace) received - // Do nothing for now - break; - default: // Append replacement character (box) if char is not ASCII - QString str2; - if ( lastSpace == 1) - str2.sprintf("0x%02x ", byte); - else str2.sprintf(" 0x%02x ", byte); - str.append(str2); - lastSpace = 1; - escReceived = false; - break; - } - } - else - { - // Ignore carriage return, because that - // is auto-added with '\n' - if (byte != '\r') str.append(byte); // Append original character - lastSpace = 0; - } - } - else - { - QString str2; - str2.sprintf("%02x ", byte); - str.append(str2); - } - lineBuffer.append(str); - lastByte = byte; - } - else - { - if (filterMAVLINK) this->bytesToIgnore--; - } - - } - // Plot every 200 ms if windows is visible - if (lineBuffer.length() > 0 && (QGC::groundTimeMilliseconds() - lastLineBuffer) > 200) { - if (isVisible()) - { - m_ui->receiveText->appendPlainText(lineBuffer); - lineBuffer.clear(); - lastLineBuffer = QGC::groundTimeMilliseconds(); - // Ensure text area scrolls correctly - m_ui->receiveText->ensureCursorVisible(); - } - if (lineBuffer.size() > 8192) - { - lineBuffer.remove(0, 4096); - } - } - } - else if (link == currLink && holdOn) - { - holdBuffer.append(bytes); - if (holdBuffer.size() > 8192) - holdBuffer.remove(0, 4096); // drop old stuff - } -} - -QByteArray DebugConsole::symbolNameToBytes(const QString& text) -{ - QByteArray b; - if (text.contains("CR+LF")) { - b.append(static_cast(0x0D)); - b.append(static_cast(0x0A)); - } else if (text.contains("LF")) { - b.append(static_cast(0x0A)); - } else if (text.contains("FF")) { - b.append(static_cast(0x0C)); - } else if (text.contains("CR")) { - b.append(static_cast(0x0D)); - } else if (text.contains("TAB")) { - b.append(static_cast(0x09)); - } else if (text.contains("NUL")) { - b.append(static_cast(0x00)); - } else if (text.contains("ESC")) { - b.append(static_cast(0x1B)); - } else if (text.contains("~")) { - b.append(static_cast(0x7E)); - } else if (text.contains("")) { - b.append(static_cast(0x20)); - } - return b; -} - -QString DebugConsole::bytesToSymbolNames(const QByteArray& b) -{ - QString text; - if (b.size() > 1 && b.contains(0x0D) && b.contains(0x0A)) { - text = ""; - } else if (b.contains(0x0A)) { - text = ""; - } else if (b.contains(0x0C)) { - text = ""; - } else if (b.contains(0x0D)) { - text = ""; - } else if (b.contains(0x09)) { - text = ""; - } else if (b.contains((char)0x00)) { - text = ""; - } else if (b.contains(0x1B)) { - text = ""; - } else if (b.contains(0x7E)) { - text = "<~>"; - } else if (b.contains(0x20)) { - text = ""; - } else { - text.append(b); - } - return text; -} - -void DebugConsole::specialSymbolSelected(const QString& text) -{ - Q_UNUSED(text); -} - -void DebugConsole::appendSpecialSymbol(const QString& text) -{ - QString line = m_ui->sendText->text(); - QByteArray symbols = symbolNameToBytes(text); - // The text is appended to the enter field - if (convertToAscii) { - line.append(symbols); - } else { - - for (int i = 0; i < symbols.size(); i++) { - QString add(" 0x%1"); - line.append(add.arg(static_cast(symbols.at(i)), 2, 16, QChar('0'))); - } - } - m_ui->sendText->setText(line); -} - -void DebugConsole::appendSpecialSymbol() -{ - appendSpecialSymbol(m_ui->specialComboBox->currentText()); -} - -void DebugConsole::sendBytes() -{ - // FIXME This store settings should be removed - // once all threading issues have been resolved - // since its called in the destructor, which - // is absolutely sufficient - storeSettings(); - - // Store command history - commandHistory.append(m_ui->sendText->text()); - // Since text was just sent, we're at position commandHistory.length() - // which is the current text - commandIndex = commandHistory.length(); - - if (!m_ui->sentText->isVisible()) { - m_ui->sentText->setVisible(true); - } - - if (!currLink->isConnected()) { - m_ui->sentText->setText(tr("Nothing sent. The link %1 is unconnected. Please connect first.").arg(currLink->getName())); - return; - } - - QString transmitUnconverted = m_ui->sendText->text(); - QByteArray specialSymbol; - - // Append special symbol if checkbox is checked - if (m_ui->specialCheckBox->isChecked()) { - // Get auto-add special symbols - specialSymbol = symbolNameToBytes(m_ui->specialComboBox->currentText()); - - // Convert them if needed - if (!convertToAscii) { - QString specialSymbolConverted; - for (int i = 0; i < specialSymbol.length(); i++) { - QString add(" 0x%1"); - specialSymbolConverted.append(add.arg(static_cast(specialSymbol.at(i)), 2, 16, QChar('0'))); - } - specialSymbol.clear(); - specialSymbol.append(specialSymbolConverted); - } - } - - QByteArray transmit; - QString feedback; - bool ok = true; - if (convertToAscii) { - // ASCII text is not converted - transmit = transmitUnconverted.toLatin1(); - // Auto-add special symbol handling - transmit.append(specialSymbol); - - QString translated; - - // Replace every occurence of a special symbol with its text name - for (int i = 0; i < transmit.size(); ++i) { - QByteArray specialChar; - specialChar.append(transmit.at(i)); - translated.append(bytesToSymbolNames(specialChar)); - } - - feedback.append(translated); - } else { - // HEX symbols are converted to bytes - QString str = transmitUnconverted.toLatin1(); - str.append(specialSymbol); - str.remove(' '); - str.remove("0x"); - str = str.simplified(); - int bufferIndex = 0; - if ((str.size() % 2) == 0) { - for (int i = 0; i < str.size(); i=i+2) { - bool okByte; - QString strBuf = QString(str.at(i)); - strBuf.append(str.at(i+1)); - unsigned char hex = strBuf.toInt(&okByte, 16); - ok = (ok && okByte); - transmit[bufferIndex++] = hex; - - if (okByte) { - // Feedback - feedback.append(str.at(i).toUpper()); - feedback.append(str.at(i+1).toUpper()); - feedback.append(" "); - } else { - feedback = tr("HEX format error near \"") + strBuf + "\""; - } - } - } else { - ok = false; - feedback = tr("HEX values have to be in pairs, e.g. AA or AA 05"); - } - } - - // Transmit ASCII or HEX formatted text, only if more than one symbol - if (ok && m_ui->sendText->text().toLatin1().size() > 0) { - // Transmit only if conversion succeeded - currLink->writeBytes(transmit, transmit.size()); - m_ui->sentText->setText(tr("Sent: ") + feedback); - } else if (m_ui->sendText->text().toLatin1().size() > 0) { - // Conversion failed, display error message - m_ui->sentText->setText(tr("Not sent: ") + feedback); - } - - // Select text to easy follow-up input from user - m_ui->sendText->selectAll(); - m_ui->sendText->setFocus(Qt::OtherFocusReason); -} - -/** - * @param mode true to convert all in and output to/from HEX, false to send and receive ASCII values - */ -void DebugConsole::hexModeEnabled(bool mode) -{ - if (convertToAscii == mode) { - convertToAscii = !mode; - if (m_ui->hexCheckBox->isChecked() != mode) { - m_ui->hexCheckBox->setChecked(mode); - } - m_ui->receiveText->clear(); - m_ui->sendText->clear(); - m_ui->sentText->clear(); - commandHistory.clear(); - } -} - -/** - * @param filter true to ignore all MAVLINK raw data in output, false, to display all incoming data - */ -void DebugConsole::MAVLINKfilterEnabled(bool filter) -{ - if (filterMAVLINK != filter) { - filterMAVLINK = filter; - this->bytesToIgnore = 0; - if (m_ui->mavlinkCheckBox->isChecked() != filter) { - m_ui->mavlinkCheckBox->setChecked(filter); - } - } -} -/** - * @param hold Freeze the input and thus any scrolling - */ -void DebugConsole::hold(bool hold) -{ - if (holdOn != hold) { - // Check if we need to append bytes from the hold buffer - if (this->holdOn && !hold) { - // TODO No conversion is done to the bytes in the hold buffer - m_ui->receiveText->appendPlainText(QString(holdBuffer)); - holdBuffer.clear(); - lowpassInDataRate = 0.0f; - } - - this->holdOn = hold; - - // Change text interaction mode - if (hold) { - m_ui->receiveText->setTextInteractionFlags(Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse | Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse); - } else { - m_ui->receiveText->setTextInteractionFlags(Qt::NoTextInteraction); - } - if (m_ui->holdCheckBox->isChecked() != hold) { - m_ui->holdCheckBox->setChecked(hold); - } - } -} - -void DebugConsole::_linkConnected(void) -{ - _setConnectionState(true); -} - -void DebugConsole::_linkDisconnected(void) -{ - _setConnectionState(false); -} - -/** - * Sets the connection state the widget shows to this state - */ -void DebugConsole::_setConnectionState(bool connected) -{ - if(connected) { - m_ui->connectButton->setText(tr("Disconn.")); - m_ui->receiveText->appendHtml(QString("%2\n").arg(QGC::colorGreen.name(), tr("Link %1 is connected.").arg(currLink->getName()))); - } else { - m_ui->connectButton->setText(tr("Connect")); - m_ui->receiveText->appendHtml(QString("%2\n").arg(QGC::colorOrange.name(), tr("Link %1 is unconnected.").arg(currLink->getName()))); - } -} - -/** @brief Handle the connect button */ -void DebugConsole::handleConnectButton() -{ - if (currLink) { - if (currLink->isConnected()) { - LinkManager::instance()->disconnect(currLink); - } else { - LinkManager::instance()->connectLink(currLink); - } - } -} - -void DebugConsole::keyPressEvent(QKeyEvent * event) -{ - if (event->key() == Qt::Key_Up) { - cycleCommandHistory(true); - } else if (event->key() == Qt::Key_Down) { - cycleCommandHistory(false); - } else { - QWidget::keyPressEvent(event); - } -} - -void DebugConsole::cycleCommandHistory(bool up) -{ - // Only cycle if there is a history - if (commandHistory.length() > 0) { - // Store current command if we're not in history yet - if (commandIndex == commandHistory.length() && up) { - currCommand = m_ui->sendText->text(); - } - - if (up) { - // UP - commandIndex--; - if (commandIndex >= 0) { - m_ui->sendText->setText(commandHistory.at(commandIndex)); - } - - // If the index - } else { - // DOWN - commandIndex++; - if (commandIndex < commandHistory.length()) { - m_ui->sendText->setText(commandHistory.at(commandIndex)); - } - // If the index is at history length, load the last current command - - } - - // Restore current command if we went out of history - if (commandIndex == commandHistory.length()) { - m_ui->sendText->setText(currCommand); - } - - // If we are too far down or too far up, wrap around to current command - if (commandIndex < 0 || commandIndex > commandHistory.length()) { - commandIndex = commandHistory.length(); - m_ui->sendText->setText(currCommand); - } - - // Bound the index - if (commandIndex < 0) commandIndex = 0; - if (commandIndex > commandHistory.length()) commandIndex = commandHistory.length(); - } -} - -void DebugConsole::changeEvent(QEvent *e) -{ - QWidget::changeEvent(e); - switch (e->type()) { - case QEvent::LanguageChange: - m_ui->retranslateUi(this); - break; - default: - break; - } -} diff --git a/src/ui/DebugConsole.h b/src/ui/DebugConsole.h deleted file mode 100644 index 6a4849157abf3cd4ba72667bbd99e309ede65e65..0000000000000000000000000000000000000000 --- a/src/ui/DebugConsole.h +++ /dev/null @@ -1,161 +0,0 @@ -/*===================================================================== - -QGroundControl Open Source Ground Control Station - -(c) 2009, 2010 QGROUNDCONTROL PROJECT - -This file is part of the QGROUNDCONTROL project - - QGROUNDCONTROL 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. - - QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . - -======================================================================*/ - -/** - * @file - * @brief Debug console - * - * @author Lorenz Meier - * - */ - -#ifndef DEBUGCONSOLE_H -#define DEBUGCONSOLE_H - -#include -#include -#include -#include -#include - -#include "LinkInterface.h" - -namespace Ui -{ -class DebugConsole; -} - -class UASInterface; - -/** - * @brief Shows a debug console - * - * This class shows the raw data stream of each link - * and the debug / text messages sent by all systems - */ -class DebugConsole : public QWidget -{ - Q_OBJECT -public: - DebugConsole(QWidget *parent = 0); - ~DebugConsole(); - -public slots: - /** @brief Add a link to the list of monitored links */ - void addLink(LinkInterface* link); - /** @brief Add a UAS to the list of monitored UAS */ - void uasCreated(UASInterface* uas); - /** @brief Remove a link from the list */ - void removeLink(LinkInterface* link); - /** @brief Update a link name */ - void updateLinkName(QString name); - /** @brief Select a link for the active view */ - void linkSelected(int linkId); - /** @brief Receive bytes from link */ - void receiveBytes(LinkInterface* link, QByteArray bytes); - /** @brief Send lineedit content over link */ - void sendBytes(); - /** @brief Enable HEX display mode */ - void hexModeEnabled(bool mode); - /** @brief Filter out MAVLINK raw data */ - void MAVLINKfilterEnabled(bool filter); - /** @brief Freeze input, do not store new incoming data */ - void hold(bool hold); - /** @brief Handle the connect button */ - void handleConnectButton(); - /** @brief Enable auto-freeze mode if traffic intensity is too high to display */ - void setAutoHold(bool hold); - /** @brief Receive plain text message to output to the user */ - void receiveTextMessage(int id, int component, int severity, QString text); - /** @brief Append a special symbol */ - void appendSpecialSymbol(const QString& text); - /** @brief Append the special symbol currently selected in combo box */ - void appendSpecialSymbol(); - /** @brief A new special symbol is selected */ - void specialSymbolSelected(const QString& text); - - void linkStatusUpdate(const QString& name,const QString& text); - -protected slots: - /** @brief Draw information overlay */ - void paintEvent(QPaintEvent *event); - /** @brief Update traffic measurements */ - void updateTrafficMeasurements(); - void loadSettings(); - void storeSettings(); - -protected: - void changeEvent(QEvent *e); - void hideEvent(QHideEvent* event); - /** @brief Convert a symbol name to the byte representation */ - QByteArray symbolNameToBytes(const QString& symbol); - /** @brief Convert a symbol byte to the name */ - QString bytesToSymbolNames(const QByteArray& b); - /** @brief Handle keypress events */ - void keyPressEvent(QKeyEvent * event); - /** @brief Cycle through the command history */ - void cycleCommandHistory(bool up); - - LinkInterface* currLink; - - bool holdOn; ///< Hold current view, ignore new data - bool convertToAscii; ///< Convert data to ASCII - bool filterMAVLINK; ///< Set true to filter out MAVLink in output - bool autoHold; ///< Auto-hold mode sets view into hold if the data rate is too high - int bytesToIgnore; ///< Number of bytes to ignore - char lastByte; ///< The last received byte - bool escReceived; ///< True if received ESC char in ASCII mode - int escIndex; ///< Index of bytes since ESC was received - char escBytes[5]; ///< Escape-following bytes - bool terminalReceived; ///< Terminal sequence received - QList sentBytes; ///< Transmitted bytes, per transmission - QByteArray holdBuffer; ///< Buffer where bytes are stored during hold-enable - QString lineBuffer; ///< Buffere where bytes are stored before writing them out - quint64 lastLineBuffer; ///< Last line buffer emission time - QTimer lineBufferTimer; ///< Line buffer timer - QTimer snapShotTimer; ///< Timer for measuring traffic snapshots - static const int snapShotInterval = 500; ///< Set the time between UI updates for the data rate (ms) - float lowpassInDataRate; ///< Lowpass filtered data rate (kilobytes/s) - static const float inDataRateThreshold; ///< Threshold where to enable auto-hold (kilobytes/s) - float lowpassOutDataRate; ///< Low-pass filtered outgoing data rate (kilobytes/s) - QStringList commandHistory; - QString currCommand; - int commandIndex; - -private slots: - void _linkConnected(void); - void _linkDisconnected(void); - -private: - /** @brief Set connection state of the current link */ - void _setConnectionState(bool); - - /// List of all links we are keeping track of. We keep SharedLinkInterface objects - /// which are QSharedPointer's in order to maintain reference counts. Otherwise signals - /// can get out of order and the link may be deleted before we clean up our side. - QList _links; - - Ui::DebugConsole *m_ui; -}; - -#endif // DEBUGCONSOLE_H diff --git a/src/ui/DebugConsole.ui b/src/ui/DebugConsole.ui deleted file mode 100644 index 68bf2ee63dec762fc5b5bda41a3baf56b03876bb..0000000000000000000000000000000000000000 --- a/src/ui/DebugConsole.ui +++ /dev/null @@ -1,375 +0,0 @@ - - - DebugConsole - - - - 0 - 0 - 570 - 211 - - - - Form - - - - 6 - - - 4 - - - 6 - - - - - - - - 130 - 16777215 - - - - Select the link to monitor - - - - - - - - 0 - 0 - - - - - 12 - 16 - - - - - 12 - 16 - - - - - 12 - 16 - - - - false - - - - - - :/res/DownArrow - - - true - - - - - - - 00.0 kB/s - - - - - - - - 12 - 16 - - - - - - - :/res/UpArrow - - - true - - - - - - - 00.0 kB/s - - - - - - - Ignore MAVLINK protocol messages in display - - - Ignore MAVLINK protocol messages in display - - - Hide MAVLink - - - - - - - Display and enter bytes in HEX representation (e.g. 0xAA) - - - Display and enter bytes in HEX representation (e.g. 0xAA) - - - HEX - - - - - - - Saves CPU ressources, automatically set view to hold if data rate is too high to prevent fast scrolling - - - Saves CPU ressources, automatically set view to hold if data rate is too high to prevent fast scrolling - - - Enable auto hold to lower the CPU consumption - - - Auto Hold - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - 300 - 50 - - - - true - - - 60 - - - - - - - Enter data/text below to send - - - true - - - - - - - 5 - - - - - - 100 - 16777215 - - - - 10 - - - QComboBox::AdjustToContentsOnFirstShow - - - 1 - - - - Add.. - - - - - CR+LF - - - - - LF - - - - - FF - - - - - CR - - - - - TAB - - - - - ESC - - - - - ~ - - - - - <Space> - - - - - - - - - - - - :/res/PlusSign:/res/PlusSign - - - - - - - Automatically send special char at end of message - - - Auto-Add - - - - - - - Send the ASCII text or HEX values over the link - - - Send - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 5 - 20 - - - - - - - - Hold - - - true - - - - - - - Clear - - - - - - - Disconn. - - - - - - - - - - 80 - 0 - - - - Type the bytes to send here, use 0xAA format for HEX (Check HEX checkbox above) - - - - - - - - - - - clearButton - clicked() - receiveText - clear() - - - 356 - 278 - - - 199 - 146 - - - - - diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index f93546bafd7d15a0a8e1a1cb6578d660c13c2981..d21fe2cbe58b9fda4b28479a7e43255f49858387 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -119,7 +119,6 @@ const char* MainWindow::_hdd2DockWidgetName = "HEAD_DOWN_DISPLAY_2_DOCKWIDGET"; const char* MainWindow::_pfdDockWidgetName = "PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET"; const char* MainWindow::_hudDockWidgetName = "HEAD_UP_DISPLAY_DOCKWIDGET"; const char* MainWindow::_uasInfoViewDockWidgetName = "UAS_INFO_INFOVIEW_DOCKWIDGET"; -const char* MainWindow::_debugConsoleDockWidgetName = "COMMUNICATION_CONSOLE_DOCKWIDGET"; static MainWindow* _instance = NULL; ///< @brief MainWindow singleton @@ -445,7 +444,6 @@ void MainWindow::_buildCommonWidgets(void) { _pfdDockWidgetName, "Primary Flight Display", Qt::RightDockWidgetArea }, { _hudDockWidgetName, "Video Downlink", Qt::RightDockWidgetArea }, { _uasInfoViewDockWidgetName, "Info View", Qt::LeftDockWidgetArea }, - { _debugConsoleDockWidgetName, "Communications Console", Qt::LeftDockWidgetArea }, }; static const size_t cDockWidgetInfo = sizeof(rgDockWidgetInfo) / sizeof(rgDockWidgetInfo[0]); @@ -586,8 +584,6 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName) QGCTabbedInfoView* pInfoView = new QGCTabbedInfoView(this); pInfoView->addSource(mavlinkDecoder); widget = pInfoView; - } else if (widgetName == _debugConsoleDockWidgetName) { - widget = new DebugConsole(this); } else { qWarning() << "Attempt to create unknown Inner Dock Widget" << widgetName; } diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index d350fdae36edbfa29118985cf8cb4ce3b3f12483..9b18241d97300af1b62430f2190e9483e239d762 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -53,7 +53,6 @@ This file is part of the QGROUNDCONTROL project #if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX) #include "Mouse6dofInput.h" #endif // QGC_MOUSE_ENABLED_WIN -#include "DebugConsole.h" #include "ParameterEditorWidget.h" #include "HDDisplay.h" #include "HSIDisplay.h" @@ -334,7 +333,6 @@ private: static const char* _pfdDockWidgetName; static const char* _hudDockWidgetName; static const char* _uasInfoViewDockWidgetName; - static const char* _debugConsoleDockWidgetName; QMap _mapName2DockWidget; QMap _mapUasId2HilDockWidget;