summaryrefslogtreecommitdiff
authorskyhusker <skyhusker>2005-02-03 21:47:50 (UTC)
committer skyhusker <skyhusker>2005-02-03 21:47:50 (UTC)
commit8aaae9e3eca7853e9c693d2401f721d75209acf7 (patch) (side-by-side diff)
tree6f700d154fac8510b322242496604d0ad7589377
parent875b3b63624308f4e50f82e17db27edeb9609d6c (diff)
downloadopie-8aaae9e3eca7853e9c693d2401f721d75209acf7.zip
opie-8aaae9e3eca7853e9c693d2401f721d75209acf7.tar.gz
opie-8aaae9e3eca7853e9c693d2401f721d75209acf7.tar.bz2
Added DCC receive support
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opieirc/dccprogress.cpp75
-rw-r--r--noncore/net/opieirc/dccprogress.h35
-rw-r--r--noncore/net/opieirc/dcctransfer.cpp41
-rw-r--r--noncore/net/opieirc/dcctransfer.h44
-rw-r--r--noncore/net/opieirc/dcctransferrecv.cpp53
-rw-r--r--noncore/net/opieirc/dcctransferrecv.h21
-rw-r--r--noncore/net/opieirc/dcctransfertab.cpp81
-rw-r--r--noncore/net/opieirc/dcctransfertab.h41
-rw-r--r--noncore/net/opieirc/ircmessageparser.cpp30
-rw-r--r--noncore/net/opieirc/ircservertab.cpp4
-rw-r--r--noncore/net/opieirc/ircservertab.h1
-rw-r--r--noncore/net/opieirc/ircsession.cpp5
-rw-r--r--noncore/net/opieirc/ircsession.h4
-rw-r--r--noncore/net/opieirc/mainwindow.cpp20
-rw-r--r--noncore/net/opieirc/mainwindow.h8
-rw-r--r--noncore/net/opieirc/opieirc.pro9
16 files changed, 459 insertions, 13 deletions
diff --git a/noncore/net/opieirc/dccprogress.cpp b/noncore/net/opieirc/dccprogress.cpp
new file mode 100644
index 0000000..28277f7
--- a/dev/null
+++ b/noncore/net/opieirc/dccprogress.cpp
@@ -0,0 +1,75 @@
+#include <qprogressbar.h>
+#include <qlabel.h>
+#include <qvbox.h>
+
+#include "dcctransfer.h"
+#include "dcctransferrecv.h"
+#include "dccprogress.h"
+
+DCCProgress::DCCProgress(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size, QWidget *parent, char *name, WFlags f)
+ : QWidget(parent, name, f), m_vbox(new QVBox(this)),
+ m_label(new QLabel(m_vbox)),
+ m_bar(new QProgressBar(m_vbox))
+{
+
+ if (DCCTransfer::Recv == type)
+ m_transfer = new DCCTransferRecv(ip4Addr, port, filename, size);
+
+
+ connect(m_transfer, SIGNAL(progress(int)), this, SLOT(slotSetProgress(int)));
+ connect(m_transfer, SIGNAL(finished(DCCTransfer *, DCCTransfer::EndCode)),
+ this, SLOT(slotFinished(DCCTransfer *, DCCTransfer::EndCode)));
+
+ m_label->setText(tr("Receiving file %1 from %2...").arg(m_transfer->filename()).arg(nickname));
+
+ m_label->show();
+ m_bar->show();
+ show();
+
+}
+
+bool DCCProgress::finished()
+{
+ return ( m_transfer == 0);
+}
+
+void DCCProgress::cancel()
+{
+ if (m_transfer)
+ m_transfer->cancel();
+}
+
+void DCCProgress::slotSetProgress(int progress)
+{
+ m_bar->setProgress(progress);
+}
+
+void DCCProgress::slotFinished(DCCTransfer *transfer, DCCTransfer::EndCode code)
+{
+ if(transfer != m_transfer)
+ // WTF!!
+ return;
+
+ QString msg;
+
+ switch(code) {
+ case DCCTransfer::Successfull:
+ msg = tr("Successfully received %1").arg(m_transfer->filename());
+ break;
+ case DCCTransfer::SelfAborted:
+ msg = tr("Aborted");
+ break;
+ case DCCTransfer::PeerAborted:
+ msg = tr("Peer Aborted");
+ break;
+ case DCCTransfer::Timeout:
+ msg = tr("Timeout");
+ break;
+ }
+
+ m_label->setText(msg);
+ delete m_transfer;
+ m_transfer = 0;
+}
+
diff --git a/noncore/net/opieirc/dccprogress.h b/noncore/net/opieirc/dccprogress.h
new file mode 100644
index 0000000..81b922e
--- a/dev/null
+++ b/noncore/net/opieirc/dccprogress.h
@@ -0,0 +1,35 @@
+#ifndef DCCPROGRESS_H
+#define DCCPROGRESS_H
+
+
+#include <qwidget.h>
+
+#include "dcctransfer.h"
+
+class QProgressBar;
+class QLabel;
+class QVBox;
+
+class DCCProgress: public QWidget {
+
+ Q_OBJECT
+public:
+ DCCProgress(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size,
+ QWidget *parent = 0, char *name = 0, WFlags f = 0);
+
+ bool finished();
+ void cancel();
+
+public slots:
+ void slotSetProgress(int progress);
+ void slotFinished(DCCTransfer *transfer, DCCTransfer::EndCode code);
+
+private:
+ QVBox *m_vbox;
+ QLabel *m_label;
+ QProgressBar *m_bar;
+ DCCTransfer *m_transfer;
+};
+
+#endif
diff --git a/noncore/net/opieirc/dcctransfer.cpp b/noncore/net/opieirc/dcctransfer.cpp
new file mode 100644
index 0000000..cfa9f74
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransfer.cpp
@@ -0,0 +1,41 @@
+#include <qsocket.h>
+#include <qfile.h>
+
+#include "dcctransfer.h"
+
+
+DCCTransfer::DCCTransfer(Q_UINT32 ip4Addr, Q_UINT16 port, const QString &filename, unsigned int size)
+ : m_socket(new QSocket), m_file(new QFile), m_bufSize(4096), m_buffer(new char[m_bufSize]),
+ m_ip4Addr(ip4Addr), m_port(port), m_totalSize(size), m_processedSize(0)
+{
+ m_file->setName(filename);
+}
+
+DCCTransfer::~DCCTransfer()
+{
+ if(m_socket)
+ delete m_socket;
+ if(m_file) {
+ m_file->close();
+ delete m_file;
+ }
+ if(m_buffer)
+ delete []m_buffer;
+}
+
+
+void DCCTransfer::cancel()
+{
+ if(m_socket)
+ m_socket->close();
+
+ emit(finished(DCCTransfer::SelfAborted));
+}
+
+QString DCCTransfer::filename()
+{
+ if(!m_file)
+ return QString::null;
+
+ return m_file->name().mid(m_file->name().findRev('/') + 1);
+}
diff --git a/noncore/net/opieirc/dcctransfer.h b/noncore/net/opieirc/dcctransfer.h
new file mode 100644
index 0000000..775ed24
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransfer.h
@@ -0,0 +1,44 @@
+#ifndef DCCTRANSFER_H
+#define DCCTRANSFER_H
+
+#include <qobject.h>
+
+class QSocket;
+class QFile;
+class QString;
+
+class DCCTransfer: public QObject {
+ Q_OBJECT
+public:
+ enum Type { Send, Recv };
+ enum EndCode { Successfull, SelfAborted, PeerAborted, Timeout };
+
+ DCCTransfer(Q_UINT32 ip4Addr, Q_UINT16 port, const QString &filename, unsigned int size);
+ virtual ~DCCTransfer();
+
+ void cancel();
+
+ QString filename();
+
+signals:
+ virtual void finished(DCCTransfer *transfer, EndCode code);
+ virtual void progress(int progress);
+
+protected slots:
+ virtual void slotProcess() = 0;
+ virtual void slotFinished() = 0;
+
+protected:
+ QSocket *m_socket;
+ QFile *m_file;
+ unsigned int m_bufSize;
+ char *m_buffer;
+ Q_UINT32 m_ip4Addr;
+ Q_UINT16 m_port;
+ unsigned int m_totalSize;
+ unsigned int m_processedSize;
+ bool m_cancel;
+ bool m_timeout;
+};
+
+#endif
diff --git a/noncore/net/opieirc/dcctransferrecv.cpp b/noncore/net/opieirc/dcctransferrecv.cpp
new file mode 100644
index 0000000..58e8d09
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransferrecv.cpp
@@ -0,0 +1,53 @@
+#include <netinet/in.h>
+
+#include <qfile.h>
+#include <qsocket.h>
+#include <qhostaddress.h>
+
+#include <opie2/odebug.h>
+
+
+#include "dcctransferrecv.h"
+
+
+DCCTransferRecv::DCCTransferRecv(Q_UINT32 ip4Addr, Q_UINT16 port, const QString &filename, unsigned int size)
+ : DCCTransfer(ip4Addr, port, filename, size)
+{
+ QHostAddress ip(ip4Addr);
+ m_socket->connectToHost(ip.toString(), m_port);
+ connect(m_socket, SIGNAL(readyRead()), this, SLOT(slotProcess()));
+ connect(m_socket, SIGNAL(connectionClosed()), this, SLOT(slotFinished()));
+
+ m_file->open(IO_WriteOnly);
+}
+
+
+void DCCTransferRecv::slotProcess()
+{
+ int availableBytes = m_socket->bytesAvailable();
+ int receivedBytes = 0;
+
+ while(receivedBytes < availableBytes) {
+ int bytes = m_socket->readBlock(m_buffer, m_bufSize);
+ receivedBytes += bytes;
+ m_file->writeBlock(m_buffer, bytes);
+ }
+
+ m_file->flush();
+ m_processedSize += availableBytes;
+ unsigned long value = htonl(m_processedSize);
+ m_socket->writeBlock((char*)&value, sizeof(unsigned long));
+
+ emit (progress((m_processedSize * 100) / m_totalSize));
+}
+
+void DCCTransferRecv::slotFinished()
+{
+ m_file->close();
+
+ if(m_processedSize == m_totalSize)
+ emit(finished(this, DCCTransfer::Successfull));
+ else
+ emit(finished(this, DCCTransfer::PeerAborted));
+}
+
diff --git a/noncore/net/opieirc/dcctransferrecv.h b/noncore/net/opieirc/dcctransferrecv.h
new file mode 100644
index 0000000..bfc55ef
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransferrecv.h
@@ -0,0 +1,21 @@
+#ifndef DCCTRANSFERRECV_H
+#define DCCTRANSFERRECV_H
+
+#include "dcctransfer.h"
+
+
+class DCCTransferRecv: public DCCTransfer {
+ Q_OBJECT
+public:
+ DCCTransferRecv(Q_UINT32 ip4Addr, Q_UINT16 port, const QString &filename, unsigned int size);
+
+signals:
+ void finished(DCCTransfer *transfer, DCCTransfer::EndCode code);
+
+public slots:
+ void slotProcess();
+ void slotFinished();
+};
+
+#endif
+
diff --git a/noncore/net/opieirc/dcctransfertab.cpp b/noncore/net/opieirc/dcctransfertab.cpp
new file mode 100644
index 0000000..ea0ff1f
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransfertab.cpp
@@ -0,0 +1,81 @@
+#include <qlist.h>
+#include <qlabel.h>
+#include <qstring.h>
+#include <qvbox.h>
+#include <qmessagebox.h>
+
+#include "dcctransfer.h"
+#include "dccprogress.h"
+#include "mainwindow.h"
+#include "dcctransfertab.h"
+
+#include <stdio.h>
+
+DCCTransferTab::DCCTransferTab(QWidget *parent, const char *name, WFlags f)
+ :IRCTab(parent, name, f), m_hbox(new QHBox(this)), m_parent(static_cast<MainWindow*>(parent))
+{
+ m_description->setText("");
+ m_layout->add(m_hbox);
+ m_hbox->show();
+}
+
+DCCTransferTab::~DCCTransferTab()
+{
+ if(m_hbox)
+ delete m_hbox;
+}
+
+QString DCCTransferTab::title()
+{
+ return "DCC";
+}
+
+void DCCTransferTab::remove()
+{
+ //Clean finished transfers
+ for(QListIterator <DCCProgress> it(m_progressList); it.current(); ++it) {
+ DCCProgress *current = it.current();
+ if (current->finished()) {
+ m_progressList.remove(current);
+ current->hide();
+ delete current;
+ }
+ }
+
+ if (m_progressList.count() > 0) {
+ int retval = QMessageBox::information( parentWidget() , tr("DCC Transfers in Progress"),
+ tr( "There are transfers in progress. <br>If you close this tab, they will be canceled."
+ "<br>Do you want to close it anyway?"),
+ tr("&Close"), tr("&Don't Close"));
+ if ( retval != 0 ) {
+ return;
+ }
+ //Cancel active transfers (user accepted)
+ for(QListIterator <DCCProgress> itr(m_progressList); itr.current(); ++itr) {
+ DCCProgress *current = itr.current();
+ m_progressList.remove(current);
+ current->hide();
+ current->cancel();
+ delete current;
+ }
+ }
+
+ //Remove
+ m_parent->killTab(this);
+}
+
+bool DCCTransferTab::confirm(QWidget *parent, const QString &nickname, const QString &filename, unsigned int size)
+{
+ int retval = QMessageBox::information(parent, tr("DCC Transfer from %1").arg(nickname),
+ tr( "%1 is trying to send you the file %2\n(%3 bytes)").arg(nickname).arg(filename).arg(size),
+ tr("&Accept"), tr("&Reject"));
+
+ return ( 0 == retval);
+
+}
+
+void DCCTransferTab::addTransfer(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size)
+{
+ m_progressList.append(new DCCProgress(type, ip4Addr, port, filename, nickname, size, this));
+}
diff --git a/noncore/net/opieirc/dcctransfertab.h b/noncore/net/opieirc/dcctransfertab.h
new file mode 100644
index 0000000..a21323d
--- a/dev/null
+++ b/noncore/net/opieirc/dcctransfertab.h
@@ -0,0 +1,41 @@
+#ifndef DCCTRANSFERTAB_H
+#define DCCTRANSFERTAB_H
+
+#include "dcctransfer.h"
+#include "irctab.h"
+
+template <class T> class QList;
+
+class DCCProgress;
+class IRCSession;
+class QString;
+class QHBox;
+class MainWindow;
+
+class DCCTransferTab: public IRCTab {
+ Q_OBJECT
+public:
+
+ DCCTransferTab(QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+ ~DCCTransferTab();
+ virtual QString DCCTransferTab::title();
+ virtual IRCSession* DCCTransferTab::session(){return 0;};
+ virtual void DCCTransferTab::appendText(QString){};
+ virtual void DCCTransferTab::remove();
+ virtual void DCCTransferTab::settingsChanged() {};
+ void addTransfer(DCCTransfer::Type type, Q_UINT32 ip4Addr,
+ Q_UINT16 port, const QString &filename,
+ const QString &nickname, unsigned int size);
+ static bool confirm(QWidget *parent = 0,
+ const QString &nickname = QString::null,
+ const QString &filename = QString::null,
+ unsigned int size = 0);
+private:
+ QHBox *m_hbox;
+ QList <DCCProgress> m_progressList;
+ MainWindow *m_parent;
+
+};
+
+#endif
+
diff --git a/noncore/net/opieirc/ircmessageparser.cpp b/noncore/net/opieirc/ircmessageparser.cpp
index ad9de2b..939cdae 100644
--- a/noncore/net/opieirc/ircmessageparser.cpp
+++ b/noncore/net/opieirc/ircmessageparser.cpp
@@ -2,8 +2,13 @@
#include <qdatetime.h>
+#include <opie2/ofiledialog.h>
+#include <opie2/ofileselector.h>
+#include <opie2/odebug.h>
+
#include "ircmessageparser.h"
#include "ircversion.h"
#include "ircchannelperson.h"
-//#include "transferreceiver.h"
+#include "dcctransfertab.h"
+#include "ircservertab.h"
/* Lookup table for literal commands */
@@ -462,10 +467,23 @@ void IRCMessageParser::parseCTCPAction(IRCMessage *message) {
void IRCMessageParser::parseCTCPDCC(IRCMessage *message) {
QStringList params = QStringList::split(' ', message->param(0).stripWhiteSpace());
- if( params.count() != 5) {
- emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Malformed DCC request from ") + IRCPerson(message->prefix()).nick()));
- return;
+
+ if(params[0] == "SEND") {
+ QString nickname = IRCPerson(message->prefix()).nick();
+ if( params.count() != 5) {
+ emit outputReady(IRCOutput(OUTPUT_ERROR, tr("Malformed DCC request from %1").arg(nickname)));
+ return;
+ }
+ bool accepted = DCCTransferTab::confirm(static_cast<QWidget*>(m_session->parent()), nickname, params[1], params[4].toUInt());
+ if(!accepted)
+ return;
+ QString filename = Opie::Ui::OFileDialog::getSaveFileName(Opie::Ui::OFileSelector::EXTENDED_ALL,
+ QString::null, params[1], MimeTypes(), 0, tr("Save As"));
+ if(filename.isEmpty())
+ return;
+
+ odebug << "Receiving file " << filename << " from " << nickname << oendl;
+ static_cast<IRCServerTab*>(m_session->parent())->mainwindow()->addDCC(DCCTransfer::Recv, params[2].toUInt(), params[3].toUInt(),
+ filename, nickname, params[4].toUInt());
}
-
- //TransferReceiver *foo = new TransferReceiver(params[2].toUInt(), params[3].toUInt(), params[1], params[4].toUInt());
}
diff --git a/noncore/net/opieirc/ircservertab.cpp b/noncore/net/opieirc/ircservertab.cpp
index 62a06e8..d3c0448 100644
--- a/noncore/net/opieirc/ircservertab.cpp
+++ b/noncore/net/opieirc/ircservertab.cpp
@@ -413,3 +413,7 @@ void IRCServerTab::slotUpdateChannels() {
}
}
+
+MainWindow *IRCServerTab::mainwindow() {
+ return m_mainWindow;
+}
diff --git a/noncore/net/opieirc/ircservertab.h b/noncore/net/opieirc/ircservertab.h
index 42f6f57..fe48a3b 100644
--- a/noncore/net/opieirc/ircservertab.h
+++ b/noncore/net/opieirc/ircservertab.h
@@ -42,4 +42,5 @@ public:
IRCSession *session();
IRCServer *server();
+ MainWindow *mainwindow();
/* Start the server session */
diff --git a/noncore/net/opieirc/ircsession.cpp b/noncore/net/opieirc/ircsession.cpp
index fd8ba72..c8d7869 100644
--- a/noncore/net/opieirc/ircsession.cpp
+++ b/noncore/net/opieirc/ircsession.cpp
@@ -5,9 +5,10 @@
#include "ircversion.h"
-IRCSession::IRCSession(QWidget *parent, IRCServer *server) {
+IRCSession::IRCSession(QObject *parent, IRCServer *server)
+ : QObject(parent)
+{
m_server = server;
m_connection = new IRCConnection(m_server);
m_parser = new IRCMessageParser(this);
- m_parent = parent;
connect(m_connection, SIGNAL(messageArrived(IRCMessage*)), this, SLOT(handleMessage(IRCMessage*)));
connect(m_parser, SIGNAL(outputReady(IRCOutput)), this, SIGNAL(outputReady(IRCOutput)));
diff --git a/noncore/net/opieirc/ircsession.h b/noncore/net/opieirc/ircsession.h
index 7c91893..23a2540 100644
--- a/noncore/net/opieirc/ircsession.h
+++ b/noncore/net/opieirc/ircsession.h
@@ -31,4 +31,5 @@
class IRCMessageParser;
+class IRCServerTab;
/* The IRCSession stores all information relating to the connection
@@ -40,5 +41,5 @@ friend class IRCMessageParser;
Q_OBJECT
public:
- IRCSession(QWidget *parent, IRCServer *server);
+ IRCSession(QObject *parent, IRCServer *server);
~IRCSession();
@@ -91,5 +92,4 @@ protected:
QString m_validUsermodes;
QString m_validChannelmodes;
- QWidget *m_parent;
};
diff --git a/noncore/net/opieirc/mainwindow.cpp b/noncore/net/opieirc/mainwindow.cpp
index 1811a0c..3d60107 100644
--- a/noncore/net/opieirc/mainwindow.cpp
+++ b/noncore/net/opieirc/mainwindow.cpp
@@ -8,7 +8,11 @@
#include "mainwindow.h"
#include "ircservertab.h"
+#include "dcctransfertab.h"
#include "ircserverlist.h"
#include "ircsettings.h"
+#include <stdio.h>
+
+
QString MainWindow::appCaption() {
return QObject::tr("Opie IRC");
@@ -34,4 +38,5 @@ MainWindow::MainWindow(QWidget *parent, const char *name, WFlags) : QMainWindow(
connect(a, SIGNAL(activated()), this, SLOT(settings()));
a->addTo(irc);
+ m_dccTab = 0;
loadSettings();
}
@@ -78,4 +83,7 @@ void MainWindow::changeEvent(IRCTab *tab) {
void MainWindow::killTab(IRCTab *tab, bool imediate) {
+ if (tab == m_dccTab)
+ m_dccTab = 0;
+
m_toDelete.append( tab );
@@ -138,2 +146,14 @@ void MainWindow::slotPing( const QString& /*channel*/ ) {
}
+void MainWindow::addDCC(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size) {
+
+ if (!m_dccTab) {
+ m_dccTab = new DCCTransferTab(this);
+ addTab(m_dccTab);
+ m_dccTab->show();
+ }
+
+ m_dccTab->addTransfer(type, ip4Addr, port, filename, nickname, size);
+}
+
diff --git a/noncore/net/opieirc/mainwindow.h b/noncore/net/opieirc/mainwindow.h
index abf205d..873a685 100644
--- a/noncore/net/opieirc/mainwindow.h
+++ b/noncore/net/opieirc/mainwindow.h
@@ -25,8 +25,11 @@
#include <qaction.h>
#include <qlist.h>
-#include "mainwindow.h"
+
+#include "dcctransfer.h"
#include "ircmisc.h"
#include "irctab.h"
+class DCCTransferTab;
+
class MainWindow : public QMainWindow {
Q_OBJECT
@@ -38,4 +41,6 @@ public:
static QString appName() { return QString::fromLatin1("opieirc"); }
static QString appCaption();
+ void addDCC(DCCTransfer::Type type, Q_UINT32 ip4Addr, Q_UINT16 port,
+ const QString &filename, const QString &nickname, unsigned int size);
signals:
void updateScroll();
@@ -57,4 +62,5 @@ protected:
QList<IRCTab> m_tabs;
QList<IRCTab> m_toDelete;
+ DCCTransferTab *m_dccTab;
};
diff --git a/noncore/net/opieirc/opieirc.pro b/noncore/net/opieirc/opieirc.pro
index 1ef9be2..5e91450 100644
--- a/noncore/net/opieirc/opieirc.pro
+++ b/noncore/net/opieirc/opieirc.pro
@@ -8,5 +8,7 @@ HEADERS = ircchannel.h ircconnection.h \
ircserverlist.h ircservereditor.h \
ircquerytab.h ircsettings.h ircmisc.h \
- ircchannelperson.h
+ ircchannelperson.h dcctransfertab.h \
+ dccprogress.h dcctransfer.h \
+ dcctransferrecv.h
SOURCES = ircchannel.cpp ircconnection.cpp \
ircmessage.cpp \
@@ -18,5 +20,8 @@ SOURCES = ircchannel.cpp ircconnection.cpp \
ircserverlist.cpp ircservereditor.cpp \
ircquerytab.cpp ircsettings.cpp ircmisc.cpp \
- ircchannelperson.cpp
+ ircchannelperson.cpp dcctransfertab.cpp \
+ dccprogress.cpp dcctransfer.cpp \
+ dcctransferrecv.cpp
+
INCLUDEPATH += $(OPIEDIR)/include
DEPENDPATH += $(OPIEDIR)/include