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
939ee6f4
Commit
939ee6f4
authored
Jan 02, 2016
by
dogmaphobic
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implemented Log Download
parent
8ccf64f0
Changes
11
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1152 additions
and
23 deletions
+1152
-23
qgroundcontrol.pro
qgroundcontrol.pro
+4
-0
qgroundcontrol.qrc
qgroundcontrol.qrc
+1
-0
QGCApplication.cc
src/QGCApplication.cc
+3
-1
LogDownload.cc
src/ViewWidgets/LogDownload.cc
+34
-0
LogDownload.h
src/ViewWidgets/LogDownload.h
+37
-0
LogDownload.qml
src/ViewWidgets/LogDownload.qml
+210
-0
LogDownloadController.cc
src/ViewWidgets/LogDownloadController.cc
+621
-0
LogDownloadController.h
src/ViewWidgets/LogDownloadController.h
+193
-0
UAS.cc
src/uas/UAS.cc
+17
-0
UASInterface.h
src/uas/UASInterface.h
+24
-20
MainWindow.cc
src/ui/MainWindow.cc
+8
-2
No files found.
qgroundcontrol.pro
View file @
939ee6f4
...
...
@@ -356,6 +356,8 @@ HEADERS += \
src
/
VehicleSetup
/
JoystickConfigController
.
h
\
src
/
ViewWidgets
/
CustomCommandWidget
.
h
\
src
/
ViewWidgets
/
CustomCommandWidgetController
.
h
\
src
/
ViewWidgets
/
LogDownload
.
h
\
src
/
ViewWidgets
/
LogDownloadController
.
h
\
src
/
ViewWidgets
/
ViewWidgetController
.
h
\
}
...
...
@@ -468,6 +470,8 @@ SOURCES += \
src
/
VehicleSetup
/
JoystickConfigController
.
cc
\
src
/
ViewWidgets
/
CustomCommandWidget
.
cc
\
src
/
ViewWidgets
/
CustomCommandWidgetController
.
cc
\
src
/
ViewWidgets
/
LogDownload
.
cc
\
src
/
ViewWidgets
/
LogDownloadController
.
cc
\
src
/
ViewWidgets
/
ViewWidgetController
.
cc
\
}
...
...
qgroundcontrol.qrc
View file @
939ee6f4
...
...
@@ -11,6 +11,7 @@
<file alias="APMAirframeComponent.qml">src/AutoPilotPlugins/APM/APMAirframeComponent.qml</file>
<file alias="APMAirframeComponentSummary.qml">src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml</file>
<file alias="CustomCommandWidget.qml">src/ViewWidgets/CustomCommandWidget.qml</file>
<file alias="LogDownload.qml">src/ViewWidgets/LogDownload.qml</file>
<file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file>
<file alias="FlightDisplayView.qml">src/FlightDisplay/FlightDisplayView.qml</file>
<file alias="FlightModesComponent.qml">src/AutoPilotPlugins/PX4/FlightModesComponent.qml</file>
...
...
src/QGCApplication.cc
View file @
939ee6f4
...
...
@@ -95,6 +95,7 @@
#include "FlightDisplayViewController.h"
#include "VideoSurface.h"
#include "VideoReceiver.h"
#include "LogDownloadController.h"
#ifndef __ios__
#include "SerialLink.h"
...
...
@@ -396,6 +397,7 @@ void QGCApplication::_initCommon(void)
qmlRegisterType
<
CustomCommandWidgetController
>
(
"QGroundControl.Controllers"
,
1
,
0
,
"CustomCommandWidgetController"
);
qmlRegisterType
<
FirmwareUpgradeController
>
(
"QGroundControl.Controllers"
,
1
,
0
,
"FirmwareUpgradeController"
);
qmlRegisterType
<
JoystickConfigController
>
(
"QGroundControl.Controllers"
,
1
,
0
,
"JoystickConfigController"
);
qmlRegisterType
<
LogDownloadController
>
(
"QGroundControl.Controllers"
,
1
,
0
,
"LogDownloadController"
);
#endif
// Register Qml Singletons
...
...
src/ViewWidgets/LogDownload.cc
0 → 100644
View file @
939ee6f4
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2010 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/>.
======================================================================*/
#include "LogDownload.h"
LogDownload
::
LogDownload
(
const
QString
&
title
,
QAction
*
action
,
QWidget
*
parent
)
:
QGCQmlWidgetHolder
(
title
,
action
,
parent
)
{
Q_UNUSED
(
title
);
Q_UNUSED
(
action
);
setSource
(
QUrl
::
fromUserInput
(
"qrc:/qml/LogDownload.qml"
));
loadSettings
();
}
src/ViewWidgets/LogDownload.h
0 → 100644
View file @
939ee6f4
/*=====================================================================
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/>.
======================================================================*/
#ifndef LogDownload_H
#define LogDownload_H
#include "QGCQmlWidgetHolder.h"
class
LogDownload
:
public
QGCQmlWidgetHolder
{
Q_OBJECT
public:
LogDownload
(
const
QString
&
title
,
QAction
*
action
,
QWidget
*
parent
=
0
);
};
#endif
src/ViewWidgets/LogDownload.qml
0 → 100644
View file @
939ee6f4
/*=====================================================================
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/>.
======================================================================*/
import
QtQuick
2.5
import
QtQuick
.
Controls
1.2
import
QtQuick
.
Controls
.
Styles
1.2
import
QtQuick
.
Dialogs
1.2
import
QGroundControl
.
Palette
1.0
import
QGroundControl
.
Controls
1.0
import
QGroundControl
.
Controllers
1.0
import
QGroundControl
.
ScreenTools
1.0
QGCView
{
viewPanel
:
panel
property
real
_margins
:
ScreenTools
.
defaultFontPixelHeight
function
numberWithCommas
(
x
)
{
return
x
.
toString
().
replace
(
/
\B(?=(\d{3})
+
(?!\d))
/g
,
"
,
"
).
replace
(
/,,/g
,
"
,
"
);
}
LogDownloadController
{
id
:
controller
factPanel
:
panel
onSelectionChanged
:
{
tableView
.
selection
.
clear
()
for
(
var
i
=
0
;
i
<
controller
.
model
.
count
;
i
++
)
{
var
o
=
controller
.
model
.
get
(
i
)
if
(
o
&&
o
.
selected
)
{
tableView
.
selection
.
select
(
i
,
i
)
}
}
}
}
QGCPalette
{
id
:
palette
;
colorGroupEnabled
:
enabled
}
QGCViewPanel
{
id
:
panel
anchors.fill
:
parent
TableView
{
id
:
tableView
anchors.margins
:
_margins
anchors.left
:
parent
.
left
anchors.right
:
refreshButton
.
left
anchors.top
:
parent
.
top
anchors.bottom
:
parent
.
bottom
model
:
controller
.
model
selectionMode
:
SelectionMode
.
MultiSelection
TableViewColumn
{
title
:
"
Id
"
width
:
ScreenTools
.
defaultFontPixelWidth
*
4
horizontalAlignment
:
Text
.
AlignHCenter
delegate
:
Text
{
horizontalAlignment
:
Text
.
AlignHCenter
text
:
{
var
o
=
controller
.
model
.
get
(
styleData
.
row
)
return
o
?
o
.
id
:
""
}
}
}
TableViewColumn
{
title
:
"
Date
"
width
:
ScreenTools
.
defaultFontPixelWidth
*
30
horizontalAlignment
:
Text
.
AlignHCenter
delegate
:
Text
{
text
:
{
var
o
=
controller
.
model
.
get
(
styleData
.
row
)
if
(
o
)
{
//-- Have we received this entry already?
if
(
controller
.
model
.
get
(
styleData
.
row
).
received
)
{
var
d
=
controller
.
model
.
get
(
styleData
.
row
).
time
if
(
d
.
getUTCFullYear
()
<
1980
)
return
"
Date Unknown
"
else
return
d
.
toLocaleString
()
}
}
return
""
}
}
}
TableViewColumn
{
title
:
"
Size
"
width
:
ScreenTools
.
defaultFontPixelWidth
*
12
horizontalAlignment
:
Text
.
AlignHCenter
delegate
:
Text
{
horizontalAlignment
:
Text
.
AlignRight
text
:
{
var
o
=
controller
.
model
.
get
(
styleData
.
row
)
return
o
?
numberWithCommas
(
o
.
size
)
:
""
}
}
}
TableViewColumn
{
title
:
"
Status
"
width
:
ScreenTools
.
defaultFontPixelWidth
*
18
horizontalAlignment
:
Text
.
AlignHCenter
delegate
:
Text
{
horizontalAlignment
:
Text
.
AlignHCenter
text
:
{
var
o
=
controller
.
model
.
get
(
styleData
.
row
)
return
o
?
o
.
status
:
""
}
}
}
}
QGCButton
{
id
:
refreshButton
anchors.margins
:
_margins
anchors.top
:
parent
.
top
anchors.right
:
parent
.
right
enabled
:
!
controller
.
requestingList
&&
!
controller
.
downloadingLogs
text
:
"
Refresh
"
onClicked
:
{
controller
.
refresh
()
}
}
QGCButton
{
id
:
downloadButton
anchors.margins
:
_margins
anchors.top
:
refreshButton
.
bottom
anchors.right
:
parent
.
right
enabled
:
!
controller
.
requestingList
&&
!
controller
.
downloadingLogs
&&
tableView
.
selection
.
count
>
0
text
:
"
Download
"
onClicked
:
{
//-- Clear selection
for
(
var
i
=
0
;
i
<
controller
.
model
.
count
;
i
++
)
{
var
o
=
controller
.
model
.
get
(
i
)
if
(
o
)
o
.
selected
=
false
}
//-- Flag selected log files
tableView
.
selection
.
forEach
(
function
(
rowIndex
){
var
o
=
controller
.
model
.
get
(
rowIndex
)
if
(
o
)
o
.
selected
=
true
})
//-- Download them
controller
.
download
()
}
}
QGCButton
{
id
:
eraseAllButton
anchors.margins
:
_margins
anchors.top
:
downloadButton
.
bottom
anchors.right
:
parent
.
right
enabled
:
!
controller
.
requestingList
&&
!
controller
.
downloadingLogs
&&
controller
.
model
.
count
>
0
text
:
"
Erase All
"
onClicked
:
{
eraseAllDialog
.
visible
=
true
}
MessageDialog
{
id
:
eraseAllDialog
visible
:
false
icon
:
StandardIcon
.
Warning
standardButtons
:
StandardButton
.
Yes
|
StandardButton
.
No
title
:
"
Delete All Log Files
"
text
:
"
All log files will be erased permanently. Is this really what you want?
"
onYes
:
{
controller
.
eraseAll
()
eraseAllDialog
.
visible
=
false
}
onNo
:
{
eraseAllDialog
.
visible
=
false
}
}
}
QGCButton
{
id
:
cancelButton
anchors.margins
:
_margins
anchors.top
:
eraseAllButton
.
bottom
anchors.right
:
parent
.
right
text
:
"
Cancel
"
enabled
:
controller
.
requestingList
||
controller
.
downloadingLogs
onClicked
:
{
controller
.
cancel
()
}
}
}
}
src/ViewWidgets/LogDownloadController.cc
0 → 100644
View file @
939ee6f4
This diff is collapsed.
Click to expand it.
src/ViewWidgets/LogDownloadController.h
0 → 100644
View file @
939ee6f4
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 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/>.
======================================================================*/
#ifndef LogDownloadController_H
#define LogDownloadController_H
#include <QObject>
#include <QTimer>
#include <QAbstractListModel>
#include <memory>
#include "UASInterface.h"
#include "AutoPilotPlugin.h"
#include "FactPanelController.h"
class
MultiVehicleManager
;
class
UASInterface
;
class
Vehicle
;
class
QGCLogEntry
;
class
LogDownloadData
;
Q_DECLARE_LOGGING_CATEGORY
(
LogDownloadLog
)
//-----------------------------------------------------------------------------
class
QGCLogModel
:
public
QAbstractListModel
{
Q_OBJECT
public:
enum
QGCLogModelRoles
{
ObjectRole
=
Qt
::
UserRole
+
1
};
QGCLogModel
(
QObject
*
parent
=
0
);
Q_PROPERTY
(
int
count
READ
count
NOTIFY
countChanged
)
Q_INVOKABLE
QGCLogEntry
*
get
(
int
index
);
int
count
(
void
)
const
;
void
append
(
QGCLogEntry
*
entry
);
void
clear
(
void
);
QGCLogEntry
*
operator
[]
(
int
i
);
int
rowCount
(
const
QModelIndex
&
parent
=
QModelIndex
())
const
;
QVariant
data
(
const
QModelIndex
&
index
,
int
role
=
Qt
::
DisplayRole
)
const
;
signals:
void
countChanged
();
protected:
QHash
<
int
,
QByteArray
>
roleNames
()
const
;
private:
QList
<
QGCLogEntry
*>
_logEntries
;
};
//-----------------------------------------------------------------------------
class
QGCLogEntry
:
public
QObject
{
Q_OBJECT
Q_PROPERTY
(
uint
id
READ
id
CONSTANT
)
Q_PROPERTY
(
QDateTime
time
READ
time
NOTIFY
timeChanged
)
Q_PROPERTY
(
uint
size
READ
size
NOTIFY
sizeChanged
)
Q_PROPERTY
(
bool
received
READ
received
NOTIFY
receivedChanged
)
Q_PROPERTY
(
bool
selected
READ
selected
WRITE
setSelected
NOTIFY
selectedChanged
)
Q_PROPERTY
(
QString
status
READ
status
NOTIFY
statusChanged
)
public:
QGCLogEntry
(
uint
logId
,
const
QDateTime
&
dateTime
=
QDateTime
(),
uint
logSize
=
0
,
bool
received
=
false
);
uint
id
()
const
{
return
_logID
;
}
uint
size
()
const
{
return
_logSize
;
}
QDateTime
time
()
const
{
return
_logTimeUTC
;
}
bool
received
()
const
{
return
_received
;
}
bool
selected
()
const
{
return
_selected
;
}
QString
status
()
const
{
return
_status
;
}
void
setId
(
uint
id_
)
{
_logID
=
id_
;
}
void
setSize
(
uint
size_
)
{
_logSize
=
size_
;
emit
sizeChanged
();
}
void
setTime
(
QDateTime
date_
)
{
_logTimeUTC
=
date_
;
emit
timeChanged
();
}
void
setReceived
(
bool
rec_
)
{
_received
=
rec_
;
emit
receivedChanged
();
}
void
setSelected
(
bool
sel_
)
{
_selected
=
sel_
;
emit
selectedChanged
();
}
void
setStatus
(
QString
stat_
)
{
_status
=
stat_
;
emit
statusChanged
();
}
signals:
void
idChanged
();
void
timeChanged
();
void
sizeChanged
();
void
receivedChanged
();
void
selectedChanged
();
void
statusChanged
();
private:
uint
_logID
;
uint
_logSize
;
QDateTime
_logTimeUTC
;
bool
_received
;
bool
_selected
;
QString
_status
;
};
//-----------------------------------------------------------------------------
class
LogDownloadData
{
public:
LogDownloadData
(
QGCLogEntry
*
entry
);
QList
<
uint
>
offsets
;
QFile
file
;
QString
filename
;
uint
ID
;
QTimer
processDataTimer
;
QGCLogEntry
*
entry
;
uint
written
;
};
//-----------------------------------------------------------------------------
class
LogDownloadController
:
public
FactPanelController
{
Q_OBJECT
public:
LogDownloadController
();
Q_PROPERTY
(
QGCLogModel
*
model
READ
model
NOTIFY
modelChanged
)
Q_PROPERTY
(
bool
requestingList
READ
requestingList
NOTIFY
requestingListChanged
)
Q_PROPERTY
(
bool
downloadingLogs
READ
downloadingLogs
NOTIFY
downloadingLogsChanged
)
QGCLogModel
*
model
()
{
return
&
_logEntriesModel
;
}
bool
requestingList
()
{
return
_requestingLogEntries
;
}
bool
downloadingLogs
()
{
return
_downloadingLogs
;
}
Q_INVOKABLE
void
refresh
();
Q_INVOKABLE
void
download
();
Q_INVOKABLE
void
eraseAll
();
Q_INVOKABLE
void
cancel
();
signals:
void
requestingListChanged
();
void
downloadingLogsChanged
();
void
modelChanged
();
void
selectionChanged
();
private
slots
:
void
_setActiveVehicle
(
Vehicle
*
vehicle
);
void
_logEntry
(
UASInterface
*
uas
,
uint32_t
time_utc
,
uint32_t
size
,
uint16_t
id
,
uint16_t
num_logs
,
uint16_t
last_log_num
);
void
_logData
(
UASInterface
*
uas
,
uint32_t
ofs
,
uint16_t
id
,
uint8_t
count
,
const
uint8_t
*
data
);
void
_processDownload
();
private:
bool
_entriesComplete
();
bool
_logComplete
();
void
_findMissingEntries
();
void
_receivedAllEntries
();
void
_receivedAllData
();
void
_resetSelection
();
void
_findMissingData
();
void
_requestLogList
(
uint32_t
start
=
0
,
uint32_t
end
=
0xFFFF
);
void
_requestLogData
(
uint8_t
id
,
uint32_t
offset
=
0
,
uint32_t
count
=
0xFFFFFFFF
);
bool
_prepareLogDownload
();
QGCLogEntry
*
_getNextSelected
();
UASInterface
*
_uas
;
LogDownloadData
*
_downloadData
;
QTimer
_timer
;
QGCLogModel
_logEntriesModel
;
Vehicle
*
_vehicle
;
bool
_requestingLogEntries
;
bool
_downloadingLogs
;
int
_retries
;
QString
_downloadPath
;
};
#endif
src/uas/UAS.cc
View file @
939ee6f4
...
...
@@ -960,6 +960,23 @@ void UAS::receiveMessage(mavlink_message_t message)
emit
NavigationControllerDataChanged
(
this
,
p
.
nav_roll
,
p
.
nav_pitch
,
p
.
nav_bearing
,
p
.
target_bearing
,
p
.
wp_dist
);
}
break
;
case
MAVLINK_MSG_ID_LOG_ENTRY
:
{
mavlink_log_entry_t
log
;
mavlink_msg_log_entry_decode
(
&
message
,
&
log
);
emit
logEntry
(
this
,
log
.
time_utc
,
log
.
size
,
log
.
id
,
log
.
num_logs
,
log
.
last_log_num
);
}
break
;
case
MAVLINK_MSG_ID_LOG_DATA
:
{
mavlink_log_data_t
log
;
mavlink_msg_log_data_decode
(
&
message
,
&
log
);
emit
logData
(
this
,
log
.
ofs
,
log
.
id
,
log
.
count
,
log
.
data
);
}
break
;
default:
break
;
}
...
...
src/uas/UASInterface.h
View file @
939ee6f4
...
...
@@ -323,6 +323,10 @@ signals:
// HOME POSITION / ORIGIN CHANGES
void
homePositionChanged
(
int
uas
,
double
lat
,
double
lon
,
double
alt
);
// Log Download Signals
void
logEntry
(
UASInterface
*
uas
,
uint32_t
time_utc
,
uint32_t
size
,
uint16_t
id
,
uint16_t
num_logs
,
uint16_t
last_log_num
);
void
logData
(
UASInterface
*
uas
,
uint32_t
ofs
,
uint16_t
id
,
uint8_t
count
,
const
uint8_t
*
data
);
protected:
// TIMEOUT CONSTANTS
...
...
src/ui/MainWindow.cc
View file @
939ee6f4
...
...
@@ -65,6 +65,7 @@ This file is part of the QGROUNDCONTROL project
#include "QGCDockWidget.h"
#include "UASInfoWidget.h"
#include "HILDockWidget.h"
#include "LogDownload.h"
#endif
#ifndef __ios__
...
...
@@ -86,7 +87,8 @@ enum DockWidgetTypes {
STATUS_DETAILS
,
INFO_VIEW
,
HIL_CONFIG
,
ANALYZE
ANALYZE
,
LOG_DOWNLOAD
};
static
const
char
*
rgDockWidgetNames
[]
=
{
...
...
@@ -96,7 +98,8 @@ static const char *rgDockWidgetNames[] = {
"Status Details"
,
"Info View"
,
"HIL Config"
,
"Analyze"
"Analyze"
,
"Log Download"
};
#define ARRAY_SIZE(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))
...
...
@@ -358,6 +361,9 @@ void MainWindow::_createInnerDockWidget(const QString& widgetName)
case
ONBOARD_FILES
:
widget
=
new
QGCUASFileViewMulti
(
widgetName
,
action
,
this
);
break
;
case
LOG_DOWNLOAD
:
widget
=
new
LogDownload
(
widgetName
,
action
,
this
);
break
;
case
STATUS_DETAILS
:
widget
=
new
UASInfoWidget
(
widgetName
,
action
,
this
);
break
;
...
...
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