Commit 2af04206 authored by Kurt Hindenburg's avatar Kurt Hindenburg

Allow Konsole's zmodem file transfers to work.

Thanks to Thomas Dreibholz <dreibh@iem.uni-due.de> for the patch.  I removed
some whitespace changes from his patch on reviewboard.

BUG: 200744

svn path=/trunk/KDE/kdebase/apps/konsole/; revision=1016847
parent 6484ae92
<!DOCTYPE kpartgui>
<kpartgui name="session" version="2">
<kpartgui name="session" version="8">
<MenuBar>
<Menu name="file">
<Action name="open-browser" group="session-operations"/>
......@@ -12,6 +12,7 @@
<Action name="rename-session" group="session-edit-operations" />
<Separator group="session-edit-operations"/>
<Action name="copy-input-to" group="session-edit-operations"/>
<Action name="zmodem-upload" group="session-edit-operations"/>
<Separator group="session-edit-operations"/>
<Action name="clear" group="session-edit-operations" />
<Action name="clear-and-reset" group="session-edit-operations" />
......
......@@ -3,6 +3,7 @@
Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
Copyright 2009 by Thomas Dreibholz <dreibh@iem.uni-due.de>
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
......@@ -1031,8 +1032,6 @@ void Session::startZModem(const QString &zmodem, const QString &dir, const QStri
if (!dir.isEmpty())
_zmodemProc->setWorkingDirectory(dir);
_zmodemProc->start();
connect(_zmodemProc,SIGNAL (readyReadStandardOutput()),
this, SLOT(zmodemReadAndSendBlock()));
connect(_zmodemProc,SIGNAL (readyReadStandardError()),
......@@ -1040,14 +1039,16 @@ void Session::startZModem(const QString &zmodem, const QString &dir, const QStri
connect(_zmodemProc,SIGNAL (finished(int,QProcess::ExitStatus)),
this, SLOT(zmodemFinished()));
disconnect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) );
connect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(zmodemRcvBlock(const char*,int)) );
_zmodemProc->start();
disconnect( _shellProcess,SIGNAL(receivedData(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) );
connect( _shellProcess,SIGNAL(receivedData(const char*,int)), this, SLOT(zmodemRcvBlock(const char*,int)) );
_zmodemProgress = new ZModemDialog(QApplication::activeWindow(), false,
i18n("ZModem Progress"));
connect(_zmodemProgress, SIGNAL(user1Clicked()),
this, SLOT(zmodemDone()));
this, SLOT(zmodemFinished()));
_zmodemProgress->show();
}
......@@ -1100,14 +1101,18 @@ void Session::zmodemRcvBlock(const char *data, int len)
void Session::zmodemFinished()
{
if (_zmodemProc)
{
delete _zmodemProc;
_zmodemProc = 0;
/* zmodemFinished() is called by QProcess's finished() and
ZModemDialog's user1Clicked(). Therefore, an invokation by
user1Clicked() will recursively invoke this function again
when the KProcess is deleted! */
if (_zmodemProc) {
KProcess* process = _zmodemProc;
_zmodemProc = 0; // Set _zmodemProc to 0 avoid recursive invokations!
_zmodemBusy = false;
delete process; // Now, the KProcess may be disposed safely.
disconnect( _shellProcess,SIGNAL(block_in(const char*,int)), this ,SLOT(zmodemRcvBlock(const char*,int)) );
connect( _shellProcess,SIGNAL(block_in(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) );
disconnect( _shellProcess,SIGNAL(receivedData(const char*,int)), this ,SLOT(zmodemRcvBlock(const char*,int)) );
connect( _shellProcess,SIGNAL(receivedData(const char*,int)), this, SLOT(onReceiveBlock(const char*,int)) );
_shellProcess->sendData("\030\030\030\030", 4); // Abort
_shellProcess->sendData("\001\013\n", 3); // Try to get prompt back
......
/*
Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
Copyright 2009 by Thomas Dreibholz <dreibh@iem.uni-due.de>
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
......@@ -31,8 +32,10 @@
#include <KInputDialog>
#include <KLocale>
#include <KMenu>
#include <KMessageBox>
#include <KRun>
#include <kshell.h>
#include <KStandardDirs>
#include <KToggleAction>
#include <KUrl>
#include <KXMLGUIFactory>
......@@ -140,7 +143,10 @@ SessionController::SessionController(Session* session , TerminalDisplay* view, Q
// listen for output changes to set activity flag
connect( _session->emulation() , SIGNAL(outputChanged()) , this ,
SLOT(fireActivity()) );
// listen for detection of ZModem transfer
connect( _session , SIGNAL(zmodemDetected()) , this , SLOT(zmodemDownload()) );
// listen for flow control status changes
connect( _session , SIGNAL(flowControlEnabledChanged(bool)) , _view ,
SLOT(setFlowControlWarningEnabled(bool)) );
......@@ -426,6 +432,12 @@ void SessionController::setupActions()
action->setIcon( KIcon("edit-clear-history") );
connect( action , SIGNAL(triggered()) , this , SLOT(clearAndReset()) );
action = collection->addAction("zmodem-upload");
action->setText( i18n( "&ZModem Upload..." ) );
action->setIcon( KIcon("document-open") );
action->setShortcut( QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_U) );
connect( action , SIGNAL(triggered()) , this , SLOT(zmodemUpload()) );
// Monitor
toggleAction = new KToggleAction(i18n("Monitor for &Activity"),this);
toggleAction->setShortcut( QKeySequence(Qt::CTRL+Qt::SHIFT+Qt::Key_A) );
......@@ -1032,6 +1044,57 @@ void SessionController::sessionStateChanged(int state)
}
}
void SessionController::zmodemDownload()
{
QString zmodem = KGlobal::dirs()->findExe("rz");
if(zmodem.isEmpty()) {
zmodem = KGlobal::dirs()->findExe("lrz");
}
if(!zmodem.isEmpty()) {
const QString path = KFileDialog::getExistingDirectory(
QString(), _view,
i18n("Save ZModem Download to..."));
if(!path.isEmpty()) {
_session->startZModem(zmodem, path, QStringList());
return;
}
}
else {
KMessageBox::error(_view,
i18n("<p>A ZModem file transfer attempt has been detected, "
"but no suitable ZModem software was found on this system.\n"
"<p>You may wish to install the 'rzsz' or 'lrzsz' package.\n"));
}
_session->cancelZModem();
return;
}
void SessionController::zmodemUpload()
{
if(_session->isZModemBusy()) {
KMessageBox::sorry(_view,
i18n("<p>The current session already has a ZModem file transfer in progress."));
return;
}
QString zmodem = KGlobal::dirs()->findExe("sz");
if(zmodem.isEmpty()) {
zmodem = KGlobal::dirs()->findExe("lsz");
}
if(zmodem.isEmpty()) {
KMessageBox::sorry(_view,
i18n("<p>No suitable ZModem software was found on this system.\n"
"<p>You may wish to install the 'rzsz' or 'lrzsz' package.\n"));
return;
}
QStringList files = KFileDialog::getOpenFileNames(KUrl(), QString(), _view,
i18n("Select Files for ZModem Upload"));
if(!files.isEmpty()) {
_session->startZModem(zmodem, QString::null, files);
}
}
SessionTask::SessionTask(QObject* parent)
: QObject(parent)
, _autoDelete(false)
......
/*
Copyright 2006-2008 by Robert Knight <robertknight@gmail.com>
Copyright 2009 by Thomas Dreibholz <dreibh@iem.uni-due.de>
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
......@@ -208,6 +209,9 @@ private slots:
// display area
void updateSearchFilter();
void zmodemDownload();
void zmodemUpload();
private:
// begins the search
......
......@@ -34,8 +34,8 @@ ZModemDialog::ZModemDialog(QWidget *parent, bool modal, const QString &caption)
setButtons( User1|Close );
setButtonGuiItem( User1, KGuiItem(i18n("&Stop")) );
setDefaultButton( User1 );
setEscapeButton(User1);
setDefaultButton( Close );
setEscapeButton( User1 );
showButtonSeparator( true );
enableButton(Close, false);
......
......@@ -154,6 +154,9 @@ void fillAboutData(KAboutData& aboutData)
aboutData.addCredit(ki18n("Stephan Binner"),
ki18n("Bug fixes and general improvements"),
"binner@kde.org");
aboutData.addCredit(ki18n("Thomas Dreibholz"),
ki18n("General improvements"),
"dreibh@iem.uni-due.de");
aboutData.addCredit(ki18n("Chris Machemer"),
ki18n("Bug fixes"),
"machey@ceinetworks.com");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment