Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Valentin Platzgummer
qgroundcontrol
Commits
a49790ec
Commit
a49790ec
authored
Jan 02, 2017
by
Don Gagne
Committed by
GitHub
Jan 02, 2017
Browse files
Merge pull request #4377 from bluerobotics/sub-frame-config
Add frame configuration page for ArduSub
parents
ec006f3e
a5ed9bbb
Changes
16
Hide whitespace changes
Inline
Side-by-side
qgcresources.qrc
View file @
a49790ec
...
@@ -58,6 +58,12 @@
...
@@ -58,6 +58,12 @@
<file alias="LandMode.svg">src/AutoPilotPlugins/PX4/Images/LandMode.svg</file>
<file alias="LandMode.svg">src/AutoPilotPlugins/PX4/Images/LandMode.svg</file>
<file alias="LandModeCopter.svg">src/AutoPilotPlugins/PX4/Images/LandModeCopter.svg</file>
<file alias="LandModeCopter.svg">src/AutoPilotPlugins/PX4/Images/LandModeCopter.svg</file>
<file alias="LightsComponentIcon.png">src/AutoPilotPlugins/APM/Images/LightsComponentIcon.png</file>
<file alias="LightsComponentIcon.png">src/AutoPilotPlugins/APM/Images/LightsComponentIcon.png</file>
<file alias="SubFrameComponentIcon.png">src/AutoPilotPlugins/APM/Images/SubFrameComponentIcon.png</file>
<file alias="Frames/BlueROV1.png">src/AutoPilotPlugins/APM/Images/bluerov-frame.png</file>
<file alias="Frames/Vectored.png">src/AutoPilotPlugins/APM/Images/vectored-frame.png</file>
<file alias="Frames/Vectored6DOF.png">src/AutoPilotPlugins/APM/Images/vectored6dof-frame.png</file>
<file alias="Frames/SimpleROV-3.png">src/AutoPilotPlugins/APM/Images/simple3-frame.png</file>
<file alias="Frames/SimpleROV-4.png">src/AutoPilotPlugins/APM/Images/simple4-frame.png</file>
<file alias="LogDownloadIcon">src/AnalyzeView/LogDownloadIcon.svg</file>
<file alias="LogDownloadIcon">src/AnalyzeView/LogDownloadIcon.svg</file>
<file alias="LowBattery.svg">src/AutoPilotPlugins/PX4/Images/LowBattery.svg</file>
<file alias="LowBattery.svg">src/AutoPilotPlugins/PX4/Images/LowBattery.svg</file>
<file alias="LowBatteryLight.svg">src/AutoPilotPlugins/PX4/Images/LowBatteryLight.svg</file>
<file alias="LowBatteryLight.svg">src/AutoPilotPlugins/PX4/Images/LowBatteryLight.svg</file>
...
...
qgroundcontrol.pro
View file @
a49790ec
...
@@ -796,6 +796,7 @@ APMFirmwarePlugin {
...
@@ -796,6 +796,7 @@ APMFirmwarePlugin {
src/AutoPilotPlugins/APM/APMFlightModesComponent.h \
src/AutoPilotPlugins/APM/APMFlightModesComponent.h \
src/AutoPilotPlugins/APM/APMFlightModesComponentController.h \
src/AutoPilotPlugins/APM/APMFlightModesComponentController.h \
src/AutoPilotPlugins/APM/APMLightsComponent.h \
src/AutoPilotPlugins/APM/APMLightsComponent.h \
src/AutoPilotPlugins/APM/APMSubFrameComponent.h \
src/AutoPilotPlugins/APM/APMPowerComponent.h \
src/AutoPilotPlugins/APM/APMPowerComponent.h \
src/AutoPilotPlugins/APM/APMRadioComponent.h \
src/AutoPilotPlugins/APM/APMRadioComponent.h \
src/AutoPilotPlugins/APM/APMSafetyComponent.h \
src/AutoPilotPlugins/APM/APMSafetyComponent.h \
...
@@ -822,6 +823,7 @@ APMFirmwarePlugin {
...
@@ -822,6 +823,7 @@ APMFirmwarePlugin {
src/AutoPilotPlugins/APM/APMFlightModesComponent.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponent.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponentController.cc \
src/AutoPilotPlugins/APM/APMFlightModesComponentController.cc \
src/AutoPilotPlugins/APM/APMLightsComponent.cc \
src/AutoPilotPlugins/APM/APMLightsComponent.cc \
src/AutoPilotPlugins/APM/APMSubFrameComponent.cc \
src/AutoPilotPlugins/APM/APMPowerComponent.cc \
src/AutoPilotPlugins/APM/APMPowerComponent.cc \
src/AutoPilotPlugins/APM/APMRadioComponent.cc \
src/AutoPilotPlugins/APM/APMRadioComponent.cc \
src/AutoPilotPlugins/APM/APMSafetyComponent.cc \
src/AutoPilotPlugins/APM/APMSafetyComponent.cc \
...
...
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.cc
View file @
a49790ec
...
@@ -27,6 +27,7 @@
...
@@ -27,6 +27,7 @@
#include
"MotorComponent.h"
#include
"MotorComponent.h"
#include
"APMCameraComponent.h"
#include
"APMCameraComponent.h"
#include
"APMLightsComponent.h"
#include
"APMLightsComponent.h"
#include
"APMSubFrameComponent.h"
#include
"ESP8266Component.h"
#include
"ESP8266Component.h"
/// This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_ARDUPILOT type.
/// This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_ARDUPILOT type.
...
@@ -36,6 +37,7 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
...
@@ -36,6 +37,7 @@ APMAutoPilotPlugin::APMAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
,
_airframeComponent
(
NULL
)
,
_airframeComponent
(
NULL
)
,
_cameraComponent
(
NULL
)
,
_cameraComponent
(
NULL
)
,
_lightsComponent
(
NULL
)
,
_lightsComponent
(
NULL
)
,
_subFrameComponent
(
NULL
)
,
_flightModesComponent
(
NULL
)
,
_flightModesComponent
(
NULL
)
,
_powerComponent
(
NULL
)
,
_powerComponent
(
NULL
)
#if 0
#if 0
...
@@ -109,6 +111,12 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
...
@@ -109,6 +111,12 @@ const QVariantList& APMAutoPilotPlugin::vehicleComponents(void)
_lightsComponent
=
new
APMLightsComponent
(
_vehicle
,
this
);
_lightsComponent
=
new
APMLightsComponent
(
_vehicle
,
this
);
_lightsComponent
->
setupTriggerSignals
();
_lightsComponent
->
setupTriggerSignals
();
_components
.
append
(
QVariant
::
fromValue
((
VehicleComponent
*
)
_lightsComponent
));
_components
.
append
(
QVariant
::
fromValue
((
VehicleComponent
*
)
_lightsComponent
));
if
(
_vehicle
->
firmwareMajorVersion
()
>
3
||
(
_vehicle
->
firmwareMajorVersion
()
==
3
&&
_vehicle
->
firmwareMinorVersion
()
>=
5
))
{
_subFrameComponent
=
new
APMSubFrameComponent
(
_vehicle
,
this
);
_subFrameComponent
->
setupTriggerSignals
();
_components
.
append
(
QVariant
::
fromValue
((
VehicleComponent
*
)
_subFrameComponent
));
}
}
}
//-- Is there an ESP8266 Connected?
//-- Is there an ESP8266 Connected?
...
...
src/AutoPilotPlugins/APM/APMAutoPilotPlugin.h
View file @
a49790ec
...
@@ -25,6 +25,7 @@ class APMPowerComponent;
...
@@ -25,6 +25,7 @@ class APMPowerComponent;
class
MotorComponent
;
class
MotorComponent
;
class
APMCameraComponent
;
class
APMCameraComponent
;
class
APMLightsComponent
;
class
APMLightsComponent
;
class
APMSubFrameComponent
;
class
ESP8266Component
;
class
ESP8266Component
;
/// This is the APM specific implementation of the AutoPilot class.
/// This is the APM specific implementation of the AutoPilot class.
...
@@ -42,6 +43,7 @@ public:
...
@@ -42,6 +43,7 @@ public:
APMAirframeComponent
*
airframeComponent
(
void
)
const
{
return
_airframeComponent
;
}
APMAirframeComponent
*
airframeComponent
(
void
)
const
{
return
_airframeComponent
;
}
APMCameraComponent
*
cameraComponent
(
void
)
const
{
return
_cameraComponent
;
}
APMCameraComponent
*
cameraComponent
(
void
)
const
{
return
_cameraComponent
;
}
APMLightsComponent
*
lightsComponent
(
void
)
const
{
return
_lightsComponent
;
}
APMLightsComponent
*
lightsComponent
(
void
)
const
{
return
_lightsComponent
;
}
APMSubFrameComponent
*
subFrameComponent
(
void
)
const
{
return
_subFrameComponent
;
}
APMFlightModesComponent
*
flightModesComponent
(
void
)
const
{
return
_flightModesComponent
;
}
APMFlightModesComponent
*
flightModesComponent
(
void
)
const
{
return
_flightModesComponent
;
}
APMPowerComponent
*
powerComponent
(
void
)
const
{
return
_powerComponent
;
}
APMPowerComponent
*
powerComponent
(
void
)
const
{
return
_powerComponent
;
}
#if 0
#if 0
...
@@ -61,6 +63,7 @@ private:
...
@@ -61,6 +63,7 @@ private:
APMAirframeComponent
*
_airframeComponent
;
APMAirframeComponent
*
_airframeComponent
;
APMCameraComponent
*
_cameraComponent
;
APMCameraComponent
*
_cameraComponent
;
APMLightsComponent
*
_lightsComponent
;
APMLightsComponent
*
_lightsComponent
;
APMSubFrameComponent
*
_subFrameComponent
;
APMFlightModesComponent
*
_flightModesComponent
;
APMFlightModesComponent
*
_flightModesComponent
;
APMPowerComponent
*
_powerComponent
;
APMPowerComponent
*
_powerComponent
;
#if 0
#if 0
...
...
src/AutoPilotPlugins/APM/APMLightsComponent.cc
View file @
a49790ec
...
@@ -65,12 +65,5 @@ QUrl APMLightsComponent::summaryQmlSource(void) const
...
@@ -65,12 +65,5 @@ QUrl APMLightsComponent::summaryQmlSource(void) const
QString
APMLightsComponent
::
prerequisiteSetup
(
void
)
const
QString
APMLightsComponent
::
prerequisiteSetup
(
void
)
const
{
{
APMAutoPilotPlugin
*
plugin
=
dynamic_cast
<
APMAutoPilotPlugin
*>
(
_autopilot
);
Q_ASSERT
(
plugin
);
if
(
!
plugin
->
airframeComponent
()
->
setupComplete
())
{
return
plugin
->
airframeComponent
()
->
name
();
}
return
QString
();
return
QString
();
}
}
src/AutoPilotPlugins/APM/APMSubFrameComponent.cc
0 → 100644
View file @
a49790ec
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
/// @file
/// @author Don Gagne <don@thegagnes.com>
/// @author Jacob Walser <jwalser90@gmail.com>
#include
"APMSubFrameComponent.h"
#include
"QGCQmlWidgetHolder.h"
#include
"APMAutoPilotPlugin.h"
#include
"APMAirframeComponent.h"
APMSubFrameComponent
::
APMSubFrameComponent
(
Vehicle
*
vehicle
,
AutoPilotPlugin
*
autopilot
,
QObject
*
parent
)
:
VehicleComponent
(
vehicle
,
autopilot
,
parent
)
,
_name
(
tr
(
"Frame"
))
{
}
QString
APMSubFrameComponent
::
name
(
void
)
const
{
return
_name
;
}
QString
APMSubFrameComponent
::
description
(
void
)
const
{
return
tr
(
"Frame setup allows you to choose your vehicle's motor configuration. Install clockwise"
\
"
\n
propellers on the green thrusters and counter-clockwise propellers on the blue thrusters"
\
"
\n
(or vice-versa). The flight controller will need to be rebooted to apply changes."
);
}
QString
APMSubFrameComponent
::
iconResource
(
void
)
const
{
return
QStringLiteral
(
"/qmlimages/SubFrameComponentIcon.png"
);
}
bool
APMSubFrameComponent
::
requiresSetup
(
void
)
const
{
return
false
;
}
bool
APMSubFrameComponent
::
setupComplete
(
void
)
const
{
return
true
;
}
QStringList
APMSubFrameComponent
::
setupCompleteChangedTriggerList
(
void
)
const
{
return
QStringList
();
}
QUrl
APMSubFrameComponent
::
setupSource
(
void
)
const
{
return
QUrl
::
fromUserInput
(
QStringLiteral
(
"qrc:/qml/APMSubFrameComponent.qml"
));
}
QUrl
APMSubFrameComponent
::
summaryQmlSource
(
void
)
const
{
return
QUrl
::
fromUserInput
(
QStringLiteral
(
"qrc:/qml/APMSubFrameComponentSummary.qml"
));
}
QString
APMSubFrameComponent
::
prerequisiteSetup
(
void
)
const
{
return
QString
();
}
src/AutoPilotPlugins/APM/APMSubFrameComponent.h
0 → 100644
View file @
a49790ec
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
#ifndef APMSubFrameComponent_H
#define APMSubFrameComponent_H
#include
"VehicleComponent.h"
class
APMSubFrameComponent
:
public
VehicleComponent
{
Q_OBJECT
public:
APMSubFrameComponent
(
Vehicle
*
vehicle
,
AutoPilotPlugin
*
autopilot
,
QObject
*
parent
=
NULL
);
// Virtuals from VehicleComponent
QStringList
setupCompleteChangedTriggerList
(
void
)
const
final
;
// Virtuals from VehicleComponent
QString
name
(
void
)
const
final
;
QString
description
(
void
)
const
final
;
QString
iconResource
(
void
)
const
final
;
bool
requiresSetup
(
void
)
const
final
;
bool
setupComplete
(
void
)
const
final
;
QUrl
setupSource
(
void
)
const
final
;
QUrl
summaryQmlSource
(
void
)
const
final
;
QString
prerequisiteSetup
(
void
)
const
final
;
private:
const
QString
_name
;
};
#endif
src/AutoPilotPlugins/APM/APMSubFrameComponent.qml
0 → 100644
View file @
a49790ec
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import
QtQuick
2.5
import
QtQuick
.
Controls
1.2
import
QGroundControl
.
FactSystem
1.0
import
QGroundControl
.
FactControls
1.0
import
QGroundControl
.
Palette
1.0
import
QGroundControl
.
Controls
1.0
import
QGroundControl
.
ScreenTools
1.0
SetupPage
{
id
:
subFramePage
pageComponent
:
subFramePageComponent
Component
{
id
:
subFramePageComponent
Column
{
id
:
mainColumn
width
:
availableWidth
FactPanelController
{
id
:
controller
;
factPanel
:
subFramePage
.
viewPanel
}
QGCPalette
{
id
:
palette
;
colorGroupEnabled
:
true
}
property
Fact
_frameConfig
:
controller
.
getParameterFact
(
-
1
,
"
FRAME_CONFIG
"
)
function
setFrameConfig
(
frame
)
{
_frameConfig
.
value
=
frame
;
}
property
real
_minW
:
ScreenTools
.
defaultFontPixelWidth
*
30
property
real
_boxWidth
:
_minW
property
real
_boxSpace
:
ScreenTools
.
defaultFontPixelWidth
onWidthChanged
:
{
computeDimensions
()
}
Component.onCompleted
:
computeDimensions
()
function
computeDimensions
()
{
var
sw
=
0
var
rw
=
0
var
idx
=
Math
.
floor
(
mainColumn
.
width
/
(
_minW
+
ScreenTools
.
defaultFontPixelWidth
))
if
(
idx
<
1
)
{
_boxWidth
=
mainColumn
.
width
_boxSpace
=
0
}
else
{
_boxSpace
=
0
if
(
idx
>
1
)
{
_boxSpace
=
ScreenTools
.
defaultFontPixelWidth
sw
=
_boxSpace
*
(
idx
-
1
)
}
rw
=
mainColumn
.
width
-
sw
_boxWidth
=
rw
/
idx
}
}
ListModel
{
id
:
subFrameModel
ListElement
{
name
:
"
BlueROV1
"
resource
:
"
qrc:///qmlimages/Frames/BlueROV1.png
"
paramValue
:
0
}
ListElement
{
name
:
"
BlueROV2/Vectored
"
resource
:
"
qrc:///qmlimages/Frames/Vectored.png
"
paramValue
:
1
}
ListElement
{
name
:
"
Vectored-6DOF
"
resource
:
"
qrc:///qmlimages/Frames/Vectored6DOF.png
"
paramValue
:
2
}
ListElement
{
name
:
"
SimpleROV-3
"
resource
:
"
qrc:///qmlimages/Frames/SimpleROV-3.png
"
paramValue
:
4
}
ListElement
{
name
:
"
SimpleROV-4
"
resource
:
"
qrc:///qmlimages/Frames/SimpleROV-4.png
"
paramValue
:
5
}
}
Flow
{
id
:
flowView
width
:
parent
.
width
spacing
:
_boxSpace
Repeater
{
model
:
subFrameModel
Rectangle
{
width
:
_boxWidth
height
:
ScreenTools
.
defaultFontPixelHeight
*
14
color
:
qgcPal
.
window
QGCLabel
{
id
:
title
text
:
subFrameModel
.
get
(
index
).
name
}
Rectangle
{
anchors.topMargin
:
ScreenTools
.
defaultFontPixelHeight
/
2
anchors.top
:
title
.
bottom
anchors.bottom
:
parent
.
bottom
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
color
:
subFrameModel
.
get
(
index
).
paramValue
==
_frameConfig
.
value
?
qgcPal
.
buttonHighlight
:
qgcPal
.
windowShade
Image
{
anchors.margins
:
ScreenTools
.
defaultFontPixelWidth
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
anchors.left
:
parent
.
left
anchors.right
:
parent
.
right
fillMode
:
Image
.
PreserveAspectFit
smooth
:
true
mipmap
:
true
source
:
subFrameModel
.
get
(
index
).
resource
}
MouseArea
{
anchors.fill
:
parent
onClicked
:
setFrameConfig
(
subFrameModel
.
get
(
index
).
paramValue
)
}
}
}
}
// Repeater
}
// Flow
}
// Column
}
// Component
}
// SetupPage
src/AutoPilotPlugins/APM/APMSubFrameComponentSummary.qml
0 → 100644
View file @
a49790ec
import
QtQuick
2.2
import
QtQuick
.
Controls
1.2
import
QGroundControl
.
FactSystem
1.0
import
QGroundControl
.
FactControls
1.0
import
QGroundControl
.
Controls
1.0
import
QGroundControl
.
Controllers
1.0
import
QGroundControl
.
Palette
1.0
FactPanel
{
id
:
panel
anchors.fill
:
parent
color
:
qgcPal
.
windowShadeDark
QGCPalette
{
id
:
qgcPal
;
colorGroupEnabled
:
enabled
}
FactPanelController
{
id
:
controller
;
factPanel
:
panel
}
property
Fact
frameFact
:
controller
.
getParameterFact
(
-
1
,
"
FRAME_CONFIG
"
)
function
frameName
()
{
switch
(
frameFact
.
value
)
{
case
0
:
return
"
BlueROV1
"
case
1
:
return
"
Vectored/BlueROV2
"
case
2
:
return
"
Vectored 6DOF
"
case
3
:
return
"
Vectored 6DOF 90Degree
"
case
4
:
return
"
SimpleROV-3
"
case
5
:
return
"
SimpleROV-4
"
case
6
:
return
"
SimpleROV-5
"
case
7
:
return
"
Custom
"
default
:
return
"
Unknown
"
}
}
Column
{
anchors.fill
:
parent
VehicleSummaryRow
{
id
:
nameRow
;
labelText
:
qsTr
(
"
Frame Type:
"
)
valueText
:
frameName
()
}
VehicleSummaryRow
{
labelText
:
qsTr
(
"
Firmware Version:
"
)
valueText
:
activeVehicle
.
firmwareMajorVersion
==
-
1
?
qsTr
(
"
Unknown
"
)
:
activeVehicle
.
firmwareMajorVersion
+
"
.
"
+
activeVehicle
.
firmwareMinorVersion
+
"
.
"
+
activeVehicle
.
firmwarePatchVersion
+
"
-
"
+
activeVehicle
.
firmwareVersionTypeString
}
}
}
src/AutoPilotPlugins/APM/Images/SubFrameComponentIcon.png
0 → 100644
View file @
a49790ec
5.71 KB
src/AutoPilotPlugins/APM/Images/bluerov-frame.png
0 → 100644
View file @
a49790ec
41.6 KB
src/AutoPilotPlugins/APM/Images/simple3-frame.png
0 → 100644
View file @
a49790ec
20.1 KB
src/AutoPilotPlugins/APM/Images/simple4-frame.png
0 → 100644
View file @
a49790ec
27.2 KB
src/AutoPilotPlugins/APM/Images/vectored-frame.png
0 → 100644
View file @
a49790ec
41.9 KB
src/AutoPilotPlugins/APM/Images/vectored6dof-frame.png
0 → 100644
View file @
a49790ec
59.2 KB
src/FirmwarePlugin/APM/APMResources.qrc
View file @
a49790ec
...
@@ -8,6 +8,8 @@
...
@@ -8,6 +8,8 @@
<file alias="APMFlightModesComponentSummary.qml">../../AutoPilotPlugins/APM/APMFlightModesComponentSummary.qml</file>
<file alias="APMFlightModesComponentSummary.qml">../../AutoPilotPlugins/APM/APMFlightModesComponentSummary.qml</file>
<file alias="APMLightsComponent.qml">../../AutoPilotPlugins/APM/APMLightsComponent.qml</file>
<file alias="APMLightsComponent.qml">../../AutoPilotPlugins/APM/APMLightsComponent.qml</file>
<file alias="APMLightsComponentSummary.qml">../../AutoPilotPlugins/APM/APMLightsComponentSummary.qml</file>
<file alias="APMLightsComponentSummary.qml">../../AutoPilotPlugins/APM/APMLightsComponentSummary.qml</file>
<file alias="APMSubFrameComponent.qml">../../AutoPilotPlugins/APM/APMSubFrameComponent.qml</file>
<file alias="APMSubFrameComponentSummary.qml">../../AutoPilotPlugins/APM/APMSubFrameComponentSummary.qml</file>
<file alias="APMNotSupported.qml">../../AutoPilotPlugins/APM/APMNotSupported.qml</file>
<file alias="APMNotSupported.qml">../../AutoPilotPlugins/APM/APMNotSupported.qml</file>
<file alias="APMPowerComponent.qml">../../AutoPilotPlugins/APM/APMPowerComponent.qml</file>
<file alias="APMPowerComponent.qml">../../AutoPilotPlugins/APM/APMPowerComponent.qml</file>
<file alias="APMPowerComponentSummary.qml">../../AutoPilotPlugins/APM/APMPowerComponentSummary.qml</file>
<file alias="APMPowerComponentSummary.qml">../../AutoPilotPlugins/APM/APMPowerComponentSummary.qml</file>
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment