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
3deecfe1
Commit
3deecfe1
authored
Jul 06, 2014
by
Lorenz Meier
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #741 from DonLakeFlyer/MoreFTP
Changed FTP to tree view
parents
2b88c6e9
84cd97ca
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
234 additions
and
68 deletions
+234
-68
QGCUASFileManager.cc
src/uas/QGCUASFileManager.cc
+4
-13
QGCUASFileManager.h
src/uas/QGCUASFileManager.h
+2
-2
QGCUASFileView.cc
src/ui/QGCUASFileView.cc
+178
-21
QGCUASFileView.h
src/ui/QGCUASFileView.h
+42
-10
QGCUASFileView.ui
src/ui/QGCUASFileView.ui
+8
-22
No files found.
src/uas/QGCUASFileManager.cc
View file @
3deecfe1
...
...
@@ -99,11 +99,6 @@ quint32 QGCUASFileManager::crc32(Request* request, unsigned state)
return
state
;
}
void
QGCUASFileManager
::
nothingMessage
()
{
// FIXME: Connect ui correctly
}
/// @brief Respond to the Ack associated with the Open command with the next Read command.
void
QGCUASFileManager
::
_openAckResponse
(
Request
*
openAck
)
{
...
...
@@ -220,17 +215,11 @@ void QGCUASFileManager::_listAckResponse(Request* listAck)
_emitErrorMessage
(
tr
(
"Missing NULL termination in list entry"
));
return
;
}
// Returned names are prepended with D for directory, F for file, U for unknown
QString
s
(
ptr
+
1
);
if
(
*
ptr
==
'D'
)
{
s
.
append
(
'/'
);
}
// Returned names are prepended with D for directory, F for file, U for unknown
if
(
*
ptr
==
'F'
||
*
ptr
==
'D'
)
{
// put it in the view
_emitStatusMessage
(
s
);
_emitStatusMessage
(
ptr
);
}
// account for the name + NUL
...
...
@@ -243,6 +232,7 @@ void QGCUASFileManager::_listAckResponse(Request* listAck)
// Directory is empty, we're done
Q_ASSERT
(
listAck
->
hdr
.
opcode
==
kRspAck
);
_currentOperation
=
kCOIdle
;
emit
listComplete
();
}
else
{
// Possibly more entries to come, need to keep trying till we get EOF
_currentOperation
=
kCOList
;
...
...
@@ -307,6 +297,7 @@ void QGCUASFileManager::receiveMessage(LinkInterface* link, mavlink_message_t me
if
(
previousOperation
==
kCOList
&&
errorCode
==
kErrEOF
)
{
// This is not an error, just the end of the read loop
emit
listComplete
();
return
;
}
else
if
(
previousOperation
==
kCORead
&&
errorCode
==
kErrEOF
)
{
// This is not an error, just the end of the read loop
...
...
src/uas/QGCUASFileManager.h
View file @
3deecfe1
...
...
@@ -43,11 +43,11 @@ public:
signals:
void
statusMessage
(
const
QString
&
msg
);
void
resetStatusMessages
();
void
errorMessage
(
const
QString
&
ms
);
void
errorMessage
(
const
QString
&
msg
);
void
listComplete
(
void
);
public
slots
:
void
receiveMessage
(
LinkInterface
*
link
,
mavlink_message_t
message
);
void
nothingMessage
();
void
listDirectory
(
const
QString
&
dirPath
);
void
downloadPath
(
const
QString
&
from
,
const
QDir
&
downloadDir
);
...
...
src/ui/QGCUASFileView.cc
View file @
3deecfe1
/*=====================================================================
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/>.
======================================================================*/
#include "QGCUASFileView.h"
#include "uas/QGCUASFileManager.h"
#include "ui_QGCUASFileView.h"
#include <QFileDialog>
#include <QDir>
#include <QMessageBox>
QGCUASFileView
::
QGCUASFileView
(
QWidget
*
parent
,
QGCUASFileManager
*
manager
)
:
QWidget
(
parent
),
_manager
(
manager
),
ui
(
new
Ui
::
QGCUASFileView
)
_manager
(
manager
)
{
ui
->
setupUi
(
this
);
_ui
.
setupUi
(
this
);
connect
(
ui
->
testButton
,
SIGNAL
(
clicked
()),
_manager
,
SLOT
(
nothingMessage
()));
connect
(
ui
->
listFilesButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
listFiles
()));
connect
(
ui
->
downloadButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
downloadFiles
()));
bool
success
=
connect
(
_ui
.
listFilesButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
_refreshTree
()));
Q_ASSERT
(
success
);
success
=
connect
(
_ui
.
downloadButton
,
SIGNAL
(
clicked
()),
this
,
SLOT
(
_downloadFiles
()));
Q_ASSERT
(
success
);
success
=
connect
(
_ui
.
treeWidget
,
SIGNAL
(
currentItemChanged
(
QTreeWidgetItem
*
,
QTreeWidgetItem
*
)),
this
,
SLOT
(
_currentItemChanged
(
QTreeWidgetItem
*
,
QTreeWidgetItem
*
)));
Q_ASSERT
(
success
);
Q_UNUSED
(
success
);
}
connect
(
_manager
,
SIGNAL
(
statusMessage
(
QString
)),
ui
->
messageArea
,
SLOT
(
appendPlainText
(
QString
)));
connect
(
_manager
,
SIGNAL
(
errorMessage
(
QString
)),
ui
->
messageArea
,
SLOT
(
appendPlainText
(
QString
)));
connect
(
_manager
,
SIGNAL
(
resetStatusMessages
()),
ui
->
messageArea
,
SLOT
(
clear
()));
void
QGCUASFileView
::
_downloadFiles
(
void
)
{
QString
dir
=
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
)
{
do
{
path
.
prepend
(
"/"
+
item
->
text
(
0
));
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
));
}
}
QGCUASFileView
::~
QGCUASFileView
(
)
void
QGCUASFileView
::
_refreshTree
(
void
)
{
delete
ui
;
QTreeWidgetItem
*
item
;
for
(
int
i
=
_ui
.
treeWidget
->
invisibleRootItem
()
->
childCount
();
i
>=
0
;
i
--
)
{
item
=
_ui
.
treeWidget
->
takeTopLevelItem
(
i
);
delete
item
;
}
_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
);
qDebug
()
<<
"List: /"
;
_manager
->
listDirectory
(
"/"
);
}
void
QGCUASFileView
::
listFiles
(
)
void
QGCUASFileView
::
_treeStatusMessage
(
const
QString
&
msg
)
{
_manager
->
listDirectory
(
ui
->
pathLineEdit
->
text
());
int
type
;
if
(
msg
.
startsWith
(
"F"
))
{
type
=
_typeFile
;
}
else
if
(
msg
.
startsWith
(
"D"
))
{
type
=
_typeDir
;
if
(
msg
==
"D."
||
msg
==
"D.."
)
{
return
;
}
}
else
{
Q_ASSERT
(
false
);
}
QTreeWidgetItem
*
item
;
if
(
_walkItemStack
.
count
()
==
0
)
{
item
=
new
QTreeWidgetItem
(
_ui
.
treeWidget
,
type
);
}
else
{
item
=
new
QTreeWidgetItem
(
_walkItemStack
.
last
(),
type
);
}
Q_CHECK_PTR
(
item
);
item
->
setText
(
0
,
msg
.
right
(
msg
.
size
()
-
1
));
}
void
QGCUASFileView
::
downloadFiles
(
)
void
QGCUASFileView
::
_treeErrorMessage
(
const
QString
&
msg
)
{
QString
dir
=
QFileDialog
::
getExistingDirectory
(
this
,
tr
(
"Download Directory"
),
QDir
::
homePath
(),
QFileDialog
::
ShowDirsOnly
|
QFileDialog
::
DontResolveSymlinks
);
// And now download to this location
_manager
->
downloadPath
(
ui
->
pathLineEdit
->
text
(),
QDir
(
dir
));
QTreeWidgetItem
*
item
;
if
(
_walkItemStack
.
count
()
==
0
)
{
item
=
new
QTreeWidgetItem
(
_ui
.
treeWidget
,
_typeError
);
}
else
{
item
=
new
QTreeWidgetItem
(
_walkItemStack
.
last
(),
_typeError
);
}
Q_CHECK_PTR
(
item
);
item
->
setText
(
0
,
tr
(
"Error: "
)
+
msg
);
}
void
QGCUASFileView
::
_listComplete
(
void
)
{
// Walk the current items, traversing down into directories
Again:
int
walkIndex
=
_walkIndexStack
.
last
();
QTreeWidgetItem
*
parentItem
=
_walkItemStack
.
last
();
QTreeWidgetItem
*
childItem
=
parentItem
->
child
(
walkIndex
);
// Loop until we hit a directory
while
(
childItem
&&
childItem
->
type
()
!=
_typeDir
)
{
// Move to next index at current level
_walkIndexStack
.
last
()
=
++
walkIndex
;
childItem
=
parentItem
->
child
(
walkIndex
);
}
if
(
childItem
)
{
// Process this item
QString
text
=
childItem
->
text
(
0
);
// Move to the next item for processing at this level
_walkIndexStack
.
last
()
=
++
walkIndex
;
// Push this new directory on the stack
_walkItemStack
.
append
(
childItem
);
_walkIndexStack
.
append
(
0
);
// Ask for the directory list
QString
dir
;
for
(
int
i
=
1
;
i
<
_walkItemStack
.
count
();
i
++
)
{
QTreeWidgetItem
*
item
=
_walkItemStack
[
i
];
dir
.
append
(
"/"
+
item
->
text
(
0
));
}
qDebug
()
<<
"List:"
<<
dir
;
_manager
->
listDirectory
(
dir
);
}
else
{
// We have run out of items at the this level, pop the stack and keep going at that level
_walkIndexStack
.
removeLast
();
_walkItemStack
.
removeLast
();
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
)));
}
}
}
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
);
_ui
.
downloadButton
->
setEnabled
(
current
->
type
()
==
_typeFile
);
}
src/ui/QGCUASFileView.h
View file @
3deecfe1
/*=====================================================================
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 QGCUASFILEVIEW_H
#define QGCUASFILEVIEW_H
#include <QWidget>
#include
"uas/QGCUASFileManager.h"
#include
<QTreeWidgetItem>
namespace
Ui
{
class
QGCUASFileView
;
}
#include "uas/QGCUASFileManager.h"
#include "ui_QGCUASFileView.h"
class
QGCUASFileView
:
public
QWidget
{
...
...
@@ -14,17 +36,27 @@ class QGCUASFileView : public QWidget
public:
explicit
QGCUASFileView
(
QWidget
*
parent
,
QGCUASFileManager
*
manager
);
~
QGCUASFileView
();
public
slots
:
void
listFiles
();
void
downloadFiles
();
protected:
QGCUASFileManager
*
_manager
;
private
slots
:
void
_refreshTree
(
void
);
void
_downloadFiles
(
void
);
void
_treeStatusMessage
(
const
QString
&
msg
);
void
_treeErrorMessage
(
const
QString
&
msg
);
void
_listComplete
(
void
);
void
_downloadStatusMessage
(
const
QString
&
msg
);
void
_currentItemChanged
(
QTreeWidgetItem
*
current
,
QTreeWidgetItem
*
previous
);
private:
Ui
::
QGCUASFileView
*
ui
;
static
const
int
_typeFile
=
QTreeWidgetItem
::
UserType
+
1
;
static
const
int
_typeDir
=
QTreeWidgetItem
::
UserType
+
2
;
static
const
int
_typeError
=
QTreeWidgetItem
::
UserType
+
3
;
QList
<
int
>
_walkIndexStack
;
QList
<
QTreeWidgetItem
*>
_walkItemStack
;
Ui
::
QGCUASFileView
_ui
;
};
#endif // QGCUASFILEVIEW_H
src/ui/QGCUASFileView.ui
View file @
3deecfe1
...
...
@@ -14,7 +14,7 @@
<string>
Form
</string>
</property>
<layout
class=
"QGridLayout"
name=
"gridLayout"
>
<item
row=
"
3
"
column=
"1"
>
<item
row=
"
1
"
column=
"1"
>
<widget
class=
"QPushButton"
name=
"listFilesButton"
>
<property
name=
"text"
>
<string>
List Files
</string>
...
...
@@ -22,10 +22,10 @@
</widget>
</item>
<item
row=
"0"
column=
"0"
colspan=
"3"
>
<widget
class=
"QPlainTextEdit"
name=
"messageArea"
/>
</item>
<item
row=
"1"
column=
"0"
colspan=
"3"
>
<widget
class=
"QTreeWidget"
name=
"treeWidget"
>
<property
name=
"headerHidden"
>
<bool>
true
</bool>
</property>
<column>
<property
name=
"text"
>
<string
notr=
"true"
>
1
</string>
...
...
@@ -33,30 +33,16 @@
</column>
</widget>
</item>
<item
row=
"3"
column=
"0"
>
<widget
class=
"QPushButton"
name=
"testButton"
>
<property
name=
"text"
>
<string>
Null Message
</string>
</property>
</widget>
</item>
<item
row=
"3"
column=
"2"
>
<item
row=
"1"
column=
"2"
>
<widget
class=
"QPushButton"
name=
"downloadButton"
>
<property
name=
"
text
"
>
<
string>
Download File
</string
>
<property
name=
"
enabled
"
>
<
bool>
false
</bool
>
</property>
</widget>
</item>
<item
row=
"2"
column=
"0"
>
<widget
class=
"QLabel"
name=
"label"
>
<property
name=
"text"
>
<string>
Path:
</string>
<string>
Download File
</string>
</property>
</widget>
</item>
<item
row=
"2"
column=
"1"
colspan=
"2"
>
<widget
class=
"QLineEdit"
name=
"pathLineEdit"
/>
</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