From 7202ac536ac98e7e433984d98cb9236330b25cc8 Mon Sep 17 00:00:00 2001 From: mickeyl Date: Mon, 22 Aug 2005 09:36:38 +0000 Subject: Replace the existing, apparently non-working, OBEX Send form with a completely new implementation. The new implementation supports selective send over both IrDA and Bluetooth, to selected receivers (which are discovered as the form pops up). The form also indicates transfer status as the transfers progress. There is a new QT Designer UI form file, integrated into the build. There are also two new source files for the form to supply the abstract methods (typical of QT2). Patch courtesy Michael Haynie - thanks! --- (limited to 'core/obex') diff --git a/core/obex/obex.cc b/core/obex/btobex.cpp index 36634ec..a2866f6 100644 --- a/core/obex/obex.cc +++ b/core/obex/btobex.cpp @@ -1,5 +1,5 @@ -#include "obex.h" +#include "btobex.h" /* OPIE */ #include @@ -15,7 +15,7 @@ using namespace OpieObex; using namespace Opie::Core; /* TRANSLATOR OpieObex::Obex */ -Obex::Obex( QObject *parent, const char* name ) +BtObex::BtObex( QObject *parent, const char* name ) : QObject(parent, name ) { m_rec = 0; @@ -27,15 +27,17 @@ Obex::Obex( QObject *parent, const char* name ) connect( this, SIGNAL(sent(bool) ), SLOT(slotError() ) ); }; -Obex::~Obex() { +BtObex::~BtObex() { delete m_rec; delete m_send; } -void Obex::receive() { +void BtObex::receive() { m_receive = true; m_outp = QString::null; m_rec = new OProcess(); - *m_rec << "irobex_palm3"; + + // TODO mbhaynie: No idea if this actually works -- maybe opd is better. + *m_rec << "obexftpd" << "-b"; // connect to the necessary slots connect(m_rec, SIGNAL(processExited(Opie::Core::OProcess*) ), this, SLOT(slotExited(Opie::Core::OProcess*) ) ); @@ -50,9 +52,11 @@ void Obex::receive() { } } -void Obex::send( const QString& fileName) { // if currently receiving stop it send receive +void BtObex::send( const QString& fileName, const QString& bdaddr) { + // if currently receiving stop it send receive m_count = 0; m_file = fileName; + m_bdaddr = bdaddr; if (m_rec != 0 ) { if (m_rec->isRunning() ) { emit error(-1 ); @@ -66,7 +70,7 @@ void Obex::send( const QString& fileName) { // if currently receiving stop it se } sendNow(); } -void Obex::sendNow(){ +void BtObex::sendNow(){ if ( m_count >= 25 ) { // could not send emit error(-1 ); emit sent(false); @@ -76,8 +80,12 @@ void Obex::sendNow(){ m_send = new OProcess(); m_send->setWorkingDirectory( QFileInfo(m_file).dirPath(true) ); - *m_send << "irobex_palm3"; + // obextool push file [channel] + // 9 for phones. + // Palm T3 accepts pictures on 1 + *m_send << "obextool" << "push"; *m_send << QFile::encodeName(QFileInfo(m_file).fileName()); + *m_send << m_bdaddr << "9"; // connect to slots Exited and and StdOut connect(m_send, SIGNAL(processExited(Opie::Core::OProcess*) ), @@ -97,14 +105,14 @@ void Obex::sendNow(){ emit currentTry( m_count ); } -void Obex::slotExited(OProcess* proc ){ +void BtObex::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){ +void BtObex::slotStdOut(OProcess* proc, char* buf, int len){ if ( proc == m_rec ) { // only receive QByteArray ar( len ); memcpy( ar.data(), buf, len ); @@ -112,7 +120,7 @@ void Obex::slotStdOut(OProcess* proc, char* buf, int len){ } } -void Obex::received() { +void BtObex::received() { if (m_rec->normalExit() ) { if ( m_rec->exitStatus() == 0 ) { // we got one QString filename = parseOut(); @@ -126,7 +134,7 @@ void Obex::received() { receive(); } -void Obex::sendEnd() { +void BtObex::sendEnd() { if (m_send->normalExit() ) { if ( m_send->exitStatus() == 0 ) { delete m_send; @@ -144,7 +152,9 @@ void Obex::sendEnd() { m_send = 0; } } -QString Obex::parseOut( ){ + +// This probably doesn't do anything useful for bt. +QString BtObex::parseOut( ){ QString path; QStringList list = QStringList::split("\n", m_outp); QStringList::Iterator it; @@ -164,18 +174,18 @@ QString Obex::parseOut( ){ /** * when sent is done slotError is called we will start receive again */ -void Obex::slotError() { +void BtObex::slotError() { if ( m_receive ) receive(); }; -void Obex::setReceiveEnabled( bool receive ) { +void BtObex::setReceiveEnabled( bool receive ) { if ( !receive ) { // m_receive = false; shutDownReceive(); } } -void Obex::shutDownReceive() { +void BtObex::shutDownReceive() { if (m_rec != 0 ) { if (m_rec->isRunning() ) { emit error(-1 ); diff --git a/core/obex/obex.h b/core/obex/btobex.h index 5993976..5ab591c 100644 --- a/core/obex/obex.h +++ b/core/obex/btobex.h @@ -1,31 +1,32 @@ -#ifndef OpieObex_H -#define OpieObex_H +#ifndef OpieBtObex_H +#define OpieBtObex_H #include namespace Opie {namespace Core {class OProcess;}} class QCopChannel; namespace OpieObex { - class Obex : public QObject { + // Maybe this should be derved from Obex. + class BtObex : public QObject { Q_OBJECT public: /** - * Obex c'tor look + * BtObex c'tor look */ - Obex( QObject *parent, const char* name); + BtObex( QObject *parent, const char* name); /** * d'tor */ - ~Obex(); + ~BtObex(); - /** - * Starting listening to irda after enabled by the applet + /** TODO mbhaynie -- Maybe opd would be a better way to receive. + * Starting listening to Bluetooth after enabled by the applet * a signal gets emitted when received a file */ void receive(); - void send( const QString& ); + void send( const QString&, const QString& ); void setReceiveEnabled( bool = false ); signals: @@ -53,6 +54,7 @@ namespace OpieObex { uint m_count; QString m_file; QString m_outp; + QString m_bdaddr; Opie::Core::OProcess *m_send; Opie::Core::OProcess *m_rec; bool m_receive : 1; @@ -60,12 +62,6 @@ namespace OpieObex { private slots: - /** - * send over palm obex - */ - - //void send(const QString&); - // the process exited void slotExited(Opie::Core::OProcess* proc) ; void slotStdOut(Opie::Core::OProcess*, char*, int); diff --git a/core/obex/obex.pro b/core/obex/obex.pro index 4e72bc4..1f4f486 100644 --- a/core/obex/obex.pro +++ b/core/obex/obex.pro @@ -1,13 +1,13 @@ TEMPLATE = lib CONFIG += qt warn_on -HEADERS = obex.h obexhandler.h obexsend.h receiver.h obeximpl.h -SOURCES = obex.cc obexsend.cpp obexhandler.cpp receiver.cpp obeximpl.cpp +HEADERS = btobex.h obexhandler.h receiver.h obeximpl.h +SOURCES = btobex.cpp obexhandler.cpp receiver.cpp obeximpl.cpp TARGET = opieobex DESTDIR = $(OPIEDIR)/plugins/obex +INTERFACES = obexsendbase.ui INCLUDEPATH += $(OPIEDIR)/include $(OPIEDIR)/core/launcher -DEPENDPATH += -LIBS += -lqpe -lopiecore2 -VERSION = 0.0.2 +LIBS += -lqpe -lopiecore2 +VERSION = 0.0.3 include( $(OPIEDIR)/include.pro ) target.path = $$prefix/plugins/applets diff --git a/core/obex/obexsend.cpp b/core/obex/obexsend.cpp deleted file mode 100644 index 675c5e4..0000000 --- a/core/obex/obexsend.cpp +++ b/dev/null @@ -1,289 +0,0 @@ -#include "obex.h" -#include "obexsend.h" -using namespace OpieObex; - -/* OPIE */ -#include -#include -using namespace Opie::Core; - -/* QT */ -#include -#include -#include -#include - -/* TRANSLATOR OpieObex::SendWidget */ - -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(dispatchIrda(const QCString&,const QByteArray&) ) ); - - chan = new QCopChannel("QPE/BluetoothBack", this ); - connect(chan, SIGNAL(received(const QCString&,const QByteArray&) ), - this, SLOT(dispatchBt(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(int,int) ), - this, SLOT(slotSelectedDevice(int,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_irDeSearch = m_devBox->addDevice( tr("IrDa is not enabled!"), DeviceBox::Error ); - m_start++; - }else - m_irDeSearch = m_devBox->addDevice( tr("Searching for IrDa Devices."), DeviceBox::Search ); - - if ( !QCopChannel::isRegistered("QPE/Bluetooth") ) { - m_btDeSearch = m_devBox->addDevice( tr("Bluetooth is not available"), DeviceBox::Error ); - m_start++; - }else - m_btDeSearch = 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()"); - } -} -void SendWidget::slotIrDaDevices( const QStringList& list) { - for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) { - int id = m_devBox->addDevice( (*it), DeviceBox::IrDa, tr("Scheduling for beam.") ); - m_irDa.insert( id, (*it) ); - } - m_devBox->removeDevice( m_irDeSearch ); - m_irDaIt = m_irDa.begin(); - - slotStartIrda(); -} - -void SendWidget::slotBTDevices( const QMap& str ) { - for(QMap::ConstIterator it = str.begin(); it != str.end(); ++it ) { - int id = m_devBox->addDevice( it.key(), DeviceBox::BT, tr("Click to beam") ); - m_bt.insert( id, Pair( it.key(), it.data() ) ); - } - m_devBox->removeDevice( m_btDeSearch ); -} -void SendWidget::slotSelectedDevice( int name, int ) { - if ( name == m_irDeSearch ) { - for (QMap::Iterator it= m_irDa.begin(); it != m_irDa.end(); ++it ) - m_devBox->removeDevice( it.key() ); - - QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); - } -} -void SendWidget::dispatchIrda( const QCString& str, const QByteArray& ar ) { - if ( str == "devices(QStringList)" ) { - QDataStream stream( ar, IO_ReadOnly ); - QStringList list; - stream >> list; - slotIrDaDevices( list ); - } -} -void SendWidget::dispatchBt( const QCString&, const QByteArray& ) { - -} -void SendWidget::slotIrError( int ) { - -} -void SendWidget::slotIrSent( bool b) { - QString text = b ? tr("Sent") : tr("Failure"); - m_devBox->setStatus( m_irDaIt.key(), text ); - ++m_irDaIt; - slotStartIrda(); -} -void SendWidget::slotIrTry(unsigned int trI) { - m_devBox->setStatus( m_irDaIt.key(), tr("Try %1").arg( QString::number( trI ) ) ); -} -void SendWidget::slotStartIrda() { - if (m_irDaIt == m_irDa.end() ) { - m_irDeSearch = m_devBox->addDevice(tr("Search again for IrDa."), DeviceBox::Search ); - return; - } - m_devBox->setStatus( m_irDaIt.key(), tr("Start sending") ); - m_obex->send( m_file ); -} -void SendWidget::closeEvent( QCloseEvent* e) { - e->accept(); // make sure - QTimer::singleShot(0, this, SLOT(slotDone() ) ); -} -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() { - -} -int DeviceBox::addDevice( const QString& name, int dev, const QString& status ) { - /* return a id for a range of devices */ - int id = idFor ( dev ); - DeviceItem item( name, status, dev,id ); - m_dev.insert( id, item ); - setText( allText() ); - - return id; -} -void DeviceBox::removeDevice( int id ) { - if (!m_dev.contains(id) ) return; - - m_dev.remove( id ); - setText( allText() ); -} -void DeviceBox::setStatus( int id, const QString& status ) { - if ( !m_dev.contains(id) ) return; - m_dev[id].setStatus(status ); - setText( allText() ); -} -void DeviceBox::setSource( const QString& str ) { - int id = str.toInt(); - emit selectedDevice( id, m_dev[id].device() ); -} -int DeviceBox::idFor ( int id ) { - static int irId = 1501; - static int irBT = 1001; - static int irSr = 501; - static int irEr = 0; - - int ret = -1; - switch(id ) { - case IrDa: - ret = irId; - irId++; - break; - case BT: - ret = irBT; - irBT++; - break; - case Search: - ret = irSr; - irSr++; - break; - case Error: - ret = irEr; - irEr++; - break; - } - return ret; -} -QString DeviceBox::allText() { - QString str; - typedef QMap DeviceMap; - - for (QMap::Iterator it = m_dev.begin(); it != m_dev.end(); ++it ) { - str += it.data().toString() + "
"; - } - return str; -} - -DeviceItem::DeviceItem( const QString& name, - const QString& status, int dev, int id) -{ - m_name = name; - m_status = status; - m_dev = dev; - m_id = id; -} -int DeviceItem::id()const { - return m_id; -} -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 = "mag"; - 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 deleted file mode 100644 index bf901cb..0000000 --- a/core/obex/obexsend.h +++ b/dev/null @@ -1,125 +0,0 @@ -#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; - - struct Pair { - Pair(const QString& first = QString::null, - const QString& second = QString::null) - : m_first(first), m_second(second ) { - } - QString first()const{ return m_first; } - QString second()const { return m_second; } - private: - QString m_first; - QString m_second; - }; - class SendWidget : public QWidget{ - Q_OBJECT - public: - SendWidget( QWidget* parent = 0, const char* name = 0); - ~SendWidget(); - - QString file()const; - - protected: - void closeEvent( QCloseEvent* ); - - 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( int id, 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; - QMap m_irDa; - QMap::Iterator m_irDaIt; - QMap m_bt; - QString m_file; - Obex* m_obex; - int m_irDeSearch; // search of irda and bt devices - int m_btDeSearch; - }; - class DeviceItem { - public: - DeviceItem( const QString& name = QString::null, - const QString& status = QString::null, int dev = 3, int id = -1); - ~DeviceItem(); - void setStatus( const QString& text ); - - QString name()const; - QString status()const; - QString pixmap()const; - int device()const; - int id()const; - QString toString()const; - private: - QString m_name; - QString m_status; - int m_dev; - int m_id; - }; - - /* - * The text field which contains the information about sending... - * - */ - class DeviceBox : public QTextBrowser { - Q_OBJECT - public: - enum Device { IrDa, BT, Search, Error }; - DeviceBox( QWidget* parent ); - ~DeviceBox(); - - void setSource( const QString& str ); - int addDevice( const QString& name, int dev, - const QString& status = QString::null ); - void removeDevice( int ); - void setStatus( int, const QString& ); - signals: - void selectedDevice( int id, int dev ); - private: - /* returns a id for a device from a device range */ - int idFor (int deviceType ); - QString allText(); - QMap m_dev; - }; -} - -#endif -- cgit v0.9.0.2