diff --git a/src/LogCompressor.cc b/src/LogCompressor.cc index faa55eccbbb6f20ce9e8cb9d24bd27b64b40e29b..97b121146c7ef61bd6cf8e58da5a3132c1969300 100644 --- a/src/LogCompressor.cc +++ b/src/LogCompressor.cc @@ -27,6 +27,9 @@ This file is part of the QGROUNDCONTROL project * */ +#include "LogCompressor.h" +#include "QGCApplication.h" + #include #include #include @@ -34,8 +37,6 @@ This file is part of the QGROUNDCONTROL project #include #include #include -#include "LogCompressor.h" - #include /** @@ -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); +} diff --git a/src/LogCompressor.h b/src/LogCompressor.h index 138c5a59c6698b947d5541a00b3eb36a873af102..41e676578e4c4af042de32164fa5c292b621630d 100644 --- a/src/LogCompressor.h +++ b/src/LogCompressor.h @@ -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 diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index f3f94515ad7afa47e6c862eee53cac8e47d4c458..4c3b190d7c29b2e6896406c0e6d804257049b3fb 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -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); +} diff --git a/src/QGCApplication.h b/src/QGCApplication.h index 2300f4fa96bf3241158063d7313a1d6981c6815a..339204d288ff56c92880d9ecfe7251a33cba6125 100644 --- a/src/QGCApplication.h +++ b/src/QGCApplication.h @@ -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); diff --git a/src/QGCFileDialog.cc b/src/QGCFileDialog.cc index 8c5df23bb90806b8163ee7b68c2454a9d233e637..b78a441450ba16f8b076640f3df693a315d455a5 100644 --- a/src/QGCFileDialog.cc +++ b/src/QGCFileDialog.cc @@ -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); diff --git a/src/QGCMessageBox.h b/src/QGCMessageBox.h index aef15f3d53844ef940fb6a2d40b4d57721330cdf..3116264bea0623b4053016f376d144016acf5765 100644 --- a/src/QGCMessageBox.h +++ b/src/QGCMessageBox.h @@ -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 diff --git a/src/comm/LinkInterface.h b/src/comm/LinkInterface.h index c69746ede8ba84b144a718e53e4c2d4dfc35f165..5085aeeccbed8c8bb1b2e2ae2cd7671c90b090a4 100644 --- a/src/comm/LinkInterface.h +++ b/src/comm/LinkInterface.h @@ -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); diff --git a/src/comm/LinkManager.cc b/src/comm/LinkManager.cc index 4c680035e2349689022f3c76d082cbcb5f587e3e..df963331a16a07730f42ef45b27f78cb6398a1ef 100644 --- a/src/comm/LinkManager.cc +++ b/src/comm/LinkManager.cc @@ -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(); diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index e7910a5c36d470d58aa2edc49881497230659445..5922b558560f1ecdfa6bca388cdd56ff8eb33eee 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -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)); diff --git a/src/comm/MAVLinkProtocol.h b/src/comm/MAVLinkProtocol.h index 1ccb3f08b6a2aca97c5795417a1893f71af7afe2..efdd4e4a553905dc6f6b04c62445c29881aaf14f 100644 --- a/src/comm/MAVLinkProtocol.h +++ b/src/comm/MAVLinkProtocol.h @@ -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 _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 diff --git a/src/comm/QGCFlightGearLink.cc b/src/comm/QGCFlightGearLink.cc index f767e1f06844939891668a00b195166e12d91128..d42ccdce7f032a53ba6126a98e7842ee2633e539 100644 --- a/src/comm/QGCFlightGearLink.cc +++ b/src/comm/QGCFlightGearLink.cc @@ -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" @@ -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= as an additional command line parameter from ui."); } - MainWindow::instance()->showCriticalMessage(tr("FlightGear settings"), errMsg); + QGCMessageBox::critical(tr("FlightGear HIL"), errMsg); return false; } @@ -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; } diff --git a/src/comm/QGCJSBSimLink.cc b/src/comm/QGCJSBSimLink.cc index 56f03d71244b2f2341f4cbf330ca43124088db59..9d2c60b196b8806f87d398a7de40fc6f122f0d62 100644 --- a/src/comm/QGCJSBSimLink.cc +++ b/src/comm/QGCJSBSimLink.cc @@ -33,11 +33,13 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include + #include + #include "QGCJSBSimLink.h" #include "QGC.h" -#include -#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); } /** diff --git a/src/comm/QGCXPlaneLink.cc b/src/comm/QGCXPlaneLink.cc index c055088a0f989fe8beca74ef20e9cf929ba51e32..42b7ad1d41fad120153567c2478c545e00bd9346 100644 --- a/src/comm/QGCXPlaneLink.cc +++ b/src/comm/QGCXPlaneLink.cc @@ -39,7 +39,7 @@ This file is part of the QGROUNDCONTROL project #include #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() diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index d24a3adfb39a86032ef4d30bf1b568925f94b8a5..e2b95f6e40db69cf7bcac1ba069cc7e70b7870f3 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -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 diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index df32f1d83e46bbf2440216bca03330c2bc6660fa..5e9911fdcce61cbe33cff0d3c54ef7d7f95fdbff 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -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; diff --git a/src/comm/TCPLink.cc b/src/comm/TCPLink.cc index f4af6d52d0975f8582a01b8ac8fb3f42f517af9a..80872dd53205b512cfc725e376f0c3fd3736b3df 100644 --- a/src/comm/TCPLink.cc +++ b/src/comm/TCPLink.cc @@ -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())); } /** diff --git a/src/comm/XbeeLink.cpp b/src/comm/XbeeLink.cpp index c83ae8bd16dfbafcb0275e87324f8046c3cacdb2..a190678e1314267946bf810dc746b49f2d54ec9b 100644 --- a/src/comm/XbeeLink.cpp +++ b/src/comm/XbeeLink.cpp @@ -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())); } } diff --git a/src/qgcunittest/MavlinkLogTest.cc b/src/qgcunittest/MavlinkLogTest.cc index eed634fc56cf6a91419fb7e097c7a91e745f8170..a870b3b9dabde2ccec80e9a2ad36ac29a6175056 100644 --- a/src/qgcunittest/MavlinkLogTest.cc +++ b/src/qgcunittest/MavlinkLogTest.cc @@ -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); + emit checkForLostLogFiles(); + QTest::qWait(1000); checkExpectedMessageBox(); checkExpectedFileDialog(); // Make sure the file is there and delete it QCOMPARE(logSaveDir.remove(_saveLogFilename), true); - - mainWindow->close(); - - delete mainWindow; } void MavlinkLogTest::_bootLogDetectionZeroLength_test(void) @@ -128,20 +125,16 @@ void MavlinkLogTest::_bootLogDetectionZeroLength_test(void) // Create a fake empty mavlink log _createTempLogFile(true); - // Zero length log files should not generate any additional UI pop-ups. It should just be deleted silently. - MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4); - Q_CHECK_PTR(mainWindow); - - mainWindow->close(); + // 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); - delete mainWindow; + // Zero length log files should not generate any additional UI pop-ups. It should just be deleted silently. } void MavlinkLogTest::_connectLog_test(void) { - MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4); - Q_CHECK_PTR(mainWindow); - LinkManager* linkMgr = LinkManager::instance(); Q_CHECK_PTR(linkMgr); @@ -163,10 +156,6 @@ void MavlinkLogTest::_connectLog_test(void) // Make sure the file is there and delete it QCOMPARE(logSaveDir.remove(_saveLogFilename), true); - - // MainWindow deletes itself on close - mainWindow->close(); - QTest::qWait(1000); // Need to allow signals to move between threads to shutdown MainWindow } void MavlinkLogTest::_deleteTempLogFiles_test(void) diff --git a/src/qgcunittest/MavlinkLogTest.h b/src/qgcunittest/MavlinkLogTest.h index 320c7ba324ff4bf9cad46458a794601cbffb3e59..a97d10b709ff81c2ba19d28782b19b7ab99ecec5 100644 --- a/src/qgcunittest/MavlinkLogTest.h +++ b/src/qgcunittest/MavlinkLogTest.h @@ -48,6 +48,9 @@ private slots: void _connectLog_test(void); void _deleteTempLogFiles_test(void); +signals: + void checkForLostLogFiles(void); + private: void _createTempLogFile(bool zeroLength); diff --git a/src/uas/UASWaypointManager.cc b/src/uas/UASWaypointManager.cc index dffa8b0840ba718cfdde5d6931806e3d6ba9e3d2..f3699489fadc15a7f8baadca3d406312c38fdd27 100644 --- a/src/uas/UASWaypointManager.cc +++ b/src/uas/UASWaypointManager.cc @@ -33,7 +33,7 @@ This file is part of the QGROUNDCONTROL project #include "UAS.h" #include "mavlink_types.h" #include "UASManager.h" -#include "MainWindow.h" +#include "QGCMessageBox.h" #define PROTOCOL_TIMEOUT_MS 2000 ///< maximum time to wait for pending messages until timeout #define PROTOCOL_DELAY_MS 20 ///< minimum delay between sent messages @@ -50,8 +50,6 @@ UASWaypointManager::UASWaypointManager(UAS* _uas) currentWaypointEditable(), protocol_timer(this) { - - _offlineEditingModeTitle = tr("OFFLINE Waypoint Editing Mode"); _offlineEditingModeMessage = tr("You are in offline editing mode. Make sure to save your mission to a file before connecting to a system - you will need to load the file into the system, the offline list will be cleared on connect."); if (uas) @@ -433,8 +431,9 @@ void UASWaypointManager::addWaypointEditable(Waypoint *wp, bool enforceFirstActi if (wp) { // Check if this is the first waypoint in an offline list - if (waypointsEditable.count() == 0 && uas == NULL) - MainWindow::instance()->showCriticalMessage(_offlineEditingModeTitle, _offlineEditingModeMessage); + if (waypointsEditable.count() == 0 && uas == NULL) { + QGCMessageBox::critical(tr("Waypoint Manager"), _offlineEditingModeMessage); + } wp->setId(waypointsEditable.count()); if (enforceFirstActive && waypointsEditable.count() == 0) @@ -456,8 +455,9 @@ void UASWaypointManager::addWaypointEditable(Waypoint *wp, bool enforceFirstActi Waypoint* UASWaypointManager::createWaypoint(bool enforceFirstActive) { // Check if this is the first waypoint in an offline list - if (waypointsEditable.count() == 0 && uas == NULL) - MainWindow::instance()->showCriticalMessage(_offlineEditingModeTitle, _offlineEditingModeMessage); + if (waypointsEditable.count() == 0 && uas == NULL) { + QGCMessageBox::critical(tr("Waypoint Manager"), _offlineEditingModeMessage); + } Waypoint* wp = new Waypoint(); wp->setId(waypointsEditable.count()); diff --git a/src/uas/UASWaypointManager.h b/src/uas/UASWaypointManager.h index b6179596f2d381cd2009cd0aeb80f2dbce6450f3..39abc59fee2744a723593773c749faa6ad0968f1 100644 --- a/src/uas/UASWaypointManager.h +++ b/src/uas/UASWaypointManager.h @@ -190,7 +190,6 @@ private: // XXX export to settings static const float defaultAltitudeHomeOffset; ///< Altitude offset in meters from home for new waypoints - QString _offlineEditingModeTitle; QString _offlineEditingModeMessage; }; diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 114d6a13b85b41439d67c260ee403333db6ebc6e..05b333f900c726cf4f00806aa054e45076309162 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -128,10 +128,7 @@ MainWindow::MainWindow(QSplashScreen* splashScreen, enum MainWindow::CUSTOM_MODE } connect(menuActionHelper, SIGNAL(needToShowDockWidget(QString,bool)),SLOT(showDockWidget(QString,bool))); - - connect(MAVLinkProtocol::instance(), SIGNAL(protocolStatusMessage(const QString&, const QString&)), this, SLOT(showCriticalMessage(const QString&, const QString&))); - connect(MAVLinkProtocol::instance(), SIGNAL(saveTempFlightDataLog(QString)), this, SLOT(_saveTempFlightDataLog(QString))); - + loadSettings(); emit initStatusChanged(tr("Loading style"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141)); @@ -931,7 +928,6 @@ void MainWindow::loadCustomWidgetsFromDefaults(const QString& systemType, const { qDebug() << "No default custom widgets for system " << systemType << "autopilot" << autopilotType << " found"; qDebug() << "Tried with path: " << defaultsDir; - showStatusMessage(tr("Did not find any custom widgets in %1").arg(defaultsDir)); } // Load all custom widgets found in the AP folder @@ -943,7 +939,6 @@ void MainWindow::loadCustomWidgetsFromDefaults(const QString& systemType, const // Will only be loaded if not already a custom widget with // the same name is present loadCustomWidget(defaultsDir+"/"+file, true); - showStatusMessage(tr("Loaded custom widget %1").arg(defaultsDir+"/"+file)); } } } @@ -1105,40 +1100,6 @@ bool MainWindow::loadStyle(QGC_MAINWINDOW_STYLE style) return success; } -/** - * The status message will be overwritten if a new message is posted to this function - * - * @param status message text - * @param timeout how long the status should be displayed - */ -void MainWindow::showStatusMessage(const QString& status, int timeout) -{ - statusBar()->showMessage(status, timeout); -} - -/** - * The status message will be overwritten if a new message is posted to this function. - * it will be automatically hidden after 5 seconds. - * - * @param status message text - */ -void MainWindow::showStatusMessage(const QString& status) -{ - statusBar()->showMessage(status, 20000); -} - -void MainWindow::showCriticalMessage(const QString& title, const QString& message) -{ - qDebug() << "Critical" << title << message; - QGCMessageBox::critical(title, message); -} - -void MainWindow::showInfoMessage(const QString& title, const QString& message) -{ - qDebug() << "Information" << title << message; - QGCMessageBox::information(title, message); -} - /** * @brief Create all actions associated to the main window * @@ -1741,19 +1702,6 @@ bool MainWindow::dockWidgetTitleBarsEnabled() const return menuActionHelper->dockWidgetTitleBarsEnabled(); } -/// @brief Save the specified Flight Data Log -void MainWindow::_saveTempFlightDataLog(QString tempLogfile) -{ - QString saveFilename = QGCFileDialog::getSaveFileName(this, - 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); -} - /// @brief Hides the spash screen if it is currently being shown void MainWindow::hideSplashScreen(void) { diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 6e2bc9e2e27c325887c521cbf78253baa6f15719..bd61c365ff8079b4afb01c08d7c1aa63a3d051c2 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -161,15 +161,6 @@ public: void hideSplashScreen(void); public slots: - /** @brief Shows a status message on the bottom status bar */ - void showStatusMessage(const QString& status, int timeout); - /** @brief Shows a status message on the bottom status bar */ - void showStatusMessage(const QString& status); - /** @brief Shows a critical message as popup or as widget */ - void showCriticalMessage(const QString& title, const QString& message); - /** @brief Shows an info message as popup or as widget */ - void showInfoMessage(const QString& title, const QString& message); - /** @brief Show the application settings */ void showSettings(); /** @brief Add a communication link */ @@ -452,7 +443,6 @@ protected: CUSTOM_MODE customMode; private slots: - void _saveTempFlightDataLog(QString tempLogfile); void _addLinkMenu(LinkInterface* link); private: diff --git a/src/ui/QGCDataPlot2D.cc b/src/ui/QGCDataPlot2D.cc index 851142022080be8bd0a367eef5243bf20bf37ebf..f17f384ecdbe92880fc0fe14ed8c68d012cf4b33 100644 --- a/src/ui/QGCDataPlot2D.cc +++ b/src/ui/QGCDataPlot2D.cc @@ -42,7 +42,6 @@ This file is part of the QGROUNDCONTROL project #include "QGCDataPlot2D.h" #include "ui_QGCDataPlot2D.h" #include "MG.h" -#include "MainWindow.h" #include "QGCFileDialog.h" #include "QGCMessageBox.h" @@ -304,7 +303,6 @@ void QGCDataPlot2D::loadRawLog(QString file, QString xAxisName, QString yAxisFil // Postprocess log file logFile = new QTemporaryFile("qt_qgc_temp_log.XXXXXX.csv"); compressor = new LogCompressor(file, logFile->fileName()); - connect(compressor, SIGNAL(logProcessingStatusChanged(QString)), MainWindow::instance(), SLOT(showStatusMessage(QString))); connect(compressor, SIGNAL(finishedFile(QString)), this, SLOT(loadFile(QString))); compressor->startCompression(); } diff --git a/src/ui/QGCMAVLinkLogPlayer.cc b/src/ui/QGCMAVLinkLogPlayer.cc index 9e4c145ca1406a03411453a55fab198cb185b4e6..f26ee69507f1598a66694295b45083c77fbc7fb7 100644 --- a/src/ui/QGCMAVLinkLogPlayer.cc +++ b/src/ui/QGCMAVLinkLogPlayer.cc @@ -9,6 +9,7 @@ #include "QGCApplication.h" #include "LinkManager.h" #include "QGCFileDialog.h" +#include "QGCMessageBox.h" QGCMAVLinkLogPlayer::QGCMAVLinkLogPlayer(MAVLinkProtocol* mavlink, QWidget *parent) : QWidget(parent), @@ -257,7 +258,7 @@ void QGCMAVLinkLogPlayer::_selectLogFileForPlayback(void) } if (foundConnection) { - MainWindow::instance()->showInfoMessage(tr("Log Replay"), tr("You must close all connections prior to replaying a log.")); + QGCMessageBox::information(tr("Log Replay"), tr("You must close all connections prior to replaying a log.")); return; } @@ -313,7 +314,7 @@ bool QGCMAVLinkLogPlayer::loadLogFile(const QString& file) // Now load the new file. logFile.setFileName(file); if (!logFile.open(QFile::ReadOnly)) { - MainWindow::instance()->showCriticalMessage(tr("The selected file is unreadable"), tr("Please make sure that the file %1 is readable or select a different file").arg(file)); + QGCMessageBox::critical(tr("Log Replay"), tr("The selected file is unreadable. Please make sure that the file %1 is readable or select a different file").arg(file)); _playbackError(); return false; } @@ -354,7 +355,7 @@ bool QGCMAVLinkLogPlayer::loadLogFile(const QString& file) } if (endtime == starttime) { - MainWindow::instance()->showCriticalMessage(tr("The selected file is corrupt"), tr("No valid timestamps were found at the end of the file.").arg(file)); + QGCMessageBox::critical(tr("Log Replay"), tr("The selected file is corrupt. No valid timestamps were found at the end of the file.").arg(file)); _playbackError(); return false; } @@ -631,7 +632,6 @@ void QGCMAVLinkLogPlayer::_finishPlayback(void) QString status = tr("Flight Data replay complete"); ui->logStatsLabel->setText(status); - MainWindow::instance()->showStatusMessage(status); // Note that we explicitly set the slider to 100%, as it may not hit that by itself depending on log file size. updatePositionSliderUi(100.0f); diff --git a/src/ui/linechart/LinechartWidget.cc b/src/ui/linechart/LinechartWidget.cc index ba7080f351b0775180c1c8c092aa10a6ac164767..82335f0173cb184d8a118697c2566170e3f6e430 100644 --- a/src/ui/linechart/LinechartWidget.cc +++ b/src/ui/linechart/LinechartWidget.cc @@ -48,7 +48,6 @@ This file is part of the PIXHAWK project #include "LinechartWidget.h" #include "LinechartPlot.h" #include "LogCompressor.h" -#include "MainWindow.h" #include "QGC.h" #include "MG.h" #include "QGCFileDialog.h" @@ -488,7 +487,6 @@ void LinechartWidget::stopLogging() // Postprocess log file compressor = new LogCompressor(logFile->fileName(), logFile->fileName()); connect(compressor, SIGNAL(finishedFile(QString)), this, SIGNAL(logfileWritten(QString))); - connect(compressor, SIGNAL(logProcessingStatusChanged(QString)), MainWindow::instance(), SLOT(showStatusMessage(QString))); QMessageBox::StandardButton button = QGCMessageBox::question(tr("Starting Log Compression"), tr("Should empty fields (e.g. due to packet drops) be filled with the previous value of the same variable (zero order hold)?"),