提交 904c1d8c 编写于 作者: L Levi Armstrong

Initial Commit

上级 2a60b621
......@@ -2,12 +2,16 @@ include(../../ros_qtc_plugins.pri)
include(project_manager.pri)
include($$QTCREATOR_SOURCES/src/qtcreatorplugin.pri)
QTW_LIBRARY_PATH = $$(QTERMWIDGET_LIBRARY_PATH)
isEmpty(QTW_LIBRARY_PATH):QTW_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu
QTW_INCLUDE_PATH = $$(QTERMWIDGET_INCLUDE_PATH)
isEmpty(QTW_INCLUDE_PATH):QTW_INCLUDE_PATH=/usr/local/include
LIBS += -L$$QTW_LIBRARY_PATH -lqtermwidget5
INCLUDEPATH += $$(QTERMWIDGET_INCLUDE_PATH)
#QTW_LIBRARY_PATH = $$(QTERMWIDGET_LIBRARY_PATH)
#isEmpty(QTW_LIBRARY_PATH):QTW_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu
#QTW_INCLUDE_PATH = $$(QTERMWIDGET_INCLUDE_PATH)
#isEmpty(QTW_INCLUDE_PATH):QTW_INCLUDE_PATH=/usr/local/include
#LIBS += -L$$QTW_LIBRARY_PATH -lqtermwidget5
#INCLUDEPATH += $$(QTERMWIDGET_INCLUDE_PATH)
INCLUDEPATH += /usr/include
INCLUDEPATH += /usr/include/KDE
LIBS += -L/usr/lib -lkdecore -lkparts
HEADERS = \
ros_project_wizard.h \
......@@ -26,7 +30,8 @@ HEADERS = \
ros_terminal_pane.h \
ros_package_wizard.h \
remove_directory_dialog.h \
ros_workspace_watcher.h
ros_workspace_watcher.h \
terminal_tab_widget.h
SOURCES = \
ros_project_wizard.cpp \
......@@ -44,7 +49,8 @@ SOURCES = \
ros_terminal_pane.cpp \
ros_package_wizard.cpp \
remove_directory_dialog.cpp \
ros_workspace_watcher.cpp
ros_workspace_watcher.cpp \
terminal_tab_widget.cpp
RESOURCES += ros_project.qrc
FORMS += ros_make_step.ui \
......
......@@ -93,9 +93,9 @@ void ROSManager::unregisterProject(ROSProject *project)
m_projects.removeAll(project);
}
QTermWidget &ROSManager::startTerminal(int startnow, const QString name)
ROSTerminalPane *ROSManager::getTerminalPane()
{
return m_terminalPane->startTerminal(startnow, name);
return m_terminalPane;
}
} // namespace Internal
......
......@@ -57,7 +57,7 @@ public:
static ROSManager *instance();
QTermWidget &startTerminal(int startnow = 1, const QString name = QString());
ROSTerminalPane *getTerminalPane();
private:
QList<ROSProject *> m_projects;
......
......@@ -4,12 +4,11 @@
#include "ui_ros_generic_configuration.h"
#include "ros_build_configuration.h"
#include "ros_utils.h"
#include "ros_terminal_pane.h"
#include <projectexplorer/project.h>
#include <projectexplorer/processparameters.h>
#include <qtermwidget5/qtermwidget.h>
namespace ROSProjectManager {
namespace Internal {
......@@ -318,7 +317,6 @@ void ROSGenericRunStep::run(QFutureInterface<bool> &fi)
Q_UNUSED(fi);
ROSProject *rp = qobject_cast<ROSProject *>(target()->project());
ROSBuildConfiguration *bc = qobject_cast<ROSBuildConfiguration *>(target()->activeBuildConfiguration());
QString command;
command = QString::fromLatin1("%1 %2 %3 %4\n")
......@@ -327,19 +325,15 @@ void ROSGenericRunStep::run(QFutureInterface<bool> &fi)
m_target,
m_arguments);
//create terminal without starting shell
QTermWidget &terminal = ROSManager::instance()->startTerminal(0, QString::fromLatin1("%1 %2 %3").arg(m_command, m_package, m_target));
terminal.setWorkingDirectory(rp->projectDirectory().toString());
ROSTerminalPane *terminal = ROSManager::instance()->getTerminalPane();
//start bash now that everything is setup
terminal.startShellProgram();
terminal->createTerminal(QString::fromLatin1("%1 %2 %3").arg(m_command, m_package, m_target), QDir(rp->projectDirectory().toString()));
// source workspace (This is a hack because the setEnvironment is not working as I expected)
terminal.sendText(QLatin1String("source devel/setup.bash\n"));
terminal->sendInput(QLatin1String("source devel/setup.bash\n"));
//send roslaunch command
terminal.sendText(command);
terminal->sendInput(command);
}
QVariantMap ROSGenericRunStep::toMap() const
......
......@@ -17,15 +17,9 @@
#include <aggregation/aggregate.h>
#include <cstring>
#include <texteditor/texteditorsettings.h>
#include <texteditor/fontsettings.h>
#include <texteditor/behaviorsettings.h>
#include <QDir>
#include <QSettings>
#include <QKeySequence>
#include <QKeyEvent>
#include <QApplication>
#include <signal.h>
......@@ -33,161 +27,85 @@ namespace ROSProjectManager {
namespace Internal {
ROSTerminalPane::ROSTerminalPane() :
// m_terminalWidget(new TerminalTabWidget),
m_stopButton(new QToolButton),
m_zoomInButton(new QToolButton),
m_zoomOutButton(new QToolButton),
m_newTerminalButton(new QToolButton)
{
m_tabWidget = new QTabWidget();
m_tabWidget->setTabsClosable(true);
{
m_stopButton->setToolTip(tr("Kill active terminal's child process"));
m_stopButton->setIcon(Core::Icons::STOP_SMALL.icon());
m_zoomInButton->setToolTip(tr("Increase Font Size"));
m_zoomInButton->setIcon(Core::Icons::PLUS.icon());
m_zoomOutButton->setToolTip(tr("Decrease Font Size"));
m_zoomOutButton->setIcon(Core::Icons::MINUS.icon());
m_newTerminalButton->setToolTip(tr("Add new terminal"));
m_newTerminalButton->setIcon(Core::Icons::NEWFILE.icon());
connect(TextEditor::TextEditorSettings::instance(),
&TextEditor::TextEditorSettings::behaviorSettingsChanged,
this, &ROSTerminalPane::updateZoomEnabled);
connect(m_zoomInButton, &QToolButton::clicked,
this, &ROSTerminalPane::zoomIn);
connect(m_zoomOutButton, &QToolButton::clicked,
this, &ROSTerminalPane::zoomOut);
connect(m_stopButton, &QToolButton::clicked,
this, &ROSTerminalPane::stopProcess);
connect(m_newTerminalButton, &QToolButton::clicked,
this, &ROSTerminalPane::startTerminalButton);
connect(m_tabWidget,SIGNAL(tabCloseRequested(int)), this, SLOT(closeTerminal(int)));
connect(m_terminalWidget, SIGNAL(terminalCreated(int)), this, SIGNAL(navigateStateUpdate));
connect(m_terminalWidget, SIGNAL(terminalClosed(int)), this, SIGNAL(navigateStateUpdate));
}
ROSTerminalPane::~ROSTerminalPane()
{
delete m_tabWidget;
delete m_terminalWidget;
delete m_stopButton;
delete m_zoomInButton;
delete m_zoomOutButton;
delete m_newTerminalButton;
}
void ROSTerminalPane::updateZoomEnabled()
{
const TextEditor::BehaviorSettings &settings
= TextEditor::TextEditorSettings::behaviorSettings();
bool zoomEnabled = settings.m_scrollWheelZooming;
m_zoomInButton->setEnabled(zoomEnabled);
m_zoomOutButton->setEnabled(zoomEnabled);
}
void ROSTerminalPane::zoomIn()
void ROSTerminalPane::startTerminalButton()
{
foreach(QTermWidget *ow, m_terminals)
{
ow->zoomIn();
}
m_terminalWidget->createTerminal();
}
void ROSTerminalPane::zoomOut()
void ROSTerminalPane::stopProcess()
{
foreach(QTermWidget *ow, m_terminals)
{
ow->zoomOut();
}
}
m_terminalWidget->stopTerminalProcess();
// foreach(QObject *obj, m_terminalWidget->ch->currentWidget()->children())
// {
// if(QLatin1String(obj->metaObject()->className()) == QLatin1String("Konsole::TerminalDisplay"))
// {
// QKeyEvent *event1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier);
// QCoreApplication::postEvent(obj, event1);
void ROSTerminalPane::startTerminalButton()
{
startTerminal();
// QKeyEvent *event2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_C, Qt::ControlModifier);
// QCoreApplication::postEvent(obj, event2);
// break;
// }
// }
}
void ROSTerminalPane::closeTerminal(int index)
int ROSTerminalPane::createTerminal(const QString &name, const QDir &workingDirectory)
{
m_tabNames.removeAll(m_tabWidget->tabText(index));
m_terminals.removeAll(qobject_cast<QTermWidget*>(m_tabWidget->currentWidget()));
m_tabWidget->removeTab(index);
int id = m_terminalWidget->createTerminal(name, workingDirectory);
emit navigateStateUpdate();
return id;
}
void ROSTerminalPane::stopProcess()
int ROSTerminalPane::createTerminal(const QDir &workingDirectory)
{
foreach(QObject *obj, m_tabWidget->currentWidget()->children())
{
if(QLatin1String(obj->metaObject()->className()) == QLatin1String("Konsole::TerminalDisplay"))
{
QKeyEvent *event1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier);
QCoreApplication::postEvent(obj, event1);
QKeyEvent *event2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_C, Qt::ControlModifier);
QCoreApplication::postEvent(obj, event2);
break;
}
}
int id = m_terminalWidget->createTerminal(workingDirectory);
emit navigateStateUpdate();
return id;
}
QTermWidget &ROSTerminalPane::startTerminal(int startnow, const QString name)
int ROSTerminalPane::createTerminal()
{
QString tabName = name;
QString tabNamePrefix;
// const char *index = std::to_string(m_terminals.count()).c_str();
// char *paneId = new char[std::strlen(ROS_OUTPUT_WINDOW_PREFIX)+std::strlen(index)+1];
// std::strcpy(paneId, ROS_OUTPUT_WINDOW_PREFIX);
// std::strcat(paneId, index);
//don't start shell yet
QTermWidget *widget = new QTermWidget(startnow);
QSettings *s = Core::ICore::settings();
s->beginGroup(QLatin1String("ROSTerminal"));
// Need to create a qtc dark color scheme for the terminal
// Example: https://github.com/lxde/qtermwidget/blob/10e17968e4457da2b91675984e17009ee6e1e7aa/lib/color-schemes/Linux.colorscheme
widget->setColorScheme(s->value(QLatin1String("ColorScheme"), QLatin1String("Linux")).toString());
// QFont f(s->value(QLatin1String("FontName"), TERMINALPLUGINDEFAULTFONT).toString());
// f.setPointSize(s->value(QLatin1String("FontSize"), 10).toInt());
// widget->setTerminalFont(f);
s->endGroup();
m_terminals.append(widget);
updateZoomEnabled();
//Create a unique tab name
tabNamePrefix = tabName;
int cnt=0;
while(m_tabNames.contains(tabName))
{
tabName = QString::fromLatin1("%1(%2)").arg(tabNamePrefix, QString::number(cnt));
cnt+=1;
};
m_tabNames.append(tabName);
int idx = m_tabWidget->addTab(widget, tabName);
m_tabWidget->setCurrentIndex(idx);
int id = m_terminalWidget->createTerminal();
emit navigateStateUpdate();
return *widget;
return id;
}
QList<QWidget*> ROSTerminalPane::toolBarWidgets() const
{
return QList<QWidget *>() << m_newTerminalButton
<< m_stopButton
<< m_zoomInButton
<< m_zoomOutButton;
<< m_stopButton;
}
bool ROSTerminalPane::hasFocus() const
{
return m_tabWidget->window()->focusWidget() == m_tabWidget;
return m_terminalWidget->hasFocus();
}
bool ROSTerminalPane::canFocus() const
......@@ -197,18 +115,18 @@ bool ROSTerminalPane::canFocus() const
void ROSTerminalPane::setFocus()
{
m_tabWidget->setFocus();
m_terminalWidget->setFocus();
}
void ROSTerminalPane::clearContents()
{
qobject_cast<QTermWidget *>(m_tabWidget->currentWidget())->clear();
// qobject_cast<QTermWidget *>(m_tabWidget->currentWidget())->clear();
}
QWidget *ROSTerminalPane::outputWidget(QWidget *parent)
{
m_tabWidget->setParent(parent);
return m_tabWidget;
m_terminalWidget->setParent(parent);
return m_terminalWidget;
}
QString ROSTerminalPane::displayName() const
......@@ -220,9 +138,14 @@ void ROSTerminalPane::visibilityChanged(bool /*b*/)
{
}
void ROSTerminalPane::sendText(const QString &text)
void ROSTerminalPane::sendInput(const QString &text)
{
m_terminalWidget->sendInput(text);
}
void ROSTerminalPane::sendInput(const int &id, const QString &text)
{
qobject_cast<QTermWidget *>(m_tabWidget->currentWidget())->sendText(text);
m_terminalWidget->sendInput(id, text);
}
int ROSTerminalPane::priorityInStatusBar() const
......@@ -232,33 +155,23 @@ int ROSTerminalPane::priorityInStatusBar() const
bool ROSTerminalPane::canNext() const
{
if(m_terminals.count() > 1 && m_tabWidget->currentIndex() < (m_terminals.count()-1))
{
return true;
}
return false;
return ((m_terminalWidget->count() > 1 && m_terminalWidget->currentIndex() < (m_terminalWidget->count()-1)) ? true : false);
}
bool ROSTerminalPane::canPrevious() const
{
if(m_terminals.count() > 1 && m_tabWidget->currentIndex() > 0)
{
return true;
}
return false;
return (m_terminalWidget->count() > 1 && m_terminalWidget->currentIndex() > 0 ? true : false);
}
void ROSTerminalPane::goToNext()
{
m_tabWidget->setCurrentIndex(m_tabWidget->currentIndex()+1);
m_terminalWidget->setCurrentIndex(m_terminalWidget->currentIndex()+1);
emit navigateStateChanged();
}
void ROSTerminalPane::goToPrev()
{
m_tabWidget->setCurrentIndex(m_tabWidget->currentIndex()-1);
m_terminalWidget->setCurrentIndex(m_terminalWidget->currentIndex()-1);
emit navigateStateChanged();
}
......
#ifndef ROSOUTPUTPANE_H
#define ROSOUTPUTPANE_H
#include <coreplugin/ioutputpane.h>
#include "terminal_tab_widget.h"
#include <coreplugin/ioutputpane.h>
#include <projectexplorer/processparameters.h>
#include <utils/qtcprocess.h>
......@@ -10,8 +11,6 @@
#include <QToolButton>
#include <QProcess>
#include <qtermwidget5/qtermwidget.h>
namespace ROSProjectManager {
namespace Internal {
......@@ -43,26 +42,21 @@ public:
void goToNext() override;
void goToPrev() override;
QTermWidget &startTerminal(int startnow = 1, const QString name = QLatin1String("Terminal"));
int createTerminal(const QString &name, const QDir &workingDirectory = QDir());
int createTerminal(const QDir &workingDirectory);
int createTerminal();
void sendText(const QString &text);
void sendInput(const QString &text);
void sendInput(const int &id, const QString &text);
private slots:
void updateZoomEnabled();
void zoomIn();
void zoomOut();
void startTerminalButton();
void stopProcess();
void closeTerminal(int index);
private:
QList<QTermWidget *> m_terminals;
QTabWidget * m_tabWidget;
QStringList m_tabNames;
TerminalTabWidget *m_terminalWidget;
QToolButton *m_stopButton;
QToolButton *m_zoomInButton;
QToolButton *m_zoomOutButton;
QToolButton *m_newTerminalButton;
};
......
#include "terminal_tab_widget.h"
#include <kde_terminal_interface_v2.h>
#include <QMessageBox>
#include <QDebug>
#include <QDir>
#include <QKeySequence>
#include <QKeyEvent>
#include <QApplication>
TerminalTabWidget::TerminalTabWidget(QWidget *parent) :
m_tabWidget(new QTabWidget(parent)),
m_counter(0)
{
m_tabWidget->setTabsClosable(true);
m_service = KService::serviceByDesktopName(QLatin1Literal("konsolepart"));
if (!m_service)
{
QMessageBox::critical(this, tr("Konsole not installed"), tr("Please install the kde konsole and try again!"), QMessageBox::Ok);
return;
}
connect(m_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(closeTerminal(int)));
}
TerminalTabWidget::~TerminalTabWidget()
{
delete m_tabWidget;
foreach (KParts::ReadOnlyPart* part, m_terminals)
{
delete part;
}
}
int TerminalTabWidget::createTerminal()
{
return createTerminal(QString::fromLatin1("Terminal%1").arg(m_counter+1));
}
int TerminalTabWidget::createTerminal(const QDir &workingDirectory)
{
return createTerminal(QString::fromLatin1("Terminal%1").arg(m_counter+1), workingDirectory);
}
int TerminalTabWidget::createTerminal(const QString &name, const QDir &workingDirectory)
{
// create one instance of konsolepart
KParts::ReadOnlyPart *part = m_service->createInstance<KParts::ReadOnlyPart>(this, this, QVariantList());
if (!part)
{
qDebug() << "Failed to create a new terminal.";
return -1;
}
if (workingDirectory.exists() && !(workingDirectory.absolutePath() == workingDirectory.homePath()))
qobject_cast<TerminalInterface*>(part)->showShellInDir(workingDirectory.absolutePath());
int id = m_tabWidget->addTab(part->widget(), name);
m_tabWidget->setCurrentIndex(id);
m_terminals[id] = part;
emit terminalCreated(id);
return id;
}
void TerminalTabWidget::closeTerminal(const int &id)
{
delete m_terminals[id];
m_tabWidget->removeTab(id);
m_terminals.remove(id);
emit terminalClosed(id);
}
void TerminalTabWidget::sendInput(const int &id, const QString &text)
{
qobject_cast<TerminalInterfaceV2*>(m_terminals[id])->sendInput(text);
}
void TerminalTabWidget::sendInput(const QString &text)
{
qobject_cast<TerminalInterfaceV2*>(m_terminals[m_tabWidget->currentIndex()])->sendInput(text);
}
void TerminalTabWidget::stopTerminalProcess()
{
// foreach(QObject *obj, m_terminalWidget->ch->currentWidget()->children())
// {
// if(QLatin1String(obj->metaObject()->className()) == QLatin1String("Konsole::TerminalDisplay"))
// {
// QKeyEvent *event1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier);
// QCoreApplication::postEvent(obj, event1);
// QKeyEvent *event2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_C, Qt::ControlModifier);
// QCoreApplication::postEvent(obj, event2);
// break;
// }
// }
stopTerminalProcess(m_tabWidget->currentIndex());
}
void TerminalTabWidget::stopTerminalProcess(int id)
{
QKeyEvent *event1 = new QKeyEvent(QEvent::KeyPress, Qt::Key_C, Qt::ControlModifier);
QCoreApplication::postEvent(m_terminals[id]->widget(), event1);
QKeyEvent *event2 = new QKeyEvent(QEvent::KeyRelease, Qt::Key_C, Qt::ControlModifier);
QCoreApplication::postEvent(m_terminals[id]->widget(), event2);
}
int TerminalTabWidget::currentTerminalId() const
{
return m_tabWidget->currentIndex();
}
void TerminalTabWidget::setCurrentTerminal(int id)
{
m_tabWidget->setCurrentIndex(id);
}
int TerminalTabWidget::currentIndex() const
{
return m_tabWidget->currentIndex();
}
void TerminalTabWidget::setCurrentIndex(int index)
{
m_tabWidget->setCurrentIndex(index);
}
int TerminalTabWidget::count() const
{
return m_tabWidget->count();
}
#ifndef Q_DECL_CONSTRUCTOR_DEPRECATED
# define Q_DECL_CONSTRUCTOR_DEPRECATED Q_DECL_DEPRECATED
#endif
#ifndef TERMINAL_TAB_WIDGET_H
#define TERMINAL_TAB_WIDGET_H
#include <KParts/ReadOnlyPart>
#include <QMainWindow>
#include <KService>
#include <QTabWidget>
#include <QDir>
class TerminalTabWidget : public QWidget
{
Q_OBJECT
public:
TerminalTabWidget(QWidget *parent = 0);
~TerminalTabWidget();
int createTerminal(const QString &name, const QDir &workingDirectory = QDir());
int createTerminal(const QDir &workingDirectory);
int createTerminal();
void sendInput(const QString &text);
void sendInput(const int &id, const QString &text);
/**
* @brief Stop active terminal's process by sending a CTRL+C.
*/
void stopTerminalProcess();
/**
* @brief Stope terminal with ID process by sending a CTRL+C
* @param id
*/
void stopTerminalProcess(int id);
int currentTerminalId(