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
d567182b
Commit
d567182b
authored
Mar 04, 2015
by
dogmaphobic
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Tool Bar Tweaks
parent
87c28f2d
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
126 additions
and
49 deletions
+126
-49
UASMessageHandler.cc
src/uas/UASMessageHandler.cc
+4
-0
UASMessageHandler.h
src/uas/UASMessageHandler.h
+5
-0
MainToolBar.cc
src/ui/toolbar/MainToolBar.cc
+57
-19
MainToolBar.h
src/ui/toolbar/MainToolBar.h
+12
-2
MainToolBar.qml
src/ui/toolbar/MainToolBar.qml
+48
-28
No files found.
src/uas/UASMessageHandler.cc
View file @
d567182b
...
...
@@ -49,6 +49,7 @@ UASMessageHandler::UASMessageHandler(QObject *parent)
{
connect
(
UASManager
::
instance
(),
SIGNAL
(
activeUASSet
(
UASInterface
*
)),
this
,
SLOT
(
setActiveUAS
(
UASInterface
*
)));
emit
textMessageReceived
(
NULL
);
emit
textMessageCountChanged
(
0
);
}
UASMessageHandler
::~
UASMessageHandler
()
...
...
@@ -67,6 +68,7 @@ void UASMessageHandler::clearMessages()
_warningCount
=
0
;
_normalCount
=
0
;
_mutex
.
unlock
();
emit
textMessageCountChanged
(
0
);
}
void
UASMessageHandler
::
setActiveUAS
(
UASInterface
*
uas
)
...
...
@@ -160,8 +162,10 @@ void UASMessageHandler::handleTextMessage(int, int compId, int severity, QString
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
));
_messages
.
append
(
message
);
int
count
=
_messages
.
count
();
_mutex
.
unlock
();
emit
textMessageReceived
(
message
);
emit
textMessageCountChanged
(
count
);
}
int
UASMessageHandler
::
getErrorCount
()
{
...
...
src/uas/UASMessageHandler.h
View file @
d567182b
...
...
@@ -127,6 +127,11 @@ signals:
* @param message A pointer to the message. NULL if resetting (new UAS assigned)
*/
void
textMessageReceived
(
UASMessage
*
message
);
/**
* @brief Sent out when the message count changes
* @param count The new message count
*/
void
textMessageCountChanged
(
int
count
);
private:
// Stores the UAS that we're currently receiving messages from.
UASInterface
*
_activeUAS
;
...
...
src/ui/toolbar/MainToolBar.cc
View file @
d567182b
...
...
@@ -48,12 +48,14 @@ MainToolBar::MainToolBar()
,
_waypointDistance
(
0.0
)
,
_currentWaypoint
(
0
)
,
_currentMessageCount
(
0
)
,
_messageCount
(
0
)
,
_currentErrorCount
(
0
)
,
_currentWarningCount
(
0
)
,
_currentNormalCount
(
0
)
,
_currentMessageType
(
MessageNone
)
,
_satelliteCount
(
-
1
)
,
_dotsPerInch
(
72.0
)
,
_dotsPerInch
(
96.0
)
// Default to Windows as it's more likely not to report below
,
_satelliteLock
(
0
)
,
_rollDownMessages
(
0
)
{
setSizePolicy
(
QSizePolicy
::
MinimumExpanding
,
QSizePolicy
::
MinimumExpanding
);
...
...
@@ -68,8 +70,12 @@ MainToolBar::MainToolBar()
}
// 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
if
(
srn
&&
srn
->
logicalDotsPerInch
()
>
50.0
)
{
_dotsPerInch
=
(
qreal
)
srn
->
logicalDotsPerInch
();
// Font point sizes are based on Mac 72dpi
}
else
{
qWarning
()
<<
"System not reporting logical DPI."
;
}
// Give the QML code a way to reach us
setContextPropertyObject
(
"mainToolBar"
,
this
);
setSource
(
QUrl
::
fromUserInput
(
"qrc:/qml/MainToolBar.qml"
));
setVisible
(
true
);
...
...
@@ -187,7 +193,7 @@ void MainToolBar::onEnterMessageArea(int x, int y)
_currentMessageCount
=
0
;
_currentMessageType
=
MessageNone
;
if
(
count
!=
_currentMessageCount
)
{
emit
m
essageCountChanged
(
0
);
emit
newM
essageCountChanged
(
0
);
}
if
(
type
!=
_currentMessageType
)
{
emit
messageTypeChanged
(
MessageNone
);
...
...
@@ -258,12 +264,13 @@ void MainToolBar::_setActiveUAS(UASInterface* active)
// If switching the UAS, disconnect the existing one.
if
(
_mav
)
{
disconnect
(
UASMessageHandler
::
instance
(),
&
UASMessageHandler
::
textMessage
Receiv
ed
,
this
,
&
MainToolBar
::
_handleTextMessage
);
disconnect
(
UASMessageHandler
::
instance
(),
&
UASMessageHandler
::
textMessage
CountChang
ed
,
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
,
&
UASInterface
::
localizationChanged
,
this
,
&
MainToolBar
::
_setSatLoc
);
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
())
...
...
@@ -282,12 +289,13 @@ void MainToolBar::_setActiveUAS(UASInterface* active)
{
_setSystemType
(
_mav
,
_mav
->
getSystemType
());
_updateArmingState
(
_mav
->
isArmed
());
connect
(
UASMessageHandler
::
instance
(),
&
UASMessageHandler
::
textMessage
Received
,
this
,
&
MainToolBar
::
_handleTextMessage
);
connect
(
UASMessageHandler
::
instance
(),
&
UASMessageHandler
::
textMessage
CountChanged
,
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
,
&
UASInterface
::
localizationChanged
,
this
,
&
MainToolBar
::
_setSatLoc
);
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
())
...
...
@@ -315,6 +323,7 @@ void MainToolBar::_updateArmingState(bool armed)
void
MainToolBar
::
_updateBatteryRemaining
(
UASInterface
*
,
double
voltage
,
double
,
double
percent
,
int
)
{
if
(
percent
<
0.0
)
{
percent
=
0.0
;
}
...
...
@@ -510,11 +519,25 @@ void MainToolBar::_heartbeatTimeout(bool timeout, unsigned int ms)
}
}
void
MainToolBar
::
_handleTextMessage
(
UASMessage
*
)
void
MainToolBar
::
_handleTextMessage
(
int
newCount
)
{
// Reset?
if
(
!
newCount
)
{
_currentMessageCount
=
0
;
_currentNormalCount
=
0
;
_currentWarningCount
=
0
;
_currentErrorCount
=
0
;
_messageCount
=
0
;
_currentMessageType
=
MessageNone
;
emit
newMessageCountChanged
(
0
);
emit
messageTypeChanged
(
MessageNone
);
emit
messageCountChanged
(
0
);
return
;
}
UASMessageHandler
*
pMh
=
UASMessageHandler
::
instance
();
Q_ASSERT
(
pMh
);
MessageType_t
type
=
_currentMessageTyp
e
;
MessageType_t
type
=
newCount
?
_currentMessageType
:
MessageNon
e
;
int
errorCount
=
_currentErrorCount
;
int
warnCount
=
_currentWarningCount
;
int
normalCount
=
_currentNormalCount
;
...
...
@@ -542,14 +565,19 @@ void MainToolBar::_handleTextMessage(UASMessage*)
int
count
=
_currentErrorCount
+
_currentWarningCount
+
_currentNormalCount
;
if
(
count
!=
_currentMessageCount
)
{
_currentMessageCount
=
count
;
// Display current total
message
count
emit
m
essageCountChanged
(
count
);
// Display current total
new messages
count
emit
newM
essageCountChanged
(
count
);
}
if
(
type
!=
_currentMessageType
)
{
_currentMessageType
=
type
;
// Update message level
emit
messageTypeChanged
(
type
);
}
// Update message count (all messages)
if
(
newCount
!=
_messageCount
)
{
_messageCount
=
newCount
;
emit
messageCountChanged
(
_messageCount
);
}
}
void
MainToolBar
::
_updateWaypointDistance
(
double
distance
)
...
...
@@ -570,10 +598,20 @@ void MainToolBar::_updateCurrentWaypoint(quint16 id)
void
MainToolBar
::
_setSatelliteCount
(
double
val
,
QString
)
{
if
(
val
<
0.0
)
val
=
0.0
;
if
(
val
>
99.0
)
val
=
99.0
;
// I'm assuming that a negative value or over 99 means there is no GPS
if
(
val
<
0.0
)
val
=
-
1.0
;
if
(
val
>
99.0
)
val
=
-
1.0
;
if
(
_satelliteCount
!=
(
int
)
val
)
{
_satelliteCount
=
(
int
)
val
;
emit
satelliteCountChanged
(
_satelliteCount
);
}
}
void
MainToolBar
::
_setSatLoc
(
UASInterface
*
,
int
fix
)
{
// fix 0: lost, 1: at least one satellite, but no GPS fix, 2: 2D lock, 3: 3D lock
if
(
_satelliteLock
!=
fix
)
{
_satelliteLock
=
fix
;
emit
satelliteLockChanged
(
_satelliteLock
);
}
}
src/ui/toolbar/MainToolBar.h
View file @
d567182b
...
...
@@ -78,6 +78,7 @@ public:
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
newMessageCount
READ
newMessageCount
NOTIFY
newMessageCountChanged
)
Q_PROPERTY
(
int
messageCount
READ
messageCount
NOTIFY
messageCountChanged
)
Q_PROPERTY
(
QString
currentConfig
READ
currentConfig
NOTIFY
currentConfigChanged
)
Q_PROPERTY
(
QString
systemPixmap
READ
systemPixmap
NOTIFY
systemPixmapChanged
)
...
...
@@ -86,6 +87,7 @@ public:
Q_PROPERTY
(
bool
mavPresent
READ
mavPresent
NOTIFY
mavPresentChanged
)
Q_PROPERTY
(
QString
currentState
READ
currentState
NOTIFY
currentStateChanged
)
Q_PROPERTY
(
double
dotsPerInch
READ
dotsPerInch
NOTIFY
dotsPerInchChanged
)
Q_PROPERTY
(
int
satelliteLock
READ
satelliteLock
NOTIFY
satelliteLockChanged
)
int
connectionCount
()
{
return
_connectionCount
;
}
double
batteryVoltage
()
{
return
_batteryVoltage
;
}
...
...
@@ -96,7 +98,8 @@ public:
unsigned
int
heartbeatTimeout
()
{
return
_currentHeartbeatTimeout
;
}
QString
currentMode
()
{
return
_currentMode
;
}
MessageType_t
messageType
()
{
return
_currentMessageType
;
}
int
messageCount
()
{
return
_currentMessageCount
;
}
int
newMessageCount
()
{
return
_currentMessageCount
;
}
int
messageCount
()
{
return
_messageCount
;
}
QString
currentConfig
()
{
return
_currentConfig
;
}
QString
systemPixmap
()
{
return
_systemPixmap
;
}
int
satelliteCount
()
{
return
_satelliteCount
;
}
...
...
@@ -104,6 +107,7 @@ public:
bool
mavPresent
()
{
return
_mav
!=
NULL
;
}
QString
currentState
()
{
return
_currentState
;
}
double
dotsPerInch
()
{
return
_dotsPerInch
;
}
int
satelliteLock
()
{
return
_satelliteLock
;
}
void
setCurrentView
(
int
currentView
);
...
...
@@ -117,6 +121,7 @@ signals:
void
heartbeatTimeoutChanged
(
unsigned
int
hbTimeout
);
void
currentModeChanged
();
void
messageTypeChanged
(
MessageType_t
type
);
void
newMessageCountChanged
(
int
count
);
void
messageCountChanged
(
int
count
);
void
currentConfigChanged
(
QString
config
);
void
systemPixmapChanged
(
QPixmap
pix
);
...
...
@@ -125,6 +130,7 @@ signals:
void
mavPresentChanged
(
bool
present
);
void
currentStateChanged
(
QString
state
);
void
dotsPerInchChanged
();
void
satelliteLockChanged
(
int
lock
);
private
slots
:
void
_setActiveUAS
(
UASInterface
*
active
);
...
...
@@ -138,11 +144,13 @@ private slots:
void
_updateName
(
const
QString
&
name
);
void
_setSystemType
(
UASInterface
*
uas
,
unsigned
int
systemType
);
void
_heartbeatTimeout
(
bool
timeout
,
unsigned
int
ms
);
void
_handleTextMessage
(
UASMessage
*
message
);
void
_handleTextMessage
(
int
newCount
);
void
_updateCurrentWaypoint
(
quint16
id
);
void
_updateWaypointDistance
(
double
distance
);
void
_setSatelliteCount
(
double
val
,
QString
name
);
void
_leaveMessageView
();
void
_setSatLoc
(
UASInterface
*
uas
,
int
fix
);
private:
void
_updateConnection
(
LinkInterface
*
disconnectedLink
=
NULL
);
...
...
@@ -166,6 +174,7 @@ private:
double
_waypointDistance
;
quint16
_currentWaypoint
;
int
_currentMessageCount
;
int
_messageCount
;
int
_currentErrorCount
;
int
_currentWarningCount
;
int
_currentNormalCount
;
...
...
@@ -173,6 +182,7 @@ private:
int
_satelliteCount
;
QStringList
_connectedList
;
qreal
_dotsPerInch
;
int
_satelliteLock
;
UASMessageViewRollDown
*
_rollDownMessages
;
};
...
...
src/ui/toolbar/MainToolBar.qml
View file @
d567182b
...
...
@@ -45,7 +45,8 @@ Rectangle {
property
double
dpiFactor
:
(
72.0
/
mainToolBar
.
dotsPerInch
);
property
var
colorBlue
:
"
#1a6eaa
"
property
var
colorGreen
:
"
#00d930
"
property
var
colorGreen
:
"
#079527
"
property
var
colorGreenText
:
"
#00d930
"
property
var
colorRed
:
"
#a81a1b
"
property
var
colorOrange
:
"
#a76f26
"
property
var
colorWhite
:
"
#f0f0f0
"
...
...
@@ -88,6 +89,29 @@ Rectangle {
return
"
qrc:/files/images/status/battery_100.svg
"
;
}
function
getBatteryColor
()
{
if
(
mainToolBar
.
batteryPercent
>
40.0
)
return
colorGreen
;
if
(
mainToolBar
.
batteryPercent
>
0.01
)
return
colorRed
;
// This means there is no battery level data
return
colorBlue
;
}
function
getSatelliteColor
()
{
// No GPS data
if
(
mainToolBar
.
satelliteCount
<
0
)
return
qgcPal
.
button
// No Lock
if
(
mainToolBar
.
satelliteLock
<
2
)
return
colorRed
;
// 2D Lock
if
(
mainToolBar
.
satelliteLock
===
2
)
return
colorBlue
;
// Lock is 3D or more
return
colorGreen
;
}
function
showMavStatus
()
{
return
(
mainToolBar
.
mavPresent
&&
mainToolBar
.
heartbeatTimeout
===
0
&&
mainToolBar
.
connectionCount
>
0
);
}
...
...
@@ -164,7 +188,7 @@ Rectangle {
Rectangle
{
id
:
messages
width
:
(
mainToolBar
.
m
essageCount
>
99
)
?
70
:
60
width
:
(
mainToolBar
.
newM
essageCount
>
99
)
?
70
:
60
height
:
cellHeight
visible
:
(
mainToolBar
.
connectionCount
>
0
)
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -191,7 +215,7 @@ Rectangle {
width
:
messages
.
width
-
messageIcon
.
width
Text
{
id
:
messageText
text
:
(
mainToolBar
.
messageCount
>
0
)
?
mainToolBar
.
m
essageCount
:
''
text
:
(
mainToolBar
.
newMessageCount
>
0
)
?
mainToolBar
.
newM
essageCount
:
''
font.pointSize
:
14
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -204,7 +228,7 @@ Rectangle {
Image
{
id
:
dropDown
source
:
"
QGroundControl/Controls/arrow-down.png
"
visible
:
(
messages
.
showTriangle
)
visible
:
(
messages
.
showTriangle
)
&&
(
mainToolBar
.
messageCount
>
0
)
anchors.bottom
:
parent
.
bottom
anchors.right
:
parent
.
right
anchors.bottomMargin
:
3
...
...
@@ -228,14 +252,13 @@ Rectangle {
messages
.
showTriangle
=
true
;
mouseOffTimer
.
start
();
}
onExited
:
{
messages
.
showTriangle
=
false
;
}
onClicked
:
{
if
(
mainToolBar
.
messageCount
>
0
)
{
var
p
=
mapToItem
(
toolBarHolder
,
mouseX
,
mouseY
);
mainToolBar
.
onEnterMessageArea
(
p
.
x
,
p
.
y
);
}
}
}
}
...
...
@@ -262,9 +285,9 @@ Rectangle {
id
:
satelitte
width
:
60
height
:
cellHeight
visible
:
showMavStatus
()
visible
:
showMavStatus
()
;
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
(
mainToolBar
.
satelliteCount
<
3
)
?
colorRed
:
colorBlue
color
:
getSatelliteColor
();
radius
:
cellRadius
border.color
:
"
#00000000
"
border.width
:
0
...
...
@@ -282,7 +305,7 @@ Rectangle {
Text
{
id
:
satelitteText
text
:
mainToolBar
.
satelliteCount
text
:
(
mainToolBar
.
satelliteCount
>
0
)
?
mainToolBar
.
satelliteCount
:
''
font.pointSize
:
14
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -299,7 +322,7 @@ Rectangle {
height
:
cellHeight
visible
:
showMavStatus
()
anchors.verticalCenter
:
parent
.
verticalCenter
color
:
(
mainToolBar
.
batteryPercent
>
40.0
||
mainToolBar
.
batteryPercent
<
0.01
)
?
color
Blue
:
colorRed
color
:
(
mainToolBar
.
batteryPercent
>
40.0
||
mainToolBar
.
batteryPercent
<
0.01
)
?
color
Green
:
colorRed
radius
:
cellRadius
border.color
:
"
#00000000
"
border.width
:
0
...
...
@@ -317,7 +340,7 @@ Rectangle {
Text
{
id
:
batteryText
text
:
mainToolBar
.
batteryVoltage
.
toFixed
(
2
)
+
'
V
'
;
text
:
mainToolBar
.
batteryVoltage
.
toFixed
(
1
)
+
'
V
'
;
font.pointSize
:
14
*
dpiFactor
font.weight
:
Font
.
DemiBold
anchors.verticalCenter
:
parent
.
verticalCenter
...
...
@@ -329,11 +352,10 @@ Rectangle {
}
Column
{
anchors.verticalCenter
:
parent
.
verticalCenter
spacing
:
cellSpacerSize
visible
:
showMavStatus
()
height
:
cellHeight
*
0.7
5
height
:
cellHeight
*
0.8
5
width
:
80
anchors.verticalCenter
:
parent
.
verticalCenter
Rectangle
{
id
:
armedStatus
...
...
@@ -349,9 +371,8 @@ Rectangle {
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
anchors.centerIn
:
parent
color
:
(
mainToolBar
.
systemArmed
)
?
colorRed
:
colorGreenText
}
}
...
...
@@ -369,9 +390,8 @@ Rectangle {
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
anchors.centerIn
:
parent
color
:
(
mainToolBar
.
currentState
===
"
STANDBY
"
)
?
colorGreenText
:
colorRed
}
}
...
...
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