mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-09-01 18:01:06 +02:00
add working termwindow class
CTermWindow() should be usable as drop-in replacement for CShellWindow()
Origin commit data
------------------
Commit: bccd547781
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2018-01-15 (Mon, 15 Jan 2018)
This commit is contained in:
committed by
vanhofen
parent
c1d31a57f7
commit
6ec6be1a41
@@ -112,6 +112,7 @@ neutrino_LDADD = \
|
|||||||
$(top_builddir)/lib/libtuxtxt/libtuxtxt.a \
|
$(top_builddir)/lib/libtuxtxt/libtuxtxt.a \
|
||||||
$(top_builddir)/lib/libdvbsub/libdvbsub.a \
|
$(top_builddir)/lib/libdvbsub/libdvbsub.a \
|
||||||
$(top_builddir)/lib/libiw/libiw.a \
|
$(top_builddir)/lib/libiw/libiw.a \
|
||||||
|
$(top_builddir)/src/gui/widget/yaft/libneutrino_gui_terminal.a \
|
||||||
@CURL_LIBS@ \
|
@CURL_LIBS@ \
|
||||||
@FREETYPE_LIBS@ \
|
@FREETYPE_LIBS@ \
|
||||||
@PNG_LIBS@ \
|
@PNG_LIBS@ \
|
||||||
|
@@ -34,6 +34,7 @@ libneutrino_gui_widget_a_SOURCES = \
|
|||||||
shellwindow.cpp \
|
shellwindow.cpp \
|
||||||
stringinput.cpp \
|
stringinput.cpp \
|
||||||
stringinput_ext.cpp \
|
stringinput_ext.cpp \
|
||||||
|
termwindow.cpp \
|
||||||
textbox.cpp
|
textbox.cpp
|
||||||
|
|
||||||
libneutrino_gui_widget2_a_SOURCES = \
|
libneutrino_gui_widget2_a_SOURCES = \
|
||||||
|
133
src/gui/widget/termwindow.cpp
Normal file
133
src/gui/widget/termwindow.cpp
Normal 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()
|
||||||
|
{
|
||||||
|
}
|
94
src/gui/widget/termwindow.h
Normal file
94
src/gui/widget/termwindow.h
Normal 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
|
Reference in New Issue
Block a user