add working termwindow class

CTermWindow() should be usable as drop-in replacement for CShellWindow()


Origin commit data
------------------
Branch: ni/coolstream
Commit: bccd547781
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2018-01-15 (Mon, 15 Jan 2018)



------------------
This commit was generated by Migit
This commit is contained in:
Stefan Seyfried
2018-01-15 19:54:52 +01:00
committed by vanhofen
parent b86a6b4a7c
commit acb21d1bf9
4 changed files with 229 additions and 0 deletions

View File

@@ -112,6 +112,7 @@ neutrino_LDADD = \
$(top_builddir)/lib/libtuxtxt/libtuxtxt.a \
$(top_builddir)/lib/libdvbsub/libdvbsub.a \
$(top_builddir)/lib/libiw/libiw.a \
$(top_builddir)/src/gui/widget/yaft/libneutrino_gui_terminal.a \
@CURL_LIBS@ \
@FREETYPE_LIBS@ \
@PNG_LIBS@ \

View File

@@ -34,6 +34,7 @@ libneutrino_gui_widget_a_SOURCES = \
shellwindow.cpp \
stringinput.cpp \
stringinput_ext.cpp \
termwindow.cpp \
textbox.cpp
libneutrino_gui_widget2_a_SOURCES = \

View File

@@ -0,0 +1,133 @@
/*
* Terminal window class
*
* (C) 2017,2017 Stefan Seyfried
* SPDX-License-Identifier: GPL-2.0
*
* drop-in-replacement for CShellWindow()
* loosely based on shellwindow.cpp, heavily stripped down.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "termwindow.h"
#include <global.h>
#include <neutrino.h>
#include <driver/framebuffer.h>
#include <stdio.h>
#include <errno.h>
#include <system/helpers.h>
#include <system/debug.h>
#include <gui/widget/yaft/yaft_class.h>
#include <gui/widget/msgbox.h>
CTermWindow::CTermWindow(const std::string &Command, const int Mode, int *Res, bool auto_exec)
{
fprintf(stderr, "%s:%d mode %d\n", __func__, __LINE__, Mode);
frameBuffer = CFrameBuffer::getInstance();
setCommand(Command, Mode, Res, auto_exec);
}
void CTermWindow::setCommand(const std::string &Command, const int Mode, int* Res, bool auto_exec)
{
command = Command;
mode = Mode;
fprintf(stderr, "%s:%d mode %d\n", __func__, __LINE__, mode);
res = Res;
if (auto_exec)
exec();
}
void CTermWindow::exec()
{
fprintf(stderr, "CTermWindow::exec: mode %d command: %s\n", mode, command.c_str());
std::string cmd;
if (mode == 0){ /* not used */
cmd = "PATH=/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin ; export PATH ; " + command + " 2>/dev/null >&2";
int r = my_system(cmd.c_str());
if (res) {
if (r == -1)
*res = r;
else
*res = WEXITSTATUS(r);
dprintf(DEBUG_NORMAL, "[CTermWindow] [%s - %d] Error! system returns: %d command: %s\n", __func__, __LINE__, *res, cmd.c_str());
}
}
else {
const char * const argv[] = {"/bin/sh\0", "-c\0", command.c_str(), NULL };
int ret;
fprintf(stderr, "%s:%d %s\n", __func__, __LINE__, argv[0]);
YaFT *y = new YaFT(argv, res, !!(mode & VERBOSE), OnShellOutputLoop);
ret = y->run();
if (res)
*res = ret;
delete y;
fprintf(stderr, "%s:%d\n", __func__, __LINE__);
showResult();
}
}
void CTermWindow::showResult()
{
if (mode == 0) /* not used */
return;
bool show_button = false;
bool exit = false;
if (mode & ACKNOWLEDGE)
show_button = true;
else if (mode & ACKNOWLEDGE_EVENT) {
if (res && *res != 0){
OnResultError(res);
if (OnResultError.empty())
DisplayErrorMessage("Error while execution of task. Please see window for details!");
show_button = true;
}else{
OnResultOk(res);
exit = true; //TODO: evaluate plausible statement
}
}
if (mode & VERBOSE) {
if (show_button) {
int b_width = 150;
int b_height = 35;
int xpos = frameBuffer->getScreenWidth() - b_width;
int ypos = frameBuffer->getScreenHeight() - b_height;
CComponentsButton btn(xpos, ypos, b_width, b_height, LOCALE_MESSAGEBOX_BACK, NEUTRINO_ICON_BUTTON_OKAY, NULL, true, true);
btn.setColorBody(COL_MENUCONTENT_PLUS_0);
btn.paint(false);
}
neutrino_msg_t msg;
neutrino_msg_data_t data;
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU]);
if (!exit) {
do {
g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd);
} while (msg != CRCInput::RC_ok && msg != CRCInput::RC_home && msg != CRCInput::RC_timeout);
}
}
frameBuffer->Clear();
}
#if 0
// only for debug
void CTermWindow::handleShellOutput(std::string* cur_line, int* Res, bool* /*ok*/)
{
int _res = *Res;
std::string line = *cur_line;
fprintf(stderr, "%s\n", line.c_str());
*Res = _res;
}
#endif
CTermWindow::~CTermWindow()
{
}

View File

@@ -0,0 +1,94 @@
/*
* terminal window class
* (C) 2017,2018 Stefan Seyfried
* SPDX-License-Identifier: GPL-2.0
*
* designed to be more or less drop-in-compatible to CShellWindow()
* derived from shellwindow.h
*/
#ifndef __WIDGET_SHELLWINDOW_H__
#define __WIDGET_SHELLWINDOW_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <string>
#include <sigc++/signal.h>
class CFrameBuffer;
class CTermWindow : public sigc::trackable
{
private:
int mode;
std::string command;
int* res;
CFrameBuffer *frameBuffer;
void showResult();
void handleShellOutput(std::string* cur_line, int* Res, bool* ok);
public:
// shell window modes for handled shell output. //NOTE: mode 0 use only system calls, with unhandled return values and no handled shell output
enum shellwindow_modes
{
/*SYSTEM = 0, */
QUIET = 1, // no window
VERBOSE = 2, // show window
ACKNOWLEDGE = 4, // show result button inside window after execution, no message box NOTE: only in VERBOSE mode
ACKNOWLEDGE_EVENT = 8 // same like ACKNOWLEDGE but shows a default error message box or a slot handled action instead default error message box
};
CTermWindow(const std::string &Command, const int Mode = 0, int* Res = NULL, bool auto_exec = true);
~CTermWindow();
void setCommand(const std::string &Command, const int Mode = 0, int* Res = NULL, bool auto_exec = true);
#if 0
std::string getCommand(){return command;}
int getMode(){return mode;}
#endif
void exec();
/*!
signal/event handler runs on loop in exec method
this allows to use the shell output lines in other objects eg. for evaluation of error or status data
example for implamentation in your class:
...your code...
//assuming in your class is declared a member function named YourMemberFunction(std::string& arg), parameter is a string as rev:
//Tis function should handle the shell output!
//declare a slot with return value as 'void' and parameter as 'string', here by rev!
sigc::slot1<void, string*> sl_shell_output;
//fill the slot with your member function in your class that do evaluate the output lines
sl_shell_output = sigc::mem_fun(*this, &CYourClass::YourMemberFunction);
//create the CShellWindow object in verbose mode, important: parameter 'auto_exec' must be set to 'false', so it is possible to connect the slot before engages the exec() methode
CTermWindow shell(cmd, (verbose ? CTermWindow::VERBOSE : 0) | (acknowledge ? CTermWindow::ACKNOWLEDGE_MSG : 0), &res, false);
//connect slot
shell.OnShellOutputLoop.connect(sl_shell_output);
//now exec...
shell.exec();
...other code...
*/
sigc::signal<void, std::string*, int*, bool*> OnShellOutputLoop;
/*!
signal/event handler runs after task is finished.
NOTE: works only with ACKNOWLEDGE_EVENT mode
After executed task comes a default messages (see method showResult()), but with these slots it is possible to use other messages
or any desired action without any touching this class.
Example for implementation in foreign class let show an alternate message than default message:
...your code...
//assuming in your foreign class is declared a member function named YourMemberFunction() without return value and int* as parmeter This method should run
instead the default message.
//declare a slot with return value as 'void' and wihout any parameter
sigc::slot<void, int*> sl_result_err;
//fill the slot with your member function in your class with your action
sl_result_err = sigc::mem_fun(*this, &CYourClass::YourMemberFunction);
//create the CShellWindow object in verbose mode, important: parameter 'auto_exec' must be set to 'false', so it is possible to connect the slot before engages the exec() methode
CTermWindow shell(cmd, (verbose ? CTermWindow::VERBOSE : 0) | (acknowledge ? CTermWindow::ACKNOWLEDGE_MSG : 0), &res, false);
//connect slot
shell1.OnResultError.connect(sl_result_err);
//now exec...
shell.exec();
...other code...
Use of OnResultOk is similar with OnResultError.
*/
sigc::signal<void, int*> OnResultError;
sigc::signal<void, int*> OnResultOk;
};
#endif