1
mirror of https://invent.kde.org/network/falkon.git synced 2024-12-20 18:56:34 +01:00

Merge branch 'srazi-master' + fixed building on Linux.

Conflicts:
	src/lib/lib.pro
This commit is contained in:
nowrep 2013-01-29 00:13:34 +01:00
commit 709bc71f1a
17 changed files with 4308 additions and 19 deletions

2510
src/lib/3rdparty/qftp.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

161
src/lib/3rdparty/qftp.h vendored Normal file
View File

@ -0,0 +1,161 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QFTP_H
#define QFTP_H
#include <QtCore/qstring.h>
#include "qurlinfo.h"
#include <QtCore/qobject.h>
QT_BEGIN_HEADER
class QFtpPrivate;
class QFtp : public QObject
{
Q_OBJECT
public:
explicit QFtp(QObject* parent = 0);
virtual ~QFtp();
enum State {
Unconnected,
HostLookup,
Connecting,
Connected,
LoggedIn,
Closing
};
enum Error {
NoError,
UnknownError,
HostNotFound,
ConnectionRefused,
NotConnected
};
enum Command {
None,
SetTransferMode,
SetProxy,
ConnectToHost,
Login,
Close,
List,
Cd,
Get,
Put,
Remove,
Mkdir,
Rmdir,
Rename,
RawCommand
};
enum TransferMode {
Active,
Passive
};
enum TransferType {
Binary,
Ascii
};
int setProxy(const QString &host, quint16 port);
int connectToHost(const QString &host, quint16 port = 21);
int login(const QString &user = QString(), const QString &password = QString());
int close();
int setTransferMode(TransferMode mode);
int list(const QString &dir = QString());
int cd(const QString &dir);
int get(const QString &file, QIODevice* dev = 0, TransferType type = Binary);
int put(const QByteArray &data, const QString &file, TransferType type = Binary);
int put(QIODevice* dev, const QString &file, TransferType type = Binary);
int remove(const QString &file);
int mkdir(const QString &dir);
int rmdir(const QString &dir);
int rename(const QString &oldname, const QString &newname);
int rawCommand(const QString &command);
qint64 bytesAvailable() const;
qint64 read(char* data, qint64 maxlen);
QByteArray readAll();
int currentId() const;
QIODevice* currentDevice() const;
Command currentCommand() const;
bool hasPendingCommands() const;
void clearPendingCommands();
State state() const;
Error error() const;
QString errorString() const;
public Q_SLOTS:
void abort();
Q_SIGNALS:
void stateChanged(int);
void listInfo(const QUrlInfo &);
void readyRead();
void dataTransferProgress(qint64, qint64);
void rawCommandReply(int, const QString &);
void commandStarted(int);
void commandFinished(int, bool);
void done(bool);
private:
Q_DISABLE_COPY(QFtp)
QScopedPointer<QFtpPrivate> d;
Q_PRIVATE_SLOT(d, void _q_startNextCommand())
Q_PRIVATE_SLOT(d, void _q_piFinished(const QString &))
Q_PRIVATE_SLOT(d, void _q_piError(int, const QString &))
Q_PRIVATE_SLOT(d, void _q_piConnectState(int))
Q_PRIVATE_SLOT(d, void _q_piFtpReply(int, const QString &))
};
QT_END_HEADER
#endif // QFTP_H

2
src/lib/3rdparty/qftp.pri vendored Normal file
View File

@ -0,0 +1,2 @@
HEADERS += $$PWD/qftp.h $$PWD/qurlinfo.h
SOURCES += $$PWD/qftp.cpp $$PWD/qurlinfo.cpp

758
src/lib/3rdparty/qurlinfo.cpp vendored Normal file
View File

@ -0,0 +1,758 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "qurlinfo.h"
#include "qurl.h"
#include "qdir.h"
#include <limits.h>
QT_BEGIN_NAMESPACE
class QUrlInfoPrivate
{
public:
QUrlInfoPrivate() :
permissions(0),
size(0),
isDir(false),
isFile(true),
isSymLink(false),
isWritable(true),
isReadable(true),
isExecutable(false)
{}
QString name;
int permissions;
QString owner;
QString group;
qint64 size;
QDateTime lastModified;
QDateTime lastRead;
bool isDir;
bool isFile;
bool isSymLink;
bool isWritable;
bool isReadable;
bool isExecutable;
};
/*!
\class QUrlInfo
\brief The QUrlInfo class stores information about URLs.
\ingroup io
\ingroup network
\inmodule QtNetwork
The information about a URL that can be retrieved includes name(),
permissions(), owner(), group(), size(), lastModified(),
lastRead(), isDir(), isFile(), isSymLink(), isWritable(),
isReadable() and isExecutable().
You can create your own QUrlInfo objects passing in all the
relevant information in the constructor, and you can modify a
QUrlInfo; for each getter mentioned above there is an equivalent
setter. Note that setting values does not affect the underlying
resource that the QUrlInfo provides information about; for example
if you call setWritable(true) on a read-only resource the only
thing changed is the QUrlInfo object, not the resource.
\sa QUrl, {FTP Example}
*/
/*!
\enum QUrlInfo::PermissionSpec
This enum is used by the permissions() function to report the
permissions of a file.
\value ReadOwner The file is readable by the owner of the file.
\value WriteOwner The file is writable by the owner of the file.
\value ExeOwner The file is executable by the owner of the file.
\value ReadGroup The file is readable by the group.
\value WriteGroup The file is writable by the group.
\value ExeGroup The file is executable by the group.
\value ReadOther The file is readable by anyone.
\value WriteOther The file is writable by anyone.
\value ExeOther The file is executable by anyone.
*/
/*!
Constructs an invalid QUrlInfo object with default values.
\sa isValid()
*/
QUrlInfo::QUrlInfo()
{
d = 0;
}
/*!
Copy constructor, copies \a ui to this URL info object.
*/
QUrlInfo::QUrlInfo(const QUrlInfo &ui)
{
if (ui.d) {
d = new QUrlInfoPrivate;
*d = *ui.d;
}
else {
d = 0;
}
}
/*!
Constructs a QUrlInfo object by specifying all the URL's
information.
The information that is passed is the \a name, file \a
permissions, \a owner and \a group and the file's \a size. Also
passed is the \a lastModified date/time and the \a lastRead
date/time. Flags are also passed, specifically, \a isDir, \a
isFile, \a isSymLink, \a isWritable, \a isReadable and \a
isExecutable.
*/
QUrlInfo::QUrlInfo(const QString &name, int permissions, const QString &owner,
const QString &group, qint64 size, const QDateTime &lastModified,
const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
bool isWritable, bool isReadable, bool isExecutable)
{
d = new QUrlInfoPrivate;
d->name = name;
d->permissions = permissions;
d->owner = owner;
d->group = group;
d->size = size;
d->lastModified = lastModified;
d->lastRead = lastRead;
d->isDir = isDir;
d->isFile = isFile;
d->isSymLink = isSymLink;
d->isWritable = isWritable;
d->isReadable = isReadable;
d->isExecutable = isExecutable;
}
/*!
Constructs a QUrlInfo object by specifying all the URL's
information.
The information that is passed is the \a url, file \a
permissions, \a owner and \a group and the file's \a size. Also
passed is the \a lastModified date/time and the \a lastRead
date/time. Flags are also passed, specifically, \a isDir, \a
isFile, \a isSymLink, \a isWritable, \a isReadable and \a
isExecutable.
*/
QUrlInfo::QUrlInfo(const QUrl &url, int permissions, const QString &owner,
const QString &group, qint64 size, const QDateTime &lastModified,
const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
bool isWritable, bool isReadable, bool isExecutable)
{
d = new QUrlInfoPrivate;
d->name = QFileInfo(url.path()).fileName();
d->permissions = permissions;
d->owner = owner;
d->group = group;
d->size = size;
d->lastModified = lastModified;
d->lastRead = lastRead;
d->isDir = isDir;
d->isFile = isFile;
d->isSymLink = isSymLink;
d->isWritable = isWritable;
d->isReadable = isReadable;
d->isExecutable = isExecutable;
}
/*!
Sets the name of the URL to \a name. The name is the full text,
for example, "http://qt.nokia.com/doc/qurlinfo.html".
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setName(const QString &name)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->name = name;
}
/*!
If \a b is true then the URL is set to be a directory; if \a b is
false then the URL is set not to be a directory (which normally
means it is a file). (Note that a URL can refer to both a file and
a directory even though most file systems do not support this.)
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setDir(bool b)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->isDir = b;
}
/*!
If \a b is true then the URL is set to be a file; if \b is false
then the URL is set not to be a file (which normally means it is a
directory). (Note that a URL can refer to both a file and a
directory even though most file systems do not support this.)
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setFile(bool b)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->isFile = b;
}
/*!
Specifies that the URL refers to a symbolic link if \a b is true
and that it does not if \a b is false.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setSymLink(bool b)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->isSymLink = b;
}
/*!
Specifies that the URL is writable if \a b is true and not
writable if \a b is false.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setWritable(bool b)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->isWritable = b;
}
/*!
Specifies that the URL is readable if \a b is true and not
readable if \a b is false.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setReadable(bool b)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->isReadable = b;
}
/*!
Specifies that the owner of the URL is called \a s.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setOwner(const QString &s)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->owner = s;
}
/*!
Specifies that the owning group of the URL is called \a s.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setGroup(const QString &s)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->group = s;
}
/*!
Specifies the \a size of the URL.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setSize(qint64 size)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->size = size;
}
/*!
Specifies that the URL has access permissions \a p.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setPermissions(int p)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->permissions = p;
}
/*!
Specifies that the object the URL refers to was last modified at
\a dt.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setLastModified(const QDateTime &dt)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->lastModified = dt;
}
/*!
\since 4.4
Specifies that the object the URL refers to was last read at
\a dt.
If you call this function for an invalid URL info, this function
turns it into a valid one.
\sa isValid()
*/
void QUrlInfo::setLastRead(const QDateTime &dt)
{
if (!d) {
d = new QUrlInfoPrivate;
}
d->lastRead = dt;
}
/*!
Destroys the URL info object.
*/
QUrlInfo::~QUrlInfo()
{
delete d;
}
/*!
Assigns the values of \a ui to this QUrlInfo object.
*/
QUrlInfo &QUrlInfo::operator=(const QUrlInfo &ui)
{
if (ui.d) {
if (!d) {
d = new QUrlInfoPrivate;
}
*d = *ui.d;
}
else {
delete d;
d = 0;
}
return *this;
}
/*!
Returns the file name of the URL.
\sa isValid()
*/
QString QUrlInfo::name() const
{
if (!d) {
return QString();
}
return d->name;
}
/*!
Returns the permissions of the URL. You can use the \c PermissionSpec flags
to test for certain permissions.
\sa isValid()
*/
int QUrlInfo::permissions() const
{
if (!d) {
return 0;
}
return d->permissions;
}
/*!
Returns the owner of the URL.
\sa isValid()
*/
QString QUrlInfo::owner() const
{
if (!d) {
return QString();
}
return d->owner;
}
/*!
Returns the group of the URL.
\sa isValid()
*/
QString QUrlInfo::group() const
{
if (!d) {
return QString();
}
return d->group;
}
/*!
Returns the size of the URL.
\sa isValid()
*/
qint64 QUrlInfo::size() const
{
if (!d) {
return 0;
}
return d->size;
}
/*!
Returns the last modification date of the URL.
\sa isValid()
*/
QDateTime QUrlInfo::lastModified() const
{
if (!d) {
return QDateTime();
}
return d->lastModified;
}
/*!
Returns the date when the URL was last read.
\sa isValid()
*/
QDateTime QUrlInfo::lastRead() const
{
if (!d) {
return QDateTime();
}
return d->lastRead;
}
/*!
Returns true if the URL is a directory; otherwise returns false.
\sa isValid()
*/
bool QUrlInfo::isDir() const
{
if (!d) {
return false;
}
return d->isDir;
}
/*!
Returns true if the URL is a file; otherwise returns false.
\sa isValid()
*/
bool QUrlInfo::isFile() const
{
if (!d) {
return false;
}
return d->isFile;
}
/*!
Returns true if the URL is a symbolic link; otherwise returns false.
\sa isValid()
*/
bool QUrlInfo::isSymLink() const
{
if (!d) {
return false;
}
return d->isSymLink;
}
/*!
Returns true if the URL is writable; otherwise returns false.
\sa isValid()
*/
bool QUrlInfo::isWritable() const
{
if (!d) {
return false;
}
return d->isWritable;
}
/*!
Returns true if the URL is readable; otherwise returns false.
\sa isValid()
*/
bool QUrlInfo::isReadable() const
{
if (!d) {
return false;
}
return d->isReadable;
}
/*!
Returns true if the URL is executable; otherwise returns false.
\sa isValid()
*/
bool QUrlInfo::isExecutable() const
{
if (!d) {
return false;
}
return d->isExecutable;
}
/*!
Returns true if \a i1 is greater than \a i2; otherwise returns
false. The objects are compared by the value, which is specified
by \a sortBy. This must be one of QDir::Name, QDir::Time or
QDir::Size.
*/
bool QUrlInfo::greaterThan(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy)
{
switch (sortBy) {
case QDir::Name:
return i1.name() > i2.name();
case QDir::Time:
return i1.lastModified() > i2.lastModified();
case QDir::Size:
return i1.size() > i2.size();
default:
return false;
}
}
/*!
Returns true if \a i1 is less than \a i2; otherwise returns false.
The objects are compared by the value, which is specified by \a
sortBy. This must be one of QDir::Name, QDir::Time or QDir::Size.
*/
bool QUrlInfo::lessThan(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy)
{
return !greaterThan(i1, i2, sortBy);
}
/*!
Returns true if \a i1 equals to \a i2; otherwise returns false.
The objects are compared by the value, which is specified by \a
sortBy. This must be one of QDir::Name, QDir::Time or QDir::Size.
*/
bool QUrlInfo::equal(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy)
{
switch (sortBy) {
case QDir::Name:
return i1.name() == i2.name();
case QDir::Time:
return i1.lastModified() == i2.lastModified();
case QDir::Size:
return i1.size() == i2.size();
default:
return false;
}
}
/*!
Returns true if this QUrlInfo is equal to \a other; otherwise
returns false.
\sa lessThan(), equal()
*/
bool QUrlInfo::operator==(const QUrlInfo &other) const
{
if (!d) {
return other.d == 0;
}
if (!other.d) {
return false;
}
return (d->name == other.d->name &&
d->permissions == other.d->permissions &&
d->owner == other.d->owner &&
d->group == other.d->group &&
d->size == other.d->size &&
d->lastModified == other.d->lastModified &&
d->lastRead == other.d->lastRead &&
d->isDir == other.d->isDir &&
d->isFile == other.d->isFile &&
d->isSymLink == other.d->isSymLink &&
d->isWritable == other.d->isWritable &&
d->isReadable == other.d->isReadable &&
d->isExecutable == other.d->isExecutable);
}
/*!
\fn bool QUrlInfo::operator!=(const QUrlInfo &other) const
\since 4.2
Returns true if this QUrlInfo is not equal to \a other; otherwise
returns false.
\sa lessThan(), equal()
*/
/*!
Returns true if the URL info is valid; otherwise returns false.
Valid means that the QUrlInfo contains real information.
You should always check if the URL info is valid before relying on
the values.
*/
bool QUrlInfo::isValid() const
{
return d != 0;
}
QT_END_NAMESPACE

127
src/lib/3rdparty/qurlinfo.h vendored Normal file
View File

@ -0,0 +1,127 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** 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, Digia gives you certain additional
** rights. These rights are described in the Digia 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.
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QURLINFO_H
#define QURLINFO_H
#include <QtCore/qdatetime.h>
#include <QtCore/qstring.h>
#include <QtCore/qiodevice.h>
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
class QUrl;
class QUrlInfoPrivate;
class QUrlInfo
{
public:
enum PermissionSpec {
ReadOwner = 00400, WriteOwner = 00200, ExeOwner = 00100,
ReadGroup = 00040, WriteGroup = 00020, ExeGroup = 00010,
ReadOther = 00004, WriteOther = 00002, ExeOther = 00001
};
QUrlInfo();
QUrlInfo(const QUrlInfo &ui);
QUrlInfo(const QString &name, int permissions, const QString &owner,
const QString &group, qint64 size, const QDateTime &lastModified,
const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
bool isWritable, bool isReadable, bool isExecutable);
QUrlInfo(const QUrl &url, int permissions, const QString &owner,
const QString &group, qint64 size, const QDateTime &lastModified,
const QDateTime &lastRead, bool isDir, bool isFile, bool isSymLink,
bool isWritable, bool isReadable, bool isExecutable);
QUrlInfo &operator=(const QUrlInfo &ui);
virtual ~QUrlInfo();
virtual void setName(const QString &name);
virtual void setDir(bool b);
virtual void setFile(bool b);
virtual void setSymLink(bool b);
virtual void setOwner(const QString &s);
virtual void setGroup(const QString &s);
virtual void setSize(qint64 size);
virtual void setWritable(bool b);
virtual void setReadable(bool b);
virtual void setPermissions(int p);
virtual void setLastModified(const QDateTime &dt);
void setLastRead(const QDateTime &dt);
bool isValid() const;
QString name() const;
int permissions() const;
QString owner() const;
QString group() const;
qint64 size() const;
QDateTime lastModified() const;
QDateTime lastRead() const;
bool isDir() const;
bool isFile() const;
bool isSymLink() const;
bool isWritable() const;
bool isReadable() const;
bool isExecutable() const;
static bool greaterThan(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy);
static bool lessThan(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy);
static bool equal(const QUrlInfo &i1, const QUrlInfo &i2,
int sortBy);
bool operator==(const QUrlInfo &i) const;
inline bool operator!=(const QUrlInfo &i) const
{ return !operator==(i); }
private:
QUrlInfoPrivate* d;
};
QT_END_NAMESPACE
QT_END_HEADER
#endif // QURLINFO_H

View File

@ -211,6 +211,7 @@ MainApplication::MainApplication(int &argc, char** argv)
setApplicationVersion(QupZilla::VERSION); setApplicationVersion(QupZilla::VERSION);
setOrganizationDomain("qupzilla"); setOrganizationDomain("qupzilla");
QDesktopServices::setUrlHandler("http", this, "addNewTab"); QDesktopServices::setUrlHandler("http", this, "addNewTab");
QDesktopServices::setUrlHandler("ftp", this, "addNewTab");
checkSettingsDir(); checkSettingsDir();
@ -414,6 +415,7 @@ void MainApplication::loadSettings()
// Allows to load files from qrc: scheme in qupzilla: pages // Allows to load files from qrc: scheme in qupzilla: pages
QWebSecurityOrigin::addLocalScheme("qupzilla"); QWebSecurityOrigin::addLocalScheme("qupzilla");
QWebSecurityOrigin::addLocalScheme("ftp");
if (m_isPrivateSession) { if (m_isPrivateSession) {
m_websettings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true); m_websettings->setAttribute(QWebSettings::PrivateBrowsingEnabled, true);

View File

@ -1524,7 +1524,7 @@ void QupZilla::searchOnPage()
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
if (QtWin::isCompositionEnabled()) { if (QtWin::isCompositionEnabled()) {
applyBlurToMainWindow(); applyBlurToMainWindow();
search->installEventFilter(this); toolBar->installEventFilter(this);
} }
#endif #endif
} }

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* QupZilla - WebKit based browser * QupZilla - WebKit based browser
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -25,6 +25,7 @@
#include "iconprovider.h" #include "iconprovider.h"
#include "networkmanager.h" #include "networkmanager.h"
#include "qztools.h" #include "qztools.h"
#include "schemehandlers/ftpschemehandler.h"
#include <QMenu> #include <QMenu>
#include <QClipboard> #include <QClipboard>
@ -43,6 +44,7 @@ DownloadItem::DownloadItem(QListWidgetItem* item, QNetworkReply* reply, const QS
, ui(new Ui::DownloadItem) , ui(new Ui::DownloadItem)
, m_item(item) , m_item(item)
, m_reply(reply) , m_reply(reply)
, m_ftpDownloader(0)
, m_path(path) , m_path(path)
, m_fileName(fileName) , m_fileName(fileName)
, m_downTimer(timer) , m_downTimer(timer)
@ -90,7 +92,18 @@ void DownloadItem::setTotalSize(qint64 total)
void DownloadItem::startDownloading() void DownloadItem::startDownloading()
{ {
QUrl locationHeader = m_reply->header(QNetworkRequest::LocationHeader).toUrl(); QUrl locationHeader = m_reply->header(QNetworkRequest::LocationHeader).toUrl();
if (locationHeader.isValid()) {
bool hasFtpUrlInHeader = locationHeader.isValid() && (locationHeader.scheme() == "ftp");
if (m_reply->url().scheme() == "ftp" || hasFtpUrlInHeader) {
QUrl url = hasFtpUrlInHeader ? locationHeader : m_reply->url();
m_reply->abort();
m_reply->deleteLater();
m_reply = 0;
startDownloadingFromFtp(url);
return;
}
else if (locationHeader.isValid()) {
m_reply->abort(); m_reply->abort();
m_reply->deleteLater(); m_reply->deleteLater();
@ -101,7 +114,7 @@ void DownloadItem::startDownloading()
connect(m_reply, SIGNAL(finished()), this, SLOT(finished())); connect(m_reply, SIGNAL(finished()), this, SLOT(finished()));
connect(m_reply, SIGNAL(readyRead()), this, SLOT(readyRead())); connect(m_reply, SIGNAL(readyRead()), this, SLOT(readyRead()));
connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64))); connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error(QNetworkReply::NetworkError))); connect(m_reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(error()));
connect(m_reply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged())); connect(m_reply, SIGNAL(metaDataChanged()), this, SLOT(metaDataChanged()));
m_downloading = true; m_downloading = true;
@ -111,7 +124,32 @@ void DownloadItem::startDownloading()
if (m_reply->error() != QNetworkReply::NoError) { if (m_reply->error() != QNetworkReply::NoError) {
stop(false); stop(false);
error(m_reply->error()); error();
}
}
void DownloadItem::startDownloadingFromFtp(const QUrl &url)
{
if (!m_outputFile.isOpen() && !m_outputFile.open(QIODevice::WriteOnly)) {
stop(false);
ui->downloadInfo->setText(tr("Error: Cannot write to file!"));
return;
}
m_ftpDownloader = new FtpDownloader(this);
connect(m_ftpDownloader, SIGNAL(finished()), this, SLOT(finished()));
connect(m_ftpDownloader, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(downloadProgress(qint64, qint64)));
connect(m_ftpDownloader, SIGNAL(errorOccured(QFtp::Error)), this, SLOT(error()));
connect(m_ftpDownloader, SIGNAL(ftpAuthenticationRequierd(const QUrl &, QAuthenticator*)), mApp->networkManager(), SLOT(ftpAuthentication(const QUrl &, QAuthenticator*)));
m_ftpDownloader->download(url, &m_outputFile);
m_downloading = true;
m_timer.start(1000, this);
QTimer::singleShot(200, this, SLOT(updateDownload()));
if (m_ftpDownloader->error() != QFtp::NoError) {
error();
} }
} }
@ -141,13 +179,20 @@ void DownloadItem::finished()
qDebug() << __FUNCTION__ << m_reply; qDebug() << __FUNCTION__ << m_reply;
#endif #endif
m_timer.stop(); m_timer.stop();
ui->downloadInfo->setText(tr("Done - %1").arg(m_reply->url().host()));
QString host = m_reply ? m_reply->url().host() : m_ftpDownloader->url().host();
ui->downloadInfo->setText(tr("Done - %1").arg(host));
ui->progressBar->hide(); ui->progressBar->hide();
ui->button->hide(); ui->button->hide();
ui->frame->hide(); ui->frame->hide();
m_outputFile.close(); m_outputFile.close();
if (m_reply) {
m_reply->deleteLater(); m_reply->deleteLater();
}
else {
m_ftpDownloader->deleteLater();
}
m_item->setSizeHint(sizeHint()); m_item->setSizeHint(sizeHint());
#if QT_VERSION == 0x040700 // Workaround #if QT_VERSION == 0x040700 // Workaround
@ -271,18 +316,23 @@ void DownloadItem::stop(bool askForDeleteFile)
#ifdef DOWNMANAGER_DEBUG #ifdef DOWNMANAGER_DEBUG
qDebug() << __FUNCTION__; qDebug() << __FUNCTION__;
#endif #endif
if (m_downloadStopped) { if (m_downloadStopped) {
return; return;
} }
m_downloadStopped = true; m_downloadStopped = true;
QString host = m_reply ? m_reply->url().host() : m_ftpDownloader->url().host();
m_openAfterFinish = false; m_openAfterFinish = false;
m_timer.stop(); m_timer.stop();
if (m_reply) {
m_reply->abort(); m_reply->abort();
}
else {
m_ftpDownloader->abort();
m_ftpDownloader->close();
}
QString outputfile = QFileInfo(m_outputFile).absoluteFilePath(); QString outputfile = QFileInfo(m_outputFile).absoluteFilePath();
m_outputFile.close(); m_outputFile.close();
ui->downloadInfo->setText(tr("Cancelled - %1").arg(m_reply->url().host())); ui->downloadInfo->setText(tr("Cancelled - %1").arg(host));
ui->progressBar->hide(); ui->progressBar->hide();
ui->button->hide(); ui->button->hide();
m_item->setSizeHint(sizeHint()); m_item->setSizeHint(sizeHint());
@ -395,14 +445,18 @@ void DownloadItem::readyRead()
m_outputFile.write(m_reply->readAll()); m_outputFile.write(m_reply->readAll());
} }
void DownloadItem::error(QNetworkReply::NetworkError error) void DownloadItem::error()
{ {
#ifdef DOWNMANAGER_DEBUG #ifdef DOWNMANAGER_DEBUG
qDebug() << __FUNCTION__ << error; qDebug() << __FUNCTION__ << (m_reply ? m_reply->error() : m_ftpDownloader->error());
#endif #endif
if (error != QNetworkReply::NoError) { if (m_reply && m_reply->error() != QNetworkReply::NoError) {
ui->downloadInfo->setText(tr("Error: ") + m_reply->errorString()); ui->downloadInfo->setText(tr("Error: ") + m_reply->errorString());
} }
else if (m_ftpDownloader && m_ftpDownloader->error() != QFtp::NoError) {
ui->downloadInfo->setText(tr("Error: ") + m_ftpDownloader->errorString());
stop(false);
}
} }
void DownloadItem::updateDownload() void DownloadItem::updateDownload()
@ -410,7 +464,9 @@ void DownloadItem::updateDownload()
#ifdef DOWNMANAGER_DEBUG #ifdef DOWNMANAGER_DEBUG
qDebug() << __FUNCTION__ ; qDebug() << __FUNCTION__ ;
#endif #endif
if (ui->progressBar->maximum() == 0 && m_outputFile.isOpen() && m_reply->isFinished()) { bool downoaderIsFinished = (m_reply && m_reply->isFinished())
|| (m_ftpDownloader && m_ftpDownloader->isFinished());
if (ui->progressBar->maximum() == 0 && m_outputFile.isOpen() && downoaderIsFinished) {
downloadProgress(0, 0); downloadProgress(0, 0);
finished(); finished();
} }

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* QupZilla - WebKit based browser * QupZilla - WebKit based browser
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -35,6 +35,7 @@ class DownloadItem;
class QListWidgetItem; class QListWidgetItem;
class DownloadManager; class DownloadManager;
class FtpDownloader;
class QT_QUPZILLA_EXPORT DownloadItem : public QWidget class QT_QUPZILLA_EXPORT DownloadItem : public QWidget
{ {
@ -67,7 +68,7 @@ private slots:
void openFile(); void openFile();
void openFolder(); void openFolder();
void readyRead(); void readyRead();
void error(QNetworkReply::NetworkError); void error();
void updateDownload(); void updateDownload();
void customContextMenuRequested(const QPoint &pos); void customContextMenuRequested(const QPoint &pos);
void clear(); void clear();
@ -77,6 +78,7 @@ private slots:
private: private:
void startDownloading(); void startDownloading();
void startDownloadingFromFtp(const QUrl &url);
void timerEvent(QTimerEvent* event); void timerEvent(QTimerEvent* event);
void updateDownloadInfo(double currSpeed, qint64 received, qint64 total); void updateDownloadInfo(double currSpeed, qint64 received, qint64 total);
@ -85,6 +87,7 @@ private:
QListWidgetItem* m_item; QListWidgetItem* m_item;
QNetworkReply* m_reply; QNetworkReply* m_reply;
FtpDownloader* m_ftpDownloader;
QString m_path; QString m_path;
QString m_fileName; QString m_fileName;
QTime* m_downTimer; QTime* m_downTimer;

View File

@ -9,6 +9,9 @@ TEMPLATE = lib
DEFINES *= QUPZILLA_SHAREDLIBRARY DEFINES *= QUPZILLA_SHAREDLIBRARY
isEqual(QT_MAJOR_VERSION, 5) {
include(3rdparty/qftp.pri)
}
include(3rdparty/qtsingleapplication.pri) include(3rdparty/qtsingleapplication.pri)
include(../defines.pri) include(../defines.pri)
include(../../translations/translations.pri) include(../../translations/translations.pri)
@ -202,6 +205,7 @@ SOURCES += \
tools/html5permissions/html5permissionsdialog.cpp \ tools/html5permissions/html5permissionsdialog.cpp \
autofill/pageformcompleter.cpp \ autofill/pageformcompleter.cpp \
autofill/autofill.cpp \ autofill/autofill.cpp \
network/schemehandlers/ftpschemehandler.cpp \
HEADERS += \ HEADERS += \
webview/tabpreview.h \ webview/tabpreview.h \
@ -366,6 +370,7 @@ HEADERS += \
tools/html5permissions/html5permissionsdialog.h \ tools/html5permissions/html5permissionsdialog.h \
autofill/pageformcompleter.h \ autofill/pageformcompleter.h \
autofill/autofill.h \ autofill/autofill.h \
network/schemehandlers/ftpschemehandler.h \
FORMS += \ FORMS += \
preferences/autofillmanager.ui \ preferences/autofillmanager.ui \

View File

@ -32,6 +32,7 @@
#include "schemehandlers/adblockschemehandler.h" #include "schemehandlers/adblockschemehandler.h"
#include "schemehandlers/qupzillaschemehandler.h" #include "schemehandlers/qupzillaschemehandler.h"
#include "schemehandlers/fileschemehandler.h" #include "schemehandlers/fileschemehandler.h"
#include "schemehandlers/ftpschemehandler.h"
#include <QFormLayout> #include <QFormLayout>
#include <QLabel> #include <QLabel>
@ -76,6 +77,7 @@ NetworkManager::NetworkManager(QupZilla* mainClass, QObject* parent)
m_schemeHandlers["qupzilla"] = new QupZillaSchemeHandler(); m_schemeHandlers["qupzilla"] = new QupZillaSchemeHandler();
m_schemeHandlers["abp"] = new AdBlockSchemeHandler(); m_schemeHandlers["abp"] = new AdBlockSchemeHandler();
m_schemeHandlers["file"] = new FileSchemeHandler(); m_schemeHandlers["file"] = new FileSchemeHandler();
m_schemeHandlers["ftp"] = new FtpSchemeHandler();
m_proxyFactory = new NetworkProxyFactory(); m_proxyFactory = new NetworkProxyFactory();
setProxyFactory(m_proxyFactory); setProxyFactory(m_proxyFactory);
@ -306,6 +308,92 @@ void NetworkManager::authentication(QNetworkReply* reply, QAuthenticator* auth)
} }
} }
void NetworkManager::ftpAuthentication(const QUrl &url, QAuthenticator* auth)
{
QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());
FtpDownloader* ftp = 0;
if (!reply) {
ftp = qobject_cast<FtpDownloader*>(sender());
}
if (!auth) {
auth = FTP_AUTHENTICATOR(url);
}
QString lastUser = auth->user();
QString lastPass = auth->password();
if (lastUser.isEmpty() && lastPass.isEmpty()) {
// The auth is empty but url contains user's info
lastUser = url.userName();
lastPass = url.password();
}
QDialog* dialog = new QDialog(mApp->getWindow());
dialog->setWindowTitle(tr("FTP authorization required"));
QFormLayout* formLa = new QFormLayout(dialog);
QLabel* label = new QLabel(dialog);
QLabel* userLab = new QLabel(dialog);
QLabel* passLab = new QLabel(dialog);
userLab->setText(tr("Username: "));
passLab->setText(tr("Password: "));
QCheckBox* anonymousLogin = new QCheckBox(dialog);
QLineEdit* user = new QLineEdit(lastUser, dialog);
QLineEdit* pass = new QLineEdit(lastPass, dialog);
anonymousLogin->setText(tr("Login anonymously"));
connect(anonymousLogin, SIGNAL(toggled(bool)), user, SLOT(setDisabled(bool)));
connect(anonymousLogin, SIGNAL(toggled(bool)), pass, SLOT(setDisabled(bool)));
anonymousLogin->setChecked(lastUser.isEmpty() && lastPass.isEmpty());
pass->setEchoMode(QLineEdit::Password);
QDialogButtonBox* box = new QDialogButtonBox(dialog);
box->addButton(QDialogButtonBox::Ok);
box->addButton(QDialogButtonBox::Cancel);
connect(box, SIGNAL(rejected()), dialog, SLOT(reject()));
connect(box, SIGNAL(accepted()), dialog, SLOT(accept()));
int port = 21;
if (url.port() != -1) {
port = url.port();
}
label->setText(tr("A username and password are being requested by %1:%2.")
.arg(url.host(), QString::number(port)));
formLa->addRow(label);
formLa->addRow(anonymousLogin);
formLa->addRow(userLab, user);
formLa->addRow(passLab, pass);
formLa->addWidget(box);
if (dialog->exec() != QDialog::Accepted) {
if (reply) {
reply->abort();
// is it safe?
reply->deleteLater();
}
else if (ftp) {
ftp->abort();
ftp->close();
}
return;
}
if (!anonymousLogin->isChecked()) {
auth->setUser(user->text());
auth->setPassword(pass->text());
}
else {
auth->setUser(QString());
auth->setPassword(QString());
}
}
void NetworkManager::proxyAuthentication(const QNetworkProxy &proxy, QAuthenticator* auth) void NetworkManager::proxyAuthentication(const QNetworkProxy &proxy, QAuthenticator* auth)
{ {
QDialog* dialog = new QDialog(p_QupZilla); QDialog* dialog = new QDialog(p_QupZilla);
@ -357,6 +445,16 @@ QNetworkReply* NetworkManager::createRequest(QNetworkAccessManager::Operation op
if (m_schemeHandlers.contains(req.url().scheme())) { if (m_schemeHandlers.contains(req.url().scheme())) {
reply = m_schemeHandlers[req.url().scheme()]->createRequest(op, req, outgoingData); reply = m_schemeHandlers[req.url().scheme()]->createRequest(op, req, outgoingData);
if (reply) { if (reply) {
if (req.url().scheme() == "ftp") {
QVariant v = req.attribute((QNetworkRequest::Attribute)(QNetworkRequest::User + 100));
WebPage* webPage = static_cast<WebPage*>(v.value<void*>());
if (webPage) {
connect(reply, SIGNAL(downloadRequest(const QNetworkRequest &)),
webPage, SLOT(downloadRequested(const QNetworkRequest &)));
}
connect(reply, SIGNAL(ftpAuthenticationRequierd(const QUrl &, QAuthenticator*)),
this, SLOT(ftpAuthentication(const QUrl &, QAuthenticator*)));
}
return reply; return reply;
} }
} }

View File

@ -1,6 +1,6 @@
/* ============================================================ /* ============================================================
* QupZilla - WebKit based browser * QupZilla - WebKit based browser
* Copyright (C) 2010-2012 David Rosca <nowrep@gmail.com> * Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -63,6 +63,7 @@ signals:
private slots: private slots:
void authentication(QNetworkReply* reply, QAuthenticator* auth); void authentication(QNetworkReply* reply, QAuthenticator* auth);
void ftpAuthentication(const QUrl &url, QAuthenticator* auth);
void proxyAuthentication(const QNetworkProxy &proxy, QAuthenticator* auth); void proxyAuthentication(const QNetworkProxy &proxy, QAuthenticator* auth);
void sslError(QNetworkReply* reply, QList<QSslError> errors); void sslError(QNetworkReply* reply, QList<QSslError> errors);
void setSSLConfiguration(QNetworkReply* reply); void setSSLConfiguration(QNetworkReply* reply);

View File

@ -0,0 +1,432 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
* Copyright (C) 2013 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
* Some codes and ideas are from webftpclient example by Qt Lab
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#include "ftpschemehandler.h"
#include "qztools.h"
#include "iconprovider.h"
#include "mainapplication.h"
#include <QFileIconProvider>
#include <QTextStream>
#include <QDateTime>
#include <QDir>
QHash<QString, QAuthenticator*> FtpSchemeHandler::m_ftpAuthenticatorsCache = QHash<QString, QAuthenticator*>();
FtpSchemeHandler::FtpSchemeHandler()
{
}
QNetworkReply* FtpSchemeHandler::createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData)
{
Q_UNUSED(outgoingData)
if (op != QNetworkAccessManager::GetOperation) {
return 0;
}
QNetworkReply* reply = new FtpSchemeReply(request);
return reply;
}
QAuthenticator* FtpSchemeHandler::ftpAuthenticator(const QUrl &url)
{
QString key = url.host();
if (key.isEmpty()) {
key = url.toString();
}
if (!m_ftpAuthenticatorsCache.contains(key) || !m_ftpAuthenticatorsCache.value(key, 0)) {
QAuthenticator* auth = new QAuthenticator();
auth->setUser(url.userName());
auth->setPassword(url.password());
m_ftpAuthenticatorsCache.insert(key, auth);
}
return m_ftpAuthenticatorsCache.value(key);
}
FtpSchemeReply::FtpSchemeReply(const QNetworkRequest &request, QObject* parent)
: QNetworkReply(parent)
, m_ftpLoginId(-1)
, m_port(21)
, m_anonymousLoginChecked(false)
, m_request(request)
{
m_ftp = new QFtp(this);
connect(m_ftp, SIGNAL(listInfo(QUrlInfo)), this, SLOT(processListInfo(QUrlInfo)));
connect(m_ftp, SIGNAL(readyRead()), this, SLOT(processData()));
connect(m_ftp, SIGNAL(commandFinished(int, bool)), this, SLOT(processCommand(int, bool)));
connect(m_ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SIGNAL(downloadProgress(qint64, qint64)));
m_buffer.open(QIODevice::ReadWrite);
if (request.url().port() != -1) {
m_port = request.url().port();
}
setUrl(request.url());
m_ftp->connectToHost(request.url().host(), m_port);
}
void FtpSchemeReply::processCommand(int id, bool err)
{
if (err) {
if (m_ftpLoginId == id) {
if (!m_anonymousLoginChecked) {
m_anonymousLoginChecked = true;
FTP_AUTHENTICATOR(url())->setUser(QString());
FTP_AUTHENTICATOR(url())->setPassword(QString());
m_ftpLoginId = m_ftp->login();
return;
}
emit ftpAuthenticationRequierd(url(), FTP_AUTHENTICATOR(url()));
m_ftpLoginId = m_ftp->login(FTP_AUTHENTICATOR(url())->user(), FTP_AUTHENTICATOR(url())->password());
return;
}
setError(ContentNotFoundError, tr("Unknown command"));
emit error(ContentNotFoundError);
emit finished();
return;
}
switch (m_ftp->currentCommand()) {
case QFtp::ConnectToHost:
if (!m_anonymousLoginChecked) {
m_anonymousLoginChecked = FTP_AUTHENTICATOR(url())->user().isEmpty()
&& FTP_AUTHENTICATOR(url())->password().isEmpty();
}
m_ftpLoginId = m_ftp->login(FTP_AUTHENTICATOR(url())->user(),
FTP_AUTHENTICATOR(url())->password());
break;
case QFtp::Login:
m_ftp->list(url().path());
break;
case QFtp::List:
loadPage();
break;
case QFtp::Get:
setContent();
break;
default:
;
}
}
void FtpSchemeReply::processListInfo(const QUrlInfo &urlInfo)
{
m_items.append(urlInfo);
}
void FtpSchemeReply::processData()
{
open(ReadOnly | Unbuffered);
QTextStream stream(&m_buffer);
stream << m_ftp->readAll();
stream.flush();
m_buffer.reset();
setHeader(QNetworkRequest::ContentLengthHeader, m_buffer.bytesAvailable());
emit metaDataChanged();
}
void FtpSchemeReply::setContent()
{
open(ReadOnly | Unbuffered);
setHeader(QNetworkRequest::ContentLengthHeader, QVariant(m_buffer.size()));
emit readyRead();
emit finished();
m_ftp->close();
}
void FtpSchemeReply::abort()
{
setError(QNetworkReply::OperationCanceledError, tr("Canceled!"));
emit error(QNetworkReply::OperationCanceledError);
emit finished();
m_ftp->close();
}
qint64 FtpSchemeReply::bytesAvailable() const
{
return m_buffer.bytesAvailable() + QNetworkReply::bytesAvailable();
}
bool FtpSchemeReply::isSequential() const
{
return true;
}
qint64 FtpSchemeReply::readData(char* data, qint64 maxSize)
{
return m_buffer.read(data, maxSize);
}
void FtpSchemeReply::loadPage()
{
if (m_items.size() == 1 && m_items.at(0).isFile()) {
QUrlInfo item = m_items.at(0);
if (url().path() == url().resolved(QUrl(item.name())).path()) {
setHeader(QNetworkRequest::ContentLengthHeader, m_buffer.bytesAvailable());
// the following code can be used to open known contents
// and download unsupported contents, but there is some problem
// for example: it loads PDFs as text file!
// m_ftp->get(url().path());
emit downloadRequest(m_request);
abort();
return;
}
}
open(ReadOnly | Unbuffered);
QTextStream stream(&m_buffer);
stream.setCodec("UTF-8");
stream << loadDirectory();
stream.flush();
m_buffer.reset();
setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("text/html"));
setHeader(QNetworkRequest::ContentLengthHeader, m_buffer.bytesAvailable());
setAttribute(QNetworkRequest::HttpStatusCodeAttribute, 200);
setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, QByteArray("Ok"));
emit metaDataChanged();
emit readyRead();
emit finished();
m_ftp->close();
}
QString FtpSchemeReply::loadDirectory()
{
QUrl u = url();
if (!u.path().endsWith("/")) {
u.setPath(u.path() + "/");
}
QString base_path = u.path();
const QDir &dir = QDir(base_path);
QUrl parent = u.resolved(QUrl(".."));
static QString sPage;
if (sPage.isEmpty()) {
sPage = QzTools::readAllFileContents(":/html/dirlist.html");
sPage.replace(QLatin1String("%BOX-BORDER%"), QLatin1String("qrc:html/box-border.png"));
sPage.replace(QLatin1String("%UP-IMG%"), QzTools::pixmapToByteArray(qIconProvider->standardIcon(QStyle::SP_FileDialogToParent).pixmap(22)));
sPage.replace(QLatin1String("%UP-DIR-TEXT%"), tr("Up to higher level directory"));
sPage.replace(QLatin1String("%SHOW-HIDDEN-TEXT%"), tr("Show hidden files"));
sPage.replace(QLatin1String("%NAME%"), tr("Name"));
sPage.replace(QLatin1String("%SIZE%"), tr("Size"));
sPage.replace(QLatin1String("%MODIFIED%"), tr("Last modified"));
sPage = QzTools::applyDirectionToPage(sPage);
}
QString page = sPage;
page.replace(QLatin1String("%TITLE%"), tr("Index for %1").arg(url().toString()));
QString upDirDisplay = QLatin1String("none");
QString tBody;
if (!dir.isRoot()) {
upDirDisplay = QLatin1String("inline");
page.replace(QLatin1String("%UP-DIR-LINK%"), parent.toEncoded());
}
int lastIndex = m_items.size();
for (int i = 0; i < lastIndex; ++i) {
if (m_items.at(i).isFile()) {
m_items.move(i, m_items.size() - 1);
--lastIndex;
--i;
}
}
foreach(const QUrlInfo & item, m_items) {
if (item.name() == QLatin1String(".") || item.name() == QLatin1String("..")) {
continue;
}
QString line = QLatin1String("<tr");
QUrl itemUrl = u.resolved(QUrl(item.name()));
QString itemPath = itemUrl.path();
if (itemPath.endsWith("/")) {
itemPath.remove(itemPath.size() - 1, 1);
}
line += QLatin1String("><td class=\"td-name\" style=\"background-image:url(data:image/png;base64,");
line += QzTools::pixmapToByteArray(item.isFile()
? QzTools::iconFromFileName(itemPath).pixmap(16)
: QFileIconProvider().icon(QFileIconProvider::Folder).pixmap(16));
line += QLatin1String(");\">");
line += QLatin1String("<a href=\"");
line += itemUrl.toEncoded();
line += QLatin1String("\">");
line += item.name();
line += QLatin1String("</a></td><td class=\"td-size\">");
line += item.isDir() ? QString() : QzTools::fileSizeToString(item.size());
line += QLatin1String("</td><td>");
line += item.lastModified().toString("dd.MM.yyyy");
line += QLatin1String("</td><td>");
line += item.lastModified().toString("hh:mm:ss");
line += QLatin1String("</td></tr>\n");
tBody.append(line);
}
if (tBody.isEmpty()) {
tBody = QString("<tr><td colspan='4'>%1</td></tr>").arg(tr("Folder is empty."));
}
page.replace(QLatin1String("%T-BODY%"), tBody);
page.replace(QLatin1String("%UP-DIR-DISPLAY%"), upDirDisplay);
page.replace(QLatin1String("%SHOW-HIDDEN-DISPLAY%"), QLatin1String("none"));
return page;
}
FtpDownloader::FtpDownloader(QObject* parent)
: QFtp(parent)
, m_ftpLoginId(-1)
, m_anonymousLoginChecked(false)
, m_isFinished(false)
, m_url(QUrl())
, m_dev(0)
, m_lastError(QFtp::NoError)
{
connect(this, SIGNAL(commandFinished(int, bool)), this, SLOT(processCommand(int, bool)));
connect(this, SIGNAL(done(bool)), this, SLOT(onDone(bool)));
}
void FtpDownloader::download(const QUrl &url, QIODevice* dev)
{
m_url = url;
m_dev = dev;
QString server = m_url.host();
if (server.isEmpty()) {
server = m_url.toString();
}
int port = 21;
if (m_url.port() != -1) {
port = m_url.port();
}
connectToHost(server, port);
}
void FtpDownloader::setError(QFtp::Error err, const QString &errStr)
{
m_lastError = err;
m_lastErrorString = errStr;
}
void FtpDownloader::abort()
{
setError(QFtp::UnknownError, tr("Canceled!"));
QFtp::abort();
}
QFtp::Error FtpDownloader::error()
{
if (m_lastError != QFtp::NoError && QFtp::error() == QFtp::NoError) {
return m_lastError;
}
else {
return QFtp::error();
}
}
QString FtpDownloader::errorString() const
{
if (!m_lastErrorString.isEmpty()
&& m_lastError != QFtp::NoError
&& QFtp::error() == QFtp::NoError) {
return m_lastErrorString;
}
else {
return QFtp::errorString();
}
}
void FtpDownloader::processCommand(int id, bool err)
{
if (!m_url.isValid() || m_url.isEmpty() || !m_dev) {
abort();
return;
}
if (err) {
if (m_ftpLoginId == id) {
if (!m_anonymousLoginChecked) {
m_anonymousLoginChecked = true;
FTP_AUTHENTICATOR(m_url)->setUser(QString());
FTP_AUTHENTICATOR(m_url)->setPassword(QString());
m_ftpLoginId = login();
return;
}
emit ftpAuthenticationRequierd(m_url, FTP_AUTHENTICATOR(m_url));
m_ftpLoginId = login(FTP_AUTHENTICATOR(m_url)->user(), FTP_AUTHENTICATOR(m_url)->password());
return;
}
abort();
return;
}
switch (currentCommand()) {
case QFtp::ConnectToHost:
if (!m_anonymousLoginChecked) {
m_anonymousLoginChecked = FTP_AUTHENTICATOR(m_url)->user().isEmpty()
&& FTP_AUTHENTICATOR(m_url)->password().isEmpty();
}
m_ftpLoginId = login(FTP_AUTHENTICATOR(m_url)->user(), FTP_AUTHENTICATOR(m_url)->password());
break;
case QFtp::Login:
get(m_url.path(), m_dev);
break;
default:
;
}
}
void FtpDownloader::onDone(bool err)
{
disconnect(this, SIGNAL(done(bool)), this, SLOT(onDone(bool)));
close();
m_ftpLoginId = -1;
if (err || m_lastError != QFtp::NoError) {
emit errorOccured(error());
}
else {
m_isFinished = true;
emit finished();
}
}

View File

@ -0,0 +1,122 @@
/* ============================================================
* QupZilla - WebKit based browser
* Copyright (C) 2010-2013 David Rosca <nowrep@gmail.com>
* Copyright (C) 2013 S. Razi Alavizadeh <s.r.alavizadeh@gmail.com>
* Some codes and ideas are from webftpclient example by Qt Lab
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
* ============================================================ */
#ifndef FTPSCHEMEHANDLER_H
#define FTPSCHEMEHANDLER_H
#include <QAuthenticator>
#include <QNetworkReply>
#include <QBuffer>
#if QT_VERSION >= 0x050000
#include "qftp.h"
#include "qurlinfo.h"
#else
#include <QFtp>
#include <QUrlInfo>
#endif
#include "schemehandler.h"
#include "qz_namespace.h"
#define FTP_AUTHENTICATOR FtpSchemeHandler::ftpAuthenticator
class QT_QUPZILLA_EXPORT FtpSchemeHandler : public SchemeHandler
{
public:
explicit FtpSchemeHandler();
QNetworkReply* createRequest(QNetworkAccessManager::Operation op, const QNetworkRequest &request, QIODevice* outgoingData);
static QAuthenticator* ftpAuthenticator(const QUrl &url);
private:
static QHash<QString, QAuthenticator*> m_ftpAuthenticatorsCache;
};
class QT_QUPZILLA_EXPORT FtpSchemeReply : public QNetworkReply
{
Q_OBJECT
public:
FtpSchemeReply(const QNetworkRequest &request, QObject* parent = 0);
void abort();
qint64 bytesAvailable() const;
bool isSequential() const;
protected:
qint64 readData(char* data, qint64 maxSize);
private slots:
void processCommand(int id, bool err);
void processListInfo(const QUrlInfo &urlInfo);
void processData();
QString loadDirectory();
void loadPage();
private:
void setContent();
QFtp* m_ftp;
QList<QUrlInfo> m_items;
int m_ftpLoginId;
int m_port;
QBuffer m_buffer;
bool m_anonymousLoginChecked;
QNetworkRequest m_request;
signals:
void ftpAuthenticationRequierd(const QUrl &, QAuthenticator*);
void downloadRequest(const QNetworkRequest &);
};
class QT_QUPZILLA_EXPORT FtpDownloader : public QFtp
{
Q_OBJECT
public:
FtpDownloader(QObject* parent = 0);
void download(const QUrl &url, QIODevice* dev);
inline bool isFinished() {return m_isFinished;}
inline QUrl url() const {return m_url;}
inline QIODevice* device() const {return m_dev;}
void setError(QFtp::Error err, const QString &errStr);
void abort();
QFtp::Error error();
QString errorString() const;
private slots:
void processCommand(int id, bool err);
void onDone(bool err);
private:
int m_ftpLoginId;
bool m_anonymousLoginChecked;
bool m_isFinished;
QUrl m_url;
QIODevice* m_dev;
QFtp::Error m_lastError;
QString m_lastErrorString;
signals:
void ftpAuthenticationRequierd(const QUrl &, QAuthenticator*);
void finished();
void errorOccured(QFtp::Error);
};
#endif // FTPSCHEMEHANDLER_H

View File

@ -31,6 +31,8 @@
#include <QDesktopWidget> #include <QDesktopWidget>
#include <QUrl> #include <QUrl>
#include <QIcon> #include <QIcon>
#include <QFileIconProvider>
#include <QTemporaryFile>
#if QT_VERSION >= 0x050000 #if QT_VERSION >= 0x050000
#include <QUrlQuery> #include <QUrlQuery>
@ -426,3 +428,12 @@ QString QzTools::buildSystem()
return "Haiku"; return "Haiku";
#endif #endif
} }
QIcon QzTools::iconFromFileName(const QString &fileName)
{
QFileInfo tempInfo(fileName);
QTemporaryFile tempFile(QDir::tempPath() + "/XXXXXX." + tempInfo.suffix());
tempFile.open();
tempInfo.setFile(tempFile.fileName());
return QFileIconProvider().icon(tempInfo);
}

View File

@ -57,6 +57,7 @@ QPixmap QT_QUPZILLA_EXPORT createPixmapForSite(const QIcon &icon, const QString
QString QT_QUPZILLA_EXPORT applyDirectionToPage(QString &pageContents); QString QT_QUPZILLA_EXPORT applyDirectionToPage(QString &pageContents);
QString QT_QUPZILLA_EXPORT buildSystem(); QString QT_QUPZILLA_EXPORT buildSystem();
QIcon QT_QUPZILLA_EXPORT iconFromFileName(const QString &fileName);
// Qt5 migration help functions // Qt5 migration help functions
bool QT_QUPZILLA_EXPORT isCertificateValid(const QSslCertificate &cert); bool QT_QUPZILLA_EXPORT isCertificateValid(const QSslCertificate &cert);

View File

@ -501,7 +501,7 @@ bool WebPage::acceptNavigationRequest(QWebFrame* frame, const QNetworkRequest &r
const QString &scheme = request.url().scheme(); const QString &scheme = request.url().scheme();
if (scheme == QLatin1String("mailto") || scheme == QLatin1String("ftp")) { if (scheme == QLatin1String("mailto")) {
desktopServicesOpen(request.url()); desktopServicesOpen(request.url());
return false; return false;
} }