C++/Qt/QFtp
QFtp base ftp window
<source lang="cpp"> /****************************************************************************
- Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
- All rights reserved.
- Contact: Nokia Corporation (qt-info@nokia.com)
- This file is part of the examples of the Qt Toolkit.
- $QT_BEGIN_LICENSE:LGPL$
- Commercial Usage
- Licensees holding valid Qt Commercial licenses may use this file in
- accordance with the Qt Commercial License Agreement provided with the
- Software or, alternatively, in accordance with the terms contained in
- a written agreement between you and Nokia.
- GNU Lesser General Public License Usage
- Alternatively, this file may be used under the terms of the GNU Lesser
- General Public License version 2.1 as published by the Free Software
- Foundation and appearing in the file LICENSE.LGPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU Lesser General Public License version 2.1 requirements
- will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
- In addition, as a special exception, Nokia gives you certain additional
- rights. These rights are described in the Nokia Qt LGPL Exception
- version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
- GNU General Public License Usage
- Alternatively, this file may be used under the terms of the GNU
- General Public License version 3.0 as published by the Free Software
- Foundation and appearing in the file LICENSE.GPL included in the
- packaging of this file. Please review the following information to
- ensure the GNU General Public License version 3.0 requirements will be
- met: http://www.gnu.org/copyleft/gpl.html.
- If you have questions regarding the use of this file, please contact
- Nokia at qt-info@nokia.com.
- $QT_END_LICENSE$
-
- /
- ifndef FTPWINDOW_H
- define FTPWINDOW_H
- include <QDialog>
- include <QHash>
QT_BEGIN_NAMESPACE class QDialogButtonBox; class QFile; class QFtp; class QLabel; class QLineEdit; class QTreeWidget; class QTreeWidgetItem; class QProgressDialog; class QPushButton; class QUrlInfo; QT_END_NAMESPACE class FtpWindow : public QDialog {
Q_OBJECT
public:
FtpWindow(QWidget *parent = 0); QSize sizeHint() const;
private slots:
void connectOrDisconnect(); void downloadFile(); void cancelDownload(); void ftpCommandFinished(int commandId, bool error); void addToList(const QUrlInfo &urlInfo); void processItem(QTreeWidgetItem *item, int column); void cdToParent(); void updateDataTransferProgress(qint64 readBytes, qint64 totalBytes); void enableDownloadButton();
private:
QLabel *ftpServerLabel; QLineEdit *ftpServerLineEdit; QLabel *statusLabel; QTreeWidget *fileList; QPushButton *cdToParentButton; QPushButton *connectButton; QPushButton *downloadButton; QPushButton *quitButton; QDialogButtonBox *buttonBox; QProgressDialog *progressDialog;
QHash<QString, bool> isDirectory; QString currentPath; QFtp *ftp; QFile *file;
};
- endif
- include <QtGui>
- include <QtNetwork>
- include "ftpwindow.h"
FtpWindow::FtpWindow(QWidget *parent)
: QDialog(parent), ftp(0)
{
ftpServerLabel = new QLabel(tr("Ftp &server:")); ftpServerLineEdit = new QLineEdit("ftp.qt.nokia.com"); ftpServerLabel->setBuddy(ftpServerLineEdit); statusLabel = new QLabel(tr("Please enter the name of an FTP server.")); fileList = new QTreeWidget; fileList->setEnabled(false); fileList->setRootIsDecorated(false); fileList->setHeaderLabels(QStringList() << tr("Name") << tr("Size") << tr("Owner") << tr("Group") << tr("Time")); fileList->header()->setStretchLastSection(false); connectButton = new QPushButton(tr("Connect")); connectButton->setDefault(true); cdToParentButton = new QPushButton; cdToParentButton->setIcon(QPixmap(":/images/cdtoparent.png")); cdToParentButton->setEnabled(false); downloadButton = new QPushButton(tr("Download")); downloadButton->setEnabled(false); quitButton = new QPushButton(tr("Quit")); buttonBox = new QDialogButtonBox; buttonBox->addButton(downloadButton, QDialogButtonBox::ActionRole); buttonBox->addButton(quitButton, QDialogButtonBox::RejectRole); progressDialog = new QProgressDialog(this); connect(fileList, SIGNAL(itemActivated(QTreeWidgetItem *, int)), this, SLOT(processItem(QTreeWidgetItem *, int))); connect(fileList, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(enableDownloadButton())); connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelDownload())); connect(connectButton, SIGNAL(clicked()), this, SLOT(connectOrDisconnect())); connect(cdToParentButton, SIGNAL(clicked()), this, SLOT(cdToParent())); connect(downloadButton, SIGNAL(clicked()), this, SLOT(downloadFile())); connect(quitButton, SIGNAL(clicked()), this, SLOT(close())); QHBoxLayout *topLayout = new QHBoxLayout; topLayout->addWidget(ftpServerLabel); topLayout->addWidget(ftpServerLineEdit); topLayout->addWidget(cdToParentButton); topLayout->addWidget(connectButton); QVBoxLayout *mainLayout = new QVBoxLayout; mainLayout->addLayout(topLayout); mainLayout->addWidget(fileList); mainLayout->addWidget(statusLabel); mainLayout->addWidget(buttonBox); setLayout(mainLayout); setWindowTitle(tr("FTP"));
} QSize FtpWindow::sizeHint() const {
return QSize(500, 300);
}
void FtpWindow::connectOrDisconnect() {
if (ftp) { ftp->abort(); ftp->deleteLater(); ftp = 0; fileList->setEnabled(false); cdToParentButton->setEnabled(false); downloadButton->setEnabled(false); connectButton->setEnabled(true); connectButton->setText(tr("Connect"));
- ifndef QT_NO_CURSOR
setCursor(Qt::ArrowCursor);
- endif
return; }
- ifndef QT_NO_CURSOR
setCursor(Qt::WaitCursor);
- endif
ftp = new QFtp(this); connect(ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(ftpCommandFinished(int, bool))); connect(ftp, SIGNAL(listInfo(const QUrlInfo &)), this, SLOT(addToList(const QUrlInfo &))); connect(ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(updateDataTransferProgress(qint64, qint64))); fileList->clear(); currentPath.clear(); isDirectory.clear();
QUrl url(ftpServerLineEdit->text()); if (!url.isValid() || url.scheme().toLower() != QLatin1String("ftp")) { ftp->connectToHost(ftpServerLineEdit->text(), 21); ftp->login(); } else { ftp->connectToHost(url.host(), url.port(21)); if (!url.userName().isEmpty()) ftp->login(QUrl::fromPercentEncoding(url.userName().toLatin1()), url.password()); else ftp->login(); if (!url.path().isEmpty()) ftp->cd(url.path()); }
fileList->setEnabled(true); connectButton->setEnabled(false); connectButton->setText(tr("Disconnect")); statusLabel->setText(tr("Connecting to FTP server %1...") .arg(ftpServerLineEdit->text()));
}
void FtpWindow::downloadFile() {
QString fileName = fileList->currentItem()->text(0);
//
if (QFile::exists(fileName)) { QMessageBox::information(this, tr("FTP"), tr("There already exists a file called %1 in " "the current directory.") .arg(fileName)); return; }
file = new QFile(fileName); if (!file->open(QIODevice::WriteOnly)) { QMessageBox::information(this, tr("FTP"), tr("Unable to save the file %1: %2.") .arg(fileName).arg(file->errorString())); delete file; return; } ftp->get(fileList->currentItem()->text(0), file); progressDialog->setLabelText(tr("Downloading %1...").arg(fileName)); downloadButton->setEnabled(false); progressDialog->exec();
}
void FtpWindow::cancelDownload() {
ftp->abort();
}
void FtpWindow::ftpCommandFinished(int, bool error) {
- ifndef QT_NO_CURSOR
setCursor(Qt::ArrowCursor);
- endif
if (ftp->currentCommand() == QFtp::ConnectToHost) { if (error) { QMessageBox::information(this, tr("FTP"), tr("Unable to connect to the FTP server " "at %1. Please check that the host " "name is correct.") .arg(ftpServerLineEdit->text())); connectOrDisconnect(); return; } statusLabel->setText(tr("Logged onto %1.") .arg(ftpServerLineEdit->text())); fileList->setFocus(); downloadButton->setDefault(true); connectButton->setEnabled(true); return; }
if (ftp->currentCommand() == QFtp::Login) ftp->list();
if (ftp->currentCommand() == QFtp::Get) { if (error) { statusLabel->setText(tr("Canceled download of %1.") .arg(file->fileName())); file->close(); file->remove(); } else { statusLabel->setText(tr("Downloaded %1 to current directory.") .arg(file->fileName())); file->close(); } delete file; enableDownloadButton(); progressDialog->hide();
} else if (ftp->currentCommand() == QFtp::List) { if (isDirectory.isEmpty()) { fileList->addTopLevelItem(new QTreeWidgetItem(QStringList() << tr("<empty>"))); fileList->setEnabled(false); } }
}
void FtpWindow::addToList(const QUrlInfo &urlInfo) {
QTreeWidgetItem *item = new QTreeWidgetItem; item->setText(0, urlInfo.name()); item->setText(1, QString::number(urlInfo.size())); item->setText(2, urlInfo.owner()); item->setText(3, urlInfo.group()); item->setText(4, urlInfo.lastModified().toString("MMM dd yyyy")); QPixmap pixmap(urlInfo.isDir() ? ":/images/dir.png" : ":/images/file.png"); item->setIcon(0, pixmap); isDirectory[urlInfo.name()] = urlInfo.isDir(); fileList->addTopLevelItem(item); if (!fileList->currentItem()) { fileList->setCurrentItem(fileList->topLevelItem(0)); fileList->setEnabled(true); }
}
void FtpWindow::processItem(QTreeWidgetItem *item, int /*column*/) {
QString name = item->text(0); if (isDirectory.value(name)) { fileList->clear(); isDirectory.clear(); currentPath += "/" + name; ftp->cd(name); ftp->list(); cdToParentButton->setEnabled(true);
- ifndef QT_NO_CURSOR
setCursor(Qt::WaitCursor);
- endif
return; }
}
void FtpWindow::cdToParent() {
- ifndef QT_NO_CURSOR
setCursor(Qt::WaitCursor);
- endif
fileList->clear(); isDirectory.clear(); currentPath = currentPath.left(currentPath.lastIndexOf("/")); if (currentPath.isEmpty()) { cdToParentButton->setEnabled(false); ftp->cd("/"); } else { ftp->cd(currentPath); } ftp->list();
}
void FtpWindow::updateDataTransferProgress(qint64 readBytes,
qint64 totalBytes)
{
progressDialog->setMaximum(totalBytes); progressDialog->setValue(readBytes);
}
void FtpWindow::enableDownloadButton() {
QTreeWidgetItem *current = fileList->currentItem(); if (current) { QString currentFile = current->text(0); downloadButton->setEnabled(!isDirectory.value(currentFile)); } else { downloadButton->setEnabled(false); }
}
- include <QApplication>
- include "ftpwindow.h"
int main(int argc, char *argv[]) {
Q_INIT_RESOURCE(ftp); QApplication app(argc, argv); FtpWindow ftpWin; ftpWin.show(); return ftpWin.exec();
}
</source>
Qt based Ftp dialog
<source lang="cpp">
Foundations of Qt Development\Chapter14\ftp\ftpdialog.cpp /*
* Copyright (c) 2006-2007, Johan Thelin * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of APress nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */
- include <QFileDialog>
- include <QMessageBox>
- include "ftpdialog.h"
FtpDialog::FtpDialog() : QDialog() {
file = 0; ui.setupUi( this ); connect( ui.connectButton, SIGNAL(clicked()), this, SLOT(connectClicked()) ); connect( ui.disconnectButton, SIGNAL(clicked()), this, SLOT(disconnectClicked()) ); connect( ui.cdButton, SIGNAL(clicked()), this, SLOT(cdClicked()) ); connect( ui.upButton, SIGNAL(clicked()), this, SLOT(upClicked()) ); connect( ui.getButton, SIGNAL(clicked()), this, SLOT(getClicked()) ); connect( ui.dirList, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()) ); connect( &ftp, SIGNAL(commandFinished(int,bool)), this, SLOT(ftpFinished(int,bool)) ); connect( &ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(ftpListInfo(QUrlInfo)) ); connect( &ftp, SIGNAL(dataTransferProgress(qint64,qint64)), this, SLOT(ftpProgress(qint64,qint64)) ); ui.disconnectButton->setEnabled( false ); ui.cdButton->setEnabled( false ); ui.upButton->setEnabled( false ); ui.getButton->setEnabled( false );
} void FtpDialog::connectClicked() {
ui.connectButton->setEnabled( false ); ftp.connectToHost( "ftp.trolltech.com" ); ui.statusLabel->setText( tr("Connecting to host...") );
} void FtpDialog::disconnectClicked() {
ui.disconnectButton->setEnabled( false ); ui.cdButton->setEnabled( false ); ui.upButton->setEnabled( false ); ui.getButton->setEnabled( false ); ftp.close();
} void FtpDialog::cdClicked() {
ui.disconnectButton->setEnabled( false ); ui.cdButton->setEnabled( false ); ui.upButton->setEnabled( false ); ui.getButton->setEnabled( false ); ftp.cd( ui.dirList->selectedItems()[0]->text() ); ui.statusLabel->setText( tr("Changing directory...") );
} void FtpDialog::upClicked() {
ui.disconnectButton->setEnabled( false ); ui.cdButton->setEnabled( false ); ui.upButton->setEnabled( false ); ui.getButton->setEnabled( false ); ftp.cd(".."); ui.statusLabel->setText( tr("Changing directory...") );
} void FtpDialog::getClicked() {
QString fileName = QFileDialog::getSaveFileName( this, tr("Get File"), ui.dirList->selectedItems()[0]->text() ); if( fileName.isEmpty() ) return; file = new QFile( fileName, this ); if( !file->open( QIODevice::WriteOnly ) ) { QMessageBox::warning( this, tr("Error"), tr("Failed to open file %1 for writing.").arg( fileName ) ); delete file; file = 0; return; } ui.disconnectButton->setEnabled( false ); ui.cdButton->setEnabled( false ); ui.upButton->setEnabled( false ); ui.getButton->setEnabled( false ); ftp.get( ui.dirList->selectedItems()[0]->text(), file ); ui.statusLabel->setText( tr("Downloading file...") );
} void FtpDialog::ftpProgress( qint64 done, qint64 total ) {
if( total == 0 ) return; ui.statusLabel->setText( tr("Downloading file... (%1%)").arg( QString::number( double(done)*100/double(total), "f", 1 ) ) );
} void FtpDialog::selectionChanged() {
if( ui.dirList->selectedItems().count() == 1 ) { if( files.indexOf( ui.dirList->selectedItems()[0]->text() ) == -1 ) { ui.cdButton->setEnabled( ui.disconnectButton->isEnabled() ); ui.getButton->setEnabled( false ); } else { ui.cdButton->setEnabled( false ); ui.getButton->setEnabled( ui.disconnectButton->isEnabled() ); } } else { ui.cdButton->setEnabled( false ); ui.getButton->setEnabled( false ); }
} void FtpDialog::getFileList() {
ui.disconnectButton->setEnabled( false ); ui.cdButton->setEnabled( false ); ui.upButton->setEnabled( false ); ui.getButton->setEnabled( false ); ui.dirList->clear(); files.clear(); if( ftp.state() == QFtp::LoggedIn ) ftp.list();
} void FtpDialog::ftpListInfo( QUrlInfo info ) {
ui.dirList->addItem( info.name() ); if( info.isFile() ) files << info.name();
} void FtpDialog::ftpFinished( int request, bool error ) {
if( error ) { switch( ftp.currentCommand() ) { case QFtp::ConnectToHost: QMessageBox::warning( this, tr("Error"), tr("Failed to connect to host.") ); ui.connectButton->setEnabled( true ); break; case QFtp::Login: QMessageBox::warning( this, tr("Error"), tr("Failed to login.") ); ui.connectButton->setEnabled( true ); break; case QFtp::List: QMessageBox::warning( this, tr("Error"), tr("Failed to get file list.\nClosing connection.") ); ftp.close(); break; case QFtp::Cd: QMessageBox::warning( this, tr("Error"), tr("Failed to change directory.") ); getFileList(); break; case QFtp::Get: QMessageBox::warning( this, tr("Error"), tr("Failed to get file?") ); file->close(); file->remove(); delete file; file = 0; ui.disconnectButton->setEnabled( true ); ui.upButton->setEnabled( true ); selectionChanged(); break; } ui.statusLabel->setText( tr("Ready.") ); } else { switch( ftp.currentCommand() ) { case QFtp::ConnectToHost: ftp.login(); break; case QFtp::Login: getFileList(); break; case QFtp::Close: ui.connectButton->setEnabled( true ); getFileList(); break; case QFtp::List: ui.disconnectButton->setEnabled( true ); ui.upButton->setEnabled( true ); ui.statusLabel->setText( tr("Ready.") ); break; case QFtp::Cd: getFileList(); break; case QFtp::Get: file->close(); delete file; file = 0; ui.disconnectButton->setEnabled( true ); ui.upButton->setEnabled( true ); selectionChanged(); ui.statusLabel->setText( tr("Ready.") ); break; } }
}
Foundations of Qt Development\Chapter14\ftp\ftpdialog.h /*
* Copyright (c) 2006-2007, Johan Thelin * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of APress nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */
- ifndef FTPDIALOG_H
- define FTPDIALOG_H
- include <QFtp>
- include <QDialog>
- include <QFile>
- include "ui_ftpdialog.h"
class FtpDialog : public QDialog {
Q_OBJECT
public:
FtpDialog();
private slots:
void connectClicked(); void disconnectClicked(); void cdClicked(); void upClicked(); void getClicked(); void selectionChanged(); void ftpFinished(int,bool); void ftpListInfo(QUrlInfo); void ftpProgress(qint64,qint64);
private:
void getFileList(); Ui::FtpDialog ui; QFtp ftp; QFile *file; QStringList files;
};
- endif // FTPDIALOG_H
Foundations of Qt Development\Chapter14\ftp\main.cpp /*
* Copyright (c) 2006-2007, Johan Thelin * * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of APress nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */
- include <QApplication>
- include "ftpdialog.h"
int main( int argc, char **argv ) {
QApplication app( argc, argv ); FtpDialog dlg; dlg.show(); return app.exec();
}
</source>