diff --git a/src/gui/components/cc_frm_button.cpp b/src/gui/components/cc_frm_button.cpp index a92617ebf..24b2d8917 100644 --- a/src/gui/components/cc_frm_button.cpp +++ b/src/gui/components/cc_frm_button.cpp @@ -100,7 +100,7 @@ void CComponentsButton::initVarButton( const int& x_pos, const int& y_pos, const width = w; height = h; shadow = shadow_mode; - shadow_w = SHADOW_OFFSET; + shadow_w = SHADOW_OFFSET/2; //buttons are mostly small elements, so these elements should have a reasonable shadow width cc_body_gradient_enable = CC_COLGRAD_OFF/*g_settings.gradiant*/; //TODO: gradient is prepared for use but disabled at the moment till some other parts of gui parts are provide gradient setColBodyGradient(cc_body_gradient_enable/*CColorGradient::gradientLight2Dark*/, CFrameBuffer::gradientVertical, CColorGradient::light); @@ -113,7 +113,7 @@ void CComponentsButton::initVarButton( const int& x_pos, const int& y_pos, const fr_thickness = 0; //TODO: parts of the GUI still don't use framed buttons append_x_offset = 6; append_y_offset = 0; - corner_rad = 0; + corner_rad = RADIUS_SMALL; cc_btn_capt_col = cc_body_gradient_enable ? COL_BUTTON_TEXT_ENABLED : COL_MENUFOOT_TEXT; cc_btn_capt_disable_col = cc_body_gradient_enable ? COL_BUTTON_TEXT_DISABLED : COL_MENUCONTENTINACTIVE_TEXT; diff --git a/src/gui/components/cc_frm_footer.cpp b/src/gui/components/cc_frm_footer.cpp index 2b51821a7..b40b4afba 100644 --- a/src/gui/components/cc_frm_footer.cpp +++ b/src/gui/components/cc_frm_footer.cpp @@ -36,7 +36,7 @@ using namespace std; CComponentsFooter::CComponentsFooter(CComponentsForm* parent) { //CComponentsFooter - initVarFooter(1, 1, 0, 0, 0, parent); + initVarFooter(1, 1, 0, 0, 0, parent, CC_SHADOW_OFF, COL_MENUCONTENT_PLUS_6, COL_MENUFOOT_PLUS_0, COL_SHADOW_PLUS_0); } CComponentsFooter::CComponentsFooter( const int& x_pos, const int& y_pos, const int& w, const int& h, @@ -117,7 +117,7 @@ void CComponentsFooter::setButtonLabels(const struct button_label_s * const cont //footer as primary container (in this context '=this') and the parent for the button label container (chain object), //button label container (chain object) itself is concurrent the parent object for button objects. if (chain == NULL){ - chain = new CComponentsFrmChain(x_chain, CC_CENTERED, w_chain, height, 0, CC_DIR_X, this); + chain = new CComponentsFrmChain(x_chain, CC_CENTERED, w_chain, height, 0, CC_DIR_X, this, CC_SHADOW_OFF, COL_MENUCONTENT_PLUS_6, col_body); chain->setCorner(this->corner_rad, this->corner_type); chain->doPaintBg(false); } diff --git a/src/gui/components/cc_frm_footer.h b/src/gui/components/cc_frm_footer.h index 311afbc3e..b10ac8c8d 100644 --- a/src/gui/components/cc_frm_footer.h +++ b/src/gui/components/cc_frm_footer.h @@ -60,13 +60,13 @@ Missing parameters are filled with default values and must be assigned afterward class CComponentsFooter : public CComponentsHeader { private: - void initVarFooter( const int& x_pos, const int& y_pos, const int& w, const int& h = 0, - const int& buttons = 0, - CComponentsForm *parent = NULL, - int shadow_mode = CC_SHADOW_OFF, - fb_pixel_t color_frame = COL_MENUCONTENT_PLUS_6, - fb_pixel_t color_body = COL_MENUFOOT_PLUS_0, - fb_pixel_t color_shadow = COL_SHADOW_PLUS_0); + void initVarFooter( const int& x_pos, const int& y_pos, const int& w, const int& h, + const int& buttons, + CComponentsForm *parent, + int shadow_mode, + fb_pixel_t color_frame, + fb_pixel_t color_body, + fb_pixel_t color_shadow ); ///show button frame and background, default false bool btn_contour; diff --git a/src/gui/components/cc_frm_window.cpp b/src/gui/components/cc_frm_window.cpp index 869acd530..682236278 100644 --- a/src/gui/components/cc_frm_window.cpp +++ b/src/gui/components/cc_frm_window.cpp @@ -168,9 +168,10 @@ void CComponentsWindow::initWindowSize() if (cc_parent) return; - if (width == 0) + if (width == 0 || (unsigned)width > frameBuffer->getScreenWidth()) width = frameBuffer->getScreenWidth(); - if (height == 0) + + if (height == 0 || (unsigned)height > frameBuffer->getScreenHeight()) height = frameBuffer->getScreenHeight(); } @@ -218,7 +219,7 @@ void CComponentsWindow::initFooter() ccw_footer->setPos(0, cc_yr + height - ccw_footer->getHeight()- fr_thickness); ccw_footer->setWidth(width-2*fr_thickness); ccw_footer->enableShadow(false/*shadow*/); - ccw_footer->setCorner(corner_rad-fr_thickness/2, CORNER_BOTTOM); + ccw_footer->setCorner(corner_rad-fr_thickness, CORNER_BOTTOM); ccw_footer->setButtonFont(ccw_button_font); ccw_footer->setColorBody(ccw_col_footer); ccw_footer->doPaintBg(true); diff --git a/src/gui/lua/lua_api_version.h b/src/gui/lua/lua_api_version.h index f95bdbc54..51f649f64 100644 --- a/src/gui/lua/lua_api_version.h +++ b/src/gui/lua/lua_api_version.h @@ -4,4 +4,4 @@ * to luainstance.h changes */ #define LUA_API_VERSION_MAJOR 1 -#define LUA_API_VERSION_MINOR 39 +#define LUA_API_VERSION_MINOR 46 diff --git a/src/gui/lua/lua_cc_picture.cpp b/src/gui/lua/lua_cc_picture.cpp index 926bb520f..b383bd79b 100644 --- a/src/gui/lua/lua_cc_picture.cpp +++ b/src/gui/lua/lua_cc_picture.cpp @@ -57,6 +57,8 @@ void CLuaInstCCPicture::CCPictureRegister(lua_State *L) { "hide", CLuaInstCCPicture::CCPictureHide }, { "setPicture", CLuaInstCCPicture::CCPictureSetPicture }, { "setCenterPos", CLuaInstCCPicture::CCPictureSetCenterPos }, + { "getHeight", CLuaInstCCPicture::CCPictureGetHeight }, + { "getWidth", CLuaInstCCPicture::CCPictureGetWidth }, { "__gc", CLuaInstCCPicture::CCPictureDelete }, { NULL, NULL } }; @@ -126,6 +128,26 @@ int CLuaInstCCPicture::CCPictureNew(lua_State *L) return 1; } +int CLuaInstCCPicture::CCPictureGetHeight(lua_State *L) +{ + CLuaCCPicture *D = CCPictureCheck(L, 1); + if (!D) return 0; + + int h = D->cp->getHeight(); + lua_pushinteger(L, h); + return 1; +} + +int CLuaInstCCPicture::CCPictureGetWidth(lua_State *L) +{ + CLuaCCPicture *D = CCPictureCheck(L, 1); + if (!D) return 0; + + int w = D->cp->getWidth(); + lua_pushinteger(L, w); + return 1; +} + int CLuaInstCCPicture::CCPicturePaint(lua_State *L) { lua_assert(lua_istable(L,1)); diff --git a/src/gui/lua/lua_cc_picture.h b/src/gui/lua/lua_cc_picture.h index 2fb7c3e14..8bbc697ad 100644 --- a/src/gui/lua/lua_cc_picture.h +++ b/src/gui/lua/lua_cc_picture.h @@ -46,6 +46,8 @@ class CLuaInstCCPicture static int CCPictureHide(lua_State *L); static int CCPictureSetPicture(lua_State *L); static int CCPictureSetCenterPos(lua_State *L); + static int CCPictureGetHeight(lua_State *L); + static int CCPictureGetWidth(lua_State *L); static int CCPictureDelete(lua_State *L); }; diff --git a/src/gui/lua/lua_cc_text.cpp b/src/gui/lua/lua_cc_text.cpp index f7ed3a540..60f23f78c 100644 --- a/src/gui/lua/lua_cc_text.cpp +++ b/src/gui/lua/lua_cc_text.cpp @@ -77,7 +77,7 @@ int CLuaInstCCText::CCTextNew(lua_State *L) lua_assert(lua_istable(L,1)); CLuaCCWindow* parent = NULL; - lua_Integer x=10, y=10, dx=100, dy=100; + lua_Integer x=10, y=10, dx=-1, dy=-1; std::string text = ""; std::string tmpMode = ""; lua_Integer mode = CTextBox::AUTO_WIDTH; @@ -139,6 +139,16 @@ int CLuaInstCCText::CCTextNew(lua_State *L) } CComponentsForm* pw = (parent && parent->w) ? parent->w->getBodyObject() : NULL; + if(pw){ + if(dy < 1) + dy = pw->getHeight(); + if(dx < 1) + dx = pw->getWidth(); + } + if(dx < 1) + dx = 100; + if(dy < 1) + dy = 100; CLuaCCText **udata = (CLuaCCText **) lua_newuserdata(L, sizeof(CLuaCCText *)); *udata = new CLuaCCText(); diff --git a/src/gui/lua/lua_cc_window.cpp b/src/gui/lua/lua_cc_window.cpp index 9977bfa2b..03313ca22 100644 --- a/src/gui/lua/lua_cc_window.cpp +++ b/src/gui/lua/lua_cc_window.cpp @@ -56,6 +56,7 @@ void CLuaInstCCWindow::CCWindowRegister(lua_State *L) { "header_height", CLuaInstCCWindow::CCWindowGetHeaderHeight_dep }, /* function 'header_height' is deprecated */ { "footer_height", CLuaInstCCWindow::CCWindowGetFooterHeight_dep }, /* function 'footer_height' is deprecated */ { "setCenterPos", CLuaInstCCWindow::CCWindowSetCenterPos }, + { "setDimensionsAll", CLuaInstCCWindow::CCWindowSetDimensionsAll }, { "__gc", CLuaInstCCWindow::CCWindowDelete }, { NULL, NULL } }; @@ -160,7 +161,7 @@ int CLuaInstCCWindow::CCWindowNew(lua_State *L) buttons.push_back(btnSblue); } if (!buttons.empty()) - footer->setButtonLabels(buttons, dx-20, (dx-20) / (buttons.size()+1)); + footer->setButtonLabels(buttons, (*udata)->w->getWidth()-20, ((*udata)->w->getWidth()-20) / (buttons.size()+1)); } } @@ -295,6 +296,28 @@ int CLuaInstCCWindow::CCWindowGetFooterHeight(lua_State *L) return 1; } +int CLuaInstCCWindow::CCWindowSetDimensionsAll(lua_State *L) +{ + CLuaCCWindow *D = CCWindowCheck(L, 1); + if (!D) return 0; + lua_Integer x = luaL_checkint(L, 2); + lua_Integer y = luaL_checkint(L, 3); + lua_Integer w = luaL_checkint(L, 4); + lua_Integer h = luaL_checkint(L, 5); + if(x>-1 && y > -1 && w > 1 && h > 1){ + if (h > (lua_Integer)CFrameBuffer::getInstance()->getScreenHeight()) + h = (lua_Integer)CFrameBuffer::getInstance()->getScreenHeight(); + if (w > (lua_Integer)CFrameBuffer::getInstance()->getScreenWidth()) + w = (lua_Integer)CFrameBuffer::getInstance()->getScreenWidth(); + if(x > w) + x = 0; + if(y > h) + y = 0; + D->w->setDimensionsAll(x,y,w,h); + } + return 0; +} + int CLuaInstCCWindow::CCWindowSetCenterPos(lua_State *L) { lua_assert(lua_istable(L,1)); diff --git a/src/gui/lua/lua_cc_window.h b/src/gui/lua/lua_cc_window.h index 0e32bc386..98cd9ac86 100644 --- a/src/gui/lua/lua_cc_window.h +++ b/src/gui/lua/lua_cc_window.h @@ -51,6 +51,7 @@ class CLuaInstCCWindow static int CCWindowGetFooterHeight_dep(lua_State *L); // function 'footer_height' is deprecated static int CCWindowSetCenterPos(lua_State *L); static int CCWindowDelete(lua_State *L); + static int CCWindowSetDimensionsAll(lua_State *L); }; #endif //_LUACCWINDOW_H diff --git a/src/gui/widget/menue.cpp b/src/gui/widget/menue.cpp index d20cfec10..d66d7da4a 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -1242,7 +1242,7 @@ void CMenuWidget::paint() header->enableShadow(CC_SHADOW_RIGHT); header->setOffset(10); } - header->setColorBody(COL_MENUHEAD_PLUS_0); + header->setColorAll(COL_MENUCONTENT_PLUS_6, COL_MENUHEAD_PLUS_0, COL_SHADOW_PLUS_0); header->setCaptionColor(COL_MENUHEAD_TEXT); header->enableColBodyGradient(g_settings.theme.menu_Head_gradient, COL_MENUCONTENT_PLUS_0); header->enableGradientBgCleanUp(savescreen); diff --git a/src/nhttpd/tuxboxapi/controlapi.cpp b/src/nhttpd/tuxboxapi/controlapi.cpp index 3cfbfd527..98993d755 100644 --- a/src/nhttpd/tuxboxapi/controlapi.cpp +++ b/src/nhttpd/tuxboxapi/controlapi.cpp @@ -219,6 +219,9 @@ const CControlAPI::TyCgiCall CControlAPI::yCgiCallList[]= {"renamebouquet", &CControlAPI::renameBouquetCGI, "text/plain"}, {"changebouquet", &CControlAPI::changeBouquetCGI, "text/plain"}, {"updatebouquet", &CControlAPI::updateBouquetCGI, "text/plain"}, + // xmltv + {"xmltv.data", &CControlAPI::xmltvepgCGI, "+xml"}, + {"xmltv.m3u", &CControlAPI::xmltvm3uCGI, ""}, // utils {"build_live_url", &CControlAPI::build_live_url, ""}, {"get_logo", &CControlAPI::logoCGI, "text/plain"}, @@ -3036,6 +3039,125 @@ void CControlAPI::updateBouquetCGI(CyhookHandler *hh) NeutrinoAPI->UpdateBouquets(); hh->SendOk(); } +//----------------------------------------------------------------------------- +// details EPG Information in xmltv format from all user bouquets +//----------------------------------------------------------------------------- +void CControlAPI::xmltvepgCGI(CyhookHandler *hh) +{ + int mode = NeutrinoAPI->Zapit->getMode(); + hh->ParamList["format"] = "xml"; + hh->outStart(); + + t_channel_id channel_id; + std::string result = ""; + std::string channelTag = "", channelData = ""; + std::string programmeTag = "", programmeData = ""; + + ZapitChannelList chanlist; + CChannelEventList eList; + CChannelEventList::iterator eventIterator; + + for (int i = 0; i < (int) g_bouquetManager->Bouquets.size(); i++) + { + if (mode == CZapitClient::MODE_RADIO) + g_bouquetManager->Bouquets[i]->getRadioChannels(chanlist); + else + g_bouquetManager->Bouquets[i]->getTvChannels(chanlist); + if(!chanlist.empty() && !g_bouquetManager->Bouquets[i]->bHidden && g_bouquetManager->Bouquets[i]->bUser) + { + for(int j = 0; j < (int) chanlist.size(); j++) + { + CZapitChannel * channel = chanlist[j]; + channel_id = channel->getChannelID() & 0xFFFFFFFFFFFFULL; + channelTag = "channel id=\""+string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel_id)+"\""; + channelData = hh->outPair("display-name", hh->outValue(channel->getName()), true); + result += hh->outObject(channelTag, channelData); + + eList.clear(); + + CEitManager::getInstance()->getEventsServiceKey(channel_id, eList); + + if (eList.size() == 0) + continue; + + if (eList.size() > 50) + eList.erase(eList.begin()+50,eList.end()); + + for (eventIterator = eList.begin(); eventIterator != eList.end(); ++eventIterator) + { + if (eventIterator->get_channel_id() == channel_id) + { + programmeTag = "programme "; + programmeTag += "channel=\""+string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel_id)+"\" "; + char zbuffer[25] = { 0 }; + struct tm *mtime = localtime(&eventIterator->startTime); + strftime(zbuffer, 21, "%Y%m%d%H%M%S +0200", mtime); + programmeTag += "start=\""+std::string(zbuffer)+"\" "; + long _stoptime = eventIterator->startTime + eventIterator->duration; + mtime = localtime(&_stoptime); + strftime(zbuffer, 21, "%Y%m%d%H%M%S +0200", mtime); + programmeTag += "stop=\""+std::string(zbuffer)+"\" "; + + programmeData = hh->outPair("title lang=\"de\"", hh->outValue(eventIterator->description), false); + programmeData += hh->outPair("desc lang=\"de\"", hh->outValue(eventIterator->text), true); + + result += hh->outArrayItem(programmeTag, programmeData, false); + } + } + } + } + } + + + result = hh->outObject("tv generator-info-name=\"Neutrino XMLTV Generator v1.0\"", result); + + result = "\n\n" + result; + + hh->SendResult(result); +} + +void CControlAPI::xmltvm3uCGI(CyhookHandler *hh) +{ + hh->outStart(); + std::string result = ""; + + int mode = NeutrinoAPI->Zapit->getMode(); + // build url + std::string url = ""; + if(!hh->ParamList["host"].empty()) + url = "http://"+hh->ParamList["host"]; + else + url = "http://"+hh->HeaderList["Host"]; + /* strip off optional custom port */ + if (url.rfind(":") != 4) + url = url.substr(0, url.rfind(":")); + + url += ":31339/id="; + + result += "#EXTM3U\n"; + + for (int i = 0; i < (int) g_bouquetManager->Bouquets.size(); i++) + { + ZapitChannelList chanlist; + if (mode == CZapitClient::MODE_RADIO) + g_bouquetManager->Bouquets[i]->getRadioChannels(chanlist); + else + g_bouquetManager->Bouquets[i]->getTvChannels(chanlist); + if(!chanlist.empty() && !g_bouquetManager->Bouquets[i]->bHidden && g_bouquetManager->Bouquets[i]->bUser) + { + for(int j = 0; j < (int) chanlist.size(); j++) + { + CZapitChannel * channel = chanlist[j]; + std::string bouq_name = g_bouquetManager->Bouquets[i]->Name; + std::string chan_id_short = string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel->getChannelID() & 0xFFFFFFFFFFFFULL); + result += "#EXTINF:-1 tvg-id=\""+chan_id_short+"\" tvg-logo=\""+chan_id_short+".png\" group-title=\""+bouq_name+"\", [COLOR gold]"+channel->getName()+"[/COLOR]\n"; + result += url+string_printf(PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS, channel->getChannelID())+"\n"; + } + } + } + + hh->SendResult(result); +} //------------------------------------------------------------------------- // audio_no : (optional) audio channel // host : (optional) ip of dbox diff --git a/src/nhttpd/tuxboxapi/controlapi.h b/src/nhttpd/tuxboxapi/controlapi.h index 05749b7f5..e80702b28 100644 --- a/src/nhttpd/tuxboxapi/controlapi.h +++ b/src/nhttpd/tuxboxapi/controlapi.h @@ -123,6 +123,8 @@ private: void renameBouquetCGI(CyhookHandler *hh); void changeBouquetCGI(CyhookHandler *hh); void updateBouquetCGI(CyhookHandler *hh); + void xmltvepgCGI(CyhookHandler *hh); + void xmltvm3uCGI(CyhookHandler *hh); void build_live_url(CyhookHandler *hh); void logoCGI(CyhookHandler *hh); void ConfigCGI(CyhookHandler *hh); diff --git a/src/nhttpd/yhttpd_core/yhook.cpp b/src/nhttpd/yhttpd_core/yhook.cpp index 56537c057..7838cefa9 100644 --- a/src/nhttpd/yhttpd_core/yhook.cpp +++ b/src/nhttpd/yhttpd_core/yhook.cpp @@ -444,10 +444,11 @@ std::string CyhookHandler::outSingle(std::string _content) { //----------------------------------------------------------------------------- std::string CyhookHandler::outPair(std::string _key, std::string _content, bool _next) { - std::string result = ""; + std::string result = "", _key_close = "", tmp; + ySplitString(_key, " ", _key_close, tmp); switch (outType) { case xml: - result = outIndent() + "<" + _key + ">" + _content + ""; + result = outIndent() + "<" + _key + ">" + _content + ""; break; case json: result = outIndent() + "\"" + _key + "\": \"" + _content + "\""; @@ -466,11 +467,12 @@ std::string CyhookHandler::outPair(std::string _key, std::string _content, bool //----------------------------------------------------------------------------- std::string CyhookHandler::outArray(std::string _key, std::string _content, bool _next) { - std::string result = ""; + std::string result = "", _key_close = "", tmp; + ySplitString(_key, " ", _key_close, tmp); switch (outType) { case xml: //TODO: xml check and DESC check - result = outIndent() + "<" + _key + ">\n" + _content + ""; + result = outIndent() + "<" + _key + ">\n" + _content + ""; result += "\n"; break; case json: @@ -489,11 +491,12 @@ std::string CyhookHandler::outArray(std::string _key, std::string _content, bool //----------------------------------------------------------------------------- std::string CyhookHandler::outArrayItem(std::string _key, std::string _content, bool _next) { - std::string result = ""; + std::string result = "", _key_close = "", tmp; + ySplitString(_key, " ", _key_close, tmp); switch (outType) { case xml: //TODO: xml check and DESC check - result = outIndent() + "<" + _key + ">\n" + _content + ""; + result = outIndent() + "<" + _key + ">\n" + _content + ""; result += "\n"; break; case json: @@ -511,11 +514,12 @@ std::string CyhookHandler::outArrayItem(std::string _key, std::string _content, } //----------------------------------------------------------------------------- std::string CyhookHandler::outObject(std::string _key, std::string _content, bool _next) { - std::string result = ""; + std::string result = "", _key_close = "", tmp; + ySplitString(_key, " ", _key_close, tmp); switch (outType) { case xml: //TODO: xml check and DESC check - result = outIndent() + "<" + _key + ">\n" + _content + ""; + result = outIndent() + "<" + _key + ">\n" + _content + ""; result += "\n"; break; case json: