author | zecke <zecke> | 2003-02-16 15:49:02 (UTC) |
---|---|---|
committer | zecke <zecke> | 2003-02-16 15:49:02 (UTC) |
commit | 30a098530260176ac20d75ba6cb7abfb3d998c13 (patch) (unidiff) | |
tree | ee5c08ca67fa00574414153921ab2de654c60421 /core/obex | |
parent | 7fab90d46144843d32e476ada8d0a5f40f50aa60 (diff) | |
download | opie-30a098530260176ac20d75ba6cb7abfb3d998c13.zip opie-30a098530260176ac20d75ba6cb7abfb3d998c13.tar.gz opie-30a098530260176ac20d75ba6cb7abfb3d998c13.tar.bz2 |
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
-rw-r--r-- | core/obex/config.in | 4 | ||||
-rw-r--r-- | core/obex/obex.cc | 195 | ||||
-rw-r--r-- | core/obex/obex.h | 84 | ||||
-rw-r--r-- | core/obex/obexhandler.cpp | 65 | ||||
-rw-r--r-- | core/obex/obexhandler.h | 39 | ||||
-rw-r--r-- | core/obex/obeximpl.cpp | 28 | ||||
-rw-r--r-- | core/obex/obeximpl.h | 22 | ||||
-rw-r--r-- | core/obex/obexsend.cpp | 251 | ||||
-rw-r--r-- | core/obex/obexsend.h | 99 | ||||
-rw-r--r-- | core/obex/receiver.cpp | 166 | ||||
-rw-r--r-- | core/obex/receiver.h | 55 |
11 files changed, 1008 insertions, 0 deletions
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 @@ | |||
1 | config OBEX | ||
2 | boolean "Obex library (library needed for beaming in Opie)" | ||
3 | default "y" | ||
4 | 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 @@ | |||
1 | |||
2 | #include <qapplication.h> | ||
3 | #include <qmessagebox.h> | ||
4 | #include <qpe/qcopenvelope_qws.h> | ||
5 | #include <opie/oprocess.h> | ||
6 | #include "obex.h" | ||
7 | |||
8 | using namespace OpieObex; | ||
9 | |||
10 | Obex::Obex( QObject *parent, const char* name ) | ||
11 | : QObject(parent, name ) | ||
12 | { | ||
13 | m_rec = 0; | ||
14 | m_send=0; | ||
15 | m_count = 0; | ||
16 | m_receive = false; | ||
17 | connect( this, SIGNAL(error(int) ), // for recovering to receive | ||
18 | SLOT(slotError() ) ); | ||
19 | connect( this, SIGNAL(sent() ), | ||
20 | SLOT(slotError() ) ); | ||
21 | }; | ||
22 | Obex::~Obex() { | ||
23 | delete m_rec; | ||
24 | delete m_send; | ||
25 | } | ||
26 | void Obex::receive() { | ||
27 | m_receive = true; | ||
28 | m_outp = QString::null; | ||
29 | qWarning("Receive" ); | ||
30 | m_rec = new OProcess(); | ||
31 | *m_rec << "irobex_palm3"; | ||
32 | // connect to the necessary slots | ||
33 | connect(m_rec, SIGNAL(processExited(OProcess*) ), | ||
34 | this, SLOT(slotExited(OProcess*) ) ); | ||
35 | |||
36 | connect(m_rec, SIGNAL(receivedStdout(OProcess*, char*, int ) ), | ||
37 | this, SLOT(slotStdOut(OProcess*, char*, int) ) ); | ||
38 | |||
39 | if(!m_rec->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) { | ||
40 | qWarning("could not start :("); | ||
41 | emit done( false ); | ||
42 | delete m_rec; | ||
43 | m_rec = 0; | ||
44 | } | ||
45 | // emit currentTry(m_count ); | ||
46 | |||
47 | } | ||
48 | void Obex::send( const QString& fileName) { // if currently receiving stop it send receive | ||
49 | m_count = 0; | ||
50 | m_file = fileName; | ||
51 | qWarning("send"); | ||
52 | if (m_rec != 0 ) { | ||
53 | qWarning("running"); | ||
54 | if (m_rec->isRunning() ) { | ||
55 | emit error(-1 ); | ||
56 | qWarning("is running"); | ||
57 | delete m_rec; | ||
58 | m_rec = 0; | ||
59 | |||
60 | }else{ | ||
61 | qWarning("is not running"); | ||
62 | emit error( -1 ); // we did not delete yet but it's not running slotExited is pending | ||
63 | return; | ||
64 | } | ||
65 | } | ||
66 | sendNow(); | ||
67 | } | ||
68 | void Obex::sendNow(){ | ||
69 | qWarning("sendNow"); | ||
70 | if ( m_count >= 25 ) { // could not send | ||
71 | emit error(-1 ); | ||
72 | emit sent(false); | ||
73 | return; | ||
74 | } | ||
75 | // OProcess inititialisation | ||
76 | m_send = new OProcess(); | ||
77 | *m_send << "irobex_palm3"; | ||
78 | *m_send << m_file; | ||
79 | |||
80 | // connect to slots Exited and and StdOut | ||
81 | connect(m_send, SIGNAL(processExited(OProcess*) ), | ||
82 | this, SLOT(slotExited(OProcess*)) ); | ||
83 | connect(m_send, SIGNAL(receivedStdout(OProcess*, char*, int )), | ||
84 | this, SLOT(slotStdOut(OProcess*, char*, int) ) ); | ||
85 | |||
86 | // now start it | ||
87 | if (!m_send->start(/*OProcess::NotifyOnExit, OProcess::AllOutput*/ ) ) { | ||
88 | qWarning("could not send" ); | ||
89 | m_count = 25; | ||
90 | emit error(-1 ); | ||
91 | delete m_send; | ||
92 | m_send=0; | ||
93 | } | ||
94 | // end | ||
95 | m_count++; | ||
96 | emit currentTry( m_count ); | ||
97 | } | ||
98 | |||
99 | void Obex::slotExited(OProcess* proc ){ | ||
100 | if (proc == m_rec ) { // receive process | ||
101 | received(); | ||
102 | }else if ( proc == m_send ) { | ||
103 | sendEnd(); | ||
104 | } | ||
105 | } | ||
106 | void Obex::slotStdOut(OProcess* proc, char* buf, int len){ | ||
107 | if ( proc == m_rec ) { // only receive | ||
108 | QCString cstring( buf, len ); | ||
109 | m_outp.append( cstring.data() ); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | void Obex::received() { | ||
114 | if (m_rec->normalExit() ) { | ||
115 | if ( m_rec->exitStatus() == 0 ) { // we got one | ||
116 | QString filename = parseOut(); | ||
117 | qWarning("ACHTUNG"); | ||
118 | emit receivedFile( filename ); | ||
119 | } | ||
120 | }else{ | ||
121 | emit done(false); | ||
122 | }; | ||
123 | delete m_rec; | ||
124 | m_rec = 0; | ||
125 | receive(); | ||
126 | } | ||
127 | |||
128 | void Obex::sendEnd() { | ||
129 | if (m_send->normalExit() ) { | ||
130 | if ( m_send->exitStatus() == 0 ) { | ||
131 | delete m_send; | ||
132 | m_send=0; | ||
133 | qWarning("done" ); | ||
134 | emit sent(true); | ||
135 | }else if (m_send->exitStatus() == 255 ) { // it failed maybe the other side wasn't ready | ||
136 | // let's try it again | ||
137 | delete m_send; | ||
138 | m_send = 0; | ||
139 | qWarning("try sending again" ); | ||
140 | sendNow(); | ||
141 | } | ||
142 | }else { | ||
143 | emit error( -1 ); | ||
144 | delete m_send; | ||
145 | m_send = 0; | ||
146 | } | ||
147 | } | ||
148 | QString Obex::parseOut( ){ | ||
149 | QString path; | ||
150 | QStringList list = QStringList::split("\n", m_outp); | ||
151 | QStringList::Iterator it; | ||
152 | for (it = list.begin(); it != list.end(); ++it ) { | ||
153 | if ( (*it).startsWith("Wrote" ) ) { | ||
154 | int pos = (*it).findRev('(' ); | ||
155 | if ( pos > 0 ) { | ||
156 | qWarning( "%d %s", pos, (*it).mid(6 ).latin1() ) ; | ||
157 | qWarning("%d %d", (*it).length(), (*it).length()-pos ); | ||
158 | |||
159 | path = (*it).remove( pos, (*it).length() - pos ); | ||
160 | qWarning("%s", path.latin1() ); | ||
161 | path = path.mid(6 ); | ||
162 | path = path.stripWhiteSpace(); | ||
163 | qWarning("path %s", path.latin1() ); | ||
164 | } | ||
165 | } | ||
166 | } | ||
167 | return path; | ||
168 | } | ||
169 | /** | ||
170 | * when sent is done slotError is called we will start receive again | ||
171 | */ | ||
172 | void Obex::slotError() { | ||
173 | qWarning("slotError"); | ||
174 | if ( m_receive ) | ||
175 | receive(); | ||
176 | }; | ||
177 | void Obex::setReceiveEnabled( bool receive ) { | ||
178 | if ( !receive ) { // | ||
179 | m_receive = false; | ||
180 | shutDownReceive(); | ||
181 | } | ||
182 | } | ||
183 | |||
184 | void Obex::shutDownReceive() { | ||
185 | if (m_rec != 0 ) { | ||
186 | qWarning("running"); | ||
187 | if (m_rec->isRunning() ) { | ||
188 | emit error(-1 ); | ||
189 | qWarning("is running"); | ||
190 | delete m_rec; | ||
191 | m_rec = 0; | ||
192 | } | ||
193 | } | ||
194 | |||
195 | } | ||
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 @@ | |||
1 | |||
2 | |||
3 | #ifndef OpieObex_H | ||
4 | #define OpieObex_H | ||
5 | |||
6 | #include <qobject.h> | ||
7 | |||
8 | class OProcess; | ||
9 | class QCopChannel; | ||
10 | namespace OpieObex { | ||
11 | class Obex : public QObject { | ||
12 | Q_OBJECT | ||
13 | public: | ||
14 | /** | ||
15 | * Obex c'tor look | ||
16 | */ | ||
17 | Obex( QObject *parent, const char* name); | ||
18 | /** | ||
19 | * d'tor | ||
20 | */ | ||
21 | ~Obex(); | ||
22 | |||
23 | /** | ||
24 | * Starting listening to irda after enabled by the applet | ||
25 | * a signal gets emitted when recieved a file | ||
26 | */ | ||
27 | void receive(); | ||
28 | void send( const QString& ); | ||
29 | void setReceiveEnabled( bool = false ); | ||
30 | signals: | ||
31 | |||
32 | /** | ||
33 | * a signal | ||
34 | * @param path The path to the recieved file | ||
35 | */ | ||
36 | void receivedFile( const QString& path); | ||
37 | /** | ||
38 | * error signal if the program couldn't be started or the | ||
39 | * the connection timed out | ||
40 | */ | ||
41 | void error( int ); | ||
42 | /** | ||
43 | * The current try to receive data | ||
44 | */ | ||
45 | void currentTry(unsigned int); | ||
46 | /** | ||
47 | * signal sent The file got beamed to the remote location | ||
48 | */ | ||
49 | void sent(bool); | ||
50 | void done(bool); | ||
51 | |||
52 | private: | ||
53 | uint m_count; | ||
54 | QString m_file; | ||
55 | QString m_outp; | ||
56 | OProcess *m_send; | ||
57 | OProcess *m_rec; | ||
58 | bool m_receive : 1; | ||
59 | void shutDownReceive(); | ||
60 | |||
61 | private slots: | ||
62 | |||
63 | /** | ||
64 | * send over palm obex | ||
65 | */ | ||
66 | |||
67 | //void send(const QString&); | ||
68 | |||
69 | // the process exited | ||
70 | void slotExited(OProcess* proc) ; | ||
71 | void slotStdOut(OProcess*, char*, int); | ||
72 | void slotError(); | ||
73 | |||
74 | private: | ||
75 | void sendNow(); | ||
76 | QString parseOut(); | ||
77 | void received(); | ||
78 | void sendEnd(); | ||
79 | |||
80 | }; | ||
81 | }; | ||
82 | |||
83 | |||
84 | #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 @@ | |||
1 | #include <qcopchannel_qws.h> | ||
2 | |||
3 | #include <qpe/qcopenvelope_qws.h> | ||
4 | |||
5 | #include "obexsend.h" | ||
6 | #include "receiver.h" | ||
7 | #include "obexhandler.h" | ||
8 | |||
9 | using namespace OpieObex; | ||
10 | |||
11 | ObexHandler::ObexHandler() { | ||
12 | m_wasRec = false; | ||
13 | m_sender = 0l; | ||
14 | m_receiver = 0l; | ||
15 | QCopChannel* chan = new QCopChannel("QPE/Obex"); | ||
16 | connect(chan, SIGNAL(received(const QCString&, const QByteArray& ) ), | ||
17 | this, SLOT(irdaMessage(const QCString&, const QByteArray& ) ) ); | ||
18 | } | ||
19 | ObexHandler::~ObexHandler() { | ||
20 | delete m_sender; | ||
21 | delete m_receiver; | ||
22 | } | ||
23 | void ObexHandler::doSend(const QString& str, const QString& desc) { | ||
24 | delete m_sender; | ||
25 | m_sender = new SendWidget; | ||
26 | m_sender->raise(); | ||
27 | m_sender->showMaximized(); | ||
28 | connect(m_sender, SIGNAL(done() ), | ||
29 | this, SLOT(slotSent() ) ); | ||
30 | m_sender->send( str, desc ); | ||
31 | } | ||
32 | void ObexHandler::doReceive(bool b) { | ||
33 | if (m_receiver && b ) return; // we should enable receiver and it is on | ||
34 | else if (!m_receiver && !b ) return; // we should disbale receiver and it is off | ||
35 | else if (m_receiver && !b ) { | ||
36 | delete m_receiver; | ||
37 | m_receiver=0; | ||
38 | }else if (!m_receiver && b ) { | ||
39 | m_receiver= new Receiver; | ||
40 | } | ||
41 | } | ||
42 | void ObexHandler::slotSent() { | ||
43 | QString file = m_sender->file(); | ||
44 | delete m_sender; | ||
45 | m_sender = 0; | ||
46 | QCopEnvelope e ("QPE/Obex", "done(QString)" ); | ||
47 | e << file; | ||
48 | doReceive(m_wasRec ); | ||
49 | m_wasRec = false; | ||
50 | } | ||
51 | void ObexHandler::irdaMessage( const QCString& msg, const QByteArray& data) { | ||
52 | QDataStream stream( data, IO_ReadOnly ); | ||
53 | if ( msg == "send(QString,QString,QString)" ) { | ||
54 | QString name, desc; | ||
55 | stream >> name; | ||
56 | stream >> desc; | ||
57 | m_wasRec = (m_receiver != 0 ); | ||
58 | doReceive( false ); | ||
59 | doSend(name, desc); | ||
60 | }else if (msg == "receive(int)") { | ||
61 | int rec; | ||
62 | stream >> rec; | ||
63 | doReceive(rec); | ||
64 | } | ||
65 | } | ||
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 @@ | |||
1 | #ifndef OPIE_OBEX_HANDLER_H | ||
2 | #define OPIE_OBEX_HANDLER_H | ||
3 | |||
4 | #include <qobject.h> | ||
5 | #include <qstring.h> | ||
6 | |||
7 | namespace OpieObex { | ||
8 | /* | ||
9 | * The handler is responsible for handling receiving | ||
10 | * and sending | ||
11 | * It will connect to the IrDa QCOP channel and then | ||
12 | * wait for activation... | ||
13 | */ | ||
14 | class SendWidget; | ||
15 | class Receiver; | ||
16 | class ObexHandler : public QObject { | ||
17 | Q_OBJECT | ||
18 | public: | ||
19 | ObexHandler(); | ||
20 | ~ObexHandler(); | ||
21 | |||
22 | private slots: | ||
23 | void doSend(const QString&,const QString& ); | ||
24 | void doReceive(bool b); | ||
25 | void slotSent(); | ||
26 | |||
27 | private slots: // QCOP message | ||
28 | void irdaMessage( const QCString&, const QByteArray& ); | ||
29 | |||
30 | private: | ||
31 | SendWidget* m_sender; | ||
32 | Receiver* m_receiver; | ||
33 | bool m_wasRec : 1; | ||
34 | |||
35 | }; | ||
36 | } | ||
37 | |||
38 | |||
39 | #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 @@ | |||
1 | #include "obexhandler.h" | ||
2 | #include "obeximpl.h" | ||
3 | |||
4 | using namespace OpieObex; | ||
5 | |||
6 | ObexImpl::ObexImpl() { | ||
7 | m_handler = new ObexHandler; | ||
8 | } | ||
9 | ObexImpl::~ObexImpl() { | ||
10 | delete m_handler; | ||
11 | } | ||
12 | QRESULT ObexImpl::queryInterface( const QUuid& uuid, QUnknownInterface **iface ) { | ||
13 | *iface = 0; | ||
14 | if ( uuid == IID_QUnknown ) { | ||
15 | *iface = this; | ||
16 | }else if ( uuid == IID_ObexInterface ) | ||
17 | *iface = this; | ||
18 | |||
19 | if (*iface) | ||
20 | (*iface)->addRef(); | ||
21 | |||
22 | return QS_OK; | ||
23 | } | ||
24 | |||
25 | |||
26 | Q_EXPORT_INTERFACE() { | ||
27 | Q_CREATE_INSTANCE( ObexImpl ) | ||
28 | } | ||
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 @@ | |||
1 | #ifndef OPIE_OBEX_IMPL_QUERY_H | ||
2 | #define OPIE_OBEX_IMPL_QUERY_H | ||
3 | |||
4 | #include <obexinterface.h> | ||
5 | |||
6 | namespace OpieObex { | ||
7 | class ObexHandler; | ||
8 | class ObexImpl : public ObexInterface { | ||
9 | public: | ||
10 | ObexImpl(); | ||
11 | virtual ~ObexImpl(); | ||
12 | QRESULT queryInterface( const QUuid&, QUnknownInterface** ); | ||
13 | Q_REFCOUNT | ||
14 | |||
15 | private: | ||
16 | ulong ref; | ||
17 | ObexHandler *m_handler; | ||
18 | |||
19 | }; | ||
20 | }; | ||
21 | |||
22 | #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 @@ | |||
1 | #include <qpushbutton.h> | ||
2 | #include <qlabel.h> | ||
3 | #include <qhbox.h> | ||
4 | #include <qlayout.h> | ||
5 | #include <qtimer.h> | ||
6 | |||
7 | #include <qcopchannel_qws.h> | ||
8 | |||
9 | #include <qpe/resource.h> | ||
10 | #include <qpe/qcopenvelope_qws.h> | ||
11 | |||
12 | #include "obex.h" | ||
13 | #include "obexsend.h" | ||
14 | |||
15 | using namespace OpieObex; | ||
16 | |||
17 | |||
18 | SendWidget::SendWidget( QWidget* parent, const char* name ) | ||
19 | : QWidget( parent, name ) { | ||
20 | initUI(); | ||
21 | } | ||
22 | SendWidget::~SendWidget() { | ||
23 | } | ||
24 | void SendWidget::initUI() { | ||
25 | m_obex = new Obex(this, "obex"); | ||
26 | connect(m_obex, SIGNAL(error(int) ), | ||
27 | this, SLOT(slotIrError(int) ) ); | ||
28 | connect(m_obex, SIGNAL(sent(bool) ), | ||
29 | this, SLOT(slotIrSent(bool) ) ); | ||
30 | connect(m_obex, SIGNAL(currentTry(unsigned int ) ), | ||
31 | this, SLOT(slotIrTry(unsigned int ) ) ); | ||
32 | |||
33 | QCopChannel* chan = new QCopChannel("QPE/IrDaAppletBack", this ); | ||
34 | connect(chan, SIGNAL(received(const QCString&, const QByteArray& ) ), | ||
35 | this, SLOT(dispatchBt(const QCString&, const QByteArray& ) ) ); | ||
36 | |||
37 | chan = new QCopChannel("QPE/BluetoothBack", this ); | ||
38 | connect(chan, SIGNAL(received(const QCString&, const QByteArray& ) ), | ||
39 | this, SLOT(dispatchIrda(const QCString&, const QByteArray& ) ) ); | ||
40 | |||
41 | QVBoxLayout* lay = new QVBoxLayout(this); | ||
42 | |||
43 | QHBox* nameBox = new QHBox(this); | ||
44 | QLabel* name = new QLabel(nameBox); | ||
45 | name->setText( tr("<qt><h1>Sending:</h1></qt>") ); | ||
46 | name->setAlignment( AlignLeft | AlignTop ); | ||
47 | m_lblFile = new QLabel(nameBox); | ||
48 | lay->addWidget(nameBox, 0); | ||
49 | |||
50 | QFrame* frame = new QFrame(this); | ||
51 | frame->setFrameShape( QFrame::HLine ); | ||
52 | frame->setFrameShadow( QFrame::Sunken ); | ||
53 | lay->addWidget(frame, 10); | ||
54 | |||
55 | QLabel* devices = new QLabel(this); | ||
56 | devices->setText("<qt><b>Devices:</b></qt>"); | ||
57 | devices->setAlignment( AlignLeft | AlignTop ); | ||
58 | lay->addWidget( devices,10 ); | ||
59 | |||
60 | m_devBox = new DeviceBox(this); | ||
61 | lay->addWidget( m_devBox, 50 ); | ||
62 | connect(m_devBox, SIGNAL(selectedDevice(const QString&, int ) ), | ||
63 | this, SLOT(slotSelectedDevice(const QString&, int) ) ); | ||
64 | |||
65 | QPushButton *but = new QPushButton(this); | ||
66 | but->setText(tr("Done") ); | ||
67 | connect(but, SIGNAL(clicked() ), | ||
68 | this, SLOT(slotDone() ) ); | ||
69 | |||
70 | lay->addWidget( but ); | ||
71 | m_lay = lay; | ||
72 | |||
73 | // QT does not like if you add items to an layout which already exits.... | ||
74 | // and was layouted invalidate() does not help too | ||
75 | // so we use RichText.... | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * in send we'll first set everything up | ||
80 | * and then wait for a list of devices. | ||
81 | */ | ||
82 | void SendWidget::send( const QString& file, const QString& desc ) { | ||
83 | m_file = file; | ||
84 | m_irDa.clear(); | ||
85 | m_start = 0; | ||
86 | m_lblFile->setText(desc.isEmpty() ? file : desc ); | ||
87 | |||
88 | if ( !QCopChannel::isRegistered("QPE/IrDaApplet") ) { | ||
89 | m_devBox->addDevice( tr("IrDa is not enabled!"), DeviceBox::Error ); | ||
90 | m_start++; | ||
91 | }else | ||
92 | m_devBox->addDevice( tr("Searching for IrDa Devices."), DeviceBox::Search ); | ||
93 | |||
94 | if ( !QCopChannel::isRegistered("QPE/Bluetooth") ) { | ||
95 | m_devBox->addDevice( tr("Bluetooth is not available"), DeviceBox::Error ); | ||
96 | m_start++; | ||
97 | }else | ||
98 | m_devBox->addDevice( tr("Searching for bluetooth Devices."), DeviceBox::Search ); | ||
99 | |||
100 | if (m_start != 2 ) { | ||
101 | QCopEnvelope e0("QPE/IrDaApplet", "enableIrda()"); | ||
102 | QCopEnvelope e1("QPE/Bluetooth", "enableBluetooth()"); | ||
103 | QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); | ||
104 | QCopEnvelope e3("QPE/Bluetooth", "listDevices()"); | ||
105 | } | ||
106 | QTimer::singleShot(5000, this, SLOT(testIt() ) ); | ||
107 | } | ||
108 | void SendWidget::slotIrDaDevices( const QStringList& list) { | ||
109 | m_irDa = list; | ||
110 | m_start = 0; | ||
111 | for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) | ||
112 | m_devBox->addDevice( (*it), DeviceBox::IrDa, tr("Scheduling for beam.") ); | ||
113 | m_devBox->removeDevice( tr("Search for IrDa Devices.") ); | ||
114 | |||
115 | slotStartIrda(); | ||
116 | } | ||
117 | void SendWidget::slotBTDevices( const QMap<QString, QString>& str ) { | ||
118 | m_bt = str; | ||
119 | for(QMap<QString, QString>::ConstIterator it = str.begin(); it != str.end(); ++it ) { | ||
120 | m_devBox->addDevice( it.key(), DeviceBox::BT, tr("Click to beam") ); | ||
121 | } | ||
122 | m_devBox->removeDevice( tr("Searching for bluetooth Devices.") ); | ||
123 | } | ||
124 | void SendWidget::slotSelectedDevice( const QString& name, int dev ) { | ||
125 | qWarning("Start beam? %s %d", name.latin1(), dev ); | ||
126 | if ( name == tr("Search again for IrDa.") ) { | ||
127 | for (QStringList::Iterator it= m_irDa.begin(); it != m_irDa.end(); ++it ) | ||
128 | m_devBox->removeDevice( (*it) ); | ||
129 | QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); | ||
130 | } | ||
131 | } | ||
132 | void SendWidget::dispatchIrda( const QCString& str, const QByteArray& ar ) { | ||
133 | qWarning("dispatch irda %s", str.data() ); | ||
134 | if ( str == "listDevices(QStringList)" ) { | ||
135 | QDataStream stream( ar, IO_ReadOnly ); | ||
136 | QStringList list; | ||
137 | stream >> list; | ||
138 | slotIrDaDevices( list ); | ||
139 | } | ||
140 | } | ||
141 | void SendWidget::dispatchBt( const QCString& str, const QByteArray& ar ) { | ||
142 | |||
143 | } | ||
144 | void SendWidget::slotIrError( int ) { | ||
145 | |||
146 | } | ||
147 | void SendWidget::slotIrSent( bool b) { | ||
148 | QString text = b ? tr("Sent") : tr("Failure"); | ||
149 | m_devBox->setStatus( m_irDa[m_start], text ); | ||
150 | m_start++; | ||
151 | slotStartIrda(); | ||
152 | } | ||
153 | void SendWidget::slotIrTry(unsigned int trI) { | ||
154 | m_devBox->setStatus( m_irDa[m_start], tr("Try %1").arg( QString::number( trI ) ) ); | ||
155 | } | ||
156 | void SendWidget::slotStartIrda() { | ||
157 | if (m_start >= m_irDa.count() ) { | ||
158 | m_devBox->addDevice(tr("Search again for IrDa."), DeviceBox::Search ); | ||
159 | return; | ||
160 | } | ||
161 | m_devBox->setStatus( m_irDa[m_start], tr("Start sending") ); | ||
162 | m_obex->send( m_file ); | ||
163 | } | ||
164 | void SendWidget::slotDone() { | ||
165 | QCopEnvelope e0("QPE/IrDaApplet", "disableIrda()"); | ||
166 | QCopEnvelope e1("QPE/Bluetooth", "disableBluetooth()"); | ||
167 | emit done(); | ||
168 | } | ||
169 | QString SendWidget::file()const { | ||
170 | return m_file; | ||
171 | } | ||
172 | DeviceBox::DeviceBox( QWidget* parent ) | ||
173 | : QTextBrowser( parent ) { | ||
174 | |||
175 | } | ||
176 | DeviceBox::~DeviceBox() { | ||
177 | |||
178 | } | ||
179 | void DeviceBox::addDevice( const QString& name, int dev, const QString& status ) { | ||
180 | QString tex; | ||
181 | DeviceItem item( name, status, dev ); | ||
182 | m_dev.insert( name, item ); | ||
183 | tex = item.toString(); | ||
184 | m_devices.prepend(tex); | ||
185 | setText( text()+ "<br>"+tex ); | ||
186 | } | ||
187 | void DeviceBox::removeDevice( const QString& name ) { | ||
188 | if (!m_dev.contains(name) ) return; | ||
189 | m_devices.remove( m_dev[name].toString() ); | ||
190 | |||
191 | m_dev.remove(name); | ||
192 | setText( m_devices.join("<br>") ); | ||
193 | |||
194 | } | ||
195 | void DeviceBox::setStatus( const QString& name, const QString& status ) { | ||
196 | if ( !m_dev.contains(name) ) return; | ||
197 | DeviceItem dev = m_dev[name]; | ||
198 | QString ole = dev.toString(); | ||
199 | dev.setStatus( status ); | ||
200 | int index = m_devices.findIndex( ole ); | ||
201 | m_devices[index] = dev.toString(); | ||
202 | setText( m_devices.join("<br>") ); | ||
203 | } | ||
204 | void DeviceBox::setSource( const QString& str ) { | ||
205 | qWarning("SetSource:%s", str.latin1() ); | ||
206 | emit selectedDevice( str, m_dev[str].device() ); | ||
207 | } | ||
208 | |||
209 | |||
210 | DeviceItem::DeviceItem( const QString& name, | ||
211 | const QString& status, int dev) | ||
212 | { | ||
213 | m_name = name; | ||
214 | m_status = status; | ||
215 | m_dev = dev; | ||
216 | } | ||
217 | QString DeviceItem::name()const { | ||
218 | return m_name; | ||
219 | } | ||
220 | QString DeviceItem::status()const { | ||
221 | return m_status; | ||
222 | } | ||
223 | int DeviceItem::device()const { | ||
224 | return m_dev; | ||
225 | } | ||
226 | QString DeviceItem::pixmap()const{ | ||
227 | QString str; | ||
228 | switch(m_dev) { | ||
229 | case DeviceBox::IrDa: | ||
230 | str ="obex/irda"; | ||
231 | break; | ||
232 | case DeviceBox::BT: | ||
233 | str ="obex/bt"; | ||
234 | break; | ||
235 | case DeviceBox::Search: | ||
236 | str = "obex/search"; | ||
237 | break; | ||
238 | case DeviceBox::Error: | ||
239 | str = "editdelete"; | ||
240 | break; | ||
241 | }; | ||
242 | return str; | ||
243 | } | ||
244 | DeviceItem::~DeviceItem() { | ||
245 | } | ||
246 | void DeviceItem::setStatus(const QString& status ) { | ||
247 | m_status = status; | ||
248 | } | ||
249 | QString DeviceItem::toString()const { | ||
250 | return "<p><a href=\""+m_name +"\" ><img src=\""+pixmap()+"\" >"+m_name+" "+m_status+" </a></p>" ; | ||
251 | } | ||
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 @@ | |||
1 | #ifndef OPIE_OBEX_SEND_WIDGET_H | ||
2 | #define OPIE_OBEX_SEND_WIDGET_H | ||
3 | |||
4 | #include <qstring.h> | ||
5 | #include <qstringlist.h> | ||
6 | #include <qwidget.h> | ||
7 | #include <qvbox.h> | ||
8 | #include <qmap.h> | ||
9 | #include <qtextbrowser.h> | ||
10 | |||
11 | class QLabel; | ||
12 | class QVBoxLayout; | ||
13 | /** | ||
14 | * This is the new sending widget for Obex | ||
15 | * It will attemp to smart and be able to send | ||
16 | * it to multiple devices. | ||
17 | * It'll support BT + IrDa | ||
18 | */ | ||
19 | namespace OpieObex { | ||
20 | class DeviceBox; | ||
21 | class Obex; | ||
22 | class SendWidget : public QWidget{ | ||
23 | Q_OBJECT | ||
24 | public: | ||
25 | SendWidget( QWidget* parent = 0, const char* name = 0); | ||
26 | ~SendWidget(); | ||
27 | |||
28 | QString file()const; | ||
29 | |||
30 | public slots: | ||
31 | void send( const QString& file, const QString& desc ); | ||
32 | |||
33 | signals: | ||
34 | void done(); | ||
35 | |||
36 | private slots: // QCOP slots | ||
37 | /* IrDa Names*/ | ||
38 | void slotIrDaDevices( const QStringList& ); | ||
39 | /* Bt Names + BD-Addr */ | ||
40 | void slotBTDevices( const QMap<QString, QString>& ); | ||
41 | void slotSelectedDevice( const QString& name, int dev ); | ||
42 | void dispatchIrda( const QCString& str, const QByteArray& ar ); | ||
43 | void dispatchBt( const QCString& str, const QByteArray& ar ); | ||
44 | |||
45 | void slotIrError( int ); | ||
46 | void slotIrSent(bool); | ||
47 | void slotIrTry(unsigned int ); | ||
48 | void slotStartIrda(); | ||
49 | void slotDone(); | ||
50 | private: | ||
51 | void initUI(); | ||
52 | QLabel* m_lblFile; | ||
53 | DeviceBox* m_devBox; | ||
54 | QVBoxLayout* m_lay; | ||
55 | int m_start; | ||
56 | QStringList m_irDa; | ||
57 | QMap<QString, QString> m_bt; | ||
58 | QString m_file; | ||
59 | Obex* m_obex; | ||
60 | }; | ||
61 | class DeviceItem { | ||
62 | public: | ||
63 | DeviceItem( const QString& name = QString::null, | ||
64 | const QString& status = QString::null, int dev = 3); | ||
65 | ~DeviceItem(); | ||
66 | void setStatus( const QString& text ); | ||
67 | |||
68 | QString name()const; | ||
69 | QString status()const; | ||
70 | QString pixmap()const; | ||
71 | int device()const; | ||
72 | QString toString()const; | ||
73 | private: | ||
74 | QString m_name; | ||
75 | QString m_status; | ||
76 | int m_dev; | ||
77 | }; | ||
78 | class DeviceBox : public QTextBrowser { | ||
79 | Q_OBJECT | ||
80 | public: | ||
81 | enum Device { IrDa, BT, Search, Error }; | ||
82 | DeviceBox( QWidget* parent ); | ||
83 | ~DeviceBox(); | ||
84 | |||
85 | void setSource( const QString& str ); | ||
86 | void addDevice( const QString& name, int dev, | ||
87 | const QString& status = QString::null ); | ||
88 | void removeDevice( const QString& name ); | ||
89 | void setStatus( const QString& name, const QString& ); | ||
90 | signals: | ||
91 | void selectedDevice( const QString& name, int dev ); | ||
92 | private: | ||
93 | QMap<QString, DeviceItem> m_dev; | ||
94 | QStringList m_devices; | ||
95 | |||
96 | }; | ||
97 | } | ||
98 | |||
99 | #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 @@ | |||
1 | #include <sys/types.h> | ||
2 | #include <sys/stat.h> | ||
3 | #include <sys/mman.h> | ||
4 | #include <unistd.h> | ||
5 | |||
6 | #include <fcntl.h> | ||
7 | |||
8 | #include <qfile.h> | ||
9 | #include <qfileinfo.h> | ||
10 | #include <qlabel.h> | ||
11 | #include <qhbox.h> | ||
12 | #include <qtextview.h> | ||
13 | #include <qpushbutton.h> | ||
14 | |||
15 | #include <qpe/applnk.h> | ||
16 | #include <qpe/qpeapplication.h> | ||
17 | #include <qpe/qcopenvelope_qws.h> | ||
18 | |||
19 | #include "obex.h" | ||
20 | #include "receiver.h" | ||
21 | |||
22 | using namespace OpieObex; | ||
23 | |||
24 | Receiver::Receiver() { | ||
25 | m_obex = new Obex(this, "Receiver"); | ||
26 | connect(m_obex, SIGNAL(receivedFile(const QString& ) ), | ||
27 | this, SLOT(slotReceived(const QString& ) ) ); | ||
28 | m_obex->receive(); | ||
29 | } | ||
30 | Receiver::~Receiver() { | ||
31 | m_obex->setReceiveEnabled( false ); | ||
32 | delete m_obex; | ||
33 | } | ||
34 | void Receiver::slotReceived( const QString& file ) { | ||
35 | int check = checkFile(file); | ||
36 | if ( check == AddressBook ) | ||
37 | handleAddr( file ); | ||
38 | else if ( check == Datebook ) | ||
39 | handleDateTodo( file ); | ||
40 | else | ||
41 | handleOther( file ); | ||
42 | } | ||
43 | void Receiver::handleAddr( const QString& str ) { | ||
44 | QCopEnvelope e("QPE/Application/addressbook", "setDocument(QString)" ); | ||
45 | e << str; | ||
46 | } | ||
47 | /* we can not say for sure if it's a VEevent ot VTodo */ | ||
48 | void Receiver::handleDateTodo( const QString& str ) { | ||
49 | QCopEnvelope e0("QPE/Application/todolist", "setDocument(QString)"); | ||
50 | e0 << str; | ||
51 | QCopEnvelope e1("QPE/Application/datebook", "setDocument(QString)" ); | ||
52 | e1 << str; | ||
53 | } | ||
54 | /* | ||
55 | * Handle other asks if it should accept the | ||
56 | * beamed object and creates a DocLnk | ||
57 | */ | ||
58 | void Receiver::handleOther( const QString& other ) { | ||
59 | OtherHandler* hand = new OtherHandler(); | ||
60 | hand->handle( other ); | ||
61 | } | ||
62 | int Receiver::checkFile( const QString& file ) { | ||
63 | int ret; | ||
64 | if (file.right(4) == ".vcs" ) { | ||
65 | ret = Datebook; | ||
66 | }else if ( file.right(4) == ".vcf") { | ||
67 | ret = AddressBook; | ||
68 | }else | ||
69 | ret = Other; | ||
70 | |||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | OtherHandler::OtherHandler() | ||
75 | : QVBox() | ||
76 | { | ||
77 | QHBox* box = new QHBox(this); | ||
78 | QLabel* lbl = new QLabel(box); | ||
79 | lbl->setText(tr("<qt><b>Received:</b></qt>")); | ||
80 | m_na = new QLabel(box); | ||
81 | |||
82 | QFrame* frame = new QFrame(this); | ||
83 | frame->setFrameShape( QFrame::HLine ); | ||
84 | frame->setFrameShadow( QFrame::Sunken ); | ||
85 | |||
86 | m_view = new QTextView(this); | ||
87 | |||
88 | box = new QHBox(this); | ||
89 | QPushButton *but = new QPushButton(box); | ||
90 | but->setText(tr("Accept") ); | ||
91 | connect(but, SIGNAL(clicked() ), | ||
92 | this, SLOT(accept()) ); | ||
93 | |||
94 | but = new QPushButton(box); | ||
95 | but->setText(tr("Deny") ); | ||
96 | connect(but, SIGNAL(clicked() ), | ||
97 | this, SLOT(deny() ) ); | ||
98 | |||
99 | raise(); | ||
100 | showMaximized(); | ||
101 | } | ||
102 | OtherHandler::~OtherHandler() { | ||
103 | |||
104 | } | ||
105 | void OtherHandler::handle( const QString& file ) { | ||
106 | m_file = file; | ||
107 | m_na->setText(file); | ||
108 | DocLnk lnk(file); | ||
109 | |||
110 | QString str = tr("<p>You received a file of type %1 (<img src=\"%2\"> )What do you want to do?").arg(lnk.type() ).arg(lnk.icon() ); | ||
111 | m_view->setText( str ); | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * hehe evil evil mmap ahead :) | ||
116 | * we quickly copy the file and then we'll create a DocLnk for it | ||
117 | */ | ||
118 | void OtherHandler::accept() { | ||
119 | QString na = targetName( m_file ); | ||
120 | copy(m_file, na ); | ||
121 | DocLnk lnk(na); | ||
122 | lnk.writeLink(); | ||
123 | QFile::remove(m_file); | ||
124 | delete this; | ||
125 | } | ||
126 | void OtherHandler::deny() { | ||
127 | QFile::remove( m_file ); | ||
128 | delete this; | ||
129 | } | ||
130 | QString OtherHandler::targetName( const QString& file ) { | ||
131 | QFileInfo info( file ); | ||
132 | QString newFile = QPEApplication::documentDir()+ "/"+ info.baseName(); | ||
133 | QString newFileBase = newFile; | ||
134 | |||
135 | int trie = 0; | ||
136 | while (QFile::exists(newFile + info.extension() ) ) { | ||
137 | newFile = newFileBase + "_"+QString::number(trie) ; | ||
138 | trie++; | ||
139 | } | ||
140 | newFile += info.extension(); | ||
141 | |||
142 | return newFile; | ||
143 | } | ||
144 | |||
145 | /* fast cpy */ | ||
146 | void OtherHandler::copy(const QString& src, const QString& file) { | ||
147 | int src_fd = ::open( QFile::encodeName( src ), O_RDONLY ); | ||
148 | int to_fd = ::open( QFile::encodeName( file), O_RDWR| O_CREAT| O_TRUNC, | ||
149 | S_IRUSR, S_IWUSR, S_IRGRP, S_IRGRP ); | ||
150 | |||
151 | struct stat stater; | ||
152 | ::fstat(src_fd, &stater ); | ||
153 | ::lseek(to_fd, stater.st_size-1, SEEK_SET ); | ||
154 | |||
155 | void *src_addr, *dest_addr; | ||
156 | src_addr = ::mmap(0, stater.st_size, PROT_READ, | ||
157 | MAP_FILE | MAP_SHARED, src_fd, 0 ); | ||
158 | dest_addr= ::mmap(0, stater.st_size, PROT_READ | PROT_WRITE, | ||
159 | MAP_FILE | MAP_PRIVATE, to_fd, 0 ); | ||
160 | |||
161 | ::memcpy(src_addr , dest_addr, stater.st_size ); | ||
162 | ::munmap(src_addr , stater.st_size ); | ||
163 | ::munmap(dest_addr, stater.st_size ); | ||
164 | |||
165 | // done | ||
166 | } | ||
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 @@ | |||
1 | #ifndef OPIE_OBEX_RECEIVER_H | ||
2 | #define OPIE_OBEX_RECEIVER_H | ||
3 | |||
4 | #include <qobject.h> | ||
5 | #include <qvbox.h> | ||
6 | #include <qstring.h> | ||
7 | |||
8 | class QLabel; | ||
9 | class QTextView; | ||
10 | namespace OpieObex { | ||
11 | class Obex; | ||
12 | class OtherHandler; | ||
13 | class Receiver : public QObject { | ||
14 | Q_OBJECT | ||
15 | public: | ||
16 | enum { Datebook , AddressBook, Other }; | ||
17 | Receiver(); | ||
18 | ~Receiver(); | ||
19 | |||
20 | private: | ||
21 | void handleAddr(const QString& ); | ||
22 | void handleDateTodo(const QString& ); | ||
23 | void handleOther(const QString& ); | ||
24 | int checkFile( const QString& file ); | ||
25 | bool testDateTodo(const QString& file); | ||
26 | bool testAddressbook(const QString& file); | ||
27 | |||
28 | private slots: | ||
29 | void slotReceived( const QString& ); | ||
30 | |||
31 | private: | ||
32 | Obex* m_obex; | ||
33 | }; | ||
34 | |||
35 | class OtherHandler : public QVBox { | ||
36 | Q_OBJECT | ||
37 | public: | ||
38 | OtherHandler(); | ||
39 | ~OtherHandler(); | ||
40 | |||
41 | void handle( const QString& file ); | ||
42 | private slots: | ||
43 | void accept(); | ||
44 | void deny(); | ||
45 | private: | ||
46 | QString targetName( const QString& file ); | ||
47 | void copy( const QString& src, const QString& dest ); | ||
48 | QLabel* m_na; | ||
49 | QTextView* m_view; | ||
50 | QString m_file; | ||
51 | }; | ||
52 | } | ||
53 | |||
54 | |||
55 | #endif | ||