Files
neutrino/src/gui/imageinfo.cpp
Thilo Graf c90348dd1e update: move image RELEASE_CYCLE define to configure.ac
It should be more sensefull to set release cycle inside environment
than hard coding inside neutrino code.
Neutrino package version is not the same like image release cycle,
therefore here it is separated from package info.
2017-12-28 00:05:28 +01:00

480 lines
13 KiB
C++

/*
Based up Neutrino-GUI - Tuxbox-Project
Copyright (C) 2001 by Steffen Hehn 'McClean'
Implementation of component classes
Copyright (C) 2013, Thilo Graf 'dbt'
License: GPL
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
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the
Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <gui/imageinfo.h>
#include <global.h>
#include <neutrino.h>
#include <driver/rcinput.h>
#include <driver/fontrenderer.h>
#include <sys/utsname.h>
#include <string>
#include <daemonc/remotecontrol.h>
#include <system/flashtool.h>
#include <system/helpers.h>
#include "version.h"
#include <gui/buildinfo.h>
#define LICENSEDIR DATADIR "/neutrino/license/"
#ifdef ENABLE_LUA
#include <gui/lua/lua_api_version.h>
#endif
#include <nhttpd/yconfig.h>
#include <ctype.h>
#define VERSION_FILE "/.version"
using namespace std;
extern CRemoteControl * g_RemoteControl; /* neutrino.cpp */
CImageInfo::CImageInfo(): config ('\t')
{
Init();
}
//init all var members
void CImageInfo::Init(void)
{
cc_win = NULL;
cc_info = NULL;
cc_tv = NULL;
cc_lic = NULL;
cc_sub_caption = NULL;
b_info = NULL;
btn_red = NULL;
item_offset = OFFSET_INNER_MID;
item_font = NULL;
item_height = 0;
y_tmp = 0;
license_txt = "";
v_info.clear();
config.loadConfig(VERSION_FILE);
}
CImageInfo::~CImageInfo()
{
hide();
//deallocate window object, deletes also added cc_items
delete cc_win;
}
void CImageInfo::Clean()
{
//deallocate of the window object causes also deallocate added items,
if (cc_win){
delete cc_win;
//it's important to set here a null pointer
cc_win = NULL;
cc_info = NULL;
cc_tv = NULL;
cc_lic = NULL;
cc_sub_caption = NULL;
delete b_info;
b_info = NULL;
btn_red = NULL;
}
}
int CImageInfo::exec(CMenuTarget* parent, const std::string &)
{
int res = menu_return::RETURN_REPAINT;
if (parent)
parent->hide();
//clean up before, because we could have a current instance with already initialized contents
Clean();
//init window object, add cc-items and paint all
ShowWindow();
bool fadeout = false;
neutrino_msg_t postmsg = 0;
neutrino_msg_t msg;
while (1)
{
neutrino_msg_data_t data;
uint64_t timeoutEnd = CRCInput::calcTimeoutEnd_MS(100);
g_RCInput->getMsgAbsoluteTimeout( &msg, &data, &timeoutEnd );
if ((msg == NeutrinoMessages::EVT_TIMER) && (data ==cc_win->GetFadeTimer())){
if (cc_win->FadeDone())
break;
continue;
}
if (fadeout && msg == CRCInput::RC_timeout){
if (cc_win->StartFadeOut()){
msg = menu_return::RETURN_EXIT_ALL;
continue;
}
else
break;
}
if(msg == CRCInput::RC_setup) {
res = menu_return::RETURN_EXIT_ALL;
fadeout = true;
}
else if (msg == CRCInput::RC_red){
// init temporarly vars
neutrino_locale_t info_cap , new_btn_cap;
info_cap = new_btn_cap = NONEXISTANT_LOCALE;
string info_txt = "";
neutrino_locale_t btn_cap = btn_red->getCaptionLocale();
//toggle caption and info contents
if (btn_cap == LOCALE_BUILDINFO_MENU){
info_cap = LOCALE_BUILDINFO_MENU;
for (uint i=0; i<CBuildInfo::BI_TYPE_IDS; i++){
info_txt += g_Locale->getText(b_info->getInfo(i).caption);
info_txt += "\n";
info_txt += b_info->getInfo(i).info_text + "\n\n";
}
new_btn_cap = LOCALE_IMAGEINFO_LICENSE;
}
if (btn_cap == LOCALE_IMAGEINFO_LICENSE){
info_cap = LOCALE_IMAGEINFO_LICENSE;
info_txt = getLicenseText();
new_btn_cap = LOCALE_BUILDINFO_MENU;
}
//assign new caption and info contents
cc_sub_caption->setText(info_cap, CTextBox::AUTO_WIDTH, item_font);
InitInfoText(info_txt);
btn_red->setCaption(new_btn_cap);
//paint items
cc_sub_caption->hide();
cc_sub_caption->paint();
cc_lic->paint(false);
btn_red->kill();
btn_red->paint(false);
}
else if (CNeutrinoApp::getInstance()->listModeKey(msg)) {
postmsg = msg;
res = menu_return::RETURN_EXIT_ALL;
fadeout = true;
}
else if ((msg == CRCInput::RC_up) || (msg == CRCInput::RC_page_up)) {
ScrollLic(false);
}
else if ((msg == CRCInput::RC_down) || (msg == CRCInput::RC_page_down)) {
ScrollLic(true);
}
else if (msg <= CRCInput::RC_MaxRC){
fadeout = true;
}
if ( msg > CRCInput::RC_MaxRC && msg != CRCInput::RC_timeout){
CNeutrinoApp::getInstance()->handleMsg( msg, data );
}
}
if (postmsg)
g_RCInput->postMsg(postmsg, 0);
hide();
return res;
}
//contains all actions to init and add the window object and items
void CImageInfo::ShowWindow()
{
CComponentsFooter *footer = NULL;
if (cc_win == NULL){
cc_win = new CComponentsWindowMax(LOCALE_IMAGEINFO_HEAD, NEUTRINO_ICON_INFO, 0, CC_SHADOW_ON);
cc_win->setWindowHeaderButtons(CComponentsHeader::CC_BTN_MENU | CComponentsHeader::CC_BTN_EXIT);
footer = cc_win->getFooterObject();
int h_footer = footer->getHeight();
fb_pixel_t btn_col = /*g_settings.theme.Button_gradient ? COL_BUTTON_BODY :*/ footer->getColorBody(); //TODO: Button_gradient option
btn_red = new CComponentsButtonRed(10, CC_CENTERED, 250, h_footer-h_footer/4, LOCALE_BUILDINFO_MENU, footer, false , true, false, footer->getColorBody(), btn_col);
btn_red->doPaintBg(false);
btn_red->setButtonTextColor(COL_MENUFOOT_TEXT);
btn_red->setColBodyGradient(CC_COLGRAD_OFF);
}
//prepare minitv
InitMinitv();
//prepare infos
InitInfos();
//prepare build infos
InitBuildInfos();
//prepare info text
InitInfoText(getLicenseText());
//paint window
cc_win->StartFadeIn();
cc_win->paint(CC_SAVE_SCREEN_NO);
}
//prepare minitv
void CImageInfo::InitMinitv()
{
//init the minitv object
if (cc_tv == NULL)
cc_tv = new CComponentsPIP (0, item_offset);
#if 0 //static assign of dimensions are distorting ratio of mini tv picture
//init width and height
cc_tv->setWidth(cc_win->getWidth()/3);
cc_tv->setHeight(cc_win->getHeight()/3);
#endif
//init x pos and use as parameter for setXPos
int cc_tv_x = (cc_win->getWidth() - cc_tv->getWidth()) - item_offset;
cc_tv->setXPos(cc_tv_x);
//add minitv to container
if (!cc_tv->isAdded())
cc_win->addWindowItem(cc_tv);
}
//prepare distribution infos
void CImageInfo::InitBuildInfos()
{
if (b_info == NULL)
b_info = new CBuildInfo();
}
//collect required data from environment
void CImageInfo::InitInfoData()
{
v_info.clear();
#ifdef BUILT_DATE
const char * builddate = BUILT_DATE;
#else
const char * builddate = config.getString("builddate", "n/a").c_str();
#endif
string version_string = config.getString("version", "");
#ifdef IMAGE_VERSION
version_string = IMAGE_VERSION;
#else
bool is_version_code = true;
for (size_t i=0; i<version_string.size(); i++){
if (!isdigit(version_string[i])){
is_version_code = false;
break;
}
}
if (is_version_code && version_string.size() == 16){
static CFlashVersionInfo versionInfo(version_string.c_str());
version_string = versionInfo.getReleaseCycle();
version_string += " ";
version_string += versionInfo.getType();
version_string += " (";
version_string += versionInfo.getDate();
version_string += ")";
}else
printf("[CImageInfo]\t[%s - %d], WARNING! %s contains possible wrong version format, content = [%s], internal release cycle [%s]\n", __func__, __LINE__, VERSION_FILE, version_string.c_str(), RELEASE_CYCLE);
#endif
struct utsname uts_info;
image_info_t imagename = {LOCALE_IMAGEINFO_IMAGE, config.getString("imagename", PACKAGE_NAME)};
v_info.push_back(imagename);
if (!version_string.empty()){
image_info_t version = {LOCALE_IMAGEINFO_VERSION, version_string};
v_info.push_back(version);
}
#ifdef VCS
image_info_t vcs = {LOCALE_IMAGEINFO_VCS, VCS};
v_info.push_back(vcs);
#endif
image_info_t date = {LOCALE_IMAGEINFO_DATE, builddate};
v_info.push_back(date);
string s_api;
#ifdef ENABLE_LUA
s_api += "LUA " + to_string(LUA_API_VERSION_MAJOR) + "." + to_string(LUA_API_VERSION_MINOR);
s_api += ", ";
#endif
s_api += "yWeb ";
s_api += getYWebVersion();
s_api += ", ";
s_api += HTTPD_NAME;
s_api += + " ";
s_api += HTTPD_VERSION;
s_api += + ", ";
s_api += YHTTPD_NAME;
s_api += + " ";
s_api += YHTTPD_VERSION;
image_info_t api = {LOCALE_IMAGEINFO_API, s_api};
v_info.push_back(api);
if (uname(&uts_info) == 0) {
image_info_t kernel = {LOCALE_IMAGEINFO_KERNEL, uts_info.release};
v_info.push_back(kernel);
}
image_info_t creator = {LOCALE_IMAGEINFO_CREATOR, config.getString("creator", "n/a")};
v_info.push_back(creator);
image_info_t www = {LOCALE_IMAGEINFO_HOMEPAGE, config.getString("homepage", "n/a")};
v_info.push_back(www);
image_info_t doc = {LOCALE_IMAGEINFO_DOKUMENTATION, config.getString("docs", "http://wiki.neutrino-hd.de")};
v_info.push_back(doc);
image_info_t forum = {LOCALE_IMAGEINFO_FORUM, config.getString("forum", "http://forum.tuxbox.org")};
v_info.push_back(forum);
}
//prepare distribution infos
void CImageInfo::InitInfos()
{
InitInfoData();
//initialize container for infos
if (cc_info == NULL)
cc_info = new CComponentsForm();
if (!cc_info->isAdded())
cc_win->addWindowItem(cc_info);
cc_info->setPos(item_offset, item_offset);
//set width, use size between left border and minitv
cc_info->setWidth(cc_win->getWidth() - cc_tv->getWidth() - 2*item_offset);
//create label and text items
y_tmp = 0;
for (size_t i=0; i<v_info.size(); i++) {
CComponentsExtTextForm *item = new CComponentsExtTextForm(1, y_tmp, cc_info->getWidth(), 0, g_Locale->getText(v_info[i].caption), v_info[i].info_text);
item->setLabelWidthPercent(15);
if (!item_font){
item_font = item->getFont();
//calculate initial height for info form
item_height = item_font->getHeight();
}
item->setHeight(item_height);
cc_info->setHeight(v_info.size()*item_height);
//add ext-text object to window body
if (!item->isAdded())
cc_info->addCCItem(item);
//add an offset before homepage and license and at the end
if (v_info[i].caption == LOCALE_IMAGEINFO_CREATOR || v_info[i].caption == LOCALE_IMAGEINFO_FORUM){
CComponentsShapeSquare *spacer = new CComponentsShapeSquare(1, y_tmp+=item_offset, 1, item_offset);
//spacer ist not visible!
spacer->allowPaint(false);
cc_info->addCCItem(spacer);
//increase height of cc_info object with offset
int tmp_h = cc_info->getHeight();
cc_info->setHeight(tmp_h + item_offset);
}
y_tmp += item->getHeight();
}
}
//get license
string CImageInfo::getLicenseText()
{
string file = LICENSEDIR;
file += g_settings.language;
file += ".license";
string res = CComponentsText::getTextFromFile(file);
//assign default text, if language file is not available
if(res.empty()){
file = LICENSEDIR;
file += "english.license";
res = CComponentsText::getTextFromFile(file);
}
return res;
}
//prepare info text
void CImageInfo::InitInfoText(const std::string& text)
{
//get window body object
CComponentsForm *winbody = cc_win->getBodyObject();
int h_body = winbody->getHeight();
int w_body = winbody->getWidth();
//add a caption for info contents
Font * caption_font = g_Font[SNeutrinoSettings::FONT_TYPE_MENU];
int caption_height = caption_font->getHeight();
y_tmp = max(y_tmp, cc_tv->getYPos()+cc_tv->getHeight());
if (cc_sub_caption == NULL)
cc_sub_caption = new CComponentsLabel(cc_info->getXPos(), y_tmp, cc_info->getWidth(), caption_height,
g_Locale->getText(LOCALE_IMAGEINFO_LICENSE), CTextBox::AUTO_WIDTH, item_font);
if (!cc_sub_caption->isAdded())
cc_win->addWindowItem(cc_sub_caption);
//add info text box
int h_txt = h_body - item_offset - cc_info->getHeight() - cc_sub_caption->getHeight() - item_offset;
if (cc_lic == NULL)
cc_lic = new CComponentsInfoBox(CC_CENTERED, y_tmp+=cc_sub_caption->getHeight(), w_body-2*item_offset, h_txt);
cc_lic->setSpaceOffset(1);
cc_lic->setText(text, CTextBox::TOP | CTextBox::AUTO_WIDTH | CTextBox::SCROLL, item_font);
cc_lic->doPaintTextBoxBg(true);
//add text to container
if (!cc_lic->isAdded())
cc_win->addWindowItem(cc_lic);
}
//scroll licens text
void CImageInfo::ScrollLic(bool scrollDown)
{
if (cc_lic && (cc_lic->cctext)) {
//get the textbox instance from infobox object and use CTexBbox scroll methods
CTextBox* ctb = cc_lic->cctext->getCTextBoxObject();
if (ctb) {
//ctb->enableBackgroundPaint(true);
if (scrollDown)
ctb->scrollPageDown(1);
else
ctb->scrollPageUp(1);
//ctb->enableBackgroundPaint(false);
}
}
}
void CImageInfo::hide()
{
printf("[CImageInfo] [%s - %d] hide...\n", __FUNCTION__, __LINE__);
if (cc_win){
cc_win->kill();
cc_win->StopFade();
Clean();
}
}
string CImageInfo::getYWebVersion()
{
CConfigFile yV('=', false);
yV.loadConfig(PRIVATE_HTTPDDIR "/Y_Version.txt");
return yV.getString("version", "n/a");
}