diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro
index 9dd7fb8dca561eb9321b18190f7f3d392b4b4d11..f61044ca6ddf76c166633b77f3b4882737a94fdd 100644
--- a/qgroundcontrol.pro
+++ b/qgroundcontrol.pro
@@ -94,7 +94,10 @@ QT += \
# testlib is needed even in release flavor for QSignalSpy support
QT += testlib
-
+ReleaseBuild {
+ # We don't need the testlib console in release mode
+ QT.testlib.CONFIG -= console
+}
#
# OS Specific settings
#
@@ -295,6 +298,7 @@ HEADERS += \
src/QmlControls/QGCImageProvider.h \
src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.h \
src/QtLocationPlugin/QMLControl/QGCMapEngineManager.h \
+ src/ViewWidgets/AppMessagesDialog.h
DebugBuild {
HEADERS += \
@@ -434,6 +438,7 @@ SOURCES += \
src/QmlControls/QGCImageProvider.cc \
src/AutoPilotPlugins/APM/APMRemoteParamsDownloader.cc \
src/QtLocationPlugin/QMLControl/QGCMapEngineManager.cc \
+ src/ViewWidgets/AppMessagesDialog.cc
DebugBuild {
SOURCES += \
diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index a87759717d864aa53495ac29c8dd88c19add6fb6..1e00af6bb08e47504e72b738fda2c0647041c274 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -12,6 +12,7 @@
src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml
src/ViewWidgets/CustomCommandWidget.qml
src/ViewWidgets/LogDownload.qml
+ src/ViewWidgets/AppMessagesDialog.qml
src/VehicleSetup/FirmwareUpgrade.qml
src/FlightDisplay/FlightDisplayView.qml
src/AutoPilotPlugins/PX4/PX4FlightModes.qml
diff --git a/src/QGCDockWidget.cc b/src/QGCDockWidget.cc
index 2d21ed74b6a2563ed6dc2ce6492cdd6fdfdbdd1c..cc368b9af38a7507f694639f8fefc896f6619731 100644
--- a/src/QGCDockWidget.cc
+++ b/src/QGCDockWidget.cc
@@ -47,6 +47,8 @@ void QGCDockWidget::closeEvent(QCloseEvent* event)
saveSettings();
event->ignore();
_action->trigger();
+ } else {
+ QWidget::closeEvent(event);
}
}
diff --git a/src/QGCDockWidget.h b/src/QGCDockWidget.h
index 5452d19973bcba2ac67c0147469a21fd819a20f1..e8fde455888c328bd7c708a8e6e9bb01ce9d4c67 100644
--- a/src/QGCDockWidget.h
+++ b/src/QGCDockWidget.h
@@ -41,7 +41,7 @@ public:
protected:
QString _title;
- QAction* _action;
+ QPointer _action;
static const char* _settingsGroup;
};
diff --git a/src/ViewWidgets/AppMessagesDialog.qml b/src/ViewWidgets/AppMessagesDialog.qml
new file mode 100644
index 0000000000000000000000000000000000000000..22c7175c4eef23d77d3a99d39289cf7bde337d08
--- /dev/null
+++ b/src/ViewWidgets/AppMessagesDialog.qml
@@ -0,0 +1,112 @@
+/*=====================================================================
+
+QGroundControl Open Source Ground Control Station
+
+(c) 2009, 2016 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 .
+
+======================================================================*/
+
+import QtQuick 2.5
+import QtQuick.Controls 1.2
+import QtQuick.Controls.Styles 1.2
+import QtQuick.Dialogs 1.2
+
+import QGroundControl.Palette 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.Controllers 1.0
+import QGroundControl.ScreenTools 1.0
+
+QGCView {
+ viewPanel: panel
+ id: logwindow
+ property bool loaded: false
+
+ QGCPalette { id: qgcPal }
+
+
+ Connections {
+ target: debugMessageModel
+
+ onDataChanged: {
+ // Keep the view in sync if the button is checked
+ if (loaded) {
+ if (followTail.checked) {
+ listview.positionViewAtEnd();
+ }
+ }
+ }
+ }
+
+ Component {
+ id: delegateItem
+ Rectangle {
+ color: index % 2 == 0 ? qgcPal.window : qgcPal.windowShade
+ height: Math.round(ScreenTools.defaultFontPixelHeight * 0.5 + field.height)
+ width: listview.width
+
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ id: field
+ text: display
+ color: qgcPal.text
+ width: parent.width
+ wrapMode: Text.Wrap
+ }
+ }
+ }
+
+ QGCViewPanel {
+ id: panel
+ anchors.fill: parent
+
+ Rectangle {
+ anchors.fill: parent
+ color: qgcPal.window
+ }
+
+ ListView {
+ Component.onCompleted: {
+ loaded = true
+ }
+ anchors.margins: ScreenTools.defaultFontPixelHeight
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: followTail.top
+ id: listview
+ model: debugMessageModel
+ delegate: delegateItem
+ }
+
+ Button {
+ id: followTail
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.margins: ScreenTools.defaultFontPixelWidth
+ text: "Show Latest"
+ checkable: true
+ checked: true
+
+ onCheckedChanged: {
+ if (checked && loaded) {
+ listview.positionViewAtEnd();
+ }
+ }
+ }
+ }
+}
diff --git a/src/ViewWidgets/appmessagesdialog.cc b/src/ViewWidgets/appmessagesdialog.cc
new file mode 100644
index 0000000000000000000000000000000000000000..4b908fd51b7d00b790bcf42c67e747d419c955f6
--- /dev/null
+++ b/src/ViewWidgets/appmessagesdialog.cc
@@ -0,0 +1,63 @@
+/*=====================================================================
+
+QGroundControl Open Source Ground Control Station
+
+(c) 2009, 2016 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 .
+
+======================================================================*/
+
+#include "AppMessagesDialog.h"
+#include
+#include
+
+static QtMessageHandler old_handler;
+static QStringListModel debug_strings;
+
+static void msgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ const char symbols[] = { 'D', 'E', '!', 'X', 'I' };
+ QString output = QString("[%1] at %2:%3 - \"%4\"").arg(symbols[type]).arg(context.file).arg(context.line).arg(msg);
+
+ // Avoid recursion
+ if (!QString(context.category).startsWith("qt.quick")) {
+ const int line = debug_strings.rowCount();
+ debug_strings.insertRows(line, 1);
+ debug_strings.setData(debug_strings.index(line), output, Qt::DisplayRole);
+ }
+
+ if (old_handler != nullptr) {
+ old_handler(type, context, msg);
+ }
+ if( type == QtFatalMsg ) abort();
+}
+
+
+AppMessagesDialog::AppMessagesDialog(const QString &title, QAction *action, QWidget *parent) :
+ QGCQmlWidgetHolder(title, action, parent)
+{
+ resize(800, 600);
+ setContextPropertyObject("debugMessageModel", &debug_strings);
+ setSource(QUrl::fromUserInput("qrc:/qml/AppMessagesDialog.qml"));
+ loadSettings();
+}
+
+void AppMessagesDialog::installHandler()
+{
+ old_handler = qInstallMessageHandler(msgHandler);
+}
+
diff --git a/src/ViewWidgets/appmessagesdialog.h b/src/ViewWidgets/appmessagesdialog.h
new file mode 100644
index 0000000000000000000000000000000000000000..e43b9f130683b6ea5a98b961d249fcb2a367f3b6
--- /dev/null
+++ b/src/ViewWidgets/appmessagesdialog.h
@@ -0,0 +1,37 @@
+/*=====================================================================
+
+QGroundControl Open Source Ground Control Station
+
+(c) 2009, 2016 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 .
+
+======================================================================*/
+
+#pragma once
+
+#include "QGCQmlWidgetHolder.h"
+
+class QStringListModel;
+
+class AppMessagesDialog : public QGCQmlWidgetHolder
+{
+ Q_OBJECT
+public:
+ AppMessagesDialog(const QString& title, QAction* action, QWidget *parent = 0);
+
+ static void installHandler();
+};
diff --git a/src/main.cc b/src/main.cc
index c6276a586ae97df248acf96ba75278ec25166fda..7ccdab5361f9f12b47a046b07c8e8fcb81af7de5 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -35,7 +35,8 @@ This file is part of the QGROUNDCONTROL project
#include
#include
#include
-
+#include
+#include "AppMessagesDialog.h"
#include "QGCApplication.h"
#define SINGLE_INSTANCE_PORT 14499
@@ -71,17 +72,6 @@ This file is part of the QGROUNDCONTROL project
#endif
#ifdef Q_OS_WIN
-
-/// @brief Message handler which is installed using qInstallMsgHandler so you do not need
-/// the MSFT debug tools installed to see qDebug(), qWarning(), qCritical and qAbort
-void msgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
-{
- const char symbols[] = { 'I', 'E', '!', 'X' };
- QString output = QString("[%1] at %2:%3 - \"%4\"").arg(symbols[type]).arg(context.file).arg(context.line).arg(msg);
- std::cerr << output.toStdString() << std::endl;
- if( type == QtFatalMsg ) abort();
-}
-
/// @brief CRT Report Hook installed using _CrtSetReportHook. We install this hook when
/// we don't want asserts to pop a dialog on windows.
int WindowsCrtReportHook(int reportType, char* message, int* returnValue)
@@ -143,10 +133,9 @@ int main(int argc, char *argv[])
#endif
#endif
-#ifdef Q_OS_WIN
// install the message handler
- qInstallMessageHandler(msgHandler);
-
+ AppMessagesDialog::installHandler();
+#ifdef Q_OS_WIN
// Set our own OpenGL buglist
qputenv("QT_OPENGL_BUGLIST", ":/opengl/resources/opengl/buglist.json");
diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc
index fe17f8ef00390814d36495f5e63ff0827ae69972..e6f42e6fffec0fb288a000a53aa814fad8c87305 100644
--- a/src/ui/MainWindow.cc
+++ b/src/ui/MainWindow.cc
@@ -66,6 +66,7 @@ This file is part of the QGROUNDCONTROL project
#include "UASInfoWidget.h"
#include "HILDockWidget.h"
#include "LogDownload.h"
+#include "AppMessagesDialog.h"
#endif
#ifndef __ios__
@@ -88,7 +89,8 @@ enum DockWidgetTypes {
INFO_VIEW,
HIL_CONFIG,
ANALYZE,
- LOG_DOWNLOAD
+ LOG_DOWNLOAD,
+ DEBUG_MESSAGES
};
static const char *rgDockWidgetNames[] = {
@@ -99,7 +101,8 @@ static const char *rgDockWidgetNames[] = {
"Info View",
"HIL Config",
"Analyze",
- "Log Download"
+ "Log Download",
+ "Debug Messages"
};
#define ARRAY_SIZE(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))
@@ -306,7 +309,7 @@ void MainWindow::_buildCommonWidgets(void)
const char* pDockWidgetName = rgDockWidgetNames[i];
// Add to menu
- QAction* action = new QAction(tr(pDockWidgetName), NULL);
+ QAction* action = new QAction(tr(pDockWidgetName), this);
action->setCheckable(true);
action->setData(i);
connect(action, &QAction::triggered, this, &MainWindow::_showDockWidgetAction);
@@ -352,6 +355,9 @@ bool MainWindow::_createInnerDockWidget(const QString& widgetName)
case LOG_DOWNLOAD:
widget = new LogDownload(widgetName, action, this);
break;
+ case DEBUG_MESSAGES:
+ widget = new AppMessagesDialog(widgetName, action, this);
+ break;
case STATUS_DETAILS:
widget = new UASInfoWidget(widgetName, action, this);
break;
@@ -419,10 +425,6 @@ void MainWindow::closeEvent(QCloseEvent *event)
_storeCurrentViewState();
storeSettings();
- //-- TODO: This effectively causes the QGCApplication destructor to not being able
- // to access the pointer it is trying to delete.
- _instance = NULL;
-
emit mainWindowClosed();
}