Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
064513e9
Commit
064513e9
authored
Apr 06, 2016
by
Don Gagne
Browse files
Merge pull request #3139 from NaterGator/consolefix
Add optional qml-based console to view debugging messages. For #3121
parents
cf510700
36c30bff
Changes
12
Hide whitespace changes
Inline
Side-by-side
qgroundcontrol.pro
View file @
064513e9
...
...
@@ -95,7 +95,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
#
...
...
@@ -280,6 +283,7 @@ HEADERS += \
src
/
QGCQuickWidget
.
h
\
src
/
QGCTemporaryFile
.
h
\
src
/
QGCToolbox
.
h
\
src
/
QmlControls
/
AppMessages
.
h
\
src
/
QmlControls
/
CoordinateVector
.
h
\
src
/
QmlControls
/
MavlinkQmlSingleton
.
h
\
src
/
QmlControls
/
ParameterEditorController
.
h
\
...
...
@@ -422,6 +426,7 @@ SOURCES += \
src
/
QGCTemporaryFile
.
cc
\
src
/
QGCToolbox
.
cc
\
src
/
QGCGeo
.
cc
\
src
/
QmlControls
/
AppMessages
.
cc
\
src
/
QmlControls
/
CoordinateVector
.
cc
\
src
/
QmlControls
/
ParameterEditorController
.
cc
\
src
/
QmlControls
/
ScreenToolsController
.
cc
\
...
...
@@ -500,7 +505,7 @@ SOURCES += \
src
/
ViewWidgets
/
CustomCommandWidgetController
.
cc
\
src
/
ViewWidgets
/
LogDownload
.
cc
\
src
/
ViewWidgets
/
LogDownloadController
.
cc
\
src
/
ViewWidgets
/
ViewWidgetController
.
cc
\
src
/
ViewWidgets
/
ViewWidgetController
.
cc
}
#
...
...
qgroundcontrol.qrc
View file @
064513e9
...
...
@@ -85,6 +85,7 @@
<file alias="QGroundControl/Controls/SubMenuButton.qml">src/QmlControls/SubMenuButton.qml</file>
<file alias="QGroundControl/Controls/VehicleRotationCal.qml">src/QmlControls/VehicleRotationCal.qml</file>
<file alias="QGroundControl/Controls/VehicleSummaryRow.qml">src/QmlControls/VehicleSummaryRow.qml</file>
<file alias="QGroundControl/Controls/AppMessages.qml">src/QmlControls/AppMessages.qml</file>
<file alias="QGroundControl/Controls/ViewWidget.qml">src/ViewWidgets/ViewWidget.qml</file>
<file alias="SimpleItemEditor.qml">src/MissionEditor/SimpleItemEditor.qml</file>
...
...
src/QGCApplication.cc
View file @
064513e9
...
...
@@ -36,6 +36,7 @@
#include
<QPainter>
#include
<QStyleFactory>
#include
<QAction>
#include
<QStringListModel>
#ifdef QGC_ENABLE_BLUETOOTH
#include
<QBluetoothLocalDevice>
...
...
@@ -100,6 +101,7 @@
#include
"LogDownloadController.h"
#include
"PX4AirframeLoader.h"
#include
"ValuesWidgetController.h"
#include
"AppMessages.h"
#ifndef __ios__
#include
"SerialLink.h"
...
...
@@ -484,6 +486,7 @@ bool QGCApplication::_initForNormalAppBoot(void)
_qmlAppEngine
=
new
QQmlApplicationEngine
(
this
);
_qmlAppEngine
->
addImportPath
(
"qrc:/qml"
);
_qmlAppEngine
->
rootContext
()
->
setContextProperty
(
"joystickManager"
,
toolbox
()
->
joystickManager
());
_qmlAppEngine
->
rootContext
()
->
setContextProperty
(
"debugMessageModel"
,
AppMessages
::
getModel
());
_qmlAppEngine
->
load
(
QUrl
(
QStringLiteral
(
"qrc:/qml/MainWindowNative.qml"
)));
#else
// Start the user interface
...
...
src/QGCDockWidget.cc
View file @
064513e9
...
...
@@ -47,6 +47,8 @@ void QGCDockWidget::closeEvent(QCloseEvent* event)
saveSettings
();
event
->
ignore
();
_action
->
trigger
();
}
else
{
QWidget
::
closeEvent
(
event
);
}
}
...
...
src/QGCDockWidget.h
View file @
064513e9
...
...
@@ -26,6 +26,7 @@
#include
<QDockWidget>
#include
<QAction>
#include
<QPointer>
class
QGCDockWidget
:
public
QWidget
{
Q_OBJECT
...
...
@@ -38,10 +39,10 @@ public:
void
saveSettings
(
void
);
void
closeEvent
(
QCloseEvent
*
event
);
protected:
QString
_title
;
QAction
*
_action
;
QPointer
<
QAction
>
_action
;
static
const
char
*
_settingsGroup
;
};
...
...
src/QmlControls/AppMessages.cc
0 → 100644
View file @
064513e9
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
// Allows QGlobalStatic to work on this translation unit
#define _LOG_CTOR_ACCESS_ public
#include
"AppMessages.h"
#include
<QFile>
#include
<QStringListModel>
#include
<QtConcurrent>
#include
<QTextStream>
Q_GLOBAL_STATIC
(
AppLogModel
,
debug_model
)
static
QtMessageHandler
old_handler
;
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"
))
{
debug_model
->
log
(
output
);
}
if
(
old_handler
!=
nullptr
)
{
old_handler
(
type
,
context
,
msg
);
}
if
(
type
==
QtFatalMsg
)
abort
();
}
void
AppMessages
::
installHandler
()
{
old_handler
=
qInstallMessageHandler
(
msgHandler
);
// Force creation of debug model on installing thread
Q_UNUSED
(
*
debug_model
);
}
AppLogModel
*
AppMessages
::
getModel
()
{
return
debug_model
;
}
AppLogModel
::
AppLogModel
()
:
QStringListModel
()
{
#ifdef __mobile__
Qt
::
ConnectionType
contype
=
Qt
::
QueuedConnection
;
#else
Qt
::
ConnectionType
contype
=
Qt
::
AutoConnection
;
#endif
connect
(
this
,
&
AppLogModel
::
emitLog
,
this
,
&
AppLogModel
::
threadsafeLog
,
contype
);
}
void
AppLogModel
::
writeMessages
(
const
QUrl
dest_file
)
{
const
QString
writebuffer
(
stringList
().
join
(
'\n'
).
append
(
'\n'
));
QtConcurrent
::
run
([
dest_file
,
writebuffer
]
{
emit
debug_model
->
writeStarted
();
bool
success
=
false
;
QFile
file
(
dest_file
.
toLocalFile
());
if
(
file
.
open
(
QIODevice
::
WriteOnly
|
QIODevice
::
Text
))
{
QTextStream
out
(
&
file
);
out
<<
writebuffer
;
success
=
out
.
status
()
==
QTextStream
::
Ok
;
}
emit
debug_model
->
writeFinished
(
success
);
});
}
void
AppLogModel
::
log
(
const
QString
message
)
{
emit
debug_model
->
emitLog
(
message
);
}
void
AppLogModel
::
threadsafeLog
(
const
QString
message
)
{
const
int
line
=
rowCount
();
insertRows
(
line
,
1
);
setData
(
index
(
line
),
message
,
Qt
::
DisplayRole
);
}
src/QmlControls/AppMessages.h
0 → 100644
View file @
064513e9
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
#pragma once
#include
<QObject>
#include
<QStringListModel>
#include
<QUrl>
// Hackish way to force only this translation unit to have public ctor access
#ifndef _LOG_CTOR_ACCESS_
#define _LOG_CTOR_ACCESS_ private
#endif
class
AppLogModel
:
public
QStringListModel
{
Q_OBJECT
public:
Q_INVOKABLE
void
writeMessages
(
const
QUrl
dest_file
);
static
void
log
(
const
QString
message
);
signals:
void
emitLog
(
const
QString
message
);
void
writeStarted
();
void
writeFinished
(
bool
success
);
private
slots
:
void
threadsafeLog
(
const
QString
message
);
_LOG_CTOR_ACCESS_:
AppLogModel
();
};
class
AppMessages
{
public:
static
void
installHandler
();
static
AppLogModel
*
getModel
();
};
src/QmlControls/AppMessages.qml
0 → 100644
View file @
064513e9
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
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
Rectangle
{
id
:
logwindow
anchors.fill
:
parent
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
color
:
qgcPal
.
window
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
}
}
}
ListView
{
Component.onCompleted
:
{
loaded
=
true
}
anchors.top
:
parent
.
top
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
anchors.bottom
:
followTail
.
top
anchors.bottomMargin
:
ScreenTools
.
defaultFontPixelWidth
clip
:
true
id
:
listview
model
:
debugMessageModel
delegate
:
delegateItem
}
FileDialog
{
id
:
writeDialog
folder
:
shortcuts
.
home
nameFilters
:
[
"
Log files (*.txt)
"
,
"
All Files (*)
"
]
selectExisting
:
false
title
:
"
Select log save file
"
onAccepted
:
{
debugMessageModel
.
writeMessages
(
fileUrl
);
visible
=
false
;
}
onRejected
:
visible
=
false
}
Connections
{
target
:
debugMessageModel
onWriteStarted
:
writeButton
.
enabled
=
false
;
onWriteFinished
:
writeButton
.
enabled
=
true
;
}
QGCButton
{
id
:
writeButton
anchors.bottom
:
parent
.
bottom
anchors.left
:
parent
.
left
onClicked
:
writeDialog
.
visible
=
true
text
:
"
Save App Log
"
}
BusyIndicator
{
id
:
writeBusy
anchors.bottom
:
writeButton
.
bottom
anchors.left
:
writeButton
.
right
height
:
writeButton
.
height
visible
:
!
writeButton
.
enabled
}
QGCButton
{
id
:
followTail
anchors.bottom
:
parent
.
bottom
anchors.right
:
parent
.
right
text
:
"
Show Latest
"
checkable
:
true
checked
:
true
onCheckedChanged
:
{
if
(
checked
&&
loaded
)
{
listview
.
positionViewAtEnd
();
}
}
}
}
src/QmlControls/QGroundControl.Controls.qmldir
View file @
064513e9
Module QGroundControl.Controls
AppMessages 1.0 AppMessages.qml
ClickableColor 1.0 ClickableColor.qml
DropButton 1.0 DropButton.qml
ExclusiveGroupItem 1.0 ExclusiveGroupItem.qml
...
...
src/main.cc
View file @
064513e9
...
...
@@ -35,8 +35,9 @@ This file is part of the QGROUNDCONTROL project
#include
<QHostAddress>
#include
<QUdpSocket>
#include
<QtPlugin>
#include
<QStringListModel>
#include
"QGCApplication.h"
#include
"AppMessages.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
)
...
...
@@ -124,6 +114,8 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved)
int
main
(
int
argc
,
char
*
argv
[])
{
// install the message handler
AppMessages
::
installHandler
();
#ifndef __mobile__
//-- Test for another instance already running. If that's the case, we simply exit.
...
...
@@ -144,9 +136,6 @@ int main(int argc, char *argv[])
#endif
#ifdef Q_OS_WIN
// install the message handler
qInstallMessageHandler
(
msgHandler
);
// Set our own OpenGL buglist
qputenv
(
"QT_OPENGL_BUGLIST"
,
":/opengl/resources/opengl/buglist.json"
);
...
...
src/ui/MainWindow.cc
View file @
064513e9
...
...
@@ -66,6 +66,7 @@ This file is part of the QGROUNDCONTROL project
#include
"UASInfoWidget.h"
#include
"HILDockWidget.h"
#include
"LogDownload.h"
#include
"AppMessages.h"
#endif
#ifndef __ios__
...
...
@@ -164,6 +165,7 @@ MainWindow::MainWindow()
QQmlEngine
::
setObjectOwnership
(
this
,
QQmlEngine
::
CppOwnership
);
_mainQmlWidgetHolder
->
setContextPropertyObject
(
"controller"
,
this
);
_mainQmlWidgetHolder
->
setContextPropertyObject
(
"debugMessageModel"
,
AppMessages
::
getModel
());
_mainQmlWidgetHolder
->
setSource
(
QUrl
::
fromUserInput
(
"qrc:qml/MainWindowHybrid.qml"
));
// Image provider
...
...
@@ -306,7 +308,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
);
...
...
@@ -419,10 +421,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
();
}
...
...
src/ui/MainWindowLeftPanel.qml
View file @
064513e9
...
...
@@ -213,6 +213,19 @@ Item {
}
}
QGCButton
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
text
:
"
Console
"
exclusiveGroup
:
panelActionGroup
onClicked
:
{
if
(
__rightPanel
.
source
!=
"
QGroundControl/Controls/AppMessages.qml
"
)
{
__rightPanel
.
source
=
"
QGroundControl/Controls/AppMessages.qml
"
}
checked
=
true
}
}
QGCButton
{
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment