diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 2ff9a34098773392751688586fc196619eb95ebf..281e00ef594944fd104423b5820f9cedb57e0766 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -138,31 +138,22 @@ static QObject* qgroundcontrolQmlGlobalSingletonFactory(QQmlEngine*, QJSEngine*) return qmlGlobal; } -/** - * @brief Constructor for the main application. - * - * This constructor initializes and starts the whole application. It takes standard - * command-line parameters - * - * @param argc The number of command-line parameters - * @param argv The string array of parameters - **/ - -QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) +QGCApplication::QGCApplication(int &argc, char* argv[], bool logOutput, bool unitTesting) #ifdef __mobile__ - : QGuiApplication(argc, argv) - , _qmlAppEngine(NULL) - #else - : QApplication(argc, argv) - #endif - , _runningUnitTests(unitTesting) - , _fakeMobile(false) - , _settingsUpgraded(false) - #ifdef QT_DEBUG - , _testHighDPI(false) - #endif - , _toolbox(NULL) - , _bluetoothAvailable(false) + : QGuiApplication (argc, argv) + , _qmlAppEngine (NULL) +#else + : QApplication (argc, argv) +#endif + , _runningUnitTests (unitTesting) + , _logOutput (logOutput) + , _fakeMobile (false) + , _settingsUpgraded (false) +#ifdef QT_DEBUG + , _testHighDPI (false) +#endif + , _toolbox (NULL) + , _bluetoothAvailable (false) { _app = this; diff --git a/src/QGCApplication.h b/src/QGCApplication.h index f2459a6acd1b6ab034230a680937dc80b8117b8f..1a41300c9277e68a253b52b3678b426041faeea1 100644 --- a/src/QGCApplication.h +++ b/src/QGCApplication.h @@ -60,7 +60,7 @@ class QGCApplication : public Q_OBJECT public: - QGCApplication(int &argc, char* argv[], bool unitTesting); + QGCApplication(int &argc, char* argv[], bool logOutput, bool unitTesting); ~QGCApplication(); /// @brief Sets the persistent flag to delete all settings the next time QGroundControl is started. @@ -69,9 +69,12 @@ public: /// @brief Clears the persistent flag to delete all settings the next time QGroundControl is started. void clearDeleteAllSettingsNextBoot(void); - /// @brief Returns truee if unit test are being run + /// @brief Returns true if unit tests are being run bool runningUnitTests(void) { return _runningUnitTests; } + /// @brief Returns true if Qt debug output should be logged to a file + bool logOutput(void) { return _logOutput; } + /// Used to report a missing Parameter. Warning will be displayed to user. Method may be called /// multiple times. void reportMissingParameter(int componentId, const QString& name); @@ -158,6 +161,7 @@ private: #endif bool _runningUnitTests; ///< true: running unit tests, false: normal app + bool _logOutput; ///< true: Log Qt debug output to file static const char* _darkStyleFile; static const char* _lightStyleFile; diff --git a/src/QmlControls/AppMessages.cc b/src/QmlControls/AppMessages.cc index fa88b30472a456314575b57e19e3290a7fd638a5..9931e593fe73cf06564109b1999f83f913f88391 100644 --- a/src/QmlControls/AppMessages.cc +++ b/src/QmlControls/AppMessages.cc @@ -11,8 +11,12 @@ // Allows QGlobalStatic to work on this translation unit #define _LOG_CTOR_ACCESS_ public + #include "AppMessages.h" -#include +#include "QGCApplication.h" +#include "SettingsManager.h" +#include "AppSettings.h" + #include #include #include @@ -87,4 +91,26 @@ void AppLogModel::threadsafeLog(const QString message) const int line = rowCount(); insertRows(line, 1); setData(index(line), message, Qt::DisplayRole); + + if (qgcApp()->logOutput()) { + if (_logFile.fileName().isEmpty()) { + QGCToolbox* toolbox = qgcApp()->toolbox(); + // Be careful of toolbox not being open yet + if (toolbox) { + QString saveDirPath = qgcApp()->toolbox()->settingsManager()->appSettings()->crashSavePath(); + QDir saveDir(saveDirPath); + QString saveFilePath = saveDir.absoluteFilePath(QStringLiteral("QGCConsole.log")); + + _logFile.setFileName(saveFilePath); + if (!_logFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + qgcApp()->showMessage(tr("Open console log output file failed %1 : %2").arg(_logFile.fileName()).arg(_logFile.errorString())); + } + } + } + + if (_logFile.isOpen()) { + QTextStream out(&_logFile); + out << message << "\n"; + } + } } diff --git a/src/QmlControls/AppMessages.h b/src/QmlControls/AppMessages.h index ff8c44ec45a00ee4a44eb46b56a79e2d9d40ae10..335b487e49331f419eb47c7447733ebb6d757eea 100644 --- a/src/QmlControls/AppMessages.h +++ b/src/QmlControls/AppMessages.h @@ -13,6 +13,7 @@ #include #include #include +#include // Hackish way to force only this translation unit to have public ctor access #ifndef _LOG_CTOR_ACCESS_ @@ -34,6 +35,9 @@ signals: private slots: void threadsafeLog(const QString message); +private: + QFile _logFile; + _LOG_CTOR_ACCESS_: AppLogModel(); }; diff --git a/src/main.cc b/src/main.cc index 8c2ff2ddc39e6e92d4ab06a6bdae70a87096af9d..02b8abd7e2f94385cac0128695d48a85f24d00aa 100644 --- a/src/main.cc +++ b/src/main.cc @@ -176,12 +176,14 @@ int main(int argc, char *argv[]) bool stressUnitTests = false; // Stress test unit tests bool quietWindowsAsserts = false; // Don't let asserts pop dialog boxes + bool logOutput = false; // true: Log Qt debug output to file QString unitTestOptions; CmdLineOpt_t rgCmdLineOptions[] = { { "--unittest", &runUnitTests, &unitTestOptions }, { "--unittest-stress", &stressUnitTests, &unitTestOptions }, { "--no-windows-assert-ui", &quietWindowsAsserts, NULL }, + { "--log-output", &logOutput, NULL }, // Add additional command line option flags here }; @@ -206,7 +208,7 @@ int main(int argc, char *argv[]) #endif #endif // QT_DEBUG - QGCApplication* app = new QGCApplication(argc, argv, runUnitTests); + QGCApplication* app = new QGCApplication(argc, argv, logOutput, runUnitTests); Q_CHECK_PTR(app); #ifdef Q_OS_LINUX