Diffstat (limited to 'noncore/net/opietooth/manager/obexftpdialog.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/net/opietooth/manager/obexftpdialog.cpp | 390 |
1 files changed, 390 insertions, 0 deletions
diff --git a/noncore/net/opietooth/manager/obexftpdialog.cpp b/noncore/net/opietooth/manager/obexftpdialog.cpp new file mode 100644 index 0000000..c77d49d --- a/dev/null +++ b/noncore/net/opietooth/manager/obexftpdialog.cpp | |||
@@ -0,0 +1,390 @@ | |||
1 | /* $Id$ */ | ||
2 | /* OBEX file browser dialog */ | ||
3 | /*************************************************************************** | ||
4 | * * | ||
5 | * This program is free software; you can redistribute it and/or modify * | ||
6 | * it under the terms of the GNU General Public License as published by * | ||
7 | * the Free Software Foundation; either version 2 of the License, or * | ||
8 | * (at your option) any later version. * | ||
9 | * * | ||
10 | ***************************************************************************/ | ||
11 | /* | ||
12 | * This code uses and is based on ObexFTP project code: http://triq.net/obexftp/ | ||
13 | */ | ||
14 | #include <sys/stat.h> | ||
15 | #include <qpushbutton.h> | ||
16 | #include <qmessagebox.h> | ||
17 | #include <qmultilineedit.h> | ||
18 | #include <qlistview.h> | ||
19 | #include <qprogressbar.h> | ||
20 | #include <qlabel.h> | ||
21 | #include <qlayout.h> | ||
22 | #include <errno.h> | ||
23 | #include "obexftpdialog.h" | ||
24 | #include "filelistitem.h" | ||
25 | |||
26 | #include <qpe/qpeapplication.h> | ||
27 | #include <qpe/resource.h> | ||
28 | #include <qpe/config.h> | ||
29 | #include <opie2/odebug.h> | ||
30 | #include <opie2/ofileselector.h> | ||
31 | |||
32 | using namespace Opie::Core; | ||
33 | using namespace Opie::Ui; | ||
34 | |||
35 | using namespace OpieTooth; | ||
36 | |||
37 | #define MAX_PROGRESS 14 //Maximal progress bar | ||
38 | |||
39 | static void info_cb(int event, const char *msg, int len, void* data); | ||
40 | |||
41 | /* | ||
42 | * Public constructor | ||
43 | * device - bluetooth address of the device | ||
44 | * port - port to connect to | ||
45 | */ | ||
46 | ObexFtpDialog::ObexFtpDialog(const QString& device, int port, | ||
47 | QWidget* parent, const char* name, bool modal, WFlags fl) | ||
48 | : ObexFtpDialogBase(parent, name, modal, fl), m_device(device), | ||
49 | m_port(port), curdir("") | ||
50 | { | ||
51 | client = NULL; | ||
52 | transport = OBEX_TRANS_BLUETOOTH; | ||
53 | use_conn = TRUE; | ||
54 | use_path = TRUE; | ||
55 | progressStatus = 0; | ||
56 | localCurdir = "/"; | ||
57 | browseLog->setEdited(FALSE); | ||
58 | fileList->setSorting(1); | ||
59 | fileList->clear(); | ||
60 | fileProgress->setTotalSteps(MAX_PROGRESS); | ||
61 | statusBar->clear(); | ||
62 | localLayout = new QVBoxLayout(localFs); | ||
63 | localLayout->setSpacing( 0 ); | ||
64 | localLayout->setMargin( 0 ); | ||
65 | destFile = new OFileSelector(localFs, | ||
66 | OFileSelector::FileSelector, | ||
67 | OFileSelector::ExtendedAll, localCurdir, ""); | ||
68 | destFile->setCloseVisible(false); | ||
69 | destFile->setNewVisible(false); | ||
70 | localLayout->addWidget(destFile); | ||
71 | connect(browseOK, SIGNAL(clicked()), SLOT(slotBrowse())); | ||
72 | connect(fileList, SIGNAL(clicked(QListViewItem*)), | ||
73 | SLOT(slotCd(QListViewItem*))); | ||
74 | connect(getButton, | ||
75 | SIGNAL(clicked()), | ||
76 | SLOT(getFile())); | ||
77 | connect(destFile, | ||
78 | SIGNAL(dirSelected (const QString&)), | ||
79 | SLOT(updateDir(const QString&))); | ||
80 | } | ||
81 | |||
82 | ObexFtpDialog::~ObexFtpDialog() | ||
83 | { | ||
84 | if (client != NULL) { | ||
85 | obexftp_disconnect(client); | ||
86 | obexftp_close(client); | ||
87 | } | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Do device browsing | ||
92 | */ | ||
93 | void ObexFtpDialog::slotBrowse() | ||
94 | { | ||
95 | stat_entry_t* ent; //Directory entry | ||
96 | void *dir; //Directory to read | ||
97 | const uint8_t use_uuid[] = __UUID_FBS_bytes; | ||
98 | int len = sizeof(UUID_FBS); | ||
99 | FileListItem* root; //root node | ||
100 | stat_entry_t* st; //File statistics | ||
101 | int fsize; //file size | ||
102 | |||
103 | status(tr("Connecting to ") + m_device); | ||
104 | odebug << "Browse device " << m_device << oendl; | ||
105 | browseLog->clear(); | ||
106 | fileList->clear(); | ||
107 | progressStatus = 0; | ||
108 | fileProgress->reset(); | ||
109 | if (!cli_connect_uuid(use_uuid, len)) { | ||
110 | log("Connection failed"); | ||
111 | errBox("Connection failed"); | ||
112 | status("Connection failed"); | ||
113 | return; | ||
114 | } | ||
115 | else { | ||
116 | log(QString("Connected to ") + m_device); | ||
117 | status(QString("Connected to ") + m_device); | ||
118 | } | ||
119 | /* List folder */ | ||
120 | root = new FileListItem(fileList, NULL); | ||
121 | dir = obexftp_opendir(client, curdir); | ||
122 | while ((ent = obexftp_readdir(dir)) != NULL) { | ||
123 | FileListItem* a; //List view item | ||
124 | #if 0 //Causes sigsegv | ||
125 | if (ent->mode != 16877) { | ||
126 | st = obexftp_stat(client, ent->name); | ||
127 | fsize = st->size; | ||
128 | } | ||
129 | else | ||
130 | #endif | ||
131 | fsize = 0; | ||
132 | log(QString(ent->name) + QString(" ") + | ||
133 | QString::number(ent->mode)); | ||
134 | |||
135 | a = new FileListItem(fileList, ent, fsize); | ||
136 | } | ||
137 | obexftp_closedir(dir); | ||
138 | } | ||
139 | |||
140 | //Error message box | ||
141 | int ObexFtpDialog::errBox(QCString msg) | ||
142 | { | ||
143 | return QMessageBox::critical(this, tr("ObexFTP error"), msg); | ||
144 | } | ||
145 | |||
146 | int ObexFtpDialog::errBox(QString msg) | ||
147 | { | ||
148 | return QMessageBox::critical(this, tr("ObexFTP error"), msg); | ||
149 | } | ||
150 | |||
151 | int ObexFtpDialog::errBox(const char* msg) | ||
152 | { | ||
153 | return QMessageBox::critical(this, tr("ObexFTP error"), tr(msg)); | ||
154 | } | ||
155 | |||
156 | //Text in the status bar | ||
157 | void ObexFtpDialog::status(QCString msg) | ||
158 | { | ||
159 | statusBar->setText(msg); | ||
160 | statusBar->repaint(); | ||
161 | } | ||
162 | |||
163 | void ObexFtpDialog::status(QString msg) | ||
164 | { | ||
165 | statusBar->setText(msg); | ||
166 | statusBar->repaint(); | ||
167 | } | ||
168 | |||
169 | void ObexFtpDialog::status(const char* msg) | ||
170 | { | ||
171 | statusBar->setText(msg); | ||
172 | statusBar->repaint(); | ||
173 | } | ||
174 | |||
175 | /* | ||
176 | * Change directory with item under the cursor | ||
177 | */ | ||
178 | void ObexFtpDialog::slotCd(QListViewItem* item) | ||
179 | { | ||
180 | FileListItem* file = (FileListItem*)item; | ||
181 | int idx; | ||
182 | if (file == NULL) | ||
183 | return; | ||
184 | odebug << "Item " << file->text(0) << " clicked" << oendl; | ||
185 | if (file->gettype() == IS_DIR) { | ||
186 | if (file->text(0) == "../") { | ||
187 | if (curdir.right(1) == "/") | ||
188 | curdir.remove(curdir.length() - 1, 1); | ||
189 | idx = curdir.findRev('/'); | ||
190 | if (idx >= 0) | ||
191 | curdir.remove(idx, curdir.length() - idx); | ||
192 | else | ||
193 | curdir = ""; | ||
194 | } | ||
195 | else { | ||
196 | if (curdir != "" && curdir.right(1) != "/") | ||
197 | curdir += "/"; | ||
198 | curdir += file->text(0); | ||
199 | } | ||
200 | odebug << "Browse " << curdir << oendl; | ||
201 | if (obexftp_setpath(client, curdir, 0) < 0) | ||
202 | log("CD failed"); | ||
203 | slotBrowse(); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | /* | ||
208 | * Get the file | ||
209 | */ | ||
210 | void ObexFtpDialog::getFile() | ||
211 | { | ||
212 | FileListItem* file = (FileListItem*)fileList->selectedItem(); | ||
213 | int result; | ||
214 | if (file == NULL) | ||
215 | return; | ||
216 | file2get = "/"; | ||
217 | local = localCurdir; | ||
218 | if (local == "") { | ||
219 | errBox("Select a destination first"); | ||
220 | return; | ||
221 | } | ||
222 | if (local.right(1) != "/") | ||
223 | local += "/"; | ||
224 | if (file->gettype() == IS_FILE) { | ||
225 | file2get += curdir; | ||
226 | if (curdir != "" && curdir.right(1) != "/") | ||
227 | file2get += "/"; | ||
228 | file2get += file->text(0); | ||
229 | local += file->text(0); | ||
230 | odebug << "Copy " << file2get << " to " << local << oendl; | ||
231 | progressStatus = 0; | ||
232 | fileProgress->reset(); | ||
233 | status(tr("Receiving file ") + file2get); | ||
234 | result = obexftp_get(client, local, file2get); | ||
235 | if (result < 0) { | ||
236 | log(file2get + QString(" receive ERROR")); | ||
237 | errBox(file2get + QString(" receive ERROR")); | ||
238 | status(file2get + QString(" receive ERROR")); | ||
239 | } | ||
240 | else { | ||
241 | log(file2get + QString(" received")); | ||
242 | status(file2get + QString(" received")); | ||
243 | destFile->reread(); | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | |||
248 | /* connect with given uuid. re-connect every time */ | ||
249 | int ObexFtpDialog::cli_connect_uuid(const uint8_t *uuid, int uuid_len) | ||
250 | { | ||
251 | int retry; | ||
252 | if (client != NULL) | ||
253 | return TRUE; | ||
254 | /* Open */ | ||
255 | client = obexftp_open (transport, NULL, info_cb, this); | ||
256 | if(client == NULL) { | ||
257 | errBox("Error opening obexftp-client"); | ||
258 | return FALSE; | ||
259 | } | ||
260 | if (!use_conn) | ||
261 | client->quirks &= ~OBEXFTP_CONN_HEADER; | ||
262 | if (!use_path) | ||
263 | client->quirks &= ~OBEXFTP_SPLIT_SETPATH; | ||
264 | for (retry = 0; retry < 3; retry++) { | ||
265 | /* Connect */ | ||
266 | switch (transport) { | ||
267 | case OBEX_TRANS_IRDA: | ||
268 | if (obexftp_connect_uuid(client, NULL, 0, uuid, uuid_len) >= 0) | ||
269 | return TRUE; | ||
270 | break; | ||
271 | case OBEX_TRANS_BLUETOOTH: | ||
272 | if (obexftp_connect_uuid(client, m_device, m_port, | ||
273 | uuid, uuid_len) >= 0) | ||
274 | return TRUE; | ||
275 | break; | ||
276 | default: | ||
277 | errBox("Transport type unknown"); | ||
278 | return FALSE; | ||
279 | } | ||
280 | log(tr("Still trying to connect")); | ||
281 | } | ||
282 | client = NULL; | ||
283 | |||
284 | return FALSE; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * Put a message to the log window | ||
289 | */ | ||
290 | void ObexFtpDialog::log(QString str) | ||
291 | { | ||
292 | browseLog->append(str); | ||
293 | } | ||
294 | |||
295 | void ObexFtpDialog::log(QCString str) | ||
296 | { | ||
297 | browseLog->append(str); | ||
298 | } | ||
299 | |||
300 | void ObexFtpDialog::log(QString& str) | ||
301 | { | ||
302 | browseLog->append(str); | ||
303 | } | ||
304 | |||
305 | void ObexFtpDialog::log(const char* str) | ||
306 | { | ||
307 | browseLog->append(str); | ||
308 | } | ||
309 | |||
310 | void ObexFtpDialog::incProgress() | ||
311 | { | ||
312 | odebug << "Progress " << progressStatus << oendl; | ||
313 | if (progressStatus < MAX_PROGRESS) { | ||
314 | fileProgress->setProgress(progressStatus++); | ||
315 | } | ||
316 | } | ||
317 | |||
318 | void ObexFtpDialog::doneProgress() | ||
319 | { | ||
320 | progressStatus = 0; | ||
321 | fileProgress->reset(); | ||
322 | } | ||
323 | |||
324 | void ObexFtpDialog::updateDir(const QString& newdir) | ||
325 | { | ||
326 | localCurdir = newdir; | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * Event callback function | ||
331 | */ | ||
332 | static void info_cb(int event, const char *msg, int len, void* data) | ||
333 | { | ||
334 | ObexFtpDialog* dlg = (ObexFtpDialog*)data; | ||
335 | QCString cmsg(msg, len); //Message to display | ||
336 | |||
337 | switch (event) { | ||
338 | |||
339 | case OBEXFTP_EV_ERRMSG: | ||
340 | dlg->log(QCString("Error: ") + cmsg); | ||
341 | break; | ||
342 | |||
343 | case OBEXFTP_EV_ERR: | ||
344 | dlg->log(QCString("failed: ") + cmsg); | ||
345 | dlg->doneProgress(); | ||
346 | break; | ||
347 | case OBEXFTP_EV_OK: | ||
348 | dlg->log(QCString("done")); | ||
349 | dlg->doneProgress(); | ||
350 | break; | ||
351 | |||
352 | case OBEXFTP_EV_CONNECTING: | ||
353 | dlg->log(QCString("Connecting...")); | ||
354 | break; | ||
355 | case OBEXFTP_EV_DISCONNECTING: | ||
356 | dlg->log(QCString("Disconnecting...")); | ||
357 | break; | ||
358 | case OBEXFTP_EV_SENDING: | ||
359 | dlg->log(QCString("Sending ") + msg); | ||
360 | break; | ||
361 | case OBEXFTP_EV_RECEIVING: | ||
362 | dlg->log(QCString("Receiving ") + msg); | ||
363 | break; | ||
364 | |||
365 | case OBEXFTP_EV_LISTENING: | ||
366 | dlg->log(QCString("Waiting for incoming connection")); | ||
367 | break; | ||
368 | |||
369 | case OBEXFTP_EV_CONNECTIND: | ||
370 | dlg->log(QCString("Incoming connection")); | ||
371 | break; | ||
372 | case OBEXFTP_EV_DISCONNECTIND: | ||
373 | dlg->log(QCString("Disconnecting")); | ||
374 | break; | ||
375 | |||
376 | case OBEXFTP_EV_INFO: | ||
377 | // 64 bit problems ? | ||
378 | dlg->log(QString("Got info ") + QString::number((int)msg)); | ||
379 | break; | ||
380 | |||
381 | case OBEXFTP_EV_BODY: | ||
382 | break; | ||
383 | |||
384 | case OBEXFTP_EV_PROGRESS: | ||
385 | dlg->incProgress(); | ||
386 | break; | ||
387 | } | ||
388 | } | ||
389 | |||
390 | //eof | ||