libqutim 0.3.1.0
filetransfer.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** qutIM - instant messenger
00004 **
00005 ** Copyright © 2011 Ruslan Nigmatullin <euroelessar@yandex.ru>
00006 **
00007 *****************************************************************************
00008 **
00009 ** $QUTIM_BEGIN_LICENSE$
00010 ** This program is free software: you can redistribute it and/or modify
00011 ** it under the terms of the GNU General Public License as published by
00012 ** the Free Software Foundation, either version 3 of the License, or
00013 ** (at your option) any later version.
00014 **
00015 ** This program is distributed in the hope that it will be useful,
00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00018 ** See the GNU General Public License for more details.
00019 **
00020 ** You should have received a copy of the GNU General Public License
00021 ** along with this program.  If not, see http://www.gnu.org/licenses/.
00022 ** $QUTIM_END_LICENSE$
00023 **
00024 ****************************************************************************/
00025 
00026 #ifndef FILETRANSFER_H
00027 #define FILETRANSFER_H
00028 
00029 #include "libqutim_global.h"
00030 #include <QHostAddress>
00031 #include <QStringList>
00032 #include <QSharedData>
00033 
00034 class QDir;
00035 class QUrl;
00036 class QIcon;
00037 
00038 namespace qutim_sdk_0_3
00039 {
00040 
00041 class ChatUnit;
00042 class LocalizedString;
00043 class FileTransferFactory;
00044 class FileTransferManager;
00045 class FileTransferManagerPrivate;
00046 class FileTransferJobPrivate;
00047 class FileTransferInfoPrivate;
00048 class FileTransferObserverPrivate;
00049 class FileTransferFactoryPrivate;
00050 class FileTransferManagerPrivate;
00051 
00052 class LIBQUTIM_EXPORT FileTransferInfo
00053 {
00054 public:
00055     FileTransferInfo();
00056     FileTransferInfo(const FileTransferInfo &other);
00057     ~FileTransferInfo();
00058     FileTransferInfo &operator =(const FileTransferInfo &other);
00059     
00060     // Relative file name
00061     QString fileName() const;
00062     void setFileName(const QString &fileName);
00063     qint64 fileSize() const;
00064     void setFileSize(qint64 fileSize);
00065 private:
00066     QSharedDataPointer<FileTransferInfoPrivate> d_ptr;
00067 };
00068 
00069 class LIBQUTIM_EXPORT FileTransferJob : public QObject
00070 {
00071     Q_OBJECT
00072     Q_DECLARE_PRIVATE(FileTransferJob)
00073     Q_ENUMS(Direction ErrorType State)
00074     Q_PROPERTY(QString title READ title NOTIFY titleChanged)
00075     Q_PROPERTY(QString fileName READ fileName NOTIFY fileNameChanged)
00076     Q_PROPERTY(int filesCount READ filesCount)
00077     Q_PROPERTY(int currentIndex READ currentIndex NOTIFY currentIndexChanged)
00078     Q_PROPERTY(qint64 totalSize READ totalSize NOTIFY totalSizeChanged)
00079     Q_PROPERTY(qint64 fileSize READ fileSize NOTIFY fileSizeChanged)
00080     Q_PROPERTY(qint64 progress READ progress NOTIFY progressChanged)
00081     Q_PROPERTY(qutim_sdk_0_3::FileTransferJob::State state READ state NOTIFY stateChanged)
00082     Q_PROPERTY(qutim_sdk_0_3::ChatUnit *chatUnit READ chatUnit)
00083 public:
00084     enum Direction { Outgoing, Incoming };
00085     enum ErrorType { NetworkError, Canceled, NotSupported, IOError, NoError };
00086     enum State { Initiation, Started, Finished, Error };
00087     
00088     FileTransferJob(ChatUnit *unit, Direction direction, FileTransferFactory *factory);
00089     virtual ~FileTransferJob();
00090     
00091     // Send some file or dir
00092     void send(const QUrl &url, const QString &title = QString());
00093     void send(const QDir &baseDir, const QStringList &files, const QString &title);
00094 
00095     Direction direction() const;
00096     QString title() const;
00097     QString fileName() const;
00098     // For outgoing only
00099     QDir baseDir() const;
00100     FileTransferInfo info(int index) const;
00101     int filesCount() const;
00102     int currentIndex() const;
00103     qint64 fileSize() const;
00104     qint64 progress() const;
00105     qint64 totalSize() const;
00106     State state() const;
00107     LocalizedString stateString();
00108     ErrorType error() const;
00109     LocalizedString errorString();
00110     ChatUnit *chatUnit() const;
00111     bool isAccepted();
00112 public slots:
00113     void stop();
00114     // Accept incoming job
00115     void accept();
00116 protected:
00117     virtual void doSend() = 0;
00118     virtual void doStop() = 0;
00119     virtual void doReceive() = 0;
00120     // For incoming only
00121     void init(int filesCount, qint64 totalSize, const QString &title);
00122     // Device for local files to read/write
00123     QIODevice *setCurrentIndex(int index);
00124     void setFileProgress(qint64 fileProgress);
00125     void setError(ErrorType error);
00126     void setErrorString(const LocalizedString &error);
00127     void setState(State state);
00128     void setStateString(const LocalizedString &state);
00129     void setFileInfo(int index, const FileTransferInfo &info);
00130     virtual void virtual_hook(int id, void *data);
00131 signals:
00132 #if !defined(Q_MOC_RUN) && !defined(DOXYGEN_SHOULD_SKIP_THIS) && !defined(IN_IDE_PARSER)
00133 private: // don't tell moc, doxygen or kdevelop, but those signals are in fact private
00134 #endif
00135     void titleChanged(const QString &);
00136     void fileNameChanged(const QString &);
00137     void fileSizeChanged(qint64);
00138     void progressChanged(qint64);
00139     void totalSizeChanged(qint64);
00140     void currentIndexChanged(int);
00141     void error(qutim_sdk_0_3::FileTransferJob::ErrorType, qutim_sdk_0_3::FileTransferJob *newJob);
00142     void errorStringChanged(const qutim_sdk_0_3::LocalizedString &);
00143     void stateChanged(qutim_sdk_0_3::FileTransferJob::State);
00144     void stateStringChanged(const qutim_sdk_0_3::LocalizedString &);
00145     void finished();
00146     void accepted();
00147 private:
00148     friend class FileTransferManager;
00149     QScopedPointer<FileTransferJobPrivate> d_ptr;
00150 };
00151 
00152 class LIBQUTIM_EXPORT FileTransferObserver : public QObject
00153 {
00154     Q_OBJECT
00155     Q_DECLARE_PRIVATE(FileTransferObserver)
00156     Q_PROPERTY(bool ability READ checkAbility NOTIFY abilityChanged)
00157     Q_PROPERTY(ChatUnit *chatUnit READ chatUnit)
00158 public:
00159     FileTransferObserver(ChatUnit *unit);
00160     ~FileTransferObserver();
00161     bool checkAbility() const;
00162     ChatUnit *chatUnit() const;
00163 signals:
00164     void abilityChanged(bool);
00165 protected:
00166     Q_PRIVATE_SLOT(d_func(), void _q_clearObserverData(QObject *unit));
00167     QScopedPointer<FileTransferObserverPrivate> d_ptr;
00168 };
00169 
00170 class LIBQUTIM_EXPORT FileTransferFactory : public QObject
00171 {
00172     Q_OBJECT
00173     Q_DECLARE_PRIVATE(FileTransferFactory)
00174     Q_ENUMS(Capability)
00175 public:
00176     enum Capability {
00177         CanSendMultiple = 0x01
00178     };
00179     Q_DECLARE_FLAGS(Capabilities, Capability)
00180     FileTransferFactory(const LocalizedString &name, Capabilities capabilities);
00181     ~FileTransferFactory();
00182     Capabilities capabilities() const;
00183     LocalizedString name() const;
00184     LocalizedString description() const;
00185     QIcon icon() const;
00186     virtual bool checkAbility(ChatUnit *unit) = 0;
00187     virtual bool startObserve(ChatUnit *unit) = 0;
00188     virtual bool stopObserve(ChatUnit *unit) = 0;
00189     virtual FileTransferJob *create(ChatUnit *unit) = 0;
00190 protected:
00191     void changeAvailability(ChatUnit *unit, bool canSend);
00192     void setDescription(const LocalizedString &description);
00193     void setIcon(const QIcon &icon);
00194     virtual void virtual_hook(int id, void *data);
00195     QScopedPointer<FileTransferFactoryPrivate> d_ptr;
00196 };
00197 
00198 class LIBQUTIM_EXPORT FileTransferManager : public QObject
00199 {
00200     Q_OBJECT
00201     Q_DECLARE_PRIVATE(FileTransferManager)
00202     Q_CLASSINFO("Service", "FileTransferManager")
00203 public:
00204     FileTransferManager();
00205     ~FileTransferManager();
00206     
00207     static bool checkAbility(ChatUnit *unit);
00208     // If the factory is null, the file/directory will be sent through
00209     // the most appropriate factory
00210     static FileTransferJob *send(ChatUnit *unit, const QUrl &url,
00211                                  const QString &title = QString(),
00212                                  FileTransferFactory *factory = 0);
00213     static QIODevice *openFile(FileTransferJob *job);
00214     static QList<FileTransferFactory*> factories();
00215     // This method must be called by the file transfer settings layer
00216     // whenever the user has changed an order of the file transfer
00217     // factories.
00218     // TODO: come up with a more appropriate name
00219     static void updateFactories(const QStringList &factoryClassNames);
00220 protected:
00221     virtual QIODevice *doOpenFile(FileTransferJob *job) = 0;
00222     virtual void handleJob(FileTransferJob *job, FileTransferJob *oldJob) = 0;
00223     virtual void virtual_hook(int id, void *data);
00224     QScopedPointer<FileTransferManagerPrivate> d_ptr;
00225 };
00226 
00227 }
00228 
00229 #endif // FILETRANSFER_H
00230