From 30a098530260176ac20d75ba6cb7abfb3d998c13 Mon Sep 17 00:00:00 2001 From: zecke Date: Sun, 16 Feb 2003 15:49:02 +0000 Subject: disable snd in IrDaApplet it hangs on my machine.. Remove the hacky OBEX Implementation Add a more cleaned up more appealing (not yet working) version which will even be able to do OBEX over Bluetooth in the future -It handles receive better let's you choose what to do with custom files and created a DocLnk -Send lets you beam to multiple devices this needs the IrDa Applet to be present --- (limited to 'core/obex') diff --git a/core/obex/config.in b/core/obex/config.in new file mode 100644 index 0000000..4d1f43d --- a/dev/null +++ b/core/obex/config.in @@ -0,0 +1,4 @@ + config OBEX + boolean "Obex library (library needed for beaming in Opie)" + default "y" + depends ( LIBQPE || LIBQPE-X11 ) && LIBOPIE diff --git a/core/obex/obex.cc b/core/obex/obex.cc new file mode 100644 index 0000000..83d1faf --- a/dev/null +++ b/core/obex/obex.cc @@ -0,0 +1,195 @@ + +#include +#include +#include +#include +#include "obex.h" + +using namespace OpieObex; + +Obex::Obex( QObject *parent, const char* name ) + : QObject(parent, name ) +{ + m_rec = 0; + m_send=0; + m_count = 0; + m_receive = false; + connect( this, SIGNAL(error(int) ), // for recovering to receive + SLOT(slotError() ) ); + connect( this, SIGNAL(sent() ), + SLOT(slotError() ) ); +}; +Obex::~Obex() { + delete m_rec; + delete m_send; +} +void Obex::receive() { + m_receive = true; + m_outp = QString::null; + qWarning("Receive" ); + m_rec = new OProcess(); + *m_rec << "irobex_palm3"; + // connect to the necessary slots + connect(m_rec, SIGNAL(processExited(OProcess*) ), + this, SLOT(slotExited(OProcess*) ) ); + + connect(m_rec, SIGNAL(receivedStdout(OProcess*, char*, int ) ), + this, SLOT(slotStdOut(OProcess*, char*, int) ) ); + + if(!m_rec->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) { + qWarning("could not start :("); + emit done( false ); + delete m_rec; + m_rec = 0; + } +// emit currentTry(m_count ); + +} +void Obex::send( const QString& fileName) { // if currently receiving stop it send receive + m_count = 0; + m_file = fileName; + qWarning("send"); + if (m_rec != 0 ) { + qWarning("running"); + if (m_rec->isRunning() ) { + emit error(-1 ); + qWarning("is running"); + delete m_rec; + m_rec = 0; + + }else{ + qWarning("is not running"); + emit error( -1 ); // we did not delete yet but it's not running slotExited is pending + return; + } + } + sendNow(); +} +void Obex::sendNow(){ + qWarning("sendNow"); + if ( m_count >= 25 ) { // could not send + emit error(-1 ); + emit sent(false); + return; + } + // OProcess inititialisation + m_send = new OProcess(); + *m_send << "irobex_palm3"; + *m_send << m_file; + + // connect to slots Exited and and StdOut + connect(m_send, SIGNAL(processExited(OProcess*) ), + this, SLOT(slotExited(OProcess*)) ); + connect(m_send, SIGNAL(receivedStdout(OProcess*, char*, int )), + this, SLOT(slotStdOut(OProcess*, char*, int) ) ); + + // now start it + if (!m_send->start(/*OProcess::NotifyOnExit, OProcess::AllOutput*/ ) ) { + qWarning("could not send" ); + m_count = 25; + emit error(-1 ); + delete m_send; + m_send=0; + } + // end + m_count++; + emit currentTry( m_count ); +} + +void Obex::slotExited(OProcess* proc ){ + if (proc == m_rec ) { // receive process + received(); + }else if ( proc == m_send ) { + sendEnd(); + } +} +void Obex::slotStdOut(OProcess* proc, char* buf, int len){ + if ( proc == m_rec ) { // only receive + QCString cstring( buf, len ); + m_outp.append( cstring.data() ); + } +} + +void Obex::received() { + if (m_rec->normalExit() ) { + if ( m_rec->exitStatus() == 0 ) { // we got one + QString filename = parseOut(); + qWarning("ACHTUNG"); + emit receivedFile( filename ); + } + }else{ + emit done(false); + }; + delete m_rec; + m_rec = 0; + receive(); +} + +void Obex::sendEnd() { + if (m_send->normalExit() ) { + if ( m_send->exitStatus() == 0 ) { + delete m_send; + m_send=0; + qWarning("done" ); + emit sent(true); + }else if (m_send->exitStatus() == 255 ) { // it failed maybe the other side wasn't ready + // let's try it again + delete m_send; + m_send = 0; + qWarning("try sending again" ); + sendNow(); + } + }else { + emit error( -1 ); + delete m_send; + m_send = 0; + } +} +QString Obex::parseOut( ){ + QString path; + QStringList list = QStringList::split("\n", m_outp); + QStringList::Iterator it; + for (it = list.begin(); it != list.end(); ++it ) { + if ( (*it).startsWith("Wrote" ) ) { + int pos = (*it).findRev('(' ); + if ( pos > 0 ) { + qWarning( "%d %s", pos, (*it).mid(6 ).latin1() ) ; + qWarning("%d %d", (*it).length(), (*it).length()-pos ); + + path = (*it).remove( pos, (*it).length() - pos ); + qWarning("%s", path.latin1() ); + path = path.mid(6 ); + path = path.stripWhiteSpace(); + qWarning("path %s", path.latin1() ); + } + } + } + return path; +} +/** + * when sent is done slotError is called we will start receive again + */ +void Obex::slotError() { + qWarning("slotError"); + if ( m_receive ) + receive(); +}; +void Obex::setReceiveEnabled( bool receive ) { + if ( !receive ) { // + m_receive = false; + shutDownReceive(); + } +} + +void Obex::shutDownReceive() { + if (m_rec != 0 ) { + qWarning("running"); + if (m_rec->isRunning() ) { + emit error(-1 ); + qWarning("is running"); + delete m_rec; + m_rec = 0; + } + } + +} diff --git a/core/obex/obex.h b/core/obex/obex.h new file mode 100644 index 0000000..60f5d28 --- a/dev/null +++ b/core/obex/obex.h @@ -0,0 +1,84 @@ + + +#ifndef OpieObex_H +#define OpieObex_H + +#include + +class OProcess; +class QCopChannel; +namespace OpieObex { + class Obex : public QObject { + Q_OBJECT + public: + /** + * Obex c'tor look + */ + Obex( QObject *parent, const char* name); + /** + * d'tor + */ + ~Obex(); + + /** + * Starting listening to irda after enabled by the applet + * a signal gets emitted when recieved a file + */ + void receive(); + void send( const QString& ); + void setReceiveEnabled( bool = false ); + signals: + + /** + * a signal + * @param path The path to the recieved file + */ + void receivedFile( const QString& path); + /** + * error signal if the program couldn't be started or the + * the connection timed out + */ + void error( int ); + /** + * The current try to receive data + */ + void currentTry(unsigned int); + /** + * signal sent The file got beamed to the remote location + */ + void sent(bool); + void done(bool); + + private: + uint m_count; + QString m_file; + QString m_outp; + OProcess *m_send; + OProcess *m_rec; + bool m_receive : 1; + void shutDownReceive(); + +private slots: + + /** + * send over palm obex + */ + + //void send(const QString&); + + // the process exited + void slotExited(OProcess* proc) ; + void slotStdOut(OProcess*, char*, int); + void slotError(); + + private: + void sendNow(); + QString parseOut(); + void received(); + void sendEnd(); + + }; +}; + + +#endif diff --git a/core/obex/obexhandler.cpp b/core/obex/obexhandler.cpp new file mode 100644 index 0000000..f71a233 --- a/dev/null +++ b/core/obex/obexhandler.cpp @@ -0,0 +1,65 @@ +#include + +#include + +#include "obexsend.h" +#include "receiver.h" +#include "obexhandler.h" + +using namespace OpieObex; + +ObexHandler::ObexHandler() { + m_wasRec = false; + m_sender = 0l; + m_receiver = 0l; + QCopChannel* chan = new QCopChannel("QPE/Obex"); + connect(chan, SIGNAL(received(const QCString&, const QByteArray& ) ), + this, SLOT(irdaMessage(const QCString&, const QByteArray& ) ) ); +} +ObexHandler::~ObexHandler() { + delete m_sender; + delete m_receiver; +} +void ObexHandler::doSend(const QString& str, const QString& desc) { + delete m_sender; + m_sender = new SendWidget; + m_sender->raise(); + m_sender->showMaximized(); + connect(m_sender, SIGNAL(done() ), + this, SLOT(slotSent() ) ); + m_sender->send( str, desc ); +} +void ObexHandler::doReceive(bool b) { + if (m_receiver && b ) return; // we should enable receiver and it is on + else if (!m_receiver && !b ) return; // we should disbale receiver and it is off + else if (m_receiver && !b ) { + delete m_receiver; + m_receiver=0; + }else if (!m_receiver && b ) { + m_receiver= new Receiver; + } +} +void ObexHandler::slotSent() { + QString file = m_sender->file(); + delete m_sender; + m_sender = 0; + QCopEnvelope e ("QPE/Obex", "done(QString)" ); + e << file; + doReceive(m_wasRec ); + m_wasRec = false; +} +void ObexHandler::irdaMessage( const QCString& msg, const QByteArray& data) { + QDataStream stream( data, IO_ReadOnly ); + if ( msg == "send(QString,QString,QString)" ) { + QString name, desc; + stream >> name; + stream >> desc; + m_wasRec = (m_receiver != 0 ); + doReceive( false ); + doSend(name, desc); + }else if (msg == "receive(int)") { + int rec; + stream >> rec; + doReceive(rec); + } +} diff --git a/core/obex/obexhandler.h b/core/obex/obexhandler.h new file mode 100644 index 0000000..230c4f0 --- a/dev/null +++ b/core/obex/obexhandler.h @@ -0,0 +1,39 @@ +#ifndef OPIE_OBEX_HANDLER_H +#define OPIE_OBEX_HANDLER_H + +#include +#include + +namespace OpieObex { + /* + * The handler is responsible for handling receiving + * and sending + * It will connect to the IrDa QCOP channel and then + * wait for activation... + */ + class SendWidget; + class Receiver; + class ObexHandler : public QObject { + Q_OBJECT + public: + ObexHandler(); + ~ObexHandler(); + + private slots: + void doSend(const QString&,const QString& ); + void doReceive(bool b); + void slotSent(); + + private slots: // QCOP message + void irdaMessage( const QCString&, const QByteArray& ); + + private: + SendWidget* m_sender; + Receiver* m_receiver; + bool m_wasRec : 1; + + }; +} + + +#endif diff --git a/core/obex/obeximpl.cpp b/core/obex/obeximpl.cpp new file mode 100644 index 0000000..12a078f --- a/dev/null +++ b/core/obex/obeximpl.cpp @@ -0,0 +1,28 @@ +#include "obexhandler.h" +#include "obeximpl.h" + +using namespace OpieObex; + +ObexImpl::ObexImpl() { + m_handler = new ObexHandler; +} +ObexImpl::~ObexImpl() { + delete m_handler; +} +QRESULT ObexImpl::queryInterface( const QUuid& uuid, QUnknownInterface **iface ) { + *iface = 0; + if ( uuid == IID_QUnknown ) { + *iface = this; + }else if ( uuid == IID_ObexInterface ) + *iface = this; + + if (*iface) + (*iface)->addRef(); + + return QS_OK; +} + + +Q_EXPORT_INTERFACE() { + Q_CREATE_INSTANCE( ObexImpl ) +} diff --git a/core/obex/obeximpl.h b/core/obex/obeximpl.h new file mode 100644 index 0000000..604eb8f --- a/dev/null +++ b/core/obex/obeximpl.h @@ -0,0 +1,22 @@ +#ifndef OPIE_OBEX_IMPL_QUERY_H +#define OPIE_OBEX_IMPL_QUERY_H + +#include + +namespace OpieObex { + class ObexHandler; + class ObexImpl : public ObexInterface { + public: + ObexImpl(); + virtual ~ObexImpl(); + QRESULT queryInterface( const QUuid&, QUnknownInterface** ); + Q_REFCOUNT + + private: + ulong ref; + ObexHandler *m_handler; + + }; +}; + +#endif diff --git a/core/obex/obexsend.cpp b/core/obex/obexsend.cpp new file mode 100644 index 0000000..a2e4c16 --- a/dev/null +++ b/core/obex/obexsend.cpp @@ -0,0 +1,251 @@ +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "obex.h" +#include "obexsend.h" + +using namespace OpieObex; + + +SendWidget::SendWidget( QWidget* parent, const char* name ) + : QWidget( parent, name ) { + initUI(); +} +SendWidget::~SendWidget() { +} +void SendWidget::initUI() { + m_obex = new Obex(this, "obex"); + connect(m_obex, SIGNAL(error(int) ), + this, SLOT(slotIrError(int) ) ); + connect(m_obex, SIGNAL(sent(bool) ), + this, SLOT(slotIrSent(bool) ) ); + connect(m_obex, SIGNAL(currentTry(unsigned int ) ), + this, SLOT(slotIrTry(unsigned int ) ) ); + + QCopChannel* chan = new QCopChannel("QPE/IrDaAppletBack", this ); + connect(chan, SIGNAL(received(const QCString&, const QByteArray& ) ), + this, SLOT(dispatchBt(const QCString&, const QByteArray& ) ) ); + + chan = new QCopChannel("QPE/BluetoothBack", this ); + connect(chan, SIGNAL(received(const QCString&, const QByteArray& ) ), + this, SLOT(dispatchIrda(const QCString&, const QByteArray& ) ) ); + + QVBoxLayout* lay = new QVBoxLayout(this); + + QHBox* nameBox = new QHBox(this); + QLabel* name = new QLabel(nameBox); + name->setText( tr("

Sending:

") ); + name->setAlignment( AlignLeft | AlignTop ); + m_lblFile = new QLabel(nameBox); + lay->addWidget(nameBox, 0); + + QFrame* frame = new QFrame(this); + frame->setFrameShape( QFrame::HLine ); + frame->setFrameShadow( QFrame::Sunken ); + lay->addWidget(frame, 10); + + QLabel* devices = new QLabel(this); + devices->setText("Devices:"); + devices->setAlignment( AlignLeft | AlignTop ); + lay->addWidget( devices,10 ); + + m_devBox = new DeviceBox(this); + lay->addWidget( m_devBox, 50 ); + connect(m_devBox, SIGNAL(selectedDevice(const QString&, int ) ), + this, SLOT(slotSelectedDevice(const QString&, int) ) ); + + QPushButton *but = new QPushButton(this); + but->setText(tr("Done") ); + connect(but, SIGNAL(clicked() ), + this, SLOT(slotDone() ) ); + + lay->addWidget( but ); + m_lay = lay; + + // QT does not like if you add items to an layout which already exits.... + // and was layouted invalidate() does not help too + // so we use RichText.... +} + +/* + * in send we'll first set everything up + * and then wait for a list of devices. + */ +void SendWidget::send( const QString& file, const QString& desc ) { + m_file = file; + m_irDa.clear(); + m_start = 0; + m_lblFile->setText(desc.isEmpty() ? file : desc ); + + if ( !QCopChannel::isRegistered("QPE/IrDaApplet") ) { + m_devBox->addDevice( tr("IrDa is not enabled!"), DeviceBox::Error ); + m_start++; + }else + m_devBox->addDevice( tr("Searching for IrDa Devices."), DeviceBox::Search ); + + if ( !QCopChannel::isRegistered("QPE/Bluetooth") ) { + m_devBox->addDevice( tr("Bluetooth is not available"), DeviceBox::Error ); + m_start++; + }else + m_devBox->addDevice( tr("Searching for bluetooth Devices."), DeviceBox::Search ); + + if (m_start != 2 ) { + QCopEnvelope e0("QPE/IrDaApplet", "enableIrda()"); + QCopEnvelope e1("QPE/Bluetooth", "enableBluetooth()"); + QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); + QCopEnvelope e3("QPE/Bluetooth", "listDevices()"); + } + QTimer::singleShot(5000, this, SLOT(testIt() ) ); +} +void SendWidget::slotIrDaDevices( const QStringList& list) { + m_irDa = list; + m_start = 0; + for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) + m_devBox->addDevice( (*it), DeviceBox::IrDa, tr("Scheduling for beam.") ); + m_devBox->removeDevice( tr("Search for IrDa Devices.") ); + + slotStartIrda(); +} +void SendWidget::slotBTDevices( const QMap& str ) { + m_bt = str; + for(QMap::ConstIterator it = str.begin(); it != str.end(); ++it ) { + m_devBox->addDevice( it.key(), DeviceBox::BT, tr("Click to beam") ); + } + m_devBox->removeDevice( tr("Searching for bluetooth Devices.") ); +} +void SendWidget::slotSelectedDevice( const QString& name, int dev ) { + qWarning("Start beam? %s %d", name.latin1(), dev ); + if ( name == tr("Search again for IrDa.") ) { + for (QStringList::Iterator it= m_irDa.begin(); it != m_irDa.end(); ++it ) + m_devBox->removeDevice( (*it) ); + QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); + } +} +void SendWidget::dispatchIrda( const QCString& str, const QByteArray& ar ) { + qWarning("dispatch irda %s", str.data() ); + if ( str == "listDevices(QStringList)" ) { + QDataStream stream( ar, IO_ReadOnly ); + QStringList list; + stream >> list; + slotIrDaDevices( list ); + } +} +void SendWidget::dispatchBt( const QCString& str, const QByteArray& ar ) { + +} +void SendWidget::slotIrError( int ) { + +} +void SendWidget::slotIrSent( bool b) { + QString text = b ? tr("Sent") : tr("Failure"); + m_devBox->setStatus( m_irDa[m_start], text ); + m_start++; + slotStartIrda(); +} +void SendWidget::slotIrTry(unsigned int trI) { + m_devBox->setStatus( m_irDa[m_start], tr("Try %1").arg( QString::number( trI ) ) ); +} +void SendWidget::slotStartIrda() { + if (m_start >= m_irDa.count() ) { + m_devBox->addDevice(tr("Search again for IrDa."), DeviceBox::Search ); + return; + } + m_devBox->setStatus( m_irDa[m_start], tr("Start sending") ); + m_obex->send( m_file ); +} +void SendWidget::slotDone() { + QCopEnvelope e0("QPE/IrDaApplet", "disableIrda()"); + QCopEnvelope e1("QPE/Bluetooth", "disableBluetooth()"); + emit done(); +} +QString SendWidget::file()const { + return m_file; +} +DeviceBox::DeviceBox( QWidget* parent ) + : QTextBrowser( parent ) { + +} +DeviceBox::~DeviceBox() { + +} +void DeviceBox::addDevice( const QString& name, int dev, const QString& status ) { + QString tex; + DeviceItem item( name, status, dev ); + m_dev.insert( name, item ); + tex = item.toString(); + m_devices.prepend(tex); + setText( text()+ "
"+tex ); +} +void DeviceBox::removeDevice( const QString& name ) { + if (!m_dev.contains(name) ) return; + m_devices.remove( m_dev[name].toString() ); + + m_dev.remove(name); + setText( m_devices.join("
") ); + +} +void DeviceBox::setStatus( const QString& name, const QString& status ) { + if ( !m_dev.contains(name) ) return; + DeviceItem dev = m_dev[name]; + QString ole = dev.toString(); + dev.setStatus( status ); + int index = m_devices.findIndex( ole ); + m_devices[index] = dev.toString(); + setText( m_devices.join("
") ); +} +void DeviceBox::setSource( const QString& str ) { + qWarning("SetSource:%s", str.latin1() ); + emit selectedDevice( str, m_dev[str].device() ); +} + + +DeviceItem::DeviceItem( const QString& name, + const QString& status, int dev) +{ + m_name = name; + m_status = status; + m_dev = dev; +} +QString DeviceItem::name()const { + return m_name; +} +QString DeviceItem::status()const { + return m_status; +} +int DeviceItem::device()const { + return m_dev; +} +QString DeviceItem::pixmap()const{ + QString str; + switch(m_dev) { + case DeviceBox::IrDa: + str ="obex/irda"; + break; + case DeviceBox::BT: + str ="obex/bt"; + break; + case DeviceBox::Search: + str = "obex/search"; + break; + case DeviceBox::Error: + str = "editdelete"; + break; + }; + return str; +} +DeviceItem::~DeviceItem() { +} +void DeviceItem::setStatus(const QString& status ) { + m_status = status; +} +QString DeviceItem::toString()const { + return "

"+m_name+" "+m_status+"

" ; +} diff --git a/core/obex/obexsend.h b/core/obex/obexsend.h new file mode 100644 index 0000000..fd819bc --- a/dev/null +++ b/core/obex/obexsend.h @@ -0,0 +1,99 @@ +#ifndef OPIE_OBEX_SEND_WIDGET_H +#define OPIE_OBEX_SEND_WIDGET_H + +#include +#include +#include +#include +#include +#include + +class QLabel; +class QVBoxLayout; +/** + * This is the new sending widget for Obex + * It will attemp to smart and be able to send + * it to multiple devices. + * It'll support BT + IrDa + */ +namespace OpieObex { + class DeviceBox; + class Obex; + class SendWidget : public QWidget{ + Q_OBJECT + public: + SendWidget( QWidget* parent = 0, const char* name = 0); + ~SendWidget(); + + QString file()const; + + public slots: + void send( const QString& file, const QString& desc ); + + signals: + void done(); + + private slots: // QCOP slots + /* IrDa Names*/ + void slotIrDaDevices( const QStringList& ); + /* Bt Names + BD-Addr */ + void slotBTDevices( const QMap& ); + void slotSelectedDevice( const QString& name, int dev ); + void dispatchIrda( const QCString& str, const QByteArray& ar ); + void dispatchBt( const QCString& str, const QByteArray& ar ); + + void slotIrError( int ); + void slotIrSent(bool); + void slotIrTry(unsigned int ); + void slotStartIrda(); + void slotDone(); + private: + void initUI(); + QLabel* m_lblFile; + DeviceBox* m_devBox; + QVBoxLayout* m_lay; + int m_start; + QStringList m_irDa; + QMap m_bt; + QString m_file; + Obex* m_obex; + }; + class DeviceItem { + public: + DeviceItem( const QString& name = QString::null, + const QString& status = QString::null, int dev = 3); + ~DeviceItem(); + void setStatus( const QString& text ); + + QString name()const; + QString status()const; + QString pixmap()const; + int device()const; + QString toString()const; + private: + QString m_name; + QString m_status; + int m_dev; + }; + class DeviceBox : public QTextBrowser { + Q_OBJECT + public: + enum Device { IrDa, BT, Search, Error }; + DeviceBox( QWidget* parent ); + ~DeviceBox(); + + void setSource( const QString& str ); + void addDevice( const QString& name, int dev, + const QString& status = QString::null ); + void removeDevice( const QString& name ); + void setStatus( const QString& name, const QString& ); + signals: + void selectedDevice( const QString& name, int dev ); + private: + QMap m_dev; + QStringList m_devices; + + }; +} + +#endif diff --git a/core/obex/receiver.cpp b/core/obex/receiver.cpp new file mode 100644 index 0000000..50ee6cb --- a/dev/null +++ b/core/obex/receiver.cpp @@ -0,0 +1,166 @@ +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "obex.h" +#include "receiver.h" + +using namespace OpieObex; + +Receiver::Receiver() { + m_obex = new Obex(this, "Receiver"); + connect(m_obex, SIGNAL(receivedFile(const QString& ) ), + this, SLOT(slotReceived(const QString& ) ) ); + m_obex->receive(); +} +Receiver::~Receiver() { + m_obex->setReceiveEnabled( false ); + delete m_obex; +} +void Receiver::slotReceived( const QString& file ) { + int check = checkFile(file); + if ( check == AddressBook ) + handleAddr( file ); + else if ( check == Datebook ) + handleDateTodo( file ); + else + handleOther( file ); +} +void Receiver::handleAddr( const QString& str ) { + QCopEnvelope e("QPE/Application/addressbook", "setDocument(QString)" ); + e << str; +} +/* we can not say for sure if it's a VEevent ot VTodo */ +void Receiver::handleDateTodo( const QString& str ) { + QCopEnvelope e0("QPE/Application/todolist", "setDocument(QString)"); + e0 << str; + QCopEnvelope e1("QPE/Application/datebook", "setDocument(QString)" ); + e1 << str; +} +/* + * Handle other asks if it should accept the + * beamed object and creates a DocLnk + */ +void Receiver::handleOther( const QString& other ) { + OtherHandler* hand = new OtherHandler(); + hand->handle( other ); +} +int Receiver::checkFile( const QString& file ) { + int ret; + if (file.right(4) == ".vcs" ) { + ret = Datebook; + }else if ( file.right(4) == ".vcf") { + ret = AddressBook; + }else + ret = Other; + + return ret; +} + +OtherHandler::OtherHandler() + : QVBox() +{ + QHBox* box = new QHBox(this); + QLabel* lbl = new QLabel(box); + lbl->setText(tr("Received:")); + m_na = new QLabel(box); + + QFrame* frame = new QFrame(this); + frame->setFrameShape( QFrame::HLine ); + frame->setFrameShadow( QFrame::Sunken ); + + m_view = new QTextView(this); + + box = new QHBox(this); + QPushButton *but = new QPushButton(box); + but->setText(tr("Accept") ); + connect(but, SIGNAL(clicked() ), + this, SLOT(accept()) ); + + but = new QPushButton(box); + but->setText(tr("Deny") ); + connect(but, SIGNAL(clicked() ), + this, SLOT(deny() ) ); + + raise(); + showMaximized(); +} +OtherHandler::~OtherHandler() { + +} +void OtherHandler::handle( const QString& file ) { + m_file = file; + m_na->setText(file); + DocLnk lnk(file); + + QString str = tr("

You received a file of type %1 ( )What do you want to do?").arg(lnk.type() ).arg(lnk.icon() ); + m_view->setText( str ); +} + +/* + * hehe evil evil mmap ahead :) + * we quickly copy the file and then we'll create a DocLnk for it + */ +void OtherHandler::accept() { + QString na = targetName( m_file ); + copy(m_file, na ); + DocLnk lnk(na); + lnk.writeLink(); + QFile::remove(m_file); + delete this; +} +void OtherHandler::deny() { + QFile::remove( m_file ); + delete this; +} +QString OtherHandler::targetName( const QString& file ) { + QFileInfo info( file ); + QString newFile = QPEApplication::documentDir()+ "/"+ info.baseName(); + QString newFileBase = newFile; + + int trie = 0; + while (QFile::exists(newFile + info.extension() ) ) { + newFile = newFileBase + "_"+QString::number(trie) ; + trie++; + } + newFile += info.extension(); + + return newFile; +} + +/* fast cpy */ +void OtherHandler::copy(const QString& src, const QString& file) { + int src_fd = ::open( QFile::encodeName( src ), O_RDONLY ); + int to_fd = ::open( QFile::encodeName( file), O_RDWR| O_CREAT| O_TRUNC, + S_IRUSR, S_IWUSR, S_IRGRP, S_IRGRP ); + + struct stat stater; + ::fstat(src_fd, &stater ); + ::lseek(to_fd, stater.st_size-1, SEEK_SET ); + + void *src_addr, *dest_addr; + src_addr = ::mmap(0, stater.st_size, PROT_READ, + MAP_FILE | MAP_SHARED, src_fd, 0 ); + dest_addr= ::mmap(0, stater.st_size, PROT_READ | PROT_WRITE, + MAP_FILE | MAP_PRIVATE, to_fd, 0 ); + + ::memcpy(src_addr , dest_addr, stater.st_size ); + ::munmap(src_addr , stater.st_size ); + ::munmap(dest_addr, stater.st_size ); + + // done +} diff --git a/core/obex/receiver.h b/core/obex/receiver.h new file mode 100644 index 0000000..5b20146 --- a/dev/null +++ b/core/obex/receiver.h @@ -0,0 +1,55 @@ +#ifndef OPIE_OBEX_RECEIVER_H +#define OPIE_OBEX_RECEIVER_H + +#include +#include +#include + +class QLabel; +class QTextView; +namespace OpieObex { + class Obex; + class OtherHandler; + class Receiver : public QObject { + Q_OBJECT + public: + enum { Datebook , AddressBook, Other }; + Receiver(); + ~Receiver(); + + private: + void handleAddr(const QString& ); + void handleDateTodo(const QString& ); + void handleOther(const QString& ); + int checkFile( const QString& file ); + bool testDateTodo(const QString& file); + bool testAddressbook(const QString& file); + + private slots: + void slotReceived( const QString& ); + + private: + Obex* m_obex; + }; + + class OtherHandler : public QVBox { + Q_OBJECT + public: + OtherHandler(); + ~OtherHandler(); + + void handle( const QString& file ); + private slots: + void accept(); + void deny(); + private: + QString targetName( const QString& file ); + void copy( const QString& src, const QString& dest ); + QLabel* m_na; + QTextView* m_view; + QString m_file; + }; +} + + +#endif -- cgit v0.9.0.2