2
* jabberfiletransfer.cpp
4
* Copyright (c) 2004 by Till Gerken <till@tantalo.net>
6
* Kopete (c) by the Kopete developers <kopete-devel@kde.org>
8
* *************************************************************************
10
* * This program is free software; you can redistribute it and/or modify *
11
* * it under the terms of the GNU General Public License as published by *
12
* * the Free Software Foundation; either version 2 of the License, or *
13
* * (at your option) any later version. *
15
* *************************************************************************
18
#include "jabberfiletransfer.h"
24
#include <kmessagebox.h>
27
#include "kopeteuiglobal.h"
28
#include "kopetemetacontact.h"
29
#include "kopetecontactlist.h"
30
#include "kopetetransfermanager.h"
31
#include "jabberaccount.h"
32
#include "jabberprotocol.h"
33
#include "jabberclient.h"
34
#include "jabbercontactpool.h"
35
#include "jabberbasecontact.h"
36
#include "jabbercontact.h"
38
JabberFileTransfer::JabberFileTransfer ( JabberAccount *account, XMPP::FileTransfer *incomingTransfer )
40
kDebug(JABBER_DEBUG_GLOBAL) << "New incoming transfer from " << incomingTransfer->peer().full () << ", filename " << incomingTransfer->fileName () << ", size " << QString::number ( incomingTransfer->fileSize () );
43
mXMPPTransfer = incomingTransfer;
45
// try to locate an exact match in our pool first
46
JabberBaseContact *contact = mAccount->contactPool()->findExactMatch ( mXMPPTransfer->peer () );
50
// we have no exact match, try a broader search
51
contact = mAccount->contactPool()->findRelevantRecipient ( mXMPPTransfer->peer () );
56
kDebug(JABBER_DEBUG_GLOBAL) << "No matching local contact found, creating a new one.";
58
Kopete::MetaContact *metaContact = new Kopete::MetaContact ();
60
metaContact->setTemporary (true);
62
contact = mAccount->contactPool()->addContact ( mXMPPTransfer->peer (), metaContact, false );
64
Kopete::ContactList::self ()->addMetaContact ( metaContact );
67
connect ( Kopete::TransferManager::transferManager (), SIGNAL (accepted(Kopete::Transfer*,QString)),
68
this, SLOT (slotIncomingTransferAccepted(Kopete::Transfer*,QString)) );
69
connect ( Kopete::TransferManager::transferManager (), SIGNAL (refused(Kopete::FileTransferInfo)),
70
this, SLOT (slotTransferRefused(Kopete::FileTransferInfo)) );
72
initializeVariables ();
74
#ifdef IRIS_FILE_TRANSFER_PREVIEW
76
if(!mXMPPTransfer->preview().isEmpty())
78
preview.loadFromData(KCodecs::base64Decode(mXMPPTransfer->preview().toAscii()));
81
mTransferId = Kopete::TransferManager::transferManager()->askIncomingTransfer ( contact,
82
mXMPPTransfer->fileName (),
83
mXMPPTransfer->fileSize (),
84
mXMPPTransfer->description () ,
91
JabberFileTransfer::JabberFileTransfer ( JabberAccount *account, JabberBaseContact *contact, const QString &file )
93
kDebug(JABBER_DEBUG_GLOBAL) << "New outgoing transfer for " << contact->contactId() << ": " << file;
96
mLocalFile.setFileName ( file );
97
bool canOpen=mLocalFile.open ( QIODevice::ReadOnly );
99
mKopeteTransfer = Kopete::TransferManager::transferManager()->addTransfer ( contact,
100
mLocalFile.fileName (),
102
contact->contactId (),
103
Kopete::FileTransferInfo::Outgoing );
106
connect ( mKopeteTransfer, SIGNAL (result(KJob*)), this, SLOT (slotTransferResult()) );
108
mXMPPTransfer = mAccount->client()->fileTransferManager()->createTransfer ();
110
initializeVariables ();
112
connect ( mXMPPTransfer, SIGNAL (connected()), this, SLOT (slotOutgoingConnected()) );
113
connect ( mXMPPTransfer, SIGNAL (bytesWritten(int)), this, SLOT (slotOutgoingBytesWritten(int)) );
114
connect ( mXMPPTransfer, SIGNAL (error(int)), this, SLOT (slotTransferError(int)) );
117
QImage img=QImage(mLocalFile.fileName());
120
img=img.scaled(64,64,Qt::KeepAspectRatio);
123
buffer.open(QIODevice::WriteOnly);
124
img.save(&buffer, "PNG"); // writes image into ba in PNG format
125
preview= KCodecs::base64Encode( ba , true );
130
#ifdef IRIS_FILE_TRANSFER_PREVIEW
131
mXMPPTransfer->sendFile ( XMPP::Jid ( contact->fullAddress () ), KUrl(file).fileName (), mLocalFile.size (), "", preview);
133
mXMPPTransfer->sendFile ( XMPP::Jid ( contact->fullAddress () ), KUrl(file).fileName (), mLocalFile.size (), "");
136
mKopeteTransfer->slotError ( KIO::ERR_CANNOT_OPEN_FOR_READING, file );
141
JabberFileTransfer::~JabberFileTransfer ()
143
kDebug(JABBER_DEBUG_GLOBAL) << "Destroying Jabber file transfer object.";
147
mXMPPTransfer->close ();
148
delete mXMPPTransfer;
152
void JabberFileTransfer::initializeVariables ()
156
mBytesTransferred = 0;
157
mBytesToTransfer = 0;
158
mXMPPTransfer->setProxy ( XMPP::Jid ( mAccount->configGroup()->readEntry ( "ProxyJID" ) ) );
162
void JabberFileTransfer::slotIncomingTransferAccepted ( Kopete::Transfer *transfer, const QString &fileName )
165
if ( (long)transfer->info().transferId () != mTransferId )
168
kDebug(JABBER_DEBUG_GLOBAL) << "Accepting transfer for " << mXMPPTransfer->peer().full ();
170
mKopeteTransfer = transfer;
171
mLocalFile.setFileName ( fileName );
173
bool couldOpen = false;
174
qlonglong offset = 0;
175
qlonglong length = 0;
177
mBytesTransferred = 0;
178
mBytesToTransfer = mXMPPTransfer->fileSize ();
180
if ( mXMPPTransfer->rangeSupported () && mLocalFile.exists () )
182
KGuiItem resumeButton ( i18n ( "&Resume" ) );
183
KGuiItem overwriteButton ( i18n ( "Over&write" ) );
185
switch ( KMessageBox::questionYesNoCancel ( Kopete::UI::Global::mainWidget (),
186
i18n ( "The file %1 already exists, do you want to resume or overwrite it?", fileName ),
187
i18n ( "File Exists: %1", fileName ),
188
resumeButton, overwriteButton ) )
190
case KMessageBox::Yes: // resume
191
couldOpen = mLocalFile.open ( QIODevice::ReadWrite );
194
offset = mLocalFile.size ();
195
length = mXMPPTransfer->fileSize () - offset;
196
mBytesTransferred = offset;
197
mBytesToTransfer = length;
198
mLocalFile.seek ( mLocalFile.size () );
202
case KMessageBox::No: // overwrite
203
couldOpen = mLocalFile.open ( QIODevice::WriteOnly );
213
// overwrite by default
214
couldOpen = mLocalFile.open ( QIODevice::WriteOnly );
219
transfer->slotError ( KIO::ERR_COULD_NOT_WRITE, fileName );
225
connect ( mKopeteTransfer, SIGNAL (result(KJob*)), this, SLOT (slotTransferResult()) );
226
connect ( mXMPPTransfer, SIGNAL (readyRead(QByteArray)), this, SLOT (slotIncomingDataReady(QByteArray)) );
227
connect ( mXMPPTransfer, SIGNAL (error(int)), this, SLOT (slotTransferError(int)) );
228
mXMPPTransfer->accept ( offset, length );
233
void JabberFileTransfer::slotTransferRefused ( const Kopete::FileTransferInfo &transfer )
236
if ( (long)transfer.transferId () != mTransferId )
239
kDebug(JABBER_DEBUG_GLOBAL) << "Local user refused transfer from " << mXMPPTransfer->peer().full ();
245
void JabberFileTransfer::slotTransferResult ()
248
if ( mKopeteTransfer->error () == KIO::ERR_USER_CANCELED )
250
kDebug(JABBER_DEBUG_GLOBAL) << "Transfer with " << mXMPPTransfer->peer().full () << " has been canceled.";
251
mXMPPTransfer->close ();
257
void JabberFileTransfer::slotTransferError ( int errorCode )
262
case XMPP::FileTransfer::ErrReject:
263
// user rejected the transfer request
264
mKopeteTransfer->slotError ( KIO::ERR_ACCESS_DENIED,
265
mXMPPTransfer->peer().full () );
268
case XMPP::FileTransfer::ErrNeg:
269
// unable to negotiate a suitable connection for the file transfer with the user
270
mKopeteTransfer->slotError ( KIO::ERR_COULD_NOT_LOGIN,
271
mXMPPTransfer->peer().full () );
274
case XMPP::FileTransfer::ErrConnect:
275
// could not connect to the user
276
mKopeteTransfer->slotError ( KIO::ERR_COULD_NOT_CONNECT,
277
mXMPPTransfer->peer().full () );
280
case XMPP::FileTransfer::ErrStream:
281
// data stream was disrupted, probably cancelled
282
mKopeteTransfer->slotError ( KIO::ERR_CONNECTION_BROKEN,
283
mXMPPTransfer->peer().full () );
288
mKopeteTransfer->slotError ( KIO::ERR_UNKNOWN,
289
mXMPPTransfer->peer().full () );
297
void JabberFileTransfer::slotIncomingDataReady ( const QByteArray &data )
300
mBytesTransferred += data.size ();
301
mBytesToTransfer -= data.size ();
303
mKopeteTransfer->slotProcessed ( mBytesTransferred );
305
mLocalFile.write ( data );
307
if ( mBytesToTransfer <= 0 )
309
kDebug(JABBER_DEBUG_GLOBAL) << "Transfer from " << mXMPPTransfer->peer().full () << " done.";
311
mKopeteTransfer->slotComplete ();
318
void JabberFileTransfer::slotOutgoingConnected ()
321
kDebug ( JABBER_DEBUG_GLOBAL ) << "Outgoing data connection is open.";
323
mBytesTransferred = mXMPPTransfer->offset ();
324
mLocalFile.seek ( mXMPPTransfer->offset () );
325
mBytesToTransfer = ( mXMPPTransfer->fileSize () > mXMPPTransfer->length () ) ? mXMPPTransfer->length () : mXMPPTransfer->fileSize ();
327
slotOutgoingBytesWritten ( 0 );
331
void JabberFileTransfer::slotOutgoingBytesWritten ( int nrWritten )
334
mBytesTransferred += nrWritten;
335
mBytesToTransfer -= nrWritten;
337
mKopeteTransfer->slotProcessed ( mBytesTransferred );
339
if ( mBytesToTransfer )
341
int nrToWrite = mXMPPTransfer->dataSizeNeeded ();
343
QByteArray readBuffer ( nrToWrite , '\0' );
345
mLocalFile.read ( readBuffer.data (), nrToWrite );
347
mXMPPTransfer->writeFileData ( readBuffer );
351
kDebug(JABBER_DEBUG_GLOBAL) << "Transfer to " << mXMPPTransfer->peer().full () << " done.";
353
mKopeteTransfer->slotComplete ();
360
#include "jabberfiletransfer.moc"