summaryrefslogtreecommitdiff
path: root/noncore/net/opietooth/manager/obexftpdialog.cpp
Side-by-side diff
Diffstat (limited to 'noncore/net/opietooth/manager/obexftpdialog.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/net/opietooth/manager/obexftpdialog.cpp390
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 @@
+/* $Id$ */
+/* OBEX file browser dialog */
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+/*
+ * This code uses and is based on ObexFTP project code: http://triq.net/obexftp/
+ */
+#include <sys/stat.h>
+#include <qpushbutton.h>
+#include <qmessagebox.h>
+#include <qmultilineedit.h>
+#include <qlistview.h>
+#include <qprogressbar.h>
+#include <qlabel.h>
+#include <qlayout.h>
+#include <errno.h>
+#include "obexftpdialog.h"
+#include "filelistitem.h"
+
+#include <qpe/qpeapplication.h>
+#include <qpe/resource.h>
+#include <qpe/config.h>
+#include <opie2/odebug.h>
+#include <opie2/ofileselector.h>
+
+using namespace Opie::Core;
+using namespace Opie::Ui;
+
+using namespace OpieTooth;
+
+#define MAX_PROGRESS 14 //Maximal progress bar
+
+static void info_cb(int event, const char *msg, int len, void* data);
+
+/*
+ * Public constructor
+ * device - bluetooth address of the device
+ * port - port to connect to
+ */
+ObexFtpDialog::ObexFtpDialog(const QString& device, int port,
+ QWidget* parent, const char* name, bool modal, WFlags fl)
+ : ObexFtpDialogBase(parent, name, modal, fl), m_device(device),
+ m_port(port), curdir("")
+{
+ client = NULL;
+ transport = OBEX_TRANS_BLUETOOTH;
+ use_conn = TRUE;
+ use_path = TRUE;
+ progressStatus = 0;
+ localCurdir = "/";
+ browseLog->setEdited(FALSE);
+ fileList->setSorting(1);
+ fileList->clear();
+ fileProgress->setTotalSteps(MAX_PROGRESS);
+ statusBar->clear();
+ localLayout = new QVBoxLayout(localFs);
+ localLayout->setSpacing( 0 );
+ localLayout->setMargin( 0 );
+ destFile = new OFileSelector(localFs,
+ OFileSelector::FileSelector,
+ OFileSelector::ExtendedAll, localCurdir, "");
+ destFile->setCloseVisible(false);
+ destFile->setNewVisible(false);
+ localLayout->addWidget(destFile);
+ connect(browseOK, SIGNAL(clicked()), SLOT(slotBrowse()));
+ connect(fileList, SIGNAL(clicked(QListViewItem*)),
+ SLOT(slotCd(QListViewItem*)));
+ connect(getButton,
+ SIGNAL(clicked()),
+ SLOT(getFile()));
+ connect(destFile,
+ SIGNAL(dirSelected (const QString&)),
+ SLOT(updateDir(const QString&)));
+}
+
+ObexFtpDialog::~ObexFtpDialog()
+{
+ if (client != NULL) {
+ obexftp_disconnect(client);
+ obexftp_close(client);
+ }
+}
+
+/*
+ * Do device browsing
+ */
+void ObexFtpDialog::slotBrowse()
+{
+ stat_entry_t* ent; //Directory entry
+ void *dir; //Directory to read
+ const uint8_t use_uuid[] = __UUID_FBS_bytes;
+ int len = sizeof(UUID_FBS);
+ FileListItem* root; //root node
+ stat_entry_t* st; //File statistics
+ int fsize; //file size
+
+ status(tr("Connecting to ") + m_device);
+ odebug << "Browse device " << m_device << oendl;
+ browseLog->clear();
+ fileList->clear();
+ progressStatus = 0;
+ fileProgress->reset();
+ if (!cli_connect_uuid(use_uuid, len)) {
+ log("Connection failed");
+ errBox("Connection failed");
+ status("Connection failed");
+ return;
+ }
+ else {
+ log(QString("Connected to ") + m_device);
+ status(QString("Connected to ") + m_device);
+ }
+ /* List folder */
+ root = new FileListItem(fileList, NULL);
+ dir = obexftp_opendir(client, curdir);
+ while ((ent = obexftp_readdir(dir)) != NULL) {
+ FileListItem* a; //List view item
+#if 0 //Causes sigsegv
+ if (ent->mode != 16877) {
+ st = obexftp_stat(client, ent->name);
+ fsize = st->size;
+ }
+ else
+#endif
+ fsize = 0;
+ log(QString(ent->name) + QString(" ") +
+ QString::number(ent->mode));
+
+ a = new FileListItem(fileList, ent, fsize);
+ }
+ obexftp_closedir(dir);
+}
+
+//Error message box
+int ObexFtpDialog::errBox(QCString msg)
+{
+ return QMessageBox::critical(this, tr("ObexFTP error"), msg);
+}
+
+int ObexFtpDialog::errBox(QString msg)
+{
+ return QMessageBox::critical(this, tr("ObexFTP error"), msg);
+}
+
+int ObexFtpDialog::errBox(const char* msg)
+{
+ return QMessageBox::critical(this, tr("ObexFTP error"), tr(msg));
+}
+
+//Text in the status bar
+void ObexFtpDialog::status(QCString msg)
+{
+ statusBar->setText(msg);
+ statusBar->repaint();
+}
+
+void ObexFtpDialog::status(QString msg)
+{
+ statusBar->setText(msg);
+ statusBar->repaint();
+}
+
+void ObexFtpDialog::status(const char* msg)
+{
+ statusBar->setText(msg);
+ statusBar->repaint();
+}
+
+/*
+ * Change directory with item under the cursor
+ */
+void ObexFtpDialog::slotCd(QListViewItem* item)
+{
+ FileListItem* file = (FileListItem*)item;
+ int idx;
+ if (file == NULL)
+ return;
+ odebug << "Item " << file->text(0) << " clicked" << oendl;
+ if (file->gettype() == IS_DIR) {
+ if (file->text(0) == "../") {
+ if (curdir.right(1) == "/")
+ curdir.remove(curdir.length() - 1, 1);
+ idx = curdir.findRev('/');
+ if (idx >= 0)
+ curdir.remove(idx, curdir.length() - idx);
+ else
+ curdir = "";
+ }
+ else {
+ if (curdir != "" && curdir.right(1) != "/")
+ curdir += "/";
+ curdir += file->text(0);
+ }
+ odebug << "Browse " << curdir << oendl;
+ if (obexftp_setpath(client, curdir, 0) < 0)
+ log("CD failed");
+ slotBrowse();
+ }
+}
+
+/*
+ * Get the file
+ */
+void ObexFtpDialog::getFile()
+{
+ FileListItem* file = (FileListItem*)fileList->selectedItem();
+ int result;
+ if (file == NULL)
+ return;
+ file2get = "/";
+ local = localCurdir;
+ if (local == "") {
+ errBox("Select a destination first");
+ return;
+ }
+ if (local.right(1) != "/")
+ local += "/";
+ if (file->gettype() == IS_FILE) {
+ file2get += curdir;
+ if (curdir != "" && curdir.right(1) != "/")
+ file2get += "/";
+ file2get += file->text(0);
+ local += file->text(0);
+ odebug << "Copy " << file2get << " to " << local << oendl;
+ progressStatus = 0;
+ fileProgress->reset();
+ status(tr("Receiving file ") + file2get);
+ result = obexftp_get(client, local, file2get);
+ if (result < 0) {
+ log(file2get + QString(" receive ERROR"));
+ errBox(file2get + QString(" receive ERROR"));
+ status(file2get + QString(" receive ERROR"));
+ }
+ else {
+ log(file2get + QString(" received"));
+ status(file2get + QString(" received"));
+ destFile->reread();
+ }
+ }
+}
+
+/* connect with given uuid. re-connect every time */
+int ObexFtpDialog::cli_connect_uuid(const uint8_t *uuid, int uuid_len)
+{
+ int retry;
+ if (client != NULL)
+ return TRUE;
+ /* Open */
+ client = obexftp_open (transport, NULL, info_cb, this);
+ if(client == NULL) {
+ errBox("Error opening obexftp-client");
+ return FALSE;
+ }
+ if (!use_conn)
+ client->quirks &= ~OBEXFTP_CONN_HEADER;
+ if (!use_path)
+ client->quirks &= ~OBEXFTP_SPLIT_SETPATH;
+ for (retry = 0; retry < 3; retry++) {
+ /* Connect */
+ switch (transport) {
+ case OBEX_TRANS_IRDA:
+ if (obexftp_connect_uuid(client, NULL, 0, uuid, uuid_len) >= 0)
+ return TRUE;
+ break;
+ case OBEX_TRANS_BLUETOOTH:
+ if (obexftp_connect_uuid(client, m_device, m_port,
+ uuid, uuid_len) >= 0)
+ return TRUE;
+ break;
+ default:
+ errBox("Transport type unknown");
+ return FALSE;
+ }
+ log(tr("Still trying to connect"));
+ }
+ client = NULL;
+
+ return FALSE;
+}
+
+/*
+ * Put a message to the log window
+ */
+void ObexFtpDialog::log(QString str)
+{
+ browseLog->append(str);
+}
+
+void ObexFtpDialog::log(QCString str)
+{
+ browseLog->append(str);
+}
+
+void ObexFtpDialog::log(QString& str)
+{
+ browseLog->append(str);
+}
+
+void ObexFtpDialog::log(const char* str)
+{
+ browseLog->append(str);
+}
+
+void ObexFtpDialog::incProgress()
+{
+ odebug << "Progress " << progressStatus << oendl;
+ if (progressStatus < MAX_PROGRESS) {
+ fileProgress->setProgress(progressStatus++);
+ }
+}
+
+void ObexFtpDialog::doneProgress()
+{
+ progressStatus = 0;
+ fileProgress->reset();
+}
+
+void ObexFtpDialog::updateDir(const QString& newdir)
+{
+ localCurdir = newdir;
+}
+
+/*
+ * Event callback function
+ */
+static void info_cb(int event, const char *msg, int len, void* data)
+{
+ ObexFtpDialog* dlg = (ObexFtpDialog*)data;
+ QCString cmsg(msg, len); //Message to display
+
+ switch (event) {
+
+ case OBEXFTP_EV_ERRMSG:
+ dlg->log(QCString("Error: ") + cmsg);
+ break;
+
+ case OBEXFTP_EV_ERR:
+ dlg->log(QCString("failed: ") + cmsg);
+ dlg->doneProgress();
+ break;
+ case OBEXFTP_EV_OK:
+ dlg->log(QCString("done"));
+ dlg->doneProgress();
+ break;
+
+ case OBEXFTP_EV_CONNECTING:
+ dlg->log(QCString("Connecting..."));
+ break;
+ case OBEXFTP_EV_DISCONNECTING:
+ dlg->log(QCString("Disconnecting..."));
+ break;
+ case OBEXFTP_EV_SENDING:
+ dlg->log(QCString("Sending ") + msg);
+ break;
+ case OBEXFTP_EV_RECEIVING:
+ dlg->log(QCString("Receiving ") + msg);
+ break;
+
+ case OBEXFTP_EV_LISTENING:
+ dlg->log(QCString("Waiting for incoming connection"));
+ break;
+
+ case OBEXFTP_EV_CONNECTIND:
+ dlg->log(QCString("Incoming connection"));
+ break;
+ case OBEXFTP_EV_DISCONNECTIND:
+ dlg->log(QCString("Disconnecting"));
+ break;
+
+ case OBEXFTP_EV_INFO:
+ // 64 bit problems ?
+ dlg->log(QString("Got info ") + QString::number((int)msg));
+ break;
+
+ case OBEXFTP_EV_BODY:
+ break;
+
+ case OBEXFTP_EV_PROGRESS:
+ dlg->incProgress();
+ break;
+ }
+}
+
+//eof