Commit 4127e96e authored by Don Gagne's avatar Don Gagne

Merge pull request #1148 from DonLakeFlyer/MainWindowReorg

Moving more things off of MainWindow
parents d2cc809e ebb14758
......@@ -27,6 +27,9 @@ This file is part of the QGROUNDCONTROL project
*
*/
#include "LogCompressor.h"
#include "QGCApplication.h"
#include <QFile>
#include <QFileInfo>
#include <QDir>
......@@ -34,8 +37,6 @@ This file is part of the QGROUNDCONTROL project
#include <QStringList>
#include <QFileInfo>
#include <QList>
#include "LogCompressor.h"
#include <QDebug>
/**
......@@ -50,6 +51,7 @@ LogCompressor::LogCompressor(QString logFileName, QString outFileName, QString d
delimiter(delimiter),
holeFillingEnabled(true)
{
connect(this, &LogCompressor::logProcessingCriticalError, qgcApp(), &QGCApplication::criticalMessageBoxOnMainThread);
}
void LogCompressor::run()
......@@ -57,7 +59,7 @@ void LogCompressor::run()
// Verify that the input file is useable
QFile infile(logFileName);
if (!infile.exists() || !infile.open(QIODevice::ReadOnly | QIODevice::Text)) {
emit logProcessingStatusChanged(tr("Log Compressor: Cannot start/compress log file, since input file %1 is not readable").arg(QFileInfo(infile.fileName()).absoluteFilePath()));
_signalCriticalError(tr("Log Compressor: Cannot start/compress log file, since input file %1 is not readable").arg(QFileInfo(infile.fileName()).absoluteFilePath()));
return;
}
......@@ -74,7 +76,7 @@ void LogCompressor::run()
// Verify that the output file is useable
QFile outTmpFile(outFileName);
if (!outTmpFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
emit logProcessingStatusChanged(tr("Log Compressor: Cannot start/compress log file, since output file %1 is not writable").arg(QFileInfo(outTmpFile.fileName()).absoluteFilePath()));
_signalCriticalError(tr("Log Compressor: Cannot start/compress log file, since output file %1 is not writable").arg(QFileInfo(outTmpFile.fileName()).absoluteFilePath()));
return;
}
......@@ -112,7 +114,7 @@ void LogCompressor::run()
headerLine = headerLine.replace(".", "");
outTmpFile.write(headerLine.toLocal8Bit());
emit logProcessingStatusChanged(tr("Log compressor: Dataset contains dimensions: ") + headerLine);
_signalCriticalError(tr("Log compressor: Dataset contains dimensions: ") + headerLine);
// Template list stores a list for populating with data as it's parsed from messages.
QStringList templateList;
......@@ -191,11 +193,8 @@ void LogCompressor::run()
// We're now done with the source file
infile.close();
emit logProcessingStatusChanged(tr("Log Compressor: Writing output to file %1").arg(QFileInfo(outFileName).absoluteFilePath()));
// Clean up and update the status before we return.
currentDataLine = 0;
emit logProcessingStatusChanged(tr("Log compressor: Finished processing file: %1").arg(outFileName));
emit finishedFile(outFileName);
running = false;
}
......@@ -219,3 +218,9 @@ int LogCompressor::getCurrentLine()
{
return currentDataLine;
}
void LogCompressor::_signalCriticalError(const QString& msg)
{
emit logProcessingCriticalError(tr("Log Compressor"), msg);
}
......@@ -24,15 +24,18 @@ protected:
bool holeFillingEnabled; ///< Enables the filling of holes in the dataset with the previous value (or NaN if none exists)
signals:
/** @brief This signal is emitted when there is a change in the status of the parsing algorithm. For instance if an error is encountered.
* @param status A status message
*/
void logProcessingStatusChanged(QString status);
/** @brief This signal is emitted once a logfile has been finished writing
* @param fileName The name of the output (CSV) file
*/
void finishedFile(QString fileName);
/// This signal is connected to QGCApplication::showCriticalMessage to show critical errors which come from the thread.
/// There is no need for clients to connect to this signal.
void logProcessingCriticalError(const QString& title, const QString& msg);
private:
void _signalCriticalError(const QString& msg);
};
#endif // LOGCOMPRESSOR_H
\ No newline at end of file
......@@ -56,6 +56,7 @@
#include "UASManager.h"
#include "AutoPilotPluginManager.h"
#include "QGCTemporaryFile.h"
#include "QGCFileDialog.h"
#ifdef QGC_RTLAB_ENABLED
#include "OpalLink.h"
......@@ -313,6 +314,10 @@ bool QGCApplication::_initForNormalAppBoot(void)
}
}
// Now that main window is upcheck for lost log files
connect(this, &QGCApplication::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles);
emit checkForLostLogFiles();
return true;
}
......@@ -482,3 +487,30 @@ void QGCApplication::_destroySingletons(void)
LinkManager::_deleteSingleton();
GAudioOutput::_deleteSingleton();
}
void QGCApplication::informationMessageBoxOnMainThread(const QString& title, const QString& msg)
{
QGCMessageBox::information(title, msg);
}
void QGCApplication::warningMessageBoxOnMainThread(const QString& title, const QString& msg)
{
QGCMessageBox::warning(title, msg);
}
void QGCApplication::criticalMessageBoxOnMainThread(const QString& title, const QString& msg)
{
QGCMessageBox::critical(title, msg);
}
void QGCApplication::saveTempFlightDataLogOnMainThread(QString tempLogfile)
{
QString saveFilename = QGCFileDialog::getSaveFileName(MainWindow::instance(),
tr("Select file to save Flight Data Log"),
qgcApp()->mavlinkLogFilesLocation(),
tr("Flight Data Log (*.mavlink)"));
if (!saveFilename.isEmpty()) {
QFile::copy(tempLogfile, saveFilename);
}
QFile::remove(tempLogfile);
}
......@@ -87,7 +87,27 @@ public:
/// @brief Returns truee if unit test are being run
bool runningUnitTests(void) { return _runningUnitTests; }
public slots:
/// You can connect to this slot to show an information message box from a different thread.
void informationMessageBoxOnMainThread(const QString& title, const QString& msg);
/// You can connect to this slot to show a warning message box from a different thread.
void warningMessageBoxOnMainThread(const QString& title, const QString& msg);
/// You can connect to this slot to show a critical message box from a different thread.
void criticalMessageBoxOnMainThread(const QString& title, const QString& msg);
/// Save the specified Flight Data Log
void saveTempFlightDataLogOnMainThread(QString tempLogfile);
signals:
/// This is connected to MAVLinkProtocol::checkForLostLogFiles. We signal this to ourselves to call the slot
/// on the MAVLinkProtocol thread;
void checkForLostLogFiles(void);
public:
// Although public, these methods are internal and should only be called by UnitTest code
/// @brief Perform initialize which is common to both normal application running and unit tests.
/// Although public should only be called by main.
void _initCommon(void);
......
......@@ -108,6 +108,8 @@ void QGCFileDialog::_validate(QString* selectedFilter, Options& options)
// You can't use QGCFileDialog if QGCApplication is not created yet.
Q_ASSERT(qgcApp());
Q_ASSERT_X(QThread::currentThread() == qgcApp()->thread(), "Threading issue", "QGCFileDialog can only be called from main thread");
// Support for selectedFilter is not yet implemented through the unit test framework
Q_UNUSED(selectedFilter);
Q_ASSERT(selectedFilter == NULL);
......
......@@ -92,10 +92,15 @@ private:
// You can't use QGCMessageBox if QGCApplication is not created yet.
Q_ASSERT(qgcApp());
Q_ASSERT_X(QThread::currentThread() == qgcApp()->thread(), "Threading issue", "QGCMessageBox can only be called from main thread");
parent = _validateParameters(buttons, &defaultButton, parent);
if (MainWindow::instance()) {
MainWindow::instance()->hideSplashScreen();
if (parent == NULL) {
parent = MainWindow::instance();
}
}
#ifdef QT_DEBUG
......
......@@ -192,7 +192,7 @@ signals:
void nameChanged(QString name);
/** @brief Communication error occured */
void communicationError(const QString& linkname, const QString& error);
void communicationError(const QString& title, const QString& error);
void communicationUpdate(const QString& linkname, const QString& text);
......
......@@ -76,7 +76,7 @@ void LinkManager::addLink(LinkInterface* link)
// MainWindow may be around when doing things like running unit tests
if (MainWindow::instance()) {
connect(link, SIGNAL(communicationError(QString,QString)), MainWindow::instance(), SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection);
connect(link, &LinkInterface::communicationError, qgcApp(), &QGCApplication::criticalMessageBoxOnMainThread);
}
MAVLinkProtocol* mavlink = MAVLinkProtocol::instance();
......
......@@ -56,8 +56,6 @@ MAVLinkProtocol::MAVLinkProtocol(QObject* parent) :
_logSuspendError(false),
_logSuspendReplay(false),
_tempLogFile(QString("%2.%3").arg(_tempLogFileTemplate).arg(_logFileExtension)),
_protocolStatusMessageConnected(false),
_saveTempFlightDataLogConnected(false),
_linkMgr(LinkManager::instance()),
_heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE),
_heartbeatsEnabled(true)
......@@ -83,6 +81,9 @@ MAVLinkProtocol::MAVLinkProtocol(QObject* parent) :
connect(&_heartbeatTimer, &QTimer::timeout, this, &MAVLinkProtocol::sendHeartbeat);
_heartbeatTimer.start(1000/_heartbeatRate);
connect(this, &MAVLinkProtocol::protocolStatusMessage, qgcApp(), &QGCApplication::criticalMessageBoxOnMainThread);
connect(this, &MAVLinkProtocol::saveTempFlightDataLog, qgcApp(), &QGCApplication::saveTempFlightDataLogOnMainThread);
emit versionCheckChanged(m_enable_version_check);
}
......@@ -233,7 +234,10 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
warnedUser = true;
// Obviously the user tries to use a 0.9 autopilot
// with QGroundControl built for version 1.0
emit protocolStatusMessage("MAVLink Version or Baud Rate Mismatch", "Your MAVLink device seems to use the deprecated version 0.9, while QGroundControl only supports version 1.0+. Please upgrade the MAVLink version of your autopilot. If your autopilot is using version 1.0, check if the baud rates of QGroundControl and your autopilot are the same.");
emit protocolStatusMessage(tr("MAVLink Protocol"), tr("There is a MAVLink Version or Baud Rate Mismatch. "
"Your MAVLink device seems to use the deprecated version 0.9, while QGroundControl only supports version 1.0+. "
"Please upgrade the MAVLink version of your autopilot. "
"If your autopilot is using version 1.0, check if the baud rates of QGroundControl and your autopilot are the same."));
}
if (decodeState == 0 && !decodedFirstPacket)
......@@ -250,7 +254,8 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
else
{
warnedUserNonMavlink = true;
emit protocolStatusMessage("MAVLink Baud Rate Mismatch", "Please check if the baud rates of QGroundControl and your autopilot are the same.");
emit protocolStatusMessage(tr("MAVLink Protocol"), tr("There is a MAVLink Version or Baud Rate Mismatch. "
"Please check if the baud rates of QGroundControl and your autopilot are the same."));
}
}
}
......@@ -303,7 +308,7 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
if(_tempLogFile.write(b) != len)
{
// If there's an error logging data, raise an alert and stop logging.
emit protocolStatusMessage(tr("MAVLink Logging failed"), tr("Could not write to file %1, logging disabled.").arg(_tempLogFile.fileName()));
emit protocolStatusMessage(tr("MAVLink Protocol"), tr("MAVLink Logging failed. Could not write to file %1, logging disabled.").arg(_tempLogFile.fileName()));
_stopLogging();
_logSuspendError = true;
}
......@@ -327,7 +332,7 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
// Check if the UAS has the same id like this system
if (message.sysid == getSystemId())
{
emit protocolStatusMessage(tr("SYSTEM ID CONFLICT!"), tr("Warning: A second system is using the same system id (%1)").arg(getSystemId()));
emit protocolStatusMessage(tr("MAVLink Protocol"), tr("Warning: A second system is using the same system id (%1)").arg(getSystemId()));
}
// Create a new UAS based on the heartbeat received
......@@ -347,8 +352,9 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b)
// Bring up dialog to inform user
if (!versionMismatchIgnore)
{
emit protocolStatusMessage(tr("The MAVLink protocol version on the MAV and QGroundControl mismatch!"),
tr("It is unsafe to use different MAVLink versions. QGroundControl therefore refuses to connect to system %1, which sends MAVLink version %2 (QGroundControl uses version %3).").arg(message.sysid).arg(heartbeat.mavlink_version).arg(MAVLINK_VERSION));
emit protocolStatusMessage(tr("MAVLink Protocol"), tr("The MAVLink protocol version on the MAV and QGroundControl mismatch! "
"It is unsafe to use different MAVLink versions. "
"QGroundControl therefore refuses to connect to system %1, which sends MAVLink version %2 (QGroundControl uses version %3).").arg(message.sysid).arg(heartbeat.mavlink_version).arg(MAVLINK_VERSION));
versionMismatchIgnore = true;
}
......@@ -649,8 +655,8 @@ void MAVLinkProtocol::_startLogging(void)
if (!_logSuspendReplay) {
if (!_tempLogFile.open()) {
emit protocolStatusMessage(tr("Opening Flight Data file for writing failed"),
tr("Unable to write to %1. Please choose a different file location.").arg(_tempLogFile.fileName()));
emit protocolStatusMessage(tr("MAVLink Protocol"), tr("Opening Flight Data file for writing failed. "
"Unable to write to %1. Please choose a different file location.").arg(_tempLogFile.fileName()));
_closeLogFile();
_logSuspendError = true;
return;
......@@ -666,7 +672,7 @@ void MAVLinkProtocol::_stopLogging(void)
{
if (_closeLogFile()) {
// If the signals are not connected it means we are running a unit test. In that case just delete log files
if (_protocolStatusMessageConnected && _saveTempFlightDataLogConnected && qgcApp()->promptFlightDataSave()) {
if (qgcApp()->promptFlightDataSave()) {
emit saveTempFlightDataLog(_tempLogFile.fileName());
} else {
QFile::remove(_tempLogFile.fileName());
......@@ -674,28 +680,10 @@ void MAVLinkProtocol::_stopLogging(void)
}
}
/// @brief We override this virtual from QObject so that we can track when the
/// protocolStatusMessage and saveTempFlightDataLog signals are connected.
/// Once both are connected we can check for lost log files.
void MAVLinkProtocol::connectNotify(const QMetaMethod& signal)
{
if (signal == QMetaMethod::fromSignal(&MAVLinkProtocol::protocolStatusMessage)) {
_protocolStatusMessageConnected = true;
if (_saveTempFlightDataLogConnected) {
_checkLostLogFiles();
}
} else if (signal == QMetaMethod::fromSignal(&MAVLinkProtocol::saveTempFlightDataLog)) {
_saveTempFlightDataLogConnected = true;
if (_protocolStatusMessageConnected) {
_checkLostLogFiles();
}
}
}
/// @brief Checks the temp directory for log files which may have been left there.
/// This could happen if QGC crashes without the temp log file being saved.
/// Give the user an option to save these orphaned files.
void MAVLinkProtocol::_checkLostLogFiles(void)
void MAVLinkProtocol::checkForLostLogFiles(void)
{
QDir tempDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
......
......@@ -205,11 +205,11 @@ public slots:
/// @brief Deletes any log files which are in the temp directory
static void deleteTempLogFiles(void);
/// Checks for lost log files
void checkForLostLogFiles(void);
protected:
// Override from QObject
virtual void connectNotify(const QMetaMethod& signal);
protected:
bool m_multiplexingEnabled; ///< Enable/disable packet multiplexing
bool m_authEnabled; ///< Enable authentication token broadcast
QString m_authKey; ///< Authentication key
......@@ -284,7 +284,6 @@ private:
bool _closeLogFile(void);
void _startLogging(void);
void _stopLogging(void);
void _checkLostLogFiles(void);
QList<LinkInterface*> _connectedLinks; ///< List of all links connected to protocol
......@@ -295,9 +294,6 @@ private:
static const char* _tempLogFileTemplate; ///< Template for temporary log file
static const char* _logFileExtension; ///< Extension for log files
bool _protocolStatusMessageConnected; ///< true: protocolStatusMessage signal has been connected
bool _saveTempFlightDataLogConnected; ///< true: saveTempFlightDataLog signal has been connected
LinkManager* _linkMgr;
QTimer _heartbeatTimer; ///< Timer to emit heartbeats
......
......@@ -41,7 +41,6 @@ This file is part of the QGROUNDCONTROL project
#include "QGCFlightGearLink.h"
#include "QGC.h"
#include "MainWindow.h"
#include "QGCFileDialog.h"
#include "QGCMessageBox.h"
......@@ -70,7 +69,7 @@ QGCFlightGearLink::QGCFlightGearLink(UASInterface* mav, QString startupArguments
setRemoteHost(remoteHost);
// We need a mechanism so show error message from our FGLink thread on the UI thread. This signal connection will do that for us.
connect(this, SIGNAL(showCriticalMessageFromThread(const QString&, const QString&)), MainWindow::instance(), SLOT(showCriticalMessage(const QString&, const QString&)));
connect(this, &QGCFlightGearLink::showCriticalMessageFromThread, qgcApp(), &QGCApplication::criticalMessageBoxOnMainThread);
}
QGCFlightGearLink::~QGCFlightGearLink()
......@@ -553,7 +552,7 @@ bool QGCFlightGearLink::parseUIArguments(QString uiArgs, QStringList& argList)
// We have a space that is finishing an argument
previousSpace = true;
if (inQuotedString) {
MainWindow::instance()->showCriticalMessage(tr("FlightGear Failed to Start"), tr("Mismatched quotes in specified command line options"));
QGCMessageBox::critical(tr("FlightGear HIL"), tr("FlightGear failed to start. There are mismatched quotes in specified command line options"));
return false;
}
if (!currentArg.isEmpty()) {
......@@ -643,7 +642,7 @@ bool QGCFlightGearLink::connectSimulation()
QStringList uiArgList;
bool mismatchedQuotes = parseUIArguments(startupArguments, uiArgList);
if (!mismatchedQuotes) {
MainWindow::instance()->showCriticalMessage(tr("FlightGear settings"), tr("Mismatched quotes in specified command line options"));
QGCMessageBox::critical(tr("FlightGear HIL"), tr("FlightGear failed to start. There are mismatched quotes in specified command line options"));
return false;
}
#ifdef DEBUG_FLIGHTGEAR_CONNECT
......@@ -798,7 +797,7 @@ bool QGCFlightGearLink::connectSimulation()
} else if (fgRootPath.isEmpty()) {
errMsg = tr("Unable to automatically determine --fg-root directory location. You will need to specify --fg-root=<directory> as an additional command line parameter from ui.");
}
MainWindow::instance()->showCriticalMessage(tr("FlightGear settings"), errMsg);
QGCMessageBox::critical(tr("FlightGear HIL"), errMsg);
return false;
}
......@@ -826,7 +825,7 @@ bool QGCFlightGearLink::connectSimulation()
} else {
errMsg = tr("Unable to automatically determine --fg-scenery directory location. You will need to specify --fg-scenery=directory as an additional command line parameter from ui.");
}
MainWindow::instance()->showCriticalMessage(tr("FlightGear settings"), errMsg);
QGCMessageBox::critical(tr("FlightGear HIL"), errMsg);
return false;
}
#else
......@@ -836,7 +835,7 @@ bool QGCFlightGearLink::connectSimulation()
// Setup and verify directory which contains QGC provided aircraft files
QString qgcAircraftDir(QApplication::applicationDirPath() + "/files/flightgear/Aircraft");
if (!QFileInfo(qgcAircraftDir).isDir()) {
MainWindow::instance()->showCriticalMessage(tr("Incorrect QGroundControl installation"), tr("Aircraft directory is missing: '%1'.").arg(qgcAircraftDir));
QGCMessageBox::critical(tr("FlightGear HIL"), tr("Incorrect QGroundControl installation. Aircraft directory is missing: '%1'.").arg(qgcAircraftDir));
return false;
}
_fgArgList += "--fg-aircraft=" + qgcAircraftDir;
......@@ -850,14 +849,14 @@ bool QGCFlightGearLink::connectSimulation()
// Verify directory where FlightGear stores communicaton protocols.
QDir fgProtocolDir(fgRootPath);
if (!fgProtocolDir.cd("Protocol")) {
MainWindow::instance()->showCriticalMessage(tr("Incorrect FlightGear setup"), tr("Protocol directory is missing: '%1'. Command line parameter for --fg-root may be set incorrectly.").arg(fgProtocolDir.path()));
QGCMessageBox::critical(tr("FlightGear HIL"), tr("Incorrect FlightGear setup. Protocol directory is missing: '%1'. Command line parameter for --fg-root may be set incorrectly.").arg(fgProtocolDir.path()));
return false;
}
// Verify directory which contains QGC provided FlightGear communication protocol files
QDir qgcProtocolDir(QApplication::applicationDirPath() + "/files/flightgear/Protocol/");
if (!qgcProtocolDir.isReadable()) {
MainWindow::instance()->showCriticalMessage(tr("Incorrect QGroundControl installation"), tr("Protocol directory is missing (%1).").arg(qgcProtocolDir.path()));
QGCMessageBox::critical(tr("FlightGear HIL"), tr("Incorrect QGroundControl installation. Protocol directory is missing (%1).").arg(qgcProtocolDir.path()));
return false;
}
......@@ -865,7 +864,7 @@ bool QGCFlightGearLink::connectSimulation()
QString fgProtocolXmlFile = fgProtocol + ".xml";
QString qgcProtocolFileFullyQualified = qgcProtocolDir.absoluteFilePath(fgProtocolXmlFile);
if (!QFileInfo(qgcProtocolFileFullyQualified).exists()) {
MainWindow::instance()->showCriticalMessage(tr("Incorrect QGroundControl installation"), tr("FlightGear protocol file missing: %1").arg(qgcProtocolFileFullyQualified));
QGCMessageBox::critical(tr("FlightGear HIL"), tr("Incorrect QGroundControl installation. FlightGear protocol file missing: %1").arg(qgcProtocolFileFullyQualified));
return false;
}
......
......@@ -33,11 +33,13 @@ This file is part of the QGROUNDCONTROL project
#include <QList>
#include <QDebug>
#include <QMutexLocker>
#include <QHostInfo>
#include <iostream>
#include "QGCJSBSimLink.h"
#include "QGC.h"
#include <QHostInfo>
#include "MainWindow.h"
#include "QGCMessageBox.h"
QGCJSBSimLink::QGCJSBSimLink(UASInterface* mav, QString startupArguments, QString remoteHost, QHostAddress host, quint16 port) :
socket(NULL),
......@@ -122,14 +124,14 @@ void QGCJSBSimLink::run()
QFileInfo executable(processJSB);
if (!executable.isExecutable())
{
MainWindow::instance()->showCriticalMessage(tr("JSBSim Failed to Start"), tr("JSBSim was not found at %1").arg(processJSB));
QGCMessageBox::critical("JSBSim", tr("JSBSim failed to start. JSBSim was not found at %1").arg(processJSB));
sane = false;
}
QFileInfo root(rootJSB);
if (!root.isDir())
{
MainWindow::instance()->showCriticalMessage(tr("JSBSim Failed to Start"), tr("JSBSim data directory was not found at %1").arg(rootJSB));
QGCMessageBox::critical("JSBSim", tr("JSBSim failed to start. JSBSim data directory was not found at %1").arg(rootJSB));
sane = false;
}
......@@ -167,28 +169,33 @@ void QGCJSBSimLink::setPort(int port)
void QGCJSBSimLink::processError(QProcess::ProcessError err)
{
switch(err)
{
case QProcess::FailedToStart:
MainWindow::instance()->showCriticalMessage(tr("JSBSim Failed to Start"), tr("Please check if the path and command is correct"));
break;
case QProcess::Crashed:
MainWindow::instance()->showCriticalMessage(tr("JSBSim Crashed"), tr("This is a FlightGear-related problem. Please upgrade FlightGear"));
break;
case QProcess::Timedout:
MainWindow::instance()->showCriticalMessage(tr("JSBSim Start Timed Out"), tr("Please check if the path and command is correct"));
break;
case QProcess::WriteError:
MainWindow::instance()->showCriticalMessage(tr("Could not Communicate with JSBSim"), tr("Please check if the path and command is correct"));
break;
case QProcess::ReadError:
MainWindow::instance()->showCriticalMessage(tr("Could not Communicate with JSBSim"), tr("Please check if the path and command is correct"));
break;
case QProcess::UnknownError:
default:
MainWindow::instance()->showCriticalMessage(tr("JSBSim Error"), tr("Please check if the path and command is correct."));
break;
QString msg;
switch(err) {
case QProcess::FailedToStart:
msg = tr("JSBSim Failed to start. Please check if the path and command is correct");
break;
case QProcess::Crashed:
msg = tr("JSBSim crashed. This is a JSBSim-related problem, check for JSBSim upgrade.");
break;
case QProcess::Timedout:
msg = tr("JSBSim start timed out. Please check if the path and command is correct");
break;
case QProcess::ReadError:
case QProcess::WriteError:
msg = tr("Could not communicate with JSBSim. Please check if the path and command are correct");
break;
case QProcess::UnknownError:
default:
msg = tr("JSBSim error occurred. Please check if the path and command is correct.");
break;
}
QGCMessageBox::critical("JSBSim HIL", msg);
}
/**
......
......@@ -39,7 +39,7 @@ This file is part of the QGROUNDCONTROL project
#include <QHostInfo>
#include "UAS.h"
#include "UASInterface.h"
#include "MainWindow.h"
#include "QGCMessageBox.h"
QGCXPlaneLink::QGCXPlaneLink(UASInterface* mav, QString remoteHost, QHostAddress localHost, quint16 localPort) :
mav(mav),
......@@ -270,28 +270,34 @@ void QGCXPlaneLink::setPort(int localPort)
void QGCXPlaneLink::processError(QProcess::ProcessError err)
{
switch(err)
{
case QProcess::FailedToStart:
MainWindow::instance()->showCriticalMessage(tr("X-Plane Failed to Start"), tr("Please check if the path and command is correct"));
break;
case QProcess::Crashed:
MainWindow::instance()->showCriticalMessage(tr("X-Plane Crashed"), tr("This is a X-Plane-related problem. Please upgrade X-Plane"));
break;
case QProcess::Timedout:
MainWindow::instance()->showCriticalMessage(tr("X-Plane Start Timed Out"), tr("Please check if the path and command is correct"));
break;
case QProcess::WriteError:
MainWindow::instance()->showCriticalMessage(tr("Could not Communicate with X-Plane"), tr("Please check if the path and command is correct"));
break;
case QProcess::ReadError:
MainWindow::instance()->showCriticalMessage(tr("Could not Communicate with X-Plane"), tr("Please check if the path and command is correct"));
break;
case QProcess::UnknownError:
default:
MainWindow::instance()->showCriticalMessage(tr("X-Plane Error"), tr("Please check if the path and command is correct."));
break;
QString msg;
switch(err) {
case QProcess::FailedToStart:
msg = tr("X-Plane Failed to start. Please check if the path and command is correct");
break;
case QProcess::Crashed:
msg = tr("X-Plane crashed. This is an X-Plane-related problem, check for X-Plane upgrade.");
break;
case QProcess::Timedout:
msg = tr("X-Plane start timed out. Please check if the path and command is correct");
break;
case QProcess::ReadError:
case QProcess::WriteError:
msg = tr("Could not communicate with X-Plane. Please check if the path and command are correct");
break;
case QProcess::UnknownError:
default:
msg = tr("X-Plane error occurred. Please check if the path and command is correct.");
break;
}
QGCMessageBox::critical(tr("X-Plane HIL"), msg);
}
QString QGCXPlaneLink::getRemoteHost()
......
......@@ -208,7 +208,7 @@ void SerialLink::run()
if (m_port) {
err = m_port->errorString();
}
emit communicationError(getName(),"Error connecting: " + err);
_emitLinkError("Error connecting: " + err);
return;
}
......@@ -348,7 +348,7 @@ void SerialLink::writeBytes(const char* data, qint64 size)
m_writeMutex.unlock();
} else {
// Error occured
emit communicationError(getName(), tr("Could not send data - link %1 is disconnected!").arg(getName()));
_emitLinkError(tr("Could not send data - link %1 is disconnected!").arg(getName()));
}
}
......@@ -902,3 +902,10 @@ void SerialLink::_rerouteDisconnected(void)
{
emit disconnected();
}
void SerialLink::_emitLinkError(const QString& errorMsg)
{
QString msg("Error on link %1. %2");
emit communicationError(tr("Link Error"), msg.arg(getName()).arg(errorMsg));
}
\ No newline at end of file
......@@ -170,6 +170,8 @@ private:
// From LinkInterface
virtual bool _connect(void);
virtual bool _disconnect(void);
void _emitLinkError(const QString& errorMsg);
volatile bool m_stopp;
volatile bool m_reqReset;
......
......@@ -232,7 +232,7 @@ bool TCPLink::_hardwareConnect(void)
// Whether a failed connection emits an error signal or not is platform specific.
// So in cases where it is not emitted, we emit one ourselves.
if (errorSpy.count() == 0) {
emit communicationError(getName(), "Connection failed");
emit communicationError(tr("Link Error"), QString("Error on link %1. Connection failed").arg(getName()));
}
delete _socket;
_socket = NULL;
......@@ -248,7 +248,7 @@ bool TCPLink::_hardwareConnect(void)
void TCPLink::_socketError(QAbstractSocket::SocketError socketError)
{
Q_UNUSED(socketError);
emit communicationError(getName(), "Error on socket: " + _socket->errorString());
emit communicationError(tr("Link Error"), QString("Error on link %1. Error on socket: %2.").arg(getName()).arg(_socket->errorString()));
}
/**
......
......@@ -204,7 +204,7 @@ void XbeeLink::writeBytes(const char *bytes, qint64 length) // TO DO: delete th
else
{
_disconnect();
emit communicationError(this->getName(), tr("Could not send data - link %1 is disconnected!").arg(this->getName()));
emit communicationError(tr("Link Error"), QString("Error on link: %1. Could not send data - link is disconnected!").arg(getName()));
}
}
......
......@@ -30,6 +30,7 @@
#include "MainWindow.h"
#include "MockLink.h"
#include "QGCTemporaryFile.h"
#include "QGCApplication.h"
UT_REGISTER_TEST(MavlinkLogTest)
......@@ -82,20 +83,18 @@ void MavlinkLogTest::_bootLogDetectionCancel_test(void)
{
// Create a fake mavlink log
_createTempLogFile(false);
// We should get a message box, followed by a getSaveFileName dialog.
setExpectedMessageBox(QMessageBox::Ok);
setExpectedFileDialog(getSaveFileName, QStringList());
MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4);
Q_CHECK_PTR(mainWindow);
// Kick the protocol to check for lost log files and wait for signals to move through
connect(this, &MavlinkLogTest::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles);
emit checkForLostLogFiles();
QTest::qWait(1000);
checkExpectedMessageBox();
checkExpectedFileDialog();
mainWindow->close();
delete mainWindow;
}
void MavlinkLogTest::_bootLogDetectionSave_test(void)
......@@ -109,18 +108,16 @@ void MavlinkLogTest::_bootLogDetectionSave_test(void)
QString logSaveFile(logSaveDir.filePath(_saveLogFilename));
setExpectedFileDialog(getSaveFileName, QStringList(logSaveFile));
MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4);
Q_CHECK_PTR(mainWindow);
// Kick the protocol to check for lost log files and wait for signals to move through
connect(this, &MavlinkLogTest::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles);