From 84629bde6c85ba9bec34324a89e8fe4de8d2caa5 Mon Sep 17 00:00:00 2001 From: louis Date: Fri, 10 Jan 2014 12:44:01 +0100 Subject: [PATCH] Added possibility to manage EPG Search Timers in red button recording menu --- HISTORY | 3 + Makefile | 2 +- config.c | 2 + config.h | 1 + fontmanager.c | 2 + fontmanager.h | 1 + icons/darkredNG/recmenuicons/activetimer.png | Bin 0 -> 1731 bytes icons/default/recmenuicons/activetimer.png | Bin 0 -> 1731 bytes icons/recmenuicons/activetimer.png | Bin 0 -> 1731 bytes po/ca_ES.po | 174 +++- po/de_DE.po | 175 +++- po/ru_RU.po | 174 +++- po/sk_SK.po | 174 +++- recmanager.c | 342 ++----- recmanager.h | 26 +- recmenu.c | 414 ++++---- recmenu.h | 63 +- recmenuitem.c | 270 +++++- recmenuitem.h | 104 +- recmenumanager.c | 521 ++++++---- recmenumanager.h | 15 +- recmenus.c | 965 +++++++++++++------ recmenus.h | 237 ++++- searchtimer.c | 556 +++++++++++ searchtimer.h | 130 +++ setup.c | 2 + switchtimer.c | 4 + switchtimer.h | 11 +- tools.c | 67 ++ tools.h | 5 + 30 files changed, 3165 insertions(+), 1275 deletions(-) create mode 100644 icons/darkredNG/recmenuicons/activetimer.png create mode 100644 icons/default/recmenuicons/activetimer.png create mode 100644 icons/recmenuicons/activetimer.png create mode 100644 searchtimer.c create mode 100644 searchtimer.h diff --git a/HISTORY b/HISTORY index 5dc53a9..0a4da2c 100644 --- a/HISTORY +++ b/HISTORY @@ -100,3 +100,6 @@ Version 1.1.0 - Added timer Timeline view in red button recording menu - Current channel positioned in middle of channellist when tvguide is opened +- Added possibility to manage EPG Search Timers in red button recording + menu +- completely refactored recording menu diff --git a/Makefile b/Makefile index dbd598a..9e69308 100644 --- a/Makefile +++ b/Makefile @@ -59,7 +59,7 @@ endif ### The object files (add further files here): -OBJS = $(PLUGIN).o channelcolumn.o channelgroup.o channelgroups.o channeljump.o config.o detailview.o dummygrid.o epggrid.o fontmanager.o footer.o geometrymanager.o grid.o headergrid.o imagecache.o imageloader.o imagemagickwrapper.o imagescaler.o osdmanager.o recmanager.o recmenu.o recmenuitem.o recmenumanager.o recmenus.o setup.o statusheader.o styledpixmap.o switchtimer.o timeline.o timer.o timerconflict.o tools.o tvguideosd.o +OBJS = $(PLUGIN).o channelcolumn.o channelgroup.o channelgroups.o channeljump.o config.o detailview.o dummygrid.o epggrid.o fontmanager.o footer.o geometrymanager.o grid.o headergrid.o imagecache.o imageloader.o imagemagickwrapper.o imagescaler.o osdmanager.o recmanager.o recmenu.o recmenuitem.o recmenumanager.o recmenus.o searchtimer.o setup.o statusheader.o styledpixmap.o switchtimer.o timeline.o timer.o timerconflict.o tools.o tvguideosd.o ### The main target: diff --git a/config.c b/config.c index 45a53b3..b3a95f7 100644 --- a/config.c +++ b/config.c @@ -70,6 +70,7 @@ cTvguideConfig::cTvguideConfig() { FontTimeLineTimeHorizontalDelta = 0; FontRecMenuItemDelta = 0; FontRecMenuItemSmallDelta = 0; + FontRecMenuItemLargeDelta = 0; timeFormat = 1; useNopacityTheme = 1; themeIndex = -1; @@ -274,6 +275,7 @@ bool cTvguideConfig::SetupParse(const char *Name, const char *Value) { else if (strcmp(Name, "FontTimeLineTimeHorizontalDelta") == 0) FontTimeLineTimeHorizontalDelta = atoi(Value); else if (strcmp(Name, "FontRecMenuItemDelta") == 0) FontRecMenuItemDelta = atoi(Value); else if (strcmp(Name, "FontRecMenuItemSmallDelta") == 0) FontRecMenuItemSmallDelta = atoi(Value); + else if (strcmp(Name, "FontRecMenuItemLargeDelta") == 0) FontRecMenuItemLargeDelta = atoi(Value); else if (strcmp(Name, "displayRerunsDetailEPGView") == 0) displayRerunsDetailEPGView = atoi(Value); else if (strcmp(Name, "numReruns") == 0) numReruns = atoi(Value); else if (strcmp(Name, "useSubtitleRerun") == 0) useSubtitleRerun = atoi(Value); diff --git a/config.h b/config.h index 4e1087c..b4d68d9 100644 --- a/config.h +++ b/config.h @@ -107,6 +107,7 @@ class cTvguideConfig { int FontTimeLineTimeHorizontalDelta; int FontRecMenuItemDelta; int FontRecMenuItemSmallDelta; + int FontRecMenuItemLargeDelta; int timeFormat; int useNopacityTheme; int themeIndex; diff --git a/fontmanager.c b/fontmanager.c index 5123b7e..7468190 100644 --- a/fontmanager.c +++ b/fontmanager.c @@ -38,6 +38,7 @@ void cFontManager::SetFonts() { //Fonts for RecMenu FontRecMenuItem = CreateFont(geoManager.osdHeight/30 + tvguideConfig.FontRecMenuItemDelta); FontRecMenuItemSmall = CreateFont(geoManager.osdHeight/40 + tvguideConfig.FontRecMenuItemSmallDelta); + FontRecMenuItemLarge = CreateFont(geoManager.osdHeight/25 + tvguideConfig.FontRecMenuItemLargeDelta); } void cFontManager::DeleteFonts() { @@ -64,6 +65,7 @@ void cFontManager::DeleteFonts() { delete FontTimeLineTimeHorizontal; delete FontRecMenuItem; delete FontRecMenuItemSmall; + delete FontRecMenuItemLarge; } void cFontManager::InitialiseFontType(void) { diff --git a/fontmanager.h b/fontmanager.h index e9e72dd..423a1be 100644 --- a/fontmanager.h +++ b/fontmanager.h @@ -35,5 +35,6 @@ class cFontManager { cFont *FontMessageBoxLarge; cFont *FontRecMenuItem; cFont *FontRecMenuItemSmall; + cFont *FontRecMenuItemLarge; }; #endif //__TVGUIDE_FONTMANAGER_H \ No newline at end of file diff --git a/icons/darkredNG/recmenuicons/activetimer.png b/icons/darkredNG/recmenuicons/activetimer.png new file mode 100644 index 0000000000000000000000000000000000000000..af4c33c0b19f30bb0cb85b8f95e4fc1132842221 GIT binary patch literal 1731 zcmV;!20ZzRP) zQG5gik)Q~MK&Vz;8iJIi4G66*q+%+MN=XHUlmqVkqrdyz?|JvTqec_wuic&5nc45| z&dv_}-zmvHq_Tr8{!326Y68OuvPZsk;#Oq%+DqdtIiRMni~#^#<~4cMVtxljTJsB; zVd1^R^K=5>IIqao1RSWy@$Dtg#Jj{0snt!)=K}+8o_wlv@;O9?X=Yt;r2nip2a+`< z1ytL3o#lxzH1LnGm;IE<4PB}q zbv7;IehCzDxhG0DtPRVvMLBWk=|!=+~M`Hn#biCyH# zblD`$z+NCk4M?+WlIi5I%OE+BJ(i7F>M;d&|%sU>DX9$Z*hOlzuawe8Av< z%A#2BjFAftaJ4$n+0Ky*jL|#As(WGxM9%C{DR&YMb#+AmDJQZq%Mx=SlI2WsIWS$^ z5U|Xeo`3@?mn?n#^)AxwqB$V-ItE=;Zu|&Dyx#6Ao#}9JjkG;}3?j-N&|4c^rMqY; zm>X?y(B|2Jq54pAMGqJ0!2pbKW*+S5OR;P7?m)NjQ4d!8&Z&1C(y({f8%LNMLmVlh!iKdo6Wea*ZhSs_c@i2V=~{Xn(5VH>)rw{q1~Gpn#E z(XW}$kcx$=k)Ie_XmcRR7+$uh0tSu2X!T5-Gt>wnJQh`uXSs!e+0wKgYj>{0lhUX`V<+##@2XeN=3{w55(`lM!i)O zYmz+15&#O6`QuUKpe-t?6x{*2%5kmP(|X1oTv)-J)@NJYsVkdGPpx@eu6i)uUA<4h zcn#M(wA@|Tz*x>uCciq&`pkp*bu_Y&!RD0groJUhWJP@US(UIn9K)nt4B1I+CY3+v zCr#!+v`B9)SCiv1KUp_#)Z!$Wq4u$jRIboRnrt;9b&kkG*UegdE-iIm>wC=UbJU6ucKa$x-u5 zsY=;q=uVK|T+MGKT=wcGXQGwqUSOr^yZ$t#5`tr?fosNKt&(_>cTE~ftd%u`))VyC znh(p4sC7b6i+IB_w3~GtCR{ViXE2X5$|AE^UUxOG^sRYYo{dqc1W?1-O}jX*!A(ZX zK3DU57^yXn$$c>^rP`zbDRDS(T~b{&ZRQcJ86ZPiJS8M*ie|n!rs-CR6m?#$Q@tEC z73=0>6_RH5Xe#eH1*GUHYgezdG z2tWPlK}X;(&Qnc=>;zC{nDd7!F_bsdMLm6i47u!Dsx{N$Jd%M;qL(UVCp#S-oryJl zxnI?YmaeH)2J?%Y%)2A7o2+F2z-uvsaO8Fy>1QbbbqA4`@{+iG=#pI?+fg1*f4bx7 z-RdJLX02i58KQnS6Q%{}jCN!UT7aS2a8~AdD$yiDYBpV$28!tI>G{4Ay0 z66q5HDu-*KC6L^uJdkRb^dC~k?yYsuRr{ykDDppy9S Z)8D6~+oh1;8B72G002ovPDHLkV1fqeGf4md literal 0 HcmV?d00001 diff --git a/icons/default/recmenuicons/activetimer.png b/icons/default/recmenuicons/activetimer.png new file mode 100644 index 0000000000000000000000000000000000000000..af4c33c0b19f30bb0cb85b8f95e4fc1132842221 GIT binary patch literal 1731 zcmV;!20ZzRP) zQG5gik)Q~MK&Vz;8iJIi4G66*q+%+MN=XHUlmqVkqrdyz?|JvTqec_wuic&5nc45| z&dv_}-zmvHq_Tr8{!326Y68OuvPZsk;#Oq%+DqdtIiRMni~#^#<~4cMVtxljTJsB; zVd1^R^K=5>IIqao1RSWy@$Dtg#Jj{0snt!)=K}+8o_wlv@;O9?X=Yt;r2nip2a+`< z1ytL3o#lxzH1LnGm;IE<4PB}q zbv7;IehCzDxhG0DtPRVvMLBWk=|!=+~M`Hn#biCyH# zblD`$z+NCk4M?+WlIi5I%OE+BJ(i7F>M;d&|%sU>DX9$Z*hOlzuawe8Av< z%A#2BjFAftaJ4$n+0Ky*jL|#As(WGxM9%C{DR&YMb#+AmDJQZq%Mx=SlI2WsIWS$^ z5U|Xeo`3@?mn?n#^)AxwqB$V-ItE=;Zu|&Dyx#6Ao#}9JjkG;}3?j-N&|4c^rMqY; zm>X?y(B|2Jq54pAMGqJ0!2pbKW*+S5OR;P7?m)NjQ4d!8&Z&1C(y({f8%LNMLmVlh!iKdo6Wea*ZhSs_c@i2V=~{Xn(5VH>)rw{q1~Gpn#E z(XW}$kcx$=k)Ie_XmcRR7+$uh0tSu2X!T5-Gt>wnJQh`uXSs!e+0wKgYj>{0lhUX`V<+##@2XeN=3{w55(`lM!i)O zYmz+15&#O6`QuUKpe-t?6x{*2%5kmP(|X1oTv)-J)@NJYsVkdGPpx@eu6i)uUA<4h zcn#M(wA@|Tz*x>uCciq&`pkp*bu_Y&!RD0groJUhWJP@US(UIn9K)nt4B1I+CY3+v zCr#!+v`B9)SCiv1KUp_#)Z!$Wq4u$jRIboRnrt;9b&kkG*UegdE-iIm>wC=UbJU6ucKa$x-u5 zsY=;q=uVK|T+MGKT=wcGXQGwqUSOr^yZ$t#5`tr?fosNKt&(_>cTE~ftd%u`))VyC znh(p4sC7b6i+IB_w3~GtCR{ViXE2X5$|AE^UUxOG^sRYYo{dqc1W?1-O}jX*!A(ZX zK3DU57^yXn$$c>^rP`zbDRDS(T~b{&ZRQcJ86ZPiJS8M*ie|n!rs-CR6m?#$Q@tEC z73=0>6_RH5Xe#eH1*GUHYgezdG z2tWPlK}X;(&Qnc=>;zC{nDd7!F_bsdMLm6i47u!Dsx{N$Jd%M;qL(UVCp#S-oryJl zxnI?YmaeH)2J?%Y%)2A7o2+F2z-uvsaO8Fy>1QbbbqA4`@{+iG=#pI?+fg1*f4bx7 z-RdJLX02i58KQnS6Q%{}jCN!UT7aS2a8~AdD$yiDYBpV$28!tI>G{4Ay0 z66q5HDu-*KC6L^uJdkRb^dC~k?yYsuRr{ykDDppy9S Z)8D6~+oh1;8B72G002ovPDHLkV1fqeGf4md literal 0 HcmV?d00001 diff --git a/icons/recmenuicons/activetimer.png b/icons/recmenuicons/activetimer.png new file mode 100644 index 0000000000000000000000000000000000000000..af4c33c0b19f30bb0cb85b8f95e4fc1132842221 GIT binary patch literal 1731 zcmV;!20ZzRP) zQG5gik)Q~MK&Vz;8iJIi4G66*q+%+MN=XHUlmqVkqrdyz?|JvTqec_wuic&5nc45| z&dv_}-zmvHq_Tr8{!326Y68OuvPZsk;#Oq%+DqdtIiRMni~#^#<~4cMVtxljTJsB; zVd1^R^K=5>IIqao1RSWy@$Dtg#Jj{0snt!)=K}+8o_wlv@;O9?X=Yt;r2nip2a+`< z1ytL3o#lxzH1LnGm;IE<4PB}q zbv7;IehCzDxhG0DtPRVvMLBWk=|!=+~M`Hn#biCyH# zblD`$z+NCk4M?+WlIi5I%OE+BJ(i7F>M;d&|%sU>DX9$Z*hOlzuawe8Av< z%A#2BjFAftaJ4$n+0Ky*jL|#As(WGxM9%C{DR&YMb#+AmDJQZq%Mx=SlI2WsIWS$^ z5U|Xeo`3@?mn?n#^)AxwqB$V-ItE=;Zu|&Dyx#6Ao#}9JjkG;}3?j-N&|4c^rMqY; zm>X?y(B|2Jq54pAMGqJ0!2pbKW*+S5OR;P7?m)NjQ4d!8&Z&1C(y({f8%LNMLmVlh!iKdo6Wea*ZhSs_c@i2V=~{Xn(5VH>)rw{q1~Gpn#E z(XW}$kcx$=k)Ie_XmcRR7+$uh0tSu2X!T5-Gt>wnJQh`uXSs!e+0wKgYj>{0lhUX`V<+##@2XeN=3{w55(`lM!i)O zYmz+15&#O6`QuUKpe-t?6x{*2%5kmP(|X1oTv)-J)@NJYsVkdGPpx@eu6i)uUA<4h zcn#M(wA@|Tz*x>uCciq&`pkp*bu_Y&!RD0groJUhWJP@US(UIn9K)nt4B1I+CY3+v zCr#!+v`B9)SCiv1KUp_#)Z!$Wq4u$jRIboRnrt;9b&kkG*UegdE-iIm>wC=UbJU6ucKa$x-u5 zsY=;q=uVK|T+MGKT=wcGXQGwqUSOr^yZ$t#5`tr?fosNKt&(_>cTE~ftd%u`))VyC znh(p4sC7b6i+IB_w3~GtCR{ViXE2X5$|AE^UUxOG^sRYYo{dqc1W?1-O}jX*!A(ZX zK3DU57^yXn$$c>^rP`zbDRDS(T~b{&ZRQcJ86ZPiJS8M*ie|n!rs-CR6m?#$Q@tEC z73=0>6_RH5Xe#eH1*GUHYgezdG z2tWPlK}X;(&Qnc=>;zC{nDd7!F_bsdMLm6i47u!Dsx{N$Jd%M;qL(UVCp#S-oryJl zxnI?YmaeH)2J?%Y%)2A7o2+F2z-uvsaO8Fy>1QbbbqA4`@{+iG=#pI?+fg1*f4bx7 z-RdJLX02i58KQnS6Q%{}jCN!UT7aS2a8~AdD$yiDYBpV$28!tI>G{4Ay0 z66q5HDu-*KC6L^uJdkRb^dC~k?yYsuRr{ykDDppy9S Z)8D6~+oh1;8B72G002ovPDHLkV1fqeGf4md literal 0 HcmV?d00001 diff --git a/po/ca_ES.po b/po/ca_ES.po index 7985a3f..0d195dd 100644 --- a/po/ca_ES.po +++ b/po/ca_ES.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-12-31 14:31+0100\n" +"POT-Creation-Date: 2014-01-10 11:54+0100\n" "PO-Revision-Date: 2013-09-21 17:49+0200\n" "Last-Translator: My friend Thanks David \n" "Language-Team: \n" @@ -81,6 +81,15 @@ msgstr "" msgid "No Timers active" msgstr "" +msgid "inactive" +msgstr "" + +msgid "active timers" +msgstr "" + +msgid "recordings done" +msgstr "" + msgid "Instant Record" msgstr "Enregistra a l'instant" @@ -90,12 +99,18 @@ msgstr "Esborra temporitzador" msgid "Edit Timer" msgstr "Edita temporitzador" -msgid "Create Series Timer" -msgstr "Programa enregistrament de Sèries" +msgid "Timer Timeline" +msgstr "" msgid "Create Search Timer" msgstr "Cerca temporitzadors" +msgid "Manage Search Timers" +msgstr "" + +msgid "Create Series Timer" +msgstr "Programa enregistrament de Sèries" + msgid "Create Switch Timer" msgstr "Canvia temporitzadors" @@ -105,9 +120,6 @@ msgstr "Esborra canvis de temporitzadors" msgid "Search" msgstr "Cerca" -msgid "Timer Timeline" -msgstr "" - msgid "Check for Timer Conflicts" msgstr "Comprova conflictes de temporitzadors" @@ -261,38 +273,23 @@ msgstr "Opcions de configuració manual" msgid "Use Template" msgstr "Utilitza plantilla" -msgid "Creating Search Timer" -msgstr "Creant cerca de temporitzador" +msgid "Manage EPGSearch Search Timers" +msgstr "" -msgid "Search Term" -msgstr "Cercant terme" +msgid "No Search Timers Configured" +msgstr "" -msgid "Using Template" -msgstr "Utilitzant plantilla" +msgid "Configure Search Timer Options" +msgstr "" -msgid "Display Results for Search Timer" -msgstr "Mostra resultats de la cerca" +msgid "Save Search Timer" +msgstr "" -msgid "Use other Template" -msgstr "Utilitza una altra plantilla" +msgid "Search String" +msgstr "" -msgid "Configure Search Timer Options for Search String" -msgstr "Configura opcions de cerca de temporitzadors amb text" - -msgid "whole term must appear" -msgstr "expressió completa" - -msgid "all terms must exist" -msgstr "totes les paraules" - -msgid "one term must exist" -msgstr "alguna paraula" - -msgid "exact match" -msgstr "coincidència exacta" - -msgid "regular expression" -msgstr "expressió regular" +msgid "Active" +msgstr "" msgid "Search Mode" msgstr "Mode de cerca" @@ -309,29 +306,68 @@ msgstr "Utilitza descripció" msgid "Limit Channels" msgstr "Canals restringits" +msgid "Use Time" +msgstr "Utilitza temps" + +msgid "Display advanced Options" +msgstr "" + +msgid "Limit Days of the Week" +msgstr "" + +msgid "Time margin for start in minutes" +msgstr "" + +msgid "Time margin for stop in minutes" +msgstr "" + +msgid "Use VPS" +msgstr "" + +msgid "Avoid Repeats" +msgstr "" + +msgid "Hide advanced Options" +msgstr "" + +msgid "Display Results for Search Timer" +msgstr "Mostra resultats de la cerca" + msgid "Start Channel" msgstr "Inicia canal" msgid "Stop Channel" msgstr "Atura canal" -msgid "Use Time" -msgstr "Utilitza temps" - msgid "Start after" msgstr "Comença després" msgid "Start before" msgstr "Comença abans" -msgid "search results for Search Timer" -msgstr "cerca resultats per temporitzador" +msgid "Select Days" +msgstr "" -msgid "search result for Search Timer" -msgstr "cerca resultat per temporitzador" +msgid "Number of allowed repeats" +msgstr "" -msgid "Nothing found for Search String" -msgstr "No s'ha trobat la cadena de text" +msgid "Compare Title" +msgstr "" + +msgid "Compare Subtitle" +msgstr "" + +msgid "Compare Description" +msgstr "" + +msgid "Really delete Search Timer" +msgstr "" + +msgid "Delete only Search Timer" +msgstr "" + +msgid "Delete Search Timer and created Timers" +msgstr "" msgid "Search Timer sucessfully created." msgstr "S'ha creat cerca de temporitzador" @@ -342,6 +378,27 @@ msgstr "Actualització de temporitzador iniciada" msgid "Search Timer NOT sucessfully created" msgstr "No s'ha creat cerca de temporitzador" +msgid "Creating Search Timer" +msgstr "Creant cerca de temporitzador" + +msgid "Search Term" +msgstr "Cercant terme" + +msgid "Using Template" +msgstr "Utilitzant plantilla" + +msgid "Use other Template" +msgstr "Utilitza una altra plantilla" + +msgid "search results for Search Timer" +msgstr "cerca resultats per temporitzador" + +msgid "search result for Search Timer" +msgstr "cerca resultat per temporitzador" + +msgid "Nothing found for Search String" +msgstr "No s'ha trobat la cadena de text" + msgid "Configure Options for Switchtimer" msgstr "Opcions de configuració de canvi de temporitzador" @@ -372,12 +429,6 @@ msgstr "No s'ha creat el canvi de temporitzador" msgid "Switch Timer deleted" msgstr "Canvi de temporitzador esborrat" -msgid "Show Search Options" -msgstr "Mostra opcions de cerca" - -msgid "Perform Search" -msgstr "Realitza la cerca" - msgid "Channel to Search" msgstr "Canal a cercar" @@ -390,6 +441,12 @@ msgstr "Cerca al subtítol" msgid "Search in Description" msgstr "Cerca a la descripció" +msgid "Show Search Options" +msgstr "Mostra opcions de cerca" + +msgid "Perform Search" +msgstr "Realitza la cerca" + msgid "search results for" msgstr "resultats de cerca per" @@ -414,6 +471,21 @@ msgstr "per" msgid "No recordings found for" msgstr "No s'han trobat gravacions per" +msgid "whole term must appear" +msgstr "expressió completa" + +msgid "all terms must exist" +msgstr "totes les paraules" + +msgid "one term must exist" +msgstr "alguna paraula" + +msgid "exact match" +msgstr "coincidència exacta" + +msgid "regular expression" +msgstr "expressió regular" + msgid "General Settings" msgstr "Preferències" @@ -651,6 +723,9 @@ msgstr "Mida de la Font - Menú Cerca & Enregistra" msgid "Search & Recording Menu Small Font Size" msgstr "Mida de la Font petita - Menú Cerca & Enregistra" +msgid "Search & Recording Main Menu Font Size" +msgstr "" + msgid "Create Log Messages for image loading" msgstr "" @@ -680,3 +755,6 @@ msgstr "" msgid "Recording Menus Icon Cache" msgstr "" + +#~ msgid "Configure Search Timer Options for Search String" +#~ msgstr "Configura opcions de cerca de temporitzadors amb text" diff --git a/po/de_DE.po b/po/de_DE.po index d42fea5..574a111 100755 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-12-31 14:31+0100\n" +"POT-Creation-Date: 2014-01-10 11:54+0100\n" "PO-Revision-Date: 2012-08-25 17:49+0200\n" "Last-Translator: Horst\n" "Language-Team: \n" @@ -78,6 +78,15 @@ msgstr "Aufn" msgid "No Timers active" msgstr "Keine Timer aktiv" +msgid "inactive" +msgstr "inaktiv" + +msgid "active timers" +msgstr "aktive Timer" + +msgid "recordings done" +msgstr "erledigte Aufnahmen" + msgid "Instant Record" msgstr "Aufnahme" @@ -87,12 +96,18 @@ msgstr "Timer löschen" msgid "Edit Timer" msgstr "Timer bearbeiten" -msgid "Create Series Timer" -msgstr "Serientimer anlegen" +msgid "Timer Timeline" +msgstr "Timer anzeigen" msgid "Create Search Timer" msgstr "Suchtimer anlegen" +msgid "Manage Search Timers" +msgstr "Suchtimer bearbeiten" + +msgid "Create Series Timer" +msgstr "Serientimer anlegen" + msgid "Create Switch Timer" msgstr "Umschalttimer anlegen" @@ -102,9 +117,6 @@ msgstr "Umschalttimer löschen" msgid "Search" msgstr "Suchen" -msgid "Timer Timeline" -msgstr "Timer Zeitleiste" - msgid "Check for Timer Conflicts" msgstr "Auf Timerkonflikte prüfen" @@ -258,38 +270,23 @@ msgstr "Optionen manuell konfigurieren" msgid "Use Template" msgstr "Template benutzen" -msgid "Creating Search Timer" -msgstr "Suchtimer anlegen" +msgid "Manage EPGSearch Search Timers" +msgstr "EPGSearch Suchtimer bearbeiten" -msgid "Search Term" +msgid "No Search Timers Configured" +msgstr "Keine Suchtimer angelegt" + +msgid "Configure Search Timer Options" +msgstr "Suchtimer konfigurieren" + +msgid "Save Search Timer" +msgstr "Suchtimer speichern" + +msgid "Search String" msgstr "Suchbegriff" -msgid "Using Template" -msgstr "Template" - -msgid "Display Results for Search Timer" -msgstr "Ergebnisse für Suchtimer anzeigen" - -msgid "Use other Template" -msgstr "Anderes Template benutzen" - -msgid "Configure Search Timer Options for Search String" -msgstr "Suchtimer Optionen konfigurieren für Suchbegriff" - -msgid "whole term must appear" -msgstr "vollständiger Ausdruck" - -msgid "all terms must exist" -msgstr "alle Worte" - -msgid "one term must exist" -msgstr "ein Wort" - -msgid "exact match" -msgstr "exakt" - -msgid "regular expression" -msgstr "Regulärer Ausdruck" +msgid "Active" +msgstr "Aktiv" msgid "Search Mode" msgstr "Suchmodus" @@ -306,29 +303,68 @@ msgstr "Beschreibung benutzen" msgid "Limit Channels" msgstr "Kanäle einschränken" +msgid "Use Time" +msgstr "Zeit benutzen" + +msgid "Display advanced Options" +msgstr "Erweiterte Optionen anzeigen" + +msgid "Limit Days of the Week" +msgstr "Wochentage beschränken" + +msgid "Time margin for start in minutes" +msgstr "Zeit vor Start in Minuten" + +msgid "Time margin for stop in minutes" +msgstr "Zeit nach Ende in Minuten" + +msgid "Use VPS" +msgstr "VPS benutzen" + +msgid "Avoid Repeats" +msgstr "Wiederholungen vermeiden" + +msgid "Hide advanced Options" +msgstr "Erweiterte Optionen ausblenden" + +msgid "Display Results for Search Timer" +msgstr "Ergebnisse für Suchtimer anzeigen" + msgid "Start Channel" msgstr "Startkanal" msgid "Stop Channel" msgstr "Stopkanal" -msgid "Use Time" -msgstr "Zeit benutzen" - msgid "Start after" msgstr "Beginn nach" msgid "Start before" msgstr "Beginn vor" -msgid "search results for Search Timer" -msgstr "Treffer für Suchtimer" +msgid "Select Days" +msgstr "Tage bestimmen" -msgid "search result for Search Timer" -msgstr "Treffer für Suchtimer" +msgid "Number of allowed repeats" +msgstr "Anzahl erlaubter Wiederholungen" -msgid "Nothing found for Search String" -msgstr "Keine Treffer für Suchbegriff" +msgid "Compare Title" +msgstr "Titel vergleichen" + +msgid "Compare Subtitle" +msgstr "Untertitel vergleichen" + +msgid "Compare Description" +msgstr "Beschreibung vergleichen" + +msgid "Really delete Search Timer" +msgstr "Suchtimer wirklich löschen" + +msgid "Delete only Search Timer" +msgstr "Nur Suchtimer löschen" + +msgid "Delete Search Timer and created Timers" +msgstr "Suchtimer und erzeugte Timer löschen" msgid "Search Timer sucessfully created." msgstr "Suchtimer erfolgreich angelegt" @@ -339,6 +375,27 @@ msgstr "Suchtimer update initialisiert" msgid "Search Timer NOT sucessfully created" msgstr "Suchtimer NICHT erfolgreich angelegt" +msgid "Creating Search Timer" +msgstr "Suchtimer anlegen" + +msgid "Search Term" +msgstr "Suchbegriff" + +msgid "Using Template" +msgstr "Template" + +msgid "Use other Template" +msgstr "Anderes Template benutzen" + +msgid "search results for Search Timer" +msgstr "Treffer für Suchtimer" + +msgid "search result for Search Timer" +msgstr "Treffer für Suchtimer" + +msgid "Nothing found for Search String" +msgstr "Keine Treffer für Suchbegriff" + msgid "Configure Options for Switchtimer" msgstr "Optionen für Umschalttimer konfigurieren" @@ -369,12 +426,6 @@ msgstr "Umschalttimer NICHT erfolgreich angelegt" msgid "Switch Timer deleted" msgstr "Umschalttimer gelöscht" -msgid "Show Search Options" -msgstr "Suchoptionen anzeigen" - -msgid "Perform Search" -msgstr "Suche ausführen" - msgid "Channel to Search" msgstr "Suche auf Kanal" @@ -387,6 +438,12 @@ msgstr "In Untertitel suchen" msgid "Search in Description" msgstr "In Beschreibung suchen" +msgid "Show Search Options" +msgstr "Suchoptionen anzeigen" + +msgid "Perform Search" +msgstr "Suche ausführen" + msgid "search results for" msgstr "Suchergebnisse für" @@ -411,6 +468,21 @@ msgstr "für" msgid "No recordings found for" msgstr "Keine Aufnahmen gefunden für" +msgid "whole term must appear" +msgstr "vollständiger Ausdruck" + +msgid "all terms must exist" +msgstr "alle Worte" + +msgid "one term must exist" +msgstr "ein Wort" + +msgid "exact match" +msgstr "exakt" + +msgid "regular expression" +msgstr "Regulärer Ausdruck" + msgid "General Settings" msgstr "Allgemeine Einstellungen" @@ -648,6 +720,9 @@ msgstr "Suchen & Aufnehmen Menu Schriftgröße" msgid "Search & Recording Menu Small Font Size" msgstr "Suchen & Aufnehmen Menu kleine Schriftgröße" +msgid "Search & Recording Main Menu Font Size" +msgstr "Suchen & Aufnehmen Hauptmenü Schriftgröße" + msgid "Create Log Messages for image loading" msgstr "Log Nachrichten für das Laden der Bilder erzeugen" diff --git a/po/ru_RU.po b/po/ru_RU.po index e9bec09..3c3ce31 100644 --- a/po/ru_RU.po +++ b/po/ru_RU.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 1.0.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-12-31 14:31+0100\n" +"POT-Creation-Date: 2014-01-10 11:54+0100\n" "PO-Revision-Date: 2013-09-25 17:49+0400\n" "Last-Translator: AmiD, ilya\n" "Language-Team: Russia-Cherepovets(wm.amid@gmail.com)\n" @@ -78,6 +78,15 @@ msgstr "" msgid "No Timers active" msgstr "" +msgid "inactive" +msgstr "" + +msgid "active timers" +msgstr "" + +msgid "recordings done" +msgstr "" + msgid "Instant Record" msgstr "Записать" @@ -87,12 +96,18 @@ msgstr "Удалить таймер" msgid "Edit Timer" msgstr "Редактировать таймер" -msgid "Create Series Timer" -msgstr "Создать циклический таймер" +msgid "Timer Timeline" +msgstr "" msgid "Create Search Timer" msgstr "Создать поисковый таймер" +msgid "Manage Search Timers" +msgstr "" + +msgid "Create Series Timer" +msgstr "Создать циклический таймер" + msgid "Create Switch Timer" msgstr "Создать таймер переключения" @@ -102,9 +117,6 @@ msgstr "Удалить таймер переключения" msgid "Search" msgstr "Поиск" -msgid "Timer Timeline" -msgstr "" - msgid "Check for Timer Conflicts" msgstr "Поиск таймер-конфликтов" @@ -258,38 +270,23 @@ msgstr "Ручная настройка параметров" msgid "Use Template" msgstr "Использовать шаблоны" -msgid "Creating Search Timer" -msgstr "Создается поисковый таймер" +msgid "Manage EPGSearch Search Timers" +msgstr "" -msgid "Search Term" -msgstr "Ключевое слово" +msgid "No Search Timers Configured" +msgstr "" -msgid "Using Template" -msgstr "Использовать шаблон" +msgid "Configure Search Timer Options" +msgstr "" -msgid "Display Results for Search Timer" -msgstr "Тест" +msgid "Save Search Timer" +msgstr "" -msgid "Use other Template" -msgstr "Использовать другие шаблоны" +msgid "Search String" +msgstr "" -msgid "Configure Search Timer Options for Search String" -msgstr "Настроить параметры таймера" - -msgid "whole term must appear" -msgstr "фраза" - -msgid "all terms must exist" -msgstr "все слова" - -msgid "one term must exist" -msgstr "хотя бы одно слово" - -msgid "exact match" -msgstr "точное совпадение" - -msgid "regular expression" -msgstr "регулярные выражения" +msgid "Active" +msgstr "" msgid "Search Mode" msgstr "Режим поиска" @@ -306,29 +303,68 @@ msgstr "Искать в описаниях" msgid "Limit Channels" msgstr "Ограничить список каналов" +msgid "Use Time" +msgstr "Время" + +msgid "Display advanced Options" +msgstr "" + +msgid "Limit Days of the Week" +msgstr "" + +msgid "Time margin for start in minutes" +msgstr "" + +msgid "Time margin for stop in minutes" +msgstr "" + +msgid "Use VPS" +msgstr "" + +msgid "Avoid Repeats" +msgstr "" + +msgid "Hide advanced Options" +msgstr "" + +msgid "Display Results for Search Timer" +msgstr "Тест" + msgid "Start Channel" msgstr "С канала" msgid "Stop Channel" msgstr "По канал" -msgid "Use Time" -msgstr "Время" - msgid "Start after" msgstr "С" msgid "Start before" msgstr "До" -msgid "search results for Search Timer" -msgstr "Совпадений найдено" +msgid "Select Days" +msgstr "" -msgid "search result for Search Timer" -msgstr "Совпадение найдено" +msgid "Number of allowed repeats" +msgstr "" -msgid "Nothing found for Search String" -msgstr "Совпадений НЕ найдено" +msgid "Compare Title" +msgstr "" + +msgid "Compare Subtitle" +msgstr "" + +msgid "Compare Description" +msgstr "" + +msgid "Really delete Search Timer" +msgstr "" + +msgid "Delete only Search Timer" +msgstr "" + +msgid "Delete Search Timer and created Timers" +msgstr "" msgid "Search Timer sucessfully created." msgstr "Поисковый таймер создан" @@ -339,6 +375,27 @@ msgstr "Поисковый таймер обновляется" msgid "Search Timer NOT sucessfully created" msgstr "Поисковый таймер НЕ создан" +msgid "Creating Search Timer" +msgstr "Создается поисковый таймер" + +msgid "Search Term" +msgstr "Ключевое слово" + +msgid "Using Template" +msgstr "Использовать шаблон" + +msgid "Use other Template" +msgstr "Использовать другие шаблоны" + +msgid "search results for Search Timer" +msgstr "Совпадений найдено" + +msgid "search result for Search Timer" +msgstr "Совпадение найдено" + +msgid "Nothing found for Search String" +msgstr "Совпадений НЕ найдено" + msgid "Configure Options for Switchtimer" msgstr "Настройка таймера переключения" @@ -369,12 +426,6 @@ msgstr "Таймер переключения НЕ был создан!" msgid "Switch Timer deleted" msgstr "Таймер переключения удален" -msgid "Show Search Options" -msgstr "Показать параметры поиска" - -msgid "Perform Search" -msgstr "Найти" - msgid "Channel to Search" msgstr "Канал для поиска" @@ -387,6 +438,12 @@ msgstr "Искать в эпизодах" msgid "Search in Description" msgstr "Искать в описаниях" +msgid "Show Search Options" +msgstr "Показать параметры поиска" + +msgid "Perform Search" +msgstr "Найти" + msgid "search results for" msgstr "Найдено по запросу" @@ -411,6 +468,21 @@ msgstr "для" msgid "No recordings found for" msgstr "Не найдено записей:" +msgid "whole term must appear" +msgstr "фраза" + +msgid "all terms must exist" +msgstr "все слова" + +msgid "one term must exist" +msgstr "хотя бы одно слово" + +msgid "exact match" +msgstr "точное совпадение" + +msgid "regular expression" +msgstr "регулярные выражения" + msgid "General Settings" msgstr "Основные настройки" @@ -648,6 +720,9 @@ msgstr "Размер шрифта меню Поиск & Запись" msgid "Search & Recording Menu Small Font Size" msgstr "Размер маленького шрифта меню Поиск & Запись" +msgid "Search & Recording Main Menu Font Size" +msgstr "" + msgid "Create Log Messages for image loading" msgstr "" @@ -677,3 +752,6 @@ msgstr "" msgid "Recording Menus Icon Cache" msgstr "" + +#~ msgid "Configure Search Timer Options for Search String" +#~ msgstr "Настроить параметры таймера" diff --git a/po/sk_SK.po b/po/sk_SK.po index 0a54044..8b0d56d 100644 --- a/po/sk_SK.po +++ b/po/sk_SK.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 1.1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-12-31 14:31+0100\n" +"POT-Creation-Date: 2014-01-10 11:54+0100\n" "PO-Revision-Date: 2013-09-15 00:12+0100\n" "Last-Translator: Milan Hrala \n" "Language-Team: \n" @@ -78,6 +78,15 @@ msgstr "" msgid "No Timers active" msgstr "" +msgid "inactive" +msgstr "" + +msgid "active timers" +msgstr "" + +msgid "recordings done" +msgstr "" + msgid "Instant Record" msgstr "Okamite nahra" @@ -87,12 +96,18 @@ msgstr "Vymaza msgid "Edit Timer" msgstr "Upravi pln nahrvania" -msgid "Create Series Timer" -msgstr "Vytvori sriov pln nahrvania" +msgid "Timer Timeline" +msgstr "" msgid "Create Search Timer" msgstr "Vytvori vyhadva plnov nahrvania" +msgid "Manage Search Timers" +msgstr "" + +msgid "Create Series Timer" +msgstr "Vytvori sriov pln nahrvania" + msgid "Create Switch Timer" msgstr "Vytvori prepnac pln" @@ -102,9 +117,6 @@ msgstr "Vymaza msgid "Search" msgstr "Hada" -msgid "Timer Timeline" -msgstr "" - msgid "Check for Timer Conflicts" msgstr "Skontrolova konflikty plnu" @@ -258,38 +270,23 @@ msgstr "Ru msgid "Use Template" msgstr "pouitie ablny" -msgid "Creating Search Timer" -msgstr "Vytvorenie vyhadvacieho plnu" +msgid "Manage EPGSearch Search Timers" +msgstr "" -msgid "Search Term" -msgstr "kov slovo" +msgid "No Search Timers Configured" +msgstr "" -msgid "Using Template" -msgstr "ablna" +msgid "Configure Search Timer Options" +msgstr "" -msgid "Display Results for Search Timer" -msgstr "Pozrie vsledky pre vyhadvanie plnov" +msgid "Save Search Timer" +msgstr "" -msgid "Use other Template" -msgstr "Poui in ablnu" +msgid "Search String" +msgstr "" -msgid "Configure Search Timer Options for Search String" -msgstr "Konfigurova monosti plnov pre vyhadvanie kovch slov" - -msgid "whole term must appear" -msgstr "kompletn vraz" - -msgid "all terms must exist" -msgstr "vetky slov" - -msgid "one term must exist" -msgstr "jeden pojem mus existova" - -msgid "exact match" -msgstr "presn zhoda" - -msgid "regular expression" -msgstr "regulrny vraz" +msgid "Active" +msgstr "" msgid "Search Mode" msgstr "Reim vyhadvania" @@ -306,29 +303,68 @@ msgstr "Pou msgid "Limit Channels" msgstr "Obmedzi kanly" +msgid "Use Time" +msgstr "Poui as" + +msgid "Display advanced Options" +msgstr "" + +msgid "Limit Days of the Week" +msgstr "" + +msgid "Time margin for start in minutes" +msgstr "" + +msgid "Time margin for stop in minutes" +msgstr "" + +msgid "Use VPS" +msgstr "" + +msgid "Avoid Repeats" +msgstr "" + +msgid "Hide advanced Options" +msgstr "" + +msgid "Display Results for Search Timer" +msgstr "Pozrie vsledky pre vyhadvanie plnov" + msgid "Start Channel" msgstr "Od kanlu" msgid "Stop Channel" msgstr "Po kanl" -msgid "Use Time" -msgstr "Poui as" - msgid "Start after" msgstr "Zaiatok po" msgid "Start before" msgstr "Zaiatok pred" -msgid "search results for Search Timer" -msgstr "njden vsledky vyhadvania plnu" +msgid "Select Days" +msgstr "" -msgid "search result for Search Timer" -msgstr "njden vsledok vyhadvania plnu" +msgid "Number of allowed repeats" +msgstr "" -msgid "Nothing found for Search String" -msgstr "Hadan vraz sa nenaiel" +msgid "Compare Title" +msgstr "" + +msgid "Compare Subtitle" +msgstr "" + +msgid "Compare Description" +msgstr "" + +msgid "Really delete Search Timer" +msgstr "" + +msgid "Delete only Search Timer" +msgstr "" + +msgid "Delete Search Timer and created Timers" +msgstr "" msgid "Search Timer sucessfully created." msgstr "Vyhadva plnu vytvoren." @@ -339,6 +375,27 @@ msgstr "Vyhlad msgid "Search Timer NOT sucessfully created" msgstr "Vyhadva plnu nie je kompletne vytvoren" +msgid "Creating Search Timer" +msgstr "Vytvorenie vyhadvacieho plnu" + +msgid "Search Term" +msgstr "kov slovo" + +msgid "Using Template" +msgstr "ablna" + +msgid "Use other Template" +msgstr "Poui in ablnu" + +msgid "search results for Search Timer" +msgstr "njden vsledky vyhadvania plnu" + +msgid "search result for Search Timer" +msgstr "njden vsledok vyhadvania plnu" + +msgid "Nothing found for Search String" +msgstr "Hadan vraz sa nenaiel" + msgid "Configure Options for Switchtimer" msgstr "Konfigurova monosti pre prepnac pln" @@ -369,12 +426,6 @@ msgstr "Pl msgid "Switch Timer deleted" msgstr "Pln prepnutia vymazan" -msgid "Show Search Options" -msgstr "Zobrazi monosti vyhadvania" - -msgid "Perform Search" -msgstr "Vykona vyhadvanie" - msgid "Channel to Search" msgstr "Hada na kanle" @@ -387,6 +438,12 @@ msgstr "H msgid "Search in Description" msgstr "Hada v popise" +msgid "Show Search Options" +msgstr "Zobrazi monosti vyhadvania" + +msgid "Perform Search" +msgstr "Vykona vyhadvanie" + msgid "search results for" msgstr "vyhadan vsledky pre" @@ -411,6 +468,21 @@ msgstr "pre" msgid "No recordings found for" msgstr "Nenali sa nahrvky s nzvom " +msgid "whole term must appear" +msgstr "kompletn vraz" + +msgid "all terms must exist" +msgstr "vetky slov" + +msgid "one term must exist" +msgstr "jeden pojem mus existova" + +msgid "exact match" +msgstr "presn zhoda" + +msgid "regular expression" +msgstr "regulrny vraz" + msgid "General Settings" msgstr "Veobecn nastavenia" @@ -648,6 +720,9 @@ msgstr "H msgid "Search & Recording Menu Small Font Size" msgstr "Hada & Nahra menu mal psmo" +msgid "Search & Recording Main Menu Font Size" +msgstr "" + msgid "Create Log Messages for image loading" msgstr "" @@ -677,3 +752,6 @@ msgstr "" msgid "Recording Menus Icon Cache" msgstr "" + +#~ msgid "Configure Search Timer Options for Search String" +#~ msgstr "Konfigurova monosti plnov pre vyhadvanie kovch slov" diff --git a/recmanager.c b/recmanager.c index d366593..d2d54e9 100644 --- a/recmanager.c +++ b/recmanager.c @@ -4,7 +4,6 @@ #include #include -#include "services/epgsearch.h" #include "services/remotetimers.h" #include "services/tvscraper.h" #include "tools.h" @@ -137,6 +136,8 @@ void cRecManager::DeleteTimer(int timerID) { } void cRecManager::DeleteTimer(const cEvent *event) { + if (!event) + return; if (tvguideConfig.useRemoteTimers && pRemoteTimers) { DeleteRemoteTimer(event); } else { @@ -176,16 +177,16 @@ void cRecManager::DeleteRemoteTimer(const cEvent *event) { } } -void cRecManager::SaveTimer(cTimer *timer, cRecMenu *menu) { +void cRecManager::SaveTimer(cTimer *timer, cTimer newTimerSettings) { if (!timer) return; - bool active = menu->GetBoolValue(1); - int prio = menu->GetIntValue(2); - int lifetime = menu->GetIntValue(3); - time_t day = menu->GetTimeValue(4); - int start = menu->GetIntValue(5); - int stop = menu->GetIntValue(6); + bool active = newTimerSettings.HasFlags(tfActive); + int prio = newTimerSettings.Priority(); + int lifetime = newTimerSettings.Lifetime(); + time_t day = newTimerSettings.Day(); + int start = newTimerSettings.Start(); + int stop = newTimerSettings.Stop(); timer->SetDay(day); timer->SetStart(start); @@ -210,6 +211,7 @@ void cRecManager::SaveTimer(cTimer *timer, cRecMenu *menu) { } } + bool cRecManager::IsRecorded(const cEvent *event) { cTimer *timer = Timers.GetMatch(event); if (!timer) @@ -236,57 +238,25 @@ cTVGuideTimerConflicts *cRecManager::CheckTimerConflict(void) { return conflictList; } -cTimer *cRecManager::CreateSeriesTimer(cRecMenu *menu, std::string path) { - bool active = menu->GetBoolValue(1); - int channelNumber = menu->GetIntValue(2); - int start = menu->GetIntValue(3); - int stop = menu->GetIntValue(4); - int weekdays = menu->GetIntValue(5); - time_t tday = menu->GetTimeValue(6); - int prio = menu->GetIntValue(7); - int lifetime = menu->GetIntValue(8); - - cChannel *channel = Channels.GetByNumber(channelNumber); - cTimer *seriesTimer = new cTimer(false, false, channel); - - cString fileName = "TITLE EPISODE"; - if (path.size() > 0) { - std::replace(path.begin(), path.end(), '/', '~'); - fileName = cString::sprintf("%s~%s", path.c_str(), *fileName); - } - - seriesTimer->SetDay(tday); - seriesTimer->SetStart(start); - seriesTimer->SetStop(stop); - seriesTimer->SetPriority(prio); - seriesTimer->SetLifetime(lifetime); - seriesTimer->SetWeekDays(weekdays); - seriesTimer->SetFile(*fileName); - if (active) - seriesTimer->SetFlags(tfActive); - else - seriesTimer->SetFlags(tfNone); +void cRecManager::CreateSeriesTimer(cTimer *seriesTimer) { seriesTimer->SetEventFromSchedule(); - if (tvguideConfig.useRemoteTimers && pRemoteTimers) { RemoteTimers_Timer_v1_0 rt; rt.timer = seriesTimer; if (!pRemoteTimers->Service("RemoteTimers::NewTimer-v1.0", &rt)) isyslog("%s", *rt.errorMsg); RefreshRemoteTimers(); - seriesTimer = NULL; } else { Timers.Add(seriesTimer); Timers.SetModified(); } - return seriesTimer; } -std::vector cRecManager::ReadEPGSearchTemplates(void) { + +void cRecManager::ReadEPGSearchTemplates(std::vector *epgTemplates) { cString ConfigDir = cPlugin::ConfigDirectory("epgsearch"); cString epgsearchConf = "epgsearchtemplates.conf"; cString fileName = AddDirectory(*ConfigDir, *epgsearchConf); - std::vector epgTemplates; if (access(fileName, F_OK) == 0) { FILE *f = fopen(fileName, "r"); if (f) { @@ -307,175 +277,12 @@ std::vector cRecManager::ReadEPGSearchTemplates(void) TVGuideEPGSearchTemplate tmp; tmp.name = name; tmp.templValue = templValue; - epgTemplates.push_back(tmp); + epgTemplates->push_back(tmp); } } catch (...){} } } } - return epgTemplates; -} - -std::string cRecManager::BuildEPGSearchString(cString searchString, std::string templValue) { - std::string strSearchString = *searchString; - std::replace(strSearchString.begin(), strSearchString.end(), ':', '|'); - std::stringstream searchTimerString; - searchTimerString << "0:"; - searchTimerString << strSearchString; - searchTimerString << templValue; - return searchTimerString.str(); -} - -std::string cRecManager::BuildEPGSearchString(cString searchString, cRecMenu *menu) { - std::string strSearchString = *searchString; - std::replace(strSearchString.begin(), strSearchString.end(), ':', '|'); - int searchMode = menu->GetIntValue(0); - bool useTitle = menu->GetBoolValue(1); - bool useSubTitle = menu->GetBoolValue(2); - bool useDescription = menu->GetBoolValue(3); - bool limitChannels = menu->GetBoolValue(4); - int startChannel = -1; - int stopChannel = -1; - if (limitChannels) { - startChannel = menu->GetIntValue(5); - stopChannel = menu->GetIntValue(6); - } - int after = 0; - int before = 0; - bool limitTime = (limitChannels)?menu->GetBoolValue(7):menu->GetBoolValue(5); - if (limitTime) { - after = (limitChannels)?menu->GetIntValue(8):menu->GetIntValue(6); - before = (limitChannels)?menu->GetIntValue(9):menu->GetIntValue(7); - } - - std::stringstream searchTimerString; - //1 - unique search timer id - searchTimerString << "0:"; - //2 - the search term - searchTimerString << strSearchString; - //3 - use time? 0/1 - //4 - start time in HHMM - //5 - stop time in HHMM - if (limitTime) { - searchTimerString << ":1:" << after << ":" << before << ":"; - } else { - searchTimerString << ":0:::"; - } - //6 - use channel? 0 = no, 1 = Interval, 2 = Channel group, 3 = FTA only - //7 - if 'use channel' = 1 then channel id[|channel id] in VDR format, - // one entry or min/max entry separated with |, if 'use channel' = 2 - // then the channel group name - if (limitChannels) { - searchTimerString << "1:"; - cChannel *startChan = Channels.GetByNumber(startChannel); - cChannel *stopChan = Channels.GetByNumber(stopChannel); - searchTimerString << *(startChan->GetChannelID().ToString()); - searchTimerString << "|"; - searchTimerString << *(stopChan->GetChannelID().ToString()) << ":"; - } else { - searchTimerString << "0::"; - } - //8 - match case? 0/1 - searchTimerString << ":0"; - /*9 - search mode: - 0 - the whole term must appear as substring - 1 - all single terms (delimiters are blank,',', ';', '|' or '~') - must exist as substrings. - 2 - at least one term (delimiters are blank, ',', ';', '|' or '~') - must exist as substring. - 3 - matches exactly - 4 - regular expression */ - searchTimerString << searchMode << ":"; - //10 - use title? 0/1 - if (useTitle) - searchTimerString << "1:"; - else - searchTimerString << "0:"; - //11 - use subtitle? 0/1 - if (useSubTitle) - searchTimerString << "1:"; - else - searchTimerString << "0:"; - // 12 - use description? 0/1 - if (useDescription) - searchTimerString << "1:"; - else - searchTimerString << "0:"; - //13 - use duration? 0/1 - //14 - min duration in hhmm - //15 - max duration in hhmm - searchTimerString << "0:::"; - //16 - use as search timer? 0/1 - searchTimerString << "1:"; - //17 - use day of week? 0/1 - //18 - day of week (0 = Sunday, 1 = Monday...; - // -1 Sunday, -2 Monday, -4 Tuesday, ...; -7 Sun, Mon, Tue) - searchTimerString << "0::"; - //19 - use series recording? 0/1 - searchTimerString << "1:"; - //20 - directory for recording - searchTimerString << ":"; - //21 - priority of recording - //22 - lifetime of recording - searchTimerString << "99:99:"; - //23 - time margin for start in minutes - //24 - time margin for stop in minutes - searchTimerString << "5:5:"; - //25 - use VPS? 0/1 - searchTimerString << "0:"; - /*26 - action: - 0 = create a timer - 1 = announce only via OSD (no timer) - 2 = switch only (no timer) - 3 = announce via OSD and switch (no timer) - 4 = announce via mail*/ - searchTimerString << "0:"; - /*27 - use extended EPG info? 0/1 - 28 - extended EPG info values. This entry has the following format - (delimiter is '|' for each category, '#' separates id and value): - 1 - the id of the extended EPG info category as specified in - epgsearchcats.conf - 2 - the value of the extended EPG info category - (a ':' will be translated to "!^colon^!", e.g. in "16:9") */ - searchTimerString << "0::"; - /*29 - avoid repeats? 0/1 - 30 - allowed repeats - 31 - compare title when testing for a repeat? 0/1 - 32 - compare subtitle when testing for a repeat? 0/1/2 - 0 - no - 1 - yes - 2 - yes, if present - 33 - compare description when testing for a repeat? 0/1 - 34 - compare extended EPG info when testing for a repeat? - This entry is a bit field of the category IDs. - 35 - accepts repeats only within x days */ - searchTimerString << "1:1:1:2:1:::"; - /*36 - delete a recording automatically after x days - 37 - but keep this number of recordings anyway - 38 - minutes before switch (if action = 2) - 39 - pause if x recordings already exist - 40 - blacklist usage mode (0 none, 1 selection, 2 all) - 41 - selected blacklist IDs separated with '|' - 42 - fuzzy tolerance value for fuzzy searching - 43 - use this search in favorites menu (0 no, 1 yes) - 44 - id of a menu search template - 45 - auto deletion mode (0 don't delete search timer, 1 delete after given - count of recordings, 2 delete after given days after first recording) - 46 - count of recordings after which to delete the search timer - 47 - count of days after the first recording after which to delete the search - timer - 48 - first day where the search timer is active (see parameter 16) - 49 - last day where the search timer is active (see parameter 16) - 50 - ignore missing EPG categories? 0/1 - 51 - unmute sound if off when used as switch timer - 52 - percentage of match when comparing the summary of two events (with 'avoid repeats') - 53 - HEX representation of the content descriptors, each descriptor ID is represented with 2 chars - 54 - compare date when testing for a repeat? (0=no, 1=same day, 2=same week, 3=same month) */ - searchTimerString << "0::::0:::0::0:::::::::0"; - - //esyslog("tvguide: epgsearch String: %s", searchTimerString.str().c_str()); - - return searchTimerString.str(); } const cEvent **cRecManager::PerformSearchTimerSearch(std::string epgSearchString, int &numResults) { @@ -519,29 +326,8 @@ const cEvent **cRecManager::PerformSearchTimerSearch(std::string epgSearchString return searchResults; } -const cEvent **cRecManager::PerformSearch(cRecMenu *menu, bool withOptions, int &numResults) { +const cEvent **cRecManager::PerformSearch(Epgsearch_searchresults_v1_0 data, int &numResults) { if (epgSearchAvailable) { - cString searchString = menu->GetStringValue(1); - Epgsearch_searchresults_v1_0 data; - data.query = (char *)*searchString; - int mode = 0; - int channelNr = 0; - bool useTitle = true; - bool useSubTitle = true; - bool useDescription = false; - if (withOptions) { - mode = menu->GetIntValue(2); - channelNr = menu->GetIntValue(3); - useTitle = menu->GetBoolValue(4); - useSubTitle = menu->GetBoolValue(5); - useDescription = menu->GetBoolValue(6); - } - data.mode = mode; - data.channelNr = channelNr; - data.useTitle = useTitle; - data.useSubTitle = useSubTitle; - data.useDescription = useDescription; - if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) { cList *list = data.pResultList; if (!list) @@ -564,6 +350,23 @@ const cEvent **cRecManager::PerformSearch(cRecMenu *menu, bool withOptions, int return NULL; } +void cRecManager::GetSearchTimers(std::vector *searchTimer) { + if (!epgSearchAvailable) { + return; + } + Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1; + if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) { + std::list searchTimerList; + searchTimerList = epgSearch->handler->SearchTimerList(); + for(std::list::iterator it = searchTimerList.begin(); it != searchTimerList.end(); it++) { + cTVGuideSearchTimer timer; + timer.SetEPGSearchString(it->c_str()); + if (timer.Parse()) + searchTimer->push_back(timer); + } + } +} + int cRecManager::CreateSearchTimer(std::string epgSearchString) { int timerID = -1; if (!epgSearchAvailable) @@ -575,6 +378,73 @@ int cRecManager::CreateSearchTimer(std::string epgSearchString) { return timerID; } +bool cRecManager::SaveSearchTimer(cTVGuideSearchTimer *searchTimer) { + if (!epgSearchAvailable) + return false; + Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1; + if (searchTimer->GetID() > -1) { + if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) { + bool success = epgSearch->handler->ModSearchTimer(searchTimer->BuildSearchString()); + if (success) { + esyslog("tvguide: search timer with id %d sucessfully modified", searchTimer->GetID()); + return true; + } else { + esyslog("tvguide: error modifying search timer with id %d, build string %s", searchTimer->GetID(), searchTimer->BuildSearchString().c_str()); + return false; + } + } + } else { + if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) { + int timerID = epgSearch->handler->AddSearchTimer(searchTimer->BuildSearchString()); + if (timerID >=0) { + esyslog("tvguide: search timer with id %d sucessfully created", timerID); + return true; + } else { + esyslog("tvguide: error creating search timer, build string %s", searchTimer->BuildSearchString().c_str()); + return false; + } + } + } + return false; +} + +void cRecManager::DeleteSearchTimer(cTVGuideSearchTimer *searchTimer, bool delTimers) { + if (!epgSearchAvailable) + return; + int searchTimerID = searchTimer->GetID(); + if (delTimers) { + cTimer *timer = Timers.First(); + while(timer) { + if (!timer->Recording()) { + char* searchID = GetAuxValue(timer, "s-id"); + if (searchID) { + if (searchTimerID == atoi(searchID)) { + cTimer* timerNext = Timers.Next(timer); + DeleteTimer(timer); + timer = timerNext; + } else { + timer = Timers.Next(timer); + } + free(searchID); + } else { + timer = Timers.Next(timer); + } + } else { + timer = Timers.Next(timer); + } + } + } + Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1; + if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) { + bool success = epgSearch->handler->DelSearchTimer(searchTimerID); + if (success) { + esyslog("tvguide: search timer \"%s\" sucessfully deleted", searchTimer->SearchString().c_str()); + } else { + esyslog("tvguide: error deleting search timer \"%s\"", searchTimer->SearchString().c_str()); + } + } +} + void cRecManager::UpdateSearchTimers(void) { if (epgSearchAvailable) { Epgsearch_updatesearchtimers_v1_0 data; @@ -584,15 +454,13 @@ void cRecManager::UpdateSearchTimers(void) { } // announceOnly: 0 = switch, 1 = announce only, 2 = ask for switch -bool cRecManager::CreateSwitchTimer(const cEvent *event, cRecMenu *menu) { - int switchMinsBefore = menu->GetIntValue(1); - int announceOnly = menu->GetIntValue(2); - if (epgSearchAvailable) { +bool cRecManager::CreateSwitchTimer(const cEvent *event, cSwitchTimer switchTimer) { + if (epgSearchAvailable && event) { Epgsearch_switchtimer_v1_0 data; data.event = event; data.mode = 1; - data.switchMinsBefore = switchMinsBefore; - data.announceOnly = announceOnly; + data.switchMinsBefore = switchTimer.switchMinsBefore; + data.announceOnly = switchTimer.switchMinsBefore; data.success = false; epgSearchPlugin->Service("Epgsearch-switchtimer-v1.0", &data); cSwitchTimer *t = new cSwitchTimer(event); @@ -615,7 +483,7 @@ void cRecManager::DeleteSwitchTimer(const cEvent *event) { } } -cRecording **cRecManager::SearchForRecordings(cString searchString, int &numResults) { +cRecording **cRecManager::SearchForRecordings(std::string searchString, int &numResults) { cRecording **matchingRecordings = NULL; int num = 0; @@ -623,7 +491,7 @@ cRecording **cRecManager::SearchForRecordings(cString searchString, int &numResu for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { std::string s1 = recording->Name(); - std::string s2 = *searchString; + std::string s2 = searchString; if (s1.empty() || s2.empty()) continue; // tolerance for fuzzy searching: 90% of the shorter text length, but at least 1 diff --git a/recmanager.h b/recmanager.h index 7701cc6..55d71f2 100644 --- a/recmanager.h +++ b/recmanager.h @@ -4,8 +4,11 @@ #include #include #include +#include "services/epgsearch.h" #include "detailview.h" #include "recmenu.h" +#include "searchtimer.h" +#include "switchtimer.h" #include "timerconflict.h" struct TVGuideEPGSearchTemplate { @@ -19,36 +22,37 @@ class cRecManager { private: cPlugin *epgSearchPlugin; bool epgSearchAvailable; - void DeleteTimer(cTimer *timer); public: - cRecManager (void); + cRecManager(void); void SetEPGSearchPlugin(void); bool EpgSearchAvailable(void) {return epgSearchAvailable;}; bool RefreshRemoteTimers(void); bool CheckEventForTimer(const cEvent *event); cTimer *GetTimerForEvent(const cEvent *event); - cTimer *createTimer(const cEvent *event, std::string path); + cTimer *createTimer(const cEvent *event, std::string path = ""); cTimer *createLocalTimer(const cEvent *event, std::string path); cTimer *createRemoteTimer(const cEvent *event, std::string path); void SetTimerPath(cTimer *timer, const cEvent *event, std::string path); + void DeleteTimer(cTimer *timer); void DeleteTimer(int timerID); void DeleteTimer(const cEvent *event); void DeleteLocalTimer(const cEvent *event); void DeleteRemoteTimer(const cEvent *event); - void SaveTimer(cTimer *timer, cRecMenu *menu); + void SaveTimer(cTimer *timer, cTimer newTimerSettings); bool IsRecorded(const cEvent *event); cTVGuideTimerConflicts *CheckTimerConflict(void); - cTimer *CreateSeriesTimer(cRecMenu *menu, std::string path); - std::string BuildEPGSearchString(cString searchString, cRecMenu *menu); - std::string BuildEPGSearchString(cString searchString, std::string templValue); + void CreateSeriesTimer(cTimer *seriesTimer); const cEvent **PerformSearchTimerSearch(std::string epgSearchString, int &numResults); - const cEvent **PerformSearch(cRecMenu *menu, bool withOptions, int &numResults); - std::vector ReadEPGSearchTemplates(void); + const cEvent **PerformSearch(Epgsearch_searchresults_v1_0 data, int &numResults); + void ReadEPGSearchTemplates(std::vector *epgTemplates); + void GetSearchTimers(std::vector *timers); int CreateSearchTimer(std::string epgSearchString); + bool SaveSearchTimer(cTVGuideSearchTimer *searchTimer); + void DeleteSearchTimer(cTVGuideSearchTimer *searchTimer, bool delTimers); void UpdateSearchTimers(void); - bool CreateSwitchTimer(const cEvent *event, cRecMenu *menu); + bool CreateSwitchTimer(const cEvent *event, cSwitchTimer switchTimer); void DeleteSwitchTimer(const cEvent *event); - cRecording **SearchForRecordings(cString searchString, int &numResults); + cRecording **SearchForRecordings(std::string searchString, int &numResults); const cEvent **LoadReruns(const cEvent *event, int &numResults); virtual ~cRecManager (void); }; diff --git a/recmenu.c b/recmenu.c index 0dc1606..7f782e9 100644 --- a/recmenu.c +++ b/recmenu.c @@ -1,3 +1,4 @@ +#include #include "recmenu.h" // --- cRecMenu ------------------------------------------------------------- @@ -7,8 +8,8 @@ cRecMenu::cRecMenu(void) { height = 2*border; headerHeight = 0; footerHeight = 0; - scrollHeight = 0; - scrollItemHeight = 0; + currentHeight = 0; + deleteMenuItems = true; scrollable = false; scrollbarWidth = 3 * border; pixmapScrollBar = NULL; @@ -23,7 +24,7 @@ cRecMenu::cRecMenu(void) { cRecMenu::~cRecMenu(void) { if (header) delete header; - menuItems.Clear(); + ClearMenuItems(); if (footer) delete footer; if (pixmapScrollBar) @@ -44,70 +45,49 @@ void cRecMenu::SetWidthPixel(int pixel) { int cRecMenu::CalculateOptimalWidth(void) { int optWidth = 0; - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - int itemWidth = item->GetWidth(); + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + int itemWidth = (*item)->GetWidth(); if (itemWidth > optWidth) optWidth = itemWidth; } return optWidth; } - -void cRecMenu::AddMenuItem(cRecMenuItem *item, cRecMenuItem *before) { - if (!before) - menuItems.Add(item); - else - menuItems.Ins(item, before); -} - -void cRecMenu::AddMenuItemScroll(cRecMenuItem *item) { - scrollHeight += item->GetHeight(); - stopIndex++; - numItems++; - if (scrollItemHeight == 0) - scrollItemHeight = item->GetHeight(); - menuItems.Add(item); -} - -bool cRecMenu::CheckHeight(void) { - int nextHeight = headerHeight + footerHeight + scrollHeight + 2*border + 150; - if (nextHeight > geoManager.osdHeight) { - scrollable = true; - return false; - } - return true; -} - -void cRecMenu::CalculateHeight(void) { - height = 2*border; +bool cRecMenu::CalculateHeight(bool reDraw) { + int newHeight = 2*border; if (header) - height += headerHeight; - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - height += item->GetHeight(); + newHeight += headerHeight; + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + newHeight += (*item)->GetHeight(); } if (footer) - height += footerHeight; - y = (geoManager.osdHeight - height) / 2; - - if (scrollable) { - width += scrollbarWidth + border; + newHeight += footerHeight; + + y = (geoManager.osdHeight - newHeight) / 2; + + if (newHeight != height) { + height = newHeight; + if (scrollable && !reDraw) { + width += scrollbarWidth + border; + } + return true; } + return false; } void cRecMenu::CreatePixmap(void) { + if (pixmap) + osdManager.releasePixmap(pixmap); pixmap = osdManager.requestPixmap(3, cRect(x, y, width, height)); if (scrollable) { int scrollBarX = x + width - scrollbarWidth - border; int scrollBarY = y + border + headerHeight; int scrollBarHeight = height - headerHeight - footerHeight - 2 * border; + if (pixmapScrollBar) + osdManager.releasePixmap(pixmapScrollBar); pixmapScrollBar = osdManager.requestPixmap(4, cRect(scrollBarX, scrollBarY, scrollbarWidth, scrollBarHeight)); - } -} - -void cRecMenu::SetFooter(cRecMenuItem *footer) { - this->footer = footer; - footerHeight = footer->GetHeight(); - height += footerHeight; + } else + pixmapScrollBar = NULL; } void cRecMenu::SetHeader(cRecMenuItem *header) { @@ -116,39 +96,105 @@ void cRecMenu::SetHeader(cRecMenuItem *header) { height += headerHeight; } -cRecMenuItem *cRecMenu::GetActiveMenuItem(void) { - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - if (item->isActive()) - return item; - } - if (footer && footer->isActive()) - return footer; - return NULL; +void cRecMenu::SetFooter(cRecMenuItem *footer) { + this->footer = footer; + footerHeight = footer->GetHeight(); + height += footerHeight; } -int cRecMenu::GetActive(bool withOffset) { - int numActive = withOffset?startIndex:0; - int i = 0; - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - if (item->isActive()) { - numActive += i; - break; +void cRecMenu::ClearMenuItems(void) { + if (deleteMenuItems) { + for (std::list::iterator it = menuItems.begin(); it != menuItems.end(); it++) { + delete *it; } - i++; } - return numActive; + menuItems.clear(); +}; + +void cRecMenu::InitMenu(bool complete) { + currentHeight = 0; + numItems = 0; + if (scrollable) { + width -= scrollbarWidth + border; + osdManager.releasePixmap(pixmapScrollBar); + pixmapScrollBar = NULL; + delete imgScrollBar; + imgScrollBar = NULL; + } + osdManager.releasePixmap(pixmap); + pixmap = NULL; + for (std::list::iterator it = menuItems.begin(); it != menuItems.end(); it++) { + if (deleteMenuItems) + delete *it; + else + (*it)->Hide(); + } + menuItems.clear(); + if (complete) { + startIndex = 0; + stopIndex = 0; + scrollable = false; + } else { + stopIndex = startIndex; + } + +} + + +void cRecMenu::AddMenuItem(cRecMenuItem *item, bool inFront) { + if (!inFront) + menuItems.push_back(item); + else + menuItems.push_front(item); +} + +bool cRecMenu::AddMenuItemInitial(cRecMenuItem *item) { + currentHeight += item->GetHeight(); + int totalHeight = headerHeight + footerHeight + currentHeight + 2*border; + if (totalHeight >= geoManager.osdHeight) { + scrollable = true; + currentHeight -= item->GetHeight(); + if (deleteMenuItems) { + delete item; + } + return false; + } + stopIndex++; + numItems++; + menuItems.push_back(item); + return true; +} + +void cRecMenu::Activate(cRecMenuItem *itemOld, cRecMenuItem *item) { + itemOld->setInactive(); + itemOld->setBackground(); + itemOld->Draw(); + item->setActive(); + item->setBackground(); + item->Draw(); } bool cRecMenu::ActivatePrev(void) { cRecMenuItem *activeItem = GetActiveMenuItem(); if (!scrollable && footer && footer->isActive()) { - Activate(footer, menuItems.Last()); - return true; + if (menuItems.size() > 0) { + cRecMenuItem *itemLast = menuItems.back(); + Activate(footer, itemLast); + return true; + } } else if (activeItem) { cRecMenuItem *prev = NULL; - for (cRecMenuItem *item = menuItems.Prev(activeItem); item; item = menuItems.Prev(item)) { - if (item->isSelectable()) { - prev = item; + bool foundActive = false; + for (std::list::iterator item = menuItems.end(); item != menuItems.begin(); ) { + item--; + if (*item == activeItem) { + foundActive = true; + continue; + } + if (!foundActive) + continue; + if ((*item)->isSelectable()) { + prev = *item; break; } } @@ -160,13 +206,56 @@ bool cRecMenu::ActivatePrev(void) { return false; } +void cRecMenu::ScrollUp(void) { + if (footer && footer->isActive()) { + if (menuItems.size() > 0) + Activate(footer, menuItems.back()); + } else { + //get perv x items + int numNewItems = numItems / 2; + int numAdded = 0; + cRecMenuItem *newItem = NULL; + while (newItem = GetMenuItem(startIndex-1)) { + AddMenuItem(newItem, true); + cRecMenuItem *last = menuItems.back(); + if (deleteMenuItems) { + delete last; + } else { + last->setInactive(); + last->Hide(); + } + menuItems.pop_back(); + stopIndex--; + startIndex--; + numAdded++; + if (numAdded >= numNewItems) + break; + } + if (numAdded != 0) { + scrollable = true; + if (CalculateHeight(true)) + CreatePixmap(); + Arrange(deleteMenuItems); + Display(deleteMenuItems); + ActivatePrev(); + } + } +} + bool cRecMenu::ActivateNext(void) { cRecMenuItem *activeItem = GetActiveMenuItem(); if (activeItem) { cRecMenuItem *next = NULL; - for (cRecMenuItem *item = menuItems.Next(activeItem); item; item = menuItems.Next(item)) { - if (item->isSelectable()) { - next = item; + bool foundActive = false; + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + if (*item == activeItem) { + foundActive = true; + continue; + } + if (!foundActive) + continue; + if ((*item)->isSelectable()) { + next = *item; break; } } @@ -181,57 +270,33 @@ bool cRecMenu::ActivateNext(void) { return false; } -void cRecMenu::Activate(cRecMenuItem *itemOld, cRecMenuItem *item) { - itemOld->setInactive(); - itemOld->setBackground(); - itemOld->Draw(); - item->setActive(); - item->setBackground(); - item->Draw(); -} - -void cRecMenu::ScrollUp(void) { - if (footer && footer->isActive()) { - Activate(footer, menuItems.Last()); - } else { - //get perv x items - int numNewItems = numItems / 2; - int numAdded = 0; - cRecMenuItem *newItem = NULL; - while (newItem = GetMenuItem(startIndex-1)) { - AddMenuItem(newItem, menuItems.First()); - menuItems.Del(menuItems.Last(), true); - stopIndex--; - startIndex--; - numAdded++; - if (numAdded >= numNewItems) - break; - } - if (numAdded != 0) { - Arrange(true); - Display(true); - ActivatePrev(); - } - } -} - void cRecMenu::ScrollDown(void) { //get next x items int numNewItems = numItems / 2; int numAdded = 0; cRecMenuItem *newItem = NULL; while (newItem = GetMenuItem(stopIndex)) { - menuItems.Add(newItem); - menuItems.Del(menuItems.First(), true); - stopIndex++; + menuItems.push_back(newItem); + cRecMenuItem *first = menuItems.front(); + if (deleteMenuItems) { + delete first; + } else { + first->setInactive(); + first->Hide(); + } + menuItems.pop_front(); startIndex++; + stopIndex++; numAdded++; if (numAdded >= numNewItems) break; } if (numAdded != 0) { - Arrange(true); - Display(true); + scrollable = true; + if (CalculateHeight(true)) + CreatePixmap(); + Arrange(deleteMenuItems); + Display(deleteMenuItems); ActivateNext(); } else { //last item reached, activate footer @@ -246,9 +311,9 @@ void cRecMenu::JumpBegin(void) { cRecMenuItem *activeItem = GetActiveMenuItem(); if (!scrollable) { cRecMenuItem *firstSelectable= NULL; - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - if (item->isSelectable()) { - firstSelectable = item; + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + if ((*item)->isSelectable()) { + firstSelectable = *item; break; } } @@ -260,7 +325,7 @@ void cRecMenu::JumpBegin(void) { activeItem->setBackground(); if (footer) footer->Draw(); - menuItems.Clear(); + ClearMenuItems(); int currentItem = 0; cRecMenuItem *newItem = NULL; while (newItem = GetMenuItem(currentItem)) { @@ -272,9 +337,10 @@ void cRecMenu::JumpBegin(void) { Arrange(true); startIndex = 0; stopIndex = numItems-1; - menuItems.First()->setActive(); - menuItems.First()->setBackground(); - menuItems.First()->Draw(); + cRecMenuItem *first = menuItems.front(); + first->setActive(); + first->setBackground(); + first->Draw(); Display(true); } } @@ -288,9 +354,10 @@ void cRecMenu::JumpEnd(void) { if (footer && footer->isSelectable()) { lastSelectable = footer; } else { - for (cRecMenuItem *item = menuItems.Last(); item; item = menuItems.Prev(item)) { - if (item->isSelectable()) { - lastSelectable = item; + for (std::list::iterator item = menuItems.end(); item != menuItems.begin(); ) { + item--; + if ((*item)->isSelectable()) { + lastSelectable = *item; break; } } @@ -301,13 +368,13 @@ void cRecMenu::JumpEnd(void) { } else { activeItem->setInactive(); activeItem->setBackground(); - menuItems.Clear(); + ClearMenuItems(); int totalNumItems = GetTotalNumMenuItems(); int currentItem = totalNumItems-1; int itemsAdded = 0; cRecMenuItem *newItem = NULL; while (newItem = GetMenuItem(currentItem)) { - AddMenuItem(newItem, menuItems.First()); + AddMenuItem(newItem, true); currentItem--; itemsAdded++; if (itemsAdded >= numItems) @@ -321,9 +388,10 @@ void cRecMenu::JumpEnd(void) { footer->setBackground(); footer->Draw(); } else { - menuItems.Last()->setActive(); - menuItems.Last()->setBackground(); - menuItems.Last()->Draw(); + cRecMenuItem *last = menuItems.back(); + last->setActive(); + last->setBackground(); + last->Draw(); } Display(true); } @@ -344,10 +412,10 @@ void cRecMenu::Arrange(bool scroll) { } yElement += header->GetHeight(); } - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - item->SetGeometry(xElement, yElement, widthElement); - item->SetPixmaps(); - yElement += item->GetHeight(); + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + (*item)->SetGeometry(xElement, yElement, widthElement); + (*item)->SetPixmaps(); + yElement += (*item)->GetHeight(); } if (footer && !scroll) { footer->SetGeometry(xElement, yElement, widthElement); @@ -367,9 +435,10 @@ void cRecMenu::Display(bool scroll) { header->setBackground(); header->Draw(); } - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - item->setBackground(); - item->Draw(); + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + (*item)->setBackground(); + (*item)->Show(); + (*item)->Draw(); } if (footer && !scroll) { footer->setBackground(); @@ -387,8 +456,8 @@ void cRecMenu::Hide(void) { header->Hide(); if (footer) footer->Hide(); - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - item->Hide(); + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + (*item)->Hide(); } } @@ -400,8 +469,8 @@ void cRecMenu::Show(void) { header->Show(); if (footer) footer->Show(); - for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { - item->Show(); + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + (*item)->Show(); } } @@ -418,58 +487,35 @@ void cRecMenu::DrawScrollBar(void) { pixmapScrollBar->DrawImage(cPoint(4, 2 + offset), *imgScrollBar); } -int cRecMenu::GetIntValue(int itemNumber) { - cRecMenuItem *item = NULL; - item = menuItems.Get(itemNumber); - if (item) { - return item->GetIntValue(); +cRecMenuItem *cRecMenu::GetActiveMenuItem(void) { + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + if ((*item)->isActive()) + return *item; } - return -1; + if (footer && footer->isActive()) + return footer; + return NULL; } -time_t cRecMenu::GetTimeValue(int itemNumber) { - cRecMenuItem *item = NULL; - item = menuItems.Get(itemNumber); - if (item) { - return item->GetTimeValue(); - } - return 0; -} - -bool cRecMenu::GetBoolValue(int itemNumber) { - cRecMenuItem *item = NULL; - item = menuItems.Get(itemNumber); - if (item) { - return item->GetBoolValue(); - } - return false; -} - -cString cRecMenu::GetStringValue(int itemNumber) { - cRecMenuItem *item = NULL; - item = menuItems.Get(itemNumber); - if (item) { - return item->GetStringValue(); - } - return cString(""); -} - -const cEvent *cRecMenu::GetEventValue(int itemNumber) { - cRecMenuItem *item = NULL; - item = menuItems.Get(itemNumber); - if (item) { - return item->GetEventValue(); +cRecMenuItem *cRecMenu::GetMenuItemAt(int num) { + int current = 0; + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + if (current == num) + return *item; + current++; } return NULL; } -cTimer *cRecMenu::GetTimerValue(int itemNumber) { - cRecMenuItem *item = NULL; - item = menuItems.Get(itemNumber); - if (item) { - return item->GetTimerValue(); +int cRecMenu::GetActive(void) { + int numActive = startIndex; + for (std::list::iterator item = menuItems.begin(); item != menuItems.end(); item++) { + if ((*item)->isActive()) { + break; + } + numActive++; } - return NULL; + return numActive; } eRecMenuState cRecMenu::ProcessKey(eKeys Key) { @@ -485,12 +531,12 @@ eRecMenuState cRecMenu::ProcessKey(eKeys Key) { } else if (state == rmsNotConsumed) { switch (Key & ~k_Repeat) { case kUp: - if (!ActivatePrev() && scrollable) + if (!ActivatePrev()) ScrollUp(); state = rmsConsumed; break; case kDown: - if (!ActivateNext() && scrollable) + if (!ActivateNext()) ScrollDown(); state = rmsConsumed; break; diff --git a/recmenu.h b/recmenu.h index 8613780..99bf69c 100644 --- a/recmenu.h +++ b/recmenu.h @@ -6,59 +6,58 @@ // --- cRecMenu ------------------------------------------------------------- class cRecMenu : public cStyledPixmap { -protected: - int x, y; - int width, height; - int headerHeight, footerHeight; - int scrollHeight; - int scrollItemHeight; +private: + std::list menuItems; int scrollbarWidth; - cPixmap *pixmapScrollBar; - cImage *imgScrollBar; - int border; - bool scrollable; int numItems; int startIndex, stopIndex; - cRecMenuItem *header; - cRecMenuItem *footer; - cList menuItems; - void SetWidthPercent(int percentOSDWidth); - void SetWidthPixel(int pixel); - int CalculateOptimalWidth(void); - bool CheckHeight(void); - void CalculateHeight(void); - void CreatePixmap(void); - void SetHeader(cRecMenuItem *header); - void SetFooter(cRecMenuItem *footer); - void AddMenuItemScroll(cRecMenuItem *item); - void AddMenuItem(cRecMenuItem *item, cRecMenuItem *before = NULL); - cRecMenuItem *GetActiveMenuItem(void); + void Activate(cRecMenuItem *itemOld, cRecMenuItem *item); bool ActivateNext(void); bool ActivatePrev(void); - void Activate(cRecMenuItem *itemOld, cRecMenuItem *item); void ScrollUp(void); void ScrollDown(void); void JumpBegin(void); void JumpEnd(void); +protected: + int x, y; + int width, height; + int headerHeight, footerHeight; + int currentHeight; + bool deleteMenuItems; + cPixmap *pixmapScrollBar; + cImage *imgScrollBar; + int border; + bool scrollable; + cRecMenuItem *header; + cRecMenuItem *footer; + void SetWidthPercent(int percentOSDWidth); + void SetWidthPixel(int pixel); + int CalculateOptimalWidth(void); + bool CalculateHeight(bool reDraw = false); + void CreatePixmap(void); + void SetHeader(cRecMenuItem *header); + void SetFooter(cRecMenuItem *footer); + void ClearMenuItems(void); + void InitMenu(bool complete); + bool AddMenuItemInitial(cRecMenuItem *item); + void AddMenuItem(cRecMenuItem *item, bool inFront = false); void DrawScrollBar(void); cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend); void Arrange(bool scroll = false); virtual cRecMenuItem *GetMenuItem(int number) { return NULL; }; + cRecMenuItem *GetActiveMenuItem(void); + cRecMenuItem *GetMenuItemAt(int num); + int GetCurrentNumMenuItems(void) { return menuItems.size(); }; virtual int GetTotalNumMenuItems(void) { return 0; }; virtual void CreateMenuItems(void) {}; + int GetStartIndex(void) { return startIndex; }; + int GetActive(void); public: cRecMenu(void); virtual ~cRecMenu(void); void Display(bool scroll = false); void Hide(void); void Show(void); - int GetActive(bool withOffset); - int GetIntValue(int itemNumber); - time_t GetTimeValue(int itemNumber); - bool GetBoolValue(int itemNumber); - cString GetStringValue(int itemNumber); - const cEvent *GetEventValue(int itemNumber); - cTimer *GetTimerValue(int itemNumber); virtual eRecMenuState ProcessKey(eKeys Key); }; #endif //__TVGUIDE_RECMENU_H \ No newline at end of file diff --git a/recmenuitem.c b/recmenuitem.c index a534e62..9770c08 100644 --- a/recmenuitem.c +++ b/recmenuitem.c @@ -3,6 +3,7 @@ #include "imageloader.h" #include "imagecache.h" #include "tools.h" +#include "recmenus.h" #include "recmenuitem.h" // --- cRecMenuItem ------------------------------------------------------------- @@ -14,6 +15,7 @@ cRecMenuItem::cRecMenuItem(void) { drawn = false; font = fontManager.FontRecMenuItem; fontSmall = fontManager.FontRecMenuItemSmall; + fontLarge = fontManager.FontRecMenuItemLarge; } cRecMenuItem::~cRecMenuItem(void) { @@ -60,12 +62,13 @@ void cRecMenuItem::setBackground(void) { // --- cRecMenuItemButton ------------------------------------------------------- -cRecMenuItemButton::cRecMenuItemButton(const char *text, eRecMenuState action, bool active, bool halfWidth, bool alignLeft) { +cRecMenuItemButton::cRecMenuItemButton(const char *text, eRecMenuState action, bool active, bool halfWidth, bool alignLeft, bool largeFont) { selectable = true; this->text = text; this->action = action; this->active = active; - height = 3 * font->Height() / 2; + fontButtons = (largeFont)?fontLarge:font; + height = 3 * fontButtons->Height() / 2; this->halfWidth = halfWidth; this->alignLeft = alignLeft; } @@ -74,7 +77,7 @@ cRecMenuItemButton::~cRecMenuItemButton(void) { } int cRecMenuItemButton::GetWidth(void) { - return font->Width(*text); + return fontButtons->Width(*text); } void cRecMenuItemButton::SetPixmaps(void) { @@ -89,13 +92,13 @@ void cRecMenuItemButton::SetPixmaps(void) { } void cRecMenuItemButton::Draw(void) { - int y = (height - font->Height()) / 2; + int y = (height - fontButtons->Height()) / 2; int x; if (!alignLeft) - x = (width - font->Width(*text)) / 2; + x = (width - fontButtons->Width(*text)) / 2; else x = 10; - pixmap->DrawText(cPoint(x, y), *text, colorText, colorTextBack, font); + pixmap->DrawText(cPoint(x, y), *text, colorText, colorTextBack, fontButtons); } eRecMenuState cRecMenuItemButton::ProcessKey(eKeys Key) { @@ -141,8 +144,8 @@ void cRecMenuItemButtonYesNo::SetPixmaps(void) { pixmap = osdManager.requestPixmap(4, cRect(yesX, yPixmaps, buttonWidth, height)); pixmapNo = new cStyledPixmap(osdManager.requestPixmap(4, cRect(noX, yPixmaps, buttonWidth, height))); } else { - pixmap->SetViewPort(cRect(x, yPixmaps, width, height)); - pixmapNo->SetViewPort(cRect(x, yPixmaps, width, height)); + pixmap->SetViewPort(cRect(yesX, yPixmaps, buttonWidth, height)); + pixmapNo->SetViewPort(cRect(noX, yPixmaps, buttonWidth, height)); } } @@ -279,13 +282,17 @@ cRecMenuItemInt::cRecMenuItemInt(cString text, int initialVal, int minVal, int maxVal, - bool active) { + bool active, + int *callback, + eRecMenuState action) { selectable = true; this->text = text; this->currentVal = initialVal; this->minVal = minVal; this->maxVal = maxVal; this->active = active; + this->callback = callback; + this->action = action; height = 3 * font->Height() / 2; pixmapVal = NULL; fresh = true; @@ -342,6 +349,8 @@ eRecMenuState cRecMenuItemInt::ProcessKey(eKeys Key) { fresh = true; if (currentVal > minVal) { currentVal--; + if (callback) + *callback = currentVal; DrawValue(); } return rmsConsumed; @@ -350,6 +359,8 @@ eRecMenuState cRecMenuItemInt::ProcessKey(eKeys Key) { fresh = true; if (currentVal < maxVal) { currentVal++; + if (callback) + *callback = currentVal; DrawValue(); } return rmsConsumed; @@ -362,9 +373,13 @@ eRecMenuState cRecMenuItemInt::ProcessKey(eKeys Key) { currentVal = currentVal * 10 + (Key - k0); if (!((currentVal >= minVal) && (currentVal <= maxVal))) currentVal = oldValue; + if (callback) + *callback = currentVal; DrawValue(); return rmsConsumed; break; + case kOk: + return action; default: break; } @@ -375,12 +390,16 @@ eRecMenuState cRecMenuItemInt::ProcessKey(eKeys Key) { cRecMenuItemBool::cRecMenuItemBool(cString text, bool initialVal, bool refresh, - bool active) { + bool active, + bool *callback, + eRecMenuState action) { selectable = true; this->text = text; this->yes = initialVal; this->refresh = refresh; this->active = active; + this->callback = callback; + this->action = action; height = 3 * font->Height() / 2; pixmapVal = NULL; } @@ -434,12 +453,16 @@ eRecMenuState cRecMenuItemBool::ProcessKey(eKeys Key) { case kLeft: case kRight: yes = !yes; + if (callback) + *callback = yes; DrawValue(); if (refresh) return rmsRefresh; else return rmsConsumed; break; + case kOk: + return action; default: break; } @@ -448,19 +471,22 @@ eRecMenuState cRecMenuItemBool::ProcessKey(eKeys Key) { // --- cRecMenuItemSelect ------------------------------------------------------- cRecMenuItemSelect::cRecMenuItemSelect(cString text, - const char * const *Strings, + std::vector Strings, int initialVal, - int numValues, - bool active) { + bool active, + int *callback, + eRecMenuState action) { selectable = true; this->text = text; strings = Strings; - this->numValues = numValues; + numValues = Strings.size(); if ((initialVal < 0) || (initialVal > numValues-1)) this->currentVal = 0; else this->currentVal = initialVal; this->active = active; + this->callback = callback; + this->action = action; height = 3 * font->Height() / 2; pixmapVal = NULL; } @@ -498,11 +524,11 @@ void cRecMenuItemSelect::Draw(void) { void cRecMenuItemSelect::DrawValue(void) { pixmapVal->Fill(clrTransparent); - const char *textVal = strings[currentVal]; + std::string textVal = strings[currentVal]; int iconSize = min(128, height); - int textX = width - font->Width(textVal) - iconSize; + int textX = width - font->Width(textVal.c_str()) - iconSize; int textY = (height - font->Height()) / 2; - pixmapVal->DrawText(cPoint(textX, textY), textVal, colorText, clrTransparent, font); + pixmapVal->DrawText(cPoint(textX, textY), textVal.c_str(), colorText, clrTransparent, font); int iconLeftX = textX - iconSize; int iconRightX = width - iconSize; int iconY = (height - iconSize) / 2; @@ -524,14 +550,20 @@ eRecMenuState cRecMenuItemSelect::ProcessKey(eKeys Key) { currentVal--; if (currentVal<0) currentVal = numValues - 1; + if (callback) + *callback = currentVal; DrawValue(); return rmsConsumed; break; case kRight: currentVal = (currentVal+1)%numValues; + if (callback) + *callback = currentVal; DrawValue(); return rmsConsumed; break; + case kOk: + return action; default: break; } @@ -542,11 +574,13 @@ eRecMenuState cRecMenuItemSelect::ProcessKey(eKeys Key) { cRecMenuItemText::cRecMenuItemText(cString title, char *initialVal, int length, - bool active) { + bool active, + char *callback) { selectable = true; this->title = title; value = initialVal; this->active = active; + this->callback = callback; height = 3 * font->Height(); pixmapVal = NULL; pixmapKeyboard = NULL; @@ -800,6 +834,9 @@ void cRecMenuItemText::LeaveEditMode(bool SaveValue) { if (SaveValue) { Utf8FromArray(valueUtf8, value, length); stripspace(value); + if (callback) { + strncpy(callback, value, TEXTINPUTLENGTH); + } } lengthUtf8 = 0; delete[] valueUtf8; @@ -1109,7 +1146,9 @@ eRecMenuState cRecMenuItemText::ProcessKey(eKeys Key) { // --- cRecMenuItemTime ------------------------------------------------------- cRecMenuItemTime::cRecMenuItemTime(cString text, int initialVal, - bool active) { + bool active, + int *callback, + eRecMenuState action) { selectable = true; this->text = text; this->value = initialVal; @@ -1118,6 +1157,8 @@ cRecMenuItemTime::cRecMenuItemTime(cString text, pos = 0; fresh = true; this->active = active; + this->callback = callback; + this->action = action; height = 3 * font->Height() / 2; pixmapVal = NULL; } @@ -1178,6 +1219,8 @@ eRecMenuState cRecMenuItemTime::ProcessKey(eKeys Key) { } fresh = true; value = hh * 100 + mm; + if (callback) + *callback = value; DrawValue(); return rmsConsumed; break; } @@ -1191,6 +1234,8 @@ eRecMenuState cRecMenuItemTime::ProcessKey(eKeys Key) { fresh = true; value = hh * 100 + mm; DrawValue(); + if (callback) + *callback = value; return rmsConsumed; break; } case k0|k_Repeat ... k9|k_Repeat: @@ -1229,9 +1274,13 @@ eRecMenuState cRecMenuItemTime::ProcessKey(eKeys Key) { default: ; } value = hh * 100 + mm; + if (callback) + *callback = value; DrawValue(); return rmsConsumed; break; } + case kOk: + return action; default: break; } @@ -1241,11 +1290,15 @@ eRecMenuState cRecMenuItemTime::ProcessKey(eKeys Key) { // --- cRecMenuItemDay ------------------------------------------------------- cRecMenuItemDay::cRecMenuItemDay(cString text, time_t initialVal, - bool active) { + bool active, + time_t *callback, + eRecMenuState action) { selectable = true; this->text = text; this->currentVal = cTimer::SetTime(initialVal, 0); this->active = active; + this->callback = callback; + this->action = action; height = 3 * font->Height() / 2; pixmapVal = NULL; } @@ -1293,14 +1346,20 @@ eRecMenuState cRecMenuItemDay::ProcessKey(eKeys Key) { switch (Key & ~k_Repeat) { case kLeft: currentVal -= 60*60*24; + if (callback) + *callback = currentVal; DrawValue(); return rmsConsumed; break; case kRight: currentVal += 60*60*24; + if (callback) + *callback = currentVal; DrawValue(); return rmsConsumed; break; + case kOk: + return action; default: break; } @@ -1646,6 +1705,15 @@ void cRecMenuItemEvent::Draw(void) { pixmapText->DrawText(cPoint(textX, textHeightLine1), *info, colorText, clrTransparent, fontSmall); pixmapText->DrawText(cPoint(textX, textHeightLine2), *title, colorText, clrTransparent, font); pixmapText->DrawText(cPoint(textX, textHeightLine3), *desc, colorText, clrTransparent, fontSmall); + + if (event->HasTimer()) { + int iconSize = height / 2; + int iconY = (height - iconSize) / 2; + cImage *imgHasTimer = imgCache.GetIcon("activetimer", iconSize, iconSize); + if (imgHasTimer) { + pixmapIcons->DrawImage(cPoint(width - iconSize - 10, iconY), *imgHasTimer); + } + } } int cRecMenuItemEvent::DrawIcons(void) { @@ -1734,7 +1802,9 @@ eRecMenuState cRecMenuItemEvent::ProcessKey(eKeys Key) { // --- cRecMenuItemChannelChooser ------------------------------------------------------- cRecMenuItemChannelChooser::cRecMenuItemChannelChooser(cString text, cChannel *initialChannel, - bool active) { + bool active, + int *callback, + eRecMenuState action) { selectable = true; this->text = text; this->channel = initialChannel; @@ -1745,6 +1815,8 @@ cRecMenuItemChannelChooser::cRecMenuItemChannelChooser(cString text, channelNumber = 0; fresh = true; this->active = active; + this->callback = callback; + this->action = action; height = 2 * font->Height(); pixmapChannel = NULL; } @@ -1829,6 +1901,12 @@ eRecMenuState cRecMenuItemChannelChooser::ProcessKey(eKeys Key) { } } } + if (callback) { + if (channel) + *callback = channel->Number(); + else + *callback = 0; + } DrawValue(); return rmsConsumed; break; } @@ -1847,6 +1925,12 @@ eRecMenuState cRecMenuItemChannelChooser::ProcessKey(eKeys Key) { } } } + if (callback) { + if (channel) + *callback = channel->Number(); + else + *callback = 0; + } DrawValue(); return rmsConsumed; break; } @@ -1860,9 +1944,13 @@ eRecMenuState cRecMenuItemChannelChooser::ProcessKey(eKeys Key) { if (chanNew) { channel = chanNew; DrawValue(); + if (callback) + *callback = channel->Number(); } return rmsConsumed; break; } + case kOk: + return action; default: break; } @@ -1872,11 +1960,15 @@ eRecMenuState cRecMenuItemChannelChooser::ProcessKey(eKeys Key) { // --- cRecMenuItemDayChooser ------------------------------------------------------- cRecMenuItemDayChooser::cRecMenuItemDayChooser(cString text, int weekdays, - bool active) { + bool active, + int *callback) { selectable = true; this->text = text; + if (weekdays < 1) + weekdays *= -1; this->weekdays = weekdays; this->active = active; + this->callback = callback; height = 2 * font->Height(); selectedDay = 0; pixmapWeekdays = NULL; @@ -1979,6 +2071,9 @@ void cRecMenuItemDayChooser::ToggleDay(void) { } else { weekdays += dayBit; } + if (callback) { + *callback = weekdays; + } } eRecMenuState cRecMenuItemDayChooser::ProcessKey(eKeys Key) { @@ -2414,3 +2509,134 @@ eRecMenuState cRecMenuItemTimelineTimer::ProcessKey(eKeys Key) { } return rmsNotConsumed; } + + +// --- cRecMenuItemSearchTimer ------------------------------------------------------- +cRecMenuItemSearchTimer::cRecMenuItemSearchTimer(cTVGuideSearchTimer timer, + eRecMenuState action1, + eRecMenuState action2, + bool active) { + this->timer = timer; + this->action = action1; + this->action2 = action2; + pixmapText = NULL; + pixmapIcons = NULL; + selectable = true; + this->active = active; + iconActive = 0; + height = 2 * font->Height();; +} + +cRecMenuItemSearchTimer::~cRecMenuItemSearchTimer(void) { + if (pixmapText) + osdManager.releasePixmap(pixmapText); + if (pixmapIcons) + osdManager.releasePixmap(pixmapIcons); +} + +void cRecMenuItemSearchTimer::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapText = osdManager.requestPixmap(5, cRect(x, y, width, height)); + pixmapIcons = osdManager.requestPixmap(6, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapText->SetViewPort(cRect(x, y, width, height)); + pixmapIcons->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemSearchTimer::Draw(void) { + int textX = DrawIcons(); + if (!drawn) { + pixmapText->Fill(clrTransparent); + textX += 20; + cString label; + if (timer.Active()) { + label = cString::sprintf("\"%s\"", timer.SearchString().c_str()); + } else { + label = cString::sprintf("\"%s\" (%s)", timer.SearchString().c_str(), tr("inactive")); + } + int numTimersActive = timer.GetNumTimers(); + int numRecordings = timer.GetNumRecordings(); + cString info = cString::sprintf("%s: %d, %s: %d", tr("active timers"), numTimersActive, tr("recordings done"), numRecordings); + pixmapText->DrawText(cPoint(textX, 5 + (height/2 - font->Height())/2), *label, colorText, clrTransparent, font); + pixmapText->DrawText(cPoint(textX, height/2 + (height/2 - fontSmall->Height())/2), *info, colorText, clrTransparent, fontSmall); + drawn = true; + } +} + +void cRecMenuItemSearchTimer::Hide(void) { + pixmap->SetLayer(-1); + pixmapText->SetLayer(-1); + pixmapIcons->SetLayer(-1); +} + +void cRecMenuItemSearchTimer::Show(void) { + pixmap->SetLayer(4); + pixmapText->SetLayer(5); + pixmapIcons->SetLayer(6); +} + +int cRecMenuItemSearchTimer::DrawIcons(void) { + pixmapIcons->Fill(clrTransparent); + int iconsX = 10; + int iconSize = height / 2; + int iconY = (height - iconSize) / 2; + std::string iconEdit, iconDelete; + if (active) { + iconEdit = (iconActive==0)?"edit_active":"edit_inactive"; + iconDelete = (iconActive==1)?"delete_active":"delete_inactive"; + } else { + iconEdit = "edit_inactive"; + iconDelete = "delete_inactive"; + } + cImage *imgEdit = imgCache.GetIcon(iconEdit, iconSize, iconSize); + if (imgEdit) { + pixmapIcons->DrawImage(cPoint(iconsX, iconY), *imgEdit); + iconsX += iconSize + 10; + } + cImage *imgDel = imgCache.GetIcon(iconDelete, iconSize, iconSize); + if (imgDel) { + pixmapIcons->DrawImage(cPoint(iconsX, iconY), *imgDel); + iconsX += iconSize + 10; + } + return iconsX; +} + +eRecMenuState cRecMenuItemSearchTimer::ProcessKey(eKeys Key) { + bool consumed = false; + switch (Key & ~k_Repeat) { + case kLeft: + if (iconActive == 1) { + iconActive = 0; + consumed = true; + } + DrawIcons(); + if (consumed) + return rmsConsumed; + else + return rmsNotConsumed; + break; + case kRight: { + if (iconActive == 0) { + iconActive = 1; + consumed = true; + } + DrawIcons(); + if (consumed) + return rmsConsumed; + else + return rmsNotConsumed; + break; } + case kOk: + if (iconActive == 0) + return action; + else if (iconActive == 1) + return action2; + break; + default: + break; + } + return rmsNotConsumed; +} diff --git a/recmenuitem.h b/recmenuitem.h index 8612939..5b3aa2e 100644 --- a/recmenuitem.h +++ b/recmenuitem.h @@ -7,6 +7,7 @@ #include #include "styledpixmap.h" #include "timerconflict.h" +#include "searchtimer.h" enum eRecMenuState { rmsConsumed, @@ -14,6 +15,7 @@ enum eRecMenuState { rmsRefresh, rmsContinue, rmsClose, + //INSTANT TIMER rmsInstantRecord, rmsInstantRecordFolder, rmsIgnoreTimerConflict, @@ -26,6 +28,7 @@ enum eRecMenuState { rmsDeleteTimerConfirmation, rmsEditTimer, rmsSaveTimer, + //SEARCH rmsSearch, rmsSearchWithOptions, rmsSearchPerform, @@ -33,28 +36,35 @@ enum eRecMenuState { rmsSearchRecord, rmsSearchRecordConfirm, rmsSearchNothingFoundConfirm, + //SERIES TIMER rmsSeriesTimer, rmsSeriesTimerFolder, rmsSeriesTimerCreate, + //SEARCHTIMER rmsSearchTimer, rmsSearchTimerOptions, - rmsSearchTimerOptionsReload, - rmsSearchTimerUseTemplate, - rmsSearchTimerOptionsManually, - rmsSearchTimerTestManually, - rmsSearchTimerTestTemplate, - rmsSearchTimerNothingFoundConfirm, - rmsSearchTimerCreateManually, - rmsSearchTimerCreateTemplate, + rmsSearchTimers, + rmsSearchTimerEdit, + rmsSearchTimerEditAdvanced, + rmsSearchTimerTest, + rmsSearchTimerSave, + rmsSearchTimerCreateWithTemplate, + rmsSearchTimerDeleteConfirm, + rmsSearchTimerDelete, + rmsSearchTimerDeleteWithTimers, + //SWITCHTIMER rmsSwitchTimer, rmsSwitchTimerCreate, rmsSwitchTimerDelete, + //RECORDINGS SEARCH rmsRecordingSearch, rmsRecordingSearchResult, + //TIMER CONFLICTS rmsTimerConflict, rmsTimerConflicts, rmsTimerConflictIgnoreReruns, rmsTimerConflictRecordRerun, + //TIMELINE rmsTimeline, rmsTimelineTimerEdit, rmsTimelineTimerSave, @@ -66,6 +76,7 @@ enum eDependend { eGreater, eLower, }; + // --- cRecMenuItem ------------------------------------------------------------- class cRecMenuItem : public cListObject, public cStyledPixmap { protected: @@ -80,6 +91,7 @@ protected: tColor colorTextBack; const cFont *font; const cFont *fontSmall; + const cFont *fontLarge; public: cRecMenuItem(void); virtual ~cRecMenuItem(void); @@ -103,7 +115,6 @@ public: virtual const cEvent *GetEventValue(void) { return NULL; }; virtual cTimer *GetTimerValue(void) { return NULL; }; virtual eRecMenuState ProcessKey(eKeys Key) { return rmsNotConsumed; }; - }; // --- cRecMenuItemButton ------------------------------------------------------- @@ -112,8 +123,9 @@ private: cString text; bool halfWidth; bool alignLeft; + const cFont *fontButtons; public: - cRecMenuItemButton(const char *text, eRecMenuState action, bool active, bool halfWidth = false, bool alignLeft = false); + cRecMenuItemButton(const char *text, eRecMenuState action, bool active, bool halfWidth = false, bool alignLeft = false, bool largeFont = false); virtual ~cRecMenuItemButton(void); int GetWidth(void); void SetPixmaps(void); @@ -166,6 +178,7 @@ class cRecMenuItemInt : public cRecMenuItem { private: cString text; int currentVal; + int *callback; int minVal; int maxVal; cPixmap *pixmapVal; @@ -176,7 +189,9 @@ public: int initialVal, int minVal, int maxVal, - bool active); + bool active = false, + int *callback = NULL, + eRecMenuState action = rmsNotConsumed); virtual ~cRecMenuItemInt(void); void SetPixmaps(void); void Hide(void); @@ -192,14 +207,17 @@ class cRecMenuItemBool : public cRecMenuItem { private: cString text; bool yes; + bool *callback; cPixmap *pixmapVal; bool refresh; void DrawValue(void); public: cRecMenuItemBool(cString text, bool initialVal, - bool refresh, - bool active); + bool refresh = false, + bool active = false, + bool *callback = NULL, + eRecMenuState action = rmsNotConsumed); virtual ~cRecMenuItemBool(void); void SetPixmaps(void); void Hide(void); @@ -214,16 +232,18 @@ class cRecMenuItemSelect : public cRecMenuItem { private: cString text; int currentVal; - const char * const *strings; + int *callback; + std::vector strings; int numValues; cPixmap *pixmapVal; void DrawValue(void); public: cRecMenuItemSelect(cString text, - const char * const *Strings, + std::vector Strings, int initialVal, - int numValues, - bool active); + bool active = false, + int *callback = NULL, + eRecMenuState action = rmsNotConsumed); virtual ~cRecMenuItemSelect(void); void SetPixmaps(void); void Hide(void); @@ -231,7 +251,7 @@ public: eRecMenuState ProcessKey(eKeys Key); void Draw(void); int GetIntValue(void) { return currentVal; }; - cString GetStringValue(void) { return strings[currentVal]; }; + cString GetStringValue(void) { return strings[currentVal].c_str(); }; }; // --- cRecMenuItemText ------------------------------------------------------- @@ -239,6 +259,7 @@ class cRecMenuItemText : public cRecMenuItem { private: cString title; char *value; + char *callback; int length; const char *allowed; int pos, offset; @@ -279,7 +300,8 @@ public: cRecMenuItemText(cString title, char *initialVal, int length, - bool active); + bool active = false, + char *callback = NULL); virtual ~cRecMenuItemText(void); void SetPixmaps(void); void Hide(void); @@ -296,6 +318,7 @@ class cRecMenuItemTime : public cRecMenuItem { private: cString text; int value; + int *callback; int mm; int hh; int pos; @@ -305,7 +328,9 @@ private: public: cRecMenuItemTime(cString text, int initialVal, - bool active); + bool active = false, + int *callback = NULL, + eRecMenuState action = rmsNotConsumed); virtual ~cRecMenuItemTime(void); void SetPixmaps(void); void Hide(void); @@ -320,12 +345,15 @@ class cRecMenuItemDay : public cRecMenuItem { private: cString text; time_t currentVal; + time_t *callback; cPixmap *pixmapVal; void DrawValue(void); public: cRecMenuItemDay(cString text, time_t initialVal, - bool active); + bool active = false, + time_t *callback = NULL, + eRecMenuState action = rmsNotConsumed); virtual ~cRecMenuItemDay(void); void SetPixmaps(void); void Hide(void); @@ -421,6 +449,7 @@ private: cString text; cChannel *channel; int channelNumber; + int *callback; bool initialChannelSet; bool fresh; cPixmap *pixmapChannel; @@ -428,7 +457,9 @@ private: public: cRecMenuItemChannelChooser (cString text, cChannel *initialChannel, - bool active); + bool active = false, + int *callback = NULL, + eRecMenuState action = rmsNotConsumed); virtual ~cRecMenuItemChannelChooser(void); void SetPixmaps(void); void Hide(void); @@ -443,6 +474,8 @@ class cRecMenuItemDayChooser : public cRecMenuItem { private: cString text; int weekdays; + int *callback; + bool epgsearchMode; std::string days; int daysX; int daysY; @@ -458,7 +491,8 @@ private: public: cRecMenuItemDayChooser (cString text, int weekdays, - bool active); + bool active = false, + int *callback = NULL); virtual ~cRecMenuItemDayChooser(void); void SetPixmaps(void); void Hide(void); @@ -541,4 +575,28 @@ public: eRecMenuState ProcessKey(eKeys Key); }; +// --- cRecMenuItemSearchTimer ------------------------------------------------------- +class cRecMenuItemSearchTimer : public cRecMenuItem { +private: + cTVGuideSearchTimer timer; + eRecMenuState action1; + eRecMenuState action2; + int iconActive; + cPixmap *pixmapText; + cPixmap *pixmapIcons; + int DrawIcons(void); +public: + cRecMenuItemSearchTimer(cTVGuideSearchTimer timer, + eRecMenuState action1, + eRecMenuState action2, + bool active); + virtual ~cRecMenuItemSearchTimer(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + void Draw(void); + cTVGuideSearchTimer GetTimer(void) { return timer; }; + eRecMenuState ProcessKey(eKeys Key); +}; + #endif //__TVGUIDE_RECMENUITEM_H \ No newline at end of file diff --git a/recmenumanager.c b/recmenumanager.c index 2adaa42..8206164 100644 --- a/recmenumanager.c +++ b/recmenumanager.c @@ -10,14 +10,7 @@ cRecMenuManager::cRecMenuManager(void) { activeMenuBuffer = NULL; recManager = new cRecManager(); recManager->SetEPGSearchPlugin(); - instantRecord = false; - folderChoosen = false; timerConflicts = NULL; - templateID = -1; - timer = NULL; - recFolderSeriesTimer = ""; - recFolderInstantTimer = ""; - searchWithOptions = false; detailViewActive = false; } @@ -37,14 +30,6 @@ cRecMenuManager::~cRecMenuManager(void) { void cRecMenuManager::Start(const cEvent *event) { active = true; activeMenuBuffer = NULL; - instantRecord = false; - folderChoosen = false; - timerConflicts = NULL; - templateID = -1; - timer = NULL; - recFolderSeriesTimer = ""; - recFolderInstantTimer = ""; - searchWithOptions = false; detailViewActive = false; SetBackground(); this->event = event; @@ -87,46 +72,43 @@ void cRecMenuManager::DeleteBackground(void) { eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { eOSState state = osContinue; switch (nextState) { - /* - * --------- INSTANT RECORDING --------------------------- - */ + /*************************************************************************************** + * INSTANT RECORDING + ****************************************************************************************/ case rmsInstantRecord: { - //Creating timer for active Event - //if no conflict, confirm and exit - instantRecord = true; - recFolderInstantTimer = ""; - if (folderChoosen) { - int activeItem = activeMenu->GetActive(false); - if (activeItem > 0) - recFolderInstantTimer = activeMenu->GetStringValue(activeItem); + //caller: main menu or folder chooser + //Creating timer for active Event, if no conflict, confirm and exit + std::string recFolder = ""; + if (cRecMenuAskFolder *menu = dynamic_cast(activeMenu)) { + recFolder = menu->GetFolder(); } delete activeMenu; - cTimer *timer = recManager->createTimer(event, *recFolderInstantTimer); - if (!displayTimerConflict(timer)) { + cTimer *timer = recManager->createTimer(event, recFolder); + if (!DisplayTimerConflict(timer)) { activeMenu = new cRecMenuConfirmTimer(event); activeMenu->Display(); } break; } case rmsInstantRecordFolder: + //caller: main menu //Asking for Folder - folderChoosen = true; delete activeMenu; activeMenu = new cRecMenuAskFolder(event, rmsInstantRecord); activeMenu->Display(); break; case rmsIgnoreTimerConflict: + //caller: cRecMenuTimerConflict //Confirming created Timer - if (instantRecord) { - delete activeMenu; - activeMenu = new cRecMenuConfirmTimer(event); - activeMenu->Display(); - } else { - state = osEnd; - Close(); - } + delete activeMenu; + activeMenu = new cRecMenuConfirmTimer(event); + activeMenu->Display(); break; case rmsTimerConflictShowInfo: { - int timerIndex = activeMenu->GetActive(true); + //caller: cRecMenuTimerConflict + int timerIndex; + if (cRecMenuTimerConflict *menu = dynamic_cast(activeMenu)) { + timerIndex = menu->GetTimerConflictIndex(); + } else break; int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex); cTimer *t = Timers.Get(timerID); if (t) { @@ -144,23 +126,29 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { } break;} case rmsDeleteTimerConflictMenu: { - //delete timer out of current timer conflict - //active menu: cRecMenuTimerConflict - int timerIndex = activeMenu->GetActive(true); + //caller: cRecMenuTimerConflict + //delete timer out of current timer conflict + int timerIndex; + if (cRecMenuTimerConflict *menu = dynamic_cast(activeMenu)) { + timerIndex = menu->GetTimerConflictIndex(); + } else break; int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex); recManager->DeleteTimer(timerID); delete activeMenu; - if (!displayTimerConflict(timerID)) { + if (!DisplayTimerConflict(timerID)) { activeMenu = new cRecMenuConfirmTimer(event); activeMenu->Display(); } break; } case rmsEditTimerConflictMenu: { - //edit timer out of current timer conflict - //active menu: cRecMenuTimerConflict - int timerIndex = activeMenu->GetActive(true); + //caller: cRecMenuTimerConflict + //edit timer out of current timer conflict + int timerIndex; + if (cRecMenuTimerConflict *menu = dynamic_cast(activeMenu)) { + timerIndex = menu->GetTimerConflictIndex(); + } else break; int timerID = timerConflicts->GetCurrentConflictTimerID(timerIndex); - timer = Timers.Get(timerID); + cTimer *timer = Timers.Get(timerID); if (timer) { delete activeMenu; activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimerConflictMenu); @@ -168,16 +156,24 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { } break; } case rmsSaveTimerConflictMenu: { - //save timer from current timer conflict - recManager->SaveTimer(timer, activeMenu); + //caller: cRecMenuEditTimer + //save timer from current timer conflict + cTimer timerModified; + cTimer *originalTimer; + if (cRecMenuEditTimer *menu = dynamic_cast(activeMenu)) { + timerModified = menu->GetTimer(); + originalTimer = menu->GetOriginalTimer(); + } else break; + recManager->SaveTimer(originalTimer, timerModified); delete activeMenu; - if (!displayTimerConflict(timer)) { + if (!DisplayTimerConflict(originalTimer)) { activeMenu = new cRecMenuConfirmTimer(event); activeMenu->Display(); } break; } case rmsDeleteTimer: - //delete timer for active event + //caller: main menu + //delete timer for active event delete activeMenu; if (recManager->IsRecorded(event)) { activeMenu = new cRecMenuAskDeleteTimer(event); @@ -188,15 +184,15 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu->Display(); break; case rmsDeleteTimerConfirmation: - //delete running timer for active event + //delete running timer for active event recManager->DeleteTimer(event); delete activeMenu; activeMenu = new cRecMenuConfirmDeleteTimer(event); activeMenu->Display(); break; case rmsEditTimer: { - //edit timer for active event - timer = recManager->GetTimerForEvent(event); + //edit timer for active event + cTimer *timer = recManager->GetTimerForEvent(event); if (timer) { delete activeMenu; activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimer); @@ -204,141 +200,214 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { } break; } case rmsSaveTimer: { - //save timer for active event - recManager->SaveTimer(timer, activeMenu); + //caller: cRecMenuEditTimer + //save timer for active event + cTimer timerModified; + cTimer *originalTimer; + if (cRecMenuEditTimer *menu = dynamic_cast(activeMenu)) { + timerModified = menu->GetTimer(); + originalTimer = menu->GetOriginalTimer(); + } else break; + recManager->SaveTimer(originalTimer, timerModified); state = osEnd; Close(); break; } - /* - * --------- SERIES TIMER --------------------------------- - */ + /*************************************************************************************** + * SERIES TIMER + ****************************************************************************************/ case rmsSeriesTimer: { - recFolderSeriesTimer = ""; - if (folderChoosen) { - int activeItem = activeMenu->GetActive(false); - if (activeItem > 0) - recFolderSeriesTimer = activeMenu->GetStringValue(activeItem); + //caller: main menu oder folder chooser + std::string recFolder = ""; + if (cRecMenuAskFolder *menu = dynamic_cast(activeMenu)) { + recFolder = menu->GetFolder(); } delete activeMenu; cChannel *channel = Channels.GetByChannelID(event->ChannelID()); - activeMenu = new cRecMenuSeriesTimer(channel, event); + activeMenu = new cRecMenuSeriesTimer(channel, event, recFolder); activeMenu->Display(); break; } case rmsSeriesTimerFolder: - //Asking for Folder - folderChoosen = true; + //caller: main menu + //Asking for Folder delete activeMenu; activeMenu = new cRecMenuAskFolder(event, rmsSeriesTimer); activeMenu->Display(); break; case rmsSeriesTimerCreate: { - cTimer *seriesTimer = recManager->CreateSeriesTimer(activeMenu, *recFolderSeriesTimer); + //caller: cRecMenuSeriesTimer + cTimer *seriesTimer; + if (cRecMenuSeriesTimer *menu = dynamic_cast(activeMenu)) { + seriesTimer = menu->GetTimer(); + } else break; + recManager->CreateSeriesTimer(seriesTimer); delete activeMenu; activeMenu = new cRecMenuConfirmSeriesTimer(seriesTimer); activeMenu->Display(); break; } - /* - * --------- SEARCH TIMER --------------------------------- - */ + /********************************************************************************************** + * SEARCH TIMER + ***********************************************************************************************/ case rmsSearchTimer: + //Caller: main menu + //set search String for search timer delete activeMenu; activeMenu = new cRecMenuSearchTimer(event); activeMenu->Display(); break; case rmsSearchTimerOptions: { - searchString = *activeMenu->GetStringValue(1); + //Caller: cRecMenuSearchTimer, cRecMenuSearchTimerTemplates + //Choose to set options manually or by template + std::string searchString; + cTVGuideSearchTimer searchTimer; + bool reload = false; + if (cRecMenuSearchTimer *menu = dynamic_cast(activeMenu)) { + searchString = menu->GetSearchString(); + } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + reload = true; + } else break; delete activeMenu; - if (isempty(*searchString)) { + if (searchString.size() < 4) { activeMenu = new cRecMenuSearchTimer(event); - } else { - epgSearchTemplates = recManager->ReadEPGSearchTemplates(); - int numTemplates = epgSearchTemplates.size(); - if (numTemplates > 0) { - activeMenu = new cRecMenuSearchTimerTemplates(searchString, epgSearchTemplates); + } else { + if (!reload) { + searchTimer.SetSearchString(searchString); + } + std::vector epgSearchTemplates; + recManager->ReadEPGSearchTemplates(&epgSearchTemplates); + if (epgSearchTemplates.size() > 0) { + activeMenu = new cRecMenuSearchTimerTemplates(searchTimer, epgSearchTemplates); } else { - activeMenu = new cRecMenuSearchTimerOptions(searchString); + activeMenu = new cRecMenuSearchTimerEdit(searchTimer, false); } } activeMenu->Display(); break; } - case rmsSearchTimerOptionsReload: { - int numTemplates = epgSearchTemplates.size(); + case rmsSearchTimers: { + //caller: main menu + DisplaySearchTimerList(); + break; } + case rmsSearchTimerEdit: + case rmsSearchTimerEditAdvanced: { + //caller: cRecMenuSearchTimers, cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplates + cTVGuideSearchTimer searchTimer; + bool advancedOptions = false; + if (cRecMenuSearchTimers *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else if (cRecMenuSearchTimerEdit *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + advancedOptions = (nextState == rmsSearchTimerEditAdvanced)?true:false; + } else if (cRecMenuSearchTimerTemplates *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else break; delete activeMenu; - activeMenu = new cRecMenuSearchTimerTemplates(searchString, epgSearchTemplates); + activeMenu = new cRecMenuSearchTimerEdit(searchTimer, advancedOptions); activeMenu->Display(); break; } - case rmsSearchTimerUseTemplate: { - templateID = activeMenu->GetActive(true) - 1; - delete activeMenu; - activeMenu = new cRecMenuSearchTimerTemplatesCreate(searchString, epgSearchTemplates[templateID].name.c_str()); - activeMenu->Display(); - break; } - case rmsSearchTimerOptionsManually: - delete activeMenu; - activeMenu = new cRecMenuSearchTimerOptions(searchString); - activeMenu->Display(); - break; - case rmsSearchTimerTestTemplate: { - std::string epgSearchString = recManager->BuildEPGSearchString(searchString, epgSearchTemplates[templateID].templValue); + case rmsSearchTimerTest: { + //caller: cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplatesCreate + //show results of currently choosen search timer + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimerEdit *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + TVGuideEPGSearchTemplate tmpl = menu->GetTemplate(); + searchTimer.SetTemplate(tmpl.templValue); + searchTimer.Parse(true); + } else break; int numSearchResults = 0; - const cEvent **searchResult = recManager->PerformSearchTimerSearch(epgSearchString, numSearchResults); - if (searchResult) { + std::string searchString = searchTimer.BuildSearchString(); + const cEvent **searchResult = recManager->PerformSearchTimerSearch(searchString, numSearchResults); + if (numSearchResults) { activeMenuBuffer = activeMenu; activeMenuBuffer->Hide(); - activeMenu = new cRecMenuSearchTimerResults(searchString, searchResult, numSearchResults, epgSearchTemplates[templateID].name); + activeMenu = new cRecMenuSearchTimerResults(searchTimer.SearchString(), searchResult, numSearchResults); activeMenu->Display(); } else { activeMenuBuffer = activeMenu; activeMenuBuffer->Hide(); - activeMenu = new cRecMenuSearchTimerNothingFound(searchString, epgSearchTemplates[templateID].name); + activeMenu = new cRecMenuSearchTimerNothingFound(searchTimer.SearchString()); activeMenu->Display(); } break; } - case rmsSearchTimerTestManually: { - std::string epgSearchString = recManager->BuildEPGSearchString(searchString, activeMenu); - int numSearchResults = 0; - const cEvent **searchResult = recManager->PerformSearchTimerSearch(epgSearchString, numSearchResults); - if (searchResult) { - activeMenuBuffer = activeMenu; - activeMenuBuffer->Hide(); - activeMenu = new cRecMenuSearchTimerResults(searchString, searchResult, numSearchResults, ""); - activeMenu->Display(); + case rmsSearchTimerSave: { + //caller: cRecMenuSearchTimerEdit, cRecMenuSearchTimerTemplatesCreate + //create new or modify existing search timer + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimerEdit *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else if (cRecMenuSearchTimerTemplatesCreate *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + TVGuideEPGSearchTemplate tmpl = menu->GetTemplate(); + searchTimer.SetTemplate(tmpl.templValue); + searchTimer.Parse(true); + } else break; + bool success = recManager->SaveSearchTimer(&searchTimer); + recManager->UpdateSearchTimers(); + if (searchTimer.GetID() >= 0) { + //Timer modified, show list + DisplaySearchTimerList(); } else { - activeMenuBuffer = activeMenu; - activeMenuBuffer->Hide(); - activeMenu = new cRecMenuSearchTimerNothingFound(searchString, ""); - activeMenu->Display(); + //new timer, confirm + delete activeMenu; + activeMenu = new cRecMenuSearchTimerCreateConfirm(success); + activeMenu->Display(); } break; } - case rmsSearchTimerNothingFoundConfirm: + case rmsSearchTimerCreateWithTemplate: { + //caller: cRecMenuSearchTimerTemplates + //create new search timer from template + TVGuideEPGSearchTemplate templ; + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimerTemplates *menu = dynamic_cast(activeMenu)) { + templ = menu->GetTemplate(); + searchTimer = menu->GetSearchTimer(); + } else break; delete activeMenu; - activeMenu = activeMenuBuffer; + activeMenu = new cRecMenuSearchTimerTemplatesCreate(templ, searchTimer); + activeMenu->Display(); + break; } + case rmsSearchTimerDeleteConfirm: { + //caller: cRecMenuSearchTimers + //Ask for confirmation and if timers created by this search timer should alo be deleted + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimers *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else break; + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerDeleteConfirm(searchTimer); + activeMenu->Display(); + break; } + case rmsSearchTimerDelete: + case rmsSearchTimerDeleteWithTimers: { + //caller: cRecMenuSearchTimerDeleteConfirm + //actually delete searchtimer + cTVGuideSearchTimer searchTimer; + if (cRecMenuSearchTimerDeleteConfirm *menu = dynamic_cast(activeMenu)) { + searchTimer = menu->GetSearchTimer(); + } else break; + bool delTimers = (nextState==rmsSearchTimerDeleteWithTimers)?true:false; + recManager->DeleteSearchTimer(&searchTimer, delTimers); + delete activeMenuBuffer; activeMenuBuffer = NULL; - activeMenu->Show(); - break; - case rmsSearchTimerCreateManually: - case rmsSearchTimerCreateTemplate: { - std::string epgSearchString; - if (nextState == rmsSearchTimerCreateManually) { - epgSearchString = recManager->BuildEPGSearchString(searchString, activeMenu); - } else if (nextState = rmsSearchTimerCreateTemplate) { - epgSearchString = recManager->BuildEPGSearchString(searchString, epgSearchTemplates[templateID].templValue); - } - bool success = createSearchTimer(epgSearchString); - delete activeMenu; - activeMenu = new cRecMenuSearchTimerCreateConfirm(success); - activeMenu->Display(); + DisplaySearchTimerList(); break; } - /* - * --------- SWITCH TIMER --------------------------------- - */ + /********************************************************************************************** + * SWITCH TIMER + ***********************************************************************************************/ case rmsSwitchTimer: delete activeMenu; activeMenu = new cRecMenuSwitchTimer(); activeMenu->Display(); break; case rmsSwitchTimerCreate: { - bool success = recManager->CreateSwitchTimer(event, activeMenu); + cSwitchTimer switchTimer; + if (cRecMenuSwitchTimer *menu = dynamic_cast(activeMenu)) { + switchTimer = menu->GetSwitchTimer(); + } else break; + bool success = recManager->CreateSwitchTimer(event, switchTimer); delete activeMenu; activeMenu = new cRecMenuSwitchTimerConfirm(success); activeMenu->Display(); @@ -349,19 +418,28 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu = new cRecMenuSwitchTimerDelete(); activeMenu->Display(); break; - /* - * --------- RECORDINGS SEARCH --------------------------------- - */ - case rmsRecordingSearch: + /********************************************************************************************** + * RECORDINGS SEARCH + ***********************************************************************************************/ + case rmsRecordingSearch: { + //caller: main menu or rmsRecordingSearchResult + std::string searchString = event->Title(); + if (cRecMenuRecordingSearchResults *menu = dynamic_cast(activeMenu)) { + searchString = menu->GetSearchString(); + }; delete activeMenu; - activeMenu = new cRecMenuRecordingSearch(event); + activeMenu = new cRecMenuRecordingSearch(searchString); activeMenu->Display(); - break; + break; } case rmsRecordingSearchResult: { - searchString = activeMenu->GetStringValue(1); + //caller: cRecMenuRecordingSearch + std::string searchString; + if (cRecMenuRecordingSearch *menu = dynamic_cast(activeMenu)) { + searchString = menu->GetSearchString(); + } else break; delete activeMenu; - if (isempty(*searchString)) { - activeMenu = new cRecMenuRecordingSearch(event); + if (searchString.size() < 4) { + activeMenu = new cRecMenuRecordingSearch(searchString); } else { int numSearchResults = 0; cRecording **searchResult = recManager->SearchForRecordings(searchString, numSearchResults); @@ -373,34 +451,35 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { } activeMenu->Display(); break; } - /* - * --------- SEARCH --------------------------------- - */ + /********************************************************************************************** + * SEARCH + ***********************************************************************************************/ case rmsSearch: - delete activeMenu; - activeMenu = new cRecMenuSearch(event); - activeMenu->Display(); - searchWithOptions = false; - break; case rmsSearchWithOptions: { - cString searchString = activeMenu->GetStringValue(1); - delete activeMenu; - if (isempty(*searchString)) { - activeMenu = new cRecMenuSearch(event); - } else { - activeMenu = new cRecMenuSearch(event, *searchString); - searchWithOptions = true; + //caller: main menu, cRecMenuSearch + bool withOptions = false; + std::string searchString = event->Title(); + if (cRecMenuSearch *menu = dynamic_cast(activeMenu)) { + withOptions = true; + searchString = menu->GetSearchString(); } + delete activeMenu; + activeMenu = new cRecMenuSearch(searchString, withOptions); activeMenu->Display(); break; } case rmsSearchPerform: { - cString searchString = activeMenu->GetStringValue(1); - if (isempty(*searchString)) { + //caller: cRecMenuSearch + Epgsearch_searchresults_v1_0 epgSearchData; + if (cRecMenuSearch *menu = dynamic_cast(activeMenu)) { + epgSearchData = menu->GetEPGSearchStruct(); + } else break; + std::string searchString = epgSearchData.query; + if (searchString.size() < 4) { delete activeMenu; - activeMenu = new cRecMenuSearch(event); + activeMenu = new cRecMenuSearch(event->Title(), false); } else { int numSearchResults = 0; - const cEvent **searchResult = recManager->PerformSearch(activeMenu, searchWithOptions, numSearchResults); + const cEvent **searchResult = recManager->PerformSearch(epgSearchData, numSearchResults); if (searchResult) { delete activeMenu; activeMenu = new cRecMenuSearchResults(searchString, searchResult, numSearchResults); @@ -419,7 +498,13 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu->Show(); break; case rmsSearchShowInfo: { - const cEvent *ev = activeMenu->GetEventValue(activeMenu->GetActive(false)); + //caller: cRecMenuSearchResults, cRecMenuSearchTimerResults + const cEvent *ev = NULL; + if (cRecMenuSearchResults *menu = dynamic_cast(activeMenu)) { + ev = menu->GetEvent(); + } else if (cRecMenuSearchTimerResults *menu = dynamic_cast(activeMenu)) { + ev = menu->GetEvent(); + } else break; if (ev) { activeMenu->Hide(); detailView = new cDetailView(ev); @@ -432,7 +517,13 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { } break;} case rmsSearchRecord: { - const cEvent *ev = activeMenu->GetEventValue(activeMenu->GetActive(false)); + //caller: cRecMenuSearchResults + const cEvent *ev = NULL; + if (cRecMenuSearchResults *menu = dynamic_cast(activeMenu)) { + ev = menu->GetEvent(); + } else break; + if (!ev) + break; cTimer *timer = recManager->createTimer(ev, ""); activeMenuBuffer = activeMenu; activeMenuBuffer->Hide(); @@ -445,12 +536,12 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenuBuffer = NULL; activeMenu->Show(); break; - /* - * --------- CHECK FOR TIMER CONFLICTS --------------------------------- - */ + /********************************************************************************************** + * CHECK FOR TIMER CONFLICTS + ***********************************************************************************************/ case rmsTimerConflicts: { - //Show timer conflict - //active menu: cRecMenuTimerConflicts + //caller: main menu + //Show timer conflict if (timerConflicts) { delete timerConflicts; } @@ -465,23 +556,30 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu->Display(); break; } case rmsTimerConflict: { - //Show timer conflict - //active menu: cRecMenuTimerConflicts + //caller: cRecMenuTimerConflicts + //Show timer conflict if (!timerConflicts) break; - timerConflicts->SetCurrentConflict(activeMenu->GetActive(true)); + int timerConflict; + if (cRecMenuTimerConflicts *menu = dynamic_cast(activeMenu)) { + timerConflict = menu->GetTimerConflict(); + } else break; + timerConflicts->SetCurrentConflict(timerConflict); delete activeMenu; activeMenu = new cRecMenuTimerConflict(timerConflicts->GetCurrentConflict()); activeMenu->Display(); break; } case rmsSearchRerunsTimerConflictMenu: { - //Show reruns for timer from timer conflict - //active menu: cRecMenuTimerConflict + //caller: cRecMenuTimerConflict + //Show reruns for timer from timer conflict if (!timerConflicts) break; - int activeItem = activeMenu->GetActive(true); - int timerID = timerConflicts->GetCurrentConflictTimerID(activeItem); - timer = Timers.Get(timerID); + int timerConflict; + if (cRecMenuTimerConflict *menu = dynamic_cast(activeMenu)) { + timerConflict = menu->GetTimerConflictIndex(); + } else break; + int timerID = timerConflicts->GetCurrentConflictTimerID(timerConflict); + cTimer *timer = Timers.Get(timerID); if (timer) { const cEvent *event = timer->Event(); if (event) { @@ -508,13 +606,25 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu->Show(); break; } case rmsTimerConflictRecordRerun: { - const cEvent *replace = activeMenu->GetEventValue(activeMenu->GetActive(false)); - int originalConflictIndex = activeMenuBuffer->GetActive(false); + //caller: cRecMenuRerunResults + //buffer: cRecMenuTimerConflict + if (!activeMenuBuffer) + break; + if (!timerConflicts) + break; + const cEvent *replace; + int originalConflictIndex; + if (cRecMenuRerunResults *menu = dynamic_cast(activeMenu)) { + replace = menu->GetRerunEvent(); + } else break; + if (cRecMenuTimerConflict *menu = dynamic_cast(activeMenuBuffer)) { + originalConflictIndex = menu->GetTimerConflictIndex(); + } else break; int originalTimerID = timerConflicts->GetCurrentConflictTimerID(originalConflictIndex); cTimer *timerOriginal = Timers.Get(originalTimerID); if (replace && timerOriginal) { recManager->DeleteTimer(timerOriginal->Event()); - recManager->createTimer(replace, *recFolderInstantTimer); + recManager->createTimer(replace); delete activeMenu; if (activeMenuBuffer) { delete activeMenuBuffer; @@ -524,10 +634,10 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu->Display(); } break; } - /* - * --------- TIMELINE --------------------------------- - */ - case rmsTimeline: { + /********************************************************************************************** + * TIMELINE + ***********************************************************************************************/ + case rmsTimeline: { if (timerConflicts) { delete timerConflicts; } @@ -537,7 +647,10 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu->Display(); break; } case rmsTimelineTimerEdit: { - timer = activeMenu->GetTimerValue(activeMenu->GetActive(true)); + cTimer *timer; + if (cRecMenuTimeline *menu = dynamic_cast(activeMenu)) { + timer = menu->GetTimer(); + } else break; if (timer) { delete activeMenu; activeMenu = new cRecMenuEditTimer(timer, rmsTimelineTimerSave); @@ -545,7 +658,13 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { } break;} case rmsTimelineTimerSave: { - recManager->SaveTimer(timer, activeMenu); + cTimer timerModified; + cTimer *originalTimer; + if (cRecMenuEditTimer *menu = dynamic_cast(activeMenu)) { + timerModified = menu->GetTimer(); + originalTimer = menu->GetOriginalTimer(); + } else break; + recManager->SaveTimer(originalTimer, timerModified); delete activeMenu; if (timerConflicts) { delete timerConflicts; @@ -555,7 +674,11 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu->Display(); break; } case rmsTimelineTimerDelete: { - recManager->DeleteTimer(timer->Event()); + cTimer *timer; + if (cRecMenuEditTimer *menu = dynamic_cast(activeMenu)) { + timer = menu->GetOriginalTimer(); + } else break; + recManager->DeleteTimer(timer); delete activeMenu; if (timerConflicts) { delete timerConflicts; @@ -564,9 +687,9 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { activeMenu = new cRecMenuTimeline(timerConflicts); activeMenu->Display(); break; } - /* - * --------- COMMON --------------------------------- - */ + /********************************************************************************************** + * COMMON + *********************************************************************************************/ case rmsClose: { if (activeMenuBuffer == NULL) { state = osEnd; @@ -585,17 +708,25 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { return state; } -bool cRecMenuManager::displayTimerConflict(cTimer *timer) { +void cRecMenuManager::DisplaySearchTimerList(void) { + delete activeMenu; + std::vector searchTimers; + recManager->GetSearchTimers(&searchTimers); + activeMenu = new cRecMenuSearchTimers(searchTimers); + activeMenu->Display(); +} + +bool cRecMenuManager::DisplayTimerConflict(cTimer *timer) { int timerID = 0; for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) { if (t == timer) - return displayTimerConflict(timerID); + return DisplayTimerConflict(timerID); timerID++; } return false; } -bool cRecMenuManager::displayTimerConflict(int timerID) { +bool cRecMenuManager::DisplayTimerConflict(int timerID) { if (timerConflicts) delete timerConflicts; timerConflicts = recManager->CheckTimerConflict(); @@ -614,16 +745,6 @@ bool cRecMenuManager::displayTimerConflict(int timerID) { return false; } -bool cRecMenuManager::createSearchTimer(std::string epgSearchString) { - int newTimerID = recManager->CreateSearchTimer(epgSearchString); - bool success = false; - if (newTimerID > -1) { - recManager->UpdateSearchTimers(); - success = true; - } - return success; -} - eOSState cRecMenuManager::ProcessKey(eKeys Key) { eOSState state = osContinue; eRecMenuState nextState = rmsContinue; diff --git a/recmenumanager.h b/recmenumanager.h index 36a94ad..cc000d1 100644 --- a/recmenumanager.h +++ b/recmenumanager.h @@ -14,23 +14,14 @@ private: const cEvent *event; cRecManager *recManager; cTVGuideTimerConflicts *timerConflicts; - std::vector epgSearchTemplates; - bool instantRecord; - bool folderChoosen; - cString recFolderInstantTimer; - int templateID; - bool searchWithOptions; - cTimer *timer; - cString recFolderSeriesTimer; - cString searchString; cDetailView *detailView; cPixmap *pixmapBackground; bool detailViewActive; void SetBackground(void); void DeleteBackground(void); - bool displayTimerConflict(cTimer *timer); - bool displayTimerConflict(int timerID); - bool createSearchTimer(std::string epgSearchString); + void DisplaySearchTimerList(void); + bool DisplayTimerConflict(cTimer *timer); + bool DisplayTimerConflict(int timerID); public: cRecMenuManager(void); virtual ~cRecMenuManager(void); diff --git a/recmenus.c b/recmenus.c index 5223ffc..f5b1041 100644 --- a/recmenus.c +++ b/recmenus.c @@ -1,4 +1,5 @@ #include "services/remotetimers.h" +#include "recmenumanager.h" #include "recmenus.h" // --- cRecMenuMain --------------------------------------------------------- @@ -8,32 +9,39 @@ cRecMenuMain::cRecMenuMain(bool epgSearchAvailable, bool timerActive, bool switc action = (tvguideConfig.recMenuAskFolder) ?rmsInstantRecordFolder :rmsInstantRecord; - AddMenuItem(new cRecMenuItemButton(tr("Instant Record"), action, true)); + AddMenuItem(new cRecMenuItemButton(tr("Instant Record"), action, true, false, false, true)); } else { - AddMenuItem(new cRecMenuItemButton(tr("Delete Timer"), rmsDeleteTimer, true)); - AddMenuItem(new cRecMenuItemButton(tr("Edit Timer"), rmsEditTimer, false)); + AddMenuItem(new cRecMenuItemButton(tr("Delete Timer"), rmsDeleteTimer, true, false, false, true)); + AddMenuItem(new cRecMenuItemButton(tr("Edit Timer"), rmsEditTimer, false, false, false, true)); } + + AddMenuItem(new cRecMenuItemButton(tr("Timer Timeline"), rmsTimeline, false, false, false, true)); + + if (epgSearchAvailable) { + AddMenuItem(new cRecMenuItemButton(tr("Create Search Timer"), rmsSearchTimer, false, false, false, true)); + AddMenuItem(new cRecMenuItemButton(tr("Manage Search Timers"), rmsSearchTimers, false, false, false, true)); + } + action = (tvguideConfig.recMenuAskFolder) ?rmsSeriesTimerFolder :rmsSeriesTimer; - AddMenuItem(new cRecMenuItemButton(tr("Create Series Timer"), action, false)); + AddMenuItem(new cRecMenuItemButton(tr("Create Series Timer"), action, false, false, false, true)); + if (epgSearchAvailable) { - AddMenuItem(new cRecMenuItemButton(tr("Create Search Timer"), rmsSearchTimer, false)); if (!switchTimerActive) { - AddMenuItem(new cRecMenuItemButton(tr("Create Switch Timer"), rmsSwitchTimer, false)); + AddMenuItem(new cRecMenuItemButton(tr("Create Switch Timer"), rmsSwitchTimer, false, false, false, true)); } else { - AddMenuItem(new cRecMenuItemButton(tr("Delete Switch Timer"), rmsSwitchTimerDelete, false)); + AddMenuItem(new cRecMenuItemButton(tr("Delete Switch Timer"), rmsSwitchTimerDelete, false, false, false, true)); } - } - if (epgSearchAvailable) { - AddMenuItem(new cRecMenuItemButton(tr("Search"), rmsSearch, false)); + AddMenuItem(new cRecMenuItemButton(tr("Search"), rmsSearch, false, false, false, true)); } - AddMenuItem(new cRecMenuItemButton(tr("Timer Timeline"), rmsTimeline, false)); if (epgSearchAvailable) { - AddMenuItem(new cRecMenuItemButton(tr("Check for Timer Conflicts"), rmsTimerConflicts, false)); + AddMenuItem(new cRecMenuItemButton(tr("Check for Timer Conflicts"), rmsTimerConflicts, false, false, false, true)); } - AddMenuItem(new cRecMenuItemButton(tr("Search in Recordings"), rmsRecordingSearch, false)); + + AddMenuItem(new cRecMenuItemButton(tr("Search in Recordings"), rmsRecordingSearch, false, false, false, true)); + int menuWidth = CalculateOptimalWidth() + 4 * border; SetWidthPixel(menuWidth); @@ -42,6 +50,10 @@ cRecMenuMain::cRecMenuMain(bool epgSearchAvailable, bool timerActive, bool switc Arrange(); }; +/****************************************************************************************** +* Instant Timer Menus +******************************************************************************************/ + // --- cRecMenuAskFolder --------------------------------------------------------- cRecMenuAskFolder::cRecMenuAskFolder(const cEvent *event, eRecMenuState nextAction) { SetWidthPercent(80); @@ -52,13 +64,12 @@ cRecMenuAskFolder::cRecMenuAskFolder(const cEvent *event, eRecMenuState nextActi infoItem->CalculateHeight(width - 2 * border); SetHeader(infoItem); - AddMenuItemScroll(new cRecMenuItemButton(tr("root video folder"), nextAction, true, false, true)); + AddMenuItemInitial(new cRecMenuItemButton(tr("root video folder"), nextAction, true, false, true)); readFolders(NULL, ""); int numFolders = folders.size(); for (int i=0; i < numFolders; i++) { - AddMenuItemScroll(new cRecMenuItemButton(*folders[i], nextAction, false, false, true)); - if (!CheckHeight()) + if (!AddMenuItemInitial(new cRecMenuItemButton(*folders[i], nextAction, false, false, true))) break; } @@ -100,6 +111,14 @@ int cRecMenuAskFolder::GetTotalNumMenuItems(void) { return folders.size()+1; } +std::string cRecMenuAskFolder::GetFolder(void) { + std::string folder = ""; + int folderActive = GetActive(); + if (folderActive > 0 && folderActive < folders.size() + 1) + folder = *folders[folderActive - 1]; + return folder; +} + // --- cRecMenuConfirmTimer --------------------------------------------------------- cRecMenuConfirmTimer::cRecMenuConfirmTimer(const cEvent *event) { SetWidthPercent(50); @@ -204,13 +223,17 @@ cRecMenuTimerConflicts::cRecMenuTimerConflicts(cTVGuideTimerConflicts *conflicts SetWidthPixel(CalculateOptimalWidth() + 4*border); infoItem->CalculateHeight(width - 2 * border); SetHeader(infoItem); - AddMenuItem(new cRecMenuItemButton(tr("Ignore Conflicts"), rmsIgnoreTimerConflict, false)); + AddMenuItem(new cRecMenuItemButton(tr("Ignore Conflicts"), rmsClose, false)); CalculateHeight(); CreatePixmap(); Arrange(); } +int cRecMenuTimerConflicts::GetTimerConflict(void) { + return GetActive(); +} + // --- cRecMenuTimerConflict --------------------------------------------------------- cRecMenuTimerConflict::cRecMenuTimerConflict(cTVGuideTimerConflict *conflict) { SetWidthPercent(95); @@ -224,7 +247,7 @@ cRecMenuTimerConflict::cRecMenuTimerConflict(cTVGuideTimerConflict *conflict) { for(std::vector::iterator it = conflict->timerIDs.begin(); it != conflict->timerIDs.end(); it++) { const cTimer *timer = Timers.Get(*it); if (timer) { - AddMenuItemScroll(new cRecMenuItemTimer( timer, + if (!AddMenuItemInitial(new cRecMenuItemTimer( timer, rmsTimerConflictShowInfo, rmsDeleteTimerConflictMenu, rmsEditTimerConflictMenu, @@ -234,11 +257,10 @@ cRecMenuTimerConflict::cRecMenuTimerConflict(cTVGuideTimerConflict *conflict) { conflict->overlapStart, conflict->overlapStop, (!i)?true:false) - ); + )) + break; i++; } - if (!CheckHeight()) - break; } CalculateHeight(); CreatePixmap(); @@ -267,6 +289,10 @@ int cRecMenuTimerConflict::GetTotalNumMenuItems(void) { return conflict->timerIDs.size(); } +int cRecMenuTimerConflict::GetTimerConflictIndex(void) { + return GetActive(); +} + // --- cRecMenuNoTimerConflict --------------------------------------------------------- cRecMenuNoTimerConflict::cRecMenuNoTimerConflict(void) { SetWidthPercent(50); @@ -299,8 +325,7 @@ cRecMenuRerunResults::cRecMenuRerunResults(const cEvent *original, const cEvent if (reruns && (numReruns > 0)) { for (int i=0; i(GetActiveMenuItem()); + return activeItem->GetEventValue(); +} + // --- cRecMenuNoRerunsFound --------------------------------------------------------- cRecMenuNoRerunsFound::cRecMenuNoRerunsFound(cString searchString) { SetWidthPercent(50); @@ -365,94 +395,149 @@ cRecMenuConfirmRerunUsed::cRecMenuConfirmRerunUsed(const cEvent *original, const } // --- cRecMenuEditTimer --------------------------------------------------------- -cRecMenuEditTimer::cRecMenuEditTimer(const cTimer *timer, eRecMenuState nextState) { +cRecMenuEditTimer::cRecMenuEditTimer(cTimer *timer, eRecMenuState nextState) { SetWidthPercent(60); - if (timer) { - cString title(""); - cString channelName(""); - if (timer->Event()) - title = timer->Event()->Title(); - if (timer->Channel()) - channelName = timer->Channel()->Name(); - cString infoText = cString::sprintf("%s:\n %s, %s", tr("Edit Timer"), *title, *channelName); - cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); - infoItem->CalculateHeight(width - 2 * border); - AddMenuItem(infoItem); - - bool timerActive = false; - if (tvguideConfig.useRemoteTimers && pRemoteTimers) { - RemoteTimers_GetMatch_v1_0 rtMatch; - rtMatch.event = timer->Event(); - pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch); - if (rtMatch.timer) { - if (rtMatch.timerMatch == tmFull) - timerActive = true; - } - } else - timerActive = timer->HasFlags(tfActive); - - time_t day = timer->Day(); - int start = timer->Start(); - int stop = timer->Stop(); - int prio = timer->Priority(); - int lifetime = timer->Lifetime(); - - AddMenuItem(new cRecMenuItemBool(tr("Timer Active"), timerActive, false, true)); - AddMenuItem(new cRecMenuItemInt(tr("Priority"), prio, 0, MAXPRIORITY, false)); - AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, MAXLIFETIME, false)); - AddMenuItem(new cRecMenuItemDay(tr("Day"), day, false)); - AddMenuItem(new cRecMenuItemTime(tr("Timer start time"), start, false)); - AddMenuItem(new cRecMenuItemTime(tr("Timer stop time"), stop, false)); - if (nextState == rmsTimelineTimerSave) { - AddMenuItem(new cRecMenuItemButton(tr("Delete Timer"), rmsTimelineTimerDelete, false, false)); - AddMenuItem(new cRecMenuItemButtonYesNo(tr("Save"), tr("Cancel"), nextState, rmsTimeline, false)); - } else { - AddMenuItem(new cRecMenuItemButtonYesNo(tr("Save"), tr("Cancel"), nextState, rmsClose, false)); + if (!timer) + return; + originalTimer = timer; + cString title(""); + cString channelName(""); + if (timer->Event()) + title = timer->Event()->Title(); + if (timer->Channel()) + channelName = timer->Channel()->Name(); + cString infoText = cString::sprintf("%s:\n %s, %s", tr("Edit Timer"), *title, *channelName); + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); + infoItem->CalculateHeight(width - 2 * border); + AddMenuItem(infoItem); + + timerActive = false; + if (tvguideConfig.useRemoteTimers && pRemoteTimers) { + RemoteTimers_GetMatch_v1_0 rtMatch; + rtMatch.event = timer->Event(); + pRemoteTimers->Service("RemoteTimers::GetMatch-v1.0", &rtMatch); + if (rtMatch.timer) { + if (rtMatch.timerMatch == tmFull) + timerActive = true; } - CalculateHeight(); - CreatePixmap(); - Arrange(); + } else + timerActive = timer->HasFlags(tfActive); + + day = timer->Day(); + start = timer->Start(); + stop = timer->Stop(); + prio = timer->Priority(); + lifetime = timer->Lifetime(); + + AddMenuItem(new cRecMenuItemBool(tr("Timer Active"), timerActive, false, true, &timerActive)); + AddMenuItem(new cRecMenuItemInt(tr("Priority"), prio, 0, MAXPRIORITY, false, &prio)); + AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, MAXLIFETIME, false, &lifetime)); + AddMenuItem(new cRecMenuItemDay(tr("Day"), day, false, &day)); + AddMenuItem(new cRecMenuItemTime(tr("Timer start time"), start, false, &start)); + AddMenuItem(new cRecMenuItemTime(tr("Timer stop time"), stop, false, &stop)); + if (nextState == rmsTimelineTimerSave) { + AddMenuItem(new cRecMenuItemButton(tr("Delete Timer"), rmsTimelineTimerDelete, false, false)); + AddMenuItem(new cRecMenuItemButtonYesNo(tr("Save"), tr("Cancel"), nextState, rmsTimeline, false)); + } else { + AddMenuItem(new cRecMenuItemButtonYesNo(tr("Save"), tr("Cancel"), nextState, rmsClose, false)); } + CalculateHeight(); + CreatePixmap(); + Arrange(); } +cTimer *cRecMenuEditTimer::GetOriginalTimer(void) { + return originalTimer; +} + +cTimer cRecMenuEditTimer::GetTimer(void) { + cTimer t; + if (timerActive) + t.SetFlags(tfActive); + else + t.SetFlags(tfNone); + t.SetDay(day); + t.SetStart(start); + t.SetStop(stop); + t.SetPriority(prio); + t.SetLifetime(lifetime); + return t; +} + +/****************************************************************************************** +* Series Timer Menus +******************************************************************************************/ + // --- cRecMenuSeriesTimer --------------------------------------------------------- -cRecMenuSeriesTimer::cRecMenuSeriesTimer(cChannel *initialChannel, const cEvent *event) { +cRecMenuSeriesTimer::cRecMenuSeriesTimer(cChannel *initialChannel, const cEvent *event, std::string folder) { + if (!initialChannel) + return; + timerActive = true; + channel = initialChannel->Number(); + dayOfWeek = 127; + priority = MAXPRIORITY; + lifetime = MAXLIFETIME; + CalculateTimes(event); + this->folder = folder; + SetWidthPercent(70); - if (initialChannel) { - cString title = tr("Create Series Timer based on"); - cString infoText = cString::sprintf("%s:\n%s", *title, event->Title()); - cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); - infoItem->CalculateHeight(width - 2 * border); - AddMenuItem(infoItem); - AddMenuItem(new cRecMenuItemBool(tr("Timer Active"), true, false, true)); - AddMenuItem(new cRecMenuItemChannelChooser(tr("Channel"), initialChannel, false)); - - time_t tstart = event->StartTime(); - tstart -= Setup.MarginStart * 60; - time_t tstop = tstart + event->Duration(); - tstop += Setup.MarginStop * 60; - - struct tm tm_r; - struct tm *time = localtime_r(&tstart, &tm_r); - int start = time->tm_hour * 100 + time->tm_min; - time = localtime_r(&tstop, &tm_r); - int stop = time->tm_hour * 100 + time->tm_min; - if (stop >= 2400) - stop -= 2400; - - AddMenuItem(new cRecMenuItemTime(tr("Series Timer start time"), start, false)); - AddMenuItem(new cRecMenuItemTime(tr("Series Timer stop time"), stop, false)); - AddMenuItem(new cRecMenuItemDayChooser(tr("Days to record"), 127, false)); - AddMenuItem(new cRecMenuItemDay(tr("Day to start"), tstart, false)); - AddMenuItem(new cRecMenuItemInt(tr("Priority"), MAXPRIORITY, 0, MAXPRIORITY, false)); - AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), MAXLIFETIME, 0, MAXLIFETIME, false)); + cString title = tr("Create Series Timer based on"); + cString infoText = cString::sprintf("%s:\n%s", *title, event->Title()); + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); + infoItem->CalculateHeight(width - 2 * border); + SetHeader(infoItem); - AddMenuItem(new cRecMenuItemButtonYesNo(tr("Create Timer"), tr("Cancel"), rmsSeriesTimerCreate, rmsClose, false)); + AddMenuItem(new cRecMenuItemBool(tr("Timer Active"), timerActive, false, true, &timerActive)); + AddMenuItem(new cRecMenuItemChannelChooser(tr("Channel"), initialChannel, false, &channel)); + AddMenuItem(new cRecMenuItemTime(tr("Series Timer start time"), start, false, &start)); + AddMenuItem(new cRecMenuItemTime(tr("Series Timer stop time"), stop, false, &stop)); + AddMenuItem(new cRecMenuItemDayChooser(tr("Days to record"), dayOfWeek, false, &dayOfWeek)); + AddMenuItem(new cRecMenuItemDay(tr("Day to start"), tstart, false, &tstart)); + AddMenuItem(new cRecMenuItemInt(tr("Priority"), priority, 0, MAXPRIORITY, false, &priority)); + AddMenuItem(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, MAXLIFETIME, false, &lifetime)); - CalculateHeight(); - CreatePixmap(); - Arrange(); + AddMenuItem(new cRecMenuItemButtonYesNo(tr("Create Timer"), tr("Cancel"), rmsSeriesTimerCreate, rmsClose, false)); + + CalculateHeight(); + CreatePixmap(); + Arrange(); +} + +cTimer *cRecMenuSeriesTimer::GetTimer(void) { + cChannel *chan = Channels.GetByNumber(channel); + cTimer *seriesTimer = new cTimer(NULL, NULL, chan); + cString fileName = "TITLE EPISODE"; + if (folder.size() > 0) { + std::replace(folder.begin(), folder.end(), '/', '~'); + fileName = cString::sprintf("%s~%s", folder.c_str(), *fileName); } + seriesTimer->SetDay(tstart); + seriesTimer->SetStart(start); + seriesTimer->SetStop(stop); + seriesTimer->SetPriority(priority); + seriesTimer->SetLifetime(lifetime); + seriesTimer->SetWeekDays(dayOfWeek); + seriesTimer->SetFile(*fileName); + if (timerActive) + seriesTimer->SetFlags(tfActive); + else + seriesTimer->SetFlags(tfNone); + return seriesTimer; +} + +void cRecMenuSeriesTimer::CalculateTimes(const cEvent *event) { + tstart = event->StartTime(); + tstart -= Setup.MarginStart * 60; + time_t tstop = tstart + event->Duration(); + tstop += Setup.MarginStop * 60; + + struct tm tm_r; + struct tm *time = localtime_r(&tstart, &tm_r); + start = time->tm_hour * 100 + time->tm_min; + time = localtime_r(&tstop, &tm_r); + stop = time->tm_hour * 100 + time->tm_min; + if (stop >= 2400) + stop -= 2400; } // --- cRecMenuConfirmSeriesTimer --------------------------------------------------------- @@ -473,6 +558,10 @@ cRecMenuConfirmSeriesTimer::cRecMenuConfirmSeriesTimer(cTimer *seriesTimer) { Arrange(); } +/****************************************************************************************** +* SearchTimer Menus +******************************************************************************************/ + // --- cRecMenuSearchTimer --------------------------------------------------------- cRecMenuSearchTimer::cRecMenuSearchTimer(const cEvent *event) { SetWidthPercent(70); @@ -480,32 +569,32 @@ cRecMenuSearchTimer::cRecMenuSearchTimer(const cEvent *event) { cString infoText = cString::sprintf("%s:\n\"%s\"", *message, event->Title()); cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); infoItem->CalculateHeight(width - 2 * border); - AddMenuItem(infoItem); - strn0cpy(initialText, event->Title(), sizeof(initialText)); - AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), initialText, sizeof(initialText), false)); - AddMenuItem(new cRecMenuItemButtonYesNo(tr("Continue"), tr("Cancel"), rmsSearchTimerOptions, rmsClose, true)); + SetHeader(infoItem); + strncpy(searchString, event->Title(), TEXTINPUTLENGTH); + AddMenuItemInitial(new cRecMenuItemText(tr("Search Expression:"), searchString, TEXTINPUTLENGTH, false)); + AddMenuItemInitial(new cRecMenuItemButtonYesNo(tr("Continue"), tr("Cancel"), rmsSearchTimerOptions, rmsClose, true)); CalculateHeight(); CreatePixmap(); Arrange(); } // --- cRecMenuSearchTimerTemplates --------------------------------------------------------- -cRecMenuSearchTimerTemplates::cRecMenuSearchTimerTemplates(cString searchString, std::vector templates) { +cRecMenuSearchTimerTemplates::cRecMenuSearchTimerTemplates(cTVGuideSearchTimer searchTimer, std::vector templates) { + this->searchTimer = searchTimer; this->templates = templates; SetWidthPercent(70); cString message = tr("Configure Search Timer for Search String"); - cString infoText = cString::sprintf("%s:\n%s", *message, *searchString); + cString infoText = cString::sprintf("%s:\n%s", *message, searchTimer.SearchString().c_str()); cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); infoItem->CalculateHeight(width - 2 * border); SetHeader(infoItem); - AddMenuItemScroll(new cRecMenuItemButton(tr("Manually configure Options"), rmsSearchTimerOptionsManually, true)); + AddMenuItemInitial(new cRecMenuItemButton(tr("Manually configure Options"), rmsSearchTimerEdit, true)); numTemplates = templates.size(); for (int i=0; i 0) && (number < numTemplates + 1)) { cString buttonText = cString::sprintf("%s \"%s\"", tr("Use Template"), templates[number-1].name.c_str()); - cRecMenuItem *templ = new cRecMenuItemButton(*buttonText, rmsSearchTimerUseTemplate, false); + cRecMenuItem *templ = new cRecMenuItemButton(*buttonText, rmsSearchTimerCreateWithTemplate, false); return templ; } return NULL; @@ -528,158 +617,299 @@ int cRecMenuSearchTimerTemplates::GetTotalNumMenuItems(void) { return numTemplates + 1; } -// --- cRecMenuSearchTimerTemplatesCreate --------------------------------------------------------- -cRecMenuSearchTimerTemplatesCreate::cRecMenuSearchTimerTemplatesCreate(cString searchString, cString tmplName) { +TVGuideEPGSearchTemplate cRecMenuSearchTimerTemplates::GetTemplate(void) { + TVGuideEPGSearchTemplate templ; + int tmplActive = GetActive() - 1; + if (tmplActive >= 0 && tmplActive < templates.size()) + templ = templates[tmplActive]; + return templ; +} +// --- cRecMenuSearchTimers --------------------------------------------------------- +cRecMenuSearchTimers::cRecMenuSearchTimers(std::vector searchTimers) { + this->searchTimers = searchTimers; + numSearchTimers = searchTimers.size(); SetWidthPercent(70); - - cString message1 = tr("Creating Search Timer"); - cString message2 = tr("Search Term"); - cString message3 = tr("Using Template"); - - cString infoText = cString::sprintf("%s\n%s: \"%s\"\n%s \"%s\"", *message1, *message2, *searchString, *message3, *tmplName); - cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); + cString headline; + if (numSearchTimers > 0) { + headline = tr("Manage EPGSearch Search Timers"); + } else { + headline = tr("No Search Timers Configured"); + } + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*headline); infoItem->CalculateHeight(width - 2 * border); - AddMenuItem(infoItem); - - AddMenuItem(new cRecMenuItemButton(tr("Display Results for Search Timer"), rmsSearchTimerTestTemplate, true)); - AddMenuItem(new cRecMenuItemButtonYesNo(tr("Create Search Timer"), tr("Use other Template"), rmsSearchTimerCreateTemplate, rmsSearchTimerOptionsReload, false)); - + SetHeader(infoItem); + if (numSearchTimers > 0) + SetMenuItems(); + cRecMenuItem *button = new cRecMenuItemButton(tr("Close"), rmsClose, (!numSearchTimers)?true:false); + SetFooter(button); CalculateHeight(); CreatePixmap(); Arrange(); } -// --- cRecMenuSearchTimerOptions --------------------------------------------------------- -cRecMenuSearchTimerOptions::cRecMenuSearchTimerOptions(cString searchString) { - this->searchString = searchString; +cRecMenuSearchTimers::~cRecMenuSearchTimers(void) { + +} + +void cRecMenuSearchTimers::SetMenuItems(void) { + for (int i = 0; i < numSearchTimers; i++) { + AddMenuItemInitial(new cRecMenuItemSearchTimer(searchTimers[i], rmsSearchTimerEdit, rmsSearchTimerDeleteConfirm, (i==0)?true:false)); + } +} + +cTVGuideSearchTimer cRecMenuSearchTimers::GetSearchTimer(void) { + cRecMenuItemSearchTimer *activeItem = dynamic_cast(GetActiveMenuItem()); + return activeItem->GetTimer(); +} + +cRecMenuItem *cRecMenuSearchTimers::GetMenuItem(int number) { + if (number < 0 || number >= numSearchTimers) + return NULL; + return new cRecMenuItemSearchTimer(searchTimers[number], rmsSearchTimerEdit, rmsSearchTimerDelete, false); +} + +int cRecMenuSearchTimers::GetTotalNumMenuItems(void) { + return numSearchTimers; +} + +// --- cRecMenuSearchTimerEdit --------------------------------------------------------- +cRecMenuSearchTimerEdit::cRecMenuSearchTimerEdit(cTVGuideSearchTimer searchTimer, bool advancedOptions) { + deleteMenuItems = false; + this->advancedOptions = advancedOptions; + this->searchTimer = searchTimer; + strncpy(searchString, searchTimer.SearchString().c_str(), TEXTINPUTLENGTH); + timerActive = searchTimer.Active(); + mode = searchTimer.SearchMode(); + useTitle = searchTimer.UseTitle(); + useSubtitle = searchTimer.UseSubtitle(); + useDescription = searchTimer.UseDescription(); + useChannel = searchTimer.UseChannel(); + startChannel = searchTimer.StartChannel(); + stopChannel = searchTimer.StopChannel(); + useTime = searchTimer.UseTime(); + startTime = searchTimer.StartTime(); + stopTime = searchTimer.StopTime(); + useDayOfWeek = searchTimer.UseDayOfWeek(); + dayOfWeek = searchTimer.DayOfWeek(); + priority = searchTimer.Priority(); + lifetime = searchTimer.Lifetime(); + marginStart = searchTimer.MarginStart(); + marginStop = searchTimer.MarginStop(); + useVPS = searchTimer.UseVPS(); + avoidRepeats = searchTimer.AvoidRepeats(); + allowedRepeats = searchTimer.AllowedRepeats(); + compareTitle = searchTimer.CompareTitle(); + compareSubtitle = searchTimer.CompareSubtitle(); + compareSummary = searchTimer.CompareSummary(); + + SetWidthPercent(70); + cString infoText; + if (searchTimer.GetID() > -1) { + infoText = tr("Configure Search Timer Options"); + } else { + infoText = tr("Create Search Timer"); + } + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); + infoItem->CalculateHeight(width - 2 * border); + SetHeader(infoItem); + cRecMenuItemButtonYesNo *footerButton = new cRecMenuItemButtonYesNo(tr("Save Search Timer"), tr("Cancel"), rmsSearchTimerSave, rmsSearchTimers, false); + SetFooter(footerButton); + InitMenuItems(); CreateMenuItems(); } -void cRecMenuSearchTimerOptions::CreateMenuItems(void) { - bool showChannelSelectors = false; - bool showTimeSelectors = false; - if (menuItems.Count() > 0) { - showChannelSelectors = GetBoolValue(4); - if (GetIntValue(5)>-1) { - showTimeSelectors = GetBoolValue(7); - } else { - showTimeSelectors = GetBoolValue(5); - } - osdManager.releasePixmap(pixmap); - delete header; - menuItems.Clear(); +cRecMenuSearchTimerEdit::~cRecMenuSearchTimerEdit(void) { + for (std::vector::iterator it = mainMenuItems.begin(); it != mainMenuItems.end(); it++) { + delete *it; } - SetWidthPercent(70); - cString message = tr("Configure Search Timer Options for Search String"); - cString infoText = cString::sprintf("%s:\n%s", *message, *searchString); - cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); - infoItem->CalculateHeight(width - 2 * border); - SetHeader(infoItem); - - searchModes[0] = tr("whole term must appear"); - searchModes[1] = tr("all terms must exist"); - searchModes[2] = tr("one term must exist"); - searchModes[3] = tr("exact match"); - searchModes[4] = tr("regular expression"); - AddMenuItem(new cRecMenuItemSelect(tr("Search Mode"), searchModes, 0, 5, false)); - AddMenuItem(new cRecMenuItemBool(tr("Use Title"), true, false, false)); - AddMenuItem(new cRecMenuItemBool(tr("Use Subtitle"), true, false, false)); - AddMenuItem(new cRecMenuItemBool(tr("Use Description"), false, false, false)); - - AddMenuItem(new cRecMenuItemBool(tr("Limit Channels"), showChannelSelectors, true, false)); - if (showChannelSelectors) { - cChannel *startChannel = NULL; - for (startChannel = Channels.First(); startChannel; startChannel = Channels.Next(startChannel)) { - if (!startChannel->GroupSep()) - break; - } - AddMenuItem(new cRecMenuItemChannelChooser(tr("Start Channel"), startChannel, false)); - AddMenuItem(new cRecMenuItemChannelChooser(tr("Stop Channel"), startChannel, false)); + mainMenuItems.clear(); + for (std::vector::iterator it = useChannelSubMenu.begin(); it != useChannelSubMenu.end(); it++) { + delete *it; } - - AddMenuItem(new cRecMenuItemBool(tr("Use Time"), showTimeSelectors, true, false)); - if (showTimeSelectors) { - AddMenuItem(new cRecMenuItemTime(tr("Start after"), 0, false)); - AddMenuItem(new cRecMenuItemTime(tr("Start before"), 2359, false)); + useChannelSubMenu.clear(); + for (std::vector::iterator it = useTimeSubMenu.begin(); it != useTimeSubMenu.end(); it++) { + delete *it; } - - AddMenuItem(new cRecMenuItemButton(tr("Display Results for Search Timer"), rmsSearchTimerTestManually, true)); - AddMenuItem(new cRecMenuItemButtonYesNo(tr("Create Search Timer"), tr("Cancel"), rmsSearchTimerCreateManually, rmsClose, false)); - CalculateHeight(); - CreatePixmap(); - Arrange(); + useTimeSubMenu.clear(); + for (std::vector::iterator it = useDayOfWeekSubMenu.begin(); it != useDayOfWeekSubMenu.end(); it++) { + delete *it; + } + useDayOfWeekSubMenu.clear(); + for (std::vector::iterator it = avoidRepeatSubMenu.begin(); it != avoidRepeatSubMenu.end(); it++) { + delete *it; + } + avoidRepeatSubMenu.clear(); + currentMenuItems.clear(); } -// --- cRecMenuSearchTimerResults --------------------------------------------------------- -cRecMenuSearchTimerResults::cRecMenuSearchTimerResults(cString searchString, const cEvent **searchResults, int numResults, std::string templateName) { - this->searchResults = searchResults; - SetWidthPercent(70); - cString message1 = tr("search results for Search Timer"); - cString message2 = tr("search result for Search Timer"); - this->numResults = numResults; - cString message3 = tr("Using Template"); - cString infoText; - if (templateName.size() > 0) { - infoText = cString::sprintf("%d %s:\n\"%s\"\n%s \"%s\"", numResults, (numResults>1)?(*message1):(*message2), *searchString, *message3, templateName.c_str()); +void cRecMenuSearchTimerEdit::InitMenuItems(void) { + + useChannelPos = 6; + useTimePos = 7; + useDayOfWeekPos = 8; + avoidRepeatsPos = 14; + + mainMenuItems.push_back(new cRecMenuItemText(tr("Search String"), searchString, TEXTINPUTLENGTH, false, searchString)); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Active"), timerActive, false, false, &timerActive, rmsSearchTimerSave)); + std::vector searchModes; + searchTimer.GetSearchModes(&searchModes); + mainMenuItems.push_back(new cRecMenuItemSelect(tr("Search Mode"), searchModes, mode, false, &mode, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Use Title"), useTitle, false, false, &useTitle, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Use Subtitle"), useSubtitle, false, false, &useSubtitle, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Use Description"), useDescription, false, false, &useDescription, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Limit Channels"), useChannel, true, false, &useChannel, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Use Time"), useTime, true, false, &useTime, rmsSearchTimerSave)); + if (!advancedOptions) { + mainMenuItems.push_back(new cRecMenuItemButton(tr("Display advanced Options"), rmsSearchTimerEditAdvanced, false)); } else { - infoText = cString::sprintf("%d %s:\n\"%s\"", numResults, (numResults>1)?(*message1):(*message2), *searchString); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Limit Days of the Week"), useDayOfWeek, true, false, &useDayOfWeek, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemInt(tr("Priority"), priority, 0, 99, false, &priority, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemInt(tr("Lifetime"), lifetime, 0, 99, false, &lifetime, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemInt(tr("Time margin for start in minutes"), marginStart, 0, 30, false, &marginStart, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemInt(tr("Time margin for stop in minutes"), marginStop, 0, 30, false, &marginStop, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Use VPS"), useVPS, false, false, &useVPS, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemBool(tr("Avoid Repeats"), avoidRepeats, true, false, &avoidRepeats, rmsSearchTimerSave)); + mainMenuItems.push_back(new cRecMenuItemButton(tr("Hide advanced Options"), rmsSearchTimerEdit, false)); + } + mainMenuItems.push_back(new cRecMenuItemButton(tr("Display Results for Search Timer"), rmsSearchTimerTest, false)); + + if (startChannel == 0) + startChannel = 1; + if (stopChannel == 0) + stopChannel = 1; + useChannelSubMenu.push_back(new cRecMenuItemChannelChooser(tr("Start Channel"), Channels.GetByNumber(startChannel), false, &startChannel, rmsSearchTimerSave)); + useChannelSubMenu.push_back(new cRecMenuItemChannelChooser(tr("Stop Channel"), Channels.GetByNumber(stopChannel), false, &stopChannel, rmsSearchTimerSave)); + + useTimeSubMenu.push_back(new cRecMenuItemTime(tr("Start after"), startTime, false, &startTime, rmsSearchTimerSave)); + useTimeSubMenu.push_back(new cRecMenuItemTime(tr("Start before"), stopTime, false, &stopTime, rmsSearchTimerSave)); + + if (advancedOptions) { + useDayOfWeekSubMenu.push_back(new cRecMenuItemDayChooser(tr("Select Days"), dayOfWeek, false, &dayOfWeek)); + avoidRepeatSubMenu.push_back(new cRecMenuItemInt(tr("Number of allowed repeats"), allowedRepeats, 1, 30, false, &allowedRepeats, rmsSearchTimerSave)); + avoidRepeatSubMenu.push_back(new cRecMenuItemBool(tr("Compare Title"), compareTitle, false, false, &compareTitle, rmsSearchTimerSave)); + avoidRepeatSubMenu.push_back(new cRecMenuItemBool(tr("Compare Subtitle"), compareSubtitle, false, false, &compareSubtitle, rmsSearchTimerSave)); + avoidRepeatSubMenu.push_back(new cRecMenuItemBool(tr("Compare Description"), compareSummary, false, false, &compareSummary, rmsSearchTimerSave)); + } +} + + +void cRecMenuSearchTimerEdit::CreateMenuItems(void) { + bool reDraw = false; + if (GetCurrentNumMenuItems() > 0) { + InitMenu(false); + currentMenuItems.clear(); + reDraw = true; } - cRecMenuItem *infoItem = new cRecMenuItemInfo(*infoText); - infoItem->CalculateHeight(width - 2 * border); - SetHeader(infoItem); - cRecMenuItem *buttons = new cRecMenuItemButton(tr("Close"), rmsClose, false); - SetFooter(buttons); - if (searchResults && (numResults > 0)) { - for (int i=0; isetActive(); + } + if (!AddMenuItemInitial(currentMenuItems[i])) { + break; } } + numMenuItems = currentMenuItems.size(); CalculateHeight(); CreatePixmap(); Arrange(); } - -cRecMenuItem *cRecMenuSearchTimerResults::GetMenuItem(int number) { - if ((number >= 0) && (number < numResults)) { - cRecMenuItem *result = new cRecMenuItemEvent(searchResults[number], rmsSearchShowInfo, rmsDisabled, false); - return result; + +void cRecMenuSearchTimerEdit::AddSubMenu(std::vector *subMenu) { + for (std::vector::iterator it = subMenu->begin(); it < subMenu->end(); it++) { + currentMenuItems.push_back(*it); + } +} + + +cTVGuideSearchTimer cRecMenuSearchTimerEdit::GetSearchTimer(void) { + searchTimer.SetSearchString(searchString); + searchTimer.SetActive(timerActive); + searchTimer.SetSearchMode(mode); + searchTimer.SetUseTitle(useTitle); + searchTimer.SetUseSubtitle(useSubtitle); + searchTimer.SetUseDesription(useDescription); + searchTimer.SetUseChannel(useChannel); + if (useChannel) { + searchTimer.SetStartChannel(startChannel); + searchTimer.SetStopChannel(stopChannel); + } + searchTimer.SetUseTime(useTime); + if (useTime) { + searchTimer.SetStartTime(startTime); + searchTimer.SetStopTime(stopTime); + } + searchTimer.SetUseDayOfWeek(useDayOfWeek); + if (useDayOfWeek) { + searchTimer.SetDayOfWeek(dayOfWeek); + } + searchTimer.SetPriority(priority); + searchTimer.SetLifetime(lifetime); + searchTimer.SetMarginStart(marginStart); + searchTimer.SetMarginStop(marginStop); + searchTimer.SetUseVPS(useVPS); + searchTimer.SetAvoidRepeats(avoidRepeats); + if (avoidRepeats) { + searchTimer.SetAllowedRepeats(allowedRepeats); + searchTimer.SetCompareTitle(compareTitle); + searchTimer.SetCompareSubtitle(compareSubtitle); + searchTimer.SetCompareSummary(compareSummary); + } + return searchTimer; +} + +int cRecMenuSearchTimerEdit::GetTotalNumMenuItems(void) { + return numMenuItems; +} + +cRecMenuItem *cRecMenuSearchTimerEdit::GetMenuItem(int number) { + if ((number > -1) && (number < numMenuItems)) { + return currentMenuItems[number]; } return NULL; } -int cRecMenuSearchTimerResults::GetTotalNumMenuItems(void) { - return numResults; -} - -// --- cRecMenuSearchTimerNothingFound --------------------------------------------------------- -cRecMenuSearchTimerNothingFound::cRecMenuSearchTimerNothingFound(cString searchString, std::string templateName) { - SetWidthPercent(50); - cString message = tr("Nothing found for Search String"); - cString message2 = tr("Using Template"); - cString text; - if (templateName.size() > 0) { - text = cString::sprintf("%s\n\"%s\"\n%s \"%s\"", - *message, - *searchString, - *message2, - templateName.c_str()); - } else { - text = cString::sprintf("%s\n\"%s\"", - *message, - *searchString); - } - cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*text); +// --- cRecMenuSearchTimerDeleteConfirm --------------------------------------------- +cRecMenuSearchTimerDeleteConfirm::cRecMenuSearchTimerDeleteConfirm(cTVGuideSearchTimer searchTimer) { + this->searchTimer = searchTimer; + SetWidthPercent(70); + cString message = tr("Really delete Search Timer"); + cString infoText = cString::sprintf("%s \"%s\"?", *message, searchTimer.SearchString().c_str()); + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); infoItem->CalculateHeight(width - 2 * border); - AddMenuItem(infoItem); - AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsSearchTimerNothingFoundConfirm, true, true)); + SetHeader(infoItem); + AddMenuItem(new cRecMenuItemButton(tr("Delete only Search Timer"), rmsSearchTimerDelete, true)); + AddMenuItem(new cRecMenuItemButton(tr("Delete Search Timer and created Timers"), rmsSearchTimerDeleteWithTimers, false)); + SetFooter(new cRecMenuItemButton(tr("Cancel"), rmsClose, false)); CalculateHeight(); CreatePixmap(); Arrange(); } +cRecMenuSearchTimerDeleteConfirm::~cRecMenuSearchTimerDeleteConfirm(void) { + +} + +cTVGuideSearchTimer cRecMenuSearchTimerDeleteConfirm::GetSearchTimer(void) { + return searchTimer; +} + // --- cRecMenuSearchTimerCreateConfirm --------------------------------------------------------- cRecMenuSearchTimerCreateConfirm::cRecMenuSearchTimerCreateConfirm(bool success) { SetWidthPercent(50); @@ -700,8 +930,106 @@ cRecMenuSearchTimerCreateConfirm::cRecMenuSearchTimerCreateConfirm(bool success) Arrange(); } +// --- cRecMenuSearchTimerTemplatesCreate --------------------------------------------------------- +cRecMenuSearchTimerTemplatesCreate::cRecMenuSearchTimerTemplatesCreate(TVGuideEPGSearchTemplate templ, cTVGuideSearchTimer searchTimer) { + this->templ = templ; + this->searchTimer = searchTimer; + SetWidthPercent(70); + + cString message1 = tr("Creating Search Timer"); + cString message2 = tr("Search Term"); + cString message3 = tr("Using Template"); + + cString infoText = cString::sprintf("%s\n%s: \"%s\"\n%s \"%s\"", *message1, *message2, searchTimer.SearchString().c_str(), *message3, templ.name.c_str()); + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); + infoItem->CalculateHeight(width - 2 * border); + AddMenuItem(infoItem); + + AddMenuItem(new cRecMenuItemButton(tr("Display Results for Search Timer"), rmsSearchTimerTest, true)); + AddMenuItem(new cRecMenuItemButtonYesNo(tr("Create Search Timer"), tr("Use other Template"), rmsSearchTimerSave, rmsSearchTimerOptions, false)); + + CalculateHeight(); + CreatePixmap(); + Arrange(); +} + + +// --- cRecMenuSearchTimerResults --------------------------------------------------------- +cRecMenuSearchTimerResults::cRecMenuSearchTimerResults(std::string searchString, const cEvent **searchResults, int numResults, std::string templateName) { + this->searchResults = searchResults; + SetWidthPercent(70); + cString message1 = tr("search results for Search Timer"); + cString message2 = tr("search result for Search Timer"); + this->numResults = numResults; + cString message3 = tr("Using Template"); + cString infoText; + if (templateName.size() > 0) { + infoText = cString::sprintf("%d %s:\n\"%s\"\n%s \"%s\"", numResults, (numResults>1)?(*message1):(*message2), searchString.c_str(), *message3, templateName.c_str()); + } else { + infoText = cString::sprintf("%d %s:\n\"%s\"", numResults, (numResults>1)?(*message1):(*message2), searchString.c_str()); + } + cRecMenuItem *infoItem = new cRecMenuItemInfo(*infoText); + infoItem->CalculateHeight(width - 2 * border); + SetHeader(infoItem); + + cRecMenuItem *buttons = new cRecMenuItemButton(tr("Close"), rmsClose, false); + SetFooter(buttons); + if (searchResults && (numResults > 0)) { + for (int i=0; i= 0) && (number < numResults)) { + cRecMenuItem *result = new cRecMenuItemEvent(searchResults[number], rmsSearchShowInfo, rmsDisabled, false); + return result; + } + return NULL; +} + +int cRecMenuSearchTimerResults::GetTotalNumMenuItems(void) { + return numResults; +} + +const cEvent *cRecMenuSearchTimerResults::GetEvent(void) { + const cEvent *ev = NULL; + if (cRecMenuItemEvent *activeItem = dynamic_cast(GetActiveMenuItem())) + ev = activeItem->GetEventValue(); + return ev; +} + +// --- cRecMenuSearchTimerNothingFound --------------------------------------------------------- +cRecMenuSearchTimerNothingFound::cRecMenuSearchTimerNothingFound(std::string searchString) { + SetWidthPercent(50); + cString message = tr("Nothing found for Search String"); + cString text; + text = cString::sprintf("%s\n\"%s\"", + *message, + searchString.c_str()); + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*text); + infoItem->CalculateHeight(width - 2 * border); + AddMenuItem(infoItem); + AddMenuItem(new cRecMenuItemButton(tr("OK"), rmsClose, true, true)); + CalculateHeight(); + CreatePixmap(); + Arrange(); +} + +/****************************************************************************************** +* SwitchTimer Menus +******************************************************************************************/ + // --- cRecMenuSwitchTimer --------------------------------------------------------- cRecMenuSwitchTimer::cRecMenuSwitchTimer(void) { + int switchMinsBefore = 2; + int announceOnly = 0; + SetWidthPercent(60); cString infoText = tr("Configure Options for Switchtimer"); @@ -709,11 +1037,12 @@ cRecMenuSwitchTimer::cRecMenuSwitchTimer(void) { infoItem->CalculateHeight(width - 2 * border); AddMenuItem(infoItem); - AddMenuItem(new cRecMenuItemInt(tr("Minutes before switching"), 2, 0, 10, false)); - switchModes[0] = tr("switch"); - switchModes[1] = tr("announce only"); - switchModes[2] = tr("ask for switch"); - AddMenuItem(new cRecMenuItemSelect(tr("Switch Mode"), switchModes, 0, 3, false)); + AddMenuItem(new cRecMenuItemInt(tr("Minutes before switching"), switchMinsBefore, 0, 10, false, &switchMinsBefore)); + std::vector switchModes; + switchModes.push_back(tr("switch")); + switchModes.push_back(tr("announce only")); + switchModes.push_back(tr("ask for switch")); + AddMenuItem(new cRecMenuItemSelect(tr("Switch Mode"), switchModes, announceOnly, false, &announceOnly)); AddMenuItem(new cRecMenuItemButtonYesNo(tr("Create"), tr("Cancel"), rmsSwitchTimerCreate, rmsClose, true)); @@ -722,6 +1051,13 @@ cRecMenuSwitchTimer::cRecMenuSwitchTimer(void) { Arrange(); } +cSwitchTimer cRecMenuSwitchTimer::GetSwitchTimer(void) { + cSwitchTimer st; + st.switchMinsBefore = switchMinsBefore; + st.announceOnly = announceOnly; + return st; +} + // --- cRecMenuSwitchTimerConfirm --------------------------------------------------------- cRecMenuSwitchTimerConfirm::cRecMenuSwitchTimerConfirm(bool success) { SetWidthPercent(50); @@ -756,55 +1092,64 @@ cRecMenuSwitchTimerDelete::cRecMenuSwitchTimerDelete(void) { Arrange(); } -// --- cRecMenuSearch --------------------------------------------------------- -cRecMenuSearch::cRecMenuSearch(const cEvent *event) { - SetWidthPercent(60); - cString infoText = tr("Search"); - cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); - infoItem->CalculateHeight(width - 2 * border); - AddMenuItem(infoItem); - strn0cpy(initialText, event->Title(), sizeof(initialText)); - AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), initialText, sizeof(initialText), false)); - AddMenuItem(new cRecMenuItemButton(tr("Show Search Options"), rmsSearchWithOptions, false)); - AddMenuItem(new cRecMenuItemButtonYesNo(tr("Perform Search"), tr("Cancel"), rmsSearchPerform, rmsClose, true)); - CalculateHeight(); - CreatePixmap(); - Arrange(); -} - -cRecMenuSearch::cRecMenuSearch(const cEvent *event, const char *searchString) { - SetWidthPercent(60); - cString infoText = tr("Search"); - cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); - infoItem->CalculateHeight(width - 2 * border); - AddMenuItem(infoItem); - strn0cpy(initialText, searchString, sizeof(initialText)); - AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), initialText, sizeof(initialText), false)); - searchModes[0] = tr("whole term must appear"); - searchModes[1] = tr("all terms must exist"); - searchModes[2] = tr("one term must exist"); - searchModes[3] = tr("exact match"); - searchModes[4] = tr("regular expression"); - AddMenuItem(new cRecMenuItemSelect(tr("Search Mode"), searchModes, 0, 5, false)); - AddMenuItem(new cRecMenuItemChannelChooser(tr("Channel to Search"), NULL, false)); - AddMenuItem(new cRecMenuItemBool(tr("Search in title"), true, false, false)); - AddMenuItem(new cRecMenuItemBool(tr("Search in Subtitle"), true, false, false)); - AddMenuItem(new cRecMenuItemBool(tr("Search in Description"), false, false, false)); +/****************************************************************************************** +* Search Menus +******************************************************************************************/ - AddMenuItem(new cRecMenuItemButtonYesNo(tr("Perform Search"), tr("Cancel"), rmsSearchPerform, rmsClose, true)); + +// --- cRecMenuSearch --------------------------------------------------------- +cRecMenuSearch::cRecMenuSearch(std::string searchString, bool withOptions) { + strncpy(this->searchString, searchString.c_str(), TEXTINPUTLENGTH); + mode = 0; + channelNr = 0; + useTitle = true; + useSubTitle = true; + useDescription = false; + SetWidthPercent(60); + cString infoText = tr("Search"); + cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); + infoItem->CalculateHeight(width - 2 * border); + SetHeader(infoItem); + AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), this->searchString, TEXTINPUTLENGTH, false, this->searchString)); + if (withOptions) { + std::vector searchModes; + cTVGuideSearchTimer searchTimer; + searchTimer.GetSearchModes(&searchModes); + AddMenuItemInitial(new cRecMenuItemSelect(tr("Search Mode"), searchModes, 0, false, &mode)); + AddMenuItemInitial(new cRecMenuItemChannelChooser(tr("Channel to Search"), NULL, false, &channelNr)); + AddMenuItemInitial(new cRecMenuItemBool(tr("Search in title"), true, false, false, &useTitle)); + AddMenuItemInitial(new cRecMenuItemBool(tr("Search in Subtitle"), true, false, false, &useSubTitle)); + AddMenuItemInitial(new cRecMenuItemBool(tr("Search in Description"), false, false, false, &useDescription)); + } else { + AddMenuItemInitial(new cRecMenuItemButton(tr("Show Search Options"), rmsSearchWithOptions, false)); + } + cRecMenuItemButtonYesNo *button = new cRecMenuItemButtonYesNo(tr("Perform Search"), tr("Cancel"), rmsSearchPerform, rmsClose, true); + SetFooter(button); CalculateHeight(); CreatePixmap(); Arrange(); } +Epgsearch_searchresults_v1_0 cRecMenuSearch::GetEPGSearchStruct(void) { + Epgsearch_searchresults_v1_0 data; + data.query = searchString; + data.mode = mode; + data.channelNr = channelNr; + data.useTitle = useTitle; + data.useSubTitle = useSubTitle; + data.useDescription = useDescription; + return data; +} + + // --- cRecMenuSearchResults --------------------------------------------------------- -cRecMenuSearchResults::cRecMenuSearchResults(cString searchString, const cEvent **searchResults, int numResults) { +cRecMenuSearchResults::cRecMenuSearchResults(std::string searchString, const cEvent **searchResults, int numResults) { this->searchResults = searchResults; SetWidthPercent(70); this->numResults = numResults; cString message1 = tr("search results for"); cString message2 = tr("search result for"); - cString infoText = cString::sprintf("%d %s:\n\"%s\"", numResults, (numResults>1)?(*message1):(*message2), *searchString); + cString infoText = cString::sprintf("%d %s:\n\"%s\"", numResults, (numResults>1)?(*message1):(*message2), searchString.c_str()); cRecMenuItem *infoItem = new cRecMenuItemInfo(*infoText); infoItem->CalculateHeight(width - 2 * border); SetHeader(infoItem); @@ -813,8 +1158,7 @@ cRecMenuSearchResults::cRecMenuSearchResults(cString searchString, const cEvent SetFooter(buttons); if (searchResults && (numResults > 0)) { for (int i=0; i(GetActiveMenuItem())) + ev = activeItem->GetEventValue(); + return ev; +} + + // --- cRecMenuSearchConfirmTimer --------------------------------------------------------- cRecMenuSearchConfirmTimer::cRecMenuSearchConfirmTimer(const cEvent *event) { SetWidthPercent(50); @@ -858,12 +1210,12 @@ cRecMenuSearchConfirmTimer::cRecMenuSearchConfirmTimer(const cEvent *event) { } // --- cRecMenuSearchNothingFound --------------------------------------------------------- -cRecMenuSearchNothingFound::cRecMenuSearchNothingFound(cString searchString) { +cRecMenuSearchNothingFound::cRecMenuSearchNothingFound(std::string searchString) { SetWidthPercent(50); cString message = tr("Nothing found for Search String"); cString text = cString::sprintf("%s\n\"%s\"", *message, - *searchString); + searchString.c_str()); cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*text); infoItem->CalculateHeight(width - 2 * border); AddMenuItem(infoItem); @@ -873,15 +1225,20 @@ cRecMenuSearchNothingFound::cRecMenuSearchNothingFound(cString searchString) { Arrange(); } +/****************************************************************************************** +* Recording Search Menus +******************************************************************************************/ + // --- cRecMenuRecordingSearch --------------------------------------------------------- -cRecMenuRecordingSearch::cRecMenuRecordingSearch(const cEvent *event) { +cRecMenuRecordingSearch::cRecMenuRecordingSearch(std::string search) { + strncpy(searchString, search.c_str(), TEXTINPUTLENGTH); SetWidthPercent(60); cString infoText = tr("Search in Recordings"); cRecMenuItemInfo *infoItem = new cRecMenuItemInfo(*infoText); infoItem->CalculateHeight(width - 2 * border); - AddMenuItem(infoItem); - strn0cpy(initialText, event->Title(), sizeof(initialText)); - AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), initialText, sizeof(initialText), false)); + SetHeader(infoItem); + + AddMenuItem(new cRecMenuItemText(tr("Search Expression:"), searchString, TEXTINPUTLENGTH, false, searchString)); AddMenuItem(new cRecMenuItemButtonYesNo(tr("Perform Search"), tr("Cancel"), rmsRecordingSearchResult, rmsClose, true)); CalculateHeight(); CreatePixmap(); @@ -889,7 +1246,8 @@ cRecMenuRecordingSearch::cRecMenuRecordingSearch(const cEvent *event) { } // --- cRecMenuRecordingSearchResults --------------------------------------------------------- -cRecMenuRecordingSearchResults::cRecMenuRecordingSearchResults(cString searchString, cRecording **searchResults, int numResults) { +cRecMenuRecordingSearchResults::cRecMenuRecordingSearchResults(std::string searchString, cRecording **searchResults, int numResults) { + this->searchString = searchString; this->searchResults = searchResults; SetWidthPercent(80); cString message1 = tr("Found"); @@ -897,7 +1255,7 @@ cRecMenuRecordingSearchResults::cRecMenuRecordingSearchResults(cString searchStr cString message3 = tr("recordings"); cString message4 = tr("for"); this->numResults = numResults; - cString infoText = cString::sprintf("%s %d %s %s:\n\"%s\"", *message1, numResults, (numResults>1)?(*message3):(*message2), *message4, *searchString); + cString infoText = cString::sprintf("%s %d %s %s:\n\"%s\"", *message1, numResults, (numResults>1)?(*message3):(*message2), *message4, searchString.c_str()); cRecMenuItem *infoItem = new cRecMenuItemInfo(*infoText); infoItem->CalculateHeight(width - 2 * border); SetHeader(infoItem); @@ -906,8 +1264,7 @@ cRecMenuRecordingSearchResults::cRecMenuRecordingSearchResults(cString searchStr SetFooter(buttons); if (searchResults && (numResults > 0)) { for (int i=0; iCalculateHeight(width - 2 * border); AddMenuItem(infoItem); @@ -944,6 +1301,10 @@ cRecMenuRecordingSearchNotFound::cRecMenuRecordingSearchNotFound(cString searchS Arrange(); } +/****************************************************************************************** +* Timeline +******************************************************************************************/ + // --- cRecMenuTimeline --------------------------------------------------------- cRecMenuTimeline::cRecMenuTimeline(cTVGuideTimerConflicts *timerConflicts) { this->timerConflicts = timerConflicts; @@ -978,7 +1339,7 @@ void cRecMenuTimeline::GetTimersForDay(void) { } void cRecMenuTimeline::SetTimers(void) { - ClearMenuItems(); + ClearMenu(); if (numTimersToday == 0) { AddMenuItem(new cRecMenuItemTimelineTimer(NULL, 0, 0, conflictsToday, header, false)); header->UnsetCurrentTimer(); @@ -988,8 +1349,7 @@ void cRecMenuTimeline::SetTimers(void) { cRecMenuItemTimelineTimer *item = new cRecMenuItemTimelineTimer(timersToday[i], timeStart, timeStop, conflictsToday, header, false); if (i==0) item->setActive(); - AddMenuItemScroll(item); - if (!CheckHeight()) + if (!AddMenuItemInitial(item)) break; } footer->setInactive(); @@ -1039,27 +1399,18 @@ int cRecMenuTimeline::GetTotalNumMenuItems(void) { return numTimersToday; } -void cRecMenuTimeline::ClearMenuItems(void) { - if (pixmap) - osdManager.releasePixmap(pixmap); - pixmap = NULL; - menuItems.Clear(); - if (pixmapScrollBar) - osdManager.releasePixmap(pixmapScrollBar); - if (imgScrollBar) - delete imgScrollBar; +void cRecMenuTimeline::ClearMenu(void) { + InitMenu(true); header->UnsetCurrentTimer(); - height = 2*border + headerHeight + footerHeight; - scrollHeight = 0; - scrollItemHeight = 0; - scrollable = false; - pixmapScrollBar = NULL; - imgScrollBar = NULL; - startIndex = 0; - stopIndex = 0; - numItems = 0; } +cTimer *cRecMenuTimeline::GetTimer(void) { + if (cRecMenuItemTimelineTimer *activeItem = dynamic_cast(GetActiveMenuItem())) + return activeItem->GetTimerValue(); + return NULL; +} + + eRecMenuState cRecMenuTimeline::ProcessKey(eKeys Key) { eRecMenuState state = rmsContinue; switch (Key & ~k_Repeat) { diff --git a/recmenus.h b/recmenus.h index 09d9d8c..2b81686 100644 --- a/recmenus.h +++ b/recmenus.h @@ -1,10 +1,13 @@ #ifndef __TVGUIDE_RECMENUS_H #define __TVGUIDE_RECMENUS_H -#define TEXTINPUTLENGTH 80 +#define TEXTINPUTLENGTH 256 #include +#include #include +#include "services/epgsearch.h" +#include "switchtimer.h" #include "recmanager.h" // --- cRecMenuMain --------------------------------------------------------- @@ -14,6 +17,11 @@ public: virtual ~cRecMenuMain(void) {}; }; +/****************************************************************************************** +* Instant Timer Menus +******************************************************************************************/ + + // --- cRecMenuAskFolder --------------------------------------------------------- class cRecMenuAskFolder: public cRecMenu { private: @@ -25,6 +33,7 @@ public: cRecMenuItem *GetMenuItem(int number); int GetTotalNumMenuItems(void); virtual ~cRecMenuAskFolder(void) {}; + std::string GetFolder(void); }; // --- cRecMenuConfirmTimer --------------------------------------------------------- @@ -53,6 +62,7 @@ class cRecMenuTimerConflicts: public cRecMenu { public: cRecMenuTimerConflicts(cTVGuideTimerConflicts *conflicts); virtual ~cRecMenuTimerConflicts(void) {}; + int GetTimerConflict(void); }; // --- cRecMenuTimerConflict --------------------------------------------------------- @@ -64,6 +74,7 @@ public: cRecMenuItem *GetMenuItem(int number); int GetTotalNumMenuItems(void); virtual ~cRecMenuTimerConflict(void) {}; + int GetTimerConflictIndex(void); }; // --- cRecMenuNoTimerConflict --------------------------------------------------------- @@ -85,6 +96,7 @@ public: virtual ~cRecMenuRerunResults(void) { delete[] reruns; }; + const cEvent *GetRerunEvent(void); }; // --- cRecMenuNoRerunsFound --------------------------------------------------------- @@ -103,17 +115,42 @@ public: // --- cRecMenuEditTimer --------------------------------------------------------- class cRecMenuEditTimer: public cRecMenu { +private: + cTimer *originalTimer; + bool timerActive; + time_t day; + int start; + int stop; + int prio; + int lifetime; public: - cRecMenuEditTimer(const cTimer *timer, eRecMenuState nextState); + cRecMenuEditTimer(cTimer *timer, eRecMenuState nextState); virtual ~cRecMenuEditTimer(void) {}; + cTimer GetTimer(void); + cTimer *GetOriginalTimer(void); }; +/****************************************************************************************** +* Series Timer Menus +******************************************************************************************/ + // --- cRecMenuSeriesTimer --------------------------------------------------------- class cRecMenuSeriesTimer: public cRecMenu { + std::string folder; + bool timerActive; + int channel; + time_t tstart; + int start; + int stop; + int dayOfWeek; + int priority; + int lifetime; + void CalculateTimes(const cEvent *event); public: - cRecMenuSeriesTimer(cChannel *initialChannel, const cEvent *event); + cRecMenuSeriesTimer(cChannel *initialChannel, const cEvent *event, std::string folder); virtual ~cRecMenuSeriesTimer(void) {}; + cTimer *GetTimer(void); }; // --- cRecMenuConfirmSeriesTimer --------------------------------------------------------- @@ -123,65 +160,109 @@ public: virtual ~cRecMenuConfirmSeriesTimer(void) {}; }; +/****************************************************************************************** +* SearchTimer Menus +******************************************************************************************/ + // --- cRecMenuSearchTimer --------------------------------------------------------- class cRecMenuSearchTimer: public cRecMenu { private: - char initialText[TEXTINPUTLENGTH]; + char searchString[TEXTINPUTLENGTH]; public: cRecMenuSearchTimer(const cEvent *event); virtual ~cRecMenuSearchTimer(void) {}; + std::string GetSearchString(void) { return searchString; }; }; // --- cRecMenuSearchTimerTemplates --------------------------------------------------------- class cRecMenuSearchTimerTemplates: public cRecMenu { private: int numTemplates; + cTVGuideSearchTimer searchTimer; std::vector templates; public: - cRecMenuSearchTimerTemplates(cString searchString, std::vector templates); + cRecMenuSearchTimerTemplates(cTVGuideSearchTimer searchTimer, std::vector templates); cRecMenuItem *GetMenuItem(int number); int GetTotalNumMenuItems(void); virtual ~cRecMenuSearchTimerTemplates(void) {}; + cTVGuideSearchTimer GetSearchTimer(void) { return searchTimer; }; + TVGuideEPGSearchTemplate GetTemplate(void); }; -// --- cRecMenuSearchTimerTemplatesCreate --------------------------------------------------------- -class cRecMenuSearchTimerTemplatesCreate: public cRecMenu { -private: -public: - cRecMenuSearchTimerTemplatesCreate(cString searchString, cString tmplName); - virtual ~cRecMenuSearchTimerTemplatesCreate(void) {}; -}; -// --- cRecMenuSearchTimerOptions --------------------------------------------------------- -class cRecMenuSearchTimerOptions: public cRecMenu { +// --- cRecMenuSearchTimers --------------------------------------------------------- +class cRecMenuSearchTimers: public cRecMenu { private: - const char * searchModes[5]; - cString searchString; + int numSearchTimers; + std::vector searchTimers; + void SetMenuItems(void); public: - cRecMenuSearchTimerOptions(cString searchString); - void CreateMenuItems(void); - virtual ~cRecMenuSearchTimerOptions(void) {}; -}; - -// --- cRecMenuSearchTimerResults --------------------------------------------------------- -class cRecMenuSearchTimerResults: public cRecMenu { -private: - const cEvent **searchResults; - int numResults; -public: - cRecMenuSearchTimerResults(cString searchString, const cEvent **searchResults, int numResults, std::string templateName); + cRecMenuSearchTimers(std::vector searchTimers); cRecMenuItem *GetMenuItem(int number); int GetTotalNumMenuItems(void); - virtual ~cRecMenuSearchTimerResults(void) { - delete[] searchResults; - }; + cTVGuideSearchTimer GetSearchTimer(void); + virtual ~cRecMenuSearchTimers(void); }; -// --- cRecMenuSearchTimerNothingFound --------------------------------------------------------- -class cRecMenuSearchTimerNothingFound: public cRecMenu { +// --- cRecMenuSearchTimerEdit --------------------------------------------------------- +class cRecMenuSearchTimerEdit: public cRecMenu { +private: + bool advancedOptions; + cTVGuideSearchTimer searchTimer; + std::vector mainMenuItems; + std::vector useChannelSubMenu; + std::vector useTimeSubMenu; + std::vector useDayOfWeekSubMenu; + std::vector avoidRepeatSubMenu; + std::vector currentMenuItems; + int numMenuItems; + int useChannelPos; + int useTimePos; + int useDayOfWeekPos; + int avoidRepeatsPos; + char searchString[TEXTINPUTLENGTH]; + bool timerActive; + int mode; + bool useTitle; + bool useSubtitle; + bool useDescription; + bool useChannel; + int startChannel; + int stopChannel; + bool useTime; + int startTime; + int stopTime; + bool useDayOfWeek; + int dayOfWeek; + int priority; + int lifetime; + int marginStart; + int marginStop; + bool useVPS; + bool avoidRepeats; + int allowedRepeats; + bool compareTitle; + bool compareSubtitle; + bool compareSummary; + void InitMenuItems(void); + void AddSubMenu(std::vector *subMenu); public: - cRecMenuSearchTimerNothingFound(cString searchString, std::string templateName); - virtual ~cRecMenuSearchTimerNothingFound(void) {}; + cRecMenuSearchTimerEdit(cTVGuideSearchTimer searchTimer, bool advancedOptions); + void CreateMenuItems(void); + virtual ~cRecMenuSearchTimerEdit(void); + cTVGuideSearchTimer GetSearchTimer(void); + cRecMenuItem *GetMenuItem(int number); + int GetTotalNumMenuItems(void); +}; + +// --- cRecMenuSearchTimerDeleteConfirm --------------------------------------------- +class cRecMenuSearchTimerDeleteConfirm: public cRecMenu { +private: + cTVGuideSearchTimer searchTimer; +public: + cRecMenuSearchTimerDeleteConfirm(cTVGuideSearchTimer searchTimer); + virtual ~cRecMenuSearchTimerDeleteConfirm(void); + cTVGuideSearchTimer GetSearchTimer(void); }; // --- cRecMenuSearchTimerCreateConfirm --------------------------------------------------------- @@ -192,13 +273,53 @@ public: virtual ~cRecMenuSearchTimerCreateConfirm(void) {}; }; +// --- cRecMenuSearchTimerTemplatesCreate --------------------------------------------------------- +class cRecMenuSearchTimerTemplatesCreate: public cRecMenu { +private: + TVGuideEPGSearchTemplate templ; + cTVGuideSearchTimer searchTimer; +public: + cRecMenuSearchTimerTemplatesCreate(TVGuideEPGSearchTemplate templ, cTVGuideSearchTimer searchTimer); + virtual ~cRecMenuSearchTimerTemplatesCreate(void) {}; + cTVGuideSearchTimer GetSearchTimer(void) { return searchTimer; }; + TVGuideEPGSearchTemplate GetTemplate(void) { return templ; }; +}; + +// --- cRecMenuSearchTimerResults --------------------------------------------------------- +class cRecMenuSearchTimerResults: public cRecMenu { +private: + const cEvent **searchResults; + int numResults; +public: + cRecMenuSearchTimerResults(std::string searchString, const cEvent **searchResults, int numResults, std::string templateName = ""); + cRecMenuItem *GetMenuItem(int number); + int GetTotalNumMenuItems(void); + virtual ~cRecMenuSearchTimerResults(void) { + delete[] searchResults; + }; + const cEvent *GetEvent(void); +}; + +// --- cRecMenuSearchTimerNothingFound --------------------------------------------------------- +class cRecMenuSearchTimerNothingFound: public cRecMenu { +public: + cRecMenuSearchTimerNothingFound(std::string searchString); + virtual ~cRecMenuSearchTimerNothingFound(void) {}; +}; + +/****************************************************************************************** +* SwitchTimer Menus +******************************************************************************************/ + // --- cRecMenuSwitchTimer --------------------------------------------------------- class cRecMenuSwitchTimer: public cRecMenu { private: - const char *switchModes[3]; + int switchMinsBefore; + int announceOnly; public: cRecMenuSwitchTimer(void); virtual ~cRecMenuSwitchTimer(void) {}; + cSwitchTimer GetSwitchTimer(void); }; // --- cRecMenuSwitchTimerConfirm --------------------------------------------------------- @@ -217,16 +338,24 @@ public: virtual ~cRecMenuSwitchTimerDelete(void) {}; }; +/****************************************************************************************** +* Search Menus +******************************************************************************************/ // --- cRecMenuSearch --------------------------------------------------------- class cRecMenuSearch: public cRecMenu { private: - char initialText[TEXTINPUTLENGTH]; - const char * searchModes[5]; + char searchString[TEXTINPUTLENGTH]; + int mode; + int channelNr; + bool useTitle; + bool useSubTitle; + bool useDescription; public: - cRecMenuSearch(const cEvent *event); - cRecMenuSearch(const cEvent *event, const char *searchString); + cRecMenuSearch(std::string searchString, bool withOptions); virtual ~cRecMenuSearch(void) {}; + Epgsearch_searchresults_v1_0 GetEPGSearchStruct(void); + std::string GetSearchString(void) { return searchString; }; }; // --- cRecMenuSearchResults --------------------------------------------------------- @@ -235,12 +364,13 @@ private: const cEvent **searchResults; int numResults; public: - cRecMenuSearchResults(cString searchString, const cEvent **searchResults, int numResults); + cRecMenuSearchResults(std::string searchString, const cEvent **searchResults, int numResults); cRecMenuItem *GetMenuItem(int number); int GetTotalNumMenuItems(void); virtual ~cRecMenuSearchResults(void) { delete[] searchResults; }; + const cEvent *GetEvent(void); }; // --- cRecMenuSearchConfirmTimer --------------------------------------------------------- @@ -253,40 +383,52 @@ public: // --- cRecMenuSearchNothingFound --------------------------------------------------------- class cRecMenuSearchNothingFound: public cRecMenu { public: - cRecMenuSearchNothingFound(cString searchString); + cRecMenuSearchNothingFound(std::string searchString); virtual ~cRecMenuSearchNothingFound(void) {}; }; +/****************************************************************************************** +* Recording Search Menus +******************************************************************************************/ + + // --- cRecMenuRecordingSearch --------------------------------------------------------- class cRecMenuRecordingSearch: public cRecMenu { private: - char initialText[TEXTINPUTLENGTH]; + char searchString[TEXTINPUTLENGTH]; public: - cRecMenuRecordingSearch(const cEvent *event); + cRecMenuRecordingSearch(std::string search); virtual ~cRecMenuRecordingSearch(void) {}; + std::string GetSearchString(void) { return searchString; }; }; // --- cRecMenuRecordingSearchResults --------------------------------------------------------- class cRecMenuRecordingSearchResults: public cRecMenu { private: + std::string searchString; cRecording **searchResults; int numResults; public: - cRecMenuRecordingSearchResults(cString searchString, cRecording **searchResults, int numResults); + cRecMenuRecordingSearchResults(std::string searchString, cRecording **searchResults, int numResults); cRecMenuItem *GetMenuItem(int number); int GetTotalNumMenuItems(void); virtual ~cRecMenuRecordingSearchResults(void) { delete[] searchResults; }; + std::string GetSearchString(void) { return searchString; }; }; // --- cRecMenuRecordingSearchNotFound --------------------------------------------------------- class cRecMenuRecordingSearchNotFound: public cRecMenu { public: - cRecMenuRecordingSearchNotFound(cString searchString); + cRecMenuRecordingSearchNotFound(std::string searchString); virtual ~cRecMenuRecordingSearchNotFound(void) {}; }; +/****************************************************************************************** +* Timeline +******************************************************************************************/ + // --- cRecMenuTimeline --------------------------------------------------------- class cRecMenuTimeline: public cRecMenu { private: @@ -303,7 +445,7 @@ private: void SetTimers(void); void PrevDay(void); void NextDay(void); - void ClearMenuItems(void); + void ClearMenu(void); public: cRecMenuTimeline(cTVGuideTimerConflicts *timerConflicts); cRecMenuItem *GetMenuItem(int number); @@ -311,6 +453,7 @@ public: virtual ~cRecMenuTimeline(void) { }; eRecMenuState ProcessKey(eKeys Key); + cTimer *GetTimer(void); }; #endif //__TVGUIDE_RECMENUS_H \ No newline at end of file diff --git a/searchtimer.c b/searchtimer.c new file mode 100644 index 0000000..9eebe3c --- /dev/null +++ b/searchtimer.c @@ -0,0 +1,556 @@ +#include +#include +#include +#include +#include +#include +#include "tools.h" +#include "searchtimer.h" + +// -- cTVGuideSearchTimer ----------------------------------------------------------------- +cTVGuideSearchTimer::cTVGuideSearchTimer(void) { + strTimer = ""; + ID = -1; + searchString = ""; + useTime = false; + startTime = 0000; + stopTime = 2359; + useChannel = false; + channelMin = Channels.GetByNumber(cDevice::CurrentChannel()); + channelMax = Channels.GetByNumber(cDevice::CurrentChannel()); + channelGroup = ""; + useCase = false; + mode = 0; + useTitle = true; + useSubtitle = true; + useDescription = true; + useDuration = false; + minDuration = 0; + maxDuration = 2359; + useAsSearchTimer = true; + useDayOfWeek = false; + dayOfWeek = 0; + directory = ""; + useEpisode = 0; + priority = 99; + lifetime = 99; + marginStart = 5; + marginStop = 5; + useVPS = false; + action = 0; + useExtEPGInfo = 0; + extEPGInfoValues = ""; + avoidRepeats = 1; + allowedRepeats = 1; + compareTitle = 1; + compareSubtitle = 2; + compareSummary = 1; + catvaluesAvoidRepeat = 0; + repeatsWithinDays = 0; + delAfterDays = 0; + recordingsKeep = 0; + switchMinsBefore = 0; + pauseOnNrRecordings = 0; + blacklistMode = 0; + blacklists = ""; + fuzzyTolerance = 0; + useInFavorites = 0; + menuTemplate = 0; + delMode = 0; + delAfterCountRecs = 0; + delAfterDaysOfFirstRec = 0; + useAsSearchTimerFrom = 0; + useAsSearchTimerTil = 0; + ignoreMissingEPGCats = 0; + unmuteSoundOnSwitch = 0; + compareSummaryMatchInPercent = 0; + contentsFilter = ""; + compareDate = 0; +} + +cTVGuideSearchTimer::~cTVGuideSearchTimer(void) { +} + +void cTVGuideSearchTimer::SetTemplate(std::string tmpl) { + std::stringstream searchTimerString; + searchTimerString << "0:"; + searchTimerString << tmpl; + strTimer = searchTimerString.str(); +} + +int cTVGuideSearchTimer::DayOfWeek(void) { + int vdrDayOfWeek = 0; + if (dayOfWeek >= 0) { + vdrDayOfWeek = pow(2, (dayOfWeek+6)%7); + } else if (dayOfWeek < 0) { + int absDayOfWeek = abs(dayOfWeek); + for (int i=0; i < 7; i++) { + if (absDayOfWeek & (1 << i)) { + vdrDayOfWeek += pow(2, (i+6)%7); + } + } + } + return vdrDayOfWeek; +} + +void cTVGuideSearchTimer::SetDayOfWeek(int VDRDayOfWeek) { + int epgSearchDayOfWeek = 0; + for (int i=0; i < 7; i++) { + if (VDRDayOfWeek & (1 << i)) { + epgSearchDayOfWeek += pow(2, (i+1)%7); + } + } + this->dayOfWeek = epgSearchDayOfWeek * (-1); +} + +/* + 0 - unique search timer id + 1 - the search term + 2 - use time? 0/1 + 3 - start time in HHMM + 4 - stop time in HHMM + 5 - use channel? 0 = no, 1 = Interval, 2 = Channel group, 3 = FTA only + 6 - if 'use channel' = 1 then channel id[|channel id] in VDR format, + one entry or min/max entry separated with |, if 'use channel' = 2 + then the channel group name + 7 - match case? 0/1 + 8 - search mode: + 0 - the whole term must appear as substring + 1 - all single terms (delimiters are blank,',', ';', '|' or '~') + must exist as substrings. + 2 - at least one term (delimiters are blank, ',', ';', '|' or '~') + must exist as substring. + 3 - matches exactly + 4 - regular expression + 9 - use title? 0/1 + 10 - use subtitle? 0/1 + 11 - use description? 0/1 + 12 - use duration? 0/1 + 13 - min duration in hhmm + 14 - max duration in hhmm + 15 - use as search timer? 0/1 + 16 - use day of week? 0/1 + 17 - day of week (0 = Sunday, 1 = Monday...; + -1 Sunday, -2 Monday, -4 Tuesday, ...; -7 Sun, Mon, Tue) + 18 - use series recording? 0/1 + 19 - directory for recording + 20 - priority of recording + 21 - lifetime of recording + 22 - time margin for start in minutes + 23 - time margin for stop in minutes + 24 - use VPS? 0/1 + 25 - action: + 0 = create a timer + 1 = announce only via OSD (no timer) + 2 = switch only (no timer) + 3 = announce via OSD and switch (no timer) + 4 = announce via mail + 26 - use extended EPG info? 0/1 + 27 - extended EPG info values. This entry has the following format + (delimiter is '|' for each category, '#' separates id and value): + 1 - the id of the extended EPG info category as specified in + epgsearchcats.conf + 2 - the value of the extended EPG info category + (a ':' will be translated to "!^colon^!", e.g. in "16:9") + 28 - avoid repeats? 0/1 + 29 - allowed repeats + 30 - compare title when testing for a repeat? 0/1 + 31 - compare subtitle when testing for a repeat? 0/1/2 + 0 - no + 1 - yes + 2 - yes, if present + 32 - compare description when testing for a repeat? 0/1 + 33 - compare extended EPG info when testing for a repeat? + This entry is a bit field of the category IDs. + 34 - accepts repeats only within x days + 35 - delete a recording automatically after x days + 36 - but keep this number of recordings anyway + 37 - minutes before switch (if action = 2) + 38 - pause if x recordings already exist + 39 - blacklist usage mode (0 none, 1 selection, 2 all) + 40 - selected blacklist IDs separated with '|' + 41 - fuzzy tolerance value for fuzzy searching + 42 - use this search in favorites menu (0 no, 1 yes) + 43 - id of a menu search template + 44 - auto deletion mode (0 don't delete search timer, 1 delete after given + count of recordings, 2 delete after given days after first recording) + 45 - count of recordings after which to delete the search timer + 46 - count of days after the first recording after which to delete the search + timer + 47 - first day where the search timer is active (see parameter 16) + 48 - last day where the search timer is active (see parameter 16) + 49 - ignore missing EPG categories? 0/1 + 50 - unmute sound if off when used as switch timer + 51 - percentage of match when comparing the summary of two events (with 'avoid repeats') + 52 - HEX representation of the content descriptors, each descriptor ID is represented with 2 chars + 53 - compare date when testing for a repeat? (0=no, 1=same day, 2=same week, 3=same month) +*/ +bool cTVGuideSearchTimer::Parse(bool readTemplate) { + splitstring s(strTimer.c_str()); + std::vector values = s.split(':', 1); + int numValues = values.size(); + if (numValues < 12) + return false; + for (int value = 0; value < numValues; value++) { + switch (value) { + case 0: + if (!readTemplate) + ID = atoi(values[value].c_str()); + break; + case 1: + if (!readTemplate) + searchString = values[value]; + break; + case 2: + useTime = atoi(values[value].c_str()); + break; + case 3: + if (useTime) { + startTime = atoi(values[value].c_str()); + } + break; + case 4: + if (useTime) { + stopTime = atoi(values[value].c_str()); + } + break; + case 5: + useChannel = atoi(values[value].c_str()); + break; + case 6: + if (useChannel == 0) { + channelMin = NULL; + channelMax = NULL; + } else if (useChannel == 1) { + char *channelMinbuffer = NULL; + char *channelMaxbuffer = NULL; + int channels = sscanf(values[value].c_str(), "%a[^|]|%a[^|]", &channelMinbuffer, &channelMaxbuffer); + channelMin = Channels.GetByChannelID(tChannelID::FromString(channelMinbuffer), true, true); + if (!channelMin) { + channelMin = channelMax = NULL; + useChannel = 0; + } + if (channels == 1) + channelMax = channelMin; + else { + channelMax = Channels.GetByChannelID(tChannelID::FromString(channelMaxbuffer), true, true); + if (!channelMax) { + channelMin = channelMax = NULL; + useChannel = 0; + } + } + free(channelMinbuffer); + free(channelMaxbuffer); + } else if (useChannel == 2) { + channelGroup = values[value]; + } + break; + case 7: + useCase = atoi(values[value].c_str()); + break; + case 8: + mode = atoi(values[value].c_str()); + break; + case 9: + useTitle = atoi(values[value].c_str()); + break; + case 10: + useSubtitle = atoi(values[value].c_str()); + break; + case 11: + useDescription = atoi(values[value].c_str()); + break; + case 12: + useDuration = atoi(values[value].c_str()); + break; + case 13: + minDuration = atoi(values[value].c_str()); + break; + case 14: + maxDuration = atoi(values[value].c_str()); + break; + case 15: + useAsSearchTimer = atoi(values[value].c_str()); + break; + case 16: + useDayOfWeek = atoi(values[value].c_str()); + break; + case 17: + dayOfWeek = atoi(values[value].c_str()); + break; + case 18: + useEpisode = atoi(values[value].c_str()); + break; + case 19: + directory = values[value]; + break; + case 20: + priority = atoi(values[value].c_str()); + break; + case 21: + lifetime = atoi(values[value].c_str()); + break; + case 22: + marginStart = atoi(values[value].c_str()); + break; + case 23: + marginStop = atoi(values[value].c_str()); + break; + case 24: + useVPS = atoi(values[value].c_str()); + break; + case 25: + action = atoi(values[value].c_str()); + break; + case 26: + useExtEPGInfo = atoi(values[value].c_str()); + break; + case 27: + extEPGInfoValues = values[value]; + break; + case 28: + avoidRepeats = atoi(values[value].c_str()); + break; + case 29: + allowedRepeats = atoi(values[value].c_str()); + break; + case 30: + compareTitle = atoi(values[value].c_str()); + break; + case 31: + compareSubtitle = atoi(values[value].c_str()); + break; + case 32: + compareSummary = atoi(values[value].c_str()); + break; + case 33: + catvaluesAvoidRepeat = atol(values[value].c_str()); + break; + case 34: + repeatsWithinDays = atoi(values[value].c_str()); + break; + case 35: + delAfterDays = atoi(values[value].c_str()); + break; + case 36: + recordingsKeep = atoi(values[value].c_str()); + break; + case 37: + switchMinsBefore = atoi(values[value].c_str()); + break; + case 38: + pauseOnNrRecordings = atoi(values[value].c_str()); + break; + case 39: + blacklistMode = atoi(values[value].c_str()); + break; + case 40: + blacklists = values[value]; + break; + case 41: + fuzzyTolerance = atoi(values[value].c_str()); + break; + case 42: + useInFavorites = atoi(values[value].c_str()); + break; + case 43: + menuTemplate = atoi(values[value].c_str()); + break; + case 44: + delMode = atoi(values[value].c_str()); + break; + case 45: + delAfterCountRecs = atoi(values[value].c_str()); + break; + case 46: + delAfterDaysOfFirstRec = atoi(values[value].c_str()); + break; + case 47: + useAsSearchTimerFrom = atol(values[value].c_str()); + break; + case 48: + useAsSearchTimerTil = atol(values[value].c_str()); + break; + case 49: + ignoreMissingEPGCats = atoi(values[value].c_str()); + break; + case 50: + unmuteSoundOnSwitch = atoi(values[value].c_str()); + break; + case 51: + compareSummaryMatchInPercent = atoi(values[value].c_str()); + break; + case 52: + contentsFilter = values[value]; + break; + case 53: + compareDate = atoi(values[value].c_str()); + break; + default: + break; + } + } + return true; +} + +std::string cTVGuideSearchTimer::BuildSearchString(void) { + std::stringstream search; + // 0 - 2 + if (ID > -1) + search << ID << ":"; + else + search << ":"; + std::string searchStringMasked = searchString; + std::replace(searchStringMasked.begin(), searchStringMasked.end(), ':', '|'); + search << searchStringMasked << ":"; + search << useTime << ":"; + + // 3 - 6 + if (useTime) { + search << *cString::sprintf("%04d", startTime) << ":"; + search << *cString::sprintf("%04d", stopTime) << ":"; + } else { + search << "::"; + } + + search << useChannel << ":"; + if (useChannel == 1) { + if (channelMin && channelMax) { + if (channelMin->Number() < channelMax->Number()) + search << std::string(channelMin->GetChannelID().ToString()) << "|" << std::string(channelMax->GetChannelID().ToString()) << ":"; + else + search << std::string(channelMin->GetChannelID().ToString()) << ":"; + } else { + search << "0:"; + } + } else if (useChannel == 2) { + search << channelGroup << ":"; + } else { + search << "0:"; + } + // 7 - 14 + search << useCase << ":"; + search << mode << ":"; + search << useTitle << ":"; + search << useSubtitle << ":"; + search << useDescription << ":"; + search << useDuration << ":"; + if (useDuration) { + search << *cString::sprintf("%04d", minDuration) << ":"; + search << *cString::sprintf("%04d", maxDuration) << ":"; + } else { + search << "::"; + } + //15 - 53 + search << useAsSearchTimer << ":"; + search << useDayOfWeek << ":"; + search << dayOfWeek << ":"; + search << useEpisode << ":"; + search << directory << ":"; + search << priority << ":"; + search << lifetime << ":"; + search << marginStart << ":"; + search << marginStop << ":"; + search << useVPS << ":"; + search << action << ":"; + search << useExtEPGInfo << ":"; + search << extEPGInfoValues << ":"; + search << avoidRepeats << ":"; + search << allowedRepeats << ":"; + search << compareTitle << ":"; + search << compareSubtitle << ":"; + search << compareSummary << ":"; + search << catvaluesAvoidRepeat << ":"; + search << repeatsWithinDays << ":"; + search << delAfterDays << ":"; + search << recordingsKeep << ":"; + search << switchMinsBefore << ":"; + search << pauseOnNrRecordings << ":"; + search << blacklistMode << ":"; + search << blacklists << ":"; + search << fuzzyTolerance << ":"; + search << useInFavorites << ":"; + search << menuTemplate << ":"; + search << delMode << ":"; + search << delAfterCountRecs << ":"; + search << delAfterDaysOfFirstRec << ":"; + search << useAsSearchTimerFrom << ":"; + search << useAsSearchTimerTil << ":"; + search << ignoreMissingEPGCats << ":"; + search << unmuteSoundOnSwitch << ":"; + search << compareSummaryMatchInPercent << ":"; + search << contentsFilter << ":"; + search << compareDate; + + strTimer = search.str(); + return strTimer; +} + +bool cTVGuideSearchTimer::Active(void) { + if (useAsSearchTimer) + return true; + return false; +} + + +int cTVGuideSearchTimer::GetNumTimers(void) { + int numTimers = 0; + if (ID < 0) + return numTimers; + for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) { + char* searchID = GetAuxValue(timer, "s-id"); + if (!searchID) continue; + if (ID == atoi(searchID)) + numTimers++; + free(searchID); + } + return numTimers; +} + +int cTVGuideSearchTimer::GetNumRecordings(void) { + int numRecordings = 0; + if (ID < 0) + return numRecordings; + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { + if (recording->IsEdited()) + continue; + if (!recording->Info()) + continue; + char* searchID = GetAuxValue(recording, "s-id"); + if (!searchID) continue; + if (ID == atoi(searchID)) + numRecordings++; + free(searchID); + } + return numRecordings; +} + +void cTVGuideSearchTimer::GetSearchModes(std::vector *searchModes) { + searchModes->push_back(tr("whole term must appear")); + searchModes->push_back(tr("all terms must exist")); + searchModes->push_back(tr("one term must exist")); + searchModes->push_back(tr("exact match")); + searchModes->push_back(tr("regular expression")); +} + + +void cTVGuideSearchTimer::Dump(void) { + esyslog("tvguide searchtimer: strTimer: %s", strTimer.c_str()); + esyslog("tvguide searchtimer: ID: %d", ID); + esyslog("tvguide searchtimer: searchString: %s", searchString.c_str()); + esyslog("tvguide searchtimer: useTime: %d", useTime); + esyslog("tvguide searchtimer: startTime: %d", startTime); + esyslog("tvguide searchtimer: stopTime: %d", stopTime); + esyslog("tvguide searchtimer: useChannel: %d", useChannel); + if (channelMin) + esyslog("tvguide searchtimer: channelMin: %s", channelMin->Name()); + if (channelMax) + esyslog("tvguide searchtimer: channelMax: %s", channelMax->Name()); + esyslog("tvguide searchtimer: channelGroup: %s", channelGroup.c_str()); + esyslog("tvguide searchtimer: useCase: %d", useCase); + esyslog("tvguide searchtimer: mode: %d", mode); + esyslog("tvguide searchtimer: useTitle: %d", useTitle); + esyslog("tvguide searchtimer: useSubtitle: %d", useSubtitle); + esyslog("tvguide searchtimer: useDescription: %d", useDescription); +} + diff --git a/searchtimer.h b/searchtimer.h new file mode 100644 index 0000000..fe0bb43 --- /dev/null +++ b/searchtimer.h @@ -0,0 +1,130 @@ +#ifndef __TVGUIDE_SEARCHTIMER_H +#define __TVGUIDE_SEARCHTIMER_H + + +class cTVGuideSearchTimer { +private: + std::string strTimer; + int ID; + std::string searchString; + int useTime; + int startTime; + int stopTime; + int useChannel; + cChannel *channelMin; + cChannel *channelMax; + std::string channelGroup; + int useCase; + int mode; + int useTitle; + int useSubtitle; + int useDescription; + int useDuration; + int minDuration; + int maxDuration; + int useAsSearchTimer; + int useDayOfWeek; + int dayOfWeek; + int useEpisode; + std::string directory; + int priority; + int lifetime; + int marginStart; + int marginStop; + int useVPS; + int action; + int useExtEPGInfo; + std::string extEPGInfoValues; + int avoidRepeats; + int allowedRepeats; + int compareTitle; + int compareSubtitle; + int compareSummary; + unsigned long catvaluesAvoidRepeat; + int repeatsWithinDays; + int delAfterDays; + int recordingsKeep; + int switchMinsBefore; + int pauseOnNrRecordings; + int blacklistMode; + std::string blacklists; + int fuzzyTolerance; + int useInFavorites; + int menuTemplate; + int delMode; + int delAfterCountRecs; + int delAfterDaysOfFirstRec; + int useAsSearchTimerFrom; + int useAsSearchTimerTil; + int ignoreMissingEPGCats; + int unmuteSoundOnSwitch; + int compareSummaryMatchInPercent; + std::string contentsFilter; + int compareDate; +public: + cTVGuideSearchTimer(void); + virtual ~cTVGuideSearchTimer(void); + void SetEPGSearchString(std::string strTimer) { this->strTimer = strTimer; }; + void SetTemplate(std::string tmpl); + bool Parse(bool readTemplate = false); + std::string BuildSearchString(void); + int GetID(void) { return ID; }; + //GETTER + std::string SearchString(void) { return searchString; }; + bool Active(void); + bool UseTitle(void) { return useTitle; }; + bool UseSubtitle(void) { return useSubtitle; }; + bool UseDescription(void) { return useDescription; }; + int SearchMode(void) { return mode; }; + bool UseChannel(void) { return useChannel; }; + int StartChannel(void) { return (channelMin)?channelMin->Number():0; }; + int StopChannel(void) { return (channelMax)?channelMax->Number():0; }; + bool UseTime(void) { return useTime; }; + int StartTime(void) { return startTime; }; + int StopTime(void) { return stopTime; }; + bool UseDayOfWeek(void) { return useDayOfWeek; }; + int DayOfWeek(void); + int UseEpisode(void) { return useEpisode; }; + int Priority(void) { return priority; }; + int Lifetime(void) { return lifetime; }; + int MarginStart(void) { return marginStart; }; + int MarginStop(void) { return marginStop; }; + bool UseVPS(void) { return useVPS; }; + bool AvoidRepeats(void) { return avoidRepeats; }; + int AllowedRepeats(void) { return allowedRepeats; }; + bool CompareTitle(void) { return compareTitle; }; + bool CompareSubtitle(void) { return compareSubtitle; }; + bool CompareSummary(void) { return compareSummary; }; + //SETTER + void SetSearchString(std::string searchString) { this->searchString = searchString; }; + void SetActive(bool active) { useAsSearchTimer = active; }; + void SetSearchMode(int searchMode) { mode = searchMode; }; + void SetUseTitle(bool useTitle) { this->useTitle = useTitle; }; + void SetUseSubtitle(bool useSubtitle) { this->useSubtitle = useSubtitle; }; + void SetUseDesription(bool useDescription) { this->useDescription = useDescription; }; + void SetUseChannel(bool useChannel) { this->useChannel = useChannel; }; + void SetStartChannel(int startChannel) { channelMin = Channels.GetByNumber(startChannel); }; + void SetStopChannel(int stopChannel) { channelMax = Channels.GetByNumber(stopChannel); }; + void SetUseTime(bool useTime) { this->useTime = useTime; }; + void SetStartTime(int startTime) { this->startTime = startTime; }; + void SetStopTime(int stopTime) { this->stopTime = stopTime; }; + void SetUseDayOfWeek(bool useDayOfWeek) { this->useDayOfWeek = useDayOfWeek; }; + void SetDayOfWeek(int VDRDayOfWeek); + void SetPriority(int priority) { this->priority = priority; }; + void SetLifetime(int lifetime) { this->lifetime = lifetime; }; + void SetMarginStart(int marginStart) { this->marginStart = marginStart; }; + void SetMarginStop(int marginStop) { this->marginStop = marginStop; }; + void SetUseVPS(bool useVPS) { this->useVPS = useVPS; }; + void SetAvoidRepeats(bool avoidRepeats) { this->avoidRepeats = avoidRepeats; }; + void SetAllowedRepeats(int allowedRepeats) { this->allowedRepeats = allowedRepeats; }; + void SetCompareTitle(bool compareTitle) { this->compareTitle = compareTitle; }; + void SetCompareSubtitle(bool compareSubtitle) { this->compareSubtitle = compareSubtitle; }; + void SetCompareSummary(bool compareSummary) { this->compareSummary = compareSummary; }; + //COMMON + int GetNumTimers(void); + int GetNumRecordings(void); + void GetSearchModes(std::vector *searchModes); + void Dump(void); +}; + +#endif //__TVGUIDE_SEARCHTIMER_H diff --git a/setup.c b/setup.c index b0c9a1f..77320c7 100644 --- a/setup.c +++ b/setup.c @@ -122,6 +122,7 @@ void cTvguideSetup::Store(void) { SetupStore("FontTimeLineTimeHorizontalDelta", tvguideConfig.FontTimeLineTimeHorizontalDelta); SetupStore("FontRecMenuItemDelta", tvguideConfig.FontRecMenuItemDelta); SetupStore("FontRecMenuItemSmallDelta", tvguideConfig.FontRecMenuItemSmallDelta); + SetupStore("FontRecMenuItemLargeDelta", tvguideConfig.FontRecMenuItemLargeDelta); SetupStore("displayRerunsDetailEPGView", tvguideConfig.displayRerunsDetailEPGView); SetupStore("numReruns", tvguideConfig.numReruns); SetupStore("useSubtitleRerun", tvguideConfig.useSubtitleRerun); @@ -339,6 +340,7 @@ void cMenuSetupFont::Set(void) { Add(new cMenuEditIntItem(tr("Search & Recording Menu Font Size"), &tmpTvguideConfig->FontRecMenuItemDelta, -30, 30)); Add(new cMenuEditIntItem(tr("Search & Recording Menu Small Font Size"), &tmpTvguideConfig->FontRecMenuItemSmallDelta, -30, 30)); + Add(new cMenuEditIntItem(tr("Search & Recording Main Menu Font Size"), &tmpTvguideConfig->FontRecMenuItemLargeDelta, -30, 30)); SetCurrent(Get(currentItem)); Display(); diff --git a/switchtimer.c b/switchtimer.c index 4ba7b45..f56c469 100644 --- a/switchtimer.c +++ b/switchtimer.c @@ -4,6 +4,10 @@ cSwitchTimers SwitchTimers; // -- cSwitchTimer ----------------------------------------------------------------- cSwitchTimer::cSwitchTimer(void) { + eventID = 0; + startTime = 0; + switchMinsBefore = 2; + announceOnly = 0; } cSwitchTimer::cSwitchTimer(const cEvent* Event) { diff --git a/switchtimer.h b/switchtimer.h index 8958b44..09ebe88 100644 --- a/switchtimer.h +++ b/switchtimer.h @@ -3,20 +3,21 @@ #include -class cSwitchTimer : public cListObject -{ +class cSwitchTimer : public cListObject { public: tEventID eventID; time_t startTime; tChannelID channelID; - + int switchMinsBefore; + int announceOnly; cSwitchTimer(void); cSwitchTimer(const cEvent* Event); bool Parse(const char *s); + void SetEventID(tEventID eventID) { this->eventID = eventID; }; + void SetStartTime(time_t startTime) { this->startTime = startTime; }; }; -class cSwitchTimers : public cConfig, public cMutex -{ +class cSwitchTimers : public cConfig, public cMutex { public: cSwitchTimers(void) {} ~cSwitchTimers(void) {} diff --git a/tools.c b/tools.c index d22f6b0..555ba29 100644 --- a/tools.c +++ b/tools.c @@ -52,6 +52,9 @@ std::string StrToLowerCase(std::string str) { return lowerCase; } +/**************************************************************************************** +* DrawRoundedCorners +****************************************************************************************/ void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor) { if( height > 2*radius) { p->DrawEllipse(cRect(posX, posY, radius, radius), borderColor, -2); @@ -109,6 +112,70 @@ int FindIgnoreCase(const std::string& expr, const std::string& query) return r - p; } + +/**************************************************************************************** +* GetAuxValue +****************************************************************************************/ +char* GetAuxValue(const char* aux, const char* name) { + if (isempty(aux)) + return NULL; + + char* descr = strdup(aux); + char* beginaux = strstr(descr, ""); + char* endaux = strstr(descr, ""); + if (!beginaux || !endaux) { + free(descr); + return NULL; + } + + beginaux += 11; // strlen(""); + endaux[0] = 0; + memmove(descr, beginaux, endaux - beginaux + 1); + + if (strcmp(name, "epgsearch") == 0) + return descr; // full aux + + int namelen = strlen(name); + char catname[100] = ""; + catname[0] = '<'; + memcpy(catname + 1, name, namelen); + catname[1 + namelen] = '>'; + catname[2 + namelen] = 0; + + char* cat = strcasestr(descr, catname); + if (!cat) { + free(descr); + return NULL; + } + + cat += namelen + 2; + char* end = strstr(cat, "Info()) + return NULL; + return GetAuxValue(recording->Info()->Aux(), name); +} + +char* GetAuxValue(const cTimer *timer, const char* name) { + if (!timer || !timer->Aux()) + return NULL; + return GetAuxValue(timer->Aux(), name); +} + /**************************************************************************************** * FUZZYSEARCH ****************************************************************************************/ diff --git a/tools.h b/tools.h index fd0a768..612f86d 100644 --- a/tools.h +++ b/tools.h @@ -4,6 +4,7 @@ #include #include #include +#include std::string CutText(std::string text, int width, const cFont *font); std::string StrToLowerCase(std::string str); @@ -18,6 +19,10 @@ public: int FindIgnoreCase(const std::string& expr, const std::string& query); +char* GetAuxValue(const char* aux, const char* name); +char* GetAuxValue(const cRecording *recording, const char* name); +char* GetAuxValue(const cTimer* timer, const char* name); + #ifndef _AFUZZY_H #define _AFUZZY_H