author | zecke <zecke> | 2002-10-11 22:31:15 (UTC) |
---|---|---|
committer | zecke <zecke> | 2002-10-11 22:31:15 (UTC) |
commit | c8c961b4106f49f544195733cef17af5f15f6bb8 (patch) (side-by-side diff) | |
tree | 3db3cad73021d14c417de2166249ec9e7a5f1aa4 | |
parent | 597cda9456f8ef883d486b6ed7d7c09339919da9 (diff) | |
download | opie-c8c961b4106f49f544195733cef17af5f15f6bb8.zip opie-c8c961b4106f49f544195733cef17af5f15f6bb8.tar.gz opie-c8c961b4106f49f544195733cef17af5f15f6bb8.tar.bz2 |
suspending connections in rawMode... closeRawIO afterwards please
Progress for FileTransfer
FileTransferLayer updates. ErrorCodes + Better methods cancel and better progress
default switch to FileTransfer
TabWidget is a OTabWidget again
-rw-r--r-- | noncore/apps/opie-console/default.cpp | 8 | ||||
-rw-r--r-- | noncore/apps/opie-console/file_layer.h | 21 | ||||
-rw-r--r-- | noncore/apps/opie-console/filetransfer.cpp | 143 | ||||
-rw-r--r-- | noncore/apps/opie-console/filetransfer.h | 15 | ||||
-rw-r--r-- | noncore/apps/opie-console/io_layer.cpp | 3 | ||||
-rw-r--r-- | noncore/apps/opie-console/io_layer.h | 8 | ||||
-rw-r--r-- | noncore/apps/opie-console/io_serial.cpp | 16 | ||||
-rw-r--r-- | noncore/apps/opie-console/io_serial.h | 1 | ||||
-rw-r--r-- | noncore/apps/opie-console/opie-console.pro | 6 | ||||
-rw-r--r-- | noncore/apps/opie-console/tabwidget.cpp | 9 | ||||
-rw-r--r-- | noncore/apps/opie-console/tabwidget.h | 4 |
11 files changed, 197 insertions, 37 deletions
diff --git a/noncore/apps/opie-console/default.cpp b/noncore/apps/opie-console/default.cpp index a6c3bc4..b092273 100644 --- a/noncore/apps/opie-console/default.cpp +++ b/noncore/apps/opie-console/default.cpp @@ -1,36 +1,36 @@ #include "io_serial.h" -#include "sz_transfer.h" +#include "filetransfer.h" #include "serialconfigwidget.h" #include "irdaconfigwidget.h" #include "btconfigwidget.h" #include "terminalwidget.h" #include "vt102emulation.h" #include "default.h" extern "C" { // FILE Transfer Stuff FileTransferLayer* newSZTransfer(IOLayer* lay) { - return new SzTransfer( SzTransfer::SZ, lay ); + return new FileTransfer( FileTransfer::SZ, lay ); } FileTransferLayer* newSYTransfer(IOLayer* lay) { - return new SzTransfer( SzTransfer::SY, lay ); + return new FileTransfer( FileTransfer::SY, lay ); } FileTransferLayer* newSXTransfer(IOLayer* lay) { - return new SzTransfer( SzTransfer::SX, lay ); + return new FileTransfer(FileTransfer ::SX, lay ); } // Layer stuff IOLayer* newSerialLayer( const Profile& prof) { return new IOSerial( prof ); } IOLayer* newBTLayer( const Profile& ) { return 0l; } IOLayer* newIrDaLayer( const Profile& ) { return 0l; } // Connection Widgets ProfileDialogWidget* newSerialWidget( const QString& str, QWidget* wid ) { return new SerialConfigWidget( str, wid ); diff --git a/noncore/apps/opie-console/file_layer.h b/noncore/apps/opie-console/file_layer.h index 0bd0fd1..bf31540 100644 --- a/noncore/apps/opie-console/file_layer.h +++ b/noncore/apps/opie-console/file_layer.h @@ -1,54 +1,69 @@ #ifndef OPIE_FILE_LAYER_H #define OPIE_FILE_LAYER_H +#include <qmap.h> + #include "io_layer.h" class QFile; /** * this is the layer for sending files */ class FileTransferLayer : public QObject { - Q_OBJECT public: + enum Errors{ + NotSupported, + StartError, + NoError, + Unknown, + Undefined, + Incomplete + }; /** *the io layer to be used */ FileTransferLayer( IOLayer* ); virtual ~FileTransferLayer(); public slots: /** * send a file over the layer */ virtual void sendFile( const QString& file ) = 0; virtual void sendFile( const QFile& ) = 0; + virtual void cancel() = 0; signals: /** * sent the file */ void sent(); /** * an error occured */ void error( int, const QString& ); /* - * 100 == done + * @param file The file to send + * @param progress the progress made from 0-100 + * @param speed Speed in bps + * @param hours The hours it take to finish + * @param minutes The minutes it takes to finish + * @param send The seconds... * */ - void progress( const QString& file, int progress ); + void progress( const QString& file, int progress, int speed, int hours, int minutes, int seconds ); protected: IOLayer* layer(); private: IOLayer* m_layer; }; #endif diff --git a/noncore/apps/opie-console/filetransfer.cpp b/noncore/apps/opie-console/filetransfer.cpp index 78982bd..7b75d35 100644 --- a/noncore/apps/opie-console/filetransfer.cpp +++ b/noncore/apps/opie-console/filetransfer.cpp @@ -1,142 +1,245 @@ #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <fcntl.h> #include <unistd.h> #include <qcstring.h> #include <qsocketnotifier.h> #include <opie/oprocess.h> #include "filetransfer.h" +/** + * + * +class FileTransferControl { +public: + FileTransferControl(); + ~FileTransferControl(); + + +}; +*/ + bool FileTransfer::terminate = false; pid_t FileTransfer::m_pid; FileTransfer::FileTransfer( Type t, IOLayer* lay ) : FileTransferLayer( lay ), m_type( t ) { + signal(SIGPIPE, SIG_IGN ); signal( SIGCHLD, signal_handler ); + m_not = 0l; } FileTransfer::~FileTransfer() { } /** * now we will send the file. * * we request an fd. The IOLayer should be closed * then we will setup a pipe for progress communication * then we will dup2 the m_fd in the forked process * to do direct IO from and to the fd */ void FileTransfer::sendFile( const QString& file ) { + m_prog =-1; m_fd = layer()->rawIO(); // // m_fd = ::open("/dev/ttyS0", O_RDWR); - + m_file = file; if ( pipe( m_comm ) < 0 ) m_comm[0] = m_comm[1] = 0; if ( pipe( m_info ) < 0 ) m_info[0] = m_info[1] = 0; - qWarning("output:"+file ); + m_pid = fork(); switch( m_pid ) { + case -1: + emit error( StartError, tr("Was not able to fork") ); + break; case 0:{ setupChild(); + qWarning("output:"+file ); /* exec */ char* verbose = "-vv"; char* binray = "-b"; /* we should never return from here */ execlp("sz", "sz", verbose, binray, file.latin1(), NULL ); /* communication for error!*/ char resultByte =1; if (m_info[1] ) write(m_info[1], &resultByte, 1 ); _exit( -1 ); break; } default:{ if ( m_info[1] ) close( m_info[1] ); if ( m_info[0] ) for (;;) { char resultByte; int len; len = read(m_info[0], &resultByte, 1 ); /* len == 1 start up failed */ - if ( len == 1 ) + if ( len == 1 ) { + emit error( StartError, tr("Could not start") ); return; + } if ( len == -1 ) if ( (errno == ECHILD ) || (errno == EINTR ) ) continue; // len == 0 or something like this break; } if ( m_info[0] ) close( m_info[0] ); terminate = false; fd_set fds; struct timeval timeout; int sel; /* replace by QSocketNotifier!!! */ - while (!terminate) { - FD_ZERO( &fds ); - FD_SET( m_comm[0], &fds ); - sel = select( m_comm[0]+1, &fds, NULL, NULL, &timeout ); - if (sel ) { - if ( FD_ISSET(m_comm[0], &fds ) ) { - printf("out:"); - QByteArray ar(4096); - int len = read(m_comm[0], ar.data(), 4096 ); - for (int i = 0; i < len; i++ ) { - // printf("%c", ar[i] ); - } - printf("\n"); - } - } - } - break; + m_not = new QSocketNotifier(m_comm[0], QSocketNotifier::Read ); + connect(m_not, SIGNAL(activated(int) ), + this, SLOT(slotRead() ) ); } + break; } } +/* + * let's call the one with the filename + */ void FileTransfer::sendFile( const QFile& file ) { sendFile( file.name() ); } +/* + * our signal handler to be replaced by + * a procctl thingie + */ void FileTransfer::signal_handler(int ) { + qWarning("Terminated"); int status; signal( SIGCHLD, signal_handler ); waitpid( m_pid, &status, WNOHANG ); terminate = true; } + +/* + * setting up communication + * between parent child and ioLayer + */ void FileTransfer::setupChild() { /* * we do not want to read from our * information channel */ if (m_info[0] ) close(m_info[0] ); /* * FD_CLOEXEC will close the * fd on successfull exec */ if (m_info[1] ) fcntl(m_info[1], F_SETFD, FD_CLOEXEC ); if (m_comm[0] ) close( m_comm[0] ); /* * now set the communication * m_fd STDIN_FILENO * STDOUT_FILENO * STDERR_FILENO */ dup2( m_fd, STDIN_FILENO ); dup2( m_fd, STDOUT_FILENO ); dup2( m_comm[1], STDERR_FILENO ); } + +/* + * read from the stderr of the child + * process + */ +void FileTransfer::slotRead() { + QByteArray ar(4096); + int len = read(m_comm[0], ar.data(), 4096 ); + qWarning("slot read %d", len); + for (int i = 0; i < len; i++ ) { + // printf("%c", ar[i] ); + } + ar.resize( len ); + QString str( ar ); + QStringList lis = QStringList::split(' ', str ); + /* + * Transfer finished.. either complete or incomplete + */ + if ( lis[0].simplifyWhiteSpace() == "Transfer" ) { + qWarning("sent!!!!"); + emit sent(); + return; + } + /* + * do progress reading + */ + slotProgress( lis ); + + +} +/* + * find the progress + */ +void FileTransfer::slotProgress( const QStringList& list ) { + bool complete = true; + int min, sec; + int bps; + unsigned long sent, total; + + min = sec = bps = -1; + sent = total = 0; + + // Data looks like this + // 0 1 2 3 4 5 + // Bytes Sent 65536/11534336 BPS:7784 ETA 24:33 + QStringList progi = QStringList::split('/', list[2].simplifyWhiteSpace() ); + sent = progi[0].toULong(&complete ); + if (!complete ) return; + + total = progi[1].toULong(&complete ); + if (!complete || total == 0) { + qWarning("returning!!"); + return; + } + + qWarning("%s, %d, %d", progi.join("/").latin1(), sent, total ); + + double pro = (double)sent/total; + int prog = pro * 100; + + // speed + progi = QStringList::split(':', list[3].simplifyWhiteSpace() ); + bps = progi[1].toInt(); + + // time + progi = QStringList::split(':', list[5].simplifyWhiteSpace() ); + min = progi[0].toInt(); + sec = progi[1].toInt(); + + + qWarning("Prog!:%d", prog ); + if ( prog > m_prog ) { + m_prog = prog; + emit progress(m_file, m_prog, bps, -1, min , sec ); + qWarning("Progress: %s, %d\%, %d, %d:%d", m_file.latin1(), m_prog, bps, min, sec ); + } + +} +void FileTransfer::cancel() { + ::kill(m_pid,9 ); + delete m_not; +} diff --git a/noncore/apps/opie-console/filetransfer.h b/noncore/apps/opie-console/filetransfer.h index 06c6d12..0829f16 100644 --- a/noncore/apps/opie-console/filetransfer.h +++ b/noncore/apps/opie-console/filetransfer.h @@ -1,38 +1,53 @@ #ifndef OPIE_FILE_TRANSFER_H #define OPIE_FILE_TRANSFER_H #include <sys/types.h> #include <qfile.h> +#include <qstringlist.h> #include "file_layer.h" class QSocketNotifier; class OProcess; +class FileTransferControl; class FileTransfer : public FileTransferLayer{ Q_OBJECT + friend class FileTransferControl; public: enum Type { SZ = 0, SX, SY }; FileTransfer( Type t, IOLayer* ); ~FileTransfer(); void sendFile( const QString& file ); void sendFile( const QFile& ); + void cancel(); private slots: void setupChild(); + void slotRead(); + void slotProgress( const QStringList& ); private: + /* + * FIXME? What does happen if we've + * two FileTransfers at a time? + * Have a procctl which does listen + * for termination and then send a signal + */ static pid_t m_pid; int m_fd; + int m_prog; int m_info[2]; int m_comm[2]; + QString m_file; Type m_type; + QSocketNotifier *m_not; static void signal_handler(int); static bool terminate; }; #endif diff --git a/noncore/apps/opie-console/io_layer.cpp b/noncore/apps/opie-console/io_layer.cpp index 79d47f5..9ba2f70 100644 --- a/noncore/apps/opie-console/io_layer.cpp +++ b/noncore/apps/opie-console/io_layer.cpp @@ -2,16 +2,19 @@ IOLayer::IOLayer() : QObject() { } IOLayer::IOLayer(const Profile &) : QObject() { } IOLayer::~IOLayer() { } int IOLayer::rawIO()const{ return -1; } +void IOLayer::closeRawIO(int) { + +} diff --git a/noncore/apps/opie-console/io_layer.h b/noncore/apps/opie-console/io_layer.h index 7745021..bf5a893 100644 --- a/noncore/apps/opie-console/io_layer.h +++ b/noncore/apps/opie-console/io_layer.h @@ -41,34 +41,42 @@ public: virtual ~IOLayer(); /** * a small internal identifier */ virtual QString identifier() const = 0; /** * a short name */ virtual QString name() const = 0; /** * a file descriptor which opens * the device for io but does not * do any ioctling on it... + * and it'll stop listening to the before opened + * device */ virtual int rawIO()const; + + /** + * will close the rawIO stuff + * and will listen to it's data again... + */ + virtual void closeRawIO(int); signals: /** * received input as QCString */ virtual void received( const QByteArray& ) = 0; /** * an error occured * int for the error number * and QString for a text */ virtual void error( int, const QString& ) = 0; public slots: /** * send a QCString to the device diff --git a/noncore/apps/opie-console/io_serial.cpp b/noncore/apps/opie-console/io_serial.cpp index 845f4be..4129d64 100644 --- a/noncore/apps/opie-console/io_serial.cpp +++ b/noncore/apps/opie-console/io_serial.cpp @@ -14,32 +14,33 @@ IOSerial::IOSerial(const Profile &config) : IOLayer(config) { IOSerial::~IOSerial() { if (m_fd) { close(); } } void IOSerial::send(const QByteArray &data) { if (m_fd) { write(m_fd, data.data(), data.size()); } else { emit error(Refuse, tr("Not connected")); } } void IOSerial::close() { + qWarning("closing!"); if (m_fd) { delete m_read; delete m_error; ::close(m_fd); m_fd = 0; } else { emit error(Refuse, tr("Not connected")); } } bool IOSerial::open() { qWarning("open"); if (!m_fd) { qWarning("going to open %s", m_device.latin1()); struct termios tty; m_fd = ::open(m_device, O_RDWR | O_NOCTTY | O_NONBLOCK); @@ -104,33 +105,33 @@ bool IOSerial::open() { tty.c_cflag &= ~(PARENB | PARODD); if (m_parity & ParityEven) tty.c_cflag |= PARENB; else if (m_parity & ParityOdd) tty.c_cflag |= (PARENB | PARODD); /* Set the changes */ tcsetattr(m_fd, TCSANOW, &tty); /* Notifications on read & errors */ m_read = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); m_error = new QSocketNotifier(m_fd, QSocketNotifier::Exception, this); connect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived())); connect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured())); return TRUE; } else { - qWarning("opened"); + qWarning(" already opened"); emit error(Refuse, tr("Device is already connected")); m_fd = 0; return FALSE; } } void IOSerial::reload(const Profile &config) { m_device = config.readEntry("Device", SERIAL_DEFAULT_DEVICE); qWarning( "Dev" +m_device ); qWarning( "Conf:" +config.readEntry("Device") ); m_baud = config.readNumEntry("Baud", SERIAL_DEFAULT_BAUD); m_parity = config.readNumEntry("Parity", SERIAL_DEFAULT_PARITY); m_dbits = config.readNumEntry("DataBits", SERIAL_DEFAULT_DBITS); m_sbits = config.readNumEntry("StopBits", SERIAL_DEFAULT_SBITS); m_flow = config.readNumEntry("Flow", SERIAL_DEFAULT_FLOW); } @@ -163,20 +164,33 @@ void IOSerial::dataArrived() { if (len == 0) close(); if (len < 0) return; array.resize( len ); emit received(array); } QString IOSerial::identifier() const { return "serial"; } QString IOSerial::name() const { return "RS232 Serial IO Layer"; } int IOSerial::rawIO()const { + if (m_read ) + disconnect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived())); + if (m_error ) + disconnect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured())); + int fd = ::open(m_device, O_RDWR ); return fd; }; +void IOSerial::closeRawIO(int fd) { + if (m_read ) + connect(m_read, SIGNAL(activated(int)), this, SLOT(dataArrived())); + if (m_error ) + connect(m_error, SIGNAL(activated(int)), this, SLOT(errorOccured())); + + ::close( fd ); +} diff --git a/noncore/apps/opie-console/io_serial.h b/noncore/apps/opie-console/io_serial.h index 00a6d2c..facbbc1 100644 --- a/noncore/apps/opie-console/io_serial.h +++ b/noncore/apps/opie-console/io_serial.h @@ -23,32 +23,33 @@ public: ParityOdd, ParitySpace, ParityMark }; enum Flow { FlowHW = 0x01, FlowSW = 0x02 }; IOSerial(const Profile &); ~IOSerial(); QString identifier() const; QString name() const; int rawIO()const; + void closeRawIO(int fd ); signals: void received(const QByteArray &); void error(int, const QString &); public slots: void send(const QByteArray &); bool open(); void close(); void reload(const Profile &); protected: int baud(int baud) const; protected slots: void dataArrived(); void errorOccured(); protected: QSocketNotifier *m_read; QSocketNotifier *m_error; diff --git a/noncore/apps/opie-console/opie-console.pro b/noncore/apps/opie-console/opie-console.pro index 996eb84..37cef92 100644 --- a/noncore/apps/opie-console/opie-console.pro +++ b/noncore/apps/opie-console/opie-console.pro @@ -1,64 +1,64 @@ TEMPLATE = app #CONFIG = qt warn_on release CONFIG = qt debug DESTDIR = $(OPIEDIR)/bin HEADERS = io_layer.h io_serial.h io_irda.h \ - file_layer.h sz_transfer.h \ + file_layer.h filetransfer.h \ metafactory.h \ session.h \ mainwindow.h \ profile.h \ profileconfig.h \ profilemanager.h \ configwidget.h \ tabwidget.h \ configdialog.h \ emulation_layer.h \ vt102emulation.h \ common.h \ history.h \ screen.h \ keytrans.h \ widget_layer.h \ transferdialog.h \ profiledialogwidget.h \ profileeditordialog.h \ default.h \ terminalwidget.h \ iolayerbase.h \ serialconfigwidget.h irdaconfigwidget.h btconfigwidget.h \ emulation_widget.h SOURCES = io_layer.cpp io_serial.cpp io_irda.cpp \ - file_layer.cpp sz_transfer.cpp \ + file_layer.cpp filetransfer.cpp \ main.cpp \ metafactory.cpp \ session.cpp \ mainwindow.cpp \ profile.cpp \ profileconfig.cpp \ profilemanager.cpp \ tabwidget.cpp \ configdialog.cpp \ emulation_layer.cpp \ vt102emulation.cpp \ history.cpp \ screen.cpp \ keytrans.cpp \ widget_layer.cpp \ transferdialog.cpp \ profiledialogwidget.cpp \ profileeditordialog.cpp \ default.cpp \ terminalwidget.cpp \ iolayerbase.cpp \ serialconfigwidget.cpp irdaconfigwidget.cpp btconfigwidget.cpp \ emulation_widget.cpp INTERFACES = configurebase.ui editbase.ui INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include -LIBS += -lqpe -lopie +LIBS += -lqpe -lopie TARGET = opie-console diff --git a/noncore/apps/opie-console/tabwidget.cpp b/noncore/apps/opie-console/tabwidget.cpp index cfaef91..466b536 100644 --- a/noncore/apps/opie-console/tabwidget.cpp +++ b/noncore/apps/opie-console/tabwidget.cpp @@ -1,43 +1,44 @@ #include "tabwidget.h" TabWidget::TabWidget( QWidget* parent, const char* name ) - : QTabWidget( parent, name ) { + : OTabWidget( parent, name ) { connect(this, SIGNAL( currentChanged(QWidget*) ), this, SLOT( slotCurChanged(QWidget*) ) ); } TabWidget::~TabWidget() { } void TabWidget::add( Session* ses ) { if ( !ses->widgetStack() ) return; qWarning("going to add it"); //reparent( ses->widgetStack(), QPoint() ); - //addTab( ses->widgetStack(), "console/konsole", ses->name() ); - addTab( ses->widgetStack(), ses->name() ); + addTab( ses->widgetStack(), "console/konsole", ses->name() ); + //addTab( ses->widgetStack(), ses->name() ); m_map.insert( ses->widgetStack(), ses ); } void TabWidget::remove( Session* ses ) { m_map.remove( ses->widgetStack() ); removePage( ses->widgetStack() ); } void TabWidget::slotCurChanged( QWidget* wid ) { QMap<QWidget*, Session*>::Iterator it; it = m_map.find( wid ); if ( it == m_map.end() ) { return; } emit activated( it.data() ); } void TabWidget::setCurrent( Session* ses ) { if (!ses ) return; - showPage( ses->widgetStack() ); + //showPage( ses->widgetStack() ); + setCurrentTab( ses->widgetStack() ); } diff --git a/noncore/apps/opie-console/tabwidget.h b/noncore/apps/opie-console/tabwidget.h index 42a00ec..cbaa0f1 100644 --- a/noncore/apps/opie-console/tabwidget.h +++ b/noncore/apps/opie-console/tabwidget.h @@ -1,28 +1,28 @@ #ifndef OPIE_TAB_WIDGET_H #define OPIE_TAB_WIDGET_H #include <qmap.h> -#include <qtabwidget.h> +#include <opie/otabwidget.h> #include "session.h" /** * This is our central tab widget * we can add sessions here */ -class TabWidget : public QTabWidget{ +class TabWidget : public OTabWidget{ Q_OBJECT public: TabWidget(QWidget *parent, const char* name ); ~TabWidget(); void add( Session* ); void remove( Session* ); void setCurrent( Session* ); signals: void activated(Session* ses ); private slots: void slotCurChanged( QWidget* wid ); private: QMap<QWidget*, Session*> m_map; }; |