summaryrefslogtreecommitdiff
authorzecke <zecke>2002-10-11 22:31:15 (UTC)
committer zecke <zecke>2002-10-11 22:31:15 (UTC)
commitc8c961b4106f49f544195733cef17af5f15f6bb8 (patch) (side-by-side diff)
tree3db3cad73021d14c417de2166249ec9e7a5f1aa4
parent597cda9456f8ef883d486b6ed7d7c09339919da9 (diff)
downloadopie-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
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/default.cpp8
-rw-r--r--noncore/apps/opie-console/file_layer.h21
-rw-r--r--noncore/apps/opie-console/filetransfer.cpp143
-rw-r--r--noncore/apps/opie-console/filetransfer.h15
-rw-r--r--noncore/apps/opie-console/io_layer.cpp3
-rw-r--r--noncore/apps/opie-console/io_layer.h8
-rw-r--r--noncore/apps/opie-console/io_serial.cpp16
-rw-r--r--noncore/apps/opie-console/io_serial.h1
-rw-r--r--noncore/apps/opie-console/opie-console.pro6
-rw-r--r--noncore/apps/opie-console/tabwidget.cpp9
-rw-r--r--noncore/apps/opie-console/tabwidget.h4
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;
};