author | mickeyl <mickeyl> | 2005-08-22 09:36:38 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2005-08-22 09:36:38 (UTC) |
commit | 7202ac536ac98e7e433984d98cb9236330b25cc8 (patch) (side-by-side diff) | |
tree | c8b5d4e57dd4b9b302999d1f88a89c28e4ee0e5e | |
parent | 140e4dc44a29678de1ae8b2cef5b1d081993223e (diff) | |
download | opie-7202ac536ac98e7e433984d98cb9236330b25cc8.zip opie-7202ac536ac98e7e433984d98cb9236330b25cc8.tar.gz opie-7202ac536ac98e7e433984d98cb9236330b25cc8.tar.bz2 |
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!
-rw-r--r-- | core/obex/btobex.cpp (renamed from core/obex/obex.cc) | 42 | ||||
-rw-r--r-- | core/obex/btobex.h (renamed from core/obex/obex.h) | 26 | ||||
-rw-r--r-- | core/obex/obex.pro | 10 | ||||
-rw-r--r-- | core/obex/obexsend.cpp | 289 | ||||
-rw-r--r-- | core/obex/obexsend.h | 125 |
5 files changed, 42 insertions, 450 deletions
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,187 +1,197 @@ -#include "obex.h" +#include "btobex.h" /* OPIE */ #include <opie2/oprocess.h> #include <opie2/odebug.h> /* QT */ #include <qfileinfo.h> 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; m_send=0; m_count = 0; m_receive = false; connect( this, SIGNAL(error(int) ), // for recovering to receive SLOT(slotError() ) ); 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*) ) ); connect(m_rec, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int ) ), this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) ); if(!m_rec->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) { emit done( false ); delete m_rec; m_rec = 0; } } -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 ); delete m_rec; m_rec = 0; }else{ emit error( -1 ); // we did not delete yet but it's not running slotExited is pending return; } } sendNow(); } -void Obex::sendNow(){ +void BtObex::sendNow(){ if ( m_count >= 25 ) { // could not send emit error(-1 ); emit sent(false); return; } // OProcess inititialisation m_send = new OProcess(); m_send->setWorkingDirectory( QFileInfo(m_file).dirPath(true) ); - *m_send << "irobex_palm3"; + // obextool push file <bdaddr> [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*) ), this, SLOT(slotExited(Opie::Core::OProcess*)) ); connect(m_send, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int )), this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) ); // now start it if (!m_send->start(/*OProcess::NotifyOnExit, OProcess::AllOutput*/ ) ) { m_count = 25; emit error(-1 ); delete m_send; m_send=0; } // end m_count++; 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 ); m_outp.append( ar ); } } -void Obex::received() { +void BtObex::received() { if (m_rec->normalExit() ) { if ( m_rec->exitStatus() == 0 ) { // we got one QString filename = parseOut(); emit receivedFile( filename ); } }else{ emit done(false); }; delete m_rec; m_rec = 0; receive(); } -void Obex::sendEnd() { +void BtObex::sendEnd() { if (m_send->normalExit() ) { if ( m_send->exitStatus() == 0 ) { delete m_send; m_send=0; 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; sendNow(); } }else { emit error( -1 ); delete m_send; 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; for (it = list.begin(); it != list.end(); ++it ) { if ( (*it).startsWith("Wrote" ) ) { int pos = (*it).findRev('(' ); if ( pos > 0 ) { path = (*it).remove( pos, (*it).length() - pos ); path = path.mid(6 ); path = path.stripWhiteSpace(); } } } return path; } /** * 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 ); delete m_rec; m_rec = 0; } } } 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,84 +1,80 @@ -#ifndef OpieObex_H -#define OpieObex_H +#ifndef OpieBtObex_H +#define OpieBtObex_H #include <qobject.h> 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: /** * a signal * @param path The path to the received 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; + QString m_bdaddr; Opie::Core::OProcess *m_send; Opie::Core::OProcess *m_rec; bool m_receive : 1; void shutDownReceive(); 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); void slotError(); private: void sendNow(); QString parseOut(); void received(); void sendEnd(); }; }; #endif 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 <opie2/odebug.h> -#include <qpe/qcopenvelope_qws.h> -using namespace Opie::Core; - -/* QT */ -#include <qpushbutton.h> -#include <qlabel.h> -#include <qlayout.h> -#include <qtimer.h> - -/* 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("<qt><h1>Sending:</h1></qt>") ); - 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("<qt><b>Devices:</b></qt>"); - 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<QString, QString>& str ) { - for(QMap<QString, QString>::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<int, QString>::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<int, DeviceItem> DeviceMap; - - for (QMap<int, DeviceItem>::Iterator it = m_dev.begin(); it != m_dev.end(); ++it ) { - str += it.data().toString() + "<br>"; - } - 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 "<p><a href=\""+QString::number(m_id) +"\" ><img src=\""+pixmap()+"\" >"+m_name+" "+m_status+" </a></p>" ; -} 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 <qstring.h> -#include <qstringlist.h> -#include <qwidget.h> -#include <qvbox.h> -#include <qmap.h> -#include <qtextbrowser.h> - -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<QString, QString>& ); - 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<int, QString> m_irDa; - QMap<int, QString>::Iterator m_irDaIt; - QMap<int, Pair > 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<int, DeviceItem> m_dev; - }; -} - -#endif |