-rw-r--r-- | core/obex/obex.cc | 28 | ||||
-rw-r--r-- | core/obex/obexsend.cpp | 7 | ||||
-rw-r--r-- | core/obex/receiver.cpp | 18 |
3 files changed, 9 insertions, 44 deletions
diff --git a/core/obex/obex.cc b/core/obex/obex.cc index 7c40b90..5dfcfb5 100644 --- a/core/obex/obex.cc +++ b/core/obex/obex.cc | |||
@@ -1,205 +1,185 @@ | |||
1 | 1 | ||
2 | #include "obex.h" | 2 | #include "obex.h" |
3 | 3 | ||
4 | /* OPIE */ | 4 | /* OPIE */ |
5 | #include <opie2/oprocess.h> | 5 | #include <opie2/oprocess.h> |
6 | #include <opie2/odebug.h> | 6 | #include <opie2/odebug.h> |
7 | 7 | ||
8 | /* QT */ | 8 | /* QT */ |
9 | #include <qfileinfo.h> | 9 | #include <qfileinfo.h> |
10 | 10 | ||
11 | 11 | ||
12 | 12 | ||
13 | using namespace OpieObex; | 13 | using namespace OpieObex; |
14 | 14 | ||
15 | using namespace Opie::Core; | 15 | using namespace Opie::Core; |
16 | /* TRANSLATOR OpieObex::Obex */ | 16 | /* TRANSLATOR OpieObex::Obex */ |
17 | 17 | ||
18 | Obex::Obex( QObject *parent, const char* name ) | 18 | Obex::Obex( QObject *parent, const char* name ) |
19 | : QObject(parent, name ) | 19 | : QObject(parent, name ) |
20 | { | 20 | { |
21 | m_rec = 0; | 21 | m_rec = 0; |
22 | m_send=0; | 22 | m_send=0; |
23 | m_count = 0; | 23 | m_count = 0; |
24 | m_receive = false; | 24 | m_receive = false; |
25 | connect( this, SIGNAL(error(int) ), // for recovering to receive | 25 | connect( this, SIGNAL(error(int) ), // for recovering to receive |
26 | SLOT(slotError() ) ); | 26 | SLOT(slotError() ) ); |
27 | connect( this, SIGNAL(sent(bool) ), | 27 | connect( this, SIGNAL(sent(bool) ), |
28 | SLOT(slotError() ) ); | 28 | SLOT(slotError() ) ); |
29 | }; | 29 | }; |
30 | Obex::~Obex() { | 30 | Obex::~Obex() { |
31 | delete m_rec; | 31 | delete m_rec; |
32 | delete m_send; | 32 | delete m_send; |
33 | } | 33 | } |
34 | void Obex::receive() { | 34 | void Obex::receive() { |
35 | m_receive = true; | 35 | m_receive = true; |
36 | m_outp = QString::null; | 36 | m_outp = QString::null; |
37 | owarn << "Receive" << oendl; | ||
38 | m_rec = new OProcess(); | 37 | m_rec = new OProcess(); |
39 | *m_rec << "irobex_palm3"; | 38 | *m_rec << "irobex_palm3"; |
40 | // connect to the necessary slots | 39 | // connect to the necessary slots |
41 | connect(m_rec, SIGNAL(processExited(Opie::Core::OProcess*) ), | 40 | connect(m_rec, SIGNAL(processExited(Opie::Core::OProcess*) ), |
42 | this, SLOT(slotExited(Opie::Core::OProcess*) ) ); | 41 | this, SLOT(slotExited(Opie::Core::OProcess*) ) ); |
43 | 42 | ||
44 | connect(m_rec, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int ) ), | 43 | connect(m_rec, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int ) ), |
45 | this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) ); | 44 | this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) ); |
46 | 45 | ||
47 | if(!m_rec->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) { | 46 | if(!m_rec->start(OProcess::NotifyOnExit, OProcess::AllOutput) ) { |
48 | owarn << "could not start :(" oendl; | ||
49 | emit done( false ); | 47 | emit done( false ); |
50 | delete m_rec; | 48 | delete m_rec; |
51 | m_rec = 0; | 49 | m_rec = 0; |
52 | } | 50 | } |
53 | // emit currentTry(m_count ); | ||
54 | |||
55 | } | 51 | } |
52 | |||
56 | void Obex::send( const QString& fileName) { // if currently receiving stop it send receive | 53 | void Obex::send( const QString& fileName) { // if currently receiving stop it send receive |
57 | m_count = 0; | 54 | m_count = 0; |
58 | m_file = fileName; | 55 | m_file = fileName; |
59 | owarn << "send " << fileName.latin1() << oendl; | ||
60 | if (m_rec != 0 ) { | 56 | if (m_rec != 0 ) { |
61 | owarn << "running" oendl; | ||
62 | if (m_rec->isRunning() ) { | 57 | if (m_rec->isRunning() ) { |
63 | emit error(-1 ); | 58 | emit error(-1 ); |
64 | owarn << "is running" << oendl; | ||
65 | delete m_rec; | 59 | delete m_rec; |
66 | m_rec = 0; | 60 | m_rec = 0; |
67 | 61 | ||
68 | }else{ | 62 | }else{ |
69 | owarn << "is not running" << oendl; | ||
70 | emit error( -1 ); // we did not delete yet but it's not running slotExited is pending | 63 | emit error( -1 ); // we did not delete yet but it's not running slotExited is pending |
71 | return; | 64 | return; |
72 | } | 65 | } |
73 | } | 66 | } |
74 | sendNow(); | 67 | sendNow(); |
75 | } | 68 | } |
76 | void Obex::sendNow(){ | 69 | void Obex::sendNow(){ |
77 | owarn << "sendNow" << oendl; | ||
78 | if ( m_count >= 25 ) { // could not send | 70 | if ( m_count >= 25 ) { // could not send |
79 | emit error(-1 ); | 71 | emit error(-1 ); |
80 | emit sent(false); | 72 | emit sent(false); |
81 | return; | 73 | return; |
82 | } | 74 | } |
83 | // OProcess inititialisation | 75 | // OProcess inititialisation |
84 | m_send = new OProcess(); | 76 | m_send = new OProcess(); |
85 | *m_send << "irobex_palm3"; | 77 | *m_send << "irobex_palm3"; |
86 | *m_send << QFile::encodeName(m_file); | 78 | *m_send << QFile::encodeName(m_file); |
87 | 79 | ||
88 | // connect to slots Exited and and StdOut | 80 | // connect to slots Exited and and StdOut |
89 | connect(m_send, SIGNAL(processExited(Opie::Core::OProcess*) ), | 81 | connect(m_send, SIGNAL(processExited(Opie::Core::OProcess*) ), |
90 | this, SLOT(slotExited(Opie::Core::OProcess*)) ); | 82 | this, SLOT(slotExited(Opie::Core::OProcess*)) ); |
91 | connect(m_send, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int )), | 83 | connect(m_send, SIGNAL(receivedStdout(Opie::Core::OProcess*, char*, int )), |
92 | this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) ); | 84 | this, SLOT(slotStdOut(Opie::Core::OProcess*, char*, int) ) ); |
93 | 85 | ||
94 | // now start it | 86 | // now start it |
95 | if (!m_send->start(/*OProcess::NotifyOnExit, OProcess::AllOutput*/ ) ) { | 87 | if (!m_send->start(/*OProcess::NotifyOnExit, OProcess::AllOutput*/ ) ) { |
96 | owarn << "could not send" << oendl; | ||
97 | m_count = 25; | 88 | m_count = 25; |
98 | emit error(-1 ); | 89 | emit error(-1 ); |
99 | delete m_send; | 90 | delete m_send; |
100 | m_send=0; | 91 | m_send=0; |
101 | } | 92 | } |
102 | // end | 93 | // end |
103 | m_count++; | 94 | m_count++; |
104 | emit currentTry( m_count ); | 95 | emit currentTry( m_count ); |
105 | } | 96 | } |
106 | 97 | ||
107 | void Obex::slotExited(OProcess* proc ){ | 98 | void Obex::slotExited(OProcess* proc ){ |
108 | if (proc == m_rec ) { // receive process | 99 | if (proc == m_rec ) // receive process |
109 | received(); | 100 | received(); |
110 | }else if ( proc == m_send ) { | 101 | else if ( proc == m_send ) |
111 | sendEnd(); | 102 | sendEnd(); |
112 | } | 103 | |
113 | } | 104 | } |
114 | void Obex::slotStdOut(OProcess* proc, char* buf, int len){ | 105 | void Obex::slotStdOut(OProcess* proc, char* buf, int len){ |
115 | if ( proc == m_rec ) { // only receive | 106 | if ( proc == m_rec ) { // only receive |
116 | QByteArray ar( len ); | 107 | QByteArray ar( len ); |
117 | memcpy( ar.data(), buf, len ); | 108 | memcpy( ar.data(), buf, len ); |
118 | owarn << "parsed: " << ar.data() << oendl; | ||
119 | m_outp.append( ar ); | 109 | m_outp.append( ar ); |
120 | } | 110 | } |
121 | } | 111 | } |
122 | 112 | ||
123 | void Obex::received() { | 113 | void Obex::received() { |
124 | if (m_rec->normalExit() ) { | 114 | if (m_rec->normalExit() ) { |
125 | if ( m_rec->exitStatus() == 0 ) { // we got one | 115 | if ( m_rec->exitStatus() == 0 ) { // we got one |
126 | QString filename = parseOut(); | 116 | QString filename = parseOut(); |
127 | owarn << "ACHTUNG " << filename.latin1() << oendl; | ||
128 | emit receivedFile( filename ); | 117 | emit receivedFile( filename ); |
129 | } | 118 | } |
130 | }else{ | 119 | }else{ |
131 | emit done(false); | 120 | emit done(false); |
132 | }; | 121 | }; |
133 | delete m_rec; | 122 | delete m_rec; |
134 | m_rec = 0; | 123 | m_rec = 0; |
135 | receive(); | 124 | receive(); |
136 | } | 125 | } |
137 | 126 | ||
138 | void Obex::sendEnd() { | 127 | void Obex::sendEnd() { |
139 | if (m_send->normalExit() ) { | 128 | if (m_send->normalExit() ) { |
140 | if ( m_send->exitStatus() == 0 ) { | 129 | if ( m_send->exitStatus() == 0 ) { |
141 | delete m_send; | 130 | delete m_send; |
142 | m_send=0; | 131 | m_send=0; |
143 | owarn << "done" << oendl; | ||
144 | emit sent(true); | 132 | emit sent(true); |
145 | }else if (m_send->exitStatus() == 255 ) { // it failed maybe the other side wasn't ready | 133 | }else if (m_send->exitStatus() == 255 ) { // it failed maybe the other side wasn't ready |
146 | // let's try it again | 134 | // let's try it again |
147 | delete m_send; | 135 | delete m_send; |
148 | m_send = 0; | 136 | m_send = 0; |
149 | owarn << "try sending again" << oendl; | ||
150 | sendNow(); | 137 | sendNow(); |
151 | } | 138 | } |
152 | }else { | 139 | }else { |
153 | emit error( -1 ); | 140 | emit error( -1 ); |
154 | delete m_send; | 141 | delete m_send; |
155 | m_send = 0; | 142 | m_send = 0; |
156 | } | 143 | } |
157 | } | 144 | } |
158 | QString Obex::parseOut( ){ | 145 | QString Obex::parseOut( ){ |
159 | QString path; | 146 | QString path; |
160 | QStringList list = QStringList::split("\n", m_outp); | 147 | QStringList list = QStringList::split("\n", m_outp); |
161 | QStringList::Iterator it; | 148 | QStringList::Iterator it; |
162 | for (it = list.begin(); it != list.end(); ++it ) { | 149 | for (it = list.begin(); it != list.end(); ++it ) { |
163 | if ( (*it).startsWith("Wrote" ) ) { | 150 | if ( (*it).startsWith("Wrote" ) ) { |
164 | int pos = (*it).findRev('(' ); | 151 | int pos = (*it).findRev('(' ); |
165 | if ( pos > 0 ) { | 152 | if ( pos > 0 ) { |
166 | owarn << pos << " " << (*it).mid(6 ).latin1() << oendl; | ||
167 | owarn << (*it).length() << " " << (*it).length()-pos << oendl; | ||
168 | 153 | ||
169 | path = (*it).remove( pos, (*it).length() - pos ); | 154 | path = (*it).remove( pos, (*it).length() - pos ); |
170 | owarn << path.latin1() << oendl; | ||
171 | path = path.mid(6 ); | 155 | path = path.mid(6 ); |
172 | path = path.stripWhiteSpace(); | 156 | path = path.stripWhiteSpace(); |
173 | owarn << "path " << path.latin1() << oendl; | ||
174 | } | 157 | } |
175 | } | 158 | } |
176 | } | 159 | } |
177 | return path; | 160 | return path; |
178 | } | 161 | } |
179 | /** | 162 | /** |
180 | * when sent is done slotError is called we will start receive again | 163 | * when sent is done slotError is called we will start receive again |
181 | */ | 164 | */ |
182 | void Obex::slotError() { | 165 | void Obex::slotError() { |
183 | owarn << "slotError" << oendl; | ||
184 | if ( m_receive ) | 166 | if ( m_receive ) |
185 | receive(); | 167 | receive(); |
186 | }; | 168 | }; |
187 | void Obex::setReceiveEnabled( bool receive ) { | 169 | void Obex::setReceiveEnabled( bool receive ) { |
188 | if ( !receive ) { // | 170 | if ( !receive ) { // |
189 | m_receive = false; | 171 | m_receive = false; |
190 | shutDownReceive(); | 172 | shutDownReceive(); |
191 | } | 173 | } |
192 | } | 174 | } |
193 | 175 | ||
194 | void Obex::shutDownReceive() { | 176 | void Obex::shutDownReceive() { |
195 | if (m_rec != 0 ) { | 177 | if (m_rec != 0 ) { |
196 | owarn << "running" << oendl; | ||
197 | if (m_rec->isRunning() ) { | 178 | if (m_rec->isRunning() ) { |
198 | emit error(-1 ); | 179 | emit error(-1 ); |
199 | owarn << "is running" << oendl; | ||
200 | delete m_rec; | 180 | delete m_rec; |
201 | m_rec = 0; | 181 | m_rec = 0; |
202 | } | 182 | } |
203 | } | 183 | } |
204 | 184 | ||
205 | } | 185 | } |
diff --git a/core/obex/obexsend.cpp b/core/obex/obexsend.cpp index f3dd11c..675c5e4 100644 --- a/core/obex/obexsend.cpp +++ b/core/obex/obexsend.cpp | |||
@@ -44,229 +44,224 @@ void SendWidget::initUI() { | |||
44 | QLabel* name = new QLabel(nameBox); | 44 | QLabel* name = new QLabel(nameBox); |
45 | name->setText( tr("<qt><h1>Sending:</h1></qt>") ); | 45 | name->setText( tr("<qt><h1>Sending:</h1></qt>") ); |
46 | name->setAlignment( AlignLeft | AlignTop ); | 46 | name->setAlignment( AlignLeft | AlignTop ); |
47 | m_lblFile = new QLabel(nameBox); | 47 | m_lblFile = new QLabel(nameBox); |
48 | lay->addWidget(nameBox, 0); | 48 | lay->addWidget(nameBox, 0); |
49 | 49 | ||
50 | QFrame* frame = new QFrame(this); | 50 | QFrame* frame = new QFrame(this); |
51 | frame->setFrameShape( QFrame::HLine ); | 51 | frame->setFrameShape( QFrame::HLine ); |
52 | frame->setFrameShadow( QFrame::Sunken ); | 52 | frame->setFrameShadow( QFrame::Sunken ); |
53 | lay->addWidget(frame, 10); | 53 | lay->addWidget(frame, 10); |
54 | 54 | ||
55 | QLabel* devices = new QLabel(this); | 55 | QLabel* devices = new QLabel(this); |
56 | devices->setText("<qt><b>Devices:</b></qt>"); | 56 | devices->setText("<qt><b>Devices:</b></qt>"); |
57 | devices->setAlignment( AlignLeft | AlignTop ); | 57 | devices->setAlignment( AlignLeft | AlignTop ); |
58 | lay->addWidget( devices,10 ); | 58 | lay->addWidget( devices,10 ); |
59 | 59 | ||
60 | m_devBox = new DeviceBox(this); | 60 | m_devBox = new DeviceBox(this); |
61 | lay->addWidget( m_devBox, 50 ); | 61 | lay->addWidget( m_devBox, 50 ); |
62 | connect(m_devBox, SIGNAL(selectedDevice(int,int) ), | 62 | connect(m_devBox, SIGNAL(selectedDevice(int,int) ), |
63 | this, SLOT(slotSelectedDevice(int,int) ) ); | 63 | this, SLOT(slotSelectedDevice(int,int) ) ); |
64 | 64 | ||
65 | QPushButton *but = new QPushButton(this); | 65 | QPushButton *but = new QPushButton(this); |
66 | but->setText(tr("Done") ); | 66 | but->setText(tr("Done") ); |
67 | connect(but, SIGNAL(clicked() ), | 67 | connect(but, SIGNAL(clicked() ), |
68 | this, SLOT(slotDone() ) ); | 68 | this, SLOT(slotDone() ) ); |
69 | 69 | ||
70 | lay->addWidget( but ); | 70 | lay->addWidget( but ); |
71 | m_lay = lay; | 71 | m_lay = lay; |
72 | 72 | ||
73 | // QT does not like if you add items to an layout which already exits.... | 73 | // QT does not like if you add items to an layout which already exits.... |
74 | // and was layouted invalidate() does not help too | 74 | // and was layouted invalidate() does not help too |
75 | // so we use RichText.... | 75 | // so we use RichText.... |
76 | } | 76 | } |
77 | 77 | ||
78 | /* | 78 | /* |
79 | * in send we'll first set everything up | 79 | * in send we'll first set everything up |
80 | * and then wait for a list of devices. | 80 | * and then wait for a list of devices. |
81 | */ | 81 | */ |
82 | void SendWidget::send( const QString& file, const QString& desc ) { | 82 | void SendWidget::send( const QString& file, const QString& desc ) { |
83 | m_file = file; | 83 | m_file = file; |
84 | m_irDa.clear(); | 84 | m_irDa.clear(); |
85 | m_start = 0; | 85 | m_start = 0; |
86 | m_lblFile->setText(desc.isEmpty() ? file : desc ); | 86 | m_lblFile->setText(desc.isEmpty() ? file : desc ); |
87 | 87 | ||
88 | if ( !QCopChannel::isRegistered("QPE/IrDaApplet") ) { | 88 | if ( !QCopChannel::isRegistered("QPE/IrDaApplet") ) { |
89 | m_irDeSearch = m_devBox->addDevice( tr("IrDa is not enabled!"), DeviceBox::Error ); | 89 | m_irDeSearch = m_devBox->addDevice( tr("IrDa is not enabled!"), DeviceBox::Error ); |
90 | m_start++; | 90 | m_start++; |
91 | }else | 91 | }else |
92 | m_irDeSearch = m_devBox->addDevice( tr("Searching for IrDa Devices."), DeviceBox::Search ); | 92 | m_irDeSearch = m_devBox->addDevice( tr("Searching for IrDa Devices."), DeviceBox::Search ); |
93 | 93 | ||
94 | if ( !QCopChannel::isRegistered("QPE/Bluetooth") ) { | 94 | if ( !QCopChannel::isRegistered("QPE/Bluetooth") ) { |
95 | m_btDeSearch = m_devBox->addDevice( tr("Bluetooth is not available"), DeviceBox::Error ); | 95 | m_btDeSearch = m_devBox->addDevice( tr("Bluetooth is not available"), DeviceBox::Error ); |
96 | m_start++; | 96 | m_start++; |
97 | }else | 97 | }else |
98 | m_btDeSearch = m_devBox->addDevice( tr("Searching for bluetooth Devices."), DeviceBox::Search ); | 98 | m_btDeSearch = m_devBox->addDevice( tr("Searching for bluetooth Devices."), DeviceBox::Search ); |
99 | 99 | ||
100 | if (m_start != 2 ) { | 100 | if (m_start != 2 ) { |
101 | QCopEnvelope e0("QPE/IrDaApplet", "enableIrda()"); | 101 | QCopEnvelope e0("QPE/IrDaApplet", "enableIrda()"); |
102 | QCopEnvelope e1("QPE/Bluetooth", "enableBluetooth()"); | 102 | QCopEnvelope e1("QPE/Bluetooth", "enableBluetooth()"); |
103 | QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); | 103 | QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); |
104 | QCopEnvelope e3("QPE/Bluetooth", "listDevices()"); | 104 | QCopEnvelope e3("QPE/Bluetooth", "listDevices()"); |
105 | } | 105 | } |
106 | } | 106 | } |
107 | void SendWidget::slotIrDaDevices( const QStringList& list) { | 107 | void SendWidget::slotIrDaDevices( const QStringList& list) { |
108 | owarn << "slot it irda devices " << oendl; | ||
109 | for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) { | 108 | for (QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) { |
110 | int id = m_devBox->addDevice( (*it), DeviceBox::IrDa, tr("Scheduling for beam.") ); | 109 | int id = m_devBox->addDevice( (*it), DeviceBox::IrDa, tr("Scheduling for beam.") ); |
111 | m_irDa.insert( id, (*it) ); | 110 | m_irDa.insert( id, (*it) ); |
112 | } | 111 | } |
113 | m_devBox->removeDevice( m_irDeSearch ); | 112 | m_devBox->removeDevice( m_irDeSearch ); |
114 | m_irDaIt = m_irDa.begin(); | 113 | m_irDaIt = m_irDa.begin(); |
115 | 114 | ||
116 | slotStartIrda(); | 115 | slotStartIrda(); |
117 | } | 116 | } |
118 | 117 | ||
119 | void SendWidget::slotBTDevices( const QMap<QString, QString>& str ) { | 118 | void SendWidget::slotBTDevices( const QMap<QString, QString>& str ) { |
120 | for(QMap<QString, QString>::ConstIterator it = str.begin(); it != str.end(); ++it ) { | 119 | for(QMap<QString, QString>::ConstIterator it = str.begin(); it != str.end(); ++it ) { |
121 | int id = m_devBox->addDevice( it.key(), DeviceBox::BT, tr("Click to beam") ); | 120 | int id = m_devBox->addDevice( it.key(), DeviceBox::BT, tr("Click to beam") ); |
122 | m_bt.insert( id, Pair( it.key(), it.data() ) ); | 121 | m_bt.insert( id, Pair( it.key(), it.data() ) ); |
123 | } | 122 | } |
124 | m_devBox->removeDevice( m_btDeSearch ); | 123 | m_devBox->removeDevice( m_btDeSearch ); |
125 | } | 124 | } |
126 | void SendWidget::slotSelectedDevice( int name, int dev ) { | 125 | void SendWidget::slotSelectedDevice( int name, int ) { |
127 | owarn << "Start beam? " << name << " " << dev << "" << oendl; | ||
128 | if ( name == m_irDeSearch ) { | 126 | if ( name == m_irDeSearch ) { |
129 | for (QMap<int, QString>::Iterator it= m_irDa.begin(); it != m_irDa.end(); ++it ) | 127 | for (QMap<int, QString>::Iterator it= m_irDa.begin(); it != m_irDa.end(); ++it ) |
130 | m_devBox->removeDevice( it.key() ); | 128 | m_devBox->removeDevice( it.key() ); |
131 | 129 | ||
132 | QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); | 130 | QCopEnvelope e2("QPE/IrDaApplet", "listDevices()"); |
133 | } | 131 | } |
134 | } | 132 | } |
135 | void SendWidget::dispatchIrda( const QCString& str, const QByteArray& ar ) { | 133 | void SendWidget::dispatchIrda( const QCString& str, const QByteArray& ar ) { |
136 | owarn << "dispatch irda " << str.data() << "" << oendl; | ||
137 | if ( str == "devices(QStringList)" ) { | 134 | if ( str == "devices(QStringList)" ) { |
138 | QDataStream stream( ar, IO_ReadOnly ); | 135 | QDataStream stream( ar, IO_ReadOnly ); |
139 | QStringList list; | 136 | QStringList list; |
140 | stream >> list; | 137 | stream >> list; |
141 | slotIrDaDevices( list ); | 138 | slotIrDaDevices( list ); |
142 | } | 139 | } |
143 | } | 140 | } |
144 | void SendWidget::dispatchBt( const QCString&, const QByteArray& ) { | 141 | void SendWidget::dispatchBt( const QCString&, const QByteArray& ) { |
145 | 142 | ||
146 | } | 143 | } |
147 | void SendWidget::slotIrError( int ) { | 144 | void SendWidget::slotIrError( int ) { |
148 | 145 | ||
149 | } | 146 | } |
150 | void SendWidget::slotIrSent( bool b) { | 147 | void SendWidget::slotIrSent( bool b) { |
151 | owarn << "irda sent!!" << oendl; | ||
152 | QString text = b ? tr("Sent") : tr("Failure"); | 148 | QString text = b ? tr("Sent") : tr("Failure"); |
153 | m_devBox->setStatus( m_irDaIt.key(), text ); | 149 | m_devBox->setStatus( m_irDaIt.key(), text ); |
154 | ++m_irDaIt; | 150 | ++m_irDaIt; |
155 | slotStartIrda(); | 151 | slotStartIrda(); |
156 | } | 152 | } |
157 | void SendWidget::slotIrTry(unsigned int trI) { | 153 | void SendWidget::slotIrTry(unsigned int trI) { |
158 | m_devBox->setStatus( m_irDaIt.key(), tr("Try %1").arg( QString::number( trI ) ) ); | 154 | m_devBox->setStatus( m_irDaIt.key(), tr("Try %1").arg( QString::number( trI ) ) ); |
159 | } | 155 | } |
160 | void SendWidget::slotStartIrda() { | 156 | void SendWidget::slotStartIrda() { |
161 | if (m_irDaIt == m_irDa.end() ) { | 157 | if (m_irDaIt == m_irDa.end() ) { |
162 | m_irDeSearch = m_devBox->addDevice(tr("Search again for IrDa."), DeviceBox::Search ); | 158 | m_irDeSearch = m_devBox->addDevice(tr("Search again for IrDa."), DeviceBox::Search ); |
163 | return; | 159 | return; |
164 | } | 160 | } |
165 | m_devBox->setStatus( m_irDaIt.key(), tr("Start sending") ); | 161 | m_devBox->setStatus( m_irDaIt.key(), tr("Start sending") ); |
166 | m_obex->send( m_file ); | 162 | m_obex->send( m_file ); |
167 | } | 163 | } |
168 | void SendWidget::closeEvent( QCloseEvent* e) { | 164 | void SendWidget::closeEvent( QCloseEvent* e) { |
169 | e->accept(); // make sure | 165 | e->accept(); // make sure |
170 | QTimer::singleShot(0, this, SLOT(slotDone() ) ); | 166 | QTimer::singleShot(0, this, SLOT(slotDone() ) ); |
171 | } | 167 | } |
172 | void SendWidget::slotDone() { | 168 | void SendWidget::slotDone() { |
173 | QCopEnvelope e0("QPE/IrDaApplet", "disableIrda()"); | 169 | QCopEnvelope e0("QPE/IrDaApplet", "disableIrda()"); |
174 | QCopEnvelope e1("QPE/Bluetooth", "disableBluetooth()"); | 170 | QCopEnvelope e1("QPE/Bluetooth", "disableBluetooth()"); |
175 | emit done(); | 171 | emit done(); |
176 | } | 172 | } |
177 | QString SendWidget::file()const { | 173 | QString SendWidget::file()const { |
178 | return m_file; | 174 | return m_file; |
179 | } | 175 | } |
180 | DeviceBox::DeviceBox( QWidget* parent ) | 176 | DeviceBox::DeviceBox( QWidget* parent ) |
181 | : QTextBrowser( parent ) { | 177 | : QTextBrowser( parent ) { |
182 | 178 | ||
183 | } | 179 | } |
184 | DeviceBox::~DeviceBox() { | 180 | DeviceBox::~DeviceBox() { |
185 | 181 | ||
186 | } | 182 | } |
187 | int DeviceBox::addDevice( const QString& name, int dev, const QString& status ) { | 183 | int DeviceBox::addDevice( const QString& name, int dev, const QString& status ) { |
188 | /* return a id for a range of devices */ | 184 | /* return a id for a range of devices */ |
189 | int id = idFor ( dev ); | 185 | int id = idFor ( dev ); |
190 | DeviceItem item( name, status, dev,id ); | 186 | DeviceItem item( name, status, dev,id ); |
191 | m_dev.insert( id, item ); | 187 | m_dev.insert( id, item ); |
192 | setText( allText() ); | 188 | setText( allText() ); |
193 | 189 | ||
194 | return id; | 190 | return id; |
195 | } | 191 | } |
196 | void DeviceBox::removeDevice( int id ) { | 192 | void DeviceBox::removeDevice( int id ) { |
197 | if (!m_dev.contains(id) ) return; | 193 | if (!m_dev.contains(id) ) return; |
198 | 194 | ||
199 | m_dev.remove( id ); | 195 | m_dev.remove( id ); |
200 | setText( allText() ); | 196 | setText( allText() ); |
201 | } | 197 | } |
202 | void DeviceBox::setStatus( int id, const QString& status ) { | 198 | void DeviceBox::setStatus( int id, const QString& status ) { |
203 | if ( !m_dev.contains(id) ) return; | 199 | if ( !m_dev.contains(id) ) return; |
204 | m_dev[id].setStatus(status ); | 200 | m_dev[id].setStatus(status ); |
205 | setText( allText() ); | 201 | setText( allText() ); |
206 | } | 202 | } |
207 | void DeviceBox::setSource( const QString& str ) { | 203 | void DeviceBox::setSource( const QString& str ) { |
208 | owarn << "SetSource:" << str.toInt() << "" << oendl; | ||
209 | int id = str.toInt(); | 204 | int id = str.toInt(); |
210 | emit selectedDevice( id, m_dev[id].device() ); | 205 | emit selectedDevice( id, m_dev[id].device() ); |
211 | } | 206 | } |
212 | int DeviceBox::idFor ( int id ) { | 207 | int DeviceBox::idFor ( int id ) { |
213 | static int irId = 1501; | 208 | static int irId = 1501; |
214 | static int irBT = 1001; | 209 | static int irBT = 1001; |
215 | static int irSr = 501; | 210 | static int irSr = 501; |
216 | static int irEr = 0; | 211 | static int irEr = 0; |
217 | 212 | ||
218 | int ret = -1; | 213 | int ret = -1; |
219 | switch(id ) { | 214 | switch(id ) { |
220 | case IrDa: | 215 | case IrDa: |
221 | ret = irId; | 216 | ret = irId; |
222 | irId++; | 217 | irId++; |
223 | break; | 218 | break; |
224 | case BT: | 219 | case BT: |
225 | ret = irBT; | 220 | ret = irBT; |
226 | irBT++; | 221 | irBT++; |
227 | break; | 222 | break; |
228 | case Search: | 223 | case Search: |
229 | ret = irSr; | 224 | ret = irSr; |
230 | irSr++; | 225 | irSr++; |
231 | break; | 226 | break; |
232 | case Error: | 227 | case Error: |
233 | ret = irEr; | 228 | ret = irEr; |
234 | irEr++; | 229 | irEr++; |
235 | break; | 230 | break; |
236 | } | 231 | } |
237 | return ret; | 232 | return ret; |
238 | } | 233 | } |
239 | QString DeviceBox::allText() { | 234 | QString DeviceBox::allText() { |
240 | QString str; | 235 | QString str; |
241 | typedef QMap<int, DeviceItem> DeviceMap; | 236 | typedef QMap<int, DeviceItem> DeviceMap; |
242 | 237 | ||
243 | for (QMap<int, DeviceItem>::Iterator it = m_dev.begin(); it != m_dev.end(); ++it ) { | 238 | for (QMap<int, DeviceItem>::Iterator it = m_dev.begin(); it != m_dev.end(); ++it ) { |
244 | str += it.data().toString() + "<br>"; | 239 | str += it.data().toString() + "<br>"; |
245 | } | 240 | } |
246 | return str; | 241 | return str; |
247 | } | 242 | } |
248 | 243 | ||
249 | DeviceItem::DeviceItem( const QString& name, | 244 | DeviceItem::DeviceItem( const QString& name, |
250 | const QString& status, int dev, int id) | 245 | const QString& status, int dev, int id) |
251 | { | 246 | { |
252 | m_name = name; | 247 | m_name = name; |
253 | m_status = status; | 248 | m_status = status; |
254 | m_dev = dev; | 249 | m_dev = dev; |
255 | m_id = id; | 250 | m_id = id; |
256 | } | 251 | } |
257 | int DeviceItem::id()const { | 252 | int DeviceItem::id()const { |
258 | return m_id; | 253 | return m_id; |
259 | } | 254 | } |
260 | QString DeviceItem::name()const { | 255 | QString DeviceItem::name()const { |
261 | return m_name; | 256 | return m_name; |
262 | } | 257 | } |
263 | QString DeviceItem::status()const { | 258 | QString DeviceItem::status()const { |
264 | return m_status; | 259 | return m_status; |
265 | } | 260 | } |
266 | int DeviceItem::device()const { | 261 | int DeviceItem::device()const { |
267 | return m_dev; | 262 | return m_dev; |
268 | } | 263 | } |
269 | QString DeviceItem::pixmap()const{ | 264 | QString DeviceItem::pixmap()const{ |
270 | QString str; | 265 | QString str; |
271 | switch(m_dev) { | 266 | switch(m_dev) { |
272 | case DeviceBox::IrDa: | 267 | case DeviceBox::IrDa: |
diff --git a/core/obex/receiver.cpp b/core/obex/receiver.cpp index d4ae323..7d9a42a 100644 --- a/core/obex/receiver.cpp +++ b/core/obex/receiver.cpp | |||
@@ -15,194 +15,184 @@ using namespace Opie::Core; | |||
15 | #include <qlabel.h> | 15 | #include <qlabel.h> |
16 | #include <qtextview.h> | 16 | #include <qtextview.h> |
17 | #include <qpushbutton.h> | 17 | #include <qpushbutton.h> |
18 | 18 | ||
19 | /* STD */ | 19 | /* STD */ |
20 | #include <sys/types.h> | 20 | #include <sys/types.h> |
21 | #include <sys/stat.h> | 21 | #include <sys/stat.h> |
22 | #include <sys/mman.h> | 22 | #include <sys/mman.h> |
23 | #include <stdlib.h> // int system | 23 | #include <stdlib.h> // int system |
24 | #include <unistd.h> | 24 | #include <unistd.h> |
25 | #include <fcntl.h> | 25 | #include <fcntl.h> |
26 | 26 | ||
27 | /* TRANSLATOR OpieObex::Receiver */ | 27 | /* TRANSLATOR OpieObex::Receiver */ |
28 | 28 | ||
29 | Receiver::Receiver() { | 29 | Receiver::Receiver() { |
30 | m_obex = new Obex(this, "Receiver"); | 30 | m_obex = new Obex(this, "Receiver"); |
31 | connect(m_obex, SIGNAL(receivedFile(const QString&) ), | 31 | connect(m_obex, SIGNAL(receivedFile(const QString&) ), |
32 | this, SLOT(slotReceived(const QString&) ) ); | 32 | this, SLOT(slotReceived(const QString&) ) ); |
33 | m_obex->receive(); | 33 | m_obex->receive(); |
34 | } | 34 | } |
35 | Receiver::~Receiver() { | 35 | Receiver::~Receiver() { |
36 | m_obex->setReceiveEnabled( false ); | 36 | m_obex->setReceiveEnabled( false ); |
37 | delete m_obex; | 37 | delete m_obex; |
38 | } | 38 | } |
39 | void Receiver::slotReceived( const QString& _file ) { | 39 | void Receiver::slotReceived( const QString& _file ) { |
40 | QString file = _file; | 40 | QString file = _file; |
41 | int check = checkFile(file); | 41 | int check = checkFile(file); |
42 | if ( check == AddressBook ) | 42 | if ( check == AddressBook ) |
43 | handleAddr( file ); | 43 | handleAddr( file ); |
44 | else if ( check == Datebook ) | 44 | else if ( check == Datebook ) |
45 | handleDateTodo( file ); | 45 | handleDateTodo( file ); |
46 | else | 46 | else |
47 | handleOther( file ); | 47 | handleOther( file ); |
48 | } | 48 | } |
49 | void Receiver::handleAddr( const QString& str ) { | 49 | void Receiver::handleAddr( const QString& str ) { |
50 | QCopEnvelope e("QPE/Application/addressbook", "setDocument(QString)" ); | 50 | QCopEnvelope e("QPE/Application/addressbook", "setDocument(QString)" ); |
51 | e << str; | 51 | e << str; |
52 | } | 52 | } |
53 | /* we can not say for sure if it's a VEevent ot VTodo */ | 53 | /* we can not say for sure if it's a VEevent ot VTodo */ |
54 | void Receiver::handleDateTodo( const QString& str ) { | 54 | void Receiver::handleDateTodo( const QString& str ) { |
55 | QCopEnvelope e0("QPE/Application/todolist", "setDocument(QString)"); | 55 | QCopEnvelope e0("QPE/Application/todolist", "setDocument(QString)"); |
56 | e0 << str; | 56 | e0 << str; |
57 | QCopEnvelope e1("QPE/Application/datebook", "setDocument(QString)" ); | 57 | QCopEnvelope e1("QPE/Application/datebook", "setDocument(QString)" ); |
58 | e1 << str; | 58 | e1 << str; |
59 | } | 59 | } |
60 | /* | 60 | /* |
61 | * Handle other asks if it should accept the | 61 | * Handle other asks if it should accept the |
62 | * beamed object and creates a DocLnk | 62 | * beamed object and creates a DocLnk |
63 | */ | 63 | */ |
64 | void Receiver::handleOther( const QString& other ) { | 64 | void Receiver::handleOther( const QString& other ) { |
65 | OtherHandler* hand = new OtherHandler(); | 65 | OtherHandler* hand = new OtherHandler(); |
66 | hand->handle( other ); | 66 | hand->handle( other ); |
67 | } | 67 | } |
68 | void Receiver::tidyUp( QString& _file, const QString& ending) { | 68 | void Receiver::tidyUp( QString& _file, const QString& ending) { |
69 | /* libversit fails on BASE64 encoding we try to sed it away */ | 69 | /* libversit fails on BASE64 encoding we try to sed it away */ |
70 | QString file = _file; | 70 | QString file = _file; |
71 | char foo[24]; // big enough | 71 | char foo[24]; // big enough |
72 | (void)::strcpy(foo, "/tmp/opie-XXXXXX"); | 72 | (void)::strcpy(foo, "/tmp/opie-XXXXXX"); |
73 | 73 | ||
74 | int fd = ::mkstemp(foo); | 74 | int fd = ::mkstemp(foo); |
75 | 75 | ||
76 | if ( fd == -1 ) | 76 | if ( fd == -1 ) |
77 | return; | 77 | return; |
78 | 78 | ||
79 | (void)::strncat( foo, ending.latin1(), 4 ); | 79 | (void)::strncat( foo, QFile::encodeName(ending), 4 ); |
80 | _file = QString::fromLatin1( foo ); | 80 | _file = QString::fromLocal8Bit( foo ); |
81 | QString cmd = QString("sed -e \"s/^\\(X-MICROSOFT-BODYINK\\)\\;/\\1:/;\" < %2 > %2 ").arg( Global::shellQuote(file)).arg( Global::shellQuote(_file) ); | 81 | QString cmd = QString("sed -e \"s/^\\(X-MICROSOFT-BODYINK\\)\\;/\\1:/;\" < %2 > %2 ").arg( Global::shellQuote(file)).arg( Global::shellQuote(_file) ); |
82 | owarn << "Executing: " << cmd << "" << oendl; | 82 | (void)::system( QFile::encodeName(cmd) ); |
83 | (void)::system( cmd.latin1() ); | ||
84 | 83 | ||
85 | cmd = QString("rm %1").arg( Global::shellQuote(file) ); | 84 | cmd = QString("rm %1").arg( Global::shellQuote(file) ); |
86 | (void)::system( cmd.latin1() ); | 85 | (void)::system( QFile::encodeName(cmd) ); |
87 | } | 86 | } |
88 | int Receiver::checkFile( QString& file ) { | 87 | int Receiver::checkFile( QString& file ) { |
89 | owarn << "check file!! " << file << "" << oendl; | ||
90 | int ret; | 88 | int ret; |
91 | QString ending; | 89 | QString ending; |
92 | 90 | ||
93 | if (file.right(4) == ".vcs" ) { | 91 | if (file.right(4) == ".vcs" ) { |
94 | ret = Datebook; | 92 | ret = Datebook; |
95 | ending = QString::fromLatin1(".vcs"); | 93 | ending = QString::fromLatin1(".vcs"); |
96 | }else if ( file.right(4) == ".vcf") { | 94 | }else if ( file.right(4) == ".vcf") { |
97 | ret = AddressBook; | 95 | ret = AddressBook; |
98 | ending = QString::fromLatin1(".vcf"); | 96 | ending = QString::fromLatin1(".vcf"); |
99 | }else | 97 | }else |
100 | ret = Other; | 98 | ret = Other; |
101 | 99 | ||
102 | 100 | ||
103 | if (ending.isEmpty() ) | 101 | if (ending.isEmpty() ) |
104 | return ret; | 102 | return ret; |
105 | 103 | ||
106 | /** | 104 | /** |
107 | * currently the parser is broken in regard of BASE64 encoding | 105 | * currently the parser is broken in regard of BASE64 encoding |
108 | * and M$ likes to send that. So we will executed a small | 106 | * and M$ likes to send that. So we will executed a small |
109 | * tidy up system sed script | 107 | * tidy up system sed script |
110 | * At this point we can also remove umlaute from the filename | 108 | * At this point we can also remove umlaute from the filename |
111 | */ | 109 | */ |
112 | tidyUp( file, ending ); | 110 | tidyUp( file, ending ); |
113 | 111 | ||
114 | owarn << "check it now " << ret << "" << oendl; | ||
115 | return ret; | 112 | return ret; |
116 | } | 113 | } |
117 | 114 | ||
118 | /* TRANSLATOR OpieObex::OtherHandler */ | 115 | /* TRANSLATOR OpieObex::OtherHandler */ |
119 | 116 | ||
120 | OtherHandler::OtherHandler() | 117 | OtherHandler::OtherHandler() |
121 | : QVBox() | 118 | : QVBox() |
122 | { | 119 | { |
123 | QHBox* box = new QHBox(this); | 120 | QHBox* box = new QHBox(this); |
124 | QLabel* lbl = new QLabel(box); | 121 | QLabel* lbl = new QLabel(box); |
125 | lbl->setText(tr("<qt><b>Received:</b></qt>")); | 122 | lbl->setText(tr("<qt><b>Received:</b></qt>")); |
126 | m_na = new QLabel(box); | 123 | m_na = new QLabel(box); |
127 | 124 | ||
128 | QFrame* frame = new QFrame(this); | 125 | QFrame* frame = new QFrame(this); |
129 | frame->setFrameShape( QFrame::HLine ); | 126 | frame->setFrameShape( QFrame::HLine ); |
130 | frame->setFrameShadow( QFrame::Sunken ); | 127 | frame->setFrameShadow( QFrame::Sunken ); |
131 | 128 | ||
132 | m_view = new QTextView(this); | 129 | m_view = new QTextView(this); |
133 | 130 | ||
134 | box = new QHBox(this); | 131 | box = new QHBox(this); |
135 | QPushButton *but = new QPushButton(box); | 132 | QPushButton *but = new QPushButton(box); |
136 | but->setText(tr("Accept") ); | 133 | but->setText(tr("Accept") ); |
137 | connect(but, SIGNAL(clicked() ), | 134 | connect(but, SIGNAL(clicked() ), |
138 | this, SLOT(accept()) ); | 135 | this, SLOT(accept()) ); |
139 | 136 | ||
140 | but = new QPushButton(box); | 137 | but = new QPushButton(box); |
141 | but->setText(tr("Deny") ); | 138 | but->setText(tr("Deny") ); |
142 | connect(but, SIGNAL(clicked() ), | 139 | connect(but, SIGNAL(clicked() ), |
143 | this, SLOT(deny() ) ); | 140 | this, SLOT(deny() ) ); |
144 | 141 | ||
145 | raise(); | 142 | raise(); |
146 | showMaximized(); | 143 | showMaximized(); |
147 | } | 144 | } |
148 | OtherHandler::~OtherHandler() { | 145 | OtherHandler::~OtherHandler() { |
149 | 146 | ||
150 | } | 147 | } |
151 | void OtherHandler::handle( const QString& file ) { | 148 | void OtherHandler::handle( const QString& file ) { |
152 | m_file = file; | 149 | m_file = file; |
153 | m_na->setText(file); | 150 | m_na->setText(file); |
154 | DocLnk lnk(file); | 151 | DocLnk lnk(file); |
155 | owarn << " " << lnk.type() << " " << lnk.icon() << "" << oendl; | ||
156 | 152 | ||
157 | 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() ); | 153 | 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() ); |
158 | m_view->setText( str ); | 154 | m_view->setText( str ); |
159 | } | 155 | } |
160 | 156 | ||
161 | /* | 157 | /* |
162 | * hehe evil evil mmap ahead :) | 158 | * hehe evil evil mmap ahead :) |
163 | * we quickly copy the file and then we'll create a DocLnk for it | 159 | * we quickly copy the file and then we'll create a DocLnk for it |
164 | */ | 160 | */ |
165 | void OtherHandler::accept() { | 161 | void OtherHandler::accept() { |
166 | QString na = targetName( m_file ); | 162 | QString na = targetName( m_file ); |
167 | copy(m_file, na ); | 163 | copy(m_file, na ); |
168 | DocLnk lnk(na); | 164 | DocLnk lnk(na); |
169 | lnk.writeLink(); | 165 | lnk.writeLink(); |
170 | QFile::remove(m_file); | 166 | QFile::remove(m_file); |
171 | delete this; | 167 | delete this; |
172 | } | 168 | } |
173 | void OtherHandler::deny() { | 169 | void OtherHandler::deny() { |
174 | QFile::remove( m_file ); | 170 | QFile::remove( m_file ); |
175 | delete this; | 171 | delete this; |
176 | } | 172 | } |
177 | QString OtherHandler::targetName( const QString& file ) { | 173 | QString OtherHandler::targetName( const QString& file ) { |
178 | QFileInfo info( file ); | 174 | QFileInfo info( file ); |
179 | 175 | ||
180 | /* $HOME needs to be set!!!! */ | 176 | /* $HOME needs to be set!!!! */ |
181 | Global::createDocDir(); | 177 | Global::createDocDir(); |
182 | 178 | ||
183 | QString newFile = QPEApplication::documentDir()+ "/"+ info.baseName(); | 179 | QString newFile = QPEApplication::documentDir()+ "/"+ info.baseName(); |
184 | QString newFileBase = newFile; | 180 | QString newFileBase = newFile; |
185 | 181 | ||
186 | int trie = 0; | 182 | int trie = 0; |
187 | while (QFile::exists(newFile + "."+info.extension() ) ) { | 183 | while (QFile::exists(newFile + "."+info.extension() ) ) { |
188 | newFile = newFileBase + "_"+QString::number(trie) ; | 184 | newFile = newFileBase + "_"+QString::number(trie) ; |
189 | trie++; | 185 | trie++; |
190 | } | 186 | } |
191 | newFile += "." + info.extension(); | 187 | newFile += "." + info.extension(); |
192 | 188 | ||
193 | return newFile; | 189 | return newFile; |
194 | } | 190 | } |
195 | 191 | ||
196 | /* fast cpy */ | 192 | /* fast cpy */ |
197 | void OtherHandler::copy(const QString& src, const QString& file) { | 193 | void OtherHandler::copy(const QString& src, const QString& file) { |
198 | owarn << "src " << src << ", dest " << file << "" << oendl; | ||
199 | FileManager *fm; | 194 | FileManager *fm; |
200 | if(!fm->copyFile(src,file)) { | 195 | if(!fm->copyFile(src,file)) { |
201 | owarn << "Copy failed" << oendl; | 196 | owarn << "Copy failed" << oendl; |
202 | } | 197 | } |
203 | |||
204 | // QString cmd = QString("mv %1 %2").arg( Global::shellQuote( src )). | ||
205 | // arg( Global::shellQuote( file ) ); | ||
206 | // ::system( cmd.latin1() ); | ||
207 | // done | ||
208 | } | 198 | } |