summaryrefslogtreecommitdiffstats
path: root/konversation/src/dcctransferrecv.h
blob: b0add72771653001aac8670e3cd466d72baa00fb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
  receive a file on DCC protocol
  begin:     Mit Aug 7 2002
  copyright: (C) 2002 by Dario Abatianni
  email:     eisfuchs@tigress.com
*/
// Copyright (C) 2004-2007 Shintaro Matsuoka <shin@shoegazed.org>
// Copyright (C) 2004,2005 John Tapsell <john@geola.co.uk>

/*
  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 2 of the License, or
  (at your option) any later version.
*/

#ifndef DCCTRANSFERRECV_H
#define DCCTRANSFERRECV_H

#include "dcctransfer.h"
// TODO: remove the dependence
#include "dccresumedialog.h"

#include <tqptrlist.h>


class TQFile;
class TQTimer;

namespace KIO
{
    class Job;
    class TransferJob;
}

namespace KNetwork
{
    class KServerSocket;
    class KStreamSocket;
}

class DccTransferRecvWriteCacheHandler;

class DccTransferRecv : public DccTransfer
{
    Q_OBJECT

    public:
        DccTransferRecv(TQObject* parent);
        virtual ~DccTransferRecv();

        // REQUIRED
        void setPartnerIp( const TQString& ip );
        // REQUIRED
        void setPartnerPort( const TQString& port );
        // REQUIRED
        void setFileSize( unsigned long fileSize );
        // OPTIONAL, if not specified, "unnamed_file"
        // TODO: "$sendername-$receiveddate" is better
        void setFileName( const TQString& fileName );
        // OPTIONAL, if not specified, default folder + the file name
        void setFileURL( const KURL& url );
        // OPTIONAL
        void setReverse( bool reverse, const TQString& reverseToken );

    public slots:
        virtual bool queue();

        /** The user has accepted the download.
         *  Check we are saving it somewhere valid, create any directories needed, and
         *  connect to remote host.
         */
        virtual void start();
        /** The user has chosen to abort.
         *  Either by chosen to abort directly, or by choosing cancel when
         *  prompted for information on where to save etc.
         *  Not called when it fails due to another problem.
         */
        virtual void abort();
        void startResume( unsigned long position );

    protected slots:
        // Local KIO
        void slotLocalCanResume( KIO::Job* job, KIO::filesize_t size );
        void slotLocalGotResult( KIO::Job* job );
        void slotLocalReady( KIO::Job* job );
        void slotLocalWriteDone();
        void slotLocalGotWriteError( const TQString& errorString );

        // Remote DCC
        void connectWithSender();
        void startReceiving();
        void connectionFailed( int errorCode );
        void readData();
        void sendAck();
        void connectionTimeout();
        void slotSocketClosed();

        // Reverse DCC
        void slotServerSocketReadyAccept();
        void slotServerSocketGotError( int errorCode );

    protected:
        void cleanUp();
        void failed(const TQString& errorMessage = TQString() );

                                                  // (startPosition == 0) means "don't resume"
        void prepareLocalKio( bool overwrite, bool resume, KIO::fileoffset_t startPosition = 0 );
        void askAndPrepareLocalKio( const TQString& message, int enabledActions, DccResumeDialog::ReceiveAction defaultAction, KIO::fileoffset_t startPosition = 0 );

        /**
         * This calls KIO::NetAccess::mkdir on all the subdirectories of dirURL, to
         * create the given directory.  Note that a url like  file:/foo/bar  will
         * make sure both foo and bar are created.  It assumes everything in the path is
         * a directory.
         * Note: If the directory already exists, returns true.
         *
         * @param dirURL A url for the directory to create.
         * @return True if the directory now exists.  False if there was a problem and the directory doesn't exist.
         */
        bool createDirs(const KURL &dirURL) const;

        void requestResume();
        // for non-reverse DCC
        void connectToSendServer();
        // for reverse DCC
        bool startListeningForSender();

        void startConnectionTimer( int sec );
        void stopConnectionTimer();

    protected:
        KURL m_saveToTmpFileURL;
        ///Current filesize of the file saved on the disk.
        KIO::filesize_t m_saveToFileSize;
        ///Current filesize of the file+".part" saved on the disk.
        KIO::filesize_t m_partialFileSize;
        DccTransferRecvWriteCacheHandler* m_writeCacheHandler;
        bool m_saveToFileExists;
        bool m_partialFileExists;
        TQTimer* m_connectionTimer;

        KNetwork::KServerSocket* m_serverSocket;
        KNetwork::KStreamSocket* m_recvSocket;

    private:
        virtual TQString getTypeText() const;
        virtual TQPixmap getTypeIcon() const;
};

class DccTransferRecvWriteCacheHandler : public QObject
{
    Q_OBJECT

        public:
        explicit DccTransferRecvWriteCacheHandler( KIO::TransferJob* transferJob );
        virtual ~DccTransferRecvWriteCacheHandler();

        void append( char* data, int size );
        bool write( bool force );
        void close();
        void closeNow();

        signals:
        void dataFinished();                      // ->  m_transferJob->slotFinished()
        void done();                              // ->  DccTransferRecv::writeDone()
                                                  // ->  DccTransferRecv::slotWriteError()
        void gotError( const TQString& errorString );

    protected slots:
                                                  // <-  m_transferJob->dataReq()
        void slotKIODataReq( KIO::Job* job, TQByteArray& data );
        void slotKIOResult( KIO::Job* job );      // <-  m_transferJob->result()

    protected:
        KIO::TransferJob* m_transferJob;
        bool m_writeAsyncMode;
        bool m_writeReady;

        TQValueList<TQByteArray> m_cacheList;
        TQDataStream* m_cacheStream;
};

#endif  // DCCTRANSFERRECV_H