Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
qgroundcontrol
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
bed21b49
Commit
bed21b49
authored
Feb 23, 2015
by
dogmaphobic
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New, QML based Tool Bar.
parent
134b2c1a
Changes
28
Hide whitespace changes
Inline
Side-by-side
Showing
28 changed files
with
2141 additions
and
473 deletions
+2141
-473
battery_0.svg
files/images/status/battery_0.svg
+22
-0
battery_100.svg
files/images/status/battery_100.svg
+31
-0
battery_20.svg
files/images/status/battery_20.svg
+24
-0
battery_40.svg
files/images/status/battery_40.svg
+26
-0
battery_60.svg
files/images/status/battery_60.svg
+28
-0
battery_80.svg
files/images/status/battery_80.svg
+30
-0
gps.svg
files/images/status/gps.svg
+275
-0
message_megaphone.png
files/images/status/message_megaphone.png
+0
-0
message_triangle.png
files/images/status/message_triangle.png
+0
-0
qgroundcontrol.pro
qgroundcontrol.pro
+5
-2
qgroundcontrol.qrc
qgroundcontrol.qrc
+10
-3
QGCQmlWidgetHolder.cpp
src/QGCQmlWidgetHolder.cpp
+5
-0
QGCQmlWidgetHolder.h
src/QGCQmlWidgetHolder.h
+5
-2
QGCQmlWidgetHolder.ui
src/QGCQmlWidgetHolder.ui
+10
-1
SetupViewTest.cc
src/VehicleSetup/SetupViewTest.cc
+3
-1
MainWindowTest.cc
src/qgcunittest/MainWindowTest.cc
+6
-2
UASMessageHandler.cc
src/uas/UASMessageHandler.cc
+36
-3
UASMessageHandler.h
src/uas/UASMessageHandler.h
+15
-0
MainWindow.cc
src/ui/MainWindow.cc
+240
-366
MainWindow.h
src/ui/MainWindow.h
+21
-24
QGCLinkConfiguration.cc
src/ui/QGCLinkConfiguration.cc
+91
-59
QGCLinkConfiguration.h
src/ui/QGCLinkConfiguration.h
+1
-0
QGCToolBar.cc
src/ui/QGCToolBar.cc
+2
-0
MainToolBar.cc
src/ui/toolbar/MainToolBar.cc
+579
-0
MainToolBar.h
src/ui/toolbar/MainToolBar.h
+180
-0
MainToolBar.qml
src/ui/toolbar/MainToolBar.qml
+489
-0
UASMessageView.cc
src/ui/uas/UASMessageView.cc
+4
-6
UASMessageView.h
src/ui/uas/UASMessageView.h
+3
-4
No files found.
files/images/status/battery_0.svg
0 → 100644
View file @
bed21b49
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version=
"1.1"
id=
"svg4264"
sodipodi:docname=
"battery_0.svg"
inkscape:version=
"0.91 r13725"
xmlns:rdf=
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc=
"http://purl.org/dc/elements/1.1/"
xmlns:inkscape=
"http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi=
"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg=
"http://www.w3.org/2000/svg"
xmlns:cc=
"http://creativecommons.org/ns#"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
x=
"0px"
y=
"0px"
viewBox=
"-142 87 326.3 620"
enable-background=
"new -142 87 326.3 620"
xml:space=
"preserve"
>
<title
id=
"title4294"
>
Battery
</title>
<sodipodi:namedview
inkscape:window-maximized=
"0"
inkscape:window-y=
"65"
inkscape:window-x=
"2776"
inkscape:window-height=
"1259"
inkscape:window-width=
"2003"
fit-margin-bottom=
"0.02"
fit-margin-right=
"0.02"
inkscape:current-layer=
"layer1"
inkscape:pageshadow=
"2"
inkscape:document-units=
"in"
inkscape:pageopacity=
"0.0"
units=
"in"
borderopacity=
"1.0"
bordercolor=
"#666666"
pagecolor=
"#ffffff"
showgrid=
"false"
inkscape:cy=
"387.50002"
inkscape:zoom=
"1.4103225"
inkscape:cx=
"115.31779"
id=
"base"
fit-margin-top=
"0.02"
fit-margin-left=
"0.02"
showborder=
"true"
>
</sodipodi:namedview>
<path
id=
"rect4970"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
d=
"M-127.7,667.9v-502
c0-14.8,13.1-26.8,29.3-26.8h239.2c16.2,0,29.3,12,29.3,26.8v502c0,14.8-13.1,26.8-29.3,26.8H-98.4
C-114.6,694.7-127.7,682.7-127.7,667.9z"
/>
<path
id=
"rect4360"
inkscape:connector-curvature=
"0"
fill=
"none"
d=
"M-140.6,677.6V156.1c0-15.4,14.2-27.9,31.8-27.9h259.9
c17.6,0,31.8,12.6,31.8,27.9v521.5c0,15.4-14.2,27.9-31.8,27.9h-259.8C-126.3,705.5-140.6,693-140.6,677.6z"
/>
<g
id=
"g4222"
transform=
"translate(-127.22081,216.20249)"
>
<path
id=
"path4224"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
stroke-miterlimit=
"10"
d=
"
M231.3-81.3c0,2.2-1.7,3.9-3.9,3.9h-155c-2.2,0-3.9-1.7-3.9-3.9v-40.2c0-2.2,1.7-3.9,3.9-3.9h155c2.2,0,3.9,1.7,3.9,3.9L231.3-81.3
L231.3-81.3L231.3-81.3z"
/>
</g>
<text
transform=
"matrix(0.757 0 0 1 -80.0776 552.9648)"
font-family=
"'Helvetica'"
font-size=
"406.7761"
>
X
</text>
</svg>
files/images/status/battery_100.svg
0 → 100644
View file @
bed21b49
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version=
"1.1"
id=
"svg4264"
sodipodi:docname=
"battery_100.svg"
inkscape:version=
"0.91 r13725"
xmlns:rdf=
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc=
"http://purl.org/dc/elements/1.1/"
xmlns:inkscape=
"http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi=
"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg=
"http://www.w3.org/2000/svg"
xmlns:cc=
"http://creativecommons.org/ns#"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
x=
"0px"
y=
"0px"
viewBox=
"-142 87 326.3 620"
enable-background=
"new -142 87 326.3 620"
xml:space=
"preserve"
>
<title
id=
"title4294"
>
Battery
</title>
<sodipodi:namedview
inkscape:window-maximized=
"0"
inkscape:window-y=
"65"
inkscape:window-x=
"2776"
inkscape:window-height=
"1259"
inkscape:window-width=
"2003"
fit-margin-bottom=
"0.02"
fit-margin-right=
"0.02"
inkscape:current-layer=
"layer1"
inkscape:pageshadow=
"2"
inkscape:document-units=
"in"
inkscape:pageopacity=
"0.0"
units=
"in"
borderopacity=
"1.0"
bordercolor=
"#666666"
pagecolor=
"#ffffff"
showgrid=
"false"
inkscape:cy=
"393.84035"
inkscape:zoom=
"1.2144444"
inkscape:cx=
"202.22082"
id=
"base"
fit-margin-top=
"0.02"
fit-margin-left=
"0.02"
showborder=
"true"
>
</sodipodi:namedview>
<path
id=
"rect4970"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
d=
"M-127.7,667.9v-502
c0-14.8,13.1-26.8,29.3-26.8h239.2c16.2,0,29.3,12,29.3,26.8v502c0,14.8-13.1,26.8-29.3,26.8H-98.4
C-114.6,694.7-127.7,682.7-127.7,667.9z"
/>
<path
id=
"rect4360"
inkscape:connector-curvature=
"0"
fill=
"none"
d=
"M-140.6,677.6V156.1c0-15.4,14.2-27.9,31.8-27.9h259.9
c17.6,0,31.8,12.6,31.8,27.9v521.5c0,15.4-14.2,27.9-31.8,27.9h-259.8C-126.3,705.5-140.6,693-140.6,677.6z"
/>
<path
id=
"path4669"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.4,260.4v-90.1h225.1v90.1
H-91.4L-91.4,260.4z"
/>
<path
id=
"path4671"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.4,363.3v-90.1h225.1v90.1
H-91.4z"
/>
<path
id=
"path4673"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.4,466.3v-90.1h225.1v90.1
H-91.4z"
/>
<path
id=
"path4675"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.4,569.2v-90.1h225.1v90.1
H-91.4z"
/>
<path
id=
"path4679"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.4,672V582h225.1V672H-91.4
z"
/>
<g
id=
"g4222"
transform=
"translate(-127.22081,216.20249)"
>
<path
id=
"path4224"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
stroke-miterlimit=
"10"
d=
"
M229.9-81.3c0,2.2-1.7,3.9-3.9,3.9h-155c-2.2,0-3.9-1.7-3.9-3.9v-40.2c0-2.2,1.7-3.9,3.9-3.9h155c2.2,0,3.9,1.7,3.9,3.9L229.9-81.3
L229.9-81.3L229.9-81.3z"
/>
</g>
</svg>
files/images/status/battery_20.svg
0 → 100644
View file @
bed21b49
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version=
"1.1"
id=
"svg4264"
sodipodi:docname=
"battery_100.svg"
inkscape:version=
"0.91 r13725"
xmlns:rdf=
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc=
"http://purl.org/dc/elements/1.1/"
xmlns:inkscape=
"http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi=
"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg=
"http://www.w3.org/2000/svg"
xmlns:cc=
"http://creativecommons.org/ns#"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
x=
"0px"
y=
"0px"
viewBox=
"-142 87 326.32 620"
enable-background=
"new -142 87 326.32 620"
xml:space=
"preserve"
>
<title
id=
"title4294"
>
Battery
</title>
<sodipodi:namedview
inkscape:window-maximized=
"0"
inkscape:window-y=
"65"
inkscape:window-x=
"2776"
inkscape:window-height=
"1259"
inkscape:window-width=
"2003"
fit-margin-bottom=
"0.02"
fit-margin-right=
"0.02"
inkscape:current-layer=
"layer1"
inkscape:pageshadow=
"2"
inkscape:document-units=
"in"
inkscape:pageopacity=
"0.0"
units=
"in"
borderopacity=
"1.0"
bordercolor=
"#666666"
pagecolor=
"#ffffff"
showgrid=
"false"
inkscape:cy=
"393.84035"
inkscape:zoom=
"1.2144444"
inkscape:cx=
"202.22082"
id=
"base"
fit-margin-top=
"0.02"
fit-margin-left=
"0.02"
showborder=
"true"
>
</sodipodi:namedview>
<path
id=
"rect4970"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
d=
"M-127.68,667.88v-502
c0-14.8,13.12-26.8,29.28-26.8h239.2c16.16,0,29.28,12,29.28,26.8v502c0,14.8-13.12,26.8-29.28,26.8H-98.4
C-114.64,694.68-127.68,682.68-127.68,667.88z"
/>
<path
id=
"rect4360"
inkscape:connector-curvature=
"0"
fill=
"none"
d=
"M-140.56,677.64V156.12c0-15.36,14.24-27.92,31.76-27.92
h259.92c17.6,0,31.76,12.56,31.76,27.92v521.52c0,15.36-14.24,27.92-31.76,27.92h-259.84C-126.32,705.48-140.56,693-140.56,677.64z"
/>
<path
id=
"path4679"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#471F0D"
d=
"M-91.36,672.04v-90.08h225.12
v90.08H-91.36z"
/>
<g
id=
"g4222"
transform=
"translate(-127.22081,216.20249)"
>
<path
id=
"path4224"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
stroke-miterlimit=
"10"
d=
"
M229.861-81.283c0,2.24-1.68,3.92-3.92,3.92H70.901c-2.24,0-3.92-1.68-3.92-3.92v-40.16c0-2.24,1.68-3.92,3.92-3.92h155.04
c2.24,0,3.92,1.68,3.92,3.92L229.861-81.283L229.861-81.283L229.861-81.283z"
/>
</g>
</svg>
files/images/status/battery_40.svg
0 → 100644
View file @
bed21b49
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version=
"1.1"
id=
"svg4264"
sodipodi:docname=
"battery_100.svg"
inkscape:version=
"0.91 r13725"
xmlns:rdf=
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc=
"http://purl.org/dc/elements/1.1/"
xmlns:inkscape=
"http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi=
"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg=
"http://www.w3.org/2000/svg"
xmlns:cc=
"http://creativecommons.org/ns#"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
x=
"0px"
y=
"0px"
viewBox=
"-142 87 326.32 620"
enable-background=
"new -142 87 326.32 620"
xml:space=
"preserve"
>
<title
id=
"title4294"
>
Battery
</title>
<sodipodi:namedview
inkscape:window-maximized=
"0"
inkscape:window-y=
"65"
inkscape:window-x=
"2776"
inkscape:window-height=
"1259"
inkscape:window-width=
"2003"
fit-margin-bottom=
"0.02"
fit-margin-right=
"0.02"
inkscape:current-layer=
"layer1"
inkscape:pageshadow=
"2"
inkscape:document-units=
"in"
inkscape:pageopacity=
"0.0"
units=
"in"
borderopacity=
"1.0"
bordercolor=
"#666666"
pagecolor=
"#ffffff"
showgrid=
"false"
inkscape:cy=
"393.84035"
inkscape:zoom=
"1.2144444"
inkscape:cx=
"202.22082"
id=
"base"
fit-margin-top=
"0.02"
fit-margin-left=
"0.02"
showborder=
"true"
>
</sodipodi:namedview>
<path
id=
"rect4970"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
d=
"M-127.68,667.88v-502
c0-14.8,13.12-26.8,29.28-26.8h239.2c16.16,0,29.28,12,29.28,26.8v502c0,14.8-13.12,26.8-29.28,26.8H-98.4
C-114.64,694.68-127.68,682.68-127.68,667.88z"
/>
<path
id=
"rect4360"
inkscape:connector-curvature=
"0"
fill=
"none"
d=
"M-140.56,677.64V156.12c0-15.36,14.24-27.92,31.76-27.92
h259.92c17.6,0,31.76,12.56,31.76,27.92v521.52c0,15.36-14.24,27.92-31.76,27.92h-259.84C-126.32,705.48-140.56,693-140.56,677.64z"
/>
<path
id=
"path4675"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#9F4B23"
d=
"M-91.36,569.16v-90.08h225.12
v90.08H-91.36z"
/>
<path
id=
"path4679"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#9F4B23"
d=
"M-91.36,672.04v-90.08h225.12
v90.08H-91.36z"
/>
<g
id=
"g4222"
transform=
"translate(-127.22081,216.20249)"
>
<path
id=
"path4224"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
stroke-miterlimit=
"10"
d=
"
M229.861-81.283c0,2.24-1.68,3.92-3.92,3.92H70.901c-2.24,0-3.92-1.68-3.92-3.92v-40.16c0-2.24,1.68-3.92,3.92-3.92h155.04
c2.24,0,3.92,1.68,3.92,3.92L229.861-81.283L229.861-81.283L229.861-81.283z"
/>
</g>
</svg>
files/images/status/battery_60.svg
0 → 100644
View file @
bed21b49
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version=
"1.1"
id=
"svg4264"
sodipodi:docname=
"battery_100.svg"
inkscape:version=
"0.91 r13725"
xmlns:rdf=
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc=
"http://purl.org/dc/elements/1.1/"
xmlns:inkscape=
"http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi=
"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg=
"http://www.w3.org/2000/svg"
xmlns:cc=
"http://creativecommons.org/ns#"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
x=
"0px"
y=
"0px"
viewBox=
"-142 87 326.32 620"
enable-background=
"new -142 87 326.32 620"
xml:space=
"preserve"
>
<title
id=
"title4294"
>
Battery
</title>
<sodipodi:namedview
inkscape:window-maximized=
"0"
inkscape:window-y=
"65"
inkscape:window-x=
"2776"
inkscape:window-height=
"1259"
inkscape:window-width=
"2003"
fit-margin-bottom=
"0.02"
fit-margin-right=
"0.02"
inkscape:current-layer=
"layer1"
inkscape:pageshadow=
"2"
inkscape:document-units=
"in"
inkscape:pageopacity=
"0.0"
units=
"in"
borderopacity=
"1.0"
bordercolor=
"#666666"
pagecolor=
"#ffffff"
showgrid=
"false"
inkscape:cy=
"393.84035"
inkscape:zoom=
"1.2144444"
inkscape:cx=
"202.22082"
id=
"base"
fit-margin-top=
"0.02"
fit-margin-left=
"0.02"
showborder=
"true"
>
</sodipodi:namedview>
<path
id=
"rect4970"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
d=
"M-127.68,667.88v-502
c0-14.8,13.12-26.8,29.28-26.8h239.2c16.16,0,29.28,12,29.28,26.8v502c0,14.8-13.12,26.8-29.28,26.8H-98.4
C-114.64,694.68-127.68,682.68-127.68,667.88z"
/>
<path
id=
"rect4360"
inkscape:connector-curvature=
"0"
fill=
"none"
d=
"M-140.56,677.64V156.12c0-15.36,14.24-27.92,31.76-27.92
h259.92c17.6,0,31.76,12.56,31.76,27.92v521.52c0,15.36-14.24,27.92-31.76,27.92h-259.84C-126.32,705.48-140.56,693-140.56,677.64z"
/>
<path
id=
"path4673"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.36,466.28V376.2h225.12
v90.08H-91.36z"
/>
<path
id=
"path4675"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.36,569.16v-90.08h225.12
v90.08H-91.36z"
/>
<path
id=
"path4679"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.36,672.04v-90.08h225.12
v90.08H-91.36z"
/>
<g
id=
"g4222"
transform=
"translate(-127.22081,216.20249)"
>
<path
id=
"path4224"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
stroke-miterlimit=
"10"
d=
"
M229.861-81.283c0,2.24-1.68,3.92-3.92,3.92H70.901c-2.24,0-3.92-1.68-3.92-3.92v-40.16c0-2.24,1.68-3.92,3.92-3.92h155.04
c2.24,0,3.92,1.68,3.92,3.92L229.861-81.283L229.861-81.283L229.861-81.283z"
/>
</g>
</svg>
files/images/status/battery_80.svg
0 → 100644
View file @
bed21b49
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg
version=
"1.1"
id=
"svg4264"
sodipodi:docname=
"battery_100.svg"
inkscape:version=
"0.91 r13725"
xmlns:rdf=
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc=
"http://purl.org/dc/elements/1.1/"
xmlns:inkscape=
"http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi=
"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:svg=
"http://www.w3.org/2000/svg"
xmlns:cc=
"http://creativecommons.org/ns#"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
x=
"0px"
y=
"0px"
viewBox=
"-142 87 326.32 620"
enable-background=
"new -142 87 326.32 620"
xml:space=
"preserve"
>
<title
id=
"title4294"
>
Battery
</title>
<sodipodi:namedview
inkscape:window-maximized=
"0"
inkscape:window-y=
"65"
inkscape:window-x=
"2776"
inkscape:window-height=
"1259"
inkscape:window-width=
"2003"
fit-margin-bottom=
"0.02"
fit-margin-right=
"0.02"
inkscape:current-layer=
"layer1"
inkscape:pageshadow=
"2"
inkscape:document-units=
"in"
inkscape:pageopacity=
"0.0"
units=
"in"
borderopacity=
"1.0"
bordercolor=
"#666666"
pagecolor=
"#ffffff"
showgrid=
"false"
inkscape:cy=
"393.84035"
inkscape:zoom=
"1.2144444"
inkscape:cx=
"202.22082"
id=
"base"
fit-margin-top=
"0.02"
fit-margin-left=
"0.02"
showborder=
"true"
>
</sodipodi:namedview>
<path
id=
"rect4970"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
d=
"M-127.68,667.88v-502
c0-14.8,13.12-26.8,29.28-26.8h239.2c16.16,0,29.28,12,29.28,26.8v502c0,14.8-13.12,26.8-29.28,26.8H-98.4
C-114.64,694.68-127.68,682.68-127.68,667.88z"
/>
<path
id=
"rect4360"
inkscape:connector-curvature=
"0"
fill=
"none"
d=
"M-140.56,677.64V156.12c0-15.36,14.24-27.92,31.76-27.92
h259.92c17.6,0,31.76,12.56,31.76,27.92v521.52c0,15.36-14.24,27.92-31.76,27.92h-259.84C-126.32,705.48-140.56,693-140.56,677.64z"
/>
<path
id=
"path4671"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.36,363.32v-90.08h225.12
v90.08H-91.36z"
/>
<path
id=
"path4673"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.36,466.28V376.2h225.12
v90.08H-91.36z"
/>
<path
id=
"path4675"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.36,569.16v-90.08h225.12
v90.08H-91.36z"
/>
<path
id=
"path4679"
sodipodi:nodetypes=
"ccccc"
inkscape:connector-curvature=
"0"
fill=
"#09753B"
d=
"M-91.36,672.04v-90.08h225.12
v90.08H-91.36z"
/>
<g
id=
"g4222"
transform=
"translate(-127.22081,216.20249)"
>
<path
id=
"path4224"
inkscape:connector-curvature=
"0"
fill=
"#E6E7E8"
stroke=
"#E6E7E8"
stroke-width=
"6"
stroke-miterlimit=
"10"
d=
"
M229.861-81.283c0,2.24-1.68,3.92-3.92,3.92H70.901c-2.24,0-3.92-1.68-3.92-3.92v-40.16c0-2.24,1.68-3.92,3.92-3.92h155.04
c2.24,0,3.92,1.68,3.92,3.92L229.861-81.283L229.861-81.283L229.861-81.283z"
/>
</g>
</svg>
files/images/status/gps.svg
0 → 100644
View file @
bed21b49
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc=
"http://purl.org/dc/elements/1.1/"
xmlns:cc=
"http://creativecommons.org/ns#"
xmlns:rdf=
"http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg=
"http://www.w3.org/2000/svg"
xmlns=
"http://www.w3.org/2000/svg"
xmlns:sodipodi=
"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape=
"http://www.inkscape.org/namespaces/inkscape"
version=
"1.1"
x=
"0px"
y=
"0px"
width=
"110px"
height=
"110px"
viewBox=
"0 0 110 110"
enable-background=
"new 0 0 110 110"
xml:space=
"preserve"
id=
"svg3852"
inkscape:version=
"0.91 r13725"
sodipodi:docname=
"gps.svg"
><title
id=
"title4758"
>
GPS
</title><metadata
id=
"metadata3933"
><rdf:RDF><cc:Work
rdf:about=
""
><dc:format>
image/svg+xml
</dc:format><dc:type
rdf:resource=
"http://purl.org/dc/dcmitype/StillImage"
/><dc:title>
GPS
</dc:title><dc:creator><cc:Agent><dc:title>
Gus Grubba
</dc:title></cc:Agent></dc:creator><cc:license
rdf:resource=
"http://creativecommons.org/licenses/by-nc/3.0/"
/></cc:Work><cc:License
rdf:about=
"http://creativecommons.org/licenses/by-nc/3.0/"
><cc:permits
rdf:resource=
"http://creativecommons.org/ns#Reproduction"
/><cc:permits
rdf:resource=
"http://creativecommons.org/ns#Distribution"
/><cc:requires
rdf:resource=
"http://creativecommons.org/ns#Notice"
/><cc:requires
rdf:resource=
"http://creativecommons.org/ns#Attribution"
/><cc:prohibits
rdf:resource=
"http://creativecommons.org/ns#CommercialUse"
/><cc:permits
rdf:resource=
"http://creativecommons.org/ns#DerivativeWorks"
/></cc:License></rdf:RDF></metadata><defs
id=
"defs3931"
/><sodipodi:namedview
pagecolor=
"#808080"
bordercolor=
"#666666"
borderopacity=
"1"
objecttolerance=
"10"
gridtolerance=
"10"
guidetolerance=
"10"
inkscape:pageopacity=
"0"
inkscape:pageshadow=
"2"
inkscape:window-width=
"640"
inkscape:window-height=
"480"
id=
"namedview3929"
showgrid=
"false"
inkscape:zoom=
"11.136364"
inkscape:cx=
"55"
inkscape:cy=
"55"
inkscape:current-layer=
"svg3852"
/><g
id=
"Layer_2"
display=
"none"
/><g
id=
"ex_thick"
style=
"fill:#ffffff;stroke:#ffffff;stroke-opacity:1"
transform=
"matrix(-1,0,0,-1,111.82126,108.29692)"
/><g
id=
"Layer_2_copy_3"
display=
"none"
/><g
id=
"ex_thin"
style=
"fill:#ffffff;stroke:#ffffff;stroke-opacity:1"
transform=
"matrix(-1,0,0,-1,111.82126,108.29692)"
/><g
id=
"Layer_2_copy"
display=
"none"
/><g
id=
"em_thick"
style=
"fill:#ffffff;stroke:#ffffff;stroke-opacity:1"
transform=
"matrix(-1,0,0,-1,111.82126,108.29692)"
/><g
id=
"Layer_2_copy_4"
display=
"none"
><g
display=
"inline"
id=
"g3861"
><rect
x=
"-36.1"
y=
"-21.3"
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
width=
"56.3"
height=
"56.3"
id=
"rect3863"
/><circle
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
cx=
"-8"
cy=
"6.8"
r=
"28.2"
id=
"circle3865"
/></g><g
display=
"inline"
id=
"g3867"
><rect
x=
"28.3"
y=
"-21.3"
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
width=
"56.3"
height=
"56.3"
id=
"rect3869"
/><circle
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
cx=
"56.5"
cy=
"6.8"
r=
"28.2"
id=
"circle3871"
/></g><g
display=
"inline"
id=
"g3873"
><rect
x=
"91.5"
y=
"-21.3"
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
width=
"56.3"
height=
"56.3"
id=
"rect3875"
/><circle
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
cx=
"119.7"
cy=
"6.8"
r=
"28.2"
id=
"circle3877"
/></g></g><rect
x=
"-129.87416"
y=
"-13.196043"
transform=
"matrix(-0.70710678,-0.70710678,0.70710678,-0.70710678,0,0)"
stroke-miterlimit=
"10"
width=
"32.29969"
height=
"16.099846"
id=
"rect3882"
style=
"fill:#ffffff;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
/><rect
x=
"24.979502"
y=
"-2.9382656"
transform=
"matrix(0.70710678,0.70710678,-0.70710678,0.70710678,0,0)"
stroke-miterlimit=
"10"
width=
"32.29969"
height=
"16.099846"
id=
"rect3884"
style=
"fill:#ffffff;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
/><path
stroke-miterlimit=
"10"
d=
"m 31.121258,78.396923 c 4.7,4.7 12.4,4.7 17.1,0 l 22.8,-22.9 -17.1,-17.1 -22.8,22.8 c -4.7,4.8 -4.7,12.4 0,17.2 z"
id=
"path3886"
style=
"fill:#ffffff;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature=
"0"
/><path
stroke-miterlimit=
"10"
d=
"m 62.521258,46.996923 c 6.3,6.3 16.5,6.3 22.8,0 l -22.8,-22.8 c -6.3,6.2 -6.3,16.5 0,22.8 z"
id=
"path3888"
style=
"fill:#ffffff;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
inkscape:connector-curvature=
"0"
/><path
stroke-miterlimit=
"10"
d=
"m 96.084265,44.511467 c 8.249995,-8.25 8.249995,-21.75 0,-30 -8.25,-8.2499943 -21.75,-8.2499943 -30,0"
id=
"path3890"
style=
"fill:none;stroke:#ffffff;stroke-width:3.89999986;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
inkscape:connector-curvature=
"0"
/><path
stroke-miterlimit=
"10"
d=
"m 86.118561,36.977171 c 3.6,-3.6 3.6,-9.3 0,-12.9 -3.6,-3.6 -9.3,-3.6 -12.9,0"
id=
"path3892"
style=
"fill:none;stroke:#ffffff;stroke-width:3.89999986;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
inkscape:connector-curvature=
"0"
/><line
stroke-miterlimit=
"10"
x1=
"65.321259"
y1=
"72.596924"
x2=
"59.621258"
y2=
"66.896919"
id=
"line3894"
style=
"fill:#ffffff;stroke:#ffffff;stroke-width:4.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"
/><line
stroke-miterlimit=
"10"
x1=
"42.521255"
y1=
"49.796921"
x2=
"36.821259"
y2=
"44.096924"
id=
"line3896"
style=
"fill:#ffffff;stroke:#ffffff;stroke-width:4.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1;stroke-dasharray:none"
/><g
id=
"Layer_2_copy_2"
display=
"none"
><g
display=
"inline"
id=
"g3905"
><rect
x=
"-36.1"
y=
"83.3"
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
width=
"56.3"
height=
"56.3"
id=
"rect3907"
/><circle
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
cx=
"-8"
cy=
"111.5"
r=
"28.2"
id=
"circle3909"
/></g><g
display=
"inline"
id=
"g3911"
><rect
x=
"28.3"
y=
"83.3"
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
width=
"56.3"
height=
"56.3"
id=
"rect3913"
/><circle
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
cx=
"56.5"
cy=
"111.5"
r=
"28.2"
id=
"circle3915"
/></g><g
display=
"inline"
id=
"g3917"
><rect
x=
"91.5"
y=
"83.3"
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
width=
"56.3"
height=
"56.3"
id=
"rect3919"
/><circle
fill=
"none"
stroke=
"#EB008B"
stroke-width=
"0.25"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
cx=
"119.7"
cy=
"111.5"
r=
"28.2"
id=
"circle3921"
/></g></g><g
id=
"hornet"
style=
"fill:#ffffff;stroke:#ffffff;stroke-opacity:1"
transform=
"matrix(-1,0,0,-1,111.82126,108.29692)"
/><g
id=
"Layer_2_copy_5"
display=
"none"
/><g
id=
"hornet_THIN"
style=
"fill:#ffffff;stroke:#ffffff;stroke-opacity:1"
transform=
"matrix(-1,0,0,-1,111.82126,108.29692)"
/><g
id=
"Layer_6"
display=
"none"
><polygon
display=
"inline"
fill=
"none"
stroke=
"#224A80"
stroke-width=
"3"
stroke-linecap=
"round"
stroke-linejoin=
"round"
stroke-miterlimit=
"10"
points=
" -14.6,111.2 -19.5,111.2 -19.5,152.2 3.4,152.2 3.4,111.2 -1.5,111.2 -1.5,104.7 -14.6,104.7 "
id=
"polygon3927"
/></g></svg>
\ No newline at end of file
files/images/status/message_megaphone.png
0 → 100644
View file @
bed21b49
346 Bytes
files/images/status/message_triangle.png
0 → 100644
View file @
bed21b49
295 Bytes
qgroundcontrol.pro
View file @
bed21b49
...
...
@@ -268,6 +268,7 @@ INCLUDEPATH += \
src
/
ui
/
configuration
\
src
/
ui
/
px4_configuration
\
src
/
ui
/
main
\
src
/
ui
/
toolbar
\
src
/
VehicleSetup
\
src
/
AutoPilotPlugins
...
...
@@ -493,7 +494,8 @@ HEADERS += \
src
/
comm
/
LinkConfiguration
.
h
\
src
/
ui
/
QGCCommConfiguration
.
h
\
src
/
ui
/
QGCUDPLinkConfiguration
.
h
\
src
/
uas
/
UASMessageHandler
.
h
src
/
uas
/
UASMessageHandler
.
h
\
src
/
ui
/
toolbar
/
MainToolBar
.
h
SOURCES
+=
\
src
/
main
.
cc
\
...
...
@@ -633,7 +635,8 @@ SOURCES += \
src
/
comm
/
LinkConfiguration
.
cc
\
src
/
ui
/
QGCCommConfiguration
.
cc
\
src
/
ui
/
QGCUDPLinkConfiguration
.
cc
\
src
/
uas
/
UASMessageHandler
.
cc
src
/
uas
/
UASMessageHandler
.
cc
\
src
/
ui
/
toolbar
/
MainToolBar
.
cc
#
#
Unit
Test
specific
configuration
goes
here
...
...
qgroundcontrol.qrc
View file @
bed21b49
...
...
@@ -54,6 +54,15 @@
<file>files/images/actions/system-shutdown.svg</file>
<file>files/images/actions/system-log-out.svg</file>
<file>files/images/actions/system-lock-screen.svg</file>
<file>files/images/status/gps.svg</file>
<file>files/images/status/battery_0.svg</file>
<file>files/images/status/battery_20.svg</file>
<file>files/images/status/battery_40.svg</file>
<file>files/images/status/battery_60.svg</file>
<file>files/images/status/battery_80.svg</file>
<file>files/images/status/battery_100.svg</file>
<file>files/images/status/message_megaphone.png</file>
<file>files/images/status/message_triangle.png</file>
<file>files/images/status/weather-storm.svg</file>
<file>files/images/status/weather-snow.svg</file>
<file>files/images/status/weather-showers.svg</file>
...
...
@@ -235,9 +244,7 @@
<qresource prefix="/QLoggingCategory">
<file alias="qtlogging.ini">files/QLoggingCategory/qtlogging.ini</file>
</qresource>
<qresource prefix="/qml">
<file alias="test.qml">src/test.qml</file>
<file alias="QmlTest.qml">src/QmlControls/QmlTest.qml</file>
...
...
@@ -298,8 +305,8 @@
<file alias="QGroundControl/Controls/FirmwareUpgradeIcon.png">src/VehicleSetup/FirmwareUpgradeIcon.png</file>
<file alias="QGroundControl/Controls/VehicleSummaryIcon.png">src/VehicleSetup/VehicleSummaryIcon.png</file>
<file alias="MainToolBar.qml">src/ui/toolbar/MainToolBar.qml</file>
</qresource>
<qresource prefix="/AutoPilotPlugins/PX4">
<file alias="ParameterFactMetaData.xml">src/AutoPilotPlugins/PX4/ParameterFactMetaData.xml</file>
</qresource>
...
...
src/QGCQmlWidgetHolder.cpp
View file @
bed21b49
...
...
@@ -52,3 +52,8 @@ void QGCQmlWidgetHolder::setContextPropertyObject(const QString& name, QObject*
{
_ui
.
qmlWidget
->
rootContext
()
->
setContextProperty
(
name
,
object
);
}
QQmlContext
*
QGCQmlWidgetHolder
::
getRootContext
()
{
return
_ui
.
qmlWidget
->
rootContext
();
}
src/QGCQmlWidgetHolder.h
View file @
bed21b49
...
...
@@ -49,10 +49,13 @@ public:
/// Sets the UAS into the widget which in turn will load facts into the context
void
setAutoPilot
(
AutoPilotPlugin
*
autoPilot
);
/// Get Root Context
QQmlContext
*
getRootContext
();
/// Sets the QML into the control. Will display errors message box if error occurs loading source.
///
@return true: source loaded, false: source not loaded, errors occured
/// @return true: source loaded, false: source not loaded, errors occured
bool
setSource
(
const
QUrl
&
qmlUrl
);
void
setContextPropertyObject
(
const
QString
&
name
,
QObject
*
object
);
private:
...
...
src/QGCQmlWidgetHolder.ui
View file @
bed21b49
...
...
@@ -15,11 +15,20 @@
</property>
<layout
class=
"QVBoxLayout"
name=
"verticalLayout"
>
<item>
<widget
class=
"QGCQuickWidget"
name=
"qmlWidget"
native=
"true"
/>
<widget
class=
"QGCQuickWidget"
name=
"qmlWidget"
>
<property
name=
"acceptDrops"
>
<bool>
true
</bool>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>
QQuickWidget
</class>
<extends>
QWidget
</extends>
<header>
QQuickWidget
</header>
</customwidget>
<customwidget>
<class>
QGCQuickWidget
</class>
<extends>
QQuickWidget
</extends>
...
...
src/VehicleSetup/SetupViewTest.cc
View file @
bed21b49
...
...
@@ -65,6 +65,8 @@ void SetupViewTest::_clickThrough_test(void)
// Find the Setup button and click it
// Tool Bar is now a QQuickWidget and cannot be manipulated like below
#if 0
QGCToolBar* toolbar = _mainWindow->findChild<QGCToolBar*>();
Q_ASSERT(toolbar);
...
...
@@ -80,7 +82,7 @@ void SetupViewTest::_clickThrough_test(void)
Q_ASSERT(setupButton);
QTest::mouseClick(setupButton, Qt::LeftButton);
QTest::qWait(1000);
#endif
// Click through all the setup buttons
// FIXME: NYI
...
...
src/qgcunittest/MainWindowTest.cc
View file @
bed21b49
...
...
@@ -31,7 +31,8 @@
#include "MockLink.h"
#include "QGCMessageBox.h"
UT_REGISTER_TEST
(
MainWindowTest
)
// TODO: This needs to be changed to accomodate the new QML based tool bar
// UT_REGISTER_TEST(MainWindowTest)
MainWindowTest
::
MainWindowTest
(
void
)
{
...
...
@@ -66,6 +67,8 @@ void MainWindowTest::_connectWindowClose_test(MAV_AUTOPILOT autopilot)
linkMgr
->
connectLink
(
link
);
QTest
::
qWait
(
5000
);
// Give enough time for UI to settle and heartbeats to go through
// Tool Bar is now a QQuickWidget and cannot be manipulated like below
#if 0
// Click through all top level toolbar buttons
QGCToolBar* toolbar = _mainWindow->findChild<QGCToolBar*>();
Q_ASSERT(toolbar);
...
...
@@ -77,7 +80,8 @@ void MainWindowTest::_connectWindowClose_test(MAV_AUTOPILOT autopilot)
QTest::qWait(1000);
}
}
#endif
// On MainWindow close we should get a message box telling the user to disconnect first. Cancel should do nothing.
setExpectedMessageBox
(
QGCMessageBox
::
Cancel
);
_mainWindow
->
close
();
...
...
src/uas/UASMessageHandler.cc
View file @
bed21b49
...
...
@@ -43,6 +43,9 @@ IMPLEMENT_QGC_SINGLETON(UASMessageHandler, UASMessageHandler)
UASMessageHandler
::
UASMessageHandler
(
QObject
*
parent
)
:
QGCSingleton
(
parent
)
,
_activeUAS
(
NULL
)
,
_errorCount
(
0
)
,
_warningCount
(
0
)
,
_normalCount
(
0
)
{
connect
(
UASManager
::
instance
(),
SIGNAL
(
activeUASSet
(
UASInterface
*
)),
this
,
SLOT
(
setActiveUAS
(
UASInterface
*
)));
emit
textMessageReceived
(
NULL
);
...
...
@@ -60,6 +63,9 @@ void UASMessageHandler::clearMessages()
delete
_messages
.
last
();
_messages
.
pop_back
();
}
_errorCount
=
0
;
_warningCount
=
0
;
_normalCount
=
0
;
_mutex
.
unlock
();
}
...
...
@@ -83,15 +89,16 @@ void UASMessageHandler::setActiveUAS(UASInterface* uas)
}
}
void
UASMessageHandler
::
handleTextMessage
(
int
uasid
,
int
compId
,
int
severity
,
QString
text
)
void
UASMessageHandler
::
handleTextMessage
(
int
,
int
compId
,
int
severity
,
QString
text
)
{
Q_UNUSED
(
uasid
);
// Color the output depending on the message severity. We have 3 distinct cases:
// 1: If we have an ERROR or worse, make it bigger, bolder, and highlight it red.
// 2: If we have a warning or notice, just make it bold and color it orange.
// 3: Otherwise color it the standard color, white.
_mutex
.
lock
();
// So first determine the styling based on the severity.
QString
style
;
switch
(
severity
)
...
...
@@ -102,13 +109,16 @@ void UASMessageHandler::handleTextMessage(int uasid, int compId, int severity, Q
case
MAV_SEVERITY_ERROR
:
//Use set RGB values from given color from QGC
style
=
QString
(
"color: rgb(%1, %2, %3); font-weight:bold"
).
arg
(
QGC
::
colorRed
.
red
()).
arg
(
QGC
::
colorRed
.
green
()).
arg
(
QGC
::
colorRed
.
blue
());
_errorCount
++
;
break
;
case
MAV_SEVERITY_NOTICE
:
case
MAV_SEVERITY_WARNING
:
style
=
QString
(
"color: rgb(%1, %2, %3); font-weight:bold"
).
arg
(
QGC
::
colorOrange
.
red
()).
arg
(
QGC
::
colorOrange
.
green
()).
arg
(
QGC
::
colorOrange
.
blue
());
_warningCount
++
;
break
;
default:
style
=
QString
(
"color:white; font-weight:bold"
);
_normalCount
++
;
break
;
}
...
...
@@ -149,8 +159,31 @@ void UASMessageHandler::handleTextMessage(int uasid, int compId, int severity, Q
QString
dateString
=
QDateTime
::
currentDateTime
().
toString
(
"hh:mm:ss.zzz"
);
UASMessage
*
message
=
new
UASMessage
(
compId
,
severity
,
text
);
message
->
_setFormatedText
(
QString
(
"<p style=
\"
color:#CCCCCC
\"
>[%2 - COMP:%3]<font style=
\"
%1
\"
>%4 %5</font></p>"
).
arg
(
style
).
arg
(
dateString
).
arg
(
compId
).
arg
(
severityText
).
arg
(
text
));
_mutex
.
lock
();
_messages
.
append
(
message
);
_mutex
.
unlock
();
emit
textMessageReceived
(
message
);
}
int
UASMessageHandler
::
getErrorCount
()
{
_mutex
.
lock
();
int
c
=
_errorCount
;
_errorCount
=
0
;
_mutex
.
unlock
();
return
c
;
}
int
UASMessageHandler
::
getWarningCount
()
{
_mutex
.
lock
();
int
c
=
_warningCount
;
_warningCount
=
0
;
_mutex
.
unlock
();
return
c
;
}
int
UASMessageHandler
::
getNormalCount
()
{
_mutex
.
lock
();
int
c
=
_normalCount
;
_normalCount
=
0
;
_mutex
.
unlock
();
return
c
;
}
src/uas/UASMessageHandler.h
View file @
bed21b49
...
...
@@ -95,6 +95,18 @@ public:
* @brief Clear messages
*/
void
clearMessages
();
/**
* @brief Get error message count (Resets count once read)
*/
int
getErrorCount
();
/**
* @brief Get warning message count (Resets count once read)
*/
int
getWarningCount
();
/**
* @brief Get normal message count (Resets count once read)
*/
int
getNormalCount
();
public
slots
:
/**
* @brief Set currently active UAS
...
...
@@ -120,6 +132,9 @@ private:
UASInterface
*
_activeUAS
;
QVector
<
UASMessage
*>
_messages
;
QMutex
_mutex
;
int
_errorCount
;
int
_warningCount
;
int
_normalCount
;
};
#endif // QGCMESSAGEHANDLER_H
src/ui/MainWindow.cc
View file @
bed21b49
...
...
@@ -103,12 +103,9 @@ static MainWindow* _instance = NULL; ///< @brief MainWindow singleton
MainWindow
*
MainWindow
::
_create
(
QSplashScreen
*
splashScreen
)
{
Q_ASSERT
(
_instance
==
NULL
);
new
MainWindow
(
splashScreen
);
// _instance is set in constructor
Q_ASSERT
(
_instance
);
return
_instance
;
}
...
...
@@ -125,14 +122,15 @@ void MainWindow::deleteInstance(void)
/// @brief Private constructor for MainWindow. MainWindow singleton is only ever created
/// by MainWindow::_create method. Hence no other code should have access to
/// constructor.
MainWindow
::
MainWindow
(
QSplashScreen
*
splashScreen
)
:
centerStackActionGroup
(
new
QActionGroup
(
this
)),
autoReconnect
(
false
),
simulationLink
(
NULL
),
lowPowerMode
(
false
),
_currentView
(
VIEW_FLIGHT
),
_currentViewWidget
(
NULL
),
_splashScreen
(
splashScreen
)
MainWindow
::
MainWindow
(
QSplashScreen
*
splashScreen
)
:
_autoReconnect
(
false
)
,
_lowPowerMode
(
false
)
,
_centerStackActionGroup
(
new
QActionGroup
(
this
))
,
_simulationLink
(
NULL
)
,
_centralLayout
(
NULL
)
,
_currentViewWidget
(
NULL
)
,
_splashScreen
(
splashScreen
)
,
_currentView
(
VIEW_SETUP
)
{
Q_ASSERT
(
_instance
==
NULL
);
_instance
=
this
;
...
...
@@ -141,48 +139,19 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) :
connect
(
this
,
&
MainWindow
::
initStatusChanged
,
splashScreen
,
&
QSplashScreen
::
showMessage
);
}
// Setup user interface
loadSettings
();
// Select the proper view. Default to the flight view or load the last one used if it's supported.
VIEW_SECTIONS
currentViewCandidate
=
(
VIEW_SECTIONS
)
settings
.
value
(
"CURRENT_VIEW"
,
_currentView
).
toInt
();
switch
(
currentViewCandidate
)
{
case
VIEW_ENGINEER
:
case
VIEW_MISSION
:
case
VIEW_FLIGHT
:
case
VIEW_SIMULATION
:
case
VIEW_SETUP
:
case
VIEW_TERMINAL
:
#ifdef QGC_OSG_ENABLED
case
VIEW_LOCAL3D
:
#endif
#ifdef QGC_GOOGLE_EARTH_ENABLED
case
VIEW_GOOGLEEARTH
:
#endif
_currentView
=
currentViewCandidate
;
break
;
default:
// Leave _currentView to the default
break
;
}
// Put it back, which will set it to a valid value
settings
.
setValue
(
"CURRENT_VIEW"
,
_currentView
);
emit
initStatusChanged
(
tr
(
"Setting up user interface"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
// Setup user interface
ui
.
setupUi
(
this
);
_ui
.
setupUi
(
this
);
// Make sure tool bar elements all fit before changing minimum width
setMinimumWidth
(
926
);
configureWindowName
();
// Setup central widget with a layout to hold the views
_centralLayout
=
new
QVBoxLayout
();
centralWidget
()
->
setLayout
(
_centralLayout
);
// Set dock options
setDockOptions
(
AnimatedDocks
|
AllowTabbedDocks
|
AllowNestedDocks
);
configureWindowName
();
// Setup corners
setCorner
(
Qt
::
BottomRightCorner
,
Qt
::
BottomDockWidgetArea
);
...
...
@@ -195,51 +164,38 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) :
#ifdef UNITTEST_BUILD
QAction
*
qmlTestAction
=
new
QAction
(
"Test QML palette and controls"
,
NULL
);
connect
(
qmlTestAction
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
_showQmlTestWidget
);
ui
.
menuTools
->
addAction
(
qmlTestAction
);
_
ui
.
menuTools
->
addAction
(
qmlTestAction
);
#endif
// Setup UI state machines
centerStackActionGroup
->
setExclusive
(
true
);
// Load Toolbar
toolBar
=
new
QGCToolBar
(
this
);
this
->
addToolBar
(
toolBar
);
// Add the perspectives to the toolbar
QList
<
QAction
*>
actions
;
actions
<<
ui
.
actionSetup
;
actions
<<
ui
.
actionMissionView
;
actions
<<
ui
.
actionFlightView
;
actions
<<
ui
.
actionEngineersView
;
toolBar
->
setPerspectiveChangeActions
(
actions
);
// Add actions for advanced users (displayed in dropdown under "advanced")
QList
<
QAction
*>
advancedActions
;
advancedActions
<<
ui
.
actionGoogleEarthView
;
advancedActions
<<
ui
.
actionLocal3DView
;
advancedActions
<<
ui
.
actionTerminalView
;
advancedActions
<<
ui
.
actionSimulationView
;
toolBar
->
setPerspectiveChangeAdvancedActions
(
advancedActions
);
// Load QML Toolbar
QDockWidget
*
widget
=
new
QDockWidget
(
this
);
widget
->
setObjectName
(
"ToolBarDockWidget"
);
qmlRegisterType
<
MainToolBar
>
(
"QGroundControl.MainToolBar"
,
1
,
0
,
"MainToolBar"
);
_mainToolBar
=
new
MainToolBar
();
_mainToolBar
->
setParent
(
widget
);
_mainToolBar
->
setVisible
(
true
);
widget
->
setWidget
(
_mainToolBar
);
widget
->
setFeatures
(
QDockWidget
::
NoDockWidgetFeatures
);
widget
->
setTitleBarWidget
(
new
QWidget
(
this
));
// Disables the title bar
addDockWidget
(
Qt
::
TopDockWidgetArea
,
widget
);
// Setup UI state machines
_centerStackActionGroup
->
setExclusive
(
true
);
// Status Bar
setStatusBar
(
new
QStatusBar
(
this
));
statusBar
()
->
setSizeGripEnabled
(
true
);
emit
initStatusChanged
(
tr
(
"Building common widgets."
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
_buildCommonWidgets
();
emit
initStatusChanged
(
tr
(
"Building common actions"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
// Create actions
connectCommonActions
();
// Connect user interface devices
emit
initStatusChanged
(
tr
(
"Initializing joystick interface"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
joystick
=
new
JoystickInput
();
#ifdef QGC_MOUSE_ENABLED_WIN
emit
initStatusChanged
(
tr
(
"Initializing 3D mouse interface"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
mouseInput
=
new
Mouse3DInput
(
this
);
mouse
=
new
Mouse6dofInput
(
mouseInput
);
#endif //QGC_MOUSE_ENABLED_WIN
...
...
@@ -252,32 +208,27 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) :
#endif //QGC_MOUSE_ENABLED_LINUX
// Connect link
if
(
autoReconnect
)
if
(
_
autoReconnect
)
{
restoreLastUsedConnection
();
}
// Set low power mode
enableLowPowerMode
(
lowPowerMode
);
enableLowPowerMode
(
_lowPowerMode
);
emit
initStatusChanged
(
tr
(
"Restoring last view state"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
// Restore the window setup
_loadCurrentViewState
();
emit
initStatusChanged
(
tr
(
"Restoring last window size"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
// Restore the window position and size
if
(
settings
.
contains
(
getWindowGeometryKey
()))
emit
initStatusChanged
(
tr
(
"Restoring last window size"
),
Qt
::
AlignLeft
|
Qt
::
AlignBottom
,
QColor
(
62
,
93
,
141
));
if
(
settings
.
contains
(
_getWindowGeometryKey
()))
{
// Restore the window geometry
restoreGeometry
(
settings
.
value
(
getWindowGeometryKey
()).
toByteArray
());
restoreGeometry
(
settings
.
value
(
_getWindowGeometryKey
()).
toByteArray
());
}
else
{
// Adjust the size
const
int
screenWidth
=
QApplication
::
desktop
()
->
width
();
const
int
screenWidth
=
QApplication
::
desktop
()
->
width
();
const
int
screenHeight
=
QApplication
::
desktop
()
->
height
();
if
(
screenWidth
<
1500
)
{
resize
(
screenWidth
,
screenHeight
-
80
);
...
...
@@ -286,47 +237,45 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) :
{
resize
(
screenWidth
*
0.67
f
,
qMin
(
screenHeight
,
(
int
)(
screenWidth
*
0.67
f
*
0.67
f
)));
}
}
// Make sure the proper fullscreen/normal menu item is checked properly.
if
(
isFullScreen
())
{
ui
.
actionFullscreen
->
setChecked
(
true
);
ui
.
actionNormal
->
setChecked
(
false
);
_
ui
.
actionFullscreen
->
setChecked
(
true
);
_
ui
.
actionNormal
->
setChecked
(
false
);
}
else
{
ui
.
actionFullscreen
->
setChecked
(
false
);
ui
.
actionNormal
->
setChecked
(
true
);
_
ui
.
actionFullscreen
->
setChecked
(
false
);
_
ui
.
actionNormal
->
setChecked
(
true
);
}
// And that they will stay checked properly after user input
QObject
::
connect
(
ui
.
actionFullscreen
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
fullScreenActionItemCallback
()));
QObject
::
connect
(
ui
.
actionNormal
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
normalActionItemCallback
()));
QObject
::
connect
(
_ui
.
actionFullscreen
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
fullScreenActionItemCallback
()));
QObject
::
connect
(
_ui
.
actionNormal
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
normalActionItemCallback
()));
// Set OS dependent keyboard shortcuts for the main window, non OS dependent shortcuts are set in MainWindow.ui
#ifdef Q_OS_MACX
ui
.
actionSetup
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+1"
,
0
));
ui
.
actionMissionView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+2"
,
0
));
ui
.
actionFlightView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+3"
,
0
));
ui
.
actionEngineersView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+4"
,
0
));
ui
.
actionGoogleEarthView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+5"
,
0
));
ui
.
actionLocal3DView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+6"
,
0
));
ui
.
actionTerminalView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+7"
,
0
));
ui
.
actionSimulationView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+8"
,
0
));
ui
.
actionFullscreen
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+Return"
,
0
));
_
ui
.
actionSetup
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+1"
,
0
));
_
ui
.
actionMissionView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+2"
,
0
));
_
ui
.
actionFlightView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+3"
,
0
));
_
ui
.
actionEngineersView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+4"
,
0
));
_
ui
.
actionGoogleEarthView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+5"
,
0
));
_
ui
.
actionLocal3DView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+6"
,
0
));
_
ui
.
actionTerminalView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+7"
,
0
));
_
ui
.
actionSimulationView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+8"
,
0
));
_
ui
.
actionFullscreen
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Meta+Return"
,
0
));
#else
ui
.
actionSetup
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+1"
,
0
));
ui
.
actionMissionView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+2"
,
0
));
ui
.
actionFlightView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+3"
,
0
));
ui
.
actionEngineersView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+4"
,
0
));
ui
.
actionGoogleEarthView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+5"
,
0
));
ui
.
actionLocal3DView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+6"
,
0
));
ui
.
actionTerminalView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+7"
,
0
));
ui
.
actionSimulationView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+8"
,
0
));
ui
.
actionFullscreen
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+Return"
,
0
));
_
ui
.
actionSetup
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+1"
,
0
));
_
ui
.
actionMissionView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+2"
,
0
));
_
ui
.
actionFlightView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+3"
,
0
));
_
ui
.
actionEngineersView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+4"
,
0
));
_
ui
.
actionGoogleEarthView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+5"
,
0
));
_
ui
.
actionLocal3DView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+6"
,
0
));
_
ui
.
actionTerminalView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+7"
,
0
));
_
ui
.
actionSimulationView
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+8"
,
0
));
_
ui
.
actionFullscreen
->
setShortcut
(
QApplication
::
translate
(
"MainWindow"
,
"Ctrl+Return"
,
0
));
#endif
connect
(
&
windowNameUpdateTimer
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
configureWindowName
()));
...
...
@@ -335,15 +284,30 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) :
if
(
!
qgcApp
()
->
runningUnitTests
())
{
show
();
#ifdef Q_OS_MAC
// TODO HACK
// This is a really ugly hack. For whatever reason, by having a QQuickWidget inside a
// QDockWidget (MainToolBar above), the main menu is not shown when the app first
// starts. I looked everywhere and I could not find a solution. What I did notice was
// that if any other window gets focus, the menu comes up when you come back to QGC.
// That is, if you were to click on another window and then back to QGC, the menus
// would appear. This hack below creates a 0x0 dialog and immediately closes it.
// That works around the issue and it will do until I find the root of the problem.
QDialog
qd
(
this
);
qd
.
show
();
qd
.
raise
();
qd
.
activateWindow
();
qd
.
close
();
#endif
}
}
MainWindow
::~
MainWindow
()
{
if
(
simulationLink
)
if
(
_
simulationLink
)
{
delete
simulationLink
;
simulationLink
=
NULL
;
delete
_
simulationLink
;
_
simulationLink
=
NULL
;
}
if
(
joystick
)
{
...
...
@@ -352,13 +316,11 @@ MainWindow::~MainWindow()
delete
joystick
;
joystick
=
NULL
;
}
// Delete all UAS objects
for
(
int
i
=
0
;
i
<
commsWidgetList
.
size
();
i
++
)
for
(
int
i
=
0
;
i
<
_
commsWidgetList
.
size
();
i
++
)
{
commsWidgetList
[
i
]
->
deleteLater
();
_
commsWidgetList
[
i
]
->
deleteLater
();
}
_instance
=
NULL
;
}
...
...
@@ -367,7 +329,7 @@ void MainWindow::resizeEvent(QResizeEvent * event)
QMainWindow
::
resizeEvent
(
event
);
}
QString
MainWindow
::
getWindowStateKey
()
QString
MainWindow
::
_
getWindowStateKey
()
{
if
(
UASManager
::
instance
()
->
getActiveUAS
())
{
...
...
@@ -377,7 +339,7 @@ QString MainWindow::getWindowStateKey()
return
QString
::
number
(
_currentView
)
+
"_windowstate_"
;
}
QString
MainWindow
::
getWindowGeometryKey
()
QString
MainWindow
::
_
getWindowGeometryKey
()
{
return
"_geometry"
;
}
...
...
@@ -385,19 +347,15 @@ QString MainWindow::getWindowGeometryKey()
void
MainWindow
::
_buildCustomWidgets
(
void
)
{
Q_ASSERT
(
_customWidgets
.
count
()
==
0
);
// Create custom widgets
_customWidgets
=
QGCToolWidget
::
createWidgetsFromSettings
(
this
);
if
(
_customWidgets
.
size
()
>
0
)
{
ui
.
menuTools
->
addSeparator
();
_
ui
.
menuTools
->
addSeparator
();
}
foreach
(
QGCToolWidget
*
tool
,
_customWidgets
)
{
// Check if this widget already has a parent, do not create it in this case
QDockWidget
*
dock
=
dynamic_cast
<
QDockWidget
*>
(
tool
->
parentWidget
());
if
(
!
dock
)
{
_createDockWidget
(
tool
->
getTitle
(),
tool
->
objectName
(),
Qt
::
BottomDockWidgetArea
,
tool
);
}
...
...
@@ -407,43 +365,37 @@ void MainWindow::_buildCustomWidgets(void)
void
MainWindow
::
_createDockWidget
(
const
QString
&
title
,
const
QString
&
name
,
Qt
::
DockWidgetArea
area
,
QWidget
*
innerWidget
)
{
Q_ASSERT
(
!
_mapName2DockWidget
.
contains
(
name
));
QGCDockWidget
*
dockWidget
=
new
QGCDockWidget
(
title
,
this
);
Q_CHECK_PTR
(
dockWidget
);
dockWidget
->
setObjectName
(
name
);
dockWidget
->
setVisible
(
false
);
if
(
innerWidget
)
{
// Put inner widget inside QDockWidget
innerWidget
->
setParent
(
dockWidget
);
dockWidget
->
setWidget
(
innerWidget
);
innerWidget
->
setVisible
(
true
);
}
// Add to menu
QAction
*
action
=
new
QAction
(
title
,
NULL
);
action
->
setCheckable
(
true
);
action
->
setData
(
name
);
connect
(
action
,
&
QAction
::
triggered
,
this
,
&
MainWindow
::
_showDockWidgetAction
);
ui
.
menuTools
->
addAction
(
action
);
_ui
.
menuTools
->
addAction
(
action
);
_mapName2DockWidget
[
name
]
=
dockWidget
;
_mapDockWidget2Action
[
dockWidget
]
=
action
;
addDockWidget
(
area
,
dockWidget
);
}
void
MainWindow
::
_buildCommonWidgets
(
void
)
{
// Add generic MAVLink decoder
// TODO: This is never deleted
mavlinkDecoder
=
new
MAVLinkDecoder
(
MAVLinkProtocol
::
instance
(),
this
);
connect
(
mavlinkDecoder
,
SIGNAL
(
valueChanged
(
int
,
QString
,
QString
,
QVariant
,
quint64
)),
this
,
SIGNAL
(
valueChanged
(
int
,
QString
,
QString
,
QVariant
,
quint64
)));
// Log player
// TODO: Make this optional with a preferences setting or under a "View" menu
logPlayer
=
new
QGCMAVLinkLogPlayer
(
MAVLinkProtocol
::
instance
(),
statusBar
());
statusBar
()
->
addPermanentWidget
(
logPlayer
);
...
...
@@ -478,7 +430,6 @@ void MainWindow::_buildCommonWidgets(void)
for
(
size_t
i
=
0
;
i
<
cDockWidgetInfo
;
i
++
)
{
const
struct
DockWidgetInfo
*
pDockInfo
=
&
rgDockWidgetInfo
[
i
];
_createDockWidget
(
pDockInfo
->
title
,
pDockInfo
->
name
,
pDockInfo
->
area
,
NULL
/* no inner widget yet */
);
}
...
...
@@ -633,7 +584,6 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName)
if
(
widget
)
{
QDockWidget
*
dockWidget
=
_mapName2DockWidget
[
widgetName
];
Q_CHECK_PTR
(
dockWidget
);
widget
->
setParent
(
dockWidget
);
dockWidget
->
setWidget
(
widget
);
}
...
...
@@ -681,18 +631,17 @@ void MainWindow::_showHILConfigurationWidgets(void)
void
MainWindow
::
fullScreenActionItemCallback
()
{
ui
.
actionNormal
->
setChecked
(
false
);
_
ui
.
actionNormal
->
setChecked
(
false
);
}
void
MainWindow
::
normalActionItemCallback
()
{
ui
.
actionFullscreen
->
setChecked
(
false
);
_
ui
.
actionFullscreen
->
setChecked
(
false
);
}
void
MainWindow
::
closeEvent
(
QCloseEvent
*
event
)
{
// Disallow window close if there are active connections
bool
foundConnections
=
false
;
foreach
(
LinkInterface
*
link
,
LinkManager
::
instance
()
->
getLinks
())
{
if
(
link
->
isConnected
())
{
...
...
@@ -702,10 +651,12 @@ void MainWindow::closeEvent(QCloseEvent *event)
}
if
(
foundConnections
)
{
QGCMessageBox
::
StandardButton
button
=
QGCMessageBox
::
warning
(
tr
(
"QGroundControl close"
),
tr
(
"There are still active connections to vehicles. Do you want to disconnect these before closing?"
),
QMessageBox
::
Yes
|
QMessageBox
::
Cancel
,
QMessageBox
::
Cancel
);
QGCMessageBox
::
StandardButton
button
=
QGCMessageBox
::
warning
(
tr
(
"QGroundControl close"
),
tr
(
"There are still active connections to vehicles. Do you want to disconnect these before closing?"
),
QMessageBox
::
Yes
|
QMessageBox
::
Cancel
,
QMessageBox
::
Cancel
);
if
(
button
==
QMessageBox
::
Yes
)
{
foreach
(
LinkInterface
*
link
,
LinkManager
::
instance
()
->
getLinks
())
{
LinkManager
::
instance
()
->
disconnectLink
(
link
);
...
...
@@ -718,13 +669,11 @@ void MainWindow::closeEvent(QCloseEvent *event)
// This will process any remaining flight log save dialogs
qgcApp
()
->
processEvents
(
QEventLoop
::
ExcludeUserInputEvents
);
// Should not be any active connections
foreach
(
LinkInterface
*
link
,
LinkManager
::
instance
()
->
getLinks
())
{
Q_UNUSED
(
link
);
Q_ASSERT
(
!
link
->
isConnected
());
}
_storeCurrentViewState
();
storeSettings
();
UASManager
::
instance
()
->
storeSettings
();
...
...
@@ -736,7 +685,7 @@ void MainWindow::_createNewCustomWidget(void)
if
(
QGCToolWidget
::
instances
()
->
isEmpty
())
{
// This is the first widget
ui
.
menuTools
->
addSeparator
();
_
ui
.
menuTools
->
addSeparator
();
}
QString
objectName
;
int
customToolIndex
=
0
;
...
...
@@ -745,13 +694,10 @@ void MainWindow::_createNewCustomWidget(void)
++
customToolIndex
;
objectName
=
QString
(
"CUSTOM_TOOL_%1"
).
arg
(
customToolIndex
)
+
"DOCK"
;
}
while
(
QGCToolWidget
::
instances
()
->
contains
(
objectName
));
QString
title
=
tr
(
"Custom Tool %1"
).
arg
(
customToolIndex
);
QGCToolWidget
*
tool
=
new
QGCToolWidget
(
objectName
,
title
);
tool
->
resize
(
100
,
100
);
_createDockWidget
(
title
,
objectName
,
Qt
::
BottomDockWidgetArea
,
tool
);
_mapName2DockWidget
[
objectName
]
->
setVisible
(
true
);
}
...
...
@@ -778,31 +724,48 @@ void MainWindow::loadSettings()
// Why the screaming?
QSettings
settings
;
settings
.
beginGroup
(
MAIN_SETTINGS_GROUP
);
autoReconnect
=
settings
.
value
(
"AUTO_RECONNECT"
,
autoReconnect
).
toBool
();
lowPowerMode
=
settings
.
value
(
"LOW_POWER_MODE"
,
lowPowerMode
).
toBool
();
_autoReconnect
=
settings
.
value
(
"AUTO_RECONNECT"
,
_
autoReconnect
).
toBool
();
_lowPowerMode
=
settings
.
value
(
"LOW_POWER_MODE"
,
_
lowPowerMode
).
toBool
();
settings
.
endGroup
();
// Select the proper view. Default to the flight view or load the last one used if it's supported.
VIEW_SECTIONS
currentViewCandidate
=
(
VIEW_SECTIONS
)
settings
.
value
(
"CURRENT_VIEW"
,
_currentView
).
toInt
();
switch
(
currentViewCandidate
)
{
case
VIEW_ENGINEER
:
case
VIEW_MISSION
:
case
VIEW_FLIGHT
:
case
VIEW_SIMULATION
:
case
VIEW_SETUP
:
case
VIEW_TERMINAL
:
#ifdef QGC_OSG_ENABLED
case
VIEW_LOCAL3D
:
#endif
#ifdef QGC_GOOGLE_EARTH_ENABLED
case
VIEW_GOOGLEEARTH
:
#endif
_currentView
=
currentViewCandidate
;
break
;
default:
// Leave _currentView to the default
break
;
}
// Put it back, which will set it to a valid value
settings
.
setValue
(
"CURRENT_VIEW"
,
_currentView
);
}
void
MainWindow
::
storeSettings
()
{
QSettings
settings
;
settings
.
beginGroup
(
MAIN_SETTINGS_GROUP
);
settings
.
setValue
(
"AUTO_RECONNECT"
,
autoReconnect
);
settings
.
setValue
(
"LOW_POWER_MODE"
,
lowPowerMode
);
settings
.
setValue
(
"AUTO_RECONNECT"
,
_
autoReconnect
);
settings
.
setValue
(
"LOW_POWER_MODE"
,
_
lowPowerMode
);
settings
.
endGroup
();
settings
.
setValue
(
getWindowGeometryKey
(),
saveGeometry
());
settings
.
setValue
(
_getWindowGeometryKey
(),
saveGeometry
());
// Save the last current view in any case
settings
.
setValue
(
"CURRENT_VIEW"
,
_currentView
);
// Save the current window state, but only if a system is connected (else no real number of widgets would be present))
if
(
UASManager
::
instance
()
->
getUASList
().
length
()
>
0
)
settings
.
setValue
(
getWindowStateKey
(),
saveState
());
if
(
UASManager
::
instance
()
->
getUASList
().
length
()
>
0
)
settings
.
setValue
(
_getWindowStateKey
(),
saveState
());
// Save the current UAS view if a UAS is connected
if
(
UASManager
::
instance
()
->
getUASList
().
length
()
>
0
)
settings
.
setValue
(
"CURRENT_VIEW_WITH_UAS_CONNECTED"
,
_currentView
);
// And save any custom weidgets
QGCToolWidget
::
storeWidgetsToSettings
(
settings
);
}
...
...
@@ -812,9 +775,7 @@ void MainWindow::configureWindowName()
QList
<
QHostAddress
>
hostAddresses
=
QNetworkInterface
::
allAddresses
();
QString
windowname
=
qApp
->
applicationName
()
+
" "
+
qApp
->
applicationVersion
();
bool
prevAddr
=
false
;
windowname
.
append
(
" ("
+
QHostInfo
::
localHostName
()
+
": "
);
for
(
int
i
=
0
;
i
<
hostAddresses
.
size
();
i
++
)
{
// Exclude loopback IPv4 and all IPv6 addresses
...
...
@@ -825,18 +786,17 @@ void MainWindow::configureWindowName()
prevAddr
=
true
;
}
}
windowname
.
append
(
")"
);
setWindowTitle
(
windowname
);
}
// TODO: This is not used
void
MainWindow
::
startVideoCapture
()
{
// TODO: What is this? What kind of "Video" is saved to bmp?
QString
format
(
"bmp"
);
QString
initialPath
=
QDir
::
currentPath
()
+
tr
(
"/untitled."
)
+
format
;
QString
screenFileName
=
QGCFileDialog
::
getSaveFileName
(
_
screenFileName
=
QGCFileDialog
::
getSaveFileName
(
this
,
tr
(
"Save Video Capture"
),
initialPath
,
tr
(
"%1 Files (*.%2);;All Files (*)"
)
...
...
@@ -847,27 +807,27 @@ void MainWindow::startVideoCapture()
videoTimer
=
new
QTimer
(
this
);
}
// TODO: This is not used
void
MainWindow
::
stopVideoCapture
()
{
videoTimer
->
stop
();
// TODO Convert raw images to PNG
}
// TODO: This is not used
void
MainWindow
::
saveScreen
()
{
QPixmap
window
=
QPixmap
::
grabWindow
(
this
->
winId
());
QString
format
=
"bmp"
;
if
(
!
screenFileName
.
isEmpty
())
if
(
!
_screenFileName
.
isEmpty
())
{
window
.
save
(
screenFileName
,
format
.
toLatin1
());
window
.
save
(
_
screenFileName
,
format
.
toLatin1
());
}
}
void
MainWindow
::
enableAutoReconnect
(
bool
enabled
)
{
autoReconnect
=
enabled
;
_
autoReconnect
=
enabled
;
}
/**
...
...
@@ -877,143 +837,150 @@ void MainWindow::enableAutoReconnect(bool enabled)
void
MainWindow
::
connectCommonActions
()
{
// Bind together the perspective actions
QActionGroup
*
perspectives
=
new
QActionGroup
(
ui
.
menuPerspectives
);
perspectives
->
addAction
(
ui
.
actionEngineersView
);
perspectives
->
addAction
(
ui
.
actionFlightView
);
perspectives
->
addAction
(
ui
.
actionSimulationView
);
perspectives
->
addAction
(
ui
.
actionMissionView
);
perspectives
->
addAction
(
ui
.
actionSetup
);
perspectives
->
addAction
(
ui
.
actionTerminalView
);
perspectives
->
addAction
(
ui
.
actionGoogleEarthView
);
perspectives
->
addAction
(
ui
.
actionLocal3DView
);
QActionGroup
*
perspectives
=
new
QActionGroup
(
_
ui
.
menuPerspectives
);
perspectives
->
addAction
(
_
ui
.
actionEngineersView
);
perspectives
->
addAction
(
_
ui
.
actionFlightView
);
perspectives
->
addAction
(
_
ui
.
actionSimulationView
);
perspectives
->
addAction
(
_
ui
.
actionMissionView
);
perspectives
->
addAction
(
_
ui
.
actionSetup
);
perspectives
->
addAction
(
_
ui
.
actionTerminalView
);
perspectives
->
addAction
(
_
ui
.
actionGoogleEarthView
);
perspectives
->
addAction
(
_
ui
.
actionLocal3DView
);
perspectives
->
setExclusive
(
true
);
/* Hide the actions that are not relevant */
#ifndef QGC_GOOGLE_EARTH_ENABLED
ui
.
actionGoogleEarthView
->
setVisible
(
false
);
_
ui
.
actionGoogleEarthView
->
setVisible
(
false
);
#endif
#ifndef QGC_OSG_ENABLED
ui
.
actionLocal3DView
->
setVisible
(
false
);
_
ui
.
actionLocal3DView
->
setVisible
(
false
);
#endif
// Mark the right one as selected
if
(
_currentView
==
VIEW_ENGINEER
)
{
ui
.
actionEngineersView
->
setChecked
(
true
);
ui
.
actionEngineersView
->
activate
(
QAction
::
Trigger
);
_
ui
.
actionEngineersView
->
setChecked
(
true
);
_
ui
.
actionEngineersView
->
activate
(
QAction
::
Trigger
);
}
if
(
_currentView
==
VIEW_FLIGHT
)
{
ui
.
actionFlightView
->
setChecked
(
true
);
ui
.
actionFlightView
->
activate
(
QAction
::
Trigger
);
_
ui
.
actionFlightView
->
setChecked
(
true
);
_
ui
.
actionFlightView
->
activate
(
QAction
::
Trigger
);
}
if
(
_currentView
==
VIEW_SIMULATION
)
{
ui
.
actionSimulationView
->
setChecked
(
true
);
ui
.
actionSimulationView
->
activate
(
QAction
::
Trigger
);
_
ui
.
actionSimulationView
->
setChecked
(
true
);
_
ui
.
actionSimulationView
->
activate
(
QAction
::
Trigger
);
}
if
(
_currentView
==
VIEW_MISSION
)
{
ui
.
actionMissionView
->
setChecked
(
true
);
ui
.
actionMissionView
->
activate
(
QAction
::
Trigger
);
_
ui
.
actionMissionView
->
setChecked
(
true
);
_
ui
.
actionMissionView
->
activate
(
QAction
::
Trigger
);
}
if
(
_currentView
==
VIEW_SETUP
)
{
ui
.
actionSetup
->
setChecked
(
true
);
ui
.
actionSetup
->
activate
(
QAction
::
Trigger
);
_
ui
.
actionSetup
->
setChecked
(
true
);
_
ui
.
actionSetup
->
activate
(
QAction
::
Trigger
);
}
if
(
_currentView
==
VIEW_TERMINAL
)
{
ui
.
actionTerminalView
->
setChecked
(
true
);
ui
.
actionTerminalView
->
activate
(
QAction
::
Trigger
);
_
ui
.
actionTerminalView
->
setChecked
(
true
);
_
ui
.
actionTerminalView
->
activate
(
QAction
::
Trigger
);
}
if
(
_currentView
==
VIEW_GOOGLEEARTH
)
{
ui
.
actionGoogleEarthView
->
setChecked
(
true
);
ui
.
actionGoogleEarthView
->
activate
(
QAction
::
Trigger
);
_
ui
.
actionGoogleEarthView
->
setChecked
(
true
);
_
ui
.
actionGoogleEarthView
->
activate
(
QAction
::
Trigger
);
}
if
(
_currentView
==
VIEW_LOCAL3D
)
{
ui
.
actionLocal3DView
->
setChecked
(
true
);
ui
.
actionLocal3DView
->
activate
(
QAction
::
Trigger
);
_
ui
.
actionLocal3DView
->
setChecked
(
true
);
_
ui
.
actionLocal3DView
->
activate
(
QAction
::
Trigger
);
}
// The UAS actions are not enabled without connection to system
ui
.
actionLiftoff
->
setEnabled
(
false
);
ui
.
actionLand
->
setEnabled
(
false
);
ui
.
actionEmergency_Kill
->
setEnabled
(
false
);
ui
.
actionEmergency_Land
->
setEnabled
(
false
);
ui
.
actionShutdownMAV
->
setEnabled
(
false
);
_
ui
.
actionLiftoff
->
setEnabled
(
false
);
_
ui
.
actionLand
->
setEnabled
(
false
);
_
ui
.
actionEmergency_Kill
->
setEnabled
(
false
);
_
ui
.
actionEmergency_Land
->
setEnabled
(
false
);
_
ui
.
actionShutdownMAV
->
setEnabled
(
false
);
// Connect actions from ui
connect
(
ui
.
actionAdd_Link
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
manageLinks
()));
connect
(
_
ui
.
actionAdd_Link
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
manageLinks
()));
// Connect internal actions
connect
(
UASManager
::
instance
(),
SIGNAL
(
UASCreated
(
UASInterface
*
)),
this
,
SLOT
(
UASCreated
(
UASInterface
*
)));
connect
(
UASManager
::
instance
(),
SIGNAL
(
activeUASSet
(
UASInterface
*
)),
this
,
SLOT
(
setActiveUAS
(
UASInterface
*
)));
// Unmanned System controls
connect
(
ui
.
actionLiftoff
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
launchActiveUAS
()));
connect
(
ui
.
actionLand
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
returnActiveUAS
()));
connect
(
ui
.
actionEmergency_Land
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
stopActiveUAS
()));
connect
(
ui
.
actionEmergency_Kill
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
killActiveUAS
()));
connect
(
ui
.
actionShutdownMAV
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
shutdownActiveUAS
()));
connect
(
_
ui
.
actionLiftoff
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
launchActiveUAS
()));
connect
(
_
ui
.
actionLand
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
returnActiveUAS
()));
connect
(
_
ui
.
actionEmergency_Land
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
stopActiveUAS
()));
connect
(
_
ui
.
actionEmergency_Kill
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
killActiveUAS
()));
connect
(
_
ui
.
actionShutdownMAV
,
SIGNAL
(
triggered
()),
UASManager
::
instance
(),
SLOT
(
shutdownActiveUAS
()));
// Views actions
connect
(
ui
.
actionFlightView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadPilotView
()));
connect
(
ui
.
actionSimulationView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadSimulationView
()));
connect
(
ui
.
actionEngineersView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadEngineerView
()));
connect
(
ui
.
actionMissionView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadOperatorView
()));
connect
(
ui
.
actionSetup
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadSetupView
()));
connect
(
ui
.
actionGoogleEarthView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadGoogleEarthView
()));
connect
(
ui
.
actionLocal3DView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadLocal3DView
()));
connect
(
ui
.
actionTerminalView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadTerminalView
()));
connect
(
_
ui
.
actionFlightView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadPilotView
()));
connect
(
_
ui
.
actionSimulationView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadSimulationView
()));
connect
(
_
ui
.
actionEngineersView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadEngineerView
()));
connect
(
_
ui
.
actionMissionView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadOperatorView
()));
connect
(
_
ui
.
actionSetup
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadSetupView
()));
connect
(
_
ui
.
actionGoogleEarthView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadGoogleEarthView
()));
connect
(
_
ui
.
actionLocal3DView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadLocal3DView
()));
connect
(
_
ui
.
actionTerminalView
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
loadTerminalView
()));
// Help Actions
connect
(
ui
.
actionOnline_Documentation
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
showHelp
()));
connect
(
ui
.
actionDeveloper_Credits
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
showCredits
()));
connect
(
ui
.
actionProject_Roadmap
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
showRoadMap
()));
connect
(
_
ui
.
actionOnline_Documentation
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
showHelp
()));
connect
(
_
ui
.
actionDeveloper_Credits
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
showCredits
()));
connect
(
_
ui
.
actionProject_Roadmap
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
showRoadMap
()));
// Custom widget actions
connect
(
ui
.
actionNewCustomWidget
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
_createNewCustomWidget
()));
connect
(
ui
.
actionLoadCustomWidgetFile
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
_loadCustomWidgetFromFile
()));
connect
(
_
ui
.
actionNewCustomWidget
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
_createNewCustomWidget
()));
connect
(
_
ui
.
actionLoadCustomWidgetFile
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
_loadCustomWidgetFromFile
()));
// Audio output
ui
.
actionMuteAudioOutput
->
setChecked
(
GAudioOutput
::
instance
()
->
isMuted
());
connect
(
GAudioOutput
::
instance
(),
SIGNAL
(
mutedChanged
(
bool
)),
ui
.
actionMuteAudioOutput
,
SLOT
(
setChecked
(
bool
)));
connect
(
ui
.
actionMuteAudioOutput
,
SIGNAL
(
triggered
(
bool
)),
GAudioOutput
::
instance
(),
SLOT
(
mute
(
bool
)));
_
ui
.
actionMuteAudioOutput
->
setChecked
(
GAudioOutput
::
instance
()
->
isMuted
());
connect
(
GAudioOutput
::
instance
(),
SIGNAL
(
mutedChanged
(
bool
)),
_
ui
.
actionMuteAudioOutput
,
SLOT
(
setChecked
(
bool
)));
connect
(
_
ui
.
actionMuteAudioOutput
,
SIGNAL
(
triggered
(
bool
)),
GAudioOutput
::
instance
(),
SLOT
(
mute
(
bool
)));
// Application Settings
connect
(
ui
.
actionSettings
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
showSettings
()));
connect
(
_
ui
.
actionSettings
,
SIGNAL
(
triggered
()),
this
,
SLOT
(
showSettings
()));
connect
(
ui
.
actionSimulate
,
SIGNAL
(
triggered
(
bool
)),
this
,
SLOT
(
simulateLink
(
bool
)));
connect
(
_ui
.
actionSimulate
,
SIGNAL
(
triggered
(
bool
)),
this
,
SLOT
(
simulateLink
(
bool
)));
// Update Tool Bar
_mainToolBar
->
setCurrentView
((
MainToolBar
::
ViewType_t
)
_currentView
);
}
void
MainWindow
::
_openUrl
(
const
QString
&
url
,
const
QString
&
errorMessage
)
{
if
(
!
QDesktopServices
::
openUrl
(
QUrl
(
url
)))
{
QMessageBox
::
critical
(
this
,
tr
(
"Could not open information in browser"
),
errorMessage
);
QMessageBox
::
critical
(
this
,
tr
(
"Could not open information in browser"
),
errorMessage
);
}
}
void
MainWindow
::
showHelp
()
{
_openUrl
(
"http://qgroundcontrol.org/users/start"
,
tr
(
"To get to the online help, please open http://qgroundcontrol.org/user_guide in a browser."
));
_openUrl
(
"http://qgroundcontrol.org/users/start"
,
tr
(
"To get to the online help, please open http://qgroundcontrol.org/user_guide in a browser."
));
}
void
MainWindow
::
showCredits
()
{
_openUrl
(
"http://qgroundcontrol.org/credits"
,
tr
(
"To get to the credits, please open http://qgroundcontrol.org/credits in a browser."
));
_openUrl
(
"http://qgroundcontrol.org/credits"
,
tr
(
"To get to the credits, please open http://qgroundcontrol.org/credits in a browser."
));
}
void
MainWindow
::
showRoadMap
()
{
_openUrl
(
"http://qgroundcontrol.org/dev/roadmap"
,
tr
(
"To get to the online help, please open http://qgroundcontrol.org/roadmap in a browser."
));
_openUrl
(
"http://qgroundcontrol.org/dev/roadmap"
,
tr
(
"To get to the online help, please open http://qgroundcontrol.org/roadmap in a browser."
));
}
void
MainWindow
::
showSettings
()
...
...
@@ -1022,38 +989,16 @@ void MainWindow::showSettings()
settings
.
exec
();
}
bool
MainWindow
::
configLink
(
LinkInterface
*
link
)
{
// Go searching for this link's configuration window
QList
<
QAction
*>
actions
=
ui
.
menuNetwork
->
actions
();
bool
found
(
false
);
const
int32_t
&
linkIndex
(
LinkManager
::
instance
()
->
getLinks
().
indexOf
(
link
));
const
int32_t
&
linkID
(
LinkManager
::
instance
()
->
getLinks
()[
linkIndex
]
->
getId
());
foreach
(
QAction
*
action
,
actions
)
{
if
(
action
->
data
().
toInt
()
==
linkID
)
{
found
=
true
;
action
->
trigger
();
// Show the Link Config Dialog
}
}
return
found
;
}
void
MainWindow
::
simulateLink
(
bool
simulate
)
{
if
(
simulate
)
{
if
(
!
simulationLink
)
{
simulationLink
=
new
MAVLinkSimulationLink
(
":/demo-log.txt"
);
Q_CHECK_PTR
(
simulationLink
);
if
(
!
_
simulationLink
)
{
_
simulationLink
=
new
MAVLinkSimulationLink
(
":/demo-log.txt"
);
Q_CHECK_PTR
(
_
simulationLink
);
}
LinkManager
::
instance
()
->
connectLink
(
simulationLink
);
LinkManager
::
instance
()
->
connectLink
(
_
simulationLink
);
}
else
{
Q_ASSERT
(
simulationLink
);
LinkManager
::
instance
()
->
disconnectLink
(
simulationLink
);
Q_ASSERT
(
_
simulationLink
);
LinkManager
::
instance
()
->
disconnectLink
(
_
simulationLink
);
}
}
...
...
@@ -1061,21 +1006,19 @@ void MainWindow::commsWidgetDestroyed(QObject *obj)
{
// Do not dynamic cast or de-reference QObject, since object is either in destructor or may have already
// been destroyed.
if
(
commsWidgetList
.
contains
(
obj
))
if
(
_commsWidgetList
.
contains
(
obj
))
{
commsWidgetList
.
removeOne
(
obj
);
_
commsWidgetList
.
removeOne
(
obj
);
}
}
void
MainWindow
::
setActiveUAS
(
UASInterface
*
uas
)
{
Q_UNUSED
(
uas
);
if
(
settings
.
contains
(
getWindowStateKey
()))
if
(
settings
.
contains
(
_
getWindowStateKey
()))
{
restoreState
(
settings
.
value
(
getWindowStateKey
()).
toByteArray
());
restoreState
(
settings
.
value
(
_
getWindowStateKey
()).
toByteArray
());
}
}
void
MainWindow
::
UASSpecsChanged
(
int
uas
)
...
...
@@ -1087,74 +1030,11 @@ void MainWindow::UASSpecsChanged(int uas)
void
MainWindow
::
UASCreated
(
UASInterface
*
uas
)
{
// The UAS actions are not enabled without connection to system
ui
.
actionLiftoff
->
setEnabled
(
true
);
ui
.
actionLand
->
setEnabled
(
true
);
ui
.
actionEmergency_Kill
->
setEnabled
(
true
);
ui
.
actionEmergency_Land
->
setEnabled
(
true
);
ui
.
actionShutdownMAV
->
setEnabled
(
true
);
QIcon
icon
;
// Set matching icon
switch
(
uas
->
getSystemType
())
{
case
MAV_TYPE_GENERIC
:
icon
=
QIcon
(
":files/images/mavs/generic.svg"
);
break
;
case
MAV_TYPE_FIXED_WING
:
icon
=
QIcon
(
":files/images/mavs/fixed-wing.svg"
);
break
;
case
MAV_TYPE_QUADROTOR
:
icon
=
QIcon
(
":files/images/mavs/quadrotor.svg"
);
break
;
case
MAV_TYPE_COAXIAL
:
icon
=
QIcon
(
":files/images/mavs/coaxial.svg"
);
break
;
case
MAV_TYPE_HELICOPTER
:
icon
=
QIcon
(
":files/images/mavs/helicopter.svg"
);
break
;
case
MAV_TYPE_ANTENNA_TRACKER
:
icon
=
QIcon
(
":files/images/mavs/antenna-tracker.svg"
);
break
;
case
MAV_TYPE_GCS
:
icon
=
QIcon
(
":files/images/mavs/groundstation.svg"
);
break
;
case
MAV_TYPE_AIRSHIP
:
icon
=
QIcon
(
":files/images/mavs/airship.svg"
);
break
;
case
MAV_TYPE_FREE_BALLOON
:
icon
=
QIcon
(
":files/images/mavs/free-balloon.svg"
);
break
;
case
MAV_TYPE_ROCKET
:
icon
=
QIcon
(
":files/images/mavs/rocket.svg"
);
break
;
case
MAV_TYPE_GROUND_ROVER
:
icon
=
QIcon
(
":files/images/mavs/ground-rover.svg"
);
break
;
case
MAV_TYPE_SURFACE_BOAT
:
icon
=
QIcon
(
":files/images/mavs/surface-boat.svg"
);
break
;
case
MAV_TYPE_SUBMARINE
:
icon
=
QIcon
(
":files/images/mavs/submarine.svg"
);
break
;
case
MAV_TYPE_HEXAROTOR
:
icon
=
QIcon
(
":files/images/mavs/hexarotor.svg"
);
break
;
case
MAV_TYPE_OCTOROTOR
:
icon
=
QIcon
(
":files/images/mavs/octorotor.svg"
);
break
;
case
MAV_TYPE_TRICOPTER
:
icon
=
QIcon
(
":files/images/mavs/tricopter.svg"
);
break
;
case
MAV_TYPE_FLAPPING_WING
:
icon
=
QIcon
(
":files/images/mavs/flapping-wing.svg"
);
break
;
case
MAV_TYPE_KITE
:
icon
=
QIcon
(
":files/images/mavs/kite.svg"
);
break
;
default:
icon
=
QIcon
(
":files/images/mavs/unknown.svg"
);
break
;
}
_ui
.
actionLiftoff
->
setEnabled
(
true
);
_ui
.
actionLand
->
setEnabled
(
true
);
_ui
.
actionEmergency_Kill
->
setEnabled
(
true
);
_ui
.
actionEmergency_Land
->
setEnabled
(
true
);
_ui
.
actionShutdownMAV
->
setEnabled
(
true
);
connect
(
uas
,
SIGNAL
(
systemSpecsChanged
(
int
)),
this
,
SLOT
(
UASSpecsChanged
(
int
)));
connect
(
uas
,
SIGNAL
(
valueChanged
(
int
,
QString
,
QString
,
QVariant
,
quint64
)),
this
,
SIGNAL
(
valueChanged
(
int
,
QString
,
QString
,
QVariant
,
quint64
)));
...
...
@@ -1190,9 +1070,7 @@ void MainWindow::_storeCurrentViewState(void)
{
// HIL dock widgets are dynamic and are not part of the saved state
_hideAllHilDockWidgets
();
// Save list of visible widgets
bool
firstWidget
=
true
;
QString
widgetNames
=
""
;
foreach
(
QDockWidget
*
dockWidget
,
_mapName2DockWidget
)
{
...
...
@@ -1204,10 +1082,9 @@ void MainWindow::_storeCurrentViewState(void)
firstWidget
=
false
;
}
}
settings
.
setValue
(
getWindowStateKey
()
+
"WIDGETS"
,
widgetNames
);
settings
.
setValue
(
getWindowStateKey
(),
saveState
());
settings
.
setValue
(
getWindowGeometryKey
(),
saveGeometry
());
settings
.
setValue
(
_getWindowStateKey
()
+
"WIDGETS"
,
widgetNames
);
settings
.
setValue
(
_getWindowStateKey
(),
saveState
());
settings
.
setValue
(
_getWindowGeometryKey
(),
saveGeometry
());
}
/// Restores the state of the toolbar, status bar and widgets associated with the current view
...
...
@@ -1282,7 +1159,7 @@ void MainWindow::_loadCurrentViewState(void)
_hideAllDockWidgets
();
// Restore the widgets for the new view
QString
widgetNames
=
settings
.
value
(
getWindowStateKey
()
+
"WIDGETS"
,
defaultWidgets
).
toString
();
QString
widgetNames
=
settings
.
value
(
_
getWindowStateKey
()
+
"WIDGETS"
,
defaultWidgets
).
toString
();
if
(
!
widgetNames
.
isEmpty
())
{
QStringList
split
=
widgetNames
.
split
(
","
);
foreach
(
QString
widgetName
,
split
)
{
...
...
@@ -1291,8 +1168,8 @@ void MainWindow::_loadCurrentViewState(void)
}
}
if
(
settings
.
contains
(
getWindowStateKey
()))
{
restoreState
(
settings
.
value
(
getWindowStateKey
()).
toByteArray
());
if
(
settings
.
contains
(
_
getWindowStateKey
()))
{
restoreState
(
settings
.
value
(
_
getWindowStateKey
()).
toByteArray
());
}
// HIL dock widget are dynamic and don't take part in the saved window state, so this
...
...
@@ -1312,7 +1189,6 @@ void MainWindow::_hideAllDockWidgets(void)
foreach
(
QDockWidget
*
dockWidget
,
_mapName2DockWidget
)
{
dockWidget
->
setVisible
(
false
);
}
_hideAllHilDockWidgets
();
}
...
...
@@ -1320,7 +1196,6 @@ void MainWindow::_showDockWidgetAction(bool show)
{
QAction
*
action
=
dynamic_cast
<
QAction
*>
(
QObject
::
sender
());
Q_ASSERT
(
action
);
_showDockWidget
(
action
->
data
().
toString
(),
show
);
}
...
...
@@ -1328,7 +1203,6 @@ void MainWindow::_showDockWidgetAction(bool show)
void
MainWindow
::
handleMisconfiguration
(
UASInterface
*
uas
)
{
static
QTime
lastTime
;
// We have to debounce this signal
if
(
!
lastTime
.
isValid
())
{
lastTime
.
start
();
...
...
@@ -1338,16 +1212,16 @@ void MainWindow::handleMisconfiguration(UASInterface* uas)
return
;
}
}
// Ask user if he wants to handle this now
QMessageBox
::
StandardButton
button
=
QGCMessageBox
::
question
(
tr
(
"Missing or Invalid Onboard Configuration"
),
tr
(
"The onboard system configuration is missing or incomplete. Do you want to resolve this now?"
),
QMessageBox
::
Ok
|
QMessageBox
::
Cancel
,
QMessageBox
::
Ok
);
// Ask user if they want to handle this now
QMessageBox
::
StandardButton
button
=
QGCMessageBox
::
question
(
tr
(
"Missing or Invalid Onboard Configuration"
),
tr
(
"The onboard system configuration is missing or incomplete. Do you want to resolve this now?"
),
QMessageBox
::
Ok
|
QMessageBox
::
Cancel
,
QMessageBox
::
Ok
);
if
(
button
==
QMessageBox
::
Ok
)
{
//
He wants
to handle it, make sure this system is selected
//
They want
to handle it, make sure this system is selected
UASManager
::
instance
()
->
setActiveUAS
(
uas
);
// Flick to config view
loadSetupView
();
}
...
...
@@ -1359,7 +1233,7 @@ void MainWindow::loadEngineerView()
{
_storeCurrentViewState
();
_currentView
=
VIEW_ENGINEER
;
ui
.
actionEngineersView
->
setChecked
(
true
);
_
ui
.
actionEngineersView
->
setChecked
(
true
);
_loadCurrentViewState
();
}
}
...
...
@@ -1370,7 +1244,7 @@ void MainWindow::loadOperatorView()
{
_storeCurrentViewState
();
_currentView
=
VIEW_MISSION
;
ui
.
actionMissionView
->
setChecked
(
true
);
_
ui
.
actionMissionView
->
setChecked
(
true
);
_loadCurrentViewState
();
}
}
...
...
@@ -1380,7 +1254,7 @@ void MainWindow::loadSetupView()
{
_storeCurrentViewState
();
_currentView
=
VIEW_SETUP
;
ui
.
actionSetup
->
setChecked
(
true
);
_
ui
.
actionSetup
->
setChecked
(
true
);
_loadCurrentViewState
();
}
}
...
...
@@ -1391,7 +1265,7 @@ void MainWindow::loadTerminalView()
{
_storeCurrentViewState
();
_currentView
=
VIEW_TERMINAL
;
ui
.
actionTerminalView
->
setChecked
(
true
);
_
ui
.
actionTerminalView
->
setChecked
(
true
);
_loadCurrentViewState
();
}
}
...
...
@@ -1402,7 +1276,7 @@ void MainWindow::loadGoogleEarthView()
{
_storeCurrentViewState
();
_currentView
=
VIEW_GOOGLEEARTH
;
ui
.
actionGoogleEarthView
->
setChecked
(
true
);
_
ui
.
actionGoogleEarthView
->
setChecked
(
true
);
_loadCurrentViewState
();
}
}
...
...
@@ -1413,7 +1287,7 @@ void MainWindow::loadLocal3DView()
{
_storeCurrentViewState
();
_currentView
=
VIEW_LOCAL3D
;
ui
.
actionLocal3DView
->
setChecked
(
true
);
_
ui
.
actionLocal3DView
->
setChecked
(
true
);
_loadCurrentViewState
();
}
}
...
...
@@ -1424,7 +1298,7 @@ void MainWindow::loadPilotView()
{
_storeCurrentViewState
();
_currentView
=
VIEW_FLIGHT
;
ui
.
actionFlightView
->
setChecked
(
true
);
_
ui
.
actionFlightView
->
setChecked
(
true
);
_loadCurrentViewState
();
}
}
...
...
@@ -1435,14 +1309,14 @@ void MainWindow::loadSimulationView()
{
_storeCurrentViewState
();
_currentView
=
VIEW_SIMULATION
;
ui
.
actionSimulationView
->
setChecked
(
true
);
_
ui
.
actionSimulationView
->
setChecked
(
true
);
_loadCurrentViewState
();
}
}
QList
<
QAction
*>
MainWindow
::
listLinkMenuActions
()
{
return
ui
.
menuNetwork
->
actions
();
return
_
ui
.
menuNetwork
->
actions
();
}
/// @brief Hides the spash screen if it is currently being shown
...
...
src/ui/MainWindow.h
View file @
bed21b49
...
...
@@ -30,6 +30,7 @@ This file is part of the QGROUNDCONTROL project
#ifndef _MAINWINDOW_H_
#define _MAINWINDOW_H_
#include <QMainWindow>
#include <QStatusBar>
#include <QStackedWidget>
...
...
@@ -59,6 +60,7 @@ This file is part of the QGROUNDCONTROL project
#ifdef QGC_GOOGLE_EARTH_ENABLED
#include "QGCGoogleEarthView.h"
#endif
#include "MainToolBar.h"
#include "QGCToolBar.h"
#include "LogCompressor.h"
...
...
@@ -76,7 +78,6 @@ class QSplashScreen;
class
QGCStatusBar
;
class
Linecharts
;
class
QGCDataPlot2D
;
class
MenuActionHelper
;
class
QGCUASFileViewMulti
;
/**
...
...
@@ -85,6 +86,7 @@ class QGCUASFileViewMulti;
**/
class
MainWindow
:
public
QMainWindow
{
friend
class
MainToolBar
;
Q_OBJECT
public:
...
...
@@ -107,13 +109,13 @@ public:
/** @brief Get auto link reconnect setting */
bool
autoReconnectEnabled
()
const
{
return
autoReconnect
;
return
_
autoReconnect
;
}
/** @brief Get low power mode setting */
bool
lowPowerModeEnabled
()
const
{
return
lowPowerMode
;
return
_
lowPowerMode
;
}
QList
<
QAction
*>
listLinkMenuActions
();
...
...
@@ -130,7 +132,6 @@ public:
public
slots
:
/** @brief Show the application settings */
void
showSettings
();
bool
configLink
(
LinkInterface
*
link
);
/** @brief Simulate a link */
void
simulateLink
(
bool
simulate
);
/** @brief Set the currently controlled UAS */
...
...
@@ -177,7 +178,7 @@ public slots:
void
enableAutoReconnect
(
bool
enabled
);
/** @brief Save power by reducing update rates */
void
enableLowPowerMode
(
bool
enabled
)
{
lowPowerMode
=
enabled
;
}
void
enableLowPowerMode
(
bool
enabled
)
{
_
lowPowerMode
=
enabled
;
}
void
closeEvent
(
QCloseEvent
*
event
);
...
...
@@ -242,7 +243,6 @@ protected:
LinkInterface
*
udpLink
;
QSettings
settings
;
QActionGroup
*
centerStackActionGroup
;
// Center widgets
QPointer
<
Linecharts
>
linechartWidget
;
...
...
@@ -254,6 +254,7 @@ protected:
#endif
QPointer
<
QGCFirmwareUpdate
>
firmwareUpdateWidget
;
QPointer
<
MainToolBar
>
_mainToolBar
;
QPointer
<
QGCToolBar
>
toolBar
;
QPointer
<
QDockWidget
>
mavlinkInspectorWidget
;
...
...
@@ -288,11 +289,7 @@ protected:
LogCompressor
*
comp
;
QString
screenFileName
;
QTimer
*
videoTimer
;
bool
autoReconnect
;
MAVLinkSimulationLink
*
simulationLink
;
bool
lowPowerMode
;
///< If enabled, QGC reduces the update rates of all widgets
QGCFlightGearLink
*
fgLink
;
QTimer
windowNameUpdateTimer
;
...
...
@@ -320,9 +317,6 @@ private:
QPointer
<
QWidget
>
_googleEarthView
;
QPointer
<
QWidget
>
_local3DView
;
VIEW_SECTIONS
_currentView
;
///< Currently displayed view
QWidget
*
_currentViewWidget
;
///< Currently displayed view widget
// Dock widget names
static
const
char
*
_uasControlDockWidgetName
;
static
const
char
*
_uasListDockWidgetName
;
...
...
@@ -365,20 +359,23 @@ private:
void
_showDockWidget
(
const
QString
&
name
,
bool
show
);
void
_showHILConfigurationWidgets
(
void
);
QList
<
QGCToolWidget
*>
_customWidgets
;
QVBoxLayout
*
_centralLayout
;
QList
<
QObject
*>
commsWidgetList
;
MenuActionHelper
*
menuActionHelper
;
Ui
::
MainWindow
ui
;
bool
_autoReconnect
;
bool
_lowPowerMode
;
///< If enabled, QGC reduces the update rates of all widgets
QActionGroup
*
_centerStackActionGroup
;
MAVLinkSimulationLink
*
_simulationLink
;
QList
<
QGCToolWidget
*>
_customWidgets
;
QVBoxLayout
*
_centralLayout
;
QList
<
QObject
*>
_commsWidgetList
;
QWidget
*
_currentViewWidget
;
///< Currently displayed view widget
QSplashScreen
*
_splashScreen
;
///< Splash screen, NULL is splash screen not currently being shown
VIEW_SECTIONS
_currentView
;
///< Currently displayed view
Ui
::
MainWindow
_ui
;
QString
_screenFileName
;
QString
getWindowStateKey
();
QString
getWindowGeometryKey
();
QString
_
getWindowStateKey
();
QString
_
getWindowGeometryKey
();
QSplashScreen
*
_splashScreen
;
///< Splash screen, NULL is splash screen not currently being shown
friend
class
MenuActionHelper
;
//For VIEW_SECTIONS
};
#endif
/* _MAINWINDOW_H_ */
src/ui/QGCLinkConfiguration.cc
View file @
bed21b49
...
...
@@ -58,64 +58,71 @@ QGCLinkConfiguration::~QGCLinkConfiguration()
void
QGCLinkConfiguration
::
on_delLinkButton_clicked
()
{
QModelIndex
index
=
_ui
->
linkView
->
currentIndex
();
LinkConfiguration
*
config
=
_viewModel
->
getConfiguration
(
index
.
row
());
if
(
config
)
{
// Ask user if they are sure
QMessageBox
::
StandardButton
button
=
QGCMessageBox
::
question
(
tr
(
"Delete Link Configuration"
),
tr
(
"Are you sure you want to delete %1?
\n
Deleting a configuration will also disconnect it if connected."
).
arg
(
config
->
name
()),
QMessageBox
::
Yes
|
QMessageBox
::
Cancel
,
QMessageBox
::
Cancel
);
if
(
button
==
QMessageBox
::
Yes
)
{
// Get link attached to this configuration (if any)
LinkInterface
*
iface
=
config
->
getLink
();
if
(
iface
)
{
// Disconnect it (if connected)
LinkManager
::
instance
()
->
disconnectLink
(
iface
);
if
(
index
.
row
()
>=
0
)
{
LinkConfiguration
*
config
=
_viewModel
->
getConfiguration
(
index
.
row
());
if
(
config
)
{
// Ask user if they are sure
QMessageBox
::
StandardButton
button
=
QGCMessageBox
::
question
(
tr
(
"Delete Link Configuration"
),
tr
(
"Are you sure you want to delete %1?
\n
Deleting a configuration will also disconnect it if connected."
).
arg
(
config
->
name
()),
QMessageBox
::
Yes
|
QMessageBox
::
Cancel
,
QMessageBox
::
Cancel
);
if
(
button
==
QMessageBox
::
Yes
)
{
// Get link attached to this configuration (if any)
LinkInterface
*
iface
=
config
->
getLink
();
if
(
iface
)
{
// Disconnect it (if connected)
LinkManager
::
instance
()
->
disconnectLink
(
iface
);
}
_viewModel
->
beginChange
();
// Remove configuration
LinkManager
::
instance
()
->
removeLinkConfiguration
(
config
);
// Save list
LinkManager
::
instance
()
->
saveLinkConfigurationList
();
_viewModel
->
endChange
();
}
_viewModel
->
beginChange
();
// Remove configuration
LinkManager
::
instance
()
->
removeLinkConfiguration
(
config
);
// Save list
LinkManager
::
instance
()
->
saveLinkConfigurationList
();
_viewModel
->
endChange
();
}
}
_updateButtons
();
}
void
QGCLinkConfiguration
::
on_linkView_clicked
(
const
QModelIndex
&
index
)
void
QGCLinkConfiguration
::
on_linkView_clicked
(
const
QModelIndex
&
)
{
LinkConfiguration
*
config
=
_viewModel
->
getConfiguration
(
index
.
row
());
bool
enabled
=
(
config
&&
!
config
->
getLink
());
_ui
->
connectLinkButton
->
setEnabled
(
enabled
);
_ui
->
delLinkButton
->
setEnabled
(
config
!=
NULL
);
_ui
->
editLinkButton
->
setEnabled
(
config
!=
NULL
);
_updateButtons
();
}
void
QGCLinkConfiguration
::
on_connectLinkButton_clicked
()
{
QModelIndex
index
=
_ui
->
linkView
->
currentIndex
();
LinkConfiguration
*
config
=
_viewModel
->
getConfiguration
(
index
.
row
());
if
(
config
)
{
// Only connect if not already connected
if
(
!
config
->
getLink
())
{
LinkInterface
*
link
=
LinkManager
::
instance
()
->
createLink
(
config
);
if
(
index
.
row
()
>=
0
)
{
LinkConfiguration
*
config
=
_viewModel
->
getConfiguration
(
index
.
row
());
if
(
config
)
{
LinkInterface
*
link
=
config
->
getLink
();
if
(
link
)
{
// Connect it
LinkManager
::
instance
()
->
connectLink
(
link
);
// Now go hunting for the parent so we can shut this down
QWidget
*
pQw
=
parentWidget
();
while
(
pQw
)
{
SettingsDialog
*
pDlg
=
dynamic_cast
<
SettingsDialog
*>
(
pQw
);
if
(
pDlg
)
{
pDlg
->
accept
();
break
;
// Disconnect Link
if
(
link
->
isConnected
())
{
LinkManager
::
instance
()
->
disconnectLink
(
link
);
}
}
else
{
LinkInterface
*
link
=
LinkManager
::
instance
()
->
createLink
(
config
);
if
(
link
)
{
// Connect it
LinkManager
::
instance
()
->
connectLink
(
link
);
// Now go hunting for the parent so we can shut this down
QWidget
*
pQw
=
parentWidget
();
while
(
pQw
)
{
SettingsDialog
*
pDlg
=
dynamic_cast
<
SettingsDialog
*>
(
pQw
);
if
(
pDlg
)
{
pDlg
->
accept
();
break
;
}
pQw
=
pQw
->
parentWidget
();
}
pQw
=
pQw
->
parentWidget
();
}
}
}
}
_updateButtons
();
}
void
QGCLinkConfiguration
::
on_editLinkButton_clicked
()
...
...
@@ -170,6 +177,7 @@ void QGCLinkConfiguration::on_addLinkButton_clicked()
_viewModel
->
endChange
();
}
}
_updateButtons
();
}
void
QGCLinkConfiguration
::
on_linkView_doubleClicked
(
const
QModelIndex
&
index
)
...
...
@@ -179,27 +187,51 @@ void QGCLinkConfiguration::on_linkView_doubleClicked(const QModelIndex &index)
void
QGCLinkConfiguration
::
_editLink
(
int
row
)
{
LinkConfiguration
*
config
=
_viewModel
->
getConfiguration
(
row
);
if
(
config
)
{
LinkConfiguration
*
tmpConfig
=
LinkConfiguration
::
duplicateSettings
(
config
);
QGCCommConfiguration
*
commDialog
=
new
QGCCommConfiguration
(
this
,
tmpConfig
);
if
(
commDialog
->
exec
()
==
QDialog
::
Accepted
)
{
// Save changes (if any)
if
(
commDialog
->
getConfig
())
{
_fixUnnamed
(
tmpConfig
);
_viewModel
->
beginChange
();
config
->
copyFrom
(
tmpConfig
);
// Save it
LinkManager
::
instance
()
->
saveLinkConfigurationList
();
_viewModel
->
endChange
();
// Tell link about changes (if any)
config
->
updateSettings
();
if
(
row
>=
0
)
{
LinkConfiguration
*
config
=
_viewModel
->
getConfiguration
(
row
);
if
(
config
)
{
LinkConfiguration
*
tmpConfig
=
LinkConfiguration
::
duplicateSettings
(
config
);
QGCCommConfiguration
*
commDialog
=
new
QGCCommConfiguration
(
this
,
tmpConfig
);
if
(
commDialog
->
exec
()
==
QDialog
::
Accepted
)
{
// Save changes (if any)
if
(
commDialog
->
getConfig
())
{
_fixUnnamed
(
tmpConfig
);
_viewModel
->
beginChange
();
config
->
copyFrom
(
tmpConfig
);
// Save it
LinkManager
::
instance
()
->
saveLinkConfigurationList
();
_viewModel
->
endChange
();
// Tell link about changes (if any)
config
->
updateSettings
();
}
}
// Discard temporary duplicate
if
(
commDialog
->
getConfig
())
delete
commDialog
->
getConfig
();
}
// Discard temporary duplicate
if
(
commDialog
->
getConfig
())
delete
commDialog
->
getConfig
();
}
_updateButtons
();
}
void
QGCLinkConfiguration
::
_updateButtons
()
{
LinkConfiguration
*
config
=
NULL
;
QModelIndex
index
=
_ui
->
linkView
->
currentIndex
();
bool
enabled
=
(
index
.
row
()
>=
0
);
if
(
enabled
)
{
config
=
_viewModel
->
getConfiguration
(
index
.
row
());
if
(
config
)
{
LinkInterface
*
link
=
config
->
getLink
();
if
(
link
)
{
_ui
->
connectLinkButton
->
setText
(
"Disconnect"
);
}
else
{
_ui
->
connectLinkButton
->
setText
(
"Connect"
);
}
}
}
_ui
->
connectLinkButton
->
setEnabled
(
enabled
);
_ui
->
delLinkButton
->
setEnabled
(
config
!=
NULL
);
_ui
->
editLinkButton
->
setEnabled
(
config
!=
NULL
);
}
LinkViewModel
::
LinkViewModel
(
QObject
*
parent
)
:
QAbstractListModel
(
parent
)
...
...
src/ui/QGCLinkConfiguration.h
View file @
bed21b49
...
...
@@ -60,6 +60,7 @@ private slots:
private:
void
_editLink
(
int
row
);
void
_fixUnnamed
(
LinkConfiguration
*
config
);
void
_updateButtons
();
Ui
::
QGCLinkConfiguration
*
_ui
;
LinkViewModel
*
_viewModel
;
...
...
src/ui/QGCToolBar.cc
View file @
bed21b49
...
...
@@ -743,6 +743,7 @@ void QGCToolBar::_updateConfigurations()
*/
void
QGCToolBar
::
enterMessageLabel
()
{
/*
// If not already there and messages are actually present
if(!_rollDownMessages && UASMessageHandler::instance()->messages().count())
{
...
...
@@ -753,6 +754,7 @@ void QGCToolBar::enterMessageLabel()
_rollDownMessages->setMinimumSize(360,200);
_rollDownMessages->show();
}
*/
}
/**
...
...
src/ui/toolbar/MainToolBar.cc
0 → 100644
View file @
bed21b49
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 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/>.
======================================================================*/
/**
* @file
* @brief QGC Main Tool Bar
* @author Gus Grubba <mavlink@grubba.com>
*/
#include <QQmlContext>
#include <QQmlEngine>
#include "MainWindow.h"
#include "MainToolBar.h"
#include "UASMessageHandler.h"
#include "UASMessageView.h"
MainToolBar
::
MainToolBar
()
:
_mav
(
NULL
)
,
_toolBar
(
NULL
)
,
_currentView
(
ViewNone
)
,
_batteryVoltage
(
0.0
)
,
_batteryPercent
(
0.0
)
,
_linkSelected
(
false
)
,
_connectionCount
(
0
)
,
_systemArmed
(
false
)
,
_currentHeartbeatTimeout
(
0
)
,
_waypointDistance
(
0.0
)
,
_currentWaypoint
(
0
)
,
_currentMessageCount
(
0
)
,
_currentErrorCount
(
0
)
,
_currentWarningCount
(
0
)
,
_currentNormalCount
(
0
)
,
_currentMessageType
(
MessageNone
)
,
_satelliteCount
(
-
1
)
,
_dotsPerInch
(
72.0
)
,
_rollDownMessages
(
0
)
{
setSizePolicy
(
QSizePolicy
::
MinimumExpanding
,
QSizePolicy
::
MinimumExpanding
);
setObjectName
(
"MainToolBar"
);
setMinimumHeight
(
40
);
setMaximumHeight
(
40
);
setMinimumWidth
(
MainWindow
::
instance
()
->
minimumWidth
());
// Get rid of layout default margins
QLayout
*
pl
=
layout
();
if
(
pl
)
{
pl
->
setContentsMargins
(
0
,
0
,
0
,
0
);
}
// Get screen DPI to manage font sizes on different platforms
QScreen
*
srn
=
QGuiApplication
::
screens
().
at
(
0
);
// TODO: Find current monitor as opposed to picking first one
_dotsPerInch
=
(
qreal
)
srn
->
logicalDotsPerInch
();
// Font point sizes are based on Mac 72dpi
setContextPropertyObject
(
"mainToolBar"
,
this
);
setSource
(
QUrl
::
fromUserInput
(
"qrc:/qml/MainToolBar.qml"
));
setVisible
(
true
);
// Configure the toolbar for the current default UAS (which should be none as we just booted)
_setActiveUAS
(
UASManager
::
instance
()
->
getActiveUAS
());
emit
configListChanged
();
emit
heartbeatTimeoutChanged
(
_currentHeartbeatTimeout
);
emit
connectionCountChanged
(
_connectionCount
);
// Link signals
connect
(
UASManager
::
instance
(),
&
UASManager
::
activeUASSet
,
this
,
&
MainToolBar
::
_setActiveUAS
);
connect
(
LinkManager
::
instance
(),
&
LinkManager
::
linkConfigurationChanged
,
this
,
&
MainToolBar
::
_updateConfigurations
);
connect
(
LinkManager
::
instance
(),
&
LinkManager
::
linkConnected
,
this
,
&
MainToolBar
::
_linkConnected
);
connect
(
LinkManager
::
instance
(),
&
LinkManager
::
linkDisconnected
,
this
,
&
MainToolBar
::
_linkDisconnected
);
}
MainToolBar
::~
MainToolBar
()
{
}
void
MainToolBar
::
onSetupView
()
{
setCurrentView
(
ViewSetup
);
MainWindow
::
instance
()
->
loadSetupView
();
}
void
MainToolBar
::
onPlanView
()
{
setCurrentView
(
ViewPlan
);
MainWindow
::
instance
()
->
loadOperatorView
();
}
void
MainToolBar
::
onFlyView
()
{
setCurrentView
(
ViewFly
);
MainWindow
::
instance
()
->
loadPilotView
();
}
void
MainToolBar
::
onAnalyzeView
()
{
setCurrentView
(
ViewAnalyze
);
MainWindow
::
instance
()
->
loadEngineerView
();
}
void
MainToolBar
::
onConnect
(
QString
conf
)
{
// If no connection, the role is "Connect"
if
(
_connectionCount
==
0
)
{
// Connect Link
if
(
_currentConfig
.
isEmpty
())
{
MainWindow
::
instance
()
->
manageLinks
();
}
else
{
// We don't want the combo box updating under our feet
LinkManager
::
instance
()
->
suspendConfigurationUpdates
(
true
);
// Create a link
LinkInterface
*
link
=
LinkManager
::
instance
()
->
createLink
(
_currentConfig
);
if
(
link
)
{
// Connect it
LinkManager
::
instance
()
->
connectLink
(
link
);
// Save last used connection
MainWindow
::
instance
()
->
saveLastUsedConnection
(
_currentConfig
);
}
LinkManager
::
instance
()
->
suspendConfigurationUpdates
(
false
);
}
}
else
{
if
(
conf
.
isEmpty
())
{
// Disconnect Only Connected Link
int
connectedCount
=
0
;
LinkInterface
*
connectedLink
=
NULL
;
QList
<
LinkInterface
*>
links
=
LinkManager
::
instance
()
->
getLinks
();
foreach
(
LinkInterface
*
link
,
links
)
{
if
(
link
->
isConnected
())
{
connectedCount
++
;
connectedLink
=
link
;
}
}
Q_ASSERT
(
connectedCount
==
1
);
Q_ASSERT
(
_connectionCount
==
1
);
Q_ASSERT
(
connectedLink
);
LinkManager
::
instance
()
->
disconnectLink
(
connectedLink
);
}
else
{
// Disconnect Named Connected Link
QList
<
LinkInterface
*>
links
=
LinkManager
::
instance
()
->
getLinks
();
foreach
(
LinkInterface
*
link
,
links
)
{
if
(
link
->
isConnected
())
{
if
(
link
->
getLinkConfiguration
()
&&
link
->
getLinkConfiguration
()
->
name
()
==
conf
)
{
LinkManager
::
instance
()
->
disconnectLink
(
link
);
}
}
}
}
}
}
void
MainToolBar
::
onLinkConfigurationChanged
(
const
QString
&
config
)
{
// User selected a link configuration from the combobox
if
(
_currentConfig
!=
config
)
{
_currentConfig
=
config
;
_linkSelected
=
true
;
}
}
void
MainToolBar
::
onEnterMessageArea
(
int
x
,
int
y
)
{
// If not already there and messages are actually present
if
(
!
_rollDownMessages
&&
UASMessageHandler
::
instance
()
->
messages
().
count
())
{
// Reset Counts
int
count
=
_currentMessageCount
;
MessageType_t
type
=
_currentMessageType
;
_currentErrorCount
=
0
;
_currentWarningCount
=
0
;
_currentNormalCount
=
0
;
_currentMessageCount
=
0
;
_currentMessageType
=
MessageNone
;
if
(
count
!=
_currentMessageCount
)
{
emit
messageCountChanged
(
0
);
}
if
(
type
!=
_currentMessageType
)
{
emit
messageTypeChanged
(
MessageNone
);
}
// Show messages
int
dialogWidth
=
400
;
x
=
x
-
(
dialogWidth
>>
1
);
if
(
x
<
0
)
x
=
0
;
y
=
height
()
/
3
;
// Put dialog on top of the message alert icon
QPoint
p
=
mapToGlobal
(
QPoint
(
x
,
y
));
_rollDownMessages
=
new
UASMessageViewRollDown
(
MainWindow
::
instance
());
_rollDownMessages
->
setAttribute
(
Qt
::
WA_DeleteOnClose
);
_rollDownMessages
->
move
(
mapFromGlobal
(
p
));
_rollDownMessages
->
setMinimumSize
(
dialogWidth
,
200
);
connect
(
_rollDownMessages
,
&
UASMessageViewRollDown
::
closeWindow
,
this
,
&
MainToolBar
::
_leaveMessageView
);
_rollDownMessages
->
show
();
}
}
QString
MainToolBar
::
getMavIconColor
()
{
// TODO: Not using because not only the colors are ghastly, it doesn't respect dark/light palette
if
(
_mav
)
return
_mav
->
getColor
().
name
();
else
return
QString
(
"black"
);
}
void
MainToolBar
::
_leaveMessageView
()
{
// Mouse has left the message window area (and it has closed itself)
_rollDownMessages
=
NULL
;
}
void
MainToolBar
::
setCurrentView
(
int
currentView
)
{
ViewType_t
view
=
ViewNone
;
switch
((
MainWindow
::
VIEW_SECTIONS
)
currentView
)
{
case
MainWindow
:
:
VIEW_ENGINEER
:
view
=
ViewAnalyze
;
break
;
case
MainWindow
:
:
VIEW_MISSION
:
view
=
ViewPlan
;
break
;
case
MainWindow
:
:
VIEW_FLIGHT
:
view
=
ViewFly
;
break
;
case
MainWindow
:
:
VIEW_SETUP
:
view
=
ViewSetup
;
break
;
default:
view
=
ViewNone
;
break
;
}
if
(
view
!=
_currentView
)
{
_currentView
=
view
;
emit
currentViewChanged
();
}
}
void
MainToolBar
::
_setActiveUAS
(
UASInterface
*
active
)
{
// Do nothing if system is the same
if
(
_mav
==
active
)
{
return
;
}
// If switching the UAS, disconnect the existing one.
if
(
_mav
)
{
disconnect
(
UASMessageHandler
::
instance
(),
&
UASMessageHandler
::
textMessageReceived
,
this
,
&
MainToolBar
::
_handleTextMessage
);
disconnect
(
_mav
,
&
UASInterface
::
heartbeatTimeout
,
this
,
&
MainToolBar
::
_heartbeatTimeout
);
disconnect
(
_mav
,
&
UASInterface
::
batteryChanged
,
this
,
&
MainToolBar
::
_updateBatteryRemaining
);
disconnect
(
_mav
,
&
UASInterface
::
modeChanged
,
this
,
&
MainToolBar
::
_updateMode
);
disconnect
(
_mav
,
&
UASInterface
::
nameChanged
,
this
,
&
MainToolBar
::
_updateName
);
disconnect
(
_mav
,
&
UASInterface
::
systemTypeSet
,
this
,
&
MainToolBar
::
_setSystemType
);
disconnect
(
_mav
,
SIGNAL
(
statusChanged
(
UASInterface
*
,
QString
,
QString
)),
this
,
SLOT
(
_updateState
(
UASInterface
*
,
QString
,
QString
)));
disconnect
(
_mav
,
SIGNAL
(
armingChanged
(
bool
)),
this
,
SLOT
(
_updateArmingState
(
bool
)));
if
(
_mav
->
getWaypointManager
())
{
disconnect
(
_mav
->
getWaypointManager
(),
&
UASWaypointManager
::
currentWaypointChanged
,
this
,
&
MainToolBar
::
_updateCurrentWaypoint
);
disconnect
(
_mav
->
getWaypointManager
(),
&
UASWaypointManager
::
waypointDistanceChanged
,
this
,
&
MainToolBar
::
_updateWaypointDistance
);
}
UAS
*
pUas
=
dynamic_cast
<
UAS
*>
(
_mav
);
if
(
pUas
)
{
disconnect
(
pUas
,
&
UAS
::
satelliteCountChanged
,
this
,
&
MainToolBar
::
_setSatelliteCount
);
}
}
// Connect new system
_mav
=
active
;
if
(
_mav
)
{
_setSystemType
(
_mav
,
_mav
->
getSystemType
());
_updateArmingState
(
_mav
->
isArmed
());
connect
(
UASMessageHandler
::
instance
(),
&
UASMessageHandler
::
textMessageReceived
,
this
,
&
MainToolBar
::
_handleTextMessage
);
connect
(
_mav
,
&
UASInterface
::
heartbeatTimeout
,
this
,
&
MainToolBar
::
_heartbeatTimeout
);
connect
(
_mav
,
&
UASInterface
::
batteryChanged
,
this
,
&
MainToolBar
::
_updateBatteryRemaining
);
connect
(
_mav
,
&
UASInterface
::
modeChanged
,
this
,
&
MainToolBar
::
_updateMode
);
connect
(
_mav
,
&
UASInterface
::
nameChanged
,
this
,
&
MainToolBar
::
_updateName
);
connect
(
_mav
,
&
UASInterface
::
systemTypeSet
,
this
,
&
MainToolBar
::
_setSystemType
);
connect
(
_mav
,
SIGNAL
(
statusChanged
(
UASInterface
*
,
QString
,
QString
)),
this
,
SLOT
(
_updateState
(
UASInterface
*
,
QString
,
QString
)));
connect
(
_mav
,
SIGNAL
(
armingChanged
(
bool
)),
this
,
SLOT
(
_updateArmingState
(
bool
)));
if
(
_mav
->
getWaypointManager
())
{
connect
(
_mav
->
getWaypointManager
(),
&
UASWaypointManager
::
currentWaypointChanged
,
this
,
&
MainToolBar
::
_updateCurrentWaypoint
);
connect
(
_mav
->
getWaypointManager
(),
&
UASWaypointManager
::
waypointDistanceChanged
,
this
,
&
MainToolBar
::
_updateWaypointDistance
);
}
UAS
*
pUas
=
dynamic_cast
<
UAS
*>
(
_mav
);
if
(
pUas
)
{
_setSatelliteCount
(
pUas
->
getSatelliteCount
(),
QString
(
""
));
connect
(
pUas
,
&
UAS
::
satelliteCountChanged
,
this
,
&
MainToolBar
::
_setSatelliteCount
);
}
}
// Let toolbar know about it
emit
mavPresentChanged
(
_mav
!=
NULL
);
}
void
MainToolBar
::
_updateArmingState
(
bool
armed
)
{
if
(
_systemArmed
!=
armed
)
{
_systemArmed
=
armed
;
emit
systemArmedChanged
(
armed
);
}
}
void
MainToolBar
::
_updateBatteryRemaining
(
UASInterface
*
,
double
voltage
,
double
,
double
percent
,
int
)
{
if
(
percent
<
0.0
)
{
percent
=
0.0
;
}
if
(
voltage
<
0.0
)
{
voltage
=
0.0
;
}
if
(
_batteryVoltage
!=
voltage
)
{
_batteryVoltage
=
voltage
;
emit
batteryVoltageChanged
(
voltage
);
}
if
(
_batteryPercent
!=
percent
)
{
_batteryPercent
=
percent
;
emit
batteryPercentChanged
(
voltage
);
}
}
void
MainToolBar
::
_updateConfigurations
()
{
bool
resetSelected
=
false
;
QString
selected
=
_currentConfig
;
QStringList
tmpList
;
QList
<
LinkConfiguration
*>
configs
=
LinkManager
::
instance
()
->
getLinkConfigurationList
();
foreach
(
LinkConfiguration
*
conf
,
configs
)
{
if
(
conf
)
{
tmpList
<<
conf
->
name
();
if
((
!
_linkSelected
&&
conf
->
isPreferred
())
||
selected
.
isEmpty
())
{
selected
=
conf
->
name
();
resetSelected
=
true
;
}
}
}
// Any changes?
if
(
tmpList
!=
_linkConfigurations
)
{
_linkConfigurations
=
tmpList
;
emit
configListChanged
();
}
// Selection change?
if
((
selected
!=
_currentConfig
&&
_linkConfigurations
.
contains
(
selected
))
||
(
selected
.
isEmpty
()))
{
_currentConfig
=
selected
;
emit
currentConfigChanged
(
_currentConfig
);
}
if
(
resetSelected
)
{
_linkSelected
=
false
;
}
}
void
MainToolBar
::
_linkConnected
(
LinkInterface
*
)
{
_updateConnection
();
}
void
MainToolBar
::
_linkDisconnected
(
LinkInterface
*
link
)
{
_updateConnection
(
link
);
}
void
MainToolBar
::
_updateConnection
(
LinkInterface
*
disconnectedLink
)
{
QStringList
connList
;
int
oldCount
=
_connectionCount
;
// If there are multiple connected links add/update the connect button menu
_connectionCount
=
0
;
QList
<
LinkInterface
*>
links
=
LinkManager
::
instance
()
->
getLinks
();
foreach
(
LinkInterface
*
link
,
links
)
{
if
(
disconnectedLink
!=
link
&&
link
->
isConnected
())
{
_connectionCount
++
;
if
(
link
->
getLinkConfiguration
())
{
connList
<<
link
->
getLinkConfiguration
()
->
name
();
}
}
}
if
(
oldCount
!=
_connectionCount
)
{
emit
connectionCountChanged
(
_connectionCount
);
}
if
(
connList
!=
_connectedList
)
{
_connectedList
=
connList
;
emit
connectedListChanged
(
_connectedList
);
}
}
void
MainToolBar
::
_updateState
(
UASInterface
*
,
QString
name
,
QString
)
{
if
(
_currentState
!=
name
)
{
_currentState
=
name
;
emit
currentStateChanged
(
_currentState
);
}
}
void
MainToolBar
::
_updateMode
(
int
,
QString
name
,
QString
)
{
if
(
name
.
size
())
{
QString
shortMode
=
name
;
shortMode
=
shortMode
.
replace
(
"D|"
,
""
);
shortMode
=
shortMode
.
replace
(
"A|"
,
""
);
if
(
_currentMode
!=
shortMode
)
{
_currentMode
=
shortMode
;
emit
currentModeChanged
();
}
}
}
void
MainToolBar
::
_updateName
(
const
QString
&
name
)
{
if
(
_systemName
!=
name
)
{
_systemName
=
name
;
// TODO: emit signal and use it
}
}
/**
* The current system type is represented through the system icon.
*
* @param uas Source system, has to be the same as this->uas
* @param systemType type ID, following the MAVLink system type conventions
* @see http://pixhawk.ethz.ch/software/mavlink
*/
void
MainToolBar
::
_setSystemType
(
UASInterface
*
,
unsigned
int
systemType
)
{
_systemPixmap
=
"qrc:/files/images/mavs/"
;
switch
(
systemType
)
{
case
MAV_TYPE_GENERIC
:
_systemPixmap
+=
"generic.svg"
;
break
;
case
MAV_TYPE_FIXED_WING
:
_systemPixmap
+=
"fixed-wing.svg"
;
break
;
case
MAV_TYPE_QUADROTOR
:
_systemPixmap
+=
"quadrotor.svg"
;
break
;
case
MAV_TYPE_COAXIAL
:
_systemPixmap
+=
"coaxial.svg"
;
break
;
case
MAV_TYPE_HELICOPTER
:
_systemPixmap
+=
"helicopter.svg"
;
break
;
case
MAV_TYPE_ANTENNA_TRACKER
:
_systemPixmap
+=
"antenna-tracker.svg"
;
break
;
case
MAV_TYPE_GCS
:
_systemPixmap
+=
"groundstation.svg"
;
break
;
case
MAV_TYPE_AIRSHIP
:
_systemPixmap
+=
"airship.svg"
;
break
;
case
MAV_TYPE_FREE_BALLOON
:
_systemPixmap
+=
"free-balloon.svg"
;
break
;
case
MAV_TYPE_ROCKET
:
_systemPixmap
+=
"rocket.svg"
;
break
;
case
MAV_TYPE_GROUND_ROVER
:
_systemPixmap
+=
"ground-rover.svg"
;
break
;
case
MAV_TYPE_SURFACE_BOAT
:
_systemPixmap
+=
"surface-boat.svg"
;
break
;
case
MAV_TYPE_SUBMARINE
:
_systemPixmap
+=
"submarine.svg"
;
break
;
case
MAV_TYPE_HEXAROTOR
:
_systemPixmap
+=
"hexarotor.svg"
;
break
;
case
MAV_TYPE_OCTOROTOR
:
_systemPixmap
+=
"octorotor.svg"
;
break
;
case
MAV_TYPE_TRICOPTER
:
_systemPixmap
+=
"tricopter.svg"
;
break
;
case
MAV_TYPE_FLAPPING_WING
:
_systemPixmap
+=
"flapping-wing.svg"
;
break
;
case
MAV_TYPE_KITE
:
_systemPixmap
+=
"kite.svg"
;
break
;
default:
_systemPixmap
+=
"unknown.svg"
;
break
;
}
emit
systemPixmapChanged
(
_systemPixmap
);
}
void
MainToolBar
::
_heartbeatTimeout
(
bool
timeout
,
unsigned
int
ms
)
{
unsigned
int
elapsed
=
ms
;
if
(
!
timeout
)
{
elapsed
=
0
;
}
if
(
elapsed
!=
_currentHeartbeatTimeout
)
{
_currentHeartbeatTimeout
=
elapsed
;
emit
heartbeatTimeoutChanged
(
_currentHeartbeatTimeout
);
}
}
void
MainToolBar
::
_handleTextMessage
(
UASMessage
*
)
{
UASMessageHandler
*
pMh
=
UASMessageHandler
::
instance
();
Q_ASSERT
(
pMh
);
MessageType_t
type
=
_currentMessageType
;
int
errorCount
=
_currentErrorCount
;
int
warnCount
=
_currentWarningCount
;
int
normalCount
=
_currentNormalCount
;
//-- Add current message counts
errorCount
+=
pMh
->
getErrorCount
();
warnCount
+=
pMh
->
getWarningCount
();
normalCount
+=
pMh
->
getNormalCount
();
//-- See if we have a higher level
if
(
errorCount
!=
_currentErrorCount
)
{
_currentErrorCount
=
errorCount
;
type
=
MessageError
;
}
if
(
warnCount
!=
_currentWarningCount
)
{
_currentWarningCount
=
warnCount
;
if
(
_currentMessageType
!=
MessageError
)
{
type
=
MessageWarning
;
}
}
if
(
normalCount
!=
_currentNormalCount
)
{
_currentNormalCount
=
normalCount
;
if
(
_currentMessageType
!=
MessageError
&&
_currentMessageType
!=
MessageWarning
)
{
type
=
MessageNormal
;
}
}
int
count
=
_currentErrorCount
+
_currentWarningCount
+
_currentNormalCount
;
if
(
count
!=
_currentMessageCount
)
{
_currentMessageCount
=
count
;
// Display current total message count
emit
messageCountChanged
(
count
);
}
if
(
type
!=
_currentMessageType
)
{
_currentMessageType
=
type
;
// Update message level
emit
messageTypeChanged
(
type
);
}
}
void
MainToolBar
::
_updateWaypointDistance
(
double
distance
)
{
if
(
_waypointDistance
!=
distance
)
{
_waypointDistance
=
distance
;
// TODO: emit signal and use it
}
}
void
MainToolBar
::
_updateCurrentWaypoint
(
quint16
id
)
{
if
(
_currentWaypoint
!=
id
)
{
_currentWaypoint
=
id
;
// TODO: emit signal and use it
}
}
void
MainToolBar
::
_setSatelliteCount
(
double
val
,
QString
)
{
if
(
val
<
0.0
)
val
=
0.0
;
if
(
val
>
99.0
)
val
=
99.0
;
if
(
_satelliteCount
!=
(
int
)
val
)
{
_satelliteCount
=
(
int
)
val
;
emit
satelliteCountChanged
(
_satelliteCount
);
}
}
src/ui/toolbar/MainToolBar.h
0 → 100644
View file @
bed21b49
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 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/>.
======================================================================*/
/**
* @file
* @brief QGC Main Tool Bar
* @author Gus Grubba <mavlink@grubba.com>
*/
#ifndef MAINTOOLBAR_H
#define MAINTOOLBAR_H
#include "QGCQmlWidgetHolder.h"
class
UASInterface
;
class
UASMessage
;
class
UASMessageViewRollDown
;
class
MainToolBar
:
public
QGCQmlWidgetHolder
{
Q_OBJECT
Q_ENUMS
(
ViewType_t
)
Q_ENUMS
(
MessageType_t
)
public:
MainToolBar
();
~
MainToolBar
();
typedef
enum
{
ViewNone
=
-
1
,
ViewAnalyze
,
// MainWindow::VIEW_ENGINEER
ViewPlan
,
// MainWindow::VIEW_MISSION
ViewFly
,
// MainWindow::VIEW_FLIGHT
ViewSetup
,
// MainWindow::VIEW_SETUP
}
ViewType_t
;
typedef
enum
{
MessageNone
,
MessageNormal
,
MessageWarning
,
MessageError
}
MessageType_t
;
Q_INVOKABLE
void
onSetupView
();
Q_INVOKABLE
void
onPlanView
();
Q_INVOKABLE
void
onFlyView
();
Q_INVOKABLE
void
onAnalyzeView
();
Q_INVOKABLE
void
onConnect
(
QString
conf
);
Q_INVOKABLE
void
onLinkConfigurationChanged
(
const
QString
&
config
);
Q_INVOKABLE
void
onEnterMessageArea
(
int
x
,
int
y
);
Q_INVOKABLE
QString
getMavIconColor
();
Q_PROPERTY
(
int
connectionCount
READ
connectionCount
NOTIFY
connectionCountChanged
)
Q_PROPERTY
(
double
batteryVoltage
READ
batteryVoltage
NOTIFY
batteryVoltageChanged
)
Q_PROPERTY
(
double
batteryPercent
READ
batteryPercent
NOTIFY
batteryPercentChanged
)
Q_PROPERTY
(
ViewType_t
currentView
READ
currentView
NOTIFY
currentViewChanged
)
Q_PROPERTY
(
QStringList
configList
READ
configList
NOTIFY
configListChanged
)
Q_PROPERTY
(
bool
systemArmed
READ
systemArmed
NOTIFY
systemArmedChanged
)
Q_PROPERTY
(
unsigned
int
heartbeatTimeout
READ
heartbeatTimeout
NOTIFY
heartbeatTimeoutChanged
)
Q_PROPERTY
(
QString
currentMode
READ
currentMode
NOTIFY
currentModeChanged
)
Q_PROPERTY
(
MessageType_t
messageType
READ
messageType
NOTIFY
messageTypeChanged
)
Q_PROPERTY
(
int
messageCount
READ
messageCount
NOTIFY
messageCountChanged
)
Q_PROPERTY
(
QString
currentConfig
READ
currentConfig
NOTIFY
currentConfigChanged
)
Q_PROPERTY
(
QString
systemPixmap
READ
systemPixmap
NOTIFY
systemPixmapChanged
)
Q_PROPERTY
(
int
satelliteCount
READ
satelliteCount
NOTIFY
satelliteCountChanged
)
Q_PROPERTY
(
QStringList
connectedList
READ
connectedList
NOTIFY
connectedListChanged
)
Q_PROPERTY
(
bool
mavPresent
READ
mavPresent
NOTIFY
mavPresentChanged
)
Q_PROPERTY
(
QString
currentState
READ
currentState
NOTIFY
currentStateChanged
)
Q_PROPERTY
(
double
dotsPerInch
READ
dotsPerInch
NOTIFY
dotsPerInchChanged
)
int
connectionCount
()
{
return
_connectionCount
;
}
double
batteryVoltage
()
{
return
_batteryVoltage
;
}
double
batteryPercent
()
{
return
_batteryPercent
;
}
ViewType_t
currentView
()
{
return
_currentView
;
}
QStringList
configList
()
{
return
_linkConfigurations
;
}
bool
systemArmed
()
{
return
_systemArmed
;
}
unsigned
int
heartbeatTimeout
()
{
return
_currentHeartbeatTimeout
;
}
QString
currentMode
()
{
return
_currentMode
;
}
MessageType_t
messageType
()
{
return
_currentMessageType
;
}
int
messageCount
()
{
return
_currentMessageCount
;
}
QString
currentConfig
()
{
return
_currentConfig
;
}
QString
systemPixmap
()
{
return
_systemPixmap
;
}
int
satelliteCount
()
{
return
_satelliteCount
;
}
QStringList
connectedList
()
{
return
_connectedList
;
}
bool
mavPresent
()
{
return
_mav
!=
NULL
;
}
QString
currentState
()
{
return
_currentState
;
}
double
dotsPerInch
()
{
return
_dotsPerInch
;
}
void
setCurrentView
(
int
currentView
);
signals:
void
connectionCountChanged
(
int
count
);
void
batteryVoltageChanged
(
double
value
);
void
batteryPercentChanged
(
double
value
);
void
currentViewChanged
();
void
configListChanged
();
void
systemArmedChanged
(
bool
systemArmed
);
void
heartbeatTimeoutChanged
(
unsigned
int
hbTimeout
);
void
currentModeChanged
();
void
messageTypeChanged
(
MessageType_t
type
);
void
messageCountChanged
(
int
count
);
void
currentConfigChanged
(
QString
config
);
void
systemPixmapChanged
(
QPixmap
pix
);
void
satelliteCountChanged
(
int
count
);
void
connectedListChanged
(
QStringList
connectedList
);
void
mavPresentChanged
(
bool
present
);
void
currentStateChanged
(
QString
state
);
void
dotsPerInchChanged
();
private
slots
:
void
_setActiveUAS
(
UASInterface
*
active
);
void
_updateBatteryRemaining
(
UASInterface
*
,
double
voltage
,
double
,
double
percent
,
int
);
void
_updateArmingState
(
bool
armed
);
void
_updateConfigurations
();
void
_linkConnected
(
LinkInterface
*
link
);
void
_linkDisconnected
(
LinkInterface
*
link
);
void
_updateState
(
UASInterface
*
system
,
QString
name
,
QString
description
);
void
_updateMode
(
int
system
,
QString
name
,
QString
description
);
void
_updateName
(
const
QString
&
name
);
void
_setSystemType
(
UASInterface
*
uas
,
unsigned
int
systemType
);
void
_heartbeatTimeout
(
bool
timeout
,
unsigned
int
ms
);
void
_handleTextMessage
(
UASMessage
*
message
);
void
_updateCurrentWaypoint
(
quint16
id
);
void
_updateWaypointDistance
(
double
distance
);
void
_setSatelliteCount
(
double
val
,
QString
name
);
void
_leaveMessageView
();
private:
void
_updateConnection
(
LinkInterface
*
disconnectedLink
=
NULL
);
private:
UASInterface
*
_mav
;
QQuickItem
*
_toolBar
;
ViewType_t
_currentView
;
double
_batteryVoltage
;
double
_batteryPercent
;
QStringList
_linkConfigurations
;
QString
_currentConfig
;
bool
_linkSelected
;
int
_connectionCount
;
bool
_systemArmed
;
QString
_currentState
;
QString
_currentMode
;
QString
_systemName
;
QString
_systemPixmap
;
unsigned
int
_currentHeartbeatTimeout
;
double
_waypointDistance
;
quint16
_currentWaypoint
;
int
_currentMessageCount
;
int
_currentErrorCount
;
int
_currentWarningCount
;
int
_currentNormalCount
;
MessageType_t
_currentMessageType
;
int
_satelliteCount
;
QStringList
_connectedList
;
qreal
_dotsPerInch
;
UASMessageViewRollDown
*
_rollDownMessages
;
};
#endif // MAINTOOLBAR_H
src/ui/toolbar/MainToolBar.qml
0 → 100644
View file @
bed21b49
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 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/>.
======================================================================*/
/**
* @file
* @brief QGC Main Tool Bar
* @author Gus Grubba <mavlink@grubba.com>
*/
import
QtQuick
2.3
import
QtQuick
.
Controls
1.2
import
QtQuick
.
Controls
.
Styles
1.2
import
QGroundControl
.
Controls
1.0
import
QGroundControl
.
FactControls
1.0
import
QGroundControl
.
Palette
1.0
import
QGroundControl
.
MainToolBar
1.0
Rectangle
{
property
var
qgcPal
:
QGCPalette
{
id
:
palette
;
colorGroupEnabled
:
true
}
property
int
cellSpacerSize
:
4
property
int
cellHeight
:
30
property
int
cellRadius
:
3
property
double
dpiFactor
:
(
72.0
/
mainToolBar
.
dotsPerInch
);
property
var
colorBlue
:
"
#1a6eaa
"
property
var
colorGreen
:
"
#00d930
"
property
var
colorRed
:
"
#a81a1b
"
property
var
colorOrange
:
"
#a76f26
"
property
var
colorWhite
:
"
#f0f0f0
"
id
:
toolBarHolder
color
:
qgcPal
.
windowShade
function
getMessageColor
()
{
if
(
mainToolBar
.
messageType
===
MainToolBar
.
MessageNone
)
return
qgcPal
.
button
;
if
(
mainToolBar
.
messageType
===
MainToolBar
.
MessageNormal
)
return
colorBlue
;
if
(
mainToolBar
.
messageType
===
MainToolBar
.
MessageWarning
)
return
colorOrange
;
if
(
mainToolBar
.
messageType
===
MainToolBar
.
MessageError
)
return
colorRed
;
// Cannot be so make make it obnoxious to show error
return
"
purple
"
;
}
function
getMessageIcon
()
{
if
(
mainToolBar
.
messageType
===
MainToolBar
.
MessageNormal
||
mainToolBar
.
messageType
===
MainToolBar
.
MessageNone
)
return
"
qrc:/files/images/status/message_megaphone.png
"
;
else
return
"
qrc:/files/images/status/message_triangle.png
"
;
}
function
getBatteryIcon
()
{
if
(
mainToolBar
.
batteryPercent
<
20.0
)
return
"
qrc:/files/images/status/battery_0.svg
"
;
else
if
(
mainToolBar
.
batteryPercent
<
40.0
)
return
"
qrc:/files/images/status/battery_20.svg
"
;
else
if
(
mainToolBar
.
batteryPercent
<
60.0
)
return
"
qrc:/files/images/status/battery_40.svg
"
;
else
if
(
mainToolBar
.
batteryPercent
<
80.0
)
return
"
qrc:/files/images/status/battery_60.svg
"
;
else
if
(
mainToolBar
.
batteryPercent
<
90.0
)
return
"
qrc:/files/images/status/battery_80.svg
"
;
else
return
"
qrc:/files/images/status/battery_100.svg
"
;
}
function
showMavStatus
()
{
return
(
mainToolBar
.
mavPresent
&&
mainToolBar
.
heartbeatTimeout
===
0
&&
mainToolBar
.
connectionCount
>
0
);
}
Row
{
id
:
row1
height
:
cellHeight
anchors.left
:
parent
.
left
spacing
:
cellSpacerSize
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.leftMargin
:
10
ExclusiveGroup
{
id
:
mainActionGroup
}
QGCButton
{
id
:
setupButton
width
:
90
height
:
cellHeight
exclusiveGroup
:
mainActionGroup
text
:
qsTr
(
"
1. Setup
"
)
anchors.verticalCenter
:
parent
.
verticalCenter
checked
:
(
mainToolBar
.
currentView
===
MainToolBar
.
ViewSetup
)
onClicked
:
{
mainToolBar
.
onSetupView
();
}
}
QGCButton
{
id
:
planButton
width
:
90
height
:
cellHeight
exclusiveGroup
:
mainActionGroup
text
:
qsTr
(
"
2. Plan
"
)
anchors.verticalCenter
:
parent
.
verticalCenter
checked
:
(
mainToolBar
.
currentView
===
MainToolBar
.
ViewPlan
)
onClicked
:
{
mainToolBar
.
onPlanView
();
}
}
QGCButton
{
id
:
flyButton
width
:
90
height
:
cellHeight
exclusiveGroup
:
mainActionGroup
text
:
qsTr
(
"
3. Fly
"
)
anchors.verticalCenter
:
parent
.
verticalCenter
checked
:
(
mainToolBar
.
currentView
===
MainToolBar
.
ViewFly
)
onClicked
:
{
mainToolBar
.
onFlyView
();
}
}
QGCButton
{
id
:
analyzeButton
width
:
90
height
:
cellHeight
exclusiveGroup
:
mainActionGroup
text
:
qsTr
(
"
4. Analyze
"
)
anchors.verticalCenter
:
parent
.
verticalCenter
checked
:
(
mainToolBar
.
currentView
===
MainToolBar
.
ViewAnalyze
)
onClicked
:
{
mainToolBar
.
onAnalyzeView
();
}
}
Rectangle
{
width
:
4
height
:
cellHeight
color
:
"
#00000000
"
border.color
:
"
#00000000
"
border.width
:
0
}
Rectangle
{
id
:
messages
width
:
(
mainToolBar
.
messageCount
>
99
)
?
70
:
60
height
:
cellHeight
visible
:
(
mainToolBar
.
connectionCount
>
0
)
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
getMessageColor
()
radius
:
cellRadius
border.color
:
"
#00000000
"
border.width
:
0
property
bool
showTriangle
:
false
Image
{
id
:
messageIcon
source
:
getMessageIcon
();
height
:
16
fillMode
:
Image
.
PreserveAspectFit
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
anchors.leftMargin
:
10
}
Rectangle
{
id
:
messageTextRect
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.right
:
parent
.
right
width
:
messages
.
width
-
messageIcon
.
width
Text
{
id
:
messageText
text
:
(
mainToolBar
.
messageCount
>
0
)
?
mainToolBar
.
messageCount
:
''
font.pointSize
:
14
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.horizontalCenter
:
parent
.
horizontalCenter
horizontalAlignment
:
Text
.
AlignHCenter
color
:
colorWhite
}
}
Image
{
id
:
dropDown
source
:
"
QGroundControl/Controls/arrow-down.png
"
visible
:
(
messages
.
showTriangle
)
anchors.bottom
:
parent
.
bottom
anchors.right
:
parent
.
right
anchors.bottomMargin
:
3
anchors.rightMargin
:
3
}
Timer
{
id
:
mouseOffTimer
interval
:
2000
;
running
:
false
;
repeat
:
false
onTriggered
:
{
messages
.
showTriangle
=
false
;
}
}
MouseArea
{
anchors.fill
:
parent
hoverEnabled
:
true
onEntered
:
{
messages
.
showTriangle
=
true
;
mouseOffTimer
.
start
();
}
onExited
:
{
messages
.
showTriangle
=
false
;
}
onClicked
:
{
var
p
=
mapToItem
(
toolBarHolder
,
mouseX
,
mouseY
);
mainToolBar
.
onEnterMessageArea
(
p
.
x
,
p
.
y
);
}
}
}
Rectangle
{
id
:
mavIcon
width
:
cellHeight
height
:
cellHeight
visible
:
showMavStatus
()
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
colorBlue
radius
:
cellRadius
border.color
:
"
#00000000
"
border.width
:
0
Image
{
source
:
mainToolBar
.
systemPixmap
height
:
cellHeight
*
0.75
fillMode
:
Image
.
PreserveAspectFit
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.horizontalCenter
:
parent
.
horizontalCenter
}
}
Rectangle
{
id
:
satelitte
width
:
60
height
:
cellHeight
visible
:
showMavStatus
()
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
(
mainToolBar
.
satelliteCount
<
3
)
?
colorRed
:
colorBlue
radius
:
cellRadius
border.color
:
"
#00000000
"
border.width
:
0
Image
{
source
:
"
qrc:/files/images/status/gps.svg
"
;
height
:
24
fillMode
:
Image
.
PreserveAspectFit
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
anchors.leftMargin
:
10
mipmap
:
true
smooth
:
true
}
Text
{
id
:
satelitteText
text
:
mainToolBar
.
satelliteCount
font.pointSize
:
14
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.right
:
parent
.
right
anchors.rightMargin
:
10
horizontalAlignment
:
Text
.
AlignRight
color
:
colorWhite
}
}
Rectangle
{
id
:
battery
width
:
80
height
:
cellHeight
visible
:
showMavStatus
()
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
(
mainToolBar
.
batteryPercent
>
40.0
||
mainToolBar
.
batteryPercent
<
0.01
)
?
colorBlue
:
colorRed
radius
:
cellRadius
border.color
:
"
#00000000
"
border.width
:
0
Image
{
source
:
getBatteryIcon
();
height
:
20
fillMode
:
Image
.
PreserveAspectFit
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.left
:
parent
.
left
anchors.leftMargin
:
6
mipmap
:
true
smooth
:
true
}
Text
{
id
:
batteryText
text
:
mainToolBar
.
batteryVoltage
.
toFixed
(
2
)
+
'
V
'
;
font.pointSize
:
14
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.right
:
parent
.
right
anchors.rightMargin
:
8
horizontalAlignment
:
Text
.
AlignRight
color
:
colorWhite
}
}
Column
{
anchors.verticalCenter
:
parent
.
verticalCenter
spacing
:
cellSpacerSize
visible
:
showMavStatus
()
height
:
cellHeight
*
0.75
width
:
80
Rectangle
{
id
:
armedStatus
width
:
parent
.
width
height
:
parent
.
height
/
2
anchors.horizontalCenter
:
parent
.
horizontalCenter
color
:
"
#00000000
"
border.color
:
"
#00000000
"
border.width
:
0
Text
{
id
:
armedStatusText
text
:
(
mainToolBar
.
systemArmed
)
?
qsTr
(
"
ARMED
"
)
:
qsTr
(
"
DISARMED
"
)
font.pointSize
:
12
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.horizontalCenter
:
parent
.
horizontalCenter
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
(
mainToolBar
.
systemArmed
)
?
colorRed
:
colorGreen
}
}
Rectangle
{
id
:
stateStatus
width
:
parent
.
width
height
:
parent
.
height
/
2
anchors.horizontalCenter
:
parent
.
horizontalCenter
color
:
"
#00000000
"
border.color
:
"
#00000000
"
border.width
:
0
Text
{
id
:
stateStatusText
text
:
mainToolBar
.
currentState
font.pointSize
:
12
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.horizontalCenter
:
parent
.
horizontalCenter
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
(
mainToolBar
.
currentState
===
"
STANDBY
"
)
?
colorGreen
:
colorRed
}
}
}
Rectangle
{
id
:
modeStatus
width
:
90
height
:
cellHeight
visible
:
showMavStatus
()
color
:
"
#00000000
"
border.color
:
"
#00000000
"
border.width
:
0
Text
{
id
:
modeStatusText
text
:
mainToolBar
.
currentMode
font.pointSize
:
12
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.horizontalCenter
:
parent
.
horizontalCenter
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
qgcPal
.
text
}
}
Rectangle
{
id
:
connectionStatus
width
:
160
height
:
cellHeight
visible
:
(
mainToolBar
.
connectionCount
>
0
&&
mainToolBar
.
mavPresent
&&
mainToolBar
.
heartbeatTimeout
!=
0
)
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
"
#00000000
"
border.color
:
"
#00000000
"
border.width
:
0
Text
{
id
:
connectionStatusText
text
:
qsTr
(
"
CONNECTION LOST
"
)
font.pointSize
:
14
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.horizontalCenter
:
parent
.
horizontalCenter
color
:
colorRed
}
}
}
Row
{
id
:
row2
height
:
cellHeight
spacing
:
cellSpacerSize
anchors.right
:
parent
.
right
anchors.verticalCenter
:
parent
.
verticalCenter
anchors.leftMargin
:
10
anchors.rightMargin
:
10
QGCComboBox
{
id
:
configList
width
:
200
height
:
cellHeight
visible
:
(
mainToolBar
.
connectionCount
===
0
&&
mainToolBar
.
configList
.
length
>
0
)
anchors.verticalCenter
:
parent
.
verticalCenter
model
:
mainToolBar
.
configList
onCurrentIndexChanged
:
{
mainToolBar
.
onLinkConfigurationChanged
(
mainToolBar
.
configList
[
currentIndex
]);
}
Component
.
onCompleted
:
{
mainToolBar
.
currentConfigChanged
.
connect
(
configList
.
onCurrentConfigChanged
)
}
function
onCurrentConfigChanged
(
config
)
{
var
index
=
configList
.
find
(
config
);
configList
.
currentIndex
=
index
;
}
}
QGCButton
{
id
:
connectButton
width
:
90
height
:
cellHeight
visible
:
(
mainToolBar
.
connectionCount
===
0
||
mainToolBar
.
connectionCount
===
1
)
text
:
(
mainToolBar
.
configList
.
length
>
0
)
?
(
mainToolBar
.
connectionCount
===
0
)
?
qsTr
(
"
Connect
"
)
:
qsTr
(
"
Disconnect
"
)
:
qsTr
(
"
Add Link
"
)
anchors.verticalCenter
:
parent
.
verticalCenter
onClicked
:
{
mainToolBar
.
onConnect
(
""
);
}
}
Menu
{
id
:
disconnectMenu
Component.onCompleted
:
{
mainToolBar
.
connectedListChanged
.
connect
(
disconnectMenu
.
onConnectedListChanged
)
}
function
onConnectedListChanged
(
conList
)
{
disconnectMenu
.
clear
();
for
(
var
i
=
0
;
i
<
conList
.
length
;
i
++
)
{
var
mItem
=
disconnectMenu
.
addItem
(
conList
[
i
]);
var
menuSlot
=
function
()
{
mainToolBar
.
onConnect
(
mItem
.
text
)};
mItem
.
triggered
.
connect
(
menuSlot
);
}
}
}
QGCButton
{
id
:
multidisconnectButton
width
:
90
height
:
cellHeight
text
:
qsTr
(
"
Disconnect
"
)
visible
:
(
mainToolBar
.
connectionCount
>
1
)
anchors.verticalCenter
:
parent
.
verticalCenter
menu
:
disconnectMenu
}
}
}
src/ui/uas/UASMessageView.cc
View file @
bed21b49
...
...
@@ -24,7 +24,7 @@ This file is part of the QGROUNDCONTROL project
#include <QMenu>
#include <QScrollBar>
#include "
QGC
ToolBar.h"
#include "
Main
ToolBar.h"
#include "UASMessageView.h"
#include "QGCUnconnectedInfoWidget.h"
#include "UASMessageHandler.h"
...
...
@@ -111,10 +111,9 @@ void UASMessageViewWidget::handleTextMessage(UASMessage *message)
UASMessageViewRollDown
-------------------------------------------------------------------------------------*/
UASMessageViewRollDown
::
UASMessageViewRollDown
(
QWidget
*
parent
,
QGCToolBar
*
toolBar
)
UASMessageViewRollDown
::
UASMessageViewRollDown
(
QWidget
*
parent
)
:
UASMessageView
(
parent
)
{
_toolBar
=
toolBar
;
setAttribute
(
Qt
::
WA_TranslucentBackground
);
setStyleSheet
(
"background-color: rgba(0%,0%,0%,80%); border: 2px;"
);
QPlainTextEdit
*
msgWidget
=
ui
()
->
plainTextEdit
;
...
...
@@ -154,9 +153,8 @@ void UASMessageViewRollDown::handleTextMessage(UASMessage *message)
}
}
void
UASMessageViewRollDown
::
leaveEvent
(
QEvent
*
event
)
void
UASMessageViewRollDown
::
leaveEvent
(
QEvent
*
)
{
Q_UNUSED
(
event
);
_toolBar
->
leaveMessageView
();
emit
closeWindow
();
close
();
}
src/ui/uas/UASMessageView.h
View file @
bed21b49
...
...
@@ -31,7 +31,6 @@ This file is part of the QGROUNDCONTROL project
#include "QGCUnconnectedInfoWidget.h"
class
UASMessage
;
class
QGCToolBar
;
namespace
Ui
{
class
UASMessageView
;
...
...
@@ -69,14 +68,14 @@ class UASMessageViewRollDown : public UASMessageView
{
Q_OBJECT
public:
explicit
UASMessageViewRollDown
(
QWidget
*
parent
,
QGCToolBar
*
toolBar
);
explicit
UASMessageViewRollDown
(
QWidget
*
parent
);
~
UASMessageViewRollDown
();
signals:
void
closeWindow
();
public
slots
:
void
handleTextMessage
(
UASMessage
*
message
);
protected:
void
leaveEvent
(
QEvent
*
event
);
private:
QGCToolBar
*
_toolBar
;
};
#endif // QGCMESSAGEVIEW_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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