X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/af49caa18e3930dc7115f56c402f6d27e2c42ef4..39f89141b06c:/src/panels/terminal/terminalpanel.cpp diff --git a/src/panels/terminal/terminalpanel.cpp b/src/panels/terminal/terminalpanel.cpp index 593015147..12b319f3c 100644 --- a/src/panels/terminal/terminalpanel.cpp +++ b/src/panels/terminal/terminalpanel.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2007 by Peter Penz * + * Copyright (C) 2007-2010 by Peter Penz * * * * 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 * @@ -20,15 +20,19 @@ #include "terminalpanel.h" #include -#include +#include #include #include +#include +#include #include #include TerminalPanel::TerminalPanel(QWidget* parent) : Panel(parent), + m_clearTerminal(true), + m_mostLocalUrlJob(0), m_layout(0), m_terminal(0), m_terminalWidget(0) @@ -48,22 +52,26 @@ QSize TerminalPanel::sizeHint() const return size; } -void TerminalPanel::setUrl(const KUrl& url) +void TerminalPanel::terminalExited() { - if (!url.isValid() || (url == Panel::url())) { - return; + emit hideTerminalPanel(); + m_terminal = 0; +} + +bool TerminalPanel::urlChanged() +{ + if (!url().isValid()) { + return false; } - Panel::setUrl(url); - if ((m_terminal != 0) && isVisible() && url.isLocalFile()) { - m_terminal->sendInput("cd " + KShell::quoteArg(url.toLocalFile()) + '\n'); + const bool sendInput = (m_terminal != 0) + && (m_terminal->foregroundProcessId() == -1) + && isVisible(); + if (sendInput) { + changeDir(url()); } -} -void TerminalPanel::terminalExited() -{ - emit hideTerminalPanel(); - m_terminal = 0; + return true; } void TerminalPanel::showEvent(QShowEvent* event) @@ -74,23 +82,69 @@ void TerminalPanel::showEvent(QShowEvent* event) } if (m_terminal == 0) { + m_clearTerminal = true; KPluginFactory* factory = KPluginLoader("libkonsolepart").factory(); KParts::ReadOnlyPart* part = factory ? (factory->create(this)) : 0; if (part != 0) { connect(part, SIGNAL(destroyed(QObject*)), this, SLOT(terminalExited())); m_terminalWidget = part->widget(); m_layout->addWidget(m_terminalWidget); - m_terminal = qobject_cast(part); - m_terminal->showShellInDir(url().path()); + m_terminal = qobject_cast(part); } } if (m_terminal != 0) { - m_terminal->sendInput("cd " + KShell::quoteArg(url().path()) + '\n'); - m_terminal->sendInput("clear\n"); + m_terminal->showShellInDir(url().toLocalFile()); + changeDir(url()); m_terminalWidget->setFocus(); } Panel::showEvent(event); } +void TerminalPanel::changeDir(const KUrl& url) +{ + delete m_mostLocalUrlJob; + m_mostLocalUrlJob = 0; + + if (url.isLocalFile()) { + sendCdToTerminal(url.toLocalFile()); + } else { + m_mostLocalUrlJob = KIO::mostLocalUrl(url, KIO::HideProgressInfo); + m_mostLocalUrlJob->ui()->setWindow(this); + connect(m_mostLocalUrlJob, SIGNAL(result(KJob*)), this, SLOT(slotMostLocalUrlResult(KJob*))); + } +} + +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 Ctrl+C is send. + QString cancel; + cancel.append(QChar(3)); + cancel.append(QChar('c')); + m_terminal->sendInput(cancel); + } + + m_terminal->sendInput("cd " + KShell::quoteArg(dir) + '\n'); + + if (m_clearTerminal) { + m_terminal->sendInput("clear\n"); + m_clearTerminal = false; + } +} + +void TerminalPanel::slotMostLocalUrlResult(KJob* job) +{ + KIO::StatJob* statJob = static_cast(job); + const KUrl url = statJob->mostLocalUrl(); + if (url.isLocalFile()) { + sendCdToTerminal(url.toLocalFile()); + } + + m_mostLocalUrlJob = 0; +} + #include "terminalpanel.moc"