From dca7e1017973354afdc31d8d72e021a771955ca2 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Sun, 24 Sep 2017 22:24:26 +0200 Subject: [PATCH 01/24] cc_detailsline.cpp: fix possible unintended reduced height of bottom marker Decrement value removed. Height of bottom marker was decreased on every new repaint if no new height was assigned. Was to see in bouqueteditor while scrolling with bouqets or channel select window. comes in with 9948649f55f2bba8ece636a17028159d11a3298b --- src/gui/components/cc_detailsline.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/gui/components/cc_detailsline.cpp b/src/gui/components/cc_detailsline.cpp index 82dd27cca..4184a145c 100644 --- a/src/gui/components/cc_detailsline.cpp +++ b/src/gui/components/cc_detailsline.cpp @@ -96,9 +96,6 @@ void CComponentsDetailsLine::paint(bool do_save_bg) int sw = shadow_w; - // reduce two times the shadow width, to avoid shadow overlaps - h_mark_down -= 2*sw; - int y_mark_top = y-h_mark_top/2; int y_mark_down = y_down-h_mark_down/2; int dx_c = dl_w%2; //correction for odd values From 9e2a7d7f79646b59d54be8c0815d0196075fcfaf Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 17:33:34 +0200 Subject: [PATCH 02/24] add LUA_CFLAGS everywhere widget/menue.h is used --- src/Makefile.am | 1 + src/daemonc/Makefile.am | 1 + src/driver/Makefile.am | 1 + src/driver/audiodec/Makefile.am | 1 + src/driver/pictureviewer/Makefile.am | 1 + src/gui/Makefile.am | 1 + src/gui/bedit/Makefile.am | 1 + src/gui/components/Makefile.am | 1 + src/gui/moviebrowser/Makefile.am | 1 + src/gui/widget/Makefile.am | 1 + src/nhttpd/tuxboxapi/Makefile.am | 1 + src/system/Makefile.am | 1 + src/zapit/src/Makefile.am | 1 + 13 files changed, 13 insertions(+) diff --git a/src/Makefile.am b/src/Makefile.am index f33f8f87c..9657a4dab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,7 @@ AM_CPPFLAGS = \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ @AVFORMAT_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ if BOXTYPE_TRIPLE diff --git a/src/daemonc/Makefile.am b/src/daemonc/Makefile.am index c272b2dee..a4df3eae6 100644 --- a/src/daemonc/Makefile.am +++ b/src/daemonc/Makefile.am @@ -13,6 +13,7 @@ AM_CPPFLAGS += \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ @AVFORMAT_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ diff --git a/src/driver/Makefile.am b/src/driver/Makefile.am index 37040c4b0..1daf88a02 100644 --- a/src/driver/Makefile.am +++ b/src/driver/Makefile.am @@ -15,6 +15,7 @@ AM_CPPFLAGS = \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ @AVFORMAT_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libneutrino_driver.a libneutrino_driver_netfile.a diff --git a/src/driver/audiodec/Makefile.am b/src/driver/audiodec/Makefile.am index eccc74b27..ab579fcc1 100644 --- a/src/driver/audiodec/Makefile.am +++ b/src/driver/audiodec/Makefile.am @@ -11,6 +11,7 @@ AM_CPPFLAGS = \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ @AVFORMAT_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libneutrino_driver_audiodec.a diff --git a/src/driver/pictureviewer/Makefile.am b/src/driver/pictureviewer/Makefile.am index bff7f879e..16bf123ca 100644 --- a/src/driver/pictureviewer/Makefile.am +++ b/src/driver/pictureviewer/Makefile.am @@ -9,6 +9,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/lib/libconfigfile \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 906cda947..e77a66f98 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -37,6 +37,7 @@ AM_CPPFLAGS += \ @CURL_CFLAGS@ \ @FREETYPE_CFLAGS@ \ @AVFORMAT_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libtimerlist.a libneutrino_gui.a libneutrino_gui2.a diff --git a/src/gui/bedit/Makefile.am b/src/gui/bedit/Makefile.am index 1aaed9a3d..e07422406 100644 --- a/src/gui/bedit/Makefile.am +++ b/src/gui/bedit/Makefile.am @@ -11,6 +11,7 @@ AM_CPPFLAGS += \ -I$(top_srcdir)/lib/xmltree \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libneutrino_gui_bedit.a diff --git a/src/gui/components/Makefile.am b/src/gui/components/Makefile.am index e43158b13..3364ad773 100644 --- a/src/gui/components/Makefile.am +++ b/src/gui/components/Makefile.am @@ -11,6 +11,7 @@ AM_CPPFLAGS += \ -I$(top_srcdir)/lib/xmltree \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libneutrino_gui_components.a diff --git a/src/gui/moviebrowser/Makefile.am b/src/gui/moviebrowser/Makefile.am index 46379f2ca..438c3ac84 100644 --- a/src/gui/moviebrowser/Makefile.am +++ b/src/gui/moviebrowser/Makefile.am @@ -11,6 +11,7 @@ AM_CPPFLAGS += \ -I$(top_srcdir)/lib/xmltree \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libneutrino_gui_moviebrowser.a diff --git a/src/gui/widget/Makefile.am b/src/gui/widget/Makefile.am index 838ba162f..6a0c88bd5 100644 --- a/src/gui/widget/Makefile.am +++ b/src/gui/widget/Makefile.am @@ -10,6 +10,7 @@ AM_CPPFLAGS += \ -I$(top_srcdir)/lib/libconfigfile \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libneutrino_gui_widget.a libneutrino_gui_widget2.a diff --git a/src/nhttpd/tuxboxapi/Makefile.am b/src/nhttpd/tuxboxapi/Makefile.am index 2376c052c..9bae88869 100644 --- a/src/nhttpd/tuxboxapi/Makefile.am +++ b/src/nhttpd/tuxboxapi/Makefile.am @@ -16,6 +16,7 @@ AM_CPPFLAGS += \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ @AVFORMAT_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libnhttpd_tuxboxapi.a diff --git a/src/system/Makefile.am b/src/system/Makefile.am index b8fdac6c1..3304ec953 100644 --- a/src/system/Makefile.am +++ b/src/system/Makefile.am @@ -20,6 +20,7 @@ AM_CPPFLAGS = \ @SIGC_CFLAGS@ \ @FREETYPE_CFLAGS@ \ @AVFORMAT_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libneutrino_system.a diff --git a/src/zapit/src/Makefile.am b/src/zapit/src/Makefile.am index 96e700284..1d185ae00 100644 --- a/src/zapit/src/Makefile.am +++ b/src/zapit/src/Makefile.am @@ -12,6 +12,7 @@ AM_CPPFLAGS += \ -I$(top_srcdir)/lib/xmltree \ @FREETYPE_CFLAGS@ \ @SIGC_CFLAGS@ \ + @LUA_CFLAGS@ \ @HWLIB_CFLAGS@ noinst_LIBRARIES = libzapit.a From 971f3703a6c6554b805682cca429b89e91271f9b Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 18:11:47 +0200 Subject: [PATCH 03/24] add comments to suppres -Wimplicit-fallthrough warnings --- lib/jsoncpp/jsoncpp.cpp | 1 + src/driver/netfile.cpp | 1 + src/driver/radiotext.cpp | 1 + src/driver/screenshot.cpp | 2 ++ src/gui/lua/lua_threads_copy.cpp | 1 + src/gui/motorcontrol.cpp | 2 ++ src/gui/screensetup.cpp | 1 + src/gui/widget/menue.cpp | 3 +++ src/neutrino.cpp | 1 + src/nhttpd/yhttpd_core/yhook.cpp | 2 +- src/system/ytparser.cpp | 1 + src/zapit/src/frontend.cpp | 5 ++++- 12 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/jsoncpp/jsoncpp.cpp b/lib/jsoncpp/jsoncpp.cpp index ce72ec1d8..59c98d5f7 100644 --- a/lib/jsoncpp/jsoncpp.cpp +++ b/lib/jsoncpp/jsoncpp.cpp @@ -1455,6 +1455,7 @@ bool OurReader::readToken(Token& token) { ok = readStringSingleQuote(); break; } // else continue + /* is a break missing here? or is this correct? */ case '/': token.type_ = tokenComment; ok = readComment(); diff --git a/src/driver/netfile.cpp b/src/driver/netfile.cpp index 12270fb93..198d87dfb 100644 --- a/src/driver/netfile.cpp +++ b/src/driver/netfile.cpp @@ -1027,6 +1027,7 @@ FILE *f_open(const char *filename, const char *acctype) /* create the correct url from the station number */ CRLFCut(url.host); sprintf(url.url, "http://classic.shoutcast.com/sbin/shoutcast-playlist.pls?rn=%s&file=filename.pls", url.host); + /* fall through */ case MODE_PLS: { char *ptr2, /*buf[4096], use local buf from function */ servers[25][1024]; diff --git a/src/driver/radiotext.cpp b/src/driver/radiotext.cpp index 773c51034..e73207964 100644 --- a/src/driver/radiotext.cpp +++ b/src/driver/radiotext.cpp @@ -289,6 +289,7 @@ if (i < 0) { fprintf(stderr, "RT %s: i < 0 (%d)\n", __FUNCTION__, i); break; } switch (val) { case 0x0a: // RT have_radiotext = true; + /* fall through */ case 0x46: // RTplus-Tags case 0xda: // RASS case 0x07: // PTY diff --git a/src/driver/screenshot.cpp b/src/driver/screenshot.cpp index 28366adc2..d44eac6ab 100644 --- a/src/driver/screenshot.cpp +++ b/src/driver/screenshot.cpp @@ -274,6 +274,7 @@ bool CScreenShot::SaveFile() break; default: printf("CScreenShot::SaveFile unsupported format %d, using jpeg\n", format); + /* fall through */ case FORMAT_JPG: ret = SaveJpg(); break; @@ -517,6 +518,7 @@ void CScreenShot::MakeFileName(const t_channel_id channel_id) break; default: printf("CScreenShot::MakeFileName unsupported format %d, using jpeg\n", format); + /* fall through */ case FORMAT_JPG: strcat(fname, ".jpg"); break; diff --git a/src/gui/lua/lua_threads_copy.cpp b/src/gui/lua/lua_threads_copy.cpp index a7d140018..6dba1651f 100644 --- a/src/gui/lua/lua_threads_copy.cpp +++ b/src/gui/lua/lua_threads_copy.cpp @@ -119,6 +119,7 @@ int CLLThread::llthread_copy_value(llthread_copy_state *state, int depth, int id lua_pushcfunction(state->to_L, fn); break; } + /* else fall through */ case LUA_TUSERDATA: case LUA_TTHREAD: default: diff --git a/src/gui/motorcontrol.cpp b/src/gui/motorcontrol.cpp index 1b9e38e36..7f3930a3c 100644 --- a/src/gui/motorcontrol.cpp +++ b/src/gui/motorcontrol.cpp @@ -350,7 +350,9 @@ void CMotorControl::motorStep(bool west) case STEP_MODE_AUTO: moving = 1; paintStatus(); + /* fall through */ default: + /* what is STEP_MODE_OFF supposed to do? */ g_Zapit->sendMotorCommand(0xE0, 0x31, cmd, 1, 40, 0); } } diff --git a/src/gui/screensetup.cpp b/src/gui/screensetup.cpp index 207020eab..5c1e29647 100644 --- a/src/gui/screensetup.cpp +++ b/src/gui/screensetup.cpp @@ -173,6 +173,7 @@ int CScreenSetup::exec(CMenuTarget* parent, const std::string &) ( g_settings.screen_EndY != y_coord[1] ) ) && (ShowMsg(LOCALE_VIDEOMENU_SCREENSETUP, LOCALE_MESSAGEBOX_DISCARD, CMsgBox::mbrYes, CMsgBox::mbYes | CMsgBox::mbCancel) == CMsgBox::mbrCancel)) break; + /* falls through */ case CRCInput::RC_timeout: loop = false; diff --git a/src/gui/widget/menue.cpp b/src/gui/widget/menue.cpp index 8cae40d7d..90947ad22 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -799,6 +799,7 @@ int CMenuWidget::exec(CMenuTarget* parent, const std::string &) switch ( rv ) { case menu_return::RETURN_EXIT_ALL: retval = menu_return::RETURN_EXIT_ALL; + /* fall through */ case menu_return::RETURN_EXIT: msg = CRCInput::RC_timeout; break; @@ -890,6 +891,7 @@ int CMenuWidget::exec(CMenuTarget* parent, const std::string &) break; case CRCInput::RC_up: dir = -1; + /* fall through */ default: /* fallthrough or RC_down => dir = 1 */ pos += dir; if (pos < 0 || pos >= (int)items.size()) @@ -950,6 +952,7 @@ int CMenuWidget::exec(CMenuTarget* parent, const std::string &) switch ( rv ) { case menu_return::RETURN_EXIT_ALL: retval = menu_return::RETURN_EXIT_ALL; + /* fall through */ case menu_return::RETURN_EXIT: msg = CRCInput::RC_timeout; break; diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 4d3a93b59..c5bbd2918 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -1790,6 +1790,7 @@ void CNeutrinoApp::SetChannelMode(int newmode) break; default: newmode = LIST_MODE_PROV; + /* fall through */ case LIST_MODE_PROV: if(mode == mode_radio) bouquetList = RADIObouquetList; diff --git a/src/nhttpd/yhttpd_core/yhook.cpp b/src/nhttpd/yhttpd_core/yhook.cpp index 2d4a88d4d..57acb79b6 100644 --- a/src/nhttpd/yhttpd_core/yhook.cpp +++ b/src/nhttpd/yhttpd_core/yhook.cpp @@ -283,7 +283,7 @@ std::string CyhookHandler::BuildHeader(bool cache) { case HTTP_MOVED_PERMANENTLY: // Status HTTP_*_TEMPORARILY (redirection) result += string_printf("Location: %s\r\n", NewURL.c_str()); - // NO break HERE !!! + // fall through default: time_t timer = time(0); diff --git a/src/system/ytparser.cpp b/src/system/ytparser.cpp index 6bd43c576..a2762f279 100644 --- a/src/system/ytparser.cpp +++ b/src/system/ytparser.cpp @@ -518,6 +518,7 @@ bool cYTFeedParser::ParseFeed(yt_feed_mode_t mode, std::string search, std::stri default: //trailer = "&time=today"; curfeed = "&chart=mostPopular"; + break; case MOST_POPULAR_ALL_TIME: curfeed = "&chart=mostPopular"; break; diff --git a/src/zapit/src/frontend.cpp b/src/zapit/src/frontend.cpp index 26482d2b1..95ad4e76c 100644 --- a/src/zapit/src/frontend.cpp +++ b/src/zapit/src/frontend.cpp @@ -435,6 +435,7 @@ fe_code_rate_t CFrontend::getCodeRate(const uint8_t fec_inner, delivery_system_t default: if (zapit_debug) printf("no valid fec for DVB-%c set.. assume auto\n", (delsys == DVB_S ? 'S' : (delsys == DVB_C ? 'C' : 'T'))); + /* fall through */ case fAuto: fec = FEC_AUTO; break; @@ -471,6 +472,7 @@ fe_code_rate_t CFrontend::getCodeRate(const uint8_t fec_inner, delivery_system_t default: if (zapit_debug) printf("no valid fec for DVB-S2 set.. !!\n"); + /* fall through */ case fAuto: fec = FEC_AUTO; break; @@ -786,6 +788,7 @@ void CFrontend::getXMLDelsysFEC(fe_code_rate_t xmlfec, delivery_system_t & delsy break; default: printf("[frontend] getXMLDelsysFEC: unknown FEC: %d !!!\n", xmlfec); + /* fall through */ case FEC_S2_AUTO: case FEC_AUTO: fec = FEC_AUTO; @@ -860,7 +863,7 @@ void CFrontend::getDelSys(delivery_system_t delsys, int f, int m, char *&fec, ch mod = (char *)"QPSK"; // AKA QAM_4 break; } - /* fallthrouh for FE_QAM... */ + /* fall through */ case QAM_AUTO: default: mod = (char *)"QAM_AUTO"; From 125eb6a7d13e55b3c0df2fe217efb169bb01d94c Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 18:13:03 +0200 Subject: [PATCH 04/24] pictureviewer: fix build with gcc7 --- src/driver/pictureviewer/crw.cpp | 17 +++++++++-------- src/driver/pictureviewer/jpeg.cpp | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/driver/pictureviewer/crw.cpp b/src/driver/pictureviewer/crw.cpp index e081aba57..1de75cdc7 100644 --- a/src/driver/pictureviewer/crw.cpp +++ b/src/driver/pictureviewer/crw.cpp @@ -173,7 +173,7 @@ int fh_crw_load(const char *filename,unsigned char **buffer,int* xp,int* /*yp*/) struct jpeg_decompress_struct *ciptr; struct r_crw_jpeg_error_mgr emgr; unsigned char *bp; - int px/*,py*/,c,x=*xp; + int px/*,py*/,c,x=*xp, ix; FILE *fh; JSAMPLE *lb; @@ -195,21 +195,22 @@ int fh_crw_load(const char *filename,unsigned char **buffer,int* xp,int* /*yp*/) jpeg_stdio_src(ciptr,fh); jpeg_read_header(ciptr,TRUE); ciptr->out_color_space=JCS_RGB; - if(x==(int)ciptr->image_width) + ix = (int)ciptr->image_width; + if (x == ix) ciptr->scale_denom=1; #if __cplusplus < 201103 - else if(abs(x*2 - ciptr->image_width) < 2) + else if (abs(x*2 - ix) < 2) ciptr->scale_denom=2; - else if(abs(x*4 - ciptr->image_width) < 4) + else if (abs(x*4 - ix) < 4) ciptr->scale_denom=4; - else if(abs(x*8 - ciptr->image_width) < 8) + else if (abs(x*8 - ix) < 8) ciptr->scale_denom=8; #else - else if(std::abs(x*2 - ciptr->image_width) < 2) + else if (std::abs(x*2 - ix) < 2) ciptr->scale_denom=2; - else if(std::abs(x*4 - ciptr->image_width) < 4) + else if (std::abs(x*4 - ix) < 4) ciptr->scale_denom=4; - else if(std::abs(x*8 - ciptr->image_width) < 8) + else if (std::abs(x*8 - ix) < 8) ciptr->scale_denom=8; #endif else diff --git a/src/driver/pictureviewer/jpeg.cpp b/src/driver/pictureviewer/jpeg.cpp index accb8a512..a61c91229 100644 --- a/src/driver/pictureviewer/jpeg.cpp +++ b/src/driver/pictureviewer/jpeg.cpp @@ -72,7 +72,7 @@ int fh_jpeg_load(const char *filename,unsigned char **buffer,int* x,int* y) struct jpeg_decompress_struct *ciptr; struct r_jpeg_error_mgr emgr; unsigned char *bp; - int px,py,c; + int px,py,c, ix; FILE *fh; JSAMPLE *lb; @@ -94,21 +94,22 @@ int fh_jpeg_load(const char *filename,unsigned char **buffer,int* x,int* y) jpeg_read_header(ciptr,TRUE); ciptr->out_color_space=JCS_RGB; ciptr->dct_method=JDCT_FASTEST; - if(*x==(int)ciptr->image_width) + ix = (int)ciptr->image_width; + if(*x == ix) ciptr->scale_denom=1; #if __cplusplus < 201103 - else if(abs(*x*2 - ciptr->image_width) < 2) + else if (abs(*x*2 - ix) < 2) ciptr->scale_denom=2; - else if(abs(*x*4 - ciptr->image_width) < 4) + else if (abs(*x*4 - ix) < 4) ciptr->scale_denom=4; - else if(abs(*x*8 - ciptr->image_width) < 8) + else if (abs(*x*8 - ix) < 8) ciptr->scale_denom=8; #else - else if(std::abs(*x*2 - ciptr->image_width) < 2) + else if (std::abs(*x*2 - ix) < 2) ciptr->scale_denom=2; - else if(std::abs(*x*4 - ciptr->image_width) < 4) + else if (std::abs(*x*4 - ix) < 4) ciptr->scale_denom=4; - else if(std::abs(*x*8 - ciptr->image_width) < 8) + else if (std::abs(*x*8 - ix) < 8) ciptr->scale_denom=8; #endif else From ea30b22119fdb17f27e099eab5cd6fdb50014ae8 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 18:13:44 +0200 Subject: [PATCH 05/24] neutrinoyparser: fix invalid logic in func_unmount_get_list --- src/nhttpd/tuxboxapi/neutrinoyparser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nhttpd/tuxboxapi/neutrinoyparser.cpp b/src/nhttpd/tuxboxapi/neutrinoyparser.cpp index 19933dd27..2dd411c59 100644 --- a/src/nhttpd/tuxboxapi/neutrinoyparser.cpp +++ b/src/nhttpd/tuxboxapi/neutrinoyparser.cpp @@ -794,7 +794,7 @@ std::string CNeutrinoYParser::func_unmount_get_list(CyhookHandler *, std::strin in >> ymount >> ylocal_dir >> yfstype; in.ignore(std::numeric_limits::max(), '\n'); yfstype = trim(yfstype); - if( (yfstype == "nfs") << (yfstype == "ftp") || (yfstype == "lufsd") ) + if( (yfstype == "nfs") || (yfstype == "ftp") || (yfstype == "lufsd") ) { mounts=ylocal_dir +" on "+ ymount + " ("+yfstype+")"; ysel = ((j==0) ? "checked=\"checked\"" : ""); From 99c8168d2ce1a6c3a2b48e2ea7555b65221ac96a Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 21:35:01 +0200 Subject: [PATCH 06/24] change time_monotonic_ms() from time_t to int64_t time_monotonic_ms values did wrap every ~24 days, leading to problems in code that did not cope with that. Instead of fixing all places where relative comparisons with time_monotonic_ms() are made, just use a bigger datatype. Convert all users to the new type. --- src/driver/abstime.c | 4 ++-- src/driver/abstime.h | 4 ++-- src/driver/fb_accel_glfb.cpp | 7 ++++--- src/driver/fb_accel_sti.cpp | 16 +++++++++------- src/eitd/xmlutil.cpp | 6 +++--- src/gui/movieplayer.h | 2 +- src/gui/widget/shellwindow.cpp | 4 ++-- src/zapit/src/frontend.cpp | 9 +++++---- 8 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/driver/abstime.c b/src/driver/abstime.c index af7c1c7fc..e74c268c3 100644 --- a/src/driver/abstime.c +++ b/src/driver/abstime.c @@ -2,7 +2,7 @@ #include /* for perror */ #include -time_t time_monotonic_ms(void) +int64_t time_monotonic_ms(void) { struct timespec t; time_t ret; @@ -11,7 +11,7 @@ time_t time_monotonic_ms(void) perror("time_monotonic_ms clock_gettime"); return -1; } - ret = ((t.tv_sec + 604800)& 0x01FFFFF) * 1000; /* avoid overflow */ + ret = (t.tv_sec + 604800) * (int64_t)1000; /* avoid overflow */ ret += t.tv_nsec / 1000000; return ret; } diff --git a/src/driver/abstime.h b/src/driver/abstime.h index b530755b6..78d1e6117 100644 --- a/src/driver/abstime.h +++ b/src/driver/abstime.h @@ -6,8 +6,8 @@ extern "C" { #endif -extern time_t time_monotonic_ms(void); -extern time_t time_monotonic(void); +time_t time_monotonic(void); +int64_t time_monotonic_ms(void); uint64_t time_monotonic_us(void); #ifdef __cplusplus } diff --git a/src/driver/fb_accel_glfb.cpp b/src/driver/fb_accel_glfb.cpp index 2d9ba539f..d62ea65f1 100644 --- a/src/driver/fb_accel_glfb.cpp +++ b/src/driver/fb_accel_glfb.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include extern GLFramebuffer *glfb; @@ -115,18 +116,18 @@ void CFbAccelGLFB::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32 void CFbAccelGLFB::run() { printf(LOGTAG "run start\n"); - time_t last_blit = 0; + int64_t last_blit = INT64_MAX; blit_pending = false; blit_thread = true; blit_mutex.lock(); set_threadname("glfb::autoblit"); while (blit_thread) { blit_cond.wait(&blit_mutex, blit_pending ? BLIT_INTERVAL_MIN : BLIT_INTERVAL_MAX); - time_t now = time_monotonic_ms(); + int64_t now = time_monotonic_ms(); if (now - last_blit < BLIT_INTERVAL_MIN) { blit_pending = true; - //printf(LOGTAG "run: skipped, time %ld\n", now - last_blit); + //printf(LOGTAG "run: skipped, time %" PRId64 "\n", now - last_blit); } else { diff --git a/src/driver/fb_accel_sti.cpp b/src/driver/fb_accel_sti.cpp index dfe0ac5c3..808254b38 100644 --- a/src/driver/fb_accel_sti.cpp +++ b/src/driver/fb_accel_sti.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -330,18 +331,19 @@ void CFbAccelSTi::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_ void CFbAccelSTi::run() { printf(LOGTAG "::run start\n"); - time_t last_blit = 0; + int64_t last_blit = INT64_MAX; /* blit at first iteration */ blit_pending = false; blit_thread = true; blit_mutex.lock(); set_threadname("stifb::autoblit"); while (blit_thread) { blit_cond.wait(&blit_mutex, blit_pending ? BLIT_INTERVAL_MIN : BLIT_INTERVAL_MAX); - time_t now = time_monotonic_ms(); - if (now - last_blit < BLIT_INTERVAL_MIN) + int64_t now = time_monotonic_ms(); + int64_t diff = now - last_blit; + if (diff < BLIT_INTERVAL_MIN) { blit_pending = true; - //printf(LOGTAG "::run: skipped, time %ld\n", now - last_blit); + //printf(LOGTAG "::run: skipped, time %" PRId64 "\n", diff); } else { @@ -367,9 +369,9 @@ void CFbAccelSTi::blit() void CFbAccelSTi::_blit() { #if 0 - static time_t last = 0; - time_t now = time_monotonic_ms(); - printf("%s %ld\n", __func__, now - last); + static int64_t last = 0; + int64_t now = time_monotonic_ms(); + printf("%s %" PRId64 "\n", __func__, now - last); last = now; #endif OpenThreads::ScopedLock m_lock(mutex); diff --git a/src/eitd/xmlutil.cpp b/src/eitd/xmlutil.cpp index 6748e14f5..4332e462a 100644 --- a/src/eitd/xmlutil.cpp +++ b/src/eitd/xmlutil.cpp @@ -486,12 +486,12 @@ void *insertEventsfromFile(void * data) std::string epg_dir = (char *) data; indexname = epg_dir + "index.xml"; - time_t now = time_monotonic_ms(); + int64_t now = time_monotonic_ms(); xmlDocPtr index_parser = parseXmlFile(indexname.c_str()); if (index_parser == NULL) { readEventsFromDir(epg_dir, ev_count); - printf("[sectionsd] Reading Information finished after %ld milliseconds (%d events)\n", + printf("[sectionsd] Reading Information finished after %" PRId64 " milliseconds (%d events)\n", time_monotonic_ms()-now, ev_count); reader_ready = true; pthread_exit(NULL); @@ -515,7 +515,7 @@ void *insertEventsfromFile(void * data) xmlFreeDoc(index_parser); printdate_ms(stdout); - printf("[sectionsd] Reading Information finished after %ld milliseconds (%d events)\n", + printf("[sectionsd] Reading Information finished after %" PRId64 " milliseconds (%d events)\n", time_monotonic_ms()-now, ev_count); reader_ready = true; diff --git a/src/gui/movieplayer.h b/src/gui/movieplayer.h index 0b6cd507d..bef6bc9c9 100644 --- a/src/gui/movieplayer.h +++ b/src/gui/movieplayer.h @@ -142,7 +142,7 @@ class CMoviePlayerGui : public CMenuTarget unsigned short sub_supported[MAX_PLAYBACK_PIDS]; int currentspid; int min_x, min_y, max_x, max_y; - time_t end_time; + int64_t end_time; bool ext_subs; bool lock_subs; uint64_t last_read; diff --git a/src/gui/widget/shellwindow.cpp b/src/gui/widget/shellwindow.cpp index bd5daa3ca..f2b641f5a 100644 --- a/src/gui/widget/shellwindow.cpp +++ b/src/gui/widget/shellwindow.cpp @@ -133,14 +133,14 @@ void CShellWindow::exec() fds.events = POLLIN | POLLHUP | POLLERR; fcntl(fds.fd, F_SETFL, fcntl(fds.fd, F_GETFL, 0) | O_NONBLOCK); - time_t lastPaint = time_monotonic_ms(); + int64_t lastPaint = time_monotonic_ms(); bool ok = true, nlseen = false, dirty = false, incomplete = false; char output[1024]; std::string txt = ""; std::string line = ""; do { - time_t now; + int64_t now; fds.revents = 0; int r = poll(&fds, 1, 300); if (r > 0) { diff --git a/src/zapit/src/frontend.cpp b/src/zapit/src/frontend.cpp index 95ad4e76c..e4a0e1195 100644 --- a/src/zapit/src/frontend.cpp +++ b/src/zapit/src/frontend.cpp @@ -128,15 +128,16 @@ static const struct dtv_property dvbt_cmdargs[] = { #define diff(x,y) (max(x,y) - min(x,y)) #define FE_TIMER_INIT() \ - unsigned int timer_start; \ - static unsigned int tmin = 2000, tmax = 0; \ - unsigned int timer_msec = 0; + int64_t timer_start; \ + static uint32_t tmin = 2000, tmax = 0; \ + uint32_t timer_msec = 0; #define FE_TIMER_START() \ timer_start = time_monotonic_ms(); #define FE_TIMER_STOP(label) \ - timer_msec = time_monotonic_ms() - timer_start; \ + timer_msec = (uint32_t)(time_monotonic_ms() - \ + timer_start); \ if(tmin > timer_msec) tmin = timer_msec; \ if(tmax < timer_msec) tmax = timer_msec; \ printf("[fe%d] %s: %u msec (min %u max %u)\n", \ From 468fd6a3c7a56c1c74e70920fcb67d4d2be28771 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 21:39:56 +0200 Subject: [PATCH 07/24] zapit: suppress one more implicit-fallthrough warning --- src/zapit/src/scan.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zapit/src/scan.cpp b/src/zapit/src/scan.cpp index d078ed4b8..233d6bf5c 100644 --- a/src/zapit/src/scan.cpp +++ b/src/zapit/src/scan.cpp @@ -694,6 +694,7 @@ void CServiceScan::ChannelFound(uint8_t service_type, std::string providerName, case ST_NVOD_REFERENCE_SERVICE: case ST_NVOD_TIME_SHIFTED_SERVICE: CZapit::getInstance()->SendEvent(CZapitClient::EVT_SCAN_SERVICENAME, (void *) serviceName.c_str(), serviceName.length() + 1); + /* fall through */ case ST_DATA_BROADCAST_SERVICE: case ST_RCS_MAP: case ST_RCS_FLS: From aa0863f0c33ecd30805424400b7552158a0571fa Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 21:40:53 +0200 Subject: [PATCH 08/24] CMenuWidget: simplify menu_left_exit code, add missing break --- src/gui/widget/menue.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/gui/widget/menue.cpp b/src/gui/widget/menue.cpp index 90947ad22..1ab6a4e9d 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -928,16 +928,12 @@ int CMenuWidget::exec(CMenuTarget* parent, const std::string &) break; } case (CRCInput::RC_left): - { - if(hasItem() && selected > -1 && (int)items.size() > selected) { - CMenuItem* itemX = items[selected]; - if (!itemX->isMenueOptionChooser()) { - if (g_settings.menu_left_exit) - msg = CRCInput::RC_timeout; - break; - } - } + if (hasItem() && selected > -1 && (int)items.size() > selected) { + CMenuItem* itemX = items[selected]; + if (!itemX->isMenueOptionChooser() && g_settings.menu_left_exit) + msg = CRCInput::RC_timeout; } + break; case (CRCInput::RC_right): case (CRCInput::RC_ok): { From 8e4907b2db92087c3212c191ec962c4bb0dde91c Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 23:40:09 +0200 Subject: [PATCH 09/24] zapit: properly initialize arrays in scanbat and scansdt --- src/zapit/src/scanbat.cpp | 2 +- src/zapit/src/scansdt.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/zapit/src/scanbat.cpp b/src/zapit/src/scanbat.cpp index 49e731568..79e3a1b24 100644 --- a/src/zapit/src/scanbat.cpp +++ b/src/zapit/src/scanbat.cpp @@ -82,7 +82,7 @@ bool CBat::Read() int secdone[255]; int sectotal = -1; - memset(secdone, 0, 255); + memset(secdone, 0, sizeof(secdone)); cDemux * dmx = new cDemux(dmxnum); dmx->Open(DMX_PSI_CHANNEL); diff --git a/src/zapit/src/scansdt.cpp b/src/zapit/src/scansdt.cpp index 5ff2aa358..9114a0eea 100644 --- a/src/zapit/src/scansdt.cpp +++ b/src/zapit/src/scansdt.cpp @@ -68,7 +68,7 @@ bool CSdt::Read() int sectotal = -1; bool cable_hack_done = false; - memset(secdone, 0, 255); + memset(secdone, 0, sizeof(secdone)); cDemux * dmx = new cDemux(dmxnum); dmx->Open(DMX_PSI_CHANNEL); From 5457ddc108d2878064acd0ef2f6590539980f330 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 23:40:54 +0200 Subject: [PATCH 10/24] moviebrowser: fix format-string warnings --- src/gui/moviebrowser/mb.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/moviebrowser/mb.cpp b/src/gui/moviebrowser/mb.cpp index 86f7d5e51..cd9200b3b 100644 --- a/src/gui/moviebrowser/mb.cpp +++ b/src/gui/moviebrowser/mb.cpp @@ -2482,8 +2482,8 @@ bool CMovieBrowser::onDelete(bool cursor_only) getSelectedFiles(filelist, movielist); - printf("CMovieBrowser::onDelete(%s) filelist size: %d\n", cursor_only ? "true" : "false", filelist.size()); - printf("CMovieBrowser::onDelete(%s) movielist size: %d\n", cursor_only ? "true" : "false", movielist.size()); + printf("CMovieBrowser::onDelete(%s) filelist size: %zd\n", cursor_only ? "true" : "false", filelist.size()); + printf("CMovieBrowser::onDelete(%s) movielist size: %zd\n", cursor_only ? "true" : "false", movielist.size()); if (cursor_only || (filelist.empty() || movielist.empty())) { @@ -2498,8 +2498,8 @@ bool CMovieBrowser::onDelete(bool cursor_only) filelist.push_back(m_movieSelectionHandler->file); movielist.push_back(m_movieSelectionHandler); - printf("CMovieBrowser::onDelete(%s) filelist size: %d\n", cursor_only ? "true" : "false", filelist.size()); - printf("CMovieBrowser::onDelete(%s) movielist size: %d\n", cursor_only ? "true" : "false", movielist.size()); + printf("CMovieBrowser::onDelete(%s) filelist size: %zd\n", cursor_only ? "true" : "false", filelist.size()); + printf("CMovieBrowser::onDelete(%s) movielist size: %zd\n", cursor_only ? "true" : "false", movielist.size()); } MI_MOVIE_LIST dellist; From 96006a04f65c31a8e2665bd2c5643b4fdf322f50 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 23:41:58 +0200 Subject: [PATCH 11/24] audioplayer: fix buffer overflow --- src/gui/audioplayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/audioplayer.cpp b/src/gui/audioplayer.cpp index ff0a572d0..68fd804cf 100644 --- a/src/gui/audioplayer.cpp +++ b/src/gui/audioplayer.cpp @@ -801,7 +801,7 @@ int CAudioPlayerGui::show() smsKey = m_SMSKeyInput.handleMsg(msg); //printf(" new key: %c", smsKey); /* show a hint box with current char (too slow at the moment?)*/ - char selectedKey[1]; + char selectedKey[2]; sprintf(selectedKey,"%c",smsKey); int x1=(g_settings.screen_EndX- g_settings.screen_StartX)/2 + g_settings.screen_StartX-50; int y1=(g_settings.screen_EndY- g_settings.screen_StartY)/2 + g_settings.screen_StartY; From 8a243ea12ee778587073f07e635ad122fe41fb53 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 23:43:59 +0200 Subject: [PATCH 12/24] subchannel_select: ensure buffer does not overflow --- src/gui/subchannel_select.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/subchannel_select.cpp b/src/gui/subchannel_select.cpp index 36867ce1c..b6d688180 100644 --- a/src/gui/subchannel_select.cpp +++ b/src/gui/subchannel_select.cpp @@ -108,6 +108,8 @@ int CSubChannelSelectMenu::getNVODMenu(CMenuWidget* menu) } count++; + if (count > 9999) + break; } if ( g_RemoteControl->are_subchannels ) { From 9425caa6e57e9a27eb36ac37919807bf55d64553 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sat, 23 Sep 2017 23:45:22 +0200 Subject: [PATCH 13/24] rcinput: disable timer debug messages --- src/driver/rcinput.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/driver/rcinput.cpp b/src/driver/rcinput.cpp index cbaab0987..3648df7a7 100644 --- a/src/driver/rcinput.cpp +++ b/src/driver/rcinput.cpp @@ -469,7 +469,7 @@ int CRCInput::addTimer(uint64_t Interval, bool oneshot, bool correct_time ) _newtimer.correct_time = correct_time; -printf("adding timer %d (0x%llx, 0x%llx)\n", _newtimer.id, _newtimer.times_out, Interval); +//printf("adding timer %d (0x%" PRIx64 ", 0x%" PRIx64 ")\n", _newtimer.id, _newtimer.times_out, Interval); std::vector::iterator e; for ( e= timers.begin(); e!= timers.end(); ++e ) @@ -482,7 +482,7 @@ printf("adding timer %d (0x%llx, 0x%llx)\n", _newtimer.id, _newtimer.times_out, void CRCInput::killTimer(uint32_t &id) { -printf("killing timer %d\n", id); +//printf("killing timer %d\n", id); if(id == 0) return; From 7f2d58f956b4e2801ce0b0b85036ace763af317f Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 24 Sep 2017 13:55:44 +0200 Subject: [PATCH 14/24] abstime: fix time_monotonic_ms on 32bit systems m) --- src/driver/abstime.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/driver/abstime.c b/src/driver/abstime.c index e74c268c3..a242b7877 100644 --- a/src/driver/abstime.c +++ b/src/driver/abstime.c @@ -5,7 +5,7 @@ int64_t time_monotonic_ms(void) { struct timespec t; - time_t ret; + int64_t ret; if (clock_gettime(CLOCK_MONOTONIC, &t)) { perror("time_monotonic_ms clock_gettime"); From a294b610a418d32d641ef9322fe17a48bd198c6b Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 24 Sep 2017 13:56:49 +0200 Subject: [PATCH 15/24] fb_accel: fix blit after time_monotonic_ms fix --- src/driver/fb_accel_glfb.cpp | 2 +- src/driver/fb_accel_sti.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/driver/fb_accel_glfb.cpp b/src/driver/fb_accel_glfb.cpp index d62ea65f1..efed7d6b5 100644 --- a/src/driver/fb_accel_glfb.cpp +++ b/src/driver/fb_accel_glfb.cpp @@ -116,7 +116,7 @@ void CFbAccelGLFB::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32 void CFbAccelGLFB::run() { printf(LOGTAG "run start\n"); - int64_t last_blit = INT64_MAX; + int64_t last_blit = 0; blit_pending = false; blit_thread = true; blit_mutex.lock(); diff --git a/src/driver/fb_accel_sti.cpp b/src/driver/fb_accel_sti.cpp index 808254b38..721120680 100644 --- a/src/driver/fb_accel_sti.cpp +++ b/src/driver/fb_accel_sti.cpp @@ -331,7 +331,7 @@ void CFbAccelSTi::blit2FB(void *fbbuff, uint32_t width, uint32_t height, uint32_ void CFbAccelSTi::run() { printf(LOGTAG "::run start\n"); - int64_t last_blit = INT64_MAX; /* blit at first iteration */ + int64_t last_blit = 0; blit_pending = false; blit_thread = true; blit_mutex.lock(); From 7955467a7764a083077cc0b0d6980a5ab701077d Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 24 Sep 2017 16:18:04 +0200 Subject: [PATCH 16/24] netfile: avoid possible buffer overflows spotted by gcc7 * use strcpy instead of sprintf(x, "constant") or sprintf(x, "%s", str) * use strncpy and ensure termination where necessary * use snprintf instead of sprintf --- src/driver/netfile.cpp | 59 ++++++++++++++++++++++-------------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/driver/netfile.cpp b/src/driver/netfile.cpp index 198d87dfb..809b40605 100644 --- a/src/driver/netfile.cpp +++ b/src/driver/netfile.cpp @@ -2,7 +2,7 @@ | Neutrino-GUI - DBoxII-Project | | Copyright (C) 2004 by Sanaia -| Copyright (C) 2010-2013 Stefan Seyfried +| Copyright (C) 2010-2013, 2017 Stefan Seyfried | | netfile - remote file access mapper | @@ -140,6 +140,9 @@ known bugs: #undef fseek #endif +/* somewhat safe, 0-terminated sprintf and strcpy */ +#define SPRINTF(a, b...) snprintf(a, sizeof(a)-1, b) +#define STRCPY(a, b) { strncpy(a, b, sizeof(a)-1); a[sizeof(a)-1] = 0; } @@ -178,7 +181,7 @@ magic_t known_magic[] = char err_txt[2048]; /* human readable error message */ char redirect_url[2048]; /* new url if we've been redirected (HTTP 301/302) */ static int debug = 0; /* print debugging output or not */ -static char logfile[255]; /* redirect errors from stderr */ +static char logfile[256]; /* redirect errors from stderr */ static int retry_num = 2 /*10*/; /* number of retries for failed connections */ static int enable_metadata = 0; /* allow shoutcast meta data streaming */ static int got_opts = 0; /* is set to 1 if getOpts() was executed */ @@ -250,7 +253,7 @@ void getOpts() if((ptr = strstr(buf, "logfile="))) { - strcpy(logfile, strchr(ptr, '=') + 1); + STRCPY(logfile, strchr(ptr, '=') + 1); CRLFCut(logfile); freopen(logfile, "w", stderr); } @@ -288,7 +291,7 @@ int ConnectToServer(char *hostname, int port) if(fd == -1) { - strcpy(err_txt, strerror(errno)); + STRCPY(err_txt, strerror(errno)); return -1; } @@ -305,7 +308,7 @@ int ConnectToServer(char *hostname, int port) { if(errno != EINPROGRESS) { close(fd); - strcpy(err_txt, strerror(errno)); + STRCPY(err_txt, strerror(errno)); dprintf(stderr, "error connecting to %s: %s\n", hostname, err_txt); return -1; } @@ -318,7 +321,7 @@ int ConnectToServer(char *hostname, int port) int ret = poll(&pfd, 1, 5000); if(ret != 1) { - strcpy(err_txt, strerror(errno)); + STRCPY(err_txt, strerror(errno)); dprintf(stderr, "error connecting to %s: %s\n", hostname, err_txt); close(fd); return -1; @@ -339,7 +342,7 @@ int ConnectToServer(char *hostname, int port) int request_file(URL *url) { - char str[255], *ptr; + char str[256], *ptr; int slot; ID3 id3; memset(&id3, 0, sizeof(ID3)); @@ -386,18 +389,18 @@ int request_file(URL *url) if (url->logindata[0]) { - sprintf(str, "Authorization: Basic %s\r\n", url->logindata); + SPRINTF(str, "Authorization: Basic %s\r\n", url->logindata); dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); } - snprintf(str, sizeof(str)-1, "Accept: */*\r\n"); + strcpy(str, "Accept: */*\r\n"); dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); if(enable_metadata) { - snprintf(str, sizeof(str)-1, "Icy-MetaData: 1\r\n"); + strcpy(str, "Icy-MetaData: 1\r\n"); dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); } @@ -464,32 +467,32 @@ int request_file(URL *url) int meta_int; CSTATE tmp; - sprintf(str, "GET %s HTTP/1.0\r\n", url->file); + SPRINTF(str, "GET %s HTTP/1.0\r\n", url->file); dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); - sprintf(str, "Host: %s\r\n", url->host); + SPRINTF(str, "Host: %s\r\n", url->host); dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); if(enable_metadata) { - sprintf(str, "icy-metadata: 1\r\n"); + strcpy(str, "icy-metadata: 1\r\n"); dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); } - sprintf(str, "User-Agent: %s\r\n", "RealPlayer/4.0"); + SPRINTF(str, "User-Agent: %s\r\n", "RealPlayer/4.0"); dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); if (url->logindata[0]) { - sprintf(str, "Authorization: Basic %s\r\n", url->logindata); + SPRINTF(str, "Authorization: Basic %s\r\n", url->logindata); dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); } - sprintf(str, "\r\n"); /* end of headers to send */ + strcpy(str, "\r\n"); /* end of headers to send */ dprintf(stderr, "> %s", str); send(url->fd, str, strlen(str), 0); @@ -623,14 +626,14 @@ int parse_response(URL *url, void * /*opt*/, CSTATE *state) case 301: /* 'file moved' error */ case 302: /* 'file not found' error */ errno = ENOENT; - strcpy(err_txt, ptr); + STRCPY(err_txt, ptr); getHeaderStr("Location", redirect_url); return -1 * response; break; case 404: /* 'file not found' error */ errno = ENOENT; - strcpy(err_txt, ptr); + STRCPY(err_txt, ptr); return -1; break; @@ -831,7 +834,7 @@ FILE *f_open(const char *filename, const char *acctype) if(ptr) *ptr = 0; - sprintf(url.url, "%s", buf); + STRCPY(url.url, buf); } else return NULL; @@ -907,7 +910,7 @@ FILE *f_open(const char *filename, const char *acctype) /* no free cache slot ? return an error */ if(i == CACHEENTMAX) { - sprintf(err_txt, "no more free cache slots. Too many open files.\n"); + strcpy(err_txt, "no more free cache slots. Too many open files.\n"); return NULL; } @@ -993,9 +996,9 @@ FILE *f_open(const char *filename, const char *acctype) /* create either a shoutcast or an icecast query */ if(url.access_mode == MODE_SCAST) - sprintf(buf2, "http://classic.shoutcast.com/directory/?orderby=listeners&s=%s", url.host); + SPRINTF(buf2, "http://classic.shoutcast.com/directory/?orderby=listeners&s=%s", url.host); else - sprintf(buf2, "http://www.icecast.org/streamlist.php?search=%s", url.host); + SPRINTF(buf2, "http://www.icecast.org/streamlist.php?search=%s", url.host); //findme // ICECAST: it ain't that simple. Icecast doesn't work yet */ @@ -1004,7 +1007,7 @@ FILE *f_open(const char *filename, const char *acctype) if(!_fd) { - sprintf(err_txt, "%s database query failed\nfailed action: %s", + SPRINTF(err_txt, "%s database query failed\nfailed action: %s", ((url.access_mode == MODE_SCAST) ? "shoutcast" : "icecast"), buf2); return NULL; } @@ -1016,17 +1019,17 @@ FILE *f_open(const char *filename, const char *acctype) if(!ptr) { - sprintf(err_txt, "failed to find station number"); + strcpy(err_txt, "failed to find station number"); dprintf(stderr, "%s\n", buf2); return NULL; } - sprintf(url.host, "%d", atoi(ptr + 3)); + SPRINTF(url.host, "%d", atoi(ptr + 3)); } /* create the correct url from the station number */ CRLFCut(url.host); - sprintf(url.url, "http://classic.shoutcast.com/sbin/shoutcast-playlist.pls?rn=%s&file=filename.pls", url.host); + SPRINTF(url.url, "http://classic.shoutcast.com/sbin/shoutcast-playlist.pls?rn=%s&file=filename.pls", url.host); /* fall through */ case MODE_PLS: { @@ -1062,7 +1065,7 @@ FILE *f_open(const char *filename, const char *acctype) if(!ptr) { dprintf(stderr, "Ups! Playlist doesn't seem to contain any URL !\nbuffer:%s\n", buf); - sprintf(err_txt, "Ups! Playlist doesn't seem to contain any URL !"); + strcpy(err_txt, "Ups! Playlist doesn't seem to contain any URL !"); return NULL; } @@ -1089,7 +1092,7 @@ FILE *f_open(const char *filename, const char *acctype) const char* const chptr = strstr(servers[i], "://"); if(chptr) { - sprintf(url.url, "icy%s", chptr); + snprintf(url.url, sizeof(url.url)-1, "icy%s", chptr); fd = f_open(url.url, "r"); } } From 163815a2e00ebfeca61480baae19215de8c38557 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 24 Sep 2017 16:19:21 +0200 Subject: [PATCH 17/24] audioplayer: allow to add https:// urls from playlist --- src/gui/audioplayer.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/gui/audioplayer.cpp b/src/gui/audioplayer.cpp index 68fd804cf..fa974d149 100644 --- a/src/gui/audioplayer.cpp +++ b/src/gui/audioplayer.cpp @@ -4,6 +4,7 @@ Copyright (C) 2001 Steffen Hehn 'McClean' Copyright (C) 2002-2008 the tuxbox project contributors Copyright (C) 2008 Novell, Inc. Author: Stefan Seyfried + Copyright (C) 2011-2013,2015,2017 Stefan Seyfried Copyright (C) 2017 Sven Hoefer License: GPL @@ -1076,9 +1077,13 @@ void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, cons if (line[0] != '#') { //printf("chunk: line = %s\n", line); - ptr = strstr(line, "http://"); - if (ptr != NULL) - { + const char *schemes[] = {"http://", "https://", NULL }; + const char **scheme = schemes; + while (*scheme) { + ptr = strstr(line, *scheme); + scheme++; + if (ptr == NULL) + continue; char *tmp; // strip \n and \r characters from url tmp = strchr(line, '\r'); @@ -1088,6 +1093,7 @@ void CAudioPlayerGui::processPlaylistUrl(const char *url, const char *name, cons if (tmp != NULL) *tmp = '\0'; addUrl2Playlist(ptr, name, tim); + break; } } } From 940fdf36fd913de47192cff160ce1fe0997bbaf2 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 24 Sep 2017 22:17:21 +0200 Subject: [PATCH 18/24] epgview: swap RC_info and RC_help in EPG view this restores old behaviour of RC_info toggling big fonts. RC_help toggles TMDB display (which is disabled by default anyway) --- src/gui/epgview.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/epgview.cpp b/src/gui/epgview.cpp index f2d5d4adb..2cab74547 100644 --- a/src/gui/epgview.cpp +++ b/src/gui/epgview.cpp @@ -1108,7 +1108,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start printf("timerd not available\n"); } break; - case CRCInput::RC_info: + case CRCInput::RC_help: { if (g_settings.tmdb_enabled) { @@ -1191,7 +1191,7 @@ int CEpgData::show(const t_channel_id channel_id, uint64_t a_id, time_t* a_start } break; } - case CRCInput::RC_help: + case CRCInput::RC_info: bigFonts = bigFonts ? false : true; ResetModules(); frameBuffer->paintBackgroundBoxRel(sx, sy, ox, oy); From 4f50b2009abb85172d263f49fa4a78412426d7f8 Mon Sep 17 00:00:00 2001 From: svenhoefer Date: Sun, 24 Sep 2017 22:03:04 +0200 Subject: [PATCH 19/24] - bouqueteditor: massively rework gui; ... * add CBEGlobals to globalize some basic calculations (maybe there's something more to globalize) * add header-icons * change header-captions * add info-texts for webtv-channels * change arrangement of status-icons * small code re-formattings bouqueteditor_bouquets: * RC_yellow now starts and stops moving of bouquets * RC_tv now switches to tv-channels * RC_radio now switches to radio-channels bouqueteditor_chanselect: * RC_green now add channels too * don't use listbox-widget anymore (listbox is unused now) --- src/gui/bedit/Makefile.am | 4 +- src/gui/bedit/bouqueteditor_bouquets.cpp | 300 +++++----- src/gui/bedit/bouqueteditor_bouquets.h | 83 +-- src/gui/bedit/bouqueteditor_channels.cpp | 458 +++++++-------- src/gui/bedit/bouqueteditor_channels.h | 85 +-- src/gui/bedit/bouqueteditor_chanselect.cpp | 636 ++++++++++++--------- src/gui/bedit/bouqueteditor_chanselect.h | 92 +-- src/gui/bedit/bouqueteditor_globals.cpp | 60 ++ src/gui/bedit/bouqueteditor_globals.h | 61 ++ 9 files changed, 990 insertions(+), 789 deletions(-) create mode 100644 src/gui/bedit/bouqueteditor_globals.cpp create mode 100644 src/gui/bedit/bouqueteditor_globals.h diff --git a/src/gui/bedit/Makefile.am b/src/gui/bedit/Makefile.am index e07422406..269ac532a 100644 --- a/src/gui/bedit/Makefile.am +++ b/src/gui/bedit/Makefile.am @@ -19,5 +19,5 @@ noinst_LIBRARIES = libneutrino_gui_bedit.a libneutrino_gui_bedit_a_SOURCES = \ bouqueteditor_bouquets.cpp \ bouqueteditor_channels.cpp \ - bouqueteditor_chanselect.cpp - + bouqueteditor_chanselect.cpp \ + bouqueteditor_globals.cpp diff --git a/src/gui/bedit/bouqueteditor_bouquets.cpp b/src/gui/bedit/bouqueteditor_bouquets.cpp index a5b2d6ebc..3c0faa388 100644 --- a/src/gui/bedit/bouqueteditor_bouquets.cpp +++ b/src/gui/bedit/bouqueteditor_bouquets.cpp @@ -1,24 +1,24 @@ /* - Neutrino-GUI - DBoxII-Project + neutrino bouquet editor - bouquets editor Copyright (C) 2001 Steffen Hehn 'McClean' Copyright (C) 2009,2011,2013,2016 Stefan Seyfried + Copyright (C) 2017 Sven Hoefer 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 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. + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H @@ -27,46 +27,49 @@ #include #include -#include "bouqueteditor_channels.h" -#include "bouqueteditor_bouquets.h" #include #include #include - #include +#include #include #include -#include #include +#include "bouqueteditor_bouquets.h" +#include "bouqueteditor_channels.h" + extern CBouquetManager *g_bouquetManager; CBEBouquetWidget::CBEBouquetWidget() { - frameBuffer = CFrameBuffer::getInstance(); - iconoffset = 0; origPosition = 0; newPosition = 0; - listmaxshow = 0; bouquetsChanged = 0; - width = 0; - height = 0; - x = 0; - y = 0; selected = 0; liststart = 0; state = beDefault; Bouquets = NULL; - iheight = 0; - ButtonHeight = footer.getHeight(); - fheight = 0; - theight = 0; + + int iw, ih; + action_icon_width = 0; + frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_DUMMY_SMALL, &action_icon_width, &ih); + + status_icon_width = 0; + frameBuffer->getIconSize(NEUTRINO_ICON_HIDDEN, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); + frameBuffer->getIconSize(NEUTRINO_ICON_LOCK, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); + frameBuffer->getIconSize(NEUTRINO_ICON_AUDIO, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); + frameBuffer->getIconSize(NEUTRINO_ICON_VIDEO, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); } void CBEBouquetWidget::paintItem(int pos) { - int ypos = y + theight + pos*iheight; + int ypos = y + header_height + pos*item_height; unsigned int current = liststart + pos; bool i_selected = current == selected; @@ -84,79 +87,91 @@ void CBEBouquetWidget::paintItem(int pos) else { bool has_channels = true; - if(current < Bouquets->size()) - has_channels = (!(*Bouquets)[current]->tvChannels.empty() ) || (!(*Bouquets)[current]->radioChannels.empty()); + if (current < Bouquets->size()) + has_channels = (!(*Bouquets)[current]->tvChannels.empty()) || (!(*Bouquets)[current]->radioChannels.empty()); if (!has_channels) color = COL_MENUCONTENTINACTIVE_TEXT; } if (i_radius) - frameBuffer->paintBoxRel(x,ypos, width - SCROLLBAR_WIDTH, iheight, COL_MENUCONTENT_PLUS_0); - frameBuffer->paintBoxRel(x,ypos, width - SCROLLBAR_WIDTH, iheight, bgcolor, i_radius); + frameBuffer->paintBoxRel(x,ypos, width - SCROLLBAR_WIDTH, item_height, COL_MENUCONTENT_PLUS_0); + frameBuffer->paintBoxRel(x,ypos, width - SCROLLBAR_WIDTH, item_height, bgcolor, i_radius); - if (current < Bouquets->size()) { + if (current < Bouquets->size()) + { if ((i_selected) && (state == beMoving)) - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_YELLOW, x + OFFSET_INNER_MID, ypos, iheight); + frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_YELLOW, x + OFFSET_INNER_MID, ypos, item_height); + else + frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_DUMMY_SMALL, x + OFFSET_INNER_MID, ypos, item_height); + + int text_offset = 2*OFFSET_INNER_MID + action_icon_width; + item_font->RenderString(x + text_offset, ypos + item_height, width - text_offset - SCROLLBAR_WIDTH - 5*OFFSET_INNER_MID - 4*status_icon_width, (*Bouquets)[current]->bFav ? g_Locale->getText(LOCALE_FAVORITES_BOUQUETNAME) : (*Bouquets)[current]->Name, color); if ((*Bouquets)[current]->bHidden) - frameBuffer->paintIcon(NEUTRINO_ICON_HIDDEN, x + OFFSET_INNER_MID + iconoffset, ypos, iheight); + frameBuffer->paintIcon(NEUTRINO_ICON_HIDDEN, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - status_icon_width, ypos, item_height); if ((*Bouquets)[current]->bLocked != g_settings.parentallock_defaultlocked) - frameBuffer->paintIcon(NEUTRINO_ICON_LOCK, x + OFFSET_INNER_MID + 2*iconoffset, ypos, iheight); + frameBuffer->paintIcon(NEUTRINO_ICON_LOCK, x + width - SCROLLBAR_WIDTH - 2*OFFSET_INNER_MID - 2*status_icon_width, ypos, item_height); - if (!(*Bouquets)[current]->tvChannels.empty() ) { - frameBuffer->paintIcon(NEUTRINO_ICON_VIDEO, x + OFFSET_INNER_MID + 3*iconoffset, ypos, iheight); - } + if (!(*Bouquets)[current]->radioChannels.empty()) + frameBuffer->paintIcon(NEUTRINO_ICON_AUDIO, x + width - SCROLLBAR_WIDTH - 3*OFFSET_INNER_MID - 3*status_icon_width, ypos, item_height); - if (!(*Bouquets)[current]->radioChannels.empty()) { - frameBuffer->paintIcon(NEUTRINO_ICON_AUDIO, x + OFFSET_INNER_MID + 4*iconoffset, ypos, iheight); - } - g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x + 2*OFFSET_INNER_MID + 5*iconoffset, ypos + iheight - (iheight-fheight)/2, width - 3*OFFSET_INNER_MID - 5*iconoffset, (*Bouquets)[current]->bFav ? g_Locale->getText(LOCALE_FAVORITES_BOUQUETNAME) : (*Bouquets)[current]->Name, color); + if (!(*Bouquets)[current]->tvChannels.empty()) + frameBuffer->paintIcon(NEUTRINO_ICON_VIDEO, x + width - SCROLLBAR_WIDTH - 4*OFFSET_INNER_MID - 4*status_icon_width, ypos, item_height); } } -void CBEBouquetWidget::paint() +void CBEBouquetWidget::paintItems() { - liststart = (selected/listmaxshow)*listmaxshow; + liststart = (selected/items_count)*items_count; - for(unsigned int count=0;countsize(), listmaxshow, selected); - paintScrollBar(x + width - SCROLLBAR_WIDTH, y + theight, SCROLLBAR_WIDTH, iheight*listmaxshow, total_pages, current_page); + getScrollBarData(&total_pages, ¤t_page, Bouquets->size(), items_count, selected); + paintScrollBar(x + width - SCROLLBAR_WIDTH, y + header_height, SCROLLBAR_WIDTH, body_height, total_pages, current_page); +} + +void CBEBouquetWidget::paintBody() +{ + PaintBoxRel(x, y + header_height, width, body_height, COL_MENUCONTENT_PLUS_0, RADIUS_NONE, CORNER_NONE, CC_SHADOW_ON); } void CBEBouquetWidget::paintHead() { - CComponentsHeader header(x, y, width, theight, LOCALE_BOUQUETLIST_HEAD, "" /*no header icon*/, CComponentsHeader::CC_BTN_EXIT); + header.setCaption(LOCALE_BOUQUETLIST_HEAD); + header.setIcon(NEUTRINO_ICON_SETTINGS); + header.setDimensionsAll(x, y, width, header_height); + header.setCorner(RADIUS_LARGE, CORNER_TOP); + header.enableShadow(CC_SHADOW_RIGHT | CC_SHADOW_CORNER_TOP_RIGHT | CC_SHADOW_CORNER_BOTTOM_RIGHT, -1, true); header.paint(CC_SAVE_SCREEN_NO); } -const struct button_label CBEBouquetWidgetButtons[6] = +const struct button_label CBEBouquetWidgetButtons[] = { - { NEUTRINO_ICON_BUTTON_RED , LOCALE_BOUQUETEDITOR_DELETE }, - { NEUTRINO_ICON_BUTTON_GREEN , LOCALE_BOUQUETEDITOR_ADD }, - { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_BOUQUETEDITOR_MOVE }, - { NEUTRINO_ICON_BUTTON_BLUE , LOCALE_BOUQUETEDITOR_RENAME}, - { NEUTRINO_ICON_BUTTON_PAUSE , LOCALE_BOUQUETEDITOR_HIDE }, - { NEUTRINO_ICON_BUTTON_STOP , LOCALE_BOUQUETEDITOR_LOCK } + { NEUTRINO_ICON_BUTTON_RED, LOCALE_BOUQUETEDITOR_DELETE }, + { NEUTRINO_ICON_BUTTON_GREEN, LOCALE_BOUQUETEDITOR_ADD }, + { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_BOUQUETEDITOR_MOVE }, + { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_BOUQUETEDITOR_RENAME }, + { NEUTRINO_ICON_BUTTON_PAUSE, LOCALE_BOUQUETEDITOR_HIDE }, + { NEUTRINO_ICON_BUTTON_STOP, LOCALE_BOUQUETEDITOR_LOCK } }; void CBEBouquetWidget::paintFoot() { size_t numbuttons = sizeof(CBEBouquetWidgetButtons)/sizeof(CBEBouquetWidgetButtons[0]); - footer.paintButtons(x, y+height, width, ButtonHeight, numbuttons, CBEBouquetWidgetButtons, width/numbuttons-2*OFFSET_INNER_MID); + + footer.setCorner(RADIUS_LARGE, CORNER_BOTTOM); + footer.enableShadow(CC_SHADOW_ON, -1, true); + footer.paintButtons(x, y + header_height + body_height, width, footer_height, numbuttons, CBEBouquetWidgetButtons); } void CBEBouquetWidget::hide() { - frameBuffer->paintBackgroundBoxRel(x,y, width,height); - footer.kill(); + frameBuffer->paintBackgroundBoxRel(x, y, width + OFFSET_SHADOW, height + OFFSET_SHADOW); } void CBEBouquetWidget::updateSelection(unsigned int newpos) @@ -167,16 +182,22 @@ void CBEBouquetWidget::updateSelection(unsigned int newpos) unsigned int prev_selected = selected; selected = newpos; - if (state == beDefault) { + if (state == beDefault) + { unsigned int oldliststart = liststart; - liststart = (selected/listmaxshow)*listmaxshow; - if(oldliststart!=liststart) { - paint(); - } else { + liststart = (selected/items_count)*items_count; + if (oldliststart != liststart) + { + paintItems(); + } + else + { paintItem(prev_selected - liststart); paintItem(selected - liststart); } - } else { + } + else + { internalMoveBouquet(prev_selected, selected); } } @@ -191,58 +212,26 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* if (parent) parent->hide(); - theight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); - fheight = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->getHeight(); - - int icol_w, icol_h; - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_YELLOW, &icol_w, &icol_h); - iheight = std::max(fheight, icol_h + OFFSET_INNER_MIN); - iconoffset = std::max(iconoffset, icol_w); - - frameBuffer->getIconSize(NEUTRINO_ICON_LOCK, &icol_w, &icol_h); - iheight = std::max(fheight, icol_h + OFFSET_INNER_MIN); - iconoffset = std::max(iconoffset, icol_w); - - frameBuffer->getIconSize(NEUTRINO_ICON_HIDDEN, &icol_w, &icol_h); - iheight = std::max(fheight, icol_h + OFFSET_INNER_MIN); - iconoffset = std::max(iconoffset, icol_w); - - frameBuffer->getIconSize(NEUTRINO_ICON_VIDEO, &icol_w, &icol_h); - iheight = std::max(fheight, icol_h + OFFSET_INNER_MIN); - iconoffset = std::max(iconoffset, icol_w); - - frameBuffer->getIconSize(NEUTRINO_ICON_AUDIO, &icol_w, &icol_h); - iheight = std::max(fheight, icol_h + OFFSET_INNER_MIN); - iconoffset = std::max(iconoffset, icol_w); - - width = frameBuffer->getScreenWidthRel(); - height = frameBuffer->getScreenHeightRel() - ButtonHeight; - - listmaxshow = (height-theight)/iheight; - height = theight+listmaxshow*iheight; // recalc height - - x = getScreenStartX(width); - y = getScreenStartY(height + ButtonHeight); - Bouquets = &g_bouquetManager->Bouquets; + paintHead(); - paint(); + paintBody(); paintFoot(); + paintItems(); bouquetsChanged = false; - uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]); + uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU]); - bool loop=true; + bool loop = true; while (loop) { - g_RCInput->getMsgAbsoluteTimeout( &msg, &data, &timeoutEnd ); + g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); - if ( msg <= CRCInput::RC_MaxRC ) - timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]); + if (msg <= CRCInput::RC_MaxRC) + timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU]); - if ((msg == CRCInput::RC_timeout) || - (msg == (neutrino_msg_t)g_settings.key_channelList_cancel)) + if ((msg == CRCInput::RC_timeout) || (msg == (neutrino_msg_t)g_settings.key_channelList_cancel)) { if (state == beDefault) { @@ -250,21 +239,28 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* { int result = ShowMsg(LOCALE_BOUQUETEDITOR_NAME, LOCALE_BOUQUETEDITOR_SAVECHANGES, CMsgBox::mbrYes, CMsgBox::mbYesNoCancel, NULL, 600); - switch( result ) + switch(result) { - case CMsgBox::mbrYes : + case CMsgBox::mbrYes: + { loop=false; saveChanges(); - break; - case CMsgBox::mbrNo : + break; + } + case CMsgBox::mbrNo: + { loop=false; discardChanges(); - break; - case CMsgBox::mbrCancel : + break; + } + case CMsgBox::mbrCancel: + { paintHead(); - paint(); + paintBody(); paintFoot(); - break; + paintItems(); + break; + } } } else @@ -280,36 +276,38 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* else if (msg == CRCInput::RC_up || msg == (neutrino_msg_t)g_settings.key_pageup || msg == CRCInput::RC_down || msg == (neutrino_msg_t)g_settings.key_pagedown) { - int new_selected = UpDownKey(*Bouquets, msg, listmaxshow, selected); + int new_selected = UpDownKey(*Bouquets, msg, items_count, selected); updateSelection(new_selected); } - else if (msg == (neutrino_msg_t) g_settings.key_list_start || msg == (neutrino_msg_t) g_settings.key_list_end) { - if (!(Bouquets->empty())) { + else if (msg == (neutrino_msg_t) g_settings.key_list_start || msg == (neutrino_msg_t) g_settings.key_list_end) + { + if (!(Bouquets->empty())) + { int new_selected = msg == (neutrino_msg_t) g_settings.key_list_start ? 0 : Bouquets->size() - 1; updateSelection(new_selected); } } - else if(msg==CRCInput::RC_red) + else if (msg == CRCInput::RC_red) { if (state == beDefault) deleteBouquet(); } - else if(msg==CRCInput::RC_green) + else if (msg == CRCInput::RC_green) { if (state == beDefault) addBouquet(); } - else if(msg==CRCInput::RC_yellow) + else if (msg == CRCInput::RC_yellow) { if (selected < Bouquets->size()) /* Bouquets->size() might be 0 */ { - liststart = (selected/listmaxshow)*listmaxshow; + liststart = (selected/items_count)*items_count; if (state == beDefault) beginMoveBouquet(); paintItem(selected - liststart); } } - else if(msg==CRCInput::RC_blue) + else if (msg == CRCInput::RC_blue) { if (selected < Bouquets->size()) /* Bouquets->size() might be 0 */ { @@ -317,8 +315,7 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* renameBouquet(); } } - - else if(msg==CRCInput::RC_pause) + else if (msg == CRCInput::RC_pause) { if (selected < Bouquets->size()) /* Bouquets->size() might be 0 */ { @@ -326,7 +323,7 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* switchHideBouquet(); } } - else if(msg==CRCInput::RC_stop) + else if (msg == CRCInput::RC_stop) { if (selected < Bouquets->size()) /* Bouquets->size() might be 0 */ { @@ -334,30 +331,35 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* switchLockBouquet(); } } - else if(msg==CRCInput::RC_ok) + else if (msg == CRCInput::RC_ok) { if (state == beDefault) { if (selected < Bouquets->size()) /* Bouquets->size() might be 0 */ { std::string ChannelWidgetCaption=(*Bouquets)[selected]->bFav ? g_Locale->getText(LOCALE_FAVORITES_BOUQUETNAME) : (*Bouquets)[selected]->Name; - if (!(*Bouquets)[selected]->tvChannels.empty() ) { - ChannelWidgetCaption = ChannelWidgetCaption+ " => TV"; +#if 0 + if (!(*Bouquets)[selected]->tvChannels.empty()) + { + ChannelWidgetCaption = ChannelWidgetCaption + " => TV"; if (!(*Bouquets)[selected]->radioChannels.empty()) - ChannelWidgetCaption = ChannelWidgetCaption+ "/Radio"; + ChannelWidgetCaption = ChannelWidgetCaption + " / Radio"; } - else if (!(*Bouquets)[selected]->radioChannels.empty()) { - ChannelWidgetCaption = ChannelWidgetCaption+ " => Radio"; + else if (!(*Bouquets)[selected]->radioChannels.empty()) + { + ChannelWidgetCaption = ChannelWidgetCaption + " => Radio"; } +#endif CBEChannelWidget* channelWidget = new CBEChannelWidget(ChannelWidgetCaption, selected); - channelWidget->exec( this, ""); + channelWidget->exec(this, ""); if (channelWidget->hasChanged()) bouquetsChanged = true; delete channelWidget; paintHead(); - paint(); + paintBody(); paintFoot(); + paintItems(); } } else if (state == beMoving) @@ -365,13 +367,13 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* finishMoveBouquet(); } } - else if( CRCInput::isNumeric(msg) ) + else if (CRCInput::isNumeric(msg)) { if (state == beDefault) { //kein pushback - wenn man versehentlich wo draufkommt is die edit-arbeit umsonst //selected = oldselected; - //g_RCInput->postMsg( msg, data ); + //g_RCInput->postMsg(msg, data); //loop=false; } else if (state == beMoving) @@ -385,7 +387,7 @@ int CBEBouquetWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* } else { - CNeutrinoApp::getInstance()->handleMsg( msg, data ); + CNeutrinoApp::getInstance()->handleMsg(msg, data); } } hide(); @@ -405,13 +407,13 @@ void CBEBouquetWidget::deleteBouquet() if (selected >= Bouquets->size()) selected = Bouquets->empty() ? 0 : (Bouquets->size() - 1); bouquetsChanged = true; - paint(); + paintItems(); } void CBEBouquetWidget::addBouquet() { std::string newName = inputName("", LOCALE_BOUQUETEDITOR_BOUQUETNAME); - if (!(newName.empty())) + if (!newName.empty()) { g_bouquetManager->addBouquet(newName, true); Bouquets = &g_bouquetManager->Bouquets; @@ -419,8 +421,9 @@ void CBEBouquetWidget::addBouquet() bouquetsChanged = true; } paintHead(); - paint(); + paintBody(); paintFoot(); + paintItems(); } void CBEBouquetWidget::beginMoveBouquet() @@ -438,27 +441,29 @@ void CBEBouquetWidget::finishMoveBouquet() Bouquets = &g_bouquetManager->Bouquets; bouquetsChanged = bouquetsChanged | true; } - paint(); + paintItems(); } void CBEBouquetWidget::cancelMoveBouquet() { state = beDefault; - internalMoveBouquet( newPosition, origPosition); + internalMoveBouquet(newPosition, origPosition); bouquetsChanged = bouquetsChanged | false; } -void CBEBouquetWidget::internalMoveBouquet( unsigned int fromPosition, unsigned int toPosition) +void CBEBouquetWidget::internalMoveBouquet(unsigned int fromPosition, unsigned int toPosition) { - if ( (int) toPosition == -1 ) return; - if ( toPosition == Bouquets->size()) return; + if ((int) toPosition == -1) + return; + if (toPosition == Bouquets->size()) + return; g_bouquetManager->moveBouquet(fromPosition, toPosition); Bouquets = &g_bouquetManager->Bouquets; //bouquetsChanged = true; selected = toPosition; newPosition = toPosition; - paint(); + paintItems(); } void CBEBouquetWidget::renameBouquet() @@ -474,22 +479,23 @@ void CBEBouquetWidget::renameBouquet() bouquetsChanged = true; } paintHead(); - paint(); + paintBody(); paintFoot(); + paintItems(); } void CBEBouquetWidget::switchHideBouquet() { bouquetsChanged = true; (*Bouquets)[selected]->bHidden = !(*Bouquets)[selected]->bHidden; - paint(); + paintItems(); } void CBEBouquetWidget::switchLockBouquet() { bouquetsChanged = true; g_bouquetManager->setBouquetLock((*Bouquets)[selected], !(*Bouquets)[selected]->bLocked); - paint(); + paintItems(); } std::string CBEBouquetWidget::inputName(const char * const defaultName, const neutrino_locale_t caption) diff --git a/src/gui/bedit/bouqueteditor_bouquets.h b/src/gui/bedit/bouqueteditor_bouquets.h index 0fa55f470..9aa27dc2c 100644 --- a/src/gui/bedit/bouqueteditor_bouquets.h +++ b/src/gui/bedit/bouqueteditor_bouquets.h @@ -1,47 +1,39 @@ /* - Neutrino-GUI - DBoxII-Project + neutrino bouquet editor - bouquets editor Copyright (C) 2001 Steffen Hehn 'McClean' - Homepage: http://dbox.cyberphoria.org/ - - Kommentar: - - Diese GUI wurde von Grund auf neu programmiert und sollte nun vom - Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert - auf der Client-Server Idee, diese GUI ist also von der direkten DBox- - Steuerung getrennt. Diese wird dann von Daemons uebernommen. - + Copyright (C) 2017 Sven Hoefer 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 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. + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifndef __bouqueteditor_bouquets__ #define __bouqueteditor_bouquets__ -#include - -#include -#include -#include -#include -#include #include -class CFrameBuffer; +#include +#include +#include +#include +#include +#include + +#include "bouqueteditor_globals.h" + /* class for handling when bouquets changed. */ /* This class should be a temporarily work around */ /* and should be replaced by standard neutrino event handlers */ @@ -52,41 +44,29 @@ public: virtual void onBouquetsChanged() {}; }; -class CBEBouquetWidget : public CMenuTarget, public CListHelpers +class CBEBouquetWidget : public CBEGlobals, public CMenuTarget, public CListHelpers { - private: - - CFrameBuffer *frameBuffer; - CComponentsFooter footer; enum { beDefault, beMoving } state; - unsigned int selected; - unsigned int origPosition; - unsigned int newPosition; + unsigned int selected; + unsigned int origPosition; + unsigned int newPosition; - unsigned int liststart; - unsigned int listmaxshow; - int fheight; // Fonthoehe Bouquetlist-Inhalt - int theight; // Fonthoehe Bouquetlist-Titel + unsigned int liststart; - int ButtonHeight; - int iconoffset; - int iheight; // item height - //std::string name; - bool bouquetsChanged; - int width; - int height; - int x; - int y; + int iconoffset; + + bool bouquetsChanged; - void paintItem(int pos); - void paint(); void paintHead(); + void paintBody(); + void paintItem(int pos); + void paintItems(); void paintFoot(); void hide(); void updateSelection(unsigned int newpos); @@ -96,7 +76,7 @@ class CBEBouquetWidget : public CMenuTarget, public CListHelpers void beginMoveBouquet(); void finishMoveBouquet(); void cancelMoveBouquet(); - void internalMoveBouquet( unsigned int fromPosition, unsigned int toPosition); + void internalMoveBouquet(unsigned int fromPosition, unsigned int toPosition); void renameBouquet(); void switchHideBouquet(); void switchLockBouquet(); @@ -104,7 +84,7 @@ class CBEBouquetWidget : public CMenuTarget, public CListHelpers void saveChanges(); void discardChanges(); - std::string inputName(const char * const defaultName, const neutrino_locale_t caption); + std::string inputName(const char* const defaultName, const neutrino_locale_t caption); public: CBEBouquetWidget(); @@ -114,5 +94,4 @@ class CBEBouquetWidget : public CMenuTarget, public CListHelpers int exec(CMenuTarget* parent, const std::string & actionKey); }; - #endif diff --git a/src/gui/bedit/bouqueteditor_channels.cpp b/src/gui/bedit/bouqueteditor_channels.cpp index d8532bd1d..e84997f94 100644 --- a/src/gui/bedit/bouqueteditor_channels.cpp +++ b/src/gui/bedit/bouqueteditor_channels.cpp @@ -1,81 +1,55 @@ /* - Neutrino-GUI - DBoxII-Project + neutrino bouquet editor - channels editor Copyright (C) 2001 Steffen Hehn 'McClean' - Homepage: http://dbox.cyberphoria.org/ - Copyright (C) 2011 CoolStream International Ltd Copyright (C) 2009,2011,2013,2016 Stefan Seyfried + Copyright (C) 2017 Sven Hoefer 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 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. + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H #include #endif -#include -#include "bouqueteditor_channels.h" - #include #include #include #include -#include "bouqueteditor_chanselect.h" #include #include -#include #include - -#include +#include +#include #include +#include + +#include "bouqueteditor_channels.h" +#include "bouqueteditor_chanselect.h" extern CBouquetManager *g_bouquetManager; CBEChannelWidget::CBEChannelWidget(const std::string & Caption, unsigned int Bouquet) { - int icol_w, icol_h; - frameBuffer = CFrameBuffer::getInstance(); selected = 0; - iconoffset = 0; origPosition = 0; newPosition = 0; - listmaxshow = 0; - numwidth = 0; - info_height = 0; channelsChanged = false; - width = 0; - height = 0; - x = 0; - y = 0; - - theight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); - fheight = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->getHeight(); - footerHeight= footer.getHeight(); - - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_YELLOW, &icol_w, &icol_h); - iheight = std::max(fheight, icol_h+2); - iconoffset = std::max(iconoffset, icol_w); - - frameBuffer->getIconSize(NEUTRINO_ICON_LOCK, &icol_w, &icol_h); - iheight = std::max(fheight, icol_h+2); - iconoffset = std::max(iconoffset, icol_w); - liststart = 0; state = beDefault; caption = Caption; @@ -84,6 +58,18 @@ CBEChannelWidget::CBEChannelWidget(const std::string & Caption, unsigned int Bou dline = NULL; ibox = NULL; Channels = NULL; + + int iw, ih; + action_icon_width = 0; + frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_DUMMY_SMALL, &action_icon_width, &ih); + + status_icon_width = 0; + frameBuffer->getIconSize(NEUTRINO_ICON_SCRAMBLED, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); + frameBuffer->getIconSize(NEUTRINO_ICON_STREAMING, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); + frameBuffer->getIconSize(NEUTRINO_ICON_LOCK, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); } CBEChannelWidget::~CBEChannelWidget() @@ -94,7 +80,7 @@ CBEChannelWidget::~CBEChannelWidget() void CBEChannelWidget::paintItem(int pos) { - int ypos = y+ theight+0 + pos*iheight; + int ypos = y + header_height + pos*item_height; unsigned int current = liststart + pos; bool i_selected = current == selected; @@ -108,10 +94,8 @@ void CBEChannelWidget::paintItem(int pos) if (i_selected) { if (current < Channels->size()) - { - initItem2DetailsLine(pos, current); - paintDetails(current); - } + paintDetails(pos, current); + i_radius = RADIUS_LARGE; } else @@ -121,174 +105,186 @@ void CBEChannelWidget::paintItem(int pos) } if (i_radius) - frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, iheight, COL_MENUCONTENT_PLUS_0); - frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, iheight, bgcolor, i_radius); + frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, item_height, COL_MENUCONTENT_PLUS_0); + frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, item_height, bgcolor, i_radius); - if ((current == selected) && (state == beMoving)) { - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_YELLOW, x + OFFSET_INNER_MID, ypos, iheight); - } - if (current < Channels->size()) { - if ((*Channels)[current]->bLocked) { - frameBuffer->paintIcon(NEUTRINO_ICON_LOCK, x + OFFSET_INNER_MID + iconoffset, ypos, iheight); - } - //FIXME numwidth ? we not show chan numbers - g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x + 2*OFFSET_INNER_MID + 2*iconoffset, ypos + iheight - (iheight-fheight)/2, width - 3*OFFSET_INNER_MID - 2*iconoffset, (*Channels)[current]->getName(), color); - if((*Channels)[current]->scrambled) - frameBuffer->paintIcon(NEUTRINO_ICON_SCRAMBLED, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - iconoffset, ypos, fheight); + if (current < Channels->size()) + { + if ((i_selected) && (state == beMoving)) + frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_YELLOW, x + OFFSET_INNER_MID, ypos, item_height); + else + frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_DUMMY_SMALL, x + OFFSET_INNER_MID, ypos, item_height); + + int text_offset = 2*OFFSET_INNER_MID + action_icon_width; + item_font->RenderString(x + text_offset, ypos + item_height, width - text_offset - SCROLLBAR_WIDTH - 3*OFFSET_INNER_MID - 2*status_icon_width, (*Channels)[current]->getName(), color); + + if ((*Channels)[current]->scrambled) + frameBuffer->paintIcon(NEUTRINO_ICON_SCRAMBLED, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - status_icon_width, ypos, item_height); else if (!(*Channels)[current]->getUrl().empty()) - frameBuffer->paintIcon(NEUTRINO_ICON_STREAMING, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - iconoffset, ypos, fheight); + frameBuffer->paintIcon(NEUTRINO_ICON_STREAMING, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - status_icon_width, ypos, item_height); + + if ((*Channels)[current]->bLocked) + frameBuffer->paintIcon(NEUTRINO_ICON_LOCK, x + width - SCROLLBAR_WIDTH - 2*OFFSET_INNER_MID - 2*status_icon_width, ypos, item_height); } } -void CBEChannelWidget::paint() +void CBEChannelWidget::paintItems() { - liststart = (selected/listmaxshow)*listmaxshow; - int lastnum = liststart + listmaxshow; + liststart = (selected/items_count)*items_count; - numwidth = 0; - int maxDigitWidth = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_NUMBER]->getMaxDigitWidth(); - int _lastnum = lastnum; - while (_lastnum) { - numwidth += maxDigitWidth; - _lastnum /= 10; - } - - for(unsigned int count=0;countsize(), listmaxshow, selected); - paintScrollBar(x + width - SCROLLBAR_WIDTH, y + theight, SCROLLBAR_WIDTH, iheight*listmaxshow, total_pages, current_page); + getScrollBarData(&total_pages, ¤t_page, Channels->size(), items_count, selected); + paintScrollBar(x + width - SCROLLBAR_WIDTH, y + header_height, SCROLLBAR_WIDTH, body_height, total_pages, current_page); +} + +void CBEChannelWidget::paintBody() +{ + PaintBoxRel(x, y + header_height, width, body_height, COL_MENUCONTENT_PLUS_0, RADIUS_NONE, CORNER_NONE, CC_SHADOW_ON); } void CBEChannelWidget::paintHead() { - CComponentsHeader header(x, y, width, theight, caption, "" /*no header icon*/, CComponentsHeader::CC_BTN_EXIT); + header.setCaption(caption + (mode == CZapitClient::MODE_TV ? " - TV" : " - Radio")); + header.setIcon(NULL); // trick the cc-header + header.setIcon(mode == CZapitClient::MODE_TV ? NEUTRINO_ICON_VIDEO : NEUTRINO_ICON_AUDIO); + header.setDimensionsAll(x, y, width, header_height); + header.setCorner(RADIUS_LARGE, CORNER_TOP); + header.enableShadow(CC_SHADOW_RIGHT | CC_SHADOW_CORNER_TOP_RIGHT | CC_SHADOW_CORNER_BOTTOM_RIGHT, -1, true); header.paint(CC_SAVE_SCREEN_NO); } -const struct button_label CBEChannelWidgetButtons[6] = +const struct button_label CBEChannelWidgetButtons[] = { - { NEUTRINO_ICON_BUTTON_RED , LOCALE_BOUQUETEDITOR_DELETE }, - { NEUTRINO_ICON_BUTTON_GREEN , LOCALE_BOUQUETEDITOR_ADD }, - { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_BOUQUETEDITOR_MOVE }, - { NEUTRINO_ICON_BUTTON_BLUE , LOCALE_BOUQUETEDITOR_RENAME }, + { NEUTRINO_ICON_BUTTON_RED, LOCALE_BOUQUETEDITOR_DELETE }, + { NEUTRINO_ICON_BUTTON_GREEN, LOCALE_BOUQUETEDITOR_ADD }, + { NEUTRINO_ICON_BUTTON_YELLOW, LOCALE_BOUQUETEDITOR_MOVE }, + { NEUTRINO_ICON_BUTTON_BLUE, LOCALE_BOUQUETEDITOR_RENAME }, { NEUTRINO_ICON_BUTTON_DUMMY_SMALL, LOCALE_BOUQUETEDITOR_SWITCHMODE }, - //{ NEUTRINO_ICON_BUTTON_FORWARD , LOCALE_BOUQUETEDITOR_MOVE_TO }, // TODO upgrade - { NEUTRINO_ICON_BUTTON_STOP , LOCALE_BOUQUETEDITOR_LOCK } +// { NEUTRINO_ICON_BUTTON_FORWARD, LOCALE_BOUQUETEDITOR_MOVE_TO }, // TODO upgrade + { NEUTRINO_ICON_BUTTON_STOP, LOCALE_BOUQUETEDITOR_LOCK } }; void CBEChannelWidget::paintFoot() { size_t numbuttons = sizeof(CBEChannelWidgetButtons)/sizeof(CBEChannelWidgetButtons[0]); - footer.paintButtons(x, y + (height-footerHeight), width, footerHeight, numbuttons, CBEChannelWidgetButtons, width/numbuttons-2*OFFSET_INNER_MID); + + footer.enableShadow(CC_SHADOW_ON, -1, true); + footer.paintButtons(x, y + header_height + body_height, width, footer_height, numbuttons, CBEChannelWidgetButtons); +} + +void CBEChannelWidget::paintDetails(int pos, int current) +{ + int xpos = x - DETAILSLINE_WIDTH; + int ypos1 = y + header_height + pos*item_height; + int ypos2 = y + height - info_height - OFFSET_SHADOW; + int ypos1a = ypos1 + (item_height/2); + int ypos2a = ypos2 + (info_height/2); + + if (dline) + dline->kill(); + + if (pos >= 0) + { + if (dline == NULL) + dline = new CComponentsDetailsLine(); + + if (dline) + { + dline->setDimensionsAll(xpos, ypos1a, ypos2a, item_height/2, info_height - RADIUS_LARGE*2); + dline->paint(CC_SAVE_SCREEN_NO); + } + + if (ibox == NULL) + { + ibox = new CComponentsInfoBox(); + + if (ibox) + { + ibox->setColorBody(COL_MENUCONTENTDARK_PLUS_0); + ibox->setTextColor(COL_MENUCONTENTDARK_TEXT); + ibox->setFrameThickness(FRAME_WIDTH_MIN); + ibox->setCorner(RADIUS_LARGE); + ibox->enableShadow(CC_SHADOW_ON); + } + } + + if (ibox) + { + if (ibox->isPainted()) + ibox->hide(); + + ibox->setDimensionsAll(x, ypos2, width, info_height); + ibox->setText(getInfoText(current), CTextBox::AUTO_WIDTH | CTextBox::NO_AUTO_LINEBREAK, info_font); + ibox->paint(CC_SAVE_SCREEN_NO); + } + } +} + +void CBEChannelWidget::hide() +{ + frameBuffer->paintBackgroundBoxRel(x, y, width + OFFSET_SHADOW, height + OFFSET_SHADOW); + + if (dline) + dline->kill(); + if (ibox) + ibox->kill(); } std::string CBEChannelWidget::getInfoText(int index) { std::string res = ""; - + std::string satname = CServiceManager::getInstance()->GetSatelliteName((*Channels)[index]->getSatellitePosition()); + if (IS_WEBTV((*Channels)[index]->getChannelID())) + satname = "WebTV"; transponder t; CServiceManager::getInstance()->GetTransponder((*Channels)[index]->getTransponderId(), t); std::string desc = t.description(); - if((*Channels)[index]->pname) - desc = desc + " (" + std::string((*Channels)[index]->pname) + ")"; - else - desc = desc + " (" + satname + ")"; - - res = satname + " " + desc; - - return res; -} - -void CBEChannelWidget::paintDetails(int index) -{ - //details line - dline->paint(CC_SAVE_SCREEN_NO); - - std::string str = getInfoText(index); - - //info box - ibox->setText(str, CTextBox::AUTO_WIDTH | CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT]); - ibox->setColorBody(COL_MENUCONTENTDARK_PLUS_0); - ibox->setTextColor(COL_MENUCONTENTDARK_TEXT); - ibox->paint(CC_SAVE_SCREEN_NO); -} - -void CBEChannelWidget::initItem2DetailsLine (int pos, int /*ch_index*/) -{ - int xpos = x - DETAILSLINE_WIDTH; - int ypos1 = y + theight+0 + pos*iheight; - int ypos2 = y + height + OFFSET_INTER; - int ypos1a = ypos1 + (fheight/2); - int ypos2a = ypos2 + (info_height/2); - - if (dline) - dline->kill(); //kill details line - - // init Line if detail info (and not valid list pos) - if (pos >= 0) + if ((*Channels)[index]->pname) { - if (dline == NULL) - dline = new CComponentsDetailsLine(xpos, ypos1a, ypos2a, fheight/2, info_height-RADIUS_LARGE*2); - dline->setYPos(ypos1a); - - //infobox - if (ibox == NULL){ - ibox = new CComponentsInfoBox(); - } - - if (ibox->isPainted()) - ibox->hide(); - - ibox->setDimensionsAll(x, ypos2, width, info_height); - ibox->setFrameThickness(FRAME_WIDTH_MIN); -#if 0 - ibox->paint(false,true); -#endif - ibox->setCorner(RADIUS_LARGE); - ibox->disableShadow(); + if (desc.empty()) + desc = std::string((*Channels)[index]->pname); + else + desc += " (" + std::string((*Channels)[index]->pname) + ")"; } -} + if (!(*Channels)[index]->getDesc().empty()) + desc += "\n" + (*Channels)[index]->getDesc(); -void CBEChannelWidget::clearItem2DetailsLine() -{ - if (dline) - dline->kill(); //kill details line - if (ibox) - ibox->kill(); //kill info box -} + res = satname + " - " + desc; -void CBEChannelWidget::hide() -{ - frameBuffer->paintBackgroundBoxRel(x,y, width,height+footerHeight); - clearItem2DetailsLine (); + return res; } void CBEChannelWidget::updateSelection(unsigned int newpos) { - if (newpos == selected || newpos == (unsigned int)-1) - return; + if (newpos == selected || newpos == (unsigned int)-1) + return; - unsigned int prev_selected = selected; - selected = newpos; + unsigned int prev_selected = selected; + selected = newpos; - if (state == beDefault) { - unsigned int oldliststart = liststart; - liststart = (selected/listmaxshow)*listmaxshow; - if(oldliststart!=liststart) { - paint(); - } else { - paintItem(prev_selected - liststart); - paintItem(selected - liststart); - } - } else { - internalMoveChannel(prev_selected, selected); - } + if (state == beDefault) + { + unsigned int oldliststart = liststart; + liststart = (selected/items_count)*items_count; + if (oldliststart != liststart) + { + paintItems(); + } + else + { + paintItem(prev_selected - liststart); + paintItem(selected - liststart); + } + } + else + { + internalMoveChannel(prev_selected, selected); + } } int CBEChannelWidget::exec(CMenuTarget* parent, const std::string & /*actionKey*/) @@ -301,43 +297,32 @@ int CBEChannelWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* if (parent) parent->hide(); - width = frameBuffer->getScreenWidthRel(); - info_height = 2*iheight + 4; - height = frameBuffer->getScreenHeightRel() - info_height; - listmaxshow = (height-theight-footerHeight-0)/iheight; - height = theight+footerHeight+listmaxshow*iheight; // recalc height - - x = getScreenStartX(width); - if (x < DETAILSLINE_WIDTH) - x = DETAILSLINE_WIDTH; - y = getScreenStartY(height + info_height); - - mode = CZapitClient::MODE_TV; if (g_bouquetManager->Bouquets[bouquet]->tvChannels.empty()) mode = CZapitClient::MODE_RADIO; else if (g_bouquetManager->Bouquets[bouquet]->radioChannels.empty()) mode = CZapitClient::MODE_TV; + Channels = mode == CZapitClient::MODE_TV ? &(g_bouquetManager->Bouquets[bouquet]->tvChannels) : &(g_bouquetManager->Bouquets[bouquet]->radioChannels); paintHead(); - paint(); + paintBody(); paintFoot(); + paintItems(); channelsChanged = false; - uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]); + uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU]); - bool loop=true; + bool loop = true; while (loop) { - g_RCInput->getMsgAbsoluteTimeout( &msg, &data, &timeoutEnd ); + g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); - if ( msg <= CRCInput::RC_MaxRC ) - timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]); + if (msg <= CRCInput::RC_MaxRC) + timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU]); - if ((msg == CRCInput::RC_timeout) || - (msg == (neutrino_msg_t)g_settings.key_channelList_cancel)) + if ((msg == CRCInput::RC_timeout) || (msg == (neutrino_msg_t)g_settings.key_channelList_cancel)) { if (state == beDefault) { @@ -351,33 +336,37 @@ int CBEChannelWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* else if (msg == CRCInput::RC_up || msg == (neutrino_msg_t)g_settings.key_pageup || msg == CRCInput::RC_down || msg == (neutrino_msg_t)g_settings.key_pagedown) { - int new_selected = UpDownKey(*Channels, msg, listmaxshow, selected); + int new_selected = UpDownKey(*Channels, msg, items_count, selected); updateSelection(new_selected); } - else if (msg == (neutrino_msg_t) g_settings.key_list_start || msg == (neutrino_msg_t) g_settings.key_list_end) { - if (!(Channels->empty())) { - int new_selected = msg == (neutrino_msg_t) g_settings.key_list_start ? 0 : Channels->size() - 1; - updateSelection(new_selected); - } - } - else if(msg==CRCInput::RC_red) + else if (msg == (neutrino_msg_t) g_settings.key_list_start || msg == (neutrino_msg_t) g_settings.key_list_end) + { + if (!(Channels->empty())) + { + int new_selected = msg == (neutrino_msg_t) g_settings.key_list_start ? 0 : Channels->size() - 1; + updateSelection(new_selected); + } + } + else if (msg == CRCInput::RC_red) { if (state == beDefault) deleteChannel(); } - else if(msg==CRCInput::RC_green) + else if (msg == CRCInput::RC_green) { if (state == beDefault) addChannel(); } - else if(msg==CRCInput::RC_yellow) + else if (msg == CRCInput::RC_yellow) { - liststart = (selected/listmaxshow)*listmaxshow; + liststart = (selected/items_count)*items_count; if (state == beDefault) beginMoveChannel(); + else if (state == beMoving) + finishMoveChannel(); paintItem(selected - liststart); } - else if(msg==CRCInput::RC_blue) + else if (msg == CRCInput::RC_blue) { if (selected < Channels->size()) /* Channels->size() might be 0 */ { @@ -385,7 +374,7 @@ int CBEChannelWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* renameChannel(); } } - else if(msg==CRCInput::RC_stop) + else if (msg == CRCInput::RC_stop) { if (selected < Channels->size()) /* Channels->size() might be 0 */ { @@ -394,7 +383,7 @@ int CBEChannelWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* } } /* TODO upgrade - else if (msg == CRCInput::RC_forward ) + else if (msg == CRCInput::RC_forward) { if (selected < Channels->size()) { @@ -403,38 +392,48 @@ int CBEChannelWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* } } */ - else if( msg == (neutrino_msg_t) g_settings.key_tvradio_mode || msg==CRCInput::RC_tv ) { - if (mode == CZapitClient::MODE_TV) + else if (msg == (neutrino_msg_t) g_settings.key_tvradio_mode || msg == CRCInput::RC_tv || msg == CRCInput::RC_radio) + { + if (msg == CRCInput::RC_radio) mode = CZapitClient::MODE_RADIO; - else + else if (msg == CRCInput::RC_tv) mode = CZapitClient::MODE_TV; + else // g_settings.key_tvradio_mode + { + if (mode == CZapitClient::MODE_TV) + mode = CZapitClient::MODE_RADIO; + else + mode = CZapitClient::MODE_TV; + } Channels = mode == CZapitClient::MODE_TV ? &(g_bouquetManager->Bouquets[bouquet]->tvChannels) : &(g_bouquetManager->Bouquets[bouquet]->radioChannels); selected = 0; paintHead(); - paint(); + paintBody(); paintFoot(); + paintItems(); } - - else if(msg==CRCInput::RC_ok) + else if (msg == CRCInput::RC_ok) { if (state == beDefault) { if (selected < Channels->size()) /* Channels.size() might be 0 */ g_Zapit->zapTo_serviceID((*Channels)[selected]->getChannelID()); - } else if (state == beMoving) { + } + else if (state == beMoving) + { finishMoveChannel(); } } - else if( CRCInput::isNumeric(msg) ) + else if (CRCInput::isNumeric(msg)) { if (state == beDefault) { //kein pushback - wenn man versehentlich wo draufkommt is die edit-arbeit umsonst //selected = oldselected; - //g_RCInput->postMsg( msg, data ); + //g_RCInput->postMsg(msg, data); //loop=false; } else if (state == beMoving) @@ -448,7 +447,7 @@ int CBEChannelWidget::exec(CMenuTarget* parent, const std::string & /*actionKey* } else { - CNeutrinoApp::getInstance()->handleMsg( msg, data ); + CNeutrinoApp::getInstance()->handleMsg(msg, data); } } hide(); @@ -470,7 +469,7 @@ void CBEChannelWidget::deleteChannel() if (selected >= Channels->size()) selected = Channels->empty() ? 0 : (Channels->size() - 1); channelsChanged = true; - paint(); + paintItems(); } void CBEChannelWidget::renameChannel() @@ -479,7 +478,7 @@ void CBEChannelWidget::renameChannel() if (newName != (*Channels)[selected]->getName()) { - if(newName.empty()) + if (newName.empty()) (*Channels)[selected]->setUserName(""); else (*Channels)[selected]->setUserName(newName); @@ -487,8 +486,9 @@ void CBEChannelWidget::renameChannel() channelsChanged = true; } paintHead(); - paint(); + paintBody(); paintFoot(); + paintItems(); } void CBEChannelWidget::switchLockChannel() @@ -513,8 +513,9 @@ void CBEChannelWidget::addChannel() } delete channelSelectWidget; paintHead(); - paint(); + paintBody(); paintFoot(); + paintItems(); } void CBEChannelWidget::beginMoveChannel() @@ -528,13 +529,13 @@ void CBEChannelWidget::finishMoveChannel() { state = beDefault; channelsChanged = channelsChanged | true; - paint(); + paintItems(); } void CBEChannelWidget::cancelMoveChannel() { state = beDefault; - internalMoveChannel( newPosition, origPosition); + internalMoveChannel(newPosition, origPosition); channelsChanged = channelsChanged | false; } /* TODO upgrade (taken from channellist.cpp) @@ -543,25 +544,26 @@ void CBEChannelWidget::moveChannelToBouquet() if (addChannelToBouquet()) deleteChannel(false); else - paint(); + paintItems(); paintHead(); } */ -void CBEChannelWidget::internalMoveChannel( unsigned int fromPosition, unsigned int toPosition) +void CBEChannelWidget::internalMoveChannel(unsigned int fromPosition, unsigned int toPosition) { - if ( (int) toPosition == -1 ) return; - if ( toPosition == Channels->size()) return; + if ((int) toPosition == -1) + return; + if (toPosition == Channels->size()) + return; - g_bouquetManager->Bouquets[bouquet]->moveService(fromPosition, toPosition, - mode == CZapitClient::MODE_TV ? 1 : 2); + g_bouquetManager->Bouquets[bouquet]->moveService(fromPosition, toPosition, mode == CZapitClient::MODE_TV ? 1 : 2); //channelsChanged = true; Channels = mode == CZapitClient::MODE_TV ? &(g_bouquetManager->Bouquets[bouquet]->tvChannels) : &(g_bouquetManager->Bouquets[bouquet]->radioChannels); selected = toPosition; newPosition = toPosition; - paint(); + paintItems(); } std::string CBEChannelWidget::inputName(const char * const defaultName, const neutrino_locale_t _caption) @@ -578,5 +580,5 @@ std::string CBEChannelWidget::inputName(const char * const defaultName, const ne bool CBEChannelWidget::hasChanged() { - return (channelsChanged); + return channelsChanged; } diff --git a/src/gui/bedit/bouqueteditor_channels.h b/src/gui/bedit/bouqueteditor_channels.h index 8ee180710..72e73d20d 100644 --- a/src/gui/bedit/bouqueteditor_channels.h +++ b/src/gui/bedit/bouqueteditor_channels.h @@ -1,95 +1,70 @@ /* - Neutrino-GUI - DBoxII-Project + neutrino bouquet editor - channels editor Copyright (C) 2001 Steffen Hehn 'McClean' - Homepage: http://dbox.cyberphoria.org/ - - Kommentar: - - Diese GUI wurde von Grund auf neu programmiert und sollte nun vom - Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert - auf der Client-Server Idee, diese GUI ist also von der direkten DBox- - Steuerung getrennt. Diese wird dann von Daemons uebernommen. - + Copyright (C) 2017 Sven Hoefer 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 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. + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifndef __bouqueteditor_channels__ #define __bouqueteditor_channels__ -#include -#include +#include + #include +#include +#include +#include +#include #include -#include -#include -#include +#include "bouqueteditor_globals.h" -class CFrameBuffer; -class CBEChannelWidget : public CMenuTarget, public CListHelpers +class CBEChannelWidget : public CBEGlobals, public CMenuTarget, public CListHelpers { - private: - CFrameBuffer *frameBuffer; CComponentsDetailsLine *dline; CComponentsInfoBox *ibox; - CComponentsFooter footer; + enum state_ { beDefault, beMoving } state; - unsigned int selected; - unsigned int origPosition; - unsigned int newPosition; + unsigned int selected; + unsigned int origPosition; + unsigned int newPosition; + unsigned int liststart; - unsigned int liststart; - unsigned int listmaxshow; - unsigned int numwidth; - int fheight; - int theight; - int iconoffset; - int iheight; // item height - int footerHeight; - int info_height; - - std::string caption; - bool channelsChanged; + bool channelsChanged; + std::string caption; CZapitClient::channelsMode mode; unsigned int bouquet; - int width; - int height; - int x; - int y; - - void paintItem(int pos); - void paintDetails(int index); - void initItem2DetailsLine (int pos, int ch_index); - void clearItem2DetailsLine (); - void paint(); void paintHead(); + void paintBody(); + void paintItem(int pos); + void paintItems(); void paintFoot(); + void paintDetails(int pos, int current); void hide(); void updateSelection(unsigned int newpos); @@ -101,10 +76,10 @@ class CBEChannelWidget : public CMenuTarget, public CListHelpers void finishMoveChannel(); void cancelMoveChannel(); void moveChannelToBouquet(); - void internalMoveChannel( unsigned int fromPosition, unsigned int toPosition); + void internalMoveChannel(unsigned int fromPosition, unsigned int toPosition); std::string getInfoText(int index); - std::string inputName(const char * const defaultName, const neutrino_locale_t caption); + std::string inputName(const char* const defaultName, const neutrino_locale_t caption); public: CBEChannelWidget( const std::string & Caption, unsigned int Bouquet); diff --git a/src/gui/bedit/bouqueteditor_chanselect.cpp b/src/gui/bedit/bouqueteditor_chanselect.cpp index e02c467c0..66d0cd3a1 100644 --- a/src/gui/bedit/bouqueteditor_chanselect.cpp +++ b/src/gui/bedit/bouqueteditor_chanselect.cpp @@ -1,32 +1,23 @@ /* - Neutrino-GUI - DBoxII-Project + neutrino bouquet editor - channel selection Copyright (C) 2001 Steffen Hehn 'McClean' - Homepage: http://dbox.cyberphoria.org/ - - Kommentar: - - Diese GUI wurde von Grund auf neu programmiert und sollte nun vom - Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert - auf der Client-Server Idee, diese GUI ist also von der direkten DBox- - Steuerung getrennt. Diese wird dann von Daemons uebernommen. - + Copyright (C) 2017 Sven Hoefer 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 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. + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifdef HAVE_CONFIG_H @@ -34,47 +25,41 @@ #endif #include + #include #include -#include "bouqueteditor_chanselect.h" #include #include #include - - -#include #include +#include + +#include "bouqueteditor_chanselect.h" extern CBouquetManager *g_bouquetManager; CBEChannelSelectWidget::CBEChannelSelectWidget(const std::string & Caption, CZapitBouquet* Bouquet, CZapitClient::channelsMode Mode) - :CListBox(Caption.c_str()) { - int icol_w, icol_h; - + caption = Caption; bouquet = Bouquet; mode = Mode; - iconoffset = 0; - info_height = 0; - theight = g_Font[SNeutrinoSettings::FONT_TYPE_MENU_TITLE]->getHeight(); - fheight = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->getHeight(); - footerHeight= footer.getHeight(); - - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_GREEN, &icol_w, &icol_h); - iheight = std::max(fheight, icol_h+2); - iconoffset = std::max(iconoffset, icol_w); - - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_OKAY, &icol_w, &icol_h); - ButtonHeight = std::max(footerHeight, icol_h+4); - frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_HOME, &icol_w, &icol_h); - ButtonHeight = std::max(footerHeight, icol_h+4); - + selected = 0; liststart = 0; channellist_sort_mode = SORT_ALPHA; bouquetChannels = NULL; dline = NULL; - ibox = new CComponentsInfoBox(); + ibox = NULL; + + int iw, ih; + action_icon_width = 0; + frameBuffer->getIconSize(NEUTRINO_ICON_BUTTON_DUMMY_SMALL, &action_icon_width, &ih); + + status_icon_width = 0; + frameBuffer->getIconSize(NEUTRINO_ICON_SCRAMBLED, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); + frameBuffer->getIconSize(NEUTRINO_ICON_STREAMING, &iw, &ih); + status_icon_width = std::max(status_icon_width, iw); } CBEChannelSelectWidget::~CBEChannelSelectWidget() @@ -83,12 +68,355 @@ CBEChannelSelectWidget::~CBEChannelSelectWidget() delete ibox; } -uint CBEChannelSelectWidget::getItemCount() +void CBEChannelSelectWidget::paintItem(int pos) { - return Channels.size(); + int ypos = y + header_height + pos*item_height; + unsigned int current = liststart + pos; + + bool i_selected = current == selected; + int i_radius = RADIUS_NONE; + + fb_pixel_t color; + fb_pixel_t bgcolor; + + getItemColors(color, bgcolor, i_selected); + + if (i_selected) + { + if (current < Channels.size()) + paintDetails(pos, current); + + i_radius = RADIUS_LARGE; + } + else + { + if (current < Channels.size() && (Channels[current]->flags & CZapitChannel::NOT_PRESENT)) + color = COL_MENUCONTENTINACTIVE_TEXT; + } + + if (i_radius) + frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, item_height, COL_MENUCONTENT_PLUS_0); + frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, item_height, bgcolor, i_radius); + + if (current < Channels.size()) + { + if (isChannelInBouquet(current)) + frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_GREEN, x + OFFSET_INNER_MID, ypos, item_height); + else + frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_DUMMY_SMALL, x + OFFSET_INNER_MID, ypos, item_height); + + int text_offset = 2*OFFSET_INNER_MID + action_icon_width; + item_font->RenderString(x + text_offset, ypos + item_height, width - text_offset - SCROLLBAR_WIDTH - 2*OFFSET_INNER_MID - status_icon_width, Channels[current]->getName(), color); + + if (Channels[current]->scrambled) + frameBuffer->paintIcon(NEUTRINO_ICON_SCRAMBLED, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - status_icon_width, ypos, item_height); + else if (!Channels[current]->getUrl().empty()) + frameBuffer->paintIcon(NEUTRINO_ICON_STREAMING, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - status_icon_width, ypos, item_height); + } } -bool CBEChannelSelectWidget::isChannelInBouquet( int index) +void CBEChannelSelectWidget::paintItems() +{ + liststart = (selected/items_count)*items_count; + + for(unsigned int count = 0; count < items_count; count++) + paintItem(count); + + int total_pages; + int current_page; + getScrollBarData(&total_pages, ¤t_page, Channels.size(), items_count, selected); + paintScrollBar(x + width - SCROLLBAR_WIDTH, y + header_height, SCROLLBAR_WIDTH, body_height, total_pages, current_page); +} + +void CBEChannelSelectWidget::paintBody() +{ + PaintBoxRel(x, y + header_height, width, body_height, COL_MENUCONTENT_PLUS_0, RADIUS_NONE, CORNER_NONE, CC_SHADOW_ON); +} + +void CBEChannelSelectWidget::paintHead() +{ + header.setCaption(caption + (mode == CZapitClient::MODE_TV ? " - TV" : " - Radio")); + header.setIcon(NULL); // trick the cc-header + header.setIcon(mode == CZapitClient::MODE_TV ? NEUTRINO_ICON_VIDEO : NEUTRINO_ICON_AUDIO); + header.setDimensionsAll(x, y, width, header_height); + header.setCorner(RADIUS_LARGE, CORNER_TOP); + header.enableShadow(CC_SHADOW_RIGHT | CC_SHADOW_CORNER_TOP_RIGHT | CC_SHADOW_CORNER_BOTTOM_RIGHT, -1, true); + header.paint(CC_SAVE_SCREEN_NO); +} + +struct button_label CBEChannelSelectButtons[] = +{ + { NEUTRINO_ICON_BUTTON_RED, LOCALE_CHANNELLIST_FOOT_SORT_ALPHA }, + { NEUTRINO_ICON_BUTTON_OKAY, LOCALE_BOUQUETEDITOR_SWITCH }, + { NEUTRINO_ICON_BUTTON_HOME, LOCALE_BOUQUETEDITOR_RETURN } +}; + +void CBEChannelSelectWidget::paintFoot() +{ + switch (channellist_sort_mode) + { + case SORT_FREQ: + { + CBEChannelSelectButtons[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_FREQ; + break; + } + case SORT_SAT: + { + CBEChannelSelectButtons[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_SAT; + break; + } + case SORT_CH_NUMBER: + { + CBEChannelSelectButtons[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_CHNUM; + break; + } + case SORT_ALPHA: + default: + { + CBEChannelSelectButtons[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_ALPHA; + break; + } + } + + const short numbuttons = sizeof(CBEChannelSelectButtons)/sizeof(CBEChannelSelectButtons[0]); + + footer.enableShadow(CC_SHADOW_ON, -1, true); + footer.paintButtons(x, y + header_height + body_height, width, footer_height, numbuttons, CBEChannelSelectButtons); +} + +void CBEChannelSelectWidget::paintDetails(int pos, int current) +{ + int xpos = x - DETAILSLINE_WIDTH; + int ypos1 = y + header_height + pos*item_height; + int ypos2 = y + height - info_height - OFFSET_SHADOW; + int ypos1a = ypos1 + (item_height/2); + int ypos2a = ypos2 + (info_height/2); + + if (dline) + dline->kill(); + + if (pos >= 0) + { + if (dline == NULL) + dline = new CComponentsDetailsLine(); + + if (dline) + { + dline->setDimensionsAll(xpos, ypos1a, ypos2a, item_height/2, info_height - RADIUS_LARGE*2); + dline->paint(CC_SAVE_SCREEN_NO); + } + + if (ibox == NULL) + { + ibox = new CComponentsInfoBox(); + + if (ibox) + { + ibox->setColorBody(COL_MENUCONTENTDARK_PLUS_0); + ibox->setTextColor(COL_MENUCONTENTDARK_TEXT); + ibox->setFrameThickness(FRAME_WIDTH_MIN); + ibox->setCorner(RADIUS_LARGE); + ibox->enableShadow(CC_SHADOW_ON); + } + } + + if (ibox) + { + if (ibox->isPainted()) + ibox->hide(); + + ibox->setDimensionsAll(x, ypos2, width, info_height); + ibox->setText(getInfoText(current), CTextBox::AUTO_WIDTH | CTextBox::NO_AUTO_LINEBREAK, info_font); + ibox->paint(CC_SAVE_SCREEN_NO); + } + } +} + +void CBEChannelSelectWidget::hide() +{ + frameBuffer->paintBackgroundBoxRel(x, y, width + OFFSET_SHADOW, height + OFFSET_SHADOW); + + if (dline) + dline->kill(); + if (ibox) + ibox->kill(); +} + +std::string CBEChannelSelectWidget::getInfoText(int index) +{ + std::string res = ""; + + std::string satname = CServiceManager::getInstance()->GetSatelliteName(Channels[index]->getSatellitePosition()); + if (IS_WEBTV(Channels[index]->getChannelID())) + satname = "WebTV"; + transponder t; + CServiceManager::getInstance()->GetTransponder(Channels[index]->getTransponderId(), t); + std::string desc = t.description(); + if (Channels[index]->pname) + { + if (desc.empty()) + desc = std::string(Channels[index]->pname); + else + desc += " (" + std::string(Channels[index]->pname) + ")"; + } + if (!Channels[index]->getDesc().empty()) + desc += "\n" + Channels[index]->getDesc(); + + res = satname + " - " + desc; + + return res; +} + +void CBEChannelSelectWidget::updateSelection(unsigned int newpos) +{ + if (newpos == selected || newpos == (unsigned int)-1) + return; + + unsigned int prev_selected = selected; + selected = newpos; + + unsigned int oldliststart = liststart; + liststart = (selected/items_count)*items_count; + if (oldliststart != liststart) + { + paintItems(); + } + else + { + paintItem(prev_selected - liststart); + paintItem(selected - liststart); + } +} + +int CBEChannelSelectWidget::exec(CMenuTarget* parent, const std::string & /*actionKey*/) +{ + neutrino_msg_t msg; + neutrino_msg_data_t data; + + int res = menu_return::RETURN_REPAINT; + selected = 0; + + if (parent) + parent->hide(); + + bouquetChannels = mode == CZapitClient::MODE_TV ? &(bouquet->tvChannels) : &(bouquet->radioChannels); + + Channels.clear(); + + if (mode == CZapitClient::MODE_RADIO) + CServiceManager::getInstance()->GetAllRadioChannels(Channels); + else + CServiceManager::getInstance()->GetAllTvChannels(Channels); + + sort(Channels.begin(), Channels.end(), CmpChannelByChName()); + + paintHead(); + paintBody(); + paintFoot(); + paintItems(); + + uint64_t timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU]); + + channelChanged = false; + bool loop = true; + while (loop) + { + g_RCInput->getMsgAbsoluteTimeout(&msg, &data, &timeoutEnd); + + if (msg <= CRCInput::RC_MaxRC) + timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_MENU]); + + if ((msg == (neutrino_msg_t)g_settings.key_channelList_cancel) || (msg == CRCInput::RC_home)) + { + loop = false; + } + else if (msg == CRCInput::RC_up || msg == (neutrino_msg_t)g_settings.key_pageup || + msg == CRCInput::RC_down || msg == (neutrino_msg_t)g_settings.key_pagedown) + { + int new_selected = UpDownKey(Channels, msg, items_count, selected); + updateSelection(new_selected); + } + else if (msg == (neutrino_msg_t) g_settings.key_list_start || msg == (neutrino_msg_t) g_settings.key_list_end) + { + if (!Channels.empty()) + { + int new_selected = msg == (neutrino_msg_t) g_settings.key_list_start ? 0 : Channels.size() - 1; + updateSelection(new_selected); + } + } + else if (msg == CRCInput::RC_ok || msg == CRCInput::RC_green) + { + if (selected < Channels.size()) + selectChannel(); + } + else if (msg == CRCInput::RC_red) + { + if (selected < Channels.size()) + sortChannels(); + } + else if (CNeutrinoApp::getInstance()->listModeKey(msg)) + { + // do nothing + } + else + { + CNeutrinoApp::getInstance()->handleMsg(msg, data); + } + } + + hide(); + return res; +} + +void CBEChannelSelectWidget::sortChannels() +{ + channellist_sort_mode++; + if (channellist_sort_mode >= SORT_END) + channellist_sort_mode = SORT_ALPHA; + switch (channellist_sort_mode) + { + case SORT_FREQ: + { + sort(Channels.begin(), Channels.end(), CmpChannelByFreq()); + break; + } + case SORT_SAT: + { + sort(Channels.begin(), Channels.end(), CmpChannelBySat()); + break; + } + case SORT_CH_NUMBER: + { + sort(Channels.begin(), Channels.end(), CmpChannelByChNum()); + break; + } + case SORT_ALPHA: + default: + { + sort(Channels.begin(), Channels.end(), CmpChannelByChName()); + break; + } + } + paintFoot(); + paintItems(); +} + +void CBEChannelSelectWidget::selectChannel() +{ + channelChanged = true; + + if (isChannelInBouquet(selected)) + bouquet->removeService(Channels[selected]); + else + bouquet->addService(Channels[selected]); + + bouquetChannels = mode == CZapitClient::MODE_TV ? &(bouquet->tvChannels) : &(bouquet->radioChannels); + + paintItem(selected - liststart); + g_RCInput->postMsg(CRCInput::RC_down, 0); +} + +bool CBEChannelSelectWidget::isChannelInBouquet(int index) { for (unsigned int i=0; i< bouquetChannels->size(); i++) { @@ -100,223 +428,5 @@ bool CBEChannelSelectWidget::isChannelInBouquet( int index) bool CBEChannelSelectWidget::hasChanged() { - return modified; -} - -void CBEChannelSelectWidget::paintItem(uint32_t itemNr, int paintNr, bool pselected) -{ - int ypos = y+ theight + paintNr*iheight; - int i_radius = RADIUS_NONE; - - fb_pixel_t color; - fb_pixel_t bgcolor; - - getItemColors(color, bgcolor, pselected); - - if (pselected) - { - if (itemNr < getItemCount()) - { - initItem2DetailsLine (paintNr, itemNr); - paintDetails(itemNr); - } - i_radius = RADIUS_LARGE; - } - else - { - if (itemNr < getItemCount() && (Channels[itemNr]->flags & CZapitChannel::NOT_PRESENT)) - color = COL_MENUCONTENTINACTIVE_TEXT; - } - - if (i_radius) - frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, iheight, COL_MENUCONTENT_PLUS_0); - frameBuffer->paintBoxRel(x, ypos, width - SCROLLBAR_WIDTH, iheight, bgcolor, i_radius); - - if(itemNr < getItemCount()) - { - if( isChannelInBouquet(itemNr)) - frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_GREEN, x + OFFSET_INNER_MID, ypos, iheight); - else - frameBuffer->paintBoxRel(x + OFFSET_INNER_MID, ypos, iconoffset, iheight, bgcolor); - - g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]->RenderString(x + 2*OFFSET_INNER_MID + 2*iconoffset, ypos + iheight - (iheight-fheight)/2, width - 3*OFFSET_INNER_MID - 2*iconoffset, Channels[itemNr]->getName(), color); - if(Channels[itemNr]->scrambled) - frameBuffer->paintIcon(NEUTRINO_ICON_SCRAMBLED, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - iconoffset, ypos, fheight); - else if (!Channels[itemNr]->getUrl().empty()) - frameBuffer->paintIcon(NEUTRINO_ICON_STREAMING, x + width - SCROLLBAR_WIDTH - OFFSET_INNER_MID - iconoffset, ypos, fheight); - } -} - -void CBEChannelSelectWidget::onOkKeyPressed() -{ - if (selected >= Channels.size()) - return; - setModified(); - if (isChannelInBouquet(selected)) - bouquet->removeService(Channels[selected]); - else - bouquet->addService(Channels[selected]); - - bouquetChannels = mode == CZapitClient::MODE_TV ? &(bouquet->tvChannels) : &(bouquet->radioChannels); - - paintItem( selected, selected - liststart, false); - g_RCInput->postMsg( CRCInput::RC_down, 0 ); -} - -void CBEChannelSelectWidget::onRedKeyPressed() -{ - if (selected >= Channels.size()) - return; - - channellist_sort_mode++; - if(channellist_sort_mode > SORT_END) - channellist_sort_mode = 0; - switch(channellist_sort_mode) - { - case SORT_ALPHA: - sort(Channels.begin(), Channels.end(), CmpChannelByChName()); - break; - case SORT_FREQ: - sort(Channels.begin(), Channels.end(), CmpChannelByFreq()); - break; - case SORT_SAT: - sort(Channels.begin(), Channels.end(), CmpChannelBySat()); - break; - case SORT_CH_NUMBER: - sort(Channels.begin(), Channels.end(), CmpChannelByChNum()); - break; - default: - sort(Channels.begin(), Channels.end(), CmpChannelByChName()); - break; - } - paintFoot(); - paint(); -} - -int CBEChannelSelectWidget::exec(CMenuTarget* parent, const std::string & actionKey) -{ - width = frameBuffer->getScreenWidthRel(); - info_height = 2*iheight + 4; - height = frameBuffer->getScreenHeightRel() - info_height; - listmaxshow = (height-theight-footerHeight-0)/iheight; - height = theight+footerHeight+listmaxshow*iheight; // recalc height - - x = getScreenStartX(width); - if (x < DETAILSLINE_WIDTH) - x = DETAILSLINE_WIDTH; - y = getScreenStartY(height + info_height); - - bouquetChannels = mode == CZapitClient::MODE_TV ? &(bouquet->tvChannels) : &(bouquet->radioChannels); - - Channels.clear(); - if (mode == CZapitClient::MODE_RADIO) - CServiceManager::getInstance()->GetAllRadioChannels(Channels); - else - CServiceManager::getInstance()->GetAllTvChannels(Channels); - - sort(Channels.begin(), Channels.end(), CmpChannelByChName()); - - return CListBox::exec(parent, actionKey); -} - -const struct button_label CBEChannelSelectButtons[] = -{ - { NEUTRINO_ICON_BUTTON_RED, LOCALE_CHANNELLIST_FOOT_SORT_ALPHA}, - { NEUTRINO_ICON_BUTTON_OKAY, LOCALE_BOUQUETEDITOR_SWITCH }, - { NEUTRINO_ICON_BUTTON_HOME, LOCALE_BOUQUETEDITOR_RETURN } -}; - -void CBEChannelSelectWidget::paintFoot() -{ - const short numbuttons = sizeof(CBEChannelSelectButtons)/sizeof(CBEChannelSelectButtons[0]); - struct button_label Button[numbuttons]; - for (int i = 0; i < numbuttons; i++) - Button[i] = CBEChannelSelectButtons[i]; - - switch (channellist_sort_mode) { - case SORT_ALPHA: - Button[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_ALPHA; - break; - case SORT_FREQ: - Button[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_FREQ; - break; - case SORT_SAT: - Button[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_SAT; - break; - case SORT_CH_NUMBER: - Button[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_CHNUM; - break; - default: - Button[0].locale = LOCALE_CHANNELLIST_FOOT_SORT_ALPHA; - break; - } - - footer.paintButtons(x, y + (height-footerHeight), width, footerHeight, numbuttons, Button, width/numbuttons-2*OFFSET_INNER_MID); -} - -std::string CBEChannelSelectWidget::getInfoText(int index) -{ - std::string res = ""; - - std::string satname = CServiceManager::getInstance()->GetSatelliteName(Channels[index]->getSatellitePosition()); - transponder t; - CServiceManager::getInstance()->GetTransponder(Channels[index]->getTransponderId(), t); - std::string desc = t.description(); - if(Channels[index]->pname) - desc = desc + " (" + std::string(Channels[index]->pname) + ")"; - else - desc = desc + " (" + satname + ")"; - - res = satname + " " + desc; - - return res; -} - -void CBEChannelSelectWidget::paintDetails(int index) -{ - //details line - dline->paint(CC_SAVE_SCREEN_NO); - - std::string str = getInfoText(index); - - //info box - ibox->setText(str, CTextBox::AUTO_WIDTH | CTextBox::NO_AUTO_LINEBREAK, g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT]); - ibox->setColorBody(COL_MENUCONTENTDARK_PLUS_0); - ibox->setTextColor(COL_MENUCONTENTDARK_TEXT); - ibox->paint(false); -} - -void CBEChannelSelectWidget::initItem2DetailsLine (int pos, int /*ch_index*/) -{ - int xpos = x - DETAILSLINE_WIDTH; - int ypos1 = y + theight+0 + pos*iheight; - int ypos2 = y + height + OFFSET_INTER; - int ypos1a = ypos1 + (fheight/2); - int ypos2a = ypos2 + (info_height/2); - - if (dline) - dline->kill(); //kill details line - - // init Line if detail info (and not valid list pos) - if (pos >= 0) - { - if (dline == NULL) - dline = new CComponentsDetailsLine(xpos, ypos1a, ypos2a, fheight/2, info_height-RADIUS_LARGE*2); - dline->setYPos(ypos1a); - - //infobox - if (ibox){ - ibox->setDimensionsAll(x, ypos2, width, info_height); - ibox->setFrameThickness(FRAME_WIDTH_MIN); - ibox->setCorner(RADIUS_LARGE); - ibox->disableShadow(); - } - } -} - -void CBEChannelSelectWidget::hide() -{ - dline->kill(); //kill details line - ibox->kill(); - CListBox::hide(); + return channelChanged; } diff --git a/src/gui/bedit/bouqueteditor_chanselect.h b/src/gui/bedit/bouqueteditor_chanselect.h index 519b16397..bf7b9e6f6 100644 --- a/src/gui/bedit/bouqueteditor_chanselect.h +++ b/src/gui/bedit/bouqueteditor_chanselect.h @@ -1,76 +1,84 @@ /* - Neutrino-GUI - DBoxII-Project + neutrino bouquet editor - channel selection Copyright (C) 2001 Steffen Hehn 'McClean' - Homepage: http://dbox.cyberphoria.org/ - - Kommentar: - - Diese GUI wurde von Grund auf neu programmiert und sollte nun vom - Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert - auf der Client-Server Idee, diese GUI ist also von der direkten DBox- - Steuerung getrennt. Diese wird dann von Daemons uebernommen. - + Copyright (C) 2017 Sven Hoefer 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 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. + 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., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #ifndef __bouqueteditor_chanselect__ #define __bouqueteditor_chanselect__ -#include +#include + #include +#include +#include +#include +#include #include -#include -#include -#include +#include "bouqueteditor_globals.h" -class CBEChannelSelectWidget : public CListBox +class CBEChannelSelectWidget : public CBEGlobals, public CMenuTarget, public CListHelpers { private: - - CZapitBouquet * bouquet; - short int channellist_sort_mode; - enum{SORT_ALPHA,SORT_FREQ,SORT_SAT,SORT_CH_NUMBER, SORT_END}; - CZapitClient::channelsMode mode; - bool isChannelInBouquet( int index); CComponentsDetailsLine *dline; CComponentsInfoBox *ibox; - CComponentsFooter footer; - uint getItemCount(); - void paintItem(uint32_t itemNr, int paintNr, bool selected); - void paintDetails(int index); - void initItem2DetailsLine (int pos, int ch_index); + + enum { + SORT_ALPHA, + SORT_FREQ, + SORT_SAT, + SORT_CH_NUMBER, + SORT_END + }; + + unsigned int selected; + unsigned int liststart; + + CZapitClient::channelsMode mode; + CZapitBouquet * bouquet; + short int channellist_sort_mode; + bool isChannelInBouquet(int index); + + bool channelChanged; + std::string caption; + + void paintHead(); + void paintBody(); + void paintItem(int pos); + void paintItems(); void paintFoot(); - void onOkKeyPressed(); - void onRedKeyPressed(); + void paintDetails(int pos, int current); void hide(); + void updateSelection(unsigned int newpos); + + void sortChannels(); + void selectChannel(); - int footerHeight; - int info_height; - std::string getInfoText(int index); - public: - ZapitChannelList Channels; - ZapitChannelList * bouquetChannels; + public: CBEChannelSelectWidget(const std::string & Caption, CZapitBouquet* Bouquet, CZapitClient::channelsMode Mode); ~CBEChannelSelectWidget(); + + ZapitChannelList Channels; + ZapitChannelList * bouquetChannels; int exec(CMenuTarget* parent, const std::string & actionKey); bool hasChanged(); }; diff --git a/src/gui/bedit/bouqueteditor_globals.cpp b/src/gui/bedit/bouqueteditor_globals.cpp new file mode 100644 index 000000000..f164d7e59 --- /dev/null +++ b/src/gui/bedit/bouqueteditor_globals.cpp @@ -0,0 +1,60 @@ +/* + neutrino bouquet editor - globals + + Copyright (C) 2017 Sven Hoefer + + 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, see . +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include + +#include "bouqueteditor_globals.h" + +class CFrameBuffer; + +CBEGlobals::CBEGlobals() +{ + frameBuffer = CFrameBuffer::getInstance(); + + item_font = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST]; + info_font = g_Font[SNeutrinoSettings::FONT_TYPE_CHANNELLIST_DESCR]; + + width = frameBuffer->getScreenWidthRel(); + height = frameBuffer->getScreenHeightRel(); + + header_height = header.getHeight(); + item_height = item_font->getHeight(); + footer_height = footer.getHeight(); + info_height = 2*info_font->getHeight() + 2*OFFSET_INNER_SMALL; + + items_count = (height - header_height - footer_height - OFFSET_INTER - info_height - 2*OFFSET_SHADOW) / item_height; + body_height = items_count*item_height; + height = header_height + body_height + footer_height + OFFSET_INTER + info_height + 2*OFFSET_SHADOW; // recalc height + + x = getScreenStartX(width); + y = getScreenStartY(height); +} + +CBEGlobals::~CBEGlobals() +{ +} diff --git a/src/gui/bedit/bouqueteditor_globals.h b/src/gui/bedit/bouqueteditor_globals.h new file mode 100644 index 000000000..49e84cbd5 --- /dev/null +++ b/src/gui/bedit/bouqueteditor_globals.h @@ -0,0 +1,61 @@ +/* + neutrino bouquet editor - globals + + Copyright (C) 2017 Sven Hoefer + + 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, see . +*/ + +#ifndef __bouqueteditor_globals__ +#define __bouqueteditor_globals__ + +#include +#include + +class CFrameBuffer; + +class CBEGlobals +{ + public: + CBEGlobals(); + ~CBEGlobals(); + + CFrameBuffer *frameBuffer; + + int x; + int y; + int width; + int height; + + int header_height; + int body_height; + int item_height; + int footer_height; + int info_height; + + CComponentsHeader header; + CComponentsFooter footer; + + unsigned int items_count; + + Font *item_font; + Font *info_font; + + int action_icon_width; + int status_icon_width; +}; + +#endif From 95ab4ac708392c355def7821a7675b5bbb47d05e Mon Sep 17 00:00:00 2001 From: svenhoefer Date: Mon, 25 Sep 2017 08:42:26 +0200 Subject: [PATCH 20/24] - detailsline: reduce two times the shadow width from the h_marks Otherwise shadows will be painted lower then the height of the object the detailsline is docked to. --- src/gui/components/cc_detailsline.cpp | 8 +++++--- src/gui/components/cc_detailsline.h | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/components/cc_detailsline.cpp b/src/gui/components/cc_detailsline.cpp index 4184a145c..0ff9adcbf 100644 --- a/src/gui/components/cc_detailsline.cpp +++ b/src/gui/components/cc_detailsline.cpp @@ -53,12 +53,14 @@ void CComponentsDetailsLine::initVarDline( const int& x_pos, const int& y_pos_to col_shadow = color_shadow; col_body = color_line; + shadow_w = 1; + //CComponentsDetailsLine y_down = y_pos_down; - h_mark_top = h_mark_top_; - h_mark_down = h_mark_down_; - shadow_w = 1; + // reduce two times the shadow width, to avoid shadow overlaps + h_mark_top = h_mark_top_ - 2*shadow_w; + h_mark_down = h_mark_down_ - 2*shadow_w; //CComponentsDetailsLine dl_w = CFrameBuffer::getInstance()->scale2Res(3); diff --git a/src/gui/components/cc_detailsline.h b/src/gui/components/cc_detailsline.h index 66197f51f..48f44635e 100644 --- a/src/gui/components/cc_detailsline.h +++ b/src/gui/components/cc_detailsline.h @@ -67,9 +67,9 @@ class CComponentsDetailsLine : public CComponents ///set property: lowest y position void setYPosDown(const int& y_pos_down){y_down = y_pos_down;}; ///set property: height of top marker - void setHMarkTop(const int& h_mark_top_){h_mark_top = h_mark_top_;}; + void setHMarkTop(const int& h_mark_top_){h_mark_top = h_mark_top_ - 2*shadow_w;}; ///property: height of bottom marker - void setHMarkDown(const int& h_mark_down_){h_mark_down = h_mark_down_;}; + void setHMarkDown(const int& h_mark_down_){h_mark_down = h_mark_down_ - 2*shadow_w;}; ///set all positions and dimensions of details line at once void setDimensionsAll(const int& x_pos,const int& y_pos, const int& y_pos_down, const int& h_mark_top_ , const int& h_mark_down_) {setXPos(x_pos); setYPos(y_pos); setYPosDown(y_pos_down); setHMarkTop(h_mark_top_); setHMarkDown(h_mark_down_);} From d9e540b865f3deb50766fdbeace4839368a62b4f Mon Sep 17 00:00:00 2001 From: svenhoefer Date: Mon, 25 Sep 2017 08:42:26 +0200 Subject: [PATCH 21/24] - menue: add possibility to add localized values in CMenuOptionNumberChooser seperately --- src/gui/widget/menue.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/widget/menue.h b/src/gui/widget/menue.h index 7e78de2ab..ade80cafd 100644 --- a/src/gui/widget/menue.h +++ b/src/gui/widget/menue.h @@ -361,6 +361,8 @@ private: void setNumberFormat(std::string format) { numberFormat = format; } void setNumberFormat(std::string (*fun)(int)) { numberFormatFunction = fun; } void setNumericInput(bool _numeric_input) { numeric_input = _numeric_input; } + void setLocalizedValue(int special_value) { localized_value = special_value; } + void setLocalizedValueName(neutrino_locale_t special_value_name) { localized_value_name = special_value_name; } }; class CMenuOptionChooserOptions From 7c429c17e0f4b8477bafaa296c098f3c9cb6ed97 Mon Sep 17 00:00:00 2001 From: svenhoefer Date: Mon, 25 Sep 2017 08:42:26 +0200 Subject: [PATCH 22/24] - osd-setup: use 0 as a localized value for timeout-settings --- src/gui/osd_setup.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index c9e9835cc..14c3d6801 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -1059,6 +1059,8 @@ void COsdSetup::showOsdTimeoutSetup(CMenuWidget* menu_timeout) { CMenuOptionNumberChooser *ch = new CMenuOptionNumberChooser(timing_setting[i].name, &g_settings.timing[i], true, 0, 240); ch->setNumberFormat(nf); + ch->setLocalizedValue(0); + ch->setLocalizedValueName(LOCALE_OPTIONS_OFF); ch->setHint("", timing_setting[i].hint); menu_timeout->addItem(ch); } From 33a596d1754e8189d02ab929b2c3252f06d7a17b Mon Sep 17 00:00:00 2001 From: svenhoefer Date: Mon, 25 Sep 2017 08:42:26 +0200 Subject: [PATCH 23/24] - menue: user smaller vertical offset for hintboxes to keep it in sync with other vertical offsets * get bottom menu offset from CMenuSeparator()->getHeight() --- src/gui/widget/menue.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/gui/widget/menue.cpp b/src/gui/widget/menue.cpp index 1ab6a4e9d..9d7cd9f72 100644 --- a/src/gui/widget/menue.cpp +++ b/src/gui/widget/menue.cpp @@ -1140,11 +1140,11 @@ void CMenuWidget::calcSize() hint_height = 0; if(g_settings.show_menu_hints && has_hints) { int lines = 2; - int text_height = 2*OFFSET_INNER_MID + lines*g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT]->getHeight(); + int text_height = 2*OFFSET_INNER_SMALL + lines*g_Font[SNeutrinoSettings::FONT_TYPE_MENU_HINT]->getHeight(); /* assuming all hint icons has the same size ! */ int icon_width, icon_height; frameBuffer->getIconSize(NEUTRINO_ICON_HINT_TVMODE, &icon_width, &icon_height); - icon_height += 2*OFFSET_INNER_MID; + icon_height += 2*OFFSET_INNER_SMALL; hint_height = std::max(icon_height, text_height); } /* set the max height to 9/10 of usable screen height @@ -1202,11 +1202,12 @@ void CMenuWidget::calcSize() // shrink menu if less items height = std::min(height, hheight + maxItemHeight); /* - Always add a bottom offset. + Always add a bottom separator offset. Most menus has an upper offset too, which is added with the intro-items */ - height += OFFSET_INNER_MID; + CMenuItem *separator = new CMenuSeparator(); + height += separator->getHeight(); //scrollbar width scrollbar_width=0; From ca09c92542971474cf21634b31a088c70635638d Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Tue, 26 Sep 2017 12:39:36 +0200 Subject: [PATCH 24/24] Revert "src/gui/osd_setup.cpp disable hint paint in channellist-mode, is broken" This reverts commit e308407b229b72cf2f1851a122221878114033d1. --- src/gui/osd_setup.cpp | 27 ++++++++++----------------- src/gui/osd_setup.h | 2 +- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/gui/osd_setup.cpp b/src/gui/osd_setup.cpp index 14c3d6801..4d4cbaf32 100644 --- a/src/gui/osd_setup.cpp +++ b/src/gui/osd_setup.cpp @@ -1232,7 +1232,7 @@ void COsdSetup::showOsdInfobarSetup(CMenuWidget *menu_infobar) } //channellist -void COsdSetup::showOsdChanlistSetup(CMenuWidget *menu_chanlist, bool hint_paint) +void COsdSetup::showOsdChanlistSetup(CMenuWidget *menu_chanlist) { CMenuOptionChooser * mc; @@ -1241,45 +1241,38 @@ void COsdSetup::showOsdChanlistSetup(CMenuWidget *menu_chanlist, bool hint_paint // channellist additional mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_ADDITIONAL, &g_settings.channellist_additional, CHANNELLIST_ADDITIONAL_OPTIONS, CHANNELLIST_ADDITIONAL_OPTION_COUNT, true); - if(hint_paint) - mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_ADDITIONAL); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_ADDITIONAL); menu_chanlist->addItem(mc); // epg align mc = new CMenuOptionChooser(LOCALE_MISCSETTINGS_CHANNELLIST_EPGTEXT_ALIGN, &g_settings.channellist_epgtext_align_right, CHANNELLIST_EPGTEXT_ALIGN_RIGHT_OPTIONS, CHANNELLIST_EPGTEXT_ALIGN_RIGHT_OPTIONS_COUNT, true); - if(hint_paint) - mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_EPG_ALIGN); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_EPG_ALIGN); menu_chanlist->addItem(mc); // extended channel list mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_EXTENDED, &g_settings.theme.progressbar_design_channellist, PROGRESSBAR_COLOR_OPTIONS, PROGRESSBAR_COLOR_OPTION_COUNT, true, this); - if(hint_paint) - mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_EXTENDED); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_EXTENDED); menu_chanlist->addItem(mc); // show infobox mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_SHOW_INFOBOX, &g_settings.channellist_show_infobox, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true, channellistNotifier); - if(hint_paint) - mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_SHOW_INFOBOX); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_SHOW_INFOBOX); menu_chanlist->addItem(mc); // foot mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_FOOT, &g_settings.channellist_foot, CHANNELLIST_FOOT_OPTIONS, CHANNELLIST_FOOT_OPTIONS_COUNT, g_settings.channellist_show_infobox); - if(hint_paint) - mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_FOOT); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_FOOT); menu_chanlist->addItem(mc); channellistNotifier->addItem(mc); //show channel logo mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_SHOW_CHANNELLOGO, &g_settings.channellist_show_channellogo, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); - if(hint_paint) - mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_SHOW_CHANNELLOGO); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_SHOW_CHANNELLOGO); menu_chanlist->addItem(mc); //show numbers mc = new CMenuOptionChooser(LOCALE_CHANNELLIST_SHOW_CHANNELNUMBER, &g_settings.channellist_show_numbers, OPTIONS_OFF0_ON1_OPTIONS, OPTIONS_OFF0_ON1_OPTION_COUNT, true); - if(hint_paint) - mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_SHOW_CHANNELNUMBER); + mc->setHint("", LOCALE_MENU_HINT_CHANNELLIST_SHOW_CHANNELNUMBER); menu_chanlist->addItem(mc); } @@ -1502,7 +1495,7 @@ int COsdSetup::showContextChanlistMenu(CChannelList *parent_channellist) menu_chanlist->enableFade(false); menu_chanlist->setSelected(cselected); - showOsdChanlistSetup(menu_chanlist, false); + showOsdChanlistSetup(menu_chanlist); menu_chanlist->addItem(new CMenuSeparator(CMenuSeparator::LINE)); CMenuWidget *fontSettingsSubMenu = new CMenuWidget(LOCALE_FONTMENU_HEAD, NEUTRINO_ICON_KEYBINDING); @@ -1520,7 +1513,7 @@ int COsdSetup::showContextChanlistMenu(CChannelList *parent_channellist) fontSettingsSubMenu->addItem(new CMenuForwarder(LOCALE_OPTIONS_DEFAULT, true, NULL, this, font_sizes_groups[i].actionkey)); CMenuForwarder * mf = new CMenuDForwarder(LOCALE_FONTMENU_HEAD, true, NULL, fontSettingsSubMenu, NULL, CRCInput::RC_red); -// mf->setHint("", LOCALE_MENU_HINT_FONTS);//FIXME menu restoreScreen + mf->setHint("", LOCALE_MENU_HINT_FONTS); menu_chanlist->addItem(mf); int res = menu_chanlist->exec(NULL, ""); diff --git a/src/gui/osd_setup.h b/src/gui/osd_setup.h index dbaaa2451..cdea56535 100644 --- a/src/gui/osd_setup.h +++ b/src/gui/osd_setup.h @@ -71,7 +71,7 @@ class COsdSetup : public CMenuTarget, public CChangeObserver void showOsdTimeoutSetup(CMenuWidget *menu_timeout); void showOsdMenusSetup(CMenuWidget *menu_menus); void showOsdInfobarSetup(CMenuWidget *menu_infobar); - void showOsdChanlistSetup(CMenuWidget *menu_chanlist, bool hint_paint = true); + void showOsdChanlistSetup(CMenuWidget *menu_chanlist); void showOsdEventlistSetup(CMenuWidget *menu_eventlist); void showOsdVolumeSetup(CMenuWidget *menu_volume); void showOsdInfoclockSetup(CMenuWidget *menu_infoclock);