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
5868dbc1
Commit
5868dbc1
authored
Aug 12, 2014
by
Don Gagne
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added progress indicator, download speed
Also updated to latest QGCUASFileManager implementation.
parent
1fa53faa
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
215 additions
and
83 deletions
+215
-83
QGCUASFileView.cc
src/ui/QGCUASFileView.cc
+171
-71
QGCUASFileView.h
src/ui/QGCUASFileView.h
+19
-10
QGCUASFileView.ui
src/ui/QGCUASFileView.ui
+25
-2
No files found.
src/ui/QGCUASFileView.cc
View file @
5868dbc1
...
...
@@ -30,107 +30,190 @@
QGCUASFileView
::
QGCUASFileView
(
QWidget
*
parent
,
QGCUASFileManager
*
manager
)
:
QWidget
(
parent
),
_manager
(
manager
)
_manager
(
manager
),
_listInProgress
(
false
),
_downloadInProgress
(
false
)
{
_ui
.
setupUi
(
this
);
bool
success
=
connect
(
_ui
.
listFilesButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
_refreshTree
()));
// Progress bar is only visible while a download is in progress
_ui
.
progressBar
->
setVisible
(
false
);
bool
success
;
Q_UNUSED
(
success
);
// Silence retail unused variable error
// Connect UI signals
success
=
connect
(
_ui
.
listFilesButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
_refreshTree
()));
Q_ASSERT
(
success
);
success
=
connect
(
_ui
.
downloadButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
_downloadFile
s
()));
success
=
connect
(
_ui
.
downloadButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
_downloadFile
()));
Q_ASSERT
(
success
);
success
=
connect
(
_ui
.
treeWidget
,
SIGNAL
(
currentItemChanged
(
QTreeWidgetItem
*
,
QTreeWidgetItem
*
)),
this
,
SLOT
(
_currentItemChanged
(
QTreeWidgetItem
*
,
QTreeWidgetItem
*
)));
Q_ASSERT
(
success
);
success
=
connect
(
&
_listCompleteTimer
,
SIGNAL
(
timeout
()),
this
,
SLOT
(
_listCompleteTimeout
()));
Q_ASSERT
(
success
);
Q_UNUSED
(
success
);
// Silence retail unused variable error
}
void
QGCUASFileView
::
_downloadFiles
(
void
)
/// @brief Downloads the file currently selected in the tree view
void
QGCUASFileView
::
_downloadFile
(
void
)
{
QString
dir
=
QFileDialog
::
getExistingDirectory
(
this
,
tr
(
"Download Directory"
),
Q_ASSERT
(
!
_downloadInProgress
);
_ui
.
statusText
->
clear
();
QString
downloadToHere
=
QFileDialog
::
getExistingDirectory
(
this
,
tr
(
"Download Directory"
),
QDir
::
homePath
(),
QFileDialog
::
ShowDirsOnly
|
QFileDialog
::
DontResolveSymlinks
);
// And now download to this location
QString
path
;
QTreeWidgetItem
*
item
=
_ui
.
treeWidget
->
currentItem
();
if
(
item
&&
item
->
type
()
==
_typeFile
)
{
_downloadFilename
.
clear
();
do
{
QString
name
=
item
->
text
(
0
).
split
(
"
\t
"
)[
0
];
// Strip off file sizes
// If this is the file name and not a directory keep track of the download file name
if
(
_downloadFilename
.
isEmpty
())
{
_downloadFilename
=
name
;
}
path
.
prepend
(
"/"
+
name
);
item
=
item
->
parent
();
}
while
(
item
);
qDebug
()
<<
"Download: "
<<
path
;
bool
success
=
connect
(
_manager
,
SIGNAL
(
statusMessage
(
QString
)),
this
,
SLOT
(
_downloadStatusMessage
(
QString
)));
Q_ASSERT
(
success
);
success
=
connect
(
_manager
,
SIGNAL
(
errorMessage
(
QString
)),
this
,
SLOT
(
_downloadStatusMessage
(
QString
)));
Q_ASSERT
(
success
);
Q_UNUSED
(
success
);
_manager
->
downloadPath
(
path
,
QDir
(
dir
));
_ui
.
downloadButton
->
setEnabled
(
false
);
_downloadInProgress
=
true
;
_connectDownloadSignals
();
_manager
->
downloadPath
(
path
,
QDir
(
downloadToHere
));
}
}
/// @brief Called when length of file being downloaded is known.
void
QGCUASFileView
::
_downloadLength
(
unsigned
int
length
)
{
Q_ASSERT
(
_downloadInProgress
);
// Setup the progress bar
QProgressBar
*
bar
=
_ui
.
progressBar
;
bar
->
setMinimum
(
0
);
bar
->
setMaximum
(
length
);
bar
->
setValue
(
0
);
bar
->
setVisible
(
true
);
_ui
.
downloadButton
->
setEnabled
(
true
);
_downloadStartTime
.
start
();
_ui
.
statusText
->
setText
(
tr
(
"Downloading: %1"
).
arg
(
_downloadFilename
));
}
/// @brief Called to update the progress of the download.
/// @param bytesReceived Current count of bytes received for current download
void
QGCUASFileView
::
_downloadProgress
(
unsigned
int
bytesReceived
)
{
static
uint
lastSecsReported
=
0
;
Q_ASSERT
(
_downloadInProgress
);
_ui
.
progressBar
->
setValue
(
bytesReceived
);
// Calculate and display download rate. Only update once per second.
uint
kbReceived
=
bytesReceived
/
1024
;
uint
secs
=
_downloadStartTime
.
elapsed
()
/
1000
;
if
(
secs
!=
0
)
{
uint
kbPerSec
=
kbReceived
/
secs
;
if
(
kbPerSec
!=
0
&&
secs
!=
lastSecsReported
)
{
lastSecsReported
=
secs
;
_ui
.
statusText
->
setText
(
tr
(
"Downloading: %1 %2 KB/sec"
).
arg
(
_downloadFilename
).
arg
(
kbPerSec
));
}
}
}
/// @brief Called when the download associated with the QGCUASFileManager::downloadPath command completes.
void
QGCUASFileView
::
_downloadComplete
(
void
)
{
Q_ASSERT
(
_downloadInProgress
);
_ui
.
downloadButton
->
setEnabled
(
true
);
_ui
.
progressBar
->
setVisible
(
false
);
_downloadInProgress
=
false
;
_disconnectDownloadSignals
();
_ui
.
statusText
->
setText
(
tr
(
"Download complete: %1"
).
arg
(
_downloadFilename
));
}
/// @brief Called when an error occurs during a download.
/// @param msg Error message
void
QGCUASFileView
::
_downloadErrorMessage
(
const
QString
&
msg
)
{
if
(
_downloadInProgress
)
{
_ui
.
downloadButton
->
setEnabled
(
true
);
_ui
.
progressBar
->
setVisible
(
false
);
_downloadInProgress
=
false
;
_disconnectDownloadSignals
();
_ui
.
statusText
->
setText
(
tr
(
"Error: "
)
+
msg
);
}
}
/// @brief Refreshes the directory list tree.
void
QGCUASFileView
::
_refreshTree
(
void
)
{
Q_ASSERT
(
!
_listInProgress
);
_ui
.
treeWidget
->
clear
();
_ui
.
statusText
->
clear
();
_walkIndexStack
.
clear
();
_walkItemStack
.
clear
();
_walkIndexStack
.
append
(
0
);
_walkItemStack
.
append
(
_ui
.
treeWidget
->
invisibleRootItem
());
bool
success
=
connect
(
_manager
,
SIGNAL
(
statusMessage
(
QString
)),
this
,
SLOT
(
_treeStatusMessage
(
QString
)));
Q_ASSERT
(
success
);
success
=
connect
(
_manager
,
SIGNAL
(
errorMessage
(
QString
)),
this
,
SLOT
(
_treeErrorMessage
(
QString
)));
Q_ASSERT
(
success
);
success
=
connect
(
_manager
,
SIGNAL
(
listComplete
(
void
)),
this
,
SLOT
(
_listComplete
(
void
)));
Q_ASSERT
(
success
);
Q_UNUSED
(
success
);
// Don't queue up more than once
_ui
.
listFilesButton
->
setEnabled
(
false
);
_listInProgress
=
true
;
_connectListSignals
();
_requestDirectoryList
(
"/"
);
}
void
QGCUASFileView
::
_treeStatusMessage
(
const
QString
&
msg
)
/// @brief Adds the specified directory entry to the tree view.
void
QGCUASFileView
::
_listEntryReceived
(
const
QString
&
entry
)
{
Q_ASSERT
(
_listInProgress
);
int
type
;
if
(
msg
.
startsWith
(
"F"
))
{
if
(
entry
.
startsWith
(
"F"
))
{
type
=
_typeFile
;
}
else
if
(
msg
.
startsWith
(
"D"
))
{
}
else
if
(
entry
.
startsWith
(
"D"
))
{
type
=
_typeDir
;
if
(
msg
==
"D."
||
msg
==
"D.."
)
{
if
(
entry
==
"D."
||
entry
==
"D.."
)
{
return
;
}
}
else
{
Q_ASSERT
(
false
);
return
;
// Silence maybe-unitialized on type
below
return
;
// Silence maybe-unitialized on type
}
QTreeWidgetItem
*
item
;
item
=
new
QTreeWidgetItem
(
_walkItemStack
.
last
(),
type
);
Q_CHECK_PTR
(
item
);
item
->
setText
(
0
,
msg
.
right
(
msg
.
size
()
-
1
));
item
->
setText
(
0
,
entry
.
right
(
entry
.
size
()
-
1
));
}
void
QGCUASFileView
::
_treeErrorMessage
(
const
QString
&
msg
)
/// @brief Called when an error occurs during a directory listing.
/// @param msg Error message
void
QGCUASFileView
::
_listErrorMessage
(
const
QString
&
msg
)
{
QTreeWidgetItem
*
item
;
item
=
new
QTreeWidgetItem
(
_walkItemStack
.
last
(),
_typeError
);
Q_CHECK_PTR
(
item
);
item
->
setText
(
0
,
tr
(
"Error: "
)
+
msg
);
// Fake listComplete signal after an error
_listComplete
();
if
(
_listInProgress
)
{
_ui
.
listFilesButton
->
setEnabled
(
true
);
_listInProgress
=
false
;
_disconnectListSignals
();
_ui
.
statusText
->
setText
(
tr
(
"Error: "
)
+
msg
);
}
}
void
QGCUASFileView
::
_listComplete
(
void
)
{
_clearListCompleteTimeout
(
);
Q_ASSERT
(
_listInProgress
);
// Walk the current items, traversing down into directories
...
...
@@ -171,54 +254,71 @@ Again:
if
(
_walkIndexStack
.
count
()
!=
0
)
{
goto
Again
;
}
else
{
disconnect
(
_manager
,
SIGNAL
(
statusMessage
(
QString
)),
this
,
SLOT
(
_treeStatusMessage
(
QString
)));
disconnect
(
_manager
,
SIGNAL
(
errorMessage
(
QString
)),
this
,
SLOT
(
_treeErrorMessage
(
QString
)));
disconnect
(
_manager
,
SIGNAL
(
listComplete
(
void
)),
this
,
SLOT
(
_listComplete
(
void
)));
_ui
.
listFilesButton
->
setEnabled
(
true
);
_listInProgress
=
false
;
_disconnectListSignals
();
}
}
}
void
QGCUASFileView
::
_downloadStatusMessage
(
const
QString
&
msg
)
{
disconnect
(
_manager
,
SIGNAL
(
statusMessage
(
QString
)),
this
,
SLOT
(
_downloadStatusMessage
(
QString
)));
disconnect
(
_manager
,
SIGNAL
(
errorMessage
(
QString
)),
this
,
SLOT
(
_downloadStatusMessage
(
QString
)));
QMessageBox
msgBox
;
msgBox
.
setWindowModality
(
Qt
::
ApplicationModal
);
msgBox
.
setText
(
msg
);
msgBox
.
exec
();
}
void
QGCUASFileView
::
_currentItemChanged
(
QTreeWidgetItem
*
current
,
QTreeWidgetItem
*
previous
)
{
Q_UNUSED
(
previous
);
// FIXME: Should not enable when downloading
_ui
.
downloadButton
->
setEnabled
(
current
?
(
current
->
type
()
==
_typeFile
)
:
false
);
}
void
QGCUASFileView
::
_
setupListCompleteTimeout
(
void
)
void
QGCUASFileView
::
_
requestDirectoryList
(
const
QString
&
dir
)
{
Q_ASSERT
(
!
_listCompleteTimer
.
isActive
());
_listCompleteTimer
.
setSingleShot
(
true
);
_listCompleteTimer
.
start
(
_listCompleteTimerTimeoutMsecs
);
qDebug
()
<<
"List:"
<<
dir
;
_manager
->
listDirectory
(
dir
);
}
void
QGCUASFileView
::
_clearListCompleteTimeout
(
void
)
/// @brief Connects to the signals associated with the QGCUASFileManager::downloadPath method. We only leave these signals connected
/// while a download because there may be multiple UAS, which in turn means multiple QGCUASFileView instances. We only want the signals
/// connected to the active FileView which is doing the current download.
void
QGCUASFileView
::
_connectDownloadSignals
(
void
)
{
Q_ASSERT
(
_listCompleteTimer
.
isActive
());
bool
success
;
Q_UNUSED
(
success
);
// Silence retail unused variable error
_listCompleteTimer
.
stop
();
success
=
connect
(
_manager
,
SIGNAL
(
downloadFileLength
(
unsigned
int
)),
this
,
SLOT
(
_downloadLength
(
unsigned
int
)));
Q_ASSERT
(
success
);
success
=
connect
(
_manager
,
SIGNAL
(
downloadFileProgress
(
unsigned
int
)),
this
,
SLOT
(
_downloadProgress
(
unsigned
int
)));
Q_ASSERT
(
success
);
success
=
connect
(
_manager
,
SIGNAL
(
downloadFileComplete
(
void
)),
this
,
SLOT
(
_downloadComplete
(
void
)));
Q_ASSERT
(
success
);
success
=
connect
(
_manager
,
SIGNAL
(
errorMessage
(
const
QString
&
)),
this
,
SLOT
(
_downloadErrorMessage
(
const
QString
&
)));
Q_ASSERT
(
success
);
}
void
QGCUASFileView
::
_
listCompleteTimeout
(
void
)
void
QGCUASFileView
::
_
disconnectDownloadSignals
(
void
)
{
_treeErrorMessage
(
tr
(
"Timeout waiting for listComplete signal"
));
disconnect
(
_manager
,
SIGNAL
(
downloadFileLength
(
unsigned
int
)),
this
,
SLOT
(
_downloadLength
(
unsigned
int
)));
disconnect
(
_manager
,
SIGNAL
(
downloadFileProgress
(
unsigned
int
)),
this
,
SLOT
(
_downloadProgress
(
unsigned
int
)));
disconnect
(
_manager
,
SIGNAL
(
downloadFileComplete
(
void
)),
this
,
SLOT
(
_downloadComplete
(
void
)));
disconnect
(
_manager
,
SIGNAL
(
errorMessage
(
const
QString
&
)),
this
,
SLOT
(
_downloadErrorMessage
(
const
QString
&
)));
}
void
QGCUASFileView
::
_requestDirectoryList
(
const
QString
&
dir
)
/// @brief Connects to the signals associated with the QGCUASFileManager::listDirectory method. We only leave these signals connected
/// while a download because there may be multiple UAS, which in turn means multiple QGCUASFileView instances. We only want the signals
/// connected to the active FileView which is doing the current download.
void
QGCUASFileView
::
_connectListSignals
(
void
)
{
qDebug
()
<<
"List:"
<<
dir
;
_setupListCompleteTimeout
();
_manager
->
listDirectory
(
dir
);
bool
success
;
Q_UNUSED
(
success
);
// Silence retail unused variable error
success
=
connect
(
_manager
,
SIGNAL
(
listEntry
(
const
QString
&
)),
this
,
SLOT
(
_listEntryReceived
(
const
QString
&
)));
Q_ASSERT
(
success
);
success
=
connect
(
_manager
,
SIGNAL
(
listComplete
(
void
)),
this
,
SLOT
(
_listComplete
(
void
)));
Q_ASSERT
(
success
);
success
=
connect
(
_manager
,
SIGNAL
(
errorMessage
(
const
QString
&
)),
this
,
SLOT
(
_listErrorMessage
(
const
QString
&
)));
Q_ASSERT
(
success
);
}
void
QGCUASFileView
::
_disconnectListSignals
(
void
)
{
disconnect
(
_manager
,
SIGNAL
(
listEntry
(
const
QString
&
)),
this
,
SLOT
(
_listEntryReceived
(
const
QString
&
)));
disconnect
(
_manager
,
SIGNAL
(
listComplete
(
void
)),
this
,
SLOT
(
_listComplete
(
void
)));
disconnect
(
_manager
,
SIGNAL
(
errorMessage
(
const
QString
&
)),
this
,
SLOT
(
_listErrorMessage
(
const
QString
&
)));
}
src/ui/QGCUASFileView.h
View file @
5868dbc1
...
...
@@ -42,29 +42,38 @@ protected:
private
slots
:
void
_refreshTree
(
void
);
void
_downloadFiles
(
void
);
void
_treeStatusMessage
(
const
QString
&
msg
);
void
_treeErrorMessage
(
const
QString
&
msg
);
void
_listEntryReceived
(
const
QString
&
entry
);
void
_listErrorMessage
(
const
QString
&
msg
);
void
_listComplete
(
void
);
void
_downloadStatusMessage
(
const
QString
&
msg
);
void
_downloadFile
(
void
);
void
_downloadLength
(
unsigned
int
length
);
void
_downloadProgress
(
unsigned
int
length
);
void
_downloadErrorMessage
(
const
QString
&
msg
);
void
_downloadComplete
(
void
);
void
_currentItemChanged
(
QTreeWidgetItem
*
current
,
QTreeWidgetItem
*
previous
);
void
_listCompleteTimeout
(
void
);
private:
void
_setupListCompleteTimeout
(
void
);
void
_clearListCompleteTimeout
(
void
);
void
_connectDownloadSignals
(
void
);
void
_disconnectDownloadSignals
(
void
);
void
_connectListSignals
(
void
);
void
_disconnectListSignals
(
void
);
void
_requestDirectoryList
(
const
QString
&
dir
);
static
const
int
_typeFile
=
QTreeWidgetItem
::
UserType
+
1
;
static
const
int
_typeDir
=
QTreeWidgetItem
::
UserType
+
2
;
static
const
int
_typeError
=
QTreeWidgetItem
::
UserType
+
3
;
QTimer
_listCompleteTimer
;
///> Used to signal a timeout waiting for a listComplete signal
static
const
int
_listCompleteTimerTimeoutMsecs
=
5000
;
///> Timeout in msecs for listComplete timer
QList
<
int
>
_walkIndexStack
;
QList
<
QTreeWidgetItem
*>
_walkItemStack
;
Ui
::
QGCUASFileView
_ui
;
QString
_downloadFilename
;
///< File currently being downloaded, not including path
QTime
_downloadStartTime
;
///< Time at which download started
bool
_listInProgress
;
///< Indicates that a listDirectory command is in progress
bool
_downloadInProgress
;
///< Indicates that a downloadPath command is in progress
};
#endif // QGCUASFILEVIEW_H
src/ui/QGCUASFileView.ui
View file @
5868dbc1
...
...
@@ -14,13 +14,23 @@
<string>
Form
</string>
</property>
<layout
class=
"QGridLayout"
name=
"gridLayout"
>
<item
row=
"
1
"
column=
"1"
>
<item
row=
"
3
"
column=
"1"
>
<widget
class=
"QPushButton"
name=
"listFilesButton"
>
<property
name=
"text"
>
<string>
List Files
</string>
</property>
</widget>
</item>
<item
row=
"1"
column=
"0"
colspan=
"3"
>
<widget
class=
"QProgressBar"
name=
"progressBar"
>
<property
name=
"value"
>
<number>
24
</number>
</property>
<property
name=
"textVisible"
>
<bool>
false
</bool>
</property>
</widget>
</item>
<item
row=
"0"
column=
"0"
colspan=
"3"
>
<widget
class=
"QTreeWidget"
name=
"treeWidget"
>
<property
name=
"headerHidden"
>
...
...
@@ -33,7 +43,7 @@
</column>
</widget>
</item>
<item
row=
"
1
"
column=
"2"
>
<item
row=
"
3
"
column=
"2"
>
<widget
class=
"QPushButton"
name=
"downloadButton"
>
<property
name=
"enabled"
>
<bool>
false
</bool>
...
...
@@ -43,6 +53,19 @@
</property>
</widget>
</item>
<item
row=
"2"
column=
"0"
colspan=
"3"
>
<widget
class=
"QLabel"
name=
"statusText"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"Expanding"
vsizetype=
"Preferred"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
<property
name=
"text"
>
<string/>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
...
...
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