From 49c03bbf2ca6f00350221c555bd50284e0c00913 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Fri, 21 Aug 2015 16:44:33 +0200 Subject: [PATCH] interactiveterminal ViewModule, based on the Konsole KPart. --- .../interactiveterminal/CMakeLists.txt | 27 ++++ .../InteractiveTerminalPage.cpp | 125 ++++++++++++++++++ .../InteractiveTerminalPage.h | 44 ++++++ .../InteractiveTerminalViewStep.cpp | 115 ++++++++++++++++ .../InteractiveTerminalViewStep.h | 64 +++++++++ .../interactiveterminal.conf | 2 + src/modules/interactiveterminal/module.desc | 7 + 7 files changed, 384 insertions(+) create mode 100644 src/modules/interactiveterminal/CMakeLists.txt create mode 100644 src/modules/interactiveterminal/InteractiveTerminalPage.cpp create mode 100644 src/modules/interactiveterminal/InteractiveTerminalPage.h create mode 100644 src/modules/interactiveterminal/InteractiveTerminalViewStep.cpp create mode 100644 src/modules/interactiveterminal/InteractiveTerminalViewStep.h create mode 100644 src/modules/interactiveterminal/interactiveterminal.conf create mode 100644 src/modules/interactiveterminal/module.desc diff --git a/src/modules/interactiveterminal/CMakeLists.txt b/src/modules/interactiveterminal/CMakeLists.txt new file mode 100644 index 000000000..4d2fb5fcb --- /dev/null +++ b/src/modules/interactiveterminal/CMakeLists.txt @@ -0,0 +1,27 @@ +find_package(ECM 0.0.13 REQUIRED NO_MODULE) +set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_MODULE_PATH}) + +include(KDEInstallDirs) # this seems to be necessary for KF5::CoreAddons +include(GenerateExportHeader) # this too, because KDE frameworks always want omnomnom more stuff + +find_package( KF5 REQUIRED Service Parts ) + +include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui + ${QTERMWIDGET_INCLUDE_DIR} ) + +set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} + ${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules ) + + +calamares_add_plugin( interactiveterminal + TYPE viewmodule + EXPORT_MACRO PLUGINDLLEXPORT_PRO + SOURCES + InteractiveTerminalViewStep.cpp + InteractiveTerminalPage.cpp + LINK_LIBRARIES + calamaresui + KF5::Service + KF5::Parts + SHARED_LIB +) diff --git a/src/modules/interactiveterminal/InteractiveTerminalPage.cpp b/src/modules/interactiveterminal/InteractiveTerminalPage.cpp new file mode 100644 index 000000000..739f02695 --- /dev/null +++ b/src/modules/interactiveterminal/InteractiveTerminalPage.cpp @@ -0,0 +1,125 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014-2015, Teo Mrnjavac + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#include "InteractiveTerminalPage.h" + +#include "viewpages/ViewStep.h" +#include "utils/Retranslator.h" +#include "utils/CalamaresUtilsGui.h" +#include "utils/Logger.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + + +InteractiveTerminalPage::InteractiveTerminalPage( QWidget* parent ) + : QWidget( parent ) + , m_layout( new QVBoxLayout( this ) ) + , m_termHostWidget( nullptr ) +{ + setLayout( m_layout ); + m_layout->setContentsMargins( 0, 0, 0, 0 ); + + m_headerLabel = new QLabel( this ); + m_layout->addWidget( m_headerLabel ); +} + + +void +InteractiveTerminalPage::onActivate() +{ + if ( m_termHostWidget ) + return; + // For whatever reason, instead of simply linking against a library we + // need to do a runtime query to KService just to get a sodding terminal + // widget. + KService::Ptr service = KService::serviceByDesktopName( "konsolepart" ); + if ( !service ) + { + // And all of this hoping the Konsole application is installed. If not, + // tough cookies. + // Maybe linking against a library seemed too simple and elegant so + // someone decided to have a terminal widget depend on over 9000 other + // KDElibs things that have nothing to do with a terminal widget, and + // have the loading happen at runtime so it's more likely to fail at + // an inconvenient time. + QMessageBox::critical( this, + tr( "Konsole not installed"), + tr( "Please install the kde konsole and try again!" ), + QMessageBox::Ok); + return ; + } + + // Create one instance of konsolepart. + KParts::ReadOnlyPart* p = + service->createInstance< KParts::ReadOnlyPart >( this, + this, + {} ); + if ( !p ) + { + // One more opportunity for the loading operation to fail. + QMessageBox::critical( this, + tr( "Konsole not installed"), + tr( "Please install the kde konsole and try again!" ), + QMessageBox::Ok); + return; + } + + // Cast the konsolepart to the TerminalInterface... + TerminalInterface* t = qobject_cast< TerminalInterface* >( p ); + if ( !t ) + { + // This is why we can't have nice things. + QMessageBox::critical( this, + tr( "Konsole not installed"), + tr( "Please install the kde konsole and try again!" ), + QMessageBox::Ok); + return; + } + + // Make the widget persist even if the KPart goes out of scope... + p->setAutoDeleteWidget( false ); + // ... but kill the KPart if the widget goes out of scope. + p->setAutoDeletePart( true ); + + m_termHostWidget = p->widget(); + m_layout->addWidget( m_termHostWidget ); + cDebug() << "Part widget ought to be" + << m_termHostWidget->metaObject()->className(); + + t->showShellInDir( QDir::home().path() ); + t->sendInput( QString( "%1\n" ).arg( m_command ) ); +} + + +void +InteractiveTerminalPage::setCommand( const QString& command ) +{ + m_command = command; + CALAMARES_RETRANSLATE( + m_headerLabel->setText( tr( "Executing script:  %1" ) + .arg( m_command ) ); + ) +} diff --git a/src/modules/interactiveterminal/InteractiveTerminalPage.h b/src/modules/interactiveterminal/InteractiveTerminalPage.h new file mode 100644 index 000000000..82a852277 --- /dev/null +++ b/src/modules/interactiveterminal/InteractiveTerminalPage.h @@ -0,0 +1,44 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014-2015, Teo Mrnjavac + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#ifndef INTERACTIVETERMINALPAGE_H +#define INTERACTIVETERMINALPAGE_H + +#include + +class QLabel; +class QVBoxLayout; + +class InteractiveTerminalPage : public QWidget +{ + Q_OBJECT +public: + explicit InteractiveTerminalPage( QWidget* parent = nullptr ); + + void onActivate(); + + void setCommand( const QString& command ); + +private: + QVBoxLayout* m_layout; + QWidget* m_termHostWidget; + QString m_command; + QLabel* m_headerLabel; +}; + +#endif // INTERACTIVETERMINALPAGE_H diff --git a/src/modules/interactiveterminal/InteractiveTerminalViewStep.cpp b/src/modules/interactiveterminal/InteractiveTerminalViewStep.cpp new file mode 100644 index 000000000..939cc8efa --- /dev/null +++ b/src/modules/interactiveterminal/InteractiveTerminalViewStep.cpp @@ -0,0 +1,115 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014-2015, Teo Mrnjavac + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#include "InteractiveTerminalViewStep.h" + +#include "InteractiveTerminalPage.h" + +#include + +InteractiveTerminalViewStep::InteractiveTerminalViewStep( QObject* parent ) + : Calamares::ViewStep( parent ) + , m_widget( new InteractiveTerminalPage() ) +{ + emit nextStatusChanged( true ); +} + + +InteractiveTerminalViewStep::~InteractiveTerminalViewStep() +{ + if ( m_widget && m_widget->parent() == nullptr ) + m_widget->deleteLater(); +} + + +QString +InteractiveTerminalViewStep::prettyName() const +{ + return tr( "Script" ); +} + + +QWidget* +InteractiveTerminalViewStep::widget() +{ + return m_widget; +} + + +void +InteractiveTerminalViewStep::next() +{ + emit done(); +} + + +void +InteractiveTerminalViewStep::back() +{} + + +bool +InteractiveTerminalViewStep::isNextEnabled() const +{ + return true; +} + + +bool +InteractiveTerminalViewStep::isBackEnabled() const +{ + return true; +} + + +bool +InteractiveTerminalViewStep::isAtBeginning() const +{ + return true; +} + + +bool +InteractiveTerminalViewStep::isAtEnd() const +{ + return true; +} + + +QList< Calamares::job_ptr > +InteractiveTerminalViewStep::jobs() const +{ + return QList< Calamares::job_ptr >(); +} + + +void +InteractiveTerminalViewStep::onActivate() +{ + m_widget->onActivate(); +} + + +void +InteractiveTerminalViewStep::setConfigurationMap( const QVariantMap& configurationMap ) +{ + if ( configurationMap.contains( "command" ) && + configurationMap.value( "command").type() == QVariant::String ) + m_widget->setCommand( configurationMap.value( "command" ).toString() ); +} + diff --git a/src/modules/interactiveterminal/InteractiveTerminalViewStep.h b/src/modules/interactiveterminal/InteractiveTerminalViewStep.h new file mode 100644 index 000000000..5405c3419 --- /dev/null +++ b/src/modules/interactiveterminal/InteractiveTerminalViewStep.h @@ -0,0 +1,64 @@ +/* === This file is part of Calamares - === + * + * Copyright 2014-2015, Teo Mrnjavac + * + * Calamares is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Calamares is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Calamares. If not, see . + */ + +#ifndef INTERACTIVETERMINALPAGEPLUGIN_H +#define INTERACTIVETERMINALPAGEPLUGIN_H + +#include + +#include "viewpages/ViewStep.h" +#include "PluginDllMacro.h" + +class InteractiveTerminalPage; + +class PLUGINDLLEXPORT InteractiveTerminalViewStep : public Calamares::ViewStep +{ + Q_OBJECT + Q_PLUGIN_METADATA( IID "calamares.ViewModule/1.0" ) + + Q_INTERFACES( Calamares::ViewStep ) + +public: + explicit InteractiveTerminalViewStep( QObject* parent = nullptr ); + virtual ~InteractiveTerminalViewStep(); + + QString prettyName() const override; + + QWidget* widget() override; + + void next() override; + void back() override; + + bool isNextEnabled() const override; + bool isBackEnabled() const override; + + bool isAtBeginning() const override; + bool isAtEnd() const override; + + QList< Calamares::job_ptr > jobs() const override; + + void onActivate() override; + +protected: + void setConfigurationMap( const QVariantMap& configurationMap ) override; + +private: + InteractiveTerminalPage* m_widget; +}; + +#endif // INTERACTIVETERMINALPAGEPLUGIN_H diff --git a/src/modules/interactiveterminal/interactiveterminal.conf b/src/modules/interactiveterminal/interactiveterminal.conf new file mode 100644 index 000000000..0786c8a01 --- /dev/null +++ b/src/modules/interactiveterminal/interactiveterminal.conf @@ -0,0 +1,2 @@ +--- +command: "echo Hello" diff --git a/src/modules/interactiveterminal/module.desc b/src/modules/interactiveterminal/module.desc new file mode 100644 index 000000000..a2b5087c9 --- /dev/null +++ b/src/modules/interactiveterminal/module.desc @@ -0,0 +1,7 @@ +# Module metadata file for interactiveterminal viewmodule +# Syntax is YAML 1.2 +--- +type: "view" +name: "interactiveterminal" +interface: "qtplugin" +load: "libcalamares_viewmodule_interactiveterminal.so"