]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Fix issue that the current terminal line does not get cleared before sending a cd...
authorPeter Penz <peter.penz19@gmail.com>
Sun, 14 Mar 2010 16:21:35 +0000 (16:21 +0000)
committerPeter Penz <peter.penz19@gmail.com>
Sun, 14 Mar 2010 16:21:35 +0000 (16:21 +0000)
The terminal interface does not provide an API for this, so as workaround backspaces are send. Not nice, but as the issue can lead to data loss, this solution is better than having nothing.

BUG: 161637

svn path=/trunk/KDE/kdebase/apps/; revision=1103207

src/panels/terminal/terminalpanel.cpp
src/panels/terminal/terminalpanel.h

index 3b77cd92e849420ea5a4416c95480fcae648cc26..856eed4c0fdbfce6a435a0108eb41578992b6549 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2007 by Peter Penz <peter.penz@gmx.at>                  *
+ *   Copyright (C) 2007-2010 by Peter Penz <peter.penz@gmx.at>             *
  *                                                                         *
  *   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  *
 #include <QBoxLayout>
 #include <QShowEvent>
 
-#include <kdebug.h>
-
 TerminalPanel::TerminalPanel(QWidget* parent) :
     Panel(parent),
+    m_clearTerminal(true),
+    m_mostLocalUrlJob(0),
     m_layout(0),
     m_terminal(0),
     m_terminalWidget(0)
@@ -64,7 +64,7 @@ void TerminalPanel::setUrl(const KUrl& url)
                            && (m_terminal->foregroundProcessId() == -1)
                            && isVisible();
     if (sendInput) {
-        cdUrl(url);
+        changeDir(url);
     }
 }
 
@@ -82,6 +82,7 @@ void TerminalPanel::showEvent(QShowEvent* event)
     }
 
     if (m_terminal == 0) {
+        m_clearTerminal = true;
         KPluginFactory* factory = KPluginLoader("libkonsolepart").factory();
         KParts::ReadOnlyPart* part = factory ? (factory->create<KParts::ReadOnlyPart>(this)) : 0;
         if (part != 0) {
@@ -93,28 +94,47 @@ void TerminalPanel::showEvent(QShowEvent* event)
     }
     if (m_terminal != 0) {
         m_terminal->showShellInDir(url().toLocalFile());
-        cdUrl(url());
-        m_terminal->sendInput("clear\n"); // TODO do clear after slotMostLocalUrlResult is called, for remote dirs?
+        changeDir(url());
         m_terminalWidget->setFocus();
     }
 
     Panel::showEvent(event);
 }
 
-void TerminalPanel::cdUrl(const KUrl& url)
+void TerminalPanel::changeDir(const KUrl& url)
 {
+    delete m_mostLocalUrlJob;
+    m_mostLocalUrlJob = 0;
+
     if (url.isLocalFile()) {
-        cdDirectory(url.toLocalFile());
+        sendCdToTerminal(url.toLocalFile());
     } else {
-        KIO::StatJob* job = KIO::mostLocalUrl(url, KIO::HideProgressInfo);
-        job->ui()->setWindow(this);
-        connect(job, SIGNAL(result(KJob*)), this, SLOT(slotMostLocalUrlResult(KJob*)));
+        m_mostLocalUrlJob = KIO::mostLocalUrl(url, KIO::HideProgressInfo);
+        m_mostLocalUrlJob->ui()->setWindow(this);
+        connect(m_mostLocalUrlJob, SIGNAL(result(KJob*)), this, SLOT(slotMostLocalUrlResult(KJob*)));
     }
 }
 
-void TerminalPanel::cdDirectory(const QString& dir)
+void TerminalPanel::sendCdToTerminal(const QString& dir)
 {
+    if (!m_clearTerminal) {
+        // The TerminalV2 interface does not provide a way to delete the
+        // current line before sending a new input. This is mandatory,
+        // otherwise sending a 'cd x' to a existing 'rm -rf *' might
+        // result in data loss. As workaround backspaces are send...
+        QString clearLine;
+        for (int i = 0; i < 256; ++i) {
+            clearLine.append(QChar(8));
+        }
+        m_terminal->sendInput(clearLine);
+    }
+
     m_terminal->sendInput("cd " + KShell::quoteArg(dir) + '\n');
+
+    if (m_clearTerminal) {
+        m_terminal->sendInput("clear\n");
+        m_clearTerminal = false;
+    }
 }
 
 void TerminalPanel::slotMostLocalUrlResult(KJob* job)
@@ -122,8 +142,10 @@ void TerminalPanel::slotMostLocalUrlResult(KJob* job)
     KIO::StatJob* statJob = static_cast<KIO::StatJob *>(job);
     const KUrl url = statJob->mostLocalUrl();
     if (url.isLocalFile()) {
-        cdDirectory(url.toLocalFile());
+        sendCdToTerminal(url.toLocalFile());
     }
+
+    m_mostLocalUrlJob = 0;
 }
 
 #include "terminalpanel.moc"
index 7b08483f64f7687024a9884553b1793827a51204..36114995eec964ccea1c39bcf21891ca0c805c38 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2007 by Peter Penz <peter.penz@gmx.at>                  *
+ *   Copyright (C) 2007-2010 by Peter Penz <peter.penz@gmx.at>             *
  *                                                                         *
  *   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  *
@@ -26,6 +26,10 @@ class TerminalInterfaceV2;
 class QVBoxLayout;
 class QWidget;
 
+namespace KIO {
+    class StatJob;
+};
+
 /**
  * @brief Shows the terminal which is synchronized with the URL of the
  *        active view.
@@ -57,10 +61,13 @@ private slots:
     void slotMostLocalUrlResult(KJob* job);
 
 private:
-    void cdUrl(const KUrl& url);
-    void cdDirectory(const QString& path);
+    void changeDir(const KUrl& url);
+    void sendCdToTerminal(const QString& path);
 
 private:
+    bool m_clearTerminal;
+    KIO::StatJob* m_mostLocalUrlJob;
+
     QVBoxLayout* m_layout;
     TerminalInterfaceV2* m_terminal;
     QWidget* m_terminalWidget;