From 809fbda03c5014ba9cd361f5113d1d717cd41ea6 Mon Sep 17 00:00:00 2001 From: louis Date: Tue, 26 Jan 2016 18:32:38 +0100 Subject: [PATCH] Version 0.8.0 beta --- Makefile | 96 +- config.c | 108 +- config.h | 34 +- coreengine/animation.c | 347 +++ coreengine/animation.h | 126 + coreengine/area.c | 767 ++++++ coreengine/area.h | 178 ++ coreengine/attribute.c | 478 ++++ coreengine/attribute.h | 126 + coreengine/attributes.c | 447 ++++ coreengine/attributes.h | 111 + coreengine/complextypes.c | 1605 ++++++++++++ coreengine/complextypes.h | 318 +++ coreengine/definitions.h | 1746 ++++++++++++++ coreengine/functions.c | 1565 ++++++++++++ coreengine/functions.h | 220 ++ {libtemplate => coreengine}/globals.c | 56 +- {libtemplate => coreengine}/globals.h | 20 +- coreengine/gridelement.c | 57 + coreengine/gridelement.h | 27 + coreengine/listelements.c | 1830 ++++++++++++++ coreengine/listelements.h | 337 +++ coreengine/osdwrapper.c | 71 + coreengine/osdwrapper.h | 26 + coreengine/view.c | 419 ++++ coreengine/view.h | 93 + coreengine/viewdetail.c | 978 ++++++++ coreengine/viewdetail.h | 114 + coreengine/viewdisplaychannel.c | 199 ++ coreengine/viewdisplaychannel.h | 31 + coreengine/viewdisplaymenu.c | 1705 +++++++++++++ coreengine/viewdisplaymenu.h | 316 +++ coreengine/viewdisplaymessage.c | 54 + coreengine/viewdisplaymessage.h | 19 + coreengine/viewdisplayplugin.c | 556 +++++ coreengine/viewdisplayplugin.h | 101 + coreengine/viewdisplayreplay.c | 314 +++ coreengine/viewdisplayreplay.h | 57 + coreengine/viewdisplaytracks.c | 122 + coreengine/viewdisplaytracks.h | 29 + coreengine/viewdisplayvolume.c | 52 + coreengine/viewdisplayvolume.h | 19 + coreengine/viewelement.c | 532 ++++ coreengine/viewelement.h | 93 + coreengine/viewelementplugin.c | 36 + coreengine/viewelementplugin.h | 22 + coreengine/viewelementscommon.c | 531 ++++ coreengine/viewelementscommon.h | 110 + coreengine/viewelementsdisplaychannel.c | 650 +++++ coreengine/viewelementsdisplaychannel.h | 145 ++ coreengine/viewelementsdisplaymenu.c | 1232 ++++++++++ coreengine/viewelementsdisplaymenu.h | 250 ++ coreengine/viewelementsdisplayreplay.c | 816 +++++++ coreengine/viewelementsdisplayreplay.h | 206 ++ coreengine/viewelementsdisplaytracks.c | 84 + coreengine/viewelementsdisplaytracks.h | 40 + coreengine/viewgrid.c | 188 ++ coreengine/viewgrid.h | 47 + coreengine/viewlist.c | 899 +++++++ coreengine/viewlist.h | 155 ++ {libtemplate => coreengine}/xmlparser.c | 401 +-- {libtemplate => coreengine}/xmlparser.h | 44 +- designer.c | 321 ++- designer.h | 36 +- displaychannel.c | 212 +- displaychannel.h | 27 +- displaymenu.c | 333 +-- displaymenu.h | 33 +- displaymessage.c | 41 +- displaymessage.h | 14 +- displayplugin.c | 201 -- displayplugin.h | 44 - displayreplay.c | 121 +- displayreplay.h | 16 +- displaytracks.c | 58 +- displaytracks.h | 16 +- displayvolume.c | 38 +- displayvolume.h | 13 +- dtd/displaychannel.dtd | 91 +- dtd/displaymenu.dtd | 86 +- dtd/displaymenuplugin.dtd | 54 +- dtd/displayreplay.dtd | 123 +- dtd/functions.dtd | 8 +- {libcore => extensions}/cairoimage.c | 3 +- {libcore => extensions}/cairoimage.h | 1 + {libcore => extensions}/curlfuncs.c | 0 {libcore => extensions}/curlfuncs.h | 0 {libcore => extensions}/extrecinfo.c | 0 {libcore => extensions}/extrecinfo.h | 0 {libcore => extensions}/fontmanager.c | 29 +- {libcore => extensions}/fontmanager.h | 7 +- {libcore => extensions}/helpers.c | 33 +- {libcore => extensions}/helpers.h | 3 +- {libcore => extensions}/imagecache.c | 122 +- {libcore => extensions}/imagecache.h | 34 +- {libcore => extensions}/imageloader.c | 0 {libcore => extensions}/imageloader.h | 0 {libcore => extensions}/libxmlwrapper.c | 2 +- {libcore => extensions}/libxmlwrapper.h | 5 +- extensions/pluginmanager.c | 301 +++ extensions/pluginmanager.h | 71 + {libcore => extensions}/recfolderinfo.c | 0 {libcore => extensions}/recfolderinfo.h | 0 extensions/scrapmanager.c | 359 +++ extensions/scrapmanager.h | 28 + {libcore => extensions}/skinrepo.c | 2 +- {libcore => extensions}/skinrepo.h | 8 +- {libcore => extensions}/skinsetup.c | 4 +- {libcore => extensions}/skinsetup.h | 4 +- {libcore => extensions}/timers.c | 0 {libcore => extensions}/timers.h | 0 libcore/pixmapcontainer.c | 835 ------- libcore/pixmapcontainer.h | 98 - libskindesignerapi/Makefile | 2 +- libskindesignerapi/osdelements.c | 160 +- libskindesignerapi/osdelements.h | 39 +- libskindesignerapi/pluginstructure.c | 92 + libskindesignerapi/pluginstructure.h | 57 + libskindesignerapi/skindesignerapi.c | 40 +- libskindesignerapi/skindesignerapi.h | 104 +- libskindesignerapi/skindesignerosdbase.c | 137 +- libskindesignerapi/skindesignerosdbase.h | 53 +- libskindesignerapi/tokencontainer.c | 305 +++ libskindesignerapi/tokencontainer.h | 69 + libtemplate/parameter.c | 493 ---- libtemplate/parameter.h | 147 -- libtemplate/template.c | 322 --- libtemplate/template.h | 61 - libtemplate/templatefunction.c | 1856 -------------- libtemplate/templatefunction.h | 270 --- libtemplate/templateloopfunction.c | 248 -- libtemplate/templateloopfunction.h | 34 - libtemplate/templatepixmap.c | 739 ------ libtemplate/templatepixmap.h | 132 - libtemplate/templateview.c | 2148 ----------------- libtemplate/templateview.h | 243 -- libtemplate/templateviewelement.c | 236 -- libtemplate/templateviewelement.h | 127 - libtemplate/templateviewgrid.c | 29 - libtemplate/templateviewgrid.h | 25 - libtemplate/templateviewlist.c | 181 -- libtemplate/templateviewlist.h | 47 - libtemplate/templateviewtab.c | 38 - libtemplate/templateviewtab.h | 31 - po/de_DE.po | 26 +- po/fi_FI.po | 26 +- setup.c | 129 +- setup.h | 14 +- skindesigner.c | 82 +- skins/metrixhd/xmlfiles/displaychannel.xml | 22 +- skins/metrixhd/xmlfiles/displaymenu.xml | 20 +- .../metrixhd/xmlfiles/displaymenuchannels.xml | 2 +- .../xmlfiles/displaymenudetailtext.xml | 5 + skins/metrixhd/xmlfiles/displaymenumain.xml | 62 +- .../xmlfiles/displaymenurecordings.xml | 50 +- .../xmlfiles/displaymenuschedules.xml | 15 +- skins/metrixhd/xmlfiles/displaymenusetup.xml | 2 +- skins/metrixhd/xmlfiles/displaymenutimers.xml | 2 +- skins/metrixhd/xmlfiles/displaymessage.xml | 2 +- skins/metrixhd/xmlfiles/displayreplay.xml | 19 +- skins/metrixhd/xmlfiles/displayvolume.xml | 2 +- .../xmlfiles/plug-tvguideng-recmenu.xml | 74 +- .../metrixhd/xmlfiles/plug-tvguideng-root.xml | 6 +- .../plug-weatherforecast-weatherforecast.xml | 20 +- ...rforecast-weatherforecastdetailcurrent.xml | 2 +- ...herforecast-weatherforecastdetaildaily.xml | 4 +- ...erforecast-weatherforecastdetailhourly.xml | 4 +- skinskeleton/xmlfiles/displayaudiotracks.xml | 2 +- skinskeleton/xmlfiles/displaychannel.xml | 6 +- skinskeleton/xmlfiles/displaymenu.xml | 8 + skinskeleton/xmlfiles/displaymenumain.xml | 4 +- skinskeleton/xmlfiles/displayreplay.xml | 11 +- views/animation.c | 111 - views/animation.h | 69 - views/displayaudiotracksview.c | 72 - views/displayaudiotracksview.h | 23 - views/displaychannelview.c | 596 ----- views/displaychannelview.h | 57 - views/displaymenudetailview.c | 871 ------- views/displaymenudetailview.h | 52 - views/displaymenuitemcurrentview.c | 636 ----- views/displaymenuitemcurrentview.h | 84 - views/displaymenuitemview.c | 981 -------- views/displaymenuitemview.h | 161 -- views/displaymenulistview.c | 274 --- views/displaymenulistview.h | 43 - views/displaymenurootview.c | 732 ------ views/displaymenurootview.h | 87 - views/displaymenutabview.c | 125 - views/displaymenutabview.h | 27 - views/displaymenuview.c | 673 ------ views/displaymenuview.h | 88 - views/displaymessageview.c | 39 - views/displaymessageview.h | 18 - views/displaypluginview.c | 288 --- views/displaypluginview.h | 62 - views/displayreplayonpauseview.c | 108 - views/displayreplayonpauseview.h | 21 - views/displayreplayview.c | 499 ---- views/displayreplayview.h | 52 - views/displayviewelements.c | 142 -- views/displayviewelements.h | 84 - views/displayvolumeview.c | 45 - views/displayvolumeview.h | 20 - views/view.c | 1533 ------------ views/view.h | 155 -- views/viewgrid.c | 89 - views/viewgrid.h | 28 - views/viewhelpers.c | 1276 ---------- views/viewhelpers.h | 62 - 210 files changed, 24710 insertions(+), 20849 deletions(-) create mode 100644 coreengine/animation.c create mode 100644 coreengine/animation.h create mode 100644 coreengine/area.c create mode 100644 coreengine/area.h create mode 100644 coreengine/attribute.c create mode 100644 coreengine/attribute.h create mode 100644 coreengine/attributes.c create mode 100644 coreengine/attributes.h create mode 100644 coreengine/complextypes.c create mode 100644 coreengine/complextypes.h create mode 100644 coreengine/definitions.h create mode 100644 coreengine/functions.c create mode 100644 coreengine/functions.h rename {libtemplate => coreengine}/globals.c (84%) rename {libtemplate => coreengine}/globals.h (74%) create mode 100644 coreengine/gridelement.c create mode 100644 coreengine/gridelement.h create mode 100644 coreengine/listelements.c create mode 100644 coreengine/listelements.h create mode 100644 coreengine/osdwrapper.c create mode 100644 coreengine/osdwrapper.h create mode 100644 coreengine/view.c create mode 100644 coreengine/view.h create mode 100644 coreengine/viewdetail.c create mode 100644 coreengine/viewdetail.h create mode 100644 coreengine/viewdisplaychannel.c create mode 100644 coreengine/viewdisplaychannel.h create mode 100644 coreengine/viewdisplaymenu.c create mode 100644 coreengine/viewdisplaymenu.h create mode 100644 coreengine/viewdisplaymessage.c create mode 100644 coreengine/viewdisplaymessage.h create mode 100644 coreengine/viewdisplayplugin.c create mode 100644 coreengine/viewdisplayplugin.h create mode 100644 coreengine/viewdisplayreplay.c create mode 100644 coreengine/viewdisplayreplay.h create mode 100644 coreengine/viewdisplaytracks.c create mode 100644 coreengine/viewdisplaytracks.h create mode 100644 coreengine/viewdisplayvolume.c create mode 100644 coreengine/viewdisplayvolume.h create mode 100644 coreengine/viewelement.c create mode 100644 coreengine/viewelement.h create mode 100644 coreengine/viewelementplugin.c create mode 100644 coreengine/viewelementplugin.h create mode 100644 coreengine/viewelementscommon.c create mode 100644 coreengine/viewelementscommon.h create mode 100644 coreengine/viewelementsdisplaychannel.c create mode 100644 coreengine/viewelementsdisplaychannel.h create mode 100644 coreengine/viewelementsdisplaymenu.c create mode 100644 coreengine/viewelementsdisplaymenu.h create mode 100644 coreengine/viewelementsdisplayreplay.c create mode 100644 coreengine/viewelementsdisplayreplay.h create mode 100644 coreengine/viewelementsdisplaytracks.c create mode 100644 coreengine/viewelementsdisplaytracks.h create mode 100644 coreengine/viewgrid.c create mode 100644 coreengine/viewgrid.h create mode 100644 coreengine/viewlist.c create mode 100644 coreengine/viewlist.h rename {libtemplate => coreengine}/xmlparser.c (61%) rename {libtemplate => coreengine}/xmlparser.h (55%) delete mode 100644 displayplugin.c delete mode 100644 displayplugin.h rename {libcore => extensions}/cairoimage.c (97%) rename {libcore => extensions}/cairoimage.h (90%) rename {libcore => extensions}/curlfuncs.c (100%) rename {libcore => extensions}/curlfuncs.h (100%) rename {libcore => extensions}/extrecinfo.c (100%) rename {libcore => extensions}/extrecinfo.h (100%) rename {libcore => extensions}/fontmanager.c (87%) rename {libcore => extensions}/fontmanager.h (86%) rename {libcore => extensions}/helpers.c (83%) rename {libcore => extensions}/helpers.h (94%) rename {libcore => extensions}/imagecache.c (79%) rename {libcore => extensions}/imagecache.h (67%) rename {libcore => extensions}/imageloader.c (100%) rename {libcore => extensions}/imageloader.h (100%) rename {libcore => extensions}/libxmlwrapper.c (95%) rename {libcore => extensions}/libxmlwrapper.h (85%) create mode 100644 extensions/pluginmanager.c create mode 100644 extensions/pluginmanager.h rename {libcore => extensions}/recfolderinfo.c (100%) rename {libcore => extensions}/recfolderinfo.h (100%) create mode 100644 extensions/scrapmanager.c create mode 100644 extensions/scrapmanager.h rename {libcore => extensions}/skinrepo.c (99%) rename {libcore => extensions}/skinrepo.h (91%) rename {libcore => extensions}/skinsetup.c (99%) rename {libcore => extensions}/skinsetup.h (98%) rename {libcore => extensions}/timers.c (100%) rename {libcore => extensions}/timers.h (100%) delete mode 100644 libcore/pixmapcontainer.c delete mode 100644 libcore/pixmapcontainer.h create mode 100644 libskindesignerapi/pluginstructure.c create mode 100644 libskindesignerapi/pluginstructure.h create mode 100644 libskindesignerapi/tokencontainer.c create mode 100644 libskindesignerapi/tokencontainer.h delete mode 100644 libtemplate/parameter.c delete mode 100644 libtemplate/parameter.h delete mode 100644 libtemplate/template.c delete mode 100644 libtemplate/template.h delete mode 100644 libtemplate/templatefunction.c delete mode 100644 libtemplate/templatefunction.h delete mode 100644 libtemplate/templateloopfunction.c delete mode 100644 libtemplate/templateloopfunction.h delete mode 100644 libtemplate/templatepixmap.c delete mode 100644 libtemplate/templatepixmap.h delete mode 100644 libtemplate/templateview.c delete mode 100644 libtemplate/templateview.h delete mode 100644 libtemplate/templateviewelement.c delete mode 100644 libtemplate/templateviewelement.h delete mode 100644 libtemplate/templateviewgrid.c delete mode 100644 libtemplate/templateviewgrid.h delete mode 100644 libtemplate/templateviewlist.c delete mode 100644 libtemplate/templateviewlist.h delete mode 100644 libtemplate/templateviewtab.c delete mode 100644 libtemplate/templateviewtab.h delete mode 100644 views/animation.c delete mode 100644 views/animation.h delete mode 100644 views/displayaudiotracksview.c delete mode 100644 views/displayaudiotracksview.h delete mode 100644 views/displaychannelview.c delete mode 100644 views/displaychannelview.h delete mode 100644 views/displaymenudetailview.c delete mode 100644 views/displaymenudetailview.h delete mode 100644 views/displaymenuitemcurrentview.c delete mode 100644 views/displaymenuitemcurrentview.h delete mode 100644 views/displaymenuitemview.c delete mode 100644 views/displaymenuitemview.h delete mode 100644 views/displaymenulistview.c delete mode 100644 views/displaymenulistview.h delete mode 100644 views/displaymenurootview.c delete mode 100644 views/displaymenurootview.h delete mode 100644 views/displaymenutabview.c delete mode 100644 views/displaymenutabview.h delete mode 100644 views/displaymenuview.c delete mode 100644 views/displaymenuview.h delete mode 100644 views/displaymessageview.c delete mode 100644 views/displaymessageview.h delete mode 100644 views/displaypluginview.c delete mode 100644 views/displaypluginview.h delete mode 100644 views/displayreplayonpauseview.c delete mode 100644 views/displayreplayonpauseview.h delete mode 100644 views/displayreplayview.c delete mode 100644 views/displayreplayview.h delete mode 100644 views/displayviewelements.c delete mode 100644 views/displayviewelements.h delete mode 100644 views/displayvolumeview.c delete mode 100644 views/displayvolumeview.h delete mode 100644 views/view.c delete mode 100644 views/view.h delete mode 100644 views/viewgrid.c delete mode 100644 views/viewgrid.h delete mode 100644 views/viewhelpers.c delete mode 100644 views/viewhelpers.h diff --git a/Makefile b/Makefile index f2c47d5..b2b6c59 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ SKINDESIGNER_SCRIPTDIR ?= $(LIBDIR)/$(PLUGIN)/scripts ### The compiler options: export CFLAGS = $(call PKGCFG,cflags) export CXXFLAGS = $(call PKGCFG,cxxflags) - +CXXFLAGS += -std=c++11 ### Allow user defined options to overwrite defaults: -include $(PLGCFG) @@ -65,51 +65,49 @@ OBJS = $(PLUGIN).o \ displayreplay.o \ displaytracks.o \ displayvolume.o \ - displayplugin.o \ - libcore/cairoimage.o \ - libcore/curlfuncs.o \ - libcore/pixmapcontainer.o \ - libcore/fontmanager.o \ - libcore/imagecache.o \ - libcore/helpers.o \ - libcore/imageloader.o \ - libcore/libxmlwrapper.o \ - libcore/recfolderinfo.o \ - libcore/skinsetup.o \ - libcore/skinrepo.o \ - libcore/extrecinfo.o \ - libcore/timers.o \ - libtemplate/globals.o \ - libtemplate/parameter.o \ - libtemplate/template.o \ - libtemplate/templateview.o \ - libtemplate/templateviewelement.o \ - libtemplate/templateviewlist.o \ - libtemplate/templateviewgrid.o \ - libtemplate/templatepixmap.o \ - libtemplate/templateviewtab.o \ - libtemplate/templatefunction.o \ - libtemplate/templateloopfunction.o \ - libtemplate/xmlparser.o \ - views/animation.o \ - views/view.o \ - views/viewgrid.o \ - views/viewhelpers.o \ - views/displayviewelements.o \ - views/displaychannelview.o \ - views/displaymenurootview.o \ - views/displaymenuview.o \ - views/displaymenulistview.o \ - views/displaymenuitemview.o \ - views/displaymenuitemcurrentview.o \ - views/displaymenudetailview.o \ - views/displaymenutabview.o \ - views/displaymessageview.o \ - views/displayreplayview.o \ - views/displayreplayonpauseview.o \ - views/displayvolumeview.o \ - views/displayaudiotracksview.o \ - views/displaypluginview.o + extensions/cairoimage.o \ + extensions/curlfuncs.o \ + extensions/fontmanager.o \ + extensions/imagecache.o \ + extensions/helpers.o \ + extensions/imageloader.o \ + extensions/libxmlwrapper.o \ + extensions/pluginmanager.o \ + extensions/recfolderinfo.o \ + extensions/scrapmanager.o \ + extensions/skinsetup.o \ + extensions/skinrepo.o \ + extensions/extrecinfo.o \ + extensions/timers.o \ + coreengine/animation.o \ + coreengine/attribute.o \ + coreengine/attributes.o \ + coreengine/functions.o \ + coreengine/complextypes.o \ + coreengine/globals.o \ + coreengine/gridelement.o \ + coreengine/osdwrapper.o \ + coreengine/view.o \ + coreengine/viewdisplaychannel.o \ + coreengine/viewdisplaymenu.o \ + coreengine/viewdisplaymessage.o \ + coreengine/viewdisplayreplay.o \ + coreengine/viewdisplaytracks.o \ + coreengine/viewdisplayvolume.o \ + coreengine/viewdisplayplugin.o \ + coreengine/viewelement.o \ + coreengine/viewelementplugin.o \ + coreengine/viewelementscommon.o \ + coreengine/viewelementsdisplaychannel.o \ + coreengine/viewelementsdisplaymenu.o \ + coreengine/viewelementsdisplayreplay.o \ + coreengine/viewelementsdisplaytracks.o \ + coreengine/viewgrid.o \ + coreengine/viewlist.o \ + coreengine/viewdetail.o \ + coreengine/listelements.o \ + coreengine/area.o \ + coreengine/xmlparser.o ### The main target: @@ -138,7 +136,7 @@ $(SOFILE): SUB_LIBS = libskindesignerapi/libskindesignerapi.so.$(shell pkg-confi ### Implicit rules: %.o: %.c - $(CXX) $(CXXFLAGS) -c $(DEFINES) $(SUB_DEFINES) $(INCLUDES) -o $@ $< + $(CXX) $(CXXFLAGS) -std=c++11 -c $(DEFINES) $(SUB_DEFINES) $(INCLUDES) -o $@ $< ### Dependencies: @@ -178,7 +176,7 @@ install-i18n: $(I18Nmsgs) ### Targets: $(SOFILE): $(OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) $(SUB_LIBS) -o $@ + $(CXX) $(CXXFLAGS) -std=c++11 $(LDFLAGS) -shared $(OBJS) $(LIBS) $(SUB_LIBS) -o $@ install-lib: $(SOFILE) install -D $^ $(DESTDIR)$(LIBDIR)/$^.$(APIVERSION) @@ -209,4 +207,4 @@ dist: $(I18Npo) clean clean: clean-subprojects @-rm -f $(PODIR)/*.mo $(PODIR)/*.pot - @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz core* *~ + @-rm -f $(OBJS) $(DEPFILE) *.so *.tgz *~ diff --git a/config.c b/config.c index 9b288c4..d969516 100644 --- a/config.c +++ b/config.c @@ -1,6 +1,6 @@ #include "config.h" -#include "libcore/helpers.h" -#include "libcore/imageloader.h" +#include "extensions/helpers.h" +#include "extensions/imageloader.h" cDesignerConfig::cDesignerConfig() { tmplGlobals = NULL; @@ -9,6 +9,7 @@ cDesignerConfig::cDesignerConfig() { installerSkinPathSet = false; logoPathSet = false; //Common + cacheImagesInitial = 1; numLogosPerSizeInitial = 30; limitLogoCache = 1; numLogosMax = 200; @@ -18,11 +19,8 @@ cDesignerConfig::cDesignerConfig() { rerunAmount = 10; rerunDistance = 2; rerunMaxChannel = 0; - //menu display style, display menu items - //one after each other or in one step - blockFlush = 1; - //frames per second for fading and shifting - framesPerSecond = 40; + //max number of custom int and string tokens + numCustomTokens = 10; //remember current skin and theme, osd size and osd fonts SetSkin(); SetOSDSize(); @@ -475,98 +473,6 @@ cString cDesignerConfig::GetSkinRessourcePath(void) { return cString::sprintf("%s%s", *skinPath, osdSkin.c_str()); } -void cDesignerConfig::AddPluginMenus(string name, map< int, string > menus) { - pluginMenus.insert(pair< string, map < int, string > >(name, menus)); -} - -void cDesignerConfig::AddPluginViews(string name, - map< int, string > views, - multimap< int, pair > subViews, - map< int, map > viewElements, - map< int, map > viewGrids) { - pluginViews.insert(pair< string, map < int, string > >(name, views)); - pluginSubViews.insert(pair< string, multimap< int, pair > >(name, subViews)); - pluginViewElements.insert(pair< string, map< int, map > >(name, viewElements)); - pluginViewGrids.insert(pair< string, map< int, map > >(name, viewGrids)); -} - -void cDesignerConfig::InitPluginMenuIterator(void) { - plugMenuIt = pluginMenus.begin(); -} - -map *cDesignerConfig::GetPluginTemplates(string &name) { - if (plugMenuIt == pluginMenus.end()) - return NULL; - name = plugMenuIt->first; - map *templates = &plugMenuIt->second; - plugMenuIt++; - return templates; -} - -void cDesignerConfig::InitPluginViewIterator(void) { - plugViewIt = pluginViews.begin(); -} - -map *cDesignerConfig::GetPluginViews(string &name) { - if (plugViewIt == pluginViews.end()) - return NULL; - name = plugViewIt->first; - map *views = &plugViewIt->second; - plugViewIt++; - return views; -} - -map cDesignerConfig::GetPluginSubViews(string name, int viewID) { - map subViews; - - map < string, multimap< int, pair > >::iterator hit = pluginSubViews.find(name); - if (hit == pluginSubViews.end()) - return subViews; - - multimap< int, pair > subs = hit->second; - - pair < multimap< int, pair >::iterator, multimap< int, pair >::iterator> viewSubViews; - viewSubViews = subs.equal_range(viewID); - - for (multimap< int, pair >::iterator it=viewSubViews.first; it!=viewSubViews.second; ++it) { - pair subViewFound = it->second; - subViews.insert(pair(subViewFound.first, subViewFound.second)); - } - return subViews; -} - -int cDesignerConfig::GetPluginViewElementID(string pluginName, string viewElementName, int viewID) { - map < string, map< int, map > >::iterator hit = pluginViewElements.find(pluginName); - if (hit == pluginViewElements.end()) - return -1; - map< int, map >::iterator hit2 = (hit->second).find(viewID); - if (hit2 == (hit->second).end()) - return -1; - - map viewElements = hit2->second; - for (map ::iterator it = viewElements.begin(); it != viewElements.end(); it++) { - if (!(it->second).compare(viewElementName)) - return it->first; - } - return -1; -} - -int cDesignerConfig::GetPluginViewGridID(string pluginName, string viewGridName, int viewID) { - map < string, map< int, map > >::iterator hit = pluginViewGrids.find(pluginName); - if (hit == pluginViewGrids.end()) - return -1; - map< int, map >::iterator hit2 = (hit->second).find(viewID); - if (hit2 == (hit->second).end()) - return -1; - - map viewGrids = hit2->second; - for (map ::iterator it = viewGrids.begin(); it != viewGrids.end(); it++) { - if (!(it->second).compare(viewGridName)) - return it->first; - } - return -1; -} - cString cDesignerConfig::CheckSlashAtEnd(std::string path) { try { if (!(path.at(path.size()-1) == '/')) @@ -578,14 +484,14 @@ cString cDesignerConfig::CheckSlashAtEnd(std::string path) { bool cDesignerConfig::SetupParse(const char *Name, const char *Value) { bool pluginSetupParam = true; if (!strcasecmp(Name, "DebugImageLoading")) debugImageLoading = atoi(Value); + else if (!strcasecmp(Name, "CacheImagesInitial")) cacheImagesInitial = atoi(Value); else if (!strcasecmp(Name, "LimitChannelLogoCache")) limitLogoCache = atoi(Value); else if (!strcasecmp(Name, "NumberLogosInitially")) numLogosPerSizeInitial = atoi(Value); else if (!strcasecmp(Name, "NumberLogosMax")) numLogosMax = atoi(Value); else if (!strcasecmp(Name, "RerunAmount")) rerunAmount = atoi(Value); else if (!strcasecmp(Name, "RerunDistance")) rerunDistance = atoi(Value); else if (!strcasecmp(Name, "RerunMaxChannel")) rerunMaxChannel = atoi(Value); - else if (!strcasecmp(Name, "BlockFlush")) blockFlush = atoi(Value); - else if (!strcasecmp(Name, "FramesPerSecond")) framesPerSecond = atoi(Value); + else if (!strcasecmp(Name, "NumCustomTokens")) numCustomTokens = atoi(Value); else pluginSetupParam = false; if (!pluginSetupParam) { diff --git a/config.h b/config.h index 1bd4d5a..0960b9b 100644 --- a/config.h +++ b/config.h @@ -8,11 +8,13 @@ #include #include #include "designer.h" -#include "libcore/fontmanager.h" -#include "libcore/imagecache.h" -#include "libcore/recfolderinfo.h" -#include "libcore/skinsetup.h" -#include "libcore/skinrepo.h" +#include "extensions/pluginmanager.h" +#include "extensions/fontmanager.h" +#include "extensions/imagecache.h" +#include "extensions/recfolderinfo.h" +#include "extensions/skinsetup.h" +#include "extensions/skinrepo.h" +#include "libskindesignerapi/skindesignerapi.h" #define SCRIPTOUTPUTPATH "/tmp/skindesigner" @@ -32,13 +34,6 @@ private: string fontSml; string osdLanguage; cGlobals *tmplGlobals; - map < string, map < int, string > > pluginMenus; - map < string, map < int, string > >::iterator plugMenuIt; - map < string, map < int, string > > pluginViews; - map < string, map < int, string > >::iterator plugViewIt; - map < string, multimap< int, pair > > pluginSubViews; - map < string, map< int, map > > pluginViewElements; - map < string, map< int, map > > pluginViewGrids; vector skinRefs; vector::iterator skinRefsIterator; vector deliveredSkins; @@ -100,15 +95,6 @@ public: void SetOsdLanguage(void) { osdLanguage = Setup.OSDLanguage; }; bool OsdLanguageChanged(void); cString GetSkinRessourcePath(void); - void AddPluginMenus(string name, map< int, string > menus); - void AddPluginViews(string name, map< int, string > views, multimap< int, pair > subViews, map< int, map > viewElements, map< int, map > viewGrids); - void InitPluginMenuIterator(void); - map *GetPluginTemplates(string &name); - void InitPluginViewIterator(void); - map *GetPluginViews(string &name); - map GetPluginSubViews(string name, int viewID); - int GetPluginViewElementID(string pluginName, string viewElementName, int viewID); - int GetPluginViewGridID(string pluginName, string viewGridName, int viewID); cString skinPath; cString installerSkinPath; cString logoPath; @@ -117,6 +103,7 @@ public: bool replaceDecPoint; char decPoint; //Setup Parameter + int cacheImagesInitial; int numLogosPerSizeInitial; int limitLogoCache; int numLogosMax; @@ -124,20 +111,21 @@ public: int rerunAmount; int rerunDistance; int rerunMaxChannel; - int blockFlush; - int framesPerSecond; + int numCustomTokens; //TemplateReload on Setup Close bool setupCloseDoReload; }; #ifdef DEFINE_CONFIG cDesignerConfig config; + cSDPluginManager *plgManager = NULL; cFontManager *fontManager = NULL; cImageCache *imgCache = NULL; cTheme Theme; cRecordingsFolderInfo recFolderInfo(Recordings); #else extern cDesignerConfig config; + extern cSDPluginManager *plgManager; extern cFontManager *fontManager; extern cImageCache *imgCache; extern cTheme Theme; diff --git a/coreengine/animation.c b/coreengine/animation.c new file mode 100644 index 0000000..59f4388 --- /dev/null +++ b/coreengine/animation.c @@ -0,0 +1,347 @@ +#include "animation.h" +#include + +/****************************************************************** +* cAnimation +******************************************************************/ +cAnimation::cAnimation(cScrollable *scrollable) : cThread("scroller") { + this->scrollable = scrollable; + this->detachable = NULL; + this->fadable = NULL; + this->shiftable = NULL; + this->blinkable = NULL; + waitOnWakeup = false; + doAnimation = true; + modeIn = false; + blinkFunc = -1; +} + +cAnimation::cAnimation(cDetachable *detachable, bool wait, bool animation) : cThread("detached") { + this->scrollable = NULL; + this->detachable = detachable; + this->fadable = NULL; + this->shiftable = NULL; + this->blinkable = NULL; + waitOnWakeup = wait; + doAnimation = animation; + modeIn = false; + blinkFunc = -1; +} + +cAnimation::cAnimation(cFadable *fadable, bool fadein) : cThread("fadable") { + this->scrollable = NULL; + this->detachable = NULL; + this->fadable = fadable; + this->shiftable = NULL; + this->blinkable = NULL; + waitOnWakeup = false; + doAnimation = true; + modeIn = fadein; + blinkFunc = -1; +} + +cAnimation::cAnimation(cShiftable *shiftable, cPoint &start, cPoint &end, bool shiftin) : cThread("shiftable") { + this->scrollable = NULL; + this->detachable = NULL; + this->fadable = NULL; + this->shiftable = shiftable; + this->blinkable = NULL; + waitOnWakeup = false; + doAnimation = true; + modeIn = shiftin; + shiftstart = start; + shiftend = end; + blinkFunc = -1; +} + +cAnimation::cAnimation(cBlinkable *blinkable, int func) : cThread("blinking") { + this->scrollable = NULL; + this->detachable = NULL; + this->fadable = NULL; + this->shiftable = NULL; + this->blinkable = blinkable; + waitOnWakeup = false; + doAnimation = true; + modeIn = false; + blinkFunc = func; +} + +cAnimation::~cAnimation(void) { + sleepWait.Signal(); + Cancel(2); +} + +void cAnimation::WakeUp(void) { + sleepWait.Signal(); +} + +void cAnimation::Stop(bool deletePixmaps) { + sleepWait.Signal(); + Cancel(2); + if (scrollable && deletePixmaps) + scrollable->StopScrolling(); +} + +void cAnimation::Action(void) { + if (scrollable) { + Scroll(); + } else if (detachable) { + Detach(); + } else if (fadable) { + Fade(); + } else if (shiftable) { + Shift(); + } else if (blinkable) { + Blink(); + } +} + +void cAnimation::Sleep(int duration) { + //sleep should wake up itself, so no infinit wait allowed + if (duration <= 0) + return; + sleepWait.Wait(duration); +} + +void cAnimation::Wait(void) { + //wait has to be waked up from outside + sleepWait.Wait(0); +} + +void cAnimation::Scroll(void) { + int delay = scrollable->ScrollDelay(); + Sleep(delay); + if (!Running()) return; + + eOrientation orientation = scrollable->ScrollOrientation(); + int scrollTotal = 0; + if (orientation == eOrientation::horizontal) { + scrollTotal = scrollable->ScrollWidth(); + } else if (orientation == eOrientation::vertical) { + scrollTotal = scrollable->ScrollHeight(); + } + + eScrollMode mode = scrollable->ScrollMode(); + bool carriageReturn = (mode == eScrollMode::carriagereturn) ? true : false; + + eScrollSpeed speed = scrollable->ScrollSpeed(); + int frameTime = 30; + if (speed == eScrollSpeed::slow) + frameTime = 50; + else if (speed == eScrollSpeed::medium) + frameTime = 30; + else if (speed == eScrollSpeed::fast) + frameTime = 15; + + if (!Running()) return; + + scrollable->StartScrolling(); + + int drawPortX = 0; + int drawPortY = 0; + int scrollDelta = 1; + + bool doSleep = false; + while (Running()) { + if (doSleep) { + Sleep(delay); + doSleep = false; + } + if (!Running()) return; + uint64_t now = cTimeMs::Now(); + + cPoint drawPortPoint(0,0); + if (orientation == eOrientation::horizontal) { + + drawPortX -= scrollDelta; + if (abs(drawPortX) > scrollTotal) { + Sleep(delay); + if (carriageReturn) { + drawPortX = 0; + doSleep = true; + } else { + scrollDelta *= -1; + drawPortX -= scrollDelta; + } + } + drawPortPoint.SetX(drawPortX); + + } else if (orientation == eOrientation::vertical) { + + drawPortY -= scrollDelta; + if (abs(drawPortY) > scrollTotal) { + Sleep(delay); + drawPortY = 0; + doSleep = true; + } + drawPortPoint.SetY(drawPortY); + + } + + if (!Running()) return; + scrollable->SetDrawPort(drawPortPoint); + + if (!Running()) return; + scrollable->Flush(); + + if (orientation == eOrientation::horizontal && !carriageReturn && (drawPortX == 0)) { + scrollDelta *= -1; + doSleep = true; + } + + int delta = cTimeMs::Now() - now; + if (delta < frameTime) + Sleep(frameTime - delta); + } +} + +void cAnimation::Detach(void) { + if (waitOnWakeup) { + Wait(); + int delay = 100 + detachable->Delay(); + Sleep(delay); + } else { + int delay = detachable->Delay(); + Sleep(delay); + } + if (!Running()) return; + detachable->ParseDetached(); + if (!Running()) return; + detachable->RenderDetached(); + if (!Running()) return; + detachable->Flush(); + if (!Running()) return; + if (doAnimation) { + detachable->StartAnimation(); + } +} + +void cAnimation::Fade(void) { + int fadetime = fadable->FadeTime(); + int frametime = 1000 / FPS; + int step = 100.0f / ((double)fadetime / (double)frametime); + uint64_t start = cTimeMs::Now(); + int transparency = 0; + if (modeIn) { + transparency = 100 - step; + } else { + transparency = step; + } + //wait configured delay if not already done by detacher + if (!fadable->Detached()) { + int delay = fadable->Delay(); + if (delay > 0) + Sleep(delay); + } + while (Running() || !modeIn) { + uint64_t now = cTimeMs::Now(); + if (Running() || !modeIn) + fadable->SetTransparency(transparency, !modeIn); + if (Running() || !modeIn) + fadable->Flush(); + int delta = cTimeMs::Now() - now; + if ((Running() || !modeIn) && (delta < frametime)) { + Sleep(frametime - delta); + } + if ((int)(now - start) > fadetime) { + if ((Running() && modeIn) && transparency > 0) { + fadable->SetTransparency(0); + fadable->Flush(); + } else if (!modeIn && transparency < 100) { + fadable->SetTransparency(100, true); + fadable->Flush(); + } + break; + } + if (modeIn) { + transparency -= step; + if (transparency < 0) + transparency = 0; + } else { + transparency += step; + if (transparency > 100) + transparency = 100; + } + } +} + +void cAnimation::Shift(void) { + int shifttime = shiftable->ShiftTime(); + eShiftMode mode = (eShiftMode)shiftable->ShiftMode(); + //in shiftmode slowedDown shifting is done starting with slowratio % faster + //at start. Then speed reduces linear to (100 - slowratio)% at end + //for me 60 is a nice value :-) + int slowRatio = 60; + + int frametime = 1000 / FPS; + int steps = (double)shifttime / (double)frametime; + int stepXLinear = 0; + int stepYLinear = 0; + if (shiftstart.X() == shiftend.X()) { + stepYLinear = (shiftend.Y() - shiftstart.Y()) / steps; + } else if (shiftstart.Y() == shiftend.Y()) { + stepXLinear = (shiftend.X() - shiftstart.X()) / steps; + } else { + stepXLinear = (shiftend.X() - shiftstart.X()) / steps; + stepYLinear = (shiftend.Y() - shiftstart.Y()) / steps; + } + int stepX = stepXLinear; + int stepY = stepYLinear; + + cPoint pos; + if (modeIn) + pos = shiftstart; + else + pos = shiftend; + + //wait configured delay if not already done by detacher + if (!shiftable->Detached()) { + int delay = shiftable->Delay(); + if (delay > 0) + Sleep(delay); + } + uint64_t start = cTimeMs::Now(); + while (Running() || !modeIn) { + uint64_t now = cTimeMs::Now(); + if (Running() || !modeIn) + shiftable->SetPosition(pos, shiftend); + if (Running() || !modeIn) + shiftable->Flush(); + int delta = cTimeMs::Now() - now; + if ((Running() || !modeIn) && (delta < frametime)) { + cCondWait::SleepMs(frametime - delta); + } + if ((int)(now - start) > shifttime) { + if ((Running() && modeIn) && pos != shiftend) { + shiftable->SetPosition(shiftend, shiftend); + shiftable->Flush(); + } + break; + } + if (mode == eShiftMode::slowedDown) { + double t = (double)(now - start) / (double)shifttime; + double factor = 1.0f + (double)slowRatio / 100.0f - 2.0f * ((double)slowRatio / 100.0f) * t; + stepX = stepXLinear * factor; + stepY = stepYLinear * factor; + } + if (modeIn) { + pos.Set(pos.X() + stepX, pos.Y() + stepY); + } else { + pos.Set(pos.X() - stepX, pos.Y() - stepY); + } + } + +} + +void cAnimation::Blink(void) { + int freq = blinkable->BlinkFreq(blinkFunc); + bool blinkOn = false; + while (Running()) { + Sleep(freq); + if (Running()) { + blinkable->DoBlink(blinkFunc, blinkOn); + blinkable->Flush(); + } + blinkOn = !blinkOn; + } +} diff --git a/coreengine/animation.h b/coreengine/animation.h new file mode 100644 index 0000000..64f17ad --- /dev/null +++ b/coreengine/animation.h @@ -0,0 +1,126 @@ +#ifndef __ANIMATION_H +#define __ANIMATION_H + +#include +#include +#include "definitions.h" + +#define FPS 50 + +/****************************************************************** +* cScrollable +******************************************************************/ +class cScrollable { +protected: + cScrollable(void) {}; + ~cScrollable(void) {}; +public: + virtual int ScrollDelay(void) = 0; + virtual int ScrollWidth(void) = 0; + virtual int ScrollHeight(void) = 0; + virtual eScrollMode ScrollMode(void) = 0; + virtual eScrollSpeed ScrollSpeed(void) = 0; + virtual eOrientation ScrollOrientation(void) = 0; + virtual void StartScrolling(void) = 0; + virtual void StopScrolling(void) = 0; + virtual void SetDrawPort(cPoint &point) = 0; + virtual void Flush(void) = 0; +}; + +/****************************************************************** +* cDetachable +******************************************************************/ +class cDetachable { +protected: + cDetachable(void) {}; + ~cDetachable(void) {}; +public: + virtual int Delay(void) = 0; + virtual void ParseDetached(void) = 0; + virtual void RenderDetached(void) = 0; + virtual void StartAnimation(void) = 0; + virtual void Flush(void) = 0; +}; + +/****************************************************************** +* cFadable +******************************************************************/ +class cFadable { +protected: + cFadable(void) {}; + ~cFadable(void) {}; +public: + virtual bool Detached(void) = 0; + virtual int Delay(void) = 0; + virtual int FadeTime(void) = 0; + virtual void SetTransparency(int transparency, bool force = false) = 0; + virtual void Flush(void) = 0; +}; + +/****************************************************************** +* cShiftable +******************************************************************/ +class cShiftable { +protected: + cShiftable(void) {}; + ~cShiftable(void) {}; +public: + virtual bool Detached(void) = 0; + virtual int Delay(void) = 0; + virtual int ShiftTime(void) = 0; + virtual int ShiftMode(void) = 0; + virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false) = 0; + virtual void Flush(void) = 0; +}; + +/****************************************************************** +* cBlinkable +******************************************************************/ +class cBlinkable { +protected: + cBlinkable(void) {}; + ~cBlinkable(void) {}; +public: + virtual int BlinkFreq(int func) = 0; + virtual void DoBlink(int func, bool on) = 0; + virtual void Flush(void) = 0; +}; + +/****************************************************************** +* cAnimation +******************************************************************/ +class cAnimation : public cThread, public cListObject { +private: + cCondWait sleepWait; + cScrollable *scrollable; + cDetachable *detachable; + cFadable *fadable; + cShiftable *shiftable; + cBlinkable *blinkable; + bool waitOnWakeup; + bool doAnimation; + bool modeIn; + int blinkFunc; + cPoint shiftstart; + cPoint shiftend; + void Sleep(int duration); + void Wait(void); + void Scroll(void); + void Detach(void); + void Blink(void); +protected: + virtual void Action(void); +public: + cAnimation(cScrollable *scrollable); + cAnimation(cDetachable *detachable, bool wait, bool animation); + cAnimation(cFadable *fadable, bool fadein); + cAnimation(cShiftable *shiftable, cPoint &start, cPoint &end, bool shiftin); + cAnimation(cBlinkable *blinkable, int func); + ~cAnimation(void); + void WakeUp(void); + void Fade(void); + void Shift(void); + void Stop(bool deletePixmaps); +}; + +#endif //__ANIMATION_H \ No newline at end of file diff --git a/coreengine/area.c b/coreengine/area.c new file mode 100644 index 0000000..b961fd8 --- /dev/null +++ b/coreengine/area.c @@ -0,0 +1,767 @@ +#include "area.h" +#include "../config.h" + +/****************************************************************** +* cAreaNode +******************************************************************/ +cAreaNode::cAreaNode(void) { + globals = NULL; + isTab = false; + activeTab = false; +} + +cAreaNode::~cAreaNode(void) { +} + +void cAreaNode::SetContainer(int x, int y, int width, int height) { + container.SetX(x); + container.SetY(y); + container.SetWidth(width); + container.SetHeight(height); +} + +/****************************************************************** +* cArea +******************************************************************/ +cArea::cArea(void) { + sdOsd = NULL; + init = true; + isBackgroundArea = false; + attribs = new cAreaAttribs((int)eAreaAttribs::count); + scrolling = false; + isScrolling = false; + scrollFunc = NULL; + blinking = false; + areaContainer = NULL; + pix = NULL; +} + +cArea::cArea(const cArea &other) { + sdOsd = other.sdOsd; + init = true; + isBackgroundArea = false; + pix = NULL; + globals = other.globals; + attribs = new cAreaAttribs(*other.attribs); + //area container is set from outside during cloning of areacontainer + areaContainer = NULL; + //scrolling is set from outside by ScrollFunc(), see below + scrolling = other.scrolling; + isScrolling = false; + blinking = false; + scrollFunc = NULL; + + for (cFunction *func = other.functions.First(); func; func = other.functions.Next(func)) { + if (cFuncFill *f = dynamic_cast(func)) { + cFuncFill *fFill = new cFuncFill(*f); + fFill->SetOwner(this); + functions.Add(fFill); + } else if (cFuncDrawRectangle *f = dynamic_cast(func)) { + cFuncDrawRectangle *fDrawRect = new cFuncDrawRectangle(*f); + fDrawRect->SetOwner(this); + functions.Add(fDrawRect); + } else if (cFuncDrawEllipse *f = dynamic_cast(func)) { + cFuncDrawEllipse *fDrawEllipse = new cFuncDrawEllipse(*f); + fDrawEllipse->SetOwner(this); + functions.Add(fDrawEllipse); + } else if (cFuncDrawSlope *f = dynamic_cast(func)) { + cFuncDrawSlope *fDrawSlope = new cFuncDrawSlope(*f); + fDrawSlope->SetOwner(this); + functions.Add(fDrawSlope); + } else if (cFuncDrawText *f = dynamic_cast(func)) { + cFuncDrawText *fDrawText = new cFuncDrawText(*f); + fDrawText->SetOwner(this); + functions.Add(fDrawText); + } else if (cFuncDrawTextVertical *f = dynamic_cast(func)) { + cFuncDrawTextVertical *fDrawTextVertical = new cFuncDrawTextVertical(*f); + fDrawTextVertical->SetOwner(this); + functions.Add(fDrawTextVertical); + } else if (cFuncDrawTextBox *f = dynamic_cast(func)) { + cFuncDrawTextBox *fDrawTextBox = new cFuncDrawTextBox(*f); + fDrawTextBox->SetOwner(this); + functions.Add(fDrawTextBox); + } else if (cFuncDrawImage *f = dynamic_cast(func)) { + cFuncDrawImage *fDrawImage = new cFuncDrawImage(*f); + fDrawImage->SetOwner(this); + functions.Add(fDrawImage); + } else { + esyslog("skindesigner: ERROR: unknown function in area cloning!!!"); + } + } + + //func references have to be set from outside if already cached clone is wanted + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->CacheFuncReferences(); + } + if (scrolling) { + SetScrollFunc(); + } +} + +cArea::~cArea(void) { + StopBlinkers(); + delete attribs; +} + +void cArea::SetGlobals(cGlobals *globals) { + this->globals = globals; + attribs->SetGlobals(globals); + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetGlobals(globals); + } +} + +void cArea::SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer) { + attribs->SetTokenContainer(tokenContainer); + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetTokenContainer(tokenContainer); + } +} + +void cArea::SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer) { + attribs->SetTokenContainerDeep(tokenContainer); + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetTokenContainerDeep(tokenContainer); + } +} + +void cArea::SetAttributes(vector &attributes) { + attribs->Set(attributes); +} + +bool cArea::ValidFunction(const char *func) { + if (!strcmp(func, "fill")) return true; + if (!strcmp(func, "drawtext")) return true; + if (!strcmp(func, "drawtextbox")) return true; + if (!strcmp(func, "drawtextvertical")) return true; + if (!strcmp(func, "drawimage")) return true; + if (!strcmp(func, "drawrectangle")) return true; + if (!strcmp(func, "drawellipse")) return true; + if (!strcmp(func, "drawslope")) return true; + esyslog("skindesigner: unknown function \"%s\"", func); + return false; +} + +cFunction *cArea::AddFunction(const char *name, vector attribs, cFuncLoop *loopFunc) { + cFunction *f = NULL; + if (!strcmp(name, "fill")) { + f = new cFuncFill(this, (int)eFillAttribs::count); + } else if (!strcmp(name, "drawrectangle")) { + f = new cFuncDrawRectangle(this, (int)eDrawRectangleAttribs::count); + } else if (!strcmp(name, "drawellipse")) { + f = new cFuncDrawEllipse(this, (int)eDrawEllipseAttribs::count); + } else if (!strcmp(name, "drawslope")) { + f = new cFuncDrawSlope(this, (int)eDrawSlopeAttribs::count); + } else if (!strcmp(name, "drawtext")) { + f = new cFuncDrawText(this, (int)eDrawTextAttribs::count); + } else if (!strcmp(name, "drawtextvertical")) { + f = new cFuncDrawTextVertical(this, (int)eDrawTextAttribs::count); + } else if (!strcmp(name, "drawtextbox")) { + f = new cFuncDrawTextBox(this, (int)eDrawTextBoxAttribs::count); + } else if (!strcmp(name, "drawimage")) { + f = new cFuncDrawImage(this, (int)eDrawImageAttribs::count); + } else if (!strcmp(name, "loop")) { + f = new cFuncLoop(this, (int)eLoopAttribs::count); + } + if (!f) { + esyslog("skindesigner: TODO: function \"%s\" not implemented", name); + return NULL; + } + f->Set(attribs); + if (!loopFunc) + functions.Add(f); + else + loopFunc->AddFunction(f); + return f; +} + +cFunction *cArea::GetFunction(const char *name) { + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + const char *funcName = f->Name(); + if (funcName && !strcmp(funcName, name)) { + return f; + } + cFuncLoop *loopFunc = dynamic_cast(f); + if (loopFunc) { + cFunction *lf = loopFunc->GetFunction(name); + if (lf) + return lf; + } + } + if (!areaContainer) + return NULL; + return areaContainer->GetFunction(name); +} + +void cArea::SetX(int x) { + attribs->SetX(x); +} + +void cArea::SetY(int y) { + attribs->SetY(y); +} + +void cArea::SetWidth(int width) { + attribs->SetWidth(width); + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetContainer(0, 0, attribs->Width(), attribs->Height()); + } +} + +void cArea::SetHeight(int height) { + attribs->SetHeight(height); + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetContainer(0, 0, attribs->Width(), attribs->Height()); + } +} + +void cArea::Cache(void) { + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->Cache(); + attribs->CheckDynamic(); + isBackgroundArea = attribs->BackgroundArea(); + + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + if (!attribs->Dynamic()) { + f->SetContainer(0, 0, attribs->Width(), attribs->Height()); + } else { + f->SetContainer(0, 0, -1, -1); + } + f->Cache(); + } + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->CacheFuncReferences(); + } + if (scrolling) { + SetScrollFunc(); + } +} + +void cArea::Close(void) { + StopBlinkers(); + if (pix) { + sdOsd->DestroyPixmap(pix); + pix = NULL; + } + init = true; +} + +void cArea::Clear(void) { + if (!init && isBackgroundArea) { + return; + } + if (pix) { + pix->Fill(clrTransparent); + } +} + +void cArea::Hide(void) { + StopBlinkers(); + if (pix) { + pix->SetLayer(-1); + } +} + +void cArea::Show(void) { + StartBlinkers(); + if (pix) { + pix->SetLayer(attribs->Layer()); + } +} + +void cArea::Render(void) { + if (attribs->DoDebug()) + Debug(); + + if (init) { + InitFunctions(); + init = false; + } + + if (!isScrolling && scrollFunc && attribs->Orientation() == (int)eOrientation::horizontal) { + scrollFunc->Scrolling(false); + } else if (isScrolling && scrollFunc && attribs->Orientation() == (int)eOrientation::horizontal) { + scrollFunc->Scrolling(true); + } + + if (!pix) { + if (!IsTab()) + CreatePixmap(); + else { + int overlap = ScrollHeight(); + if (overlap > 0) { + cRect drawport; + drawport.SetX(0); + drawport.SetY(0); + drawport.SetWidth(attribs->Width()); + drawport.SetHeight(overlap + attribs->Height()); + CreatePixmap(drawport); + } else { + CreatePixmap(); + } + } + } + + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + if (f->DoDebug()) + f->Debug(); + if (!f->DoExecute()) + continue; + if (pix) { + f->Render(pix); + } + } + + StartBlinkers(); +} + +bool cArea::Execute(void) { + return attribs->DoExecute(); +} + +void cArea::SetTransparency(int transparency, bool absolute) { + if (transparency < 0 || transparency > 100) + return; + int alpha = (100 - transparency)*255/100; + if (!absolute) { + int pixTransparency = attribs->Transparency(); + if (pixTransparency > 0) { + alpha = (100 - pixTransparency) * alpha / 100; + } + } + if (pix) { + pix->SetAlpha(alpha); + } +} + +bool cArea::Scrolling(void) { + if (!scrolling) + return false; + if (!Execute()) + return false; + if (ScrollOrientation() == eOrientation::horizontal) { + if (!scrollFunc) + return false; + if (scrollFunc->X() + scrollFunc->FuncWidth() > attribs->Width()) + return true; + } else if (ScrollOrientation() == eOrientation::vertical) { + int maxHeight = 0; + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + int funcHeight = f->FuncY() + f->FuncHeight(); + if (funcHeight > maxHeight) + maxHeight = funcHeight; + } + if (maxHeight > attribs->Height()) + return true; + } + return false; +} + +int cArea::ScrollWidth(void) { + if (!scrollFunc) + return 0; + return scrollFunc->X() + scrollFunc->FuncWidth() + 10 - attribs->Width(); +} + +int cArea::ScrollHeight(void) { + int maxHeight = 0; + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + if (!f->DoExecute()) + continue; + int funcHeight = f->FuncY() + f->FuncHeight(); + if (funcHeight > maxHeight) + maxHeight = funcHeight; + } + return maxHeight - attribs->Height(); +} + +int cArea::ScrollDelay(void) { + return attribs->Delay(); +} + +eScrollMode cArea::ScrollMode(void) { + return (eScrollMode)attribs->Mode(); +} + +eScrollSpeed cArea::ScrollSpeed(void) { + return (eScrollSpeed)attribs->ScrollSpeed(); +} + +eOrientation cArea::ScrollOrientation(void) { + return (eOrientation)attribs->Orientation(); +} + +void cArea::StartScrolling(void) { + cRect drawport; + drawport.SetX(0); + drawport.SetY(0); + if (ScrollOrientation() == eOrientation::horizontal) { + drawport.SetWidth(ScrollWidth() + attribs->Width()); + drawport.SetHeight(attribs->Height()); + } else if (ScrollOrientation() == eOrientation::vertical) { + drawport.SetWidth(attribs->Width()); + drawport.SetHeight(ScrollHeight() + attribs->Height() + 10); + } + isScrolling = true; + CreatePixmap(drawport); + Render(); +} + +void cArea::StopScrolling(void) { + isScrolling = false; + if (pix && !(pix->ViewPort().Size() == pix->DrawPort().Size())) { + sdOsd->DestroyPixmap(pix); + pix = NULL; + } +} + +void cArea::SetViewPort(cRect &vp) { + if (!pix) + return; + pix->SetViewPort(vp); +} + +void cArea::SetPosition(cPoint &pos, cPoint &ref) { + if (!pix) + return; + int x = (attribs->X() - ref.X()) + pos.X(); + int y = (attribs->Y() - ref.Y()) + pos.Y(); + pix->SetViewPort(cRect(x, y, pix->ViewPort().Width(), pix->ViewPort().Height())); +} + +void cArea::SetDrawPort(cPoint &point) { + if (!pix) + return; + pix->SetDrawPortPoint(point); +} + +cRect cArea::ViewPort(void) { + if (!pix) + return cRect::Null; + cRect vp = pix->ViewPort(); + return vp; +} + +cRect cArea::CoveringArea(void) { + return ViewPort(); +} + +cRect cArea::DrawPort(void) { + if (!pix) + return cRect::Null; + cRect dp = pix->DrawPort(); + return dp; +} + +int cArea::BlinkFreq(int func) { + cFunction *blinkFunc = functions.Get(func); + if (!blinkFunc) + return -1; + return blinkFunc->BlinkFreq(); +} + +void cArea::DoBlink(int func, bool on) { + cFunction *blinker = functions.Get(func); + if (!blinker) + return; + if (on) { + if (pix) { + blinker->Render(pix); + } + } else { + cRect blinkRect = cRect(blinker->GetX((eAlign)blinker->Align(), 0, 0), + blinker->GetY((eAlign)blinker->Valign(), 0, 0), + blinker->FuncWidth(), + blinker->FuncHeight()); + if (pix) { + pix->DrawRectangle(blinkRect, clrTransparent); + } + } +} + +void cArea::Debug(bool full) { + esyslog("skindesigner: --> area"); + esyslog("skindesigner: container %d %d %dx%d", container.X(), container.Y(), container.Width(), container.Height()); + attribs->Debug(); + if (!full) + return; + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->Debug(); + } +} + +void cArea::Flush(void) { + sdOsd->Flush(); +} +/****************************************************************** +* Private Functions +******************************************************************/ +void cArea::InitFunctions(void) { + if (!attribs->Dynamic()) + return; + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetContainer(0, 0, attribs->Width(), attribs->Height()); + } +} + +void cArea::CreatePixmap(cRect drawPort) { + if (pix) { + sdOsd->DestroyPixmap(pix); + pix = NULL; + } + if (attribs->Width() <=0 || attribs->Height() <= 0) { + return; + } + + int layer = attribs->Layer(); + cRect viewPort(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + pix = sdOsd->CreatePixmap(layer, viewPort, drawPort); + if (pix) + pix->Clear(); + + int pixTransparency = attribs->Transparency(); + if (pixTransparency > 0) { + SetTransparency(pixTransparency, true); + } +} + +void cArea::SetScrollFunc(void) { + //if area has only one function, take this anyway + if (functions.Count() == 1) { + scrollFunc = functions.First(); + return; + } + //else use scrollelement name + const char *scrollFuncName = attribs->GetScrollElement(); + if (!scrollFuncName) + return; + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + if (!f->Name()) + continue; + if (!strcmp(f->Name(), scrollFuncName)) { + scrollFunc = f; + return; + } + } +} + +void cArea::StartBlinkers(void) { + if (blinking) + return; + blinking = true; + int func = 0; + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + if (!f->DoExecute()) { + func++; + continue; + } + if (f->Blinking()) { + cAnimation *blink = new cAnimation((cBlinkable*)this, func); + blinkers.Add(blink); + blink->Start(); + } + func++; + } +} + +void cArea::StopBlinkers(void) { + blinking = false; + blinkers.Clear(); +} + +/****************************************************************** +* cAreaContainer +******************************************************************/ +cAreaContainer::cAreaContainer(void) { + attribs = new cAreaContainerAttribs((int)eAreaContainerAttribs::count); +} + +cAreaContainer::cAreaContainer(const cAreaContainer &other) { + globals = other.globals; + attribs = new cAreaContainerAttribs(*other.attribs); + for (cArea *area = other.areas.First(); area; area = other.areas.Next(area)) { + cArea *a = new cArea(*area); + a->SetAreaContainer(this); + areas.Add(a); + } +} + +cAreaContainer::~cAreaContainer(void) { + delete attribs; +} + +void cAreaContainer::SetAttributes(vector &attributes) { + attribs->Set(attributes); +} + +void cAreaContainer::SetGlobals(cGlobals *globals) { + this->globals = globals; + attribs->SetGlobals(globals); + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetGlobals(globals); + } +} + +void cAreaContainer::SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer) { + attribs->SetTokenContainer(tokenContainer); + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetTokenContainer(tokenContainer); + } +} + +void cAreaContainer::SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer) { + attribs->SetTokenContainerDeep(tokenContainer); + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetTokenContainerDeep(tokenContainer); + } +} + +void cAreaContainer::AddArea(cArea *area) { + area->SetAreaContainer(this); + areas.Add(area); +} + +cFunction *cAreaContainer::GetFunction(const char *name) { + cFunction *fRef = NULL; + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + fRef = area->GetFunction(name); + if (fRef) + return fRef; + } + return NULL; +} + +void cAreaContainer::SetX(int x) { + attribs->SetX(x); + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetX(x); + } +} + +void cAreaContainer::SetY(int y) { + attribs->SetY(y); + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetY(y); + } +} + +void cAreaContainer::SetWidth(int width) { + attribs->SetWidth(width); + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetWidth(width); + } +} + +void cAreaContainer::SetHeight(int height) { + attribs->SetHeight(height); + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetHeight(height); + } +} + +void cAreaContainer::Cache(void) { + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->Cache(); + int x = attribs->X() > -1 ? attribs->X() : container.X(); + int y = attribs->Y() > -1 ? attribs->Y() : container.Y(); + int width = attribs->Width() > -1 ? attribs->Width() : container.Width(); + int height = attribs->Height() > -1 ? attribs->Height() : container.Height(); + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetContainer(x, y, width, height); + if (attribs->Width() > -1) { + area->SetWidth(width); + } + if (attribs->Height() > -1) { + area->SetHeight(height); + } + area->Cache(); + } +} + +void cAreaContainer::Close(void) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->Close(); + } +} + +void cAreaContainer::Clear(void) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->Clear(); + } +} + +void cAreaContainer::Hide(void) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->Hide(); + } +} + +void cAreaContainer::Show(void) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->Show(); + } +} + +void cAreaContainer::Render(void) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + if (area->Execute()) + area->Render(); + } +} + +bool cAreaContainer::Execute(void) { + return attribs->DoExecute(); +} + +void cAreaContainer::SetTransparency(int transparency, bool absolute) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetTransparency(transparency, absolute); + } +} + +void cAreaContainer::SetViewPort(cRect &vp) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetViewPort(vp); + } +} + +void cAreaContainer::SetPosition(cPoint &pos, cPoint &ref) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->SetPosition(pos, ref); + } +} + +cRect cAreaContainer::CoveringArea(void) { + cRect unionArea; + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + unionArea.Combine(area->CoveringArea()); + } + return unionArea; +} + +bool cAreaContainer::Scrolling(void) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + if (area->Scrolling()) + return true; + } + return false; +} + +cArea *cAreaContainer::ScrollingArea(void) { + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + if (area->Execute() && area->Scrolling()) + return area; + } + return NULL; +} + +void cAreaContainer::Debug(bool full) { + esyslog("skindesigner: --> area container"); + esyslog("skindesigner: container %d %d %dx%d", container.X(), container.Y(), container.Width(), container.Height()); + attribs->Debug(); + if (!full) + return; + for (cArea *area = areas.First(); area; area = areas.Next(area)) { + area->Debug(full); + } +} diff --git a/coreengine/area.h b/coreengine/area.h new file mode 100644 index 0000000..e77b946 --- /dev/null +++ b/coreengine/area.h @@ -0,0 +1,178 @@ +#ifndef __TEMPLATEAREA_H +#define __TEMPLATEAREA_H + +#include +#include +#include +#include + +#include "osdwrapper.h" +#include "definitions.h" +#include "globals.h" +#include "../libskindesignerapi/tokencontainer.h" +#include "attributes.h" +#include "functions.h" +#include "animation.h" + +class cArea; +/****************************************************************** +* cAreaNode +******************************************************************/ +class cAreaNode : public cListObject { +protected: + cGlobals *globals; + cRect container; + bool isTab; + bool activeTab; +public: + cAreaNode(void); + virtual ~cAreaNode(void); + virtual void SetGlobals(cGlobals *globals) {}; + virtual void SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer) {}; + virtual void SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer) {}; + void SetContainer(int x, int y, int width, int height); + virtual void SetAttributes(vector &attributes) {}; + virtual void SetX(int x) {}; + virtual void SetY(int y) {}; + virtual void SetWidth(int width) {}; + virtual void SetHeight(int height) {}; + void SetTab(void) { isTab = true; }; + bool IsTab(void) { return isTab; }; + void SetActiveTab(bool active) { activeTab = active; }; + bool ActiveTab(void) { return activeTab; }; + virtual int GetWidth(void) { return 0; }; + virtual void Cache(void) {}; + virtual void Close(void) {}; + virtual void Clear(void) {}; + virtual void Hide(void) {}; + virtual void Show(void) {}; + virtual void Render(void) {}; + virtual bool Execute(void) { return true; }; + virtual void SetTransparency(int transparency, bool absolute = false) {}; + virtual void SetViewPort(cRect &vp) {}; + virtual void SetPosition(cPoint &pos, cPoint &ref) {}; + virtual cRect CoveringArea(void) { return cRect::Null; }; + virtual bool Scrolling(void) { return false; }; + virtual cArea *ScrollingArea(void) { return NULL; }; + virtual cFunction *GetFunction(const char *name) { return NULL; }; + virtual const char *Name(void) { return NULL; }; + virtual bool BackgroundArea(void) { return false; }; + virtual void Debug(bool full = false) {}; +}; + +class cAreaContainer; +/****************************************************************** +* cArea +******************************************************************/ +class cArea : public cAreaNode, public cScrollable, public cBlinkable { +private: + cSdOsd *sdOsd; + bool init; + bool isBackgroundArea; + cPixmap *pix; + cAreaAttribs *attribs; + cAreaContainer *areaContainer; + cList functions; + bool scrolling; + bool isScrolling; + cFunction *scrollFunc; + cList blinkers; + bool blinking; + void InitFunctions(void); + void CreatePixmap(cRect drawPort = cRect::Null); + void SetScrollFunc(void); + void StartBlinkers(void); + void StopBlinkers(void); +public: + cArea(void); + cArea(const cArea &other); + virtual ~cArea(void); + void SetOsd(cSdOsd *osd) { sdOsd = osd; }; + void SetGlobals(cGlobals *globals); + void SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer); + void SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer); + void SetAttributes(vector &attributes); + void SetScrolling(void) { scrolling = true; }; + void SetAreaContainer(cAreaContainer *ac) { areaContainer = ac; }; + bool ValidFunction(const char *func); + cFunction *AddFunction(const char *name, vector attribs, cFuncLoop *loopFunc = NULL); + cFunction *GetFunction(const char *name); + void SetX(int x); + void SetY(int y); + void SetWidth(int width); + void SetHeight(int height); + void Cache(void); + int GetWidth(void) { return attribs->Width(); }; + void Close(void); + void Clear(void); + void Hide(void); + void Show(void); + void Render(void); + bool Execute(void); + void SetTransparency(int transparency, bool absolute = false); + cRect CoveringArea(void); + //Scrollable + bool Scrolling(void); + int ScrollWidth(void); + int ScrollHeight(void); + int ScrollDelay(void); + eScrollMode ScrollMode(void); + eScrollSpeed ScrollSpeed(void); + eOrientation ScrollOrientation(void); + cArea *ScrollingArea(void) { return this; }; + void StartScrolling(void); + void StopScrolling(void); + cRect ViewPort(void); + void SetDrawPort(cPoint &point); + void SetViewPort(cRect &vp); + void SetPosition(cPoint &pos, cPoint &ref); + cRect DrawPort(void); + int ScrollStep(void) { return attribs->ScrollStep(); }; + //Blinkable + int BlinkFreq(int func); + void DoBlink(int func, bool on); + //Common + const char *Name(void) { return attribs->Name(); }; + bool BackgroundArea(void) { return attribs->BackgroundArea(); }; + void Flush(void); + void Debug(bool full = false); +}; + +/****************************************************************** +* cAreaContainer +******************************************************************/ +class cAreaContainer : public cAreaNode { +private: + cAreaContainerAttribs *attribs; + cList areas; +public: + cAreaContainer(void); + cAreaContainer(const cAreaContainer &other); + virtual ~cAreaContainer(void); + void SetGlobals(cGlobals *globals); + void SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer); + void SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer); + void SetAttributes(vector &attributes); + void AddArea(cArea *area); + cFunction *GetFunction(const char *name); + void SetX(int x); + void SetY(int y); + void SetWidth(int width); + void SetHeight(int height); + void Cache(void); + void Close(void); + void Clear(void); + void Hide(void); + void Show(void); + void Render(void); + bool Execute(void); + void SetTransparency(int transparency, bool absolute = false); + void SetViewPort(cRect &vp); + void SetPosition(cPoint &pos, cPoint &ref); + cRect CoveringArea(void); + bool Scrolling(void); + cArea *ScrollingArea(void); + void Debug(bool full = false); +}; + +#endif //__TEMPLATEAREA_H \ No newline at end of file diff --git a/coreengine/attribute.c b/coreengine/attribute.c new file mode 100644 index 0000000..06ea17e --- /dev/null +++ b/coreengine/attribute.c @@ -0,0 +1,478 @@ +#include "attribute.h" +#include "../config.h" + +/*************************************************************************** +* cAttributes +***************************************************************************/ +cAttributes::cAttributes(int numAttributes) { + globals = NULL; + tokenContainer = NULL; + numAttribs = (int)eCommonAttribs::count + numAttributes; + attribs = new int[numAttribs]; + for (int i=0; i < numAttribs; i++) + attribs[i] = ATTR_UNKNOWN; + attribCtors = new cNumericExpr*[numAttribs]; + for (int i=0; i < numAttribs; i++) + attribCtors[i] = NULL; + cond = NULL; + SetCommonAttributesDefs(); +} + +cAttributes::cAttributes(const cAttributes &other) : cAttributes(other.numAttribs - (int)eCommonAttribs::count){ + globals = other.globals; + for (int i=0; i < numAttribs; i++) { + attribs[i] = other.attribs[i]; + if (other.attribCtors[i]) { + attribCtors[i] = new cNumericExpr(*other.attribCtors[i]); + attribCtors[i]->SetContainer(&container); + } + } + cond = NULL; + if (other.cond) { + cond = new cCondition(*other.cond); + } + attribIDs = other.attribIDs; + attribNames = other.attribNames; +} + +cAttributes::~cAttributes(void) { + delete[] attribs; + for (int i=0; i < numAttribs; i++) { + delete attribCtors[i]; + } + delete[] attribCtors; + delete cond; +} + +void cAttributes::SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer) { + this->tokenContainer = tokenContainer; +} + +void cAttributes::SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer) { + this->tokenContainer = tokenContainer; + if (cond) { + cond->SetTokenContainer(tokenContainer); + } + for (int i=0; i < numAttribs; i++) { + if (!attribCtors[i]) + continue; + attribCtors[i]->SetTokenContainer(tokenContainer); + } +} + +void cAttributes::SetContainer(int x, int y, int width, int height) { + container.SetX(x); + container.SetY(y); + container.SetWidth(width); + container.SetHeight(height); +} + +void cAttributes::SetX(int x) { + attribs[(int)eCommonAttribs::x] = x; +} + +void cAttributes::SetY(int y) { + attribs[(int)eCommonAttribs::y] = y; +} + +void cAttributes::SetWidth(int width) { + attribs[(int)eCommonAttribs::width] = width; +} + +void cAttributes::SetHeight(int height) { + attribs[(int)eCommonAttribs::height] = height; +} + +void cAttributes::Cache(void) { + if (cond) { + cond->SetGlobals(globals); + cond->SetTokenContainer(tokenContainer); + cond->Prepare(); + } + for (int i=0; i < numAttribs; i++) { + if (!attribCtors[i]) + continue; + attribCtors[i]->SetContainer(&container); + attribCtors[i]->SetGlobals(globals); + attribCtors[i]->SetTokenContainer(tokenContainer); + if (attribCtors[i]->CacheStatic()) { + int val = attribCtors[i]->GetValue(); + attribs[i] = val; + delete attribCtors[i]; + attribCtors[i] = NULL; + } else { + attribCtors[i]->PrepareTokens(); + } + } +} + +int cAttributes::GetValue(int id) { + if (!attribCtors[id + (int)eCommonAttribs::count]) + return attribs[(int)id + (int)eCommonAttribs::count]; + return attribCtors[id + (int)eCommonAttribs::count]->Calculate(); +} + + +int cAttributes::X(void) { + int x = 0; + if (!attribCtors[(int)eCommonAttribs::x]) + x = attribs[(int)eCommonAttribs::x]; + else + x = attribCtors[(int)eCommonAttribs::x]->Calculate(); + x += container.X(); + return x; +} + +int cAttributes::Y(void) { + int y = 0; + if (!attribCtors[(int)eCommonAttribs::y]) + y = attribs[(int)eCommonAttribs::y]; + else + y = attribCtors[(int)eCommonAttribs::y]->Calculate(); + y += container.Y(); + return y; +} + +int cAttributes::Width(void) { + if (!attribCtors[(int)eCommonAttribs::width]) + return attribs[(int)eCommonAttribs::width]; + return attribCtors[(int)eCommonAttribs::width]->Calculate(); +} + +int cAttributes::Height(void) { + if (!attribCtors[(int)eCommonAttribs::height]) + return attribs[(int)eCommonAttribs::height]; + return attribCtors[(int)eCommonAttribs::height]->Calculate(); +} + +bool cAttributes::DoExecute(void) { + if (!cond) + return true; + return cond->True(); +} + + +void cAttributes::Debug(void) { + esyslog("skindesigner: container %d %d %dx%d", container.X(), container.Y(), container.Width(), container.Height()); + for (int i=0; i < numAttribs; i++) { + if (attribs[i] != ATTR_UNKNOWN) { + if (i == (int)eCommonAttribs::debug) + continue; + const char *attName = "attribute"; + if (i < (int)eCommonAttribs::count) + attName = CommonAttributeName(i); + else + attName = AttributeName(i - (int)eCommonAttribs::count); + dsyslog("skindesigner: fixed Value %s = %d", attName, attribs[i]); + } + if (attribCtors[i]) { + const char *attName = "attribute"; + if (i < (int)eCommonAttribs::count) + attName = CommonAttributeName(i); + else + attName = AttributeName(i - (int)eCommonAttribs::count); + dsyslog("skindesigner: %s constructor:", attName); + attribCtors[i]->Debug(); + } + } + if (cond) { + cond->Debug(); + } +} + +/*************************************************************************** +* Protected Functions +***************************************************************************/ +int cAttributes::CommonAttributeId(const char *att) { + if (!strcmp(att, "condition")) + return ATTR_COND; + map::iterator hit = commonAttribIDs.find(att); + if (hit != commonAttribIDs.end()) + return hit->second; + return ATTR_UNKNOWN; +} + +const char *cAttributes::CommonAttributeName(int id) { + if (id < 0 || id >= (int)eCommonAttribs::count) + return ""; + map::iterator hit = commonAttribNames.find(id); + if (hit != commonAttribNames.end()) + return hit->second.c_str(); + return ""; +} + +int cAttributes::AttributeId(const char *att) { + int id = CommonAttributeId(att); + if (id != ATTR_UNKNOWN) + return id; + map::iterator hit = attribIDs.find(att); + if (hit != attribIDs.end()) + id = (int)hit->second + (int)eCommonAttribs::count; + return id; +} + +const char *cAttributes::AttributeName(int id) { + map::iterator hit = attribNames.find(id); + if (hit != attribNames.end()) + return hit->second.c_str(); + return ""; +} + +bool cAttributes::SetCommon(int id, const char *val) { + if (id == ATTR_COND) { + cond = new cCondition(val); + return true; + } + if (id == (int)eCommonAttribs::debug) { + SetBool(id, val); + return true; + } else if (id == (int)eCommonAttribs::x || id == (int)eCommonAttribs::width) { + attribCtors[id] = new cNumericExpr(val); + return true; + } else if (id == (int)eCommonAttribs::y || id == (int)eCommonAttribs::height) { + attribCtors[id] = new cNumericExpr(val); + attribCtors[id]->SetVertical(); + return true; + } + return false; +} + +bool cAttributes::IdEqual(int id, int compId) { + if (compId + (int)eCommonAttribs::count == id) + return true; + return false; +} + + +void cAttributes::SetBool(int id, const char *val) { + if (!strcmp(val, "true")) { + attribs[id] = 1; + } else { + attribs[id] = 0; + } +} + +void cAttributes::SetViewElementMode(int id, const char *val) { + eViewElementMode mode = eViewElementMode::regular; + if (!strcmp(val, "light")) + mode = eViewElementMode::light; + attribs[id] = (int)mode; +} + +void cAttributes::SetShiftType(int id, const char *val) { + eShiftType shiftType = eShiftType::none; + if (!strcmp(val, "left")) + shiftType = eShiftType::left; + else if (!strcmp(val, "right")) + shiftType = eShiftType::right; + else if (!strcmp(val, "top")) + shiftType = eShiftType::top; + else if (!strcmp(val, "bottom")) + shiftType = eShiftType::bottom; + else { + esyslog("skindesigner: unknown shift type \"%s\"", val); + return; + } + attribs[id] = (int)shiftType; +} + +void cAttributes::SetShiftMode(int id, const char *val) { + eShiftMode shiftMode = eShiftMode::linear; + if (!strcmp(val, "slowed")) + shiftMode = eShiftMode::slowedDown; + attribs[id] = (int)shiftMode; +} + +void cAttributes::SetScrollMode(int id, const char *val) { + eScrollMode mode = eScrollMode::none; + if (!strcmp(val, "forthandback")) + mode = eScrollMode::forthandback; + else if (!strcmp(val, "carriagereturn")) + mode = eScrollMode::carriagereturn; + attribs[id] = (int)mode; +} + +void cAttributes::SetScrollSpeed(int id, const char *val) { + eScrollSpeed speed = eScrollSpeed::medium; + if (!strcmp(val, "slow")) + speed = eScrollSpeed::slow; + else if (!strcmp(val, "fast")) + speed = eScrollSpeed::fast; + else if (!strcmp(val, "medium")) + speed = eScrollSpeed::medium; + attribs[id] = (int)speed; +} + +void cAttributes::SetOrientation(int id, const char *val) { + eOrientation orientation = eOrientation::none; + if (!strcmp(val, "horizontal")) + orientation = eOrientation::horizontal; + else if (!strcmp(val, "vertical")) + orientation = eOrientation::vertical; + else if (!strcmp(val, "absolute")) + orientation = eOrientation::absolute; + attribs[id] = (int)orientation; +} + +void cAttributes::SetAlign(int id, const char *val) { + eAlign align = eAlign::left; + if (!strcmp(val, "center")) { + align = eAlign::center; + } else if (!strcmp(val, "right")) { + align = eAlign::right; + } else if (!strcmp(val, "top")) { + align = eAlign::top; + } else if (!strcmp(val, "bottom")) { + align = eAlign::bottom; + } else if (!strcmp(val, "left")) { + align = eAlign::left; + } + attribs[id] = (int)align; +} + +void cAttributes::SetDirection(int id, const char *val) { + eDirection direction = eDirection::none; + if (!strcmp(val, "bottomup")) + direction = eDirection::bottomup; + else if (!strcmp(val, "topdown")) + direction = eDirection::topdown; + attribs[id] = (int)direction; +} + +/*************************************************************************** +* Private Functions +***************************************************************************/ +void cAttributes::SetCommonAttributesDefs(void) { + commonAttribIDs.insert(pair("x", (int)eCommonAttribs::x)); + commonAttribIDs.insert(pair("y", (int)eCommonAttribs::y)); + commonAttribIDs.insert(pair("width", (int)eCommonAttribs::width)); + commonAttribIDs.insert(pair("height", (int)eCommonAttribs::height)); + commonAttribIDs.insert(pair("debug", (int)eCommonAttribs::debug)); + commonAttribNames.insert(pair((int)eCommonAttribs::x, "x")); + commonAttribNames.insert(pair((int)eCommonAttribs::y, "y")); + commonAttribNames.insert(pair((int)eCommonAttribs::width, "width")); + commonAttribNames.insert(pair((int)eCommonAttribs::height, "height")); + commonAttribNames.insert(pair((int)eCommonAttribs::debug, "debug")); +} + +/*************************************************************************** +* cFunction +***************************************************************************/ +cFunction::cFunction(cArea *owner, int numAttributes) : cAttributes(numAttributes) { + funcType = "Unknown"; + owningArea = owner; + color = NULL; + name = NULL; + scrolling = false; +} + +cFunction::cFunction(const cFunction &other) : cAttributes(other) { + funcType = other.funcType; + owningArea = NULL; + color = NULL; + if (other.color) + color = new cColor(*other.color); + name = NULL; + if (other.name) + name = strdup(other.name); + scrolling = other.scrolling; +} + +cFunction::~cFunction(void) { + delete color; + free(name); +} + +void cFunction::SetLoopInfo(cLoopInfo *loopInfo) { + for (int i=0; i < numAttribs; i++) { + if (!attribCtors[i]) + continue; + attribCtors[i]->SetLoopInfo(loopInfo); + } + if (cond) + cond->SetLoopInfo(loopInfo); +} + +void cFunction::Cache(void) { + if (color) { + color->SetGlobals(globals); + color->Cache(); + } + cAttributes::Cache(); +} + +void cFunction::CacheFuncReferences(void) { + for (int i=0; i < numAttribs; i++) { + if (!attribCtors[i]) + continue; + vector refFactors = attribCtors[i]->GetRefFactors(); + for (vector::iterator it = refFactors.begin(); it != refFactors.end(); it++) { + cFactor *f = *it; + if (!f->funcRefName) + continue; + cFunction *fRef = owningArea->GetFunction(f->funcRefName); + if (fRef) { + f->funcRef = fRef; + } + } + } +} + +int cFunction::GetX(eAlign align, int x0, int colWidth) { + int containerWidth = colWidth > 0 ? colWidth : container.Width(); + int x = x0 + X(); + if (align == eAlign::right) { + x = x0 + containerWidth - FuncWidth(); + } else if (align == eAlign::center) { + x = x0 + (containerWidth - FuncWidth()) / 2; + } + return x; +} + +int cFunction::GetY(eAlign valign, int y0, int rowHeight) { + int containerHeight = rowHeight > 0 ? rowHeight : container.Height(); + int y = y0 + Y(); + if (valign == eAlign::bottom) { + y = y0 + containerHeight - FuncHeight(); + } else if (valign == eAlign::center) { + y = y0 + (containerHeight - FuncHeight()) / 2; + } + return y; +} + +void cFunction::Debug(void) { + esyslog("skindesigner: ---> Function %s", funcType); + cAttributes::Debug(); + if (name) { + esyslog("skindesigner: name %s", name); + } + if (color) { + color->Debug(); + } +} + +/*************************************************************************** +* Protected Functions +***************************************************************************/ + +void cFunction::SetColor(const char *val) { + color = new cColor(val); +} + +void cFunction::SetAnimType(int id, const char *val) { + eAnimType animType = eAnimType::none; + if (!strcmp(val, "blink")) + animType = eAnimType::blink; + else if (!strcmp(val, "animated")) + animType = eAnimType::animated; + attribs[id] = (int)animType; +} + +void cFunction::SetOverflow(int id, const char *val) { + eOverflowType overflowType = eOverflowType::none; + if (!strcmp(val, "linewrap")) + overflowType = eOverflowType::wrap; + else if (!strcmp(val, "cut")) + overflowType = eOverflowType::cut; + attribs[id] = (int)overflowType; +} diff --git a/coreengine/attribute.h b/coreengine/attribute.h new file mode 100644 index 0000000..e9da37e --- /dev/null +++ b/coreengine/attribute.h @@ -0,0 +1,126 @@ +#ifndef __ATTRIBUTE_H +#define __ATTRIBUTE_H + +#include +#include +#include +#include +#include +#include +#include "globals.h" +#include "../libskindesignerapi/tokencontainer.h" +#include "definitions.h" +#include "complextypes.h" + +class cArea; +/****************************************************************** +* cAttributes +******************************************************************/ +class cAttributes { +private: + map commonAttribIDs; + map commonAttribNames; + void SetCommonAttributesDefs(void); +protected: + cGlobals *globals; + skindesignerapi::cTokenContainer *tokenContainer; + cRect container; + int numAttribs; + int *attribs; + cNumericExpr **attribCtors; + cCondition *cond; + map attribIDs; + map attribNames; + int CommonAttributeId(const char *att); + const char *CommonAttributeName(int id); + int AttributeId(const char *att); + const char *AttributeName(int id); + bool SetCommon(int id, const char *val); + virtual bool IdEqual(int id, int compId); + void SetBool(int id, const char *val); + void SetViewElementMode(int id, const char *val); + void SetShiftType(int id, const char *val); + void SetShiftMode(int id, const char *val); + void SetScrollMode(int id, const char *val); + void SetScrollSpeed(int id, const char *val); + void SetOrientation(int id, const char *val); + void SetDirection(int id, const char *val); + void SetAlign(int id, const char *val); +public: + cAttributes(int numAttributes); + cAttributes(const cAttributes &other); + virtual ~cAttributes(void); + void SetGlobals(cGlobals *globals) { this->globals = globals; }; + void SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer); + virtual void SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer); + virtual void SetContainer(int x, int y, int width, int height); + virtual void Set(vector &attributes) {}; + void SetX(int width); + void SetY(int height); + void SetWidth(int width); + void SetHeight(int height); + virtual void Cache(void); + int GetValue(int id); + int X(void); + int Y(void); + int Width(void); + int Height(void); + int DoDebug(void) { return attribs[(int)eCommonAttribs::debug] == 1 ? true : false; }; + bool DoExecute(void); + virtual void Debug(void); +}; +/****************************************************************** +* cLoopInfo +******************************************************************/ +class cLoopInfo { +public: + int colWidth; + int rowHeight; + int index; + int row; + cLoopInfo(void) { + colWidth = 0; + rowHeight = 0; + index = 0; + row = 0; + }; +}; +/****************************************************************** +* cFunction +******************************************************************/ +class cFunction : public cAttributes, public cListObject { +private: + cArea *owningArea; +protected: + const char *funcType; + cColor *color; + char *name; + bool scrolling; + void SetColor(const char *val); + void SetAnimType(int id, const char *val); + void SetOverflow(int id, const char *val); +public: + cFunction(cArea *owner, int numAttributes); + cFunction(const cFunction &other); + virtual ~cFunction(void); + virtual void SetLoopInfo(cLoopInfo *loopInfo); + void SetOwner(cArea *owner) { owningArea = owner; }; + const char *Name(void) { return name; }; + virtual void Cache(void); + void CacheFuncReferences(void); + void Scrolling(bool scrolling) { this->scrolling = scrolling; }; + virtual void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0) {}; + virtual int FuncX(void) { return X(); }; + virtual int FuncY(void) { return Y(); }; + virtual int FuncWidth(void) { return Width(); }; + virtual int FuncHeight(void) { return Height(); }; + virtual int Align(void) { return (int)eAlign::left; }; + virtual int Valign(void) { return (int)eAlign::top; }; + int GetX(eAlign align, int x0, int colWidth); + int GetY(eAlign valign, int y0, int rowHeight); + virtual bool Blinking(void) { return false; }; + virtual int BlinkFreq(void) { return -1; }; + virtual void Debug(void); +}; + +#endif //__ATTRIBUTE_H \ No newline at end of file diff --git a/coreengine/attributes.c b/coreengine/attributes.c new file mode 100644 index 0000000..97387d4 --- /dev/null +++ b/coreengine/attributes.c @@ -0,0 +1,447 @@ +#include "attributes.h" +#include "../config.h" + +/*************************************************************************** +* cViewAttribs +***************************************************************************/ +cViewAttribs::cViewAttribs(int numAttributes) : cAttributes(numAttributes) { + orientation = NULL; + SetAttributesDefs(); +} + +cViewAttribs::~cViewAttribs(void) { + delete orientation; +} + +void cViewAttribs::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown view attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eViewAttribs::shifttype)) { + SetShiftType(id, attVal); + } else if (IdEqual(id, (int)eViewAttribs::shiftmode)) { + SetShiftMode(id, attVal); + } else if (IdEqual(id, (int)eViewAttribs::orientation)) { + SetOrientationDynamic(id, attVal); + } else if (IdEqual(id, (int)eViewAttribs::hideroot)) { + SetBool(id, attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + if ( (id == (int)eViewAttribs::starty + (int)eCommonAttribs::count) || + (id == (int)eViewAttribs::scaletvy + (int)eCommonAttribs::count) || + (id == (int)eViewAttribs::scaletvheight + (int)eCommonAttribs::count) ) { + attribCtors[id]->SetVertical(); + } + } + } +} + +void cViewAttribs::SetAttributesDefs(void) { + attribIDs.insert(pair("fadetime", (int)eViewAttribs::fadetime)); + attribIDs.insert(pair("shifttime", (int)eViewAttribs::shifttime)); + attribIDs.insert(pair("shifttype", (int)eViewAttribs::shifttype)); + attribIDs.insert(pair("shiftmode", (int)eViewAttribs::shiftmode)); + attribIDs.insert(pair("startx", (int)eViewAttribs::startx)); + attribIDs.insert(pair("starty", (int)eViewAttribs::starty)); + attribIDs.insert(pair("scaletvx", (int)eViewAttribs::scaletvx)); + attribIDs.insert(pair("scaletvy", (int)eViewAttribs::scaletvy)); + attribIDs.insert(pair("scaletvwidth", (int)eViewAttribs::scaletvwidth)); + attribIDs.insert(pair("scaletvheight", (int)eViewAttribs::scaletvheight)); + attribIDs.insert(pair("orientation", (int)eViewAttribs::orientation)); + attribIDs.insert(pair("debuggrid", (int)eViewAttribs::debuggrid)); + attribIDs.insert(pair("hideroot", (int)eViewAttribs::hideroot)); + attribNames.insert(pair((int)eViewAttribs::fadetime, "fadetime")); + attribNames.insert(pair((int)eViewAttribs::shifttime, "shifttime")); + attribNames.insert(pair((int)eViewAttribs::shifttype, "shifttype")); + attribNames.insert(pair((int)eViewAttribs::shiftmode, "shiftmode")); + attribNames.insert(pair((int)eViewAttribs::startx, "startx")); + attribNames.insert(pair((int)eViewAttribs::starty, "starty")); + attribNames.insert(pair((int)eViewAttribs::scaletvx, "scaletvx")); + attribNames.insert(pair((int)eViewAttribs::scaletvy, "scaletvy")); + attribNames.insert(pair((int)eViewAttribs::scaletvwidth, "scaletvwidth")); + attribNames.insert(pair((int)eViewAttribs::scaletvheight, "scaletvheight")); + attribNames.insert(pair((int)eViewAttribs::orientation, "orientation")); + attribNames.insert(pair((int)eViewAttribs::debuggrid, "debuggrid")); + attribNames.insert(pair((int)eViewAttribs::hideroot, "hideroot")); +} + +void cViewAttribs::Cache(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + cAttributes::Cache(); + if (orientation) { + orientation->SetGlobals(globals); + orientation->SetTokenContainer(tokenContainer); + orientation->Cache(); + char *res = orientation->DeterminateText(); + if (res) { + SetOrientation((int)eViewAttribs::orientation + (int)eCommonAttribs::count, res); + } + free(res); + } +} + +void cViewAttribs::Debug(void) { + esyslog("skindesigner: --> View Attribs"); + cAttributes::Debug(); +} + +eOrientation cViewAttribs::Orientation(void) { + int orientation = GetValue((int)eViewAttribs::orientation); + if (orientation == -1) + return eOrientation::vertical; + if (orientation == (int)eOrientation::none) + return eOrientation::vertical; + return (eOrientation)orientation; +} + +cRect cViewAttribs::TvFrame(void) { + int frameX = GetValue((int)eViewAttribs::scaletvx); + int frameY = GetValue((int)eViewAttribs::scaletvy); + int frameWidth = GetValue((int)eViewAttribs::scaletvwidth); + int frameHeight = GetValue((int)eViewAttribs::scaletvheight); + if (frameX < 0 || frameY < 0 || frameWidth <= 0 || frameHeight <= 0) + return cRect::Null; + frameX += cOsd::OsdLeft(); + frameY += cOsd::OsdTop(); + return cRect(frameX, frameY, frameWidth, frameHeight); +} + +void cViewAttribs::SetOrientationDynamic(int id, const char *val) { + if (strchr(val, '{') && strchr(val, '}')) { + orientation = new cTextExpr(val); + } else { + SetOrientation(id, val); + } +} + +/*************************************************************************** +* cViewElementAttribs +***************************************************************************/ +cViewElementAttribs::cViewElementAttribs(int numAttributes) : cAttributes(numAttributes) { + name = NULL; + SetAttributesDefs(); +} + +cViewElementAttribs::cViewElementAttribs(const cViewElementAttribs &other) : cAttributes(other) { + name = NULL; +} + +cViewElementAttribs::~cViewElementAttribs(void) { + free(name); +} + +void cViewElementAttribs::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown view element attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eViewElementAttribs::mode)) { + SetViewElementMode(id, attVal); + } else if (IdEqual(id, (int)eViewElementAttribs::shifttype)) { + SetShiftType(id, attVal); + } else if (IdEqual(id, (int)eViewElementAttribs::shiftmode)) { + SetShiftMode(id, attVal); + } else if (IdEqual(id, (int)eViewElementAttribs::orientation)) { + SetOrientation(id, attVal); + } else if (IdEqual(id, (int)eViewElementAttribs::name)) { + name = strdup(attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + if (id == (int)eViewElementAttribs::starty + (int)eCommonAttribs::count) { + attribCtors[id]->SetVertical(); + } + } + } +} + +void cViewElementAttribs::SetAttributesDefs(void) { + attribIDs.insert(pair("delay", (int)eViewElementAttribs::delay)); + attribIDs.insert(pair("fadetime", (int)eViewElementAttribs::fadetime)); + attribIDs.insert(pair("shifttime", (int)eViewElementAttribs::shifttime)); + attribIDs.insert(pair("shifttype", (int)eViewElementAttribs::shifttype)); + attribIDs.insert(pair("shiftmode", (int)eViewElementAttribs::shiftmode)); + attribIDs.insert(pair("startx", (int)eViewElementAttribs::startx)); + attribIDs.insert(pair("starty", (int)eViewElementAttribs::starty)); + attribIDs.insert(pair("orientation", (int)eViewElementAttribs::orientation)); + attribIDs.insert(pair("mode", (int)eViewElementAttribs::mode)); + attribIDs.insert(pair("name", (int)eViewElementAttribs::name)); + attribNames.insert(pair((int)eViewElementAttribs::delay, "delay")); + attribNames.insert(pair((int)eViewElementAttribs::fadetime, "fadetime")); + attribNames.insert(pair((int)eViewElementAttribs::shifttime, "shifttime")); + attribNames.insert(pair((int)eViewElementAttribs::shifttype, "shifttype")); + attribNames.insert(pair((int)eViewElementAttribs::shiftmode, "shiftmode")); + attribNames.insert(pair((int)eViewElementAttribs::startx, "startx")); + attribNames.insert(pair((int)eViewElementAttribs::starty, "starty")); + attribNames.insert(pair((int)eViewElementAttribs::orientation, "orientation")); + attribNames.insert(pair((int)eViewElementAttribs::mode, "mode")); + attribNames.insert(pair((int)eViewElementAttribs::name, "name")); +} + +eOrientation cViewElementAttribs::Orientation(void) { + int orientation = GetValue((int)eViewElementAttribs::orientation); + if (orientation == -1) + return eOrientation::vertical; + if (orientation == (int)eOrientation::none) + return eOrientation::vertical; + return (eOrientation)orientation; +} + +void cViewElementAttribs::Debug(void) { + esyslog("skindesigner: ---> View Element Attribs"); + cAttributes::Debug(); +} + +/*************************************************************************** +* cViewListAttribs +***************************************************************************/ +cViewListAttribs::cViewListAttribs(int numAttributes) : cAttributes(numAttributes) { + determinateFont = NULL; + SetAttributesDefs(); +} + +cViewListAttribs::~cViewListAttribs(void) { + free(determinateFont); +} + +void cViewListAttribs::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown view list attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eViewListAttribs::align)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eViewListAttribs::determinatefont)) { + determinateFont = strdup(attVal); + } else if (IdEqual(id, (int)eViewListAttribs::orientation)) { + SetOrientation(id, attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +int cViewListAttribs::NumListElements(void) { + return GetValue((int)eViewListAttribs::numlistelements); +} + +int cViewListAttribs::MenuItemWidth(void) { + return GetValue((int)eViewListAttribs::menuitemwidth); +} + +const char *cViewListAttribs::DeterminateFont(void) { + return determinateFont; +} + +eAlign cViewListAttribs::Align(void) { + int align = GetValue((int)eViewListAttribs::align); + if (align < 0) + return eAlign::top; + return (eAlign)align; +} + +eOrientation cViewListAttribs::Orientation(void) { + int orientation = GetValue((int)eViewListAttribs::orientation); + if (orientation < 0) + return eOrientation::vertical; + return (eOrientation)orientation; +} + +void cViewListAttribs::SetAttributesDefs(void) { + attribIDs.insert(pair("align", (int)eViewListAttribs::align)); + attribIDs.insert(pair("menuitemwidth", (int)eViewListAttribs::menuitemwidth)); + attribIDs.insert(pair("determinatefont", (int)eViewListAttribs::determinatefont)); + attribIDs.insert(pair("numlistelements", (int)eViewListAttribs::numlistelements)); + attribIDs.insert(pair("orientation", (int)eViewListAttribs::orientation)); + attribIDs.insert(pair("condition", (int)eViewListAttribs::condition)); + attribNames.insert(pair((int)eViewListAttribs::align, "align")); + attribNames.insert(pair((int)eViewListAttribs::menuitemwidth, "menuitemwidth")); + attribNames.insert(pair((int)eViewListAttribs::determinatefont, "determinatefont")); + attribNames.insert(pair((int)eViewListAttribs::numlistelements, "numlistelements")); + attribNames.insert(pair((int)eViewListAttribs::orientation, "orientation")); + attribNames.insert(pair((int)eViewListAttribs::condition, "condition")); +} + +void cViewListAttribs::Debug(void) { + esyslog("skindesigner: ---> View List Attribs"); + esyslog("skindesigner: DeterminateFont %s", determinateFont); + cAttributes::Debug(); +} + +/*************************************************************************** +* cAreaAttribs +***************************************************************************/ +cAreaAttribs::cAreaAttribs(int numAttributes) : cAttributes(numAttributes) { + name = NULL; + scrollElement = NULL; + dynamic = false; + SetAttributesDefs(); +} + +cAreaAttribs::cAreaAttribs(const cAreaAttribs &other) : cAttributes(other) { + name = NULL; + if (other.name) + name = new cTextExpr(*other.name); + scrollElement = NULL; + if (other.scrollElement) + scrollElement = strdup(other.scrollElement); + dynamic = false; +} + +cAreaAttribs::~cAreaAttribs(void) { + delete name; + free(scrollElement); +} + +void cAreaAttribs::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown area attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eAreaAttribs::scrollelement)) { + scrollElement = strdup(attVal); + } else if (IdEqual(id, (int)eAreaAttribs::mode)) { + SetScrollMode(id, attVal); + } else if (IdEqual(id, (int)eAreaAttribs::orientation)) { + SetOrientation(id, attVal); + } else if (IdEqual(id, (int)eAreaAttribs::scrollspeed)) { + SetScrollSpeed(id, attVal); + } else if (IdEqual(id, (int)eAreaAttribs::background)) { + SetBool(id, attVal); + } else if (IdEqual(id, (int)eAreaAttribs::name)) { + name = new cTextExpr(attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +int cAreaAttribs::Layer(void) { + if (GetValue((int)eAreaAttribs::layer) > 0) { + return GetValue((int)eAreaAttribs::layer); + } + return 1; +} + +bool cAreaAttribs::BackgroundArea(void) { + int isBackground = GetValue((int)eAreaAttribs::background); + if (isBackground == 1) + return true; + return false; +} + +void cAreaAttribs::CheckDynamic(void) { + for (int i = (int)eCommonAttribs::x; i <= (int)eCommonAttribs::height; ++i ) { + if (attribCtors[i] && attribCtors[i]->Dynamic()) { + dynamic = true; + return; + } + } +} + +const char *cAreaAttribs::Name(void) { + if (name) + return name->DeterminateText(); + return NULL; +} + +void cAreaAttribs::SetAttributesDefs(void) { + attribIDs.insert(pair("layer", (int)eAreaAttribs::layer)); + attribIDs.insert(pair("transparency", (int)eAreaAttribs::transparency)); + attribIDs.insert(pair("mode", (int)eAreaAttribs::mode)); + attribIDs.insert(pair("orientation", (int)eAreaAttribs::orientation)); + attribIDs.insert(pair("scrollelement", (int)eAreaAttribs::scrollelement)); + attribIDs.insert(pair("scrollspeed", (int)eAreaAttribs::scrollspeed)); + attribIDs.insert(pair("delay", (int)eAreaAttribs::delay)); + attribIDs.insert(pair("background", (int)eAreaAttribs::background)); + attribIDs.insert(pair("name", (int)eAreaAttribs::name)); + attribIDs.insert(pair("scrollheight", (int)eAreaAttribs::scrollheight)); + attribNames.insert(pair((int)eAreaAttribs::layer, "layer")); + attribNames.insert(pair((int)eAreaAttribs::transparency, "transparency")); + attribNames.insert(pair((int)eAreaAttribs::mode, "mode")); + attribNames.insert(pair((int)eAreaAttribs::orientation, "orientation")); + attribNames.insert(pair((int)eAreaAttribs::scrollelement, "scrollelement")); + attribNames.insert(pair((int)eAreaAttribs::scrollspeed, "scrollspeed")); + attribNames.insert(pair((int)eAreaAttribs::delay, "delay")); + attribNames.insert(pair((int)eAreaAttribs::background, "background")); + attribNames.insert(pair((int)eAreaAttribs::name, "name")); + attribNames.insert(pair((int)eAreaAttribs::scrollheight, "scrollheight")); +} + +void cAreaAttribs::Cache(void) { + cAttributes::Cache(); + if (name) { + name->SetGlobals(globals); + name->SetTokenContainer(tokenContainer); + name->Cache(); + } +} + +void cAreaAttribs::Debug(void) { + if (!name) { + esyslog("skindesigner: ---> Area Attribs"); + } else { + esyslog("skindesigner: ---> Tab %s Attribs", name->DeterminateText()); + } + cAttributes::Debug(); +} + +/*************************************************************************** +* cAreaContainerAttribs +***************************************************************************/ +cAreaContainerAttribs::cAreaContainerAttribs(int numAttributes) : cAttributes(numAttributes) { + SetAttributesDefs(); +} + +cAreaContainerAttribs::cAreaContainerAttribs(const cAreaContainerAttribs &other) : cAttributes(other) { +} + +cAreaContainerAttribs::~cAreaContainerAttribs(void) { +} + +void cAreaContainerAttribs::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown area container attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + } +} + +void cAreaContainerAttribs::SetAttributesDefs(void) { +} + +void cAreaContainerAttribs::Debug(void) { + esyslog("skindesigner: ---> Area Container Attribs"); + cAttributes::Debug(); +} + diff --git a/coreengine/attributes.h b/coreengine/attributes.h new file mode 100644 index 0000000..5280db7 --- /dev/null +++ b/coreengine/attributes.h @@ -0,0 +1,111 @@ +#ifndef __ATTRIBUTES_H +#define __ATTRIBUTES_H + +#include "attribute.h" +/****************************************************************** +* cViewAttribs +******************************************************************/ +class cViewAttribs : public cAttributes { +private: + cTextExpr *orientation; + void SetAttributesDefs(void); + void SetOrientationDynamic(int id, const char *val); +public: + cViewAttribs(int numAttributes); + virtual ~cViewAttribs(void); + void Set(vector &attributes); + eOrientation Orientation(void); + int FadeTime(void) { return GetValue((int)eViewAttribs::fadetime); }; + int ShiftTime(void) { return GetValue((int)eViewAttribs::shifttime); }; + cPoint ShiftStartpoint(void) { return cPoint(GetValue((int)eViewAttribs::startx), GetValue((int)eViewAttribs::starty)); }; + int ShiftType(void) { return GetValue((int)eViewAttribs::shifttype); }; + int ShiftMode(void) { return GetValue((int)eViewAttribs::shiftmode); }; + cRect TvFrame(void); + void Cache(void); + void Debug(void); +}; +/****************************************************************** +* cViewElementAttribs +******************************************************************/ +class cViewElementAttribs : public cAttributes { +private: + char *name; + void SetAttributesDefs(void); +public: + cViewElementAttribs(int numAttributes); + cViewElementAttribs(const cViewElementAttribs &other); + virtual ~cViewElementAttribs(void); + void Set(vector &attributes); + int Mode(void) { return GetValue((int)eViewElementAttribs::mode); }; + int Delay(void) { return GetValue((int)eViewElementAttribs::delay); }; + eOrientation Orientation(void); + int FadeTime(void) { return GetValue((int)eViewElementAttribs::fadetime); }; + int ShiftTime(void) { return GetValue((int)eViewElementAttribs::shifttime); }; + cPoint ShiftStartpoint(void) { return cPoint(GetValue((int)eViewElementAttribs::startx), GetValue((int)eViewElementAttribs::starty)); }; + int ShiftType(void) { return GetValue((int)eViewElementAttribs::shifttype); }; + int ShiftMode(void) { return GetValue((int)eViewElementAttribs::shiftmode); }; + const char *Name(void) { return name; }; + void Debug(void); +}; +/****************************************************************** +* cViewListAttribs +******************************************************************/ +class cViewListAttribs : public cAttributes { +private: + char *determinateFont; + void SetAttributesDefs(void); +public: + cViewListAttribs(int numAttributes); + virtual ~cViewListAttribs(void); + void Set(vector &attributes); + int NumListElements(void); + int MenuItemWidth(void); + const char *DeterminateFont(void); + eAlign Align(void); + eOrientation Orientation(void); + void Debug(void); +}; +/****************************************************************** +* cAreaAttribs +******************************************************************/ +class cAreaAttribs : public cAttributes { +private: + cTextExpr *name; + char *scrollElement; + void SetAttributesDefs(void); + bool dynamic; +public: + cAreaAttribs(int numAttributes); + cAreaAttribs(const cAreaAttribs &other); + virtual ~cAreaAttribs(void); + void Set(vector &attributes); + const char *GetScrollElement(void) { return scrollElement; }; + int Orientation(void) { return GetValue((int)eAreaAttribs::orientation); }; + int Delay(void) { return GetValue((int)eAreaAttribs::delay); }; + int Mode(void) { return GetValue((int)eAreaAttribs::mode); }; + int ScrollSpeed(void) { return GetValue((int)eAreaAttribs::scrollspeed); }; + int Transparency(void) { return GetValue((int)eAreaAttribs::transparency); }; + int Layer(void); + int ScrollStep(void) { return GetValue((int)eAreaAttribs::scrollheight); }; + bool BackgroundArea(void); + const char *Name(void); + void CheckDynamic(void); + bool Dynamic(void) {return dynamic; }; + void Cache(void); + void Debug(void); +}; +/****************************************************************** +* cAreaContainerAttribs +******************************************************************/ +class cAreaContainerAttribs : public cAttributes { +private: + void SetAttributesDefs(void); +public: + cAreaContainerAttribs(int numAttributes); + cAreaContainerAttribs(const cAreaContainerAttribs &other); + virtual ~cAreaContainerAttribs(void); + void Set(vector &attributes); + void Debug(void); +}; + +#endif //__ATTRIBUTES_H \ No newline at end of file diff --git a/coreengine/complextypes.c b/coreengine/complextypes.c new file mode 100644 index 0000000..ea15bf4 --- /dev/null +++ b/coreengine/complextypes.c @@ -0,0 +1,1605 @@ +#include "complextypes.h" +#include "../config.h" + +/****************************************************************** +* helpers +******************************************************************/ +char *RemoveSpace(char *e) { + if (!e) + return e; + int numSpaces = 0; + int exprLen = strlen(e); + for (int i = 0; i < exprLen; ++i) { + if (isspace(e[i])) + ++numSpaces; + } + if (numSpaces == 0) + return e; + + char *replaced = (char*)malloc(exprLen - numSpaces + 1); + replaced[exprLen - numSpaces] = '\0'; + int j = 0; + for (int i = 0; i < exprLen; ++i) { + if (!isspace(e[i])){ + replaced[j++] = e[i]; + } + } + free(e); + return replaced; +} + +void ReplaceDecimalpoint(char *e) { + int size = (int)strlen(e); + for ( int i = 0; i < size; ++i ) { + if (e[i] == '.') + e[i] = config.decPoint; + } +} + +void ReplaceStart(char *e, int num) { + int size = (int)strlen(e); + if (size <= num) + return; + for ( int i = 0; i < size; ++i ) { + if (i < size - num) + e[i] = e[i+num]; + else e[i] = 0; + } +} + +void ReplaceEnd(char *e, int num) { + int size = (int)strlen(e) - 1; + if (size <= num) + return; + for ( int i = size; i > size-num; --i ) { + e[i] = 0; + } +} +/****************************************************************** +* cCond +******************************************************************/ +cCond::cCond(const char *expression) { + this->expr = strdup(expression); + operation = eCondOp::tAnd; + type = eCondType::token; + constant = false; + isTrue = false; + tokenIndex = -1; + compareValue = -1; + compareStrValue = NULL; +} + +cCond::cCond(const cCond &other) { + expr = strdup(other.expr); + operation = other.operation; + type = other.type; + constant = other.constant; + tokenType = other.tokenType; + isTrue = other.isTrue; + tokenIndex = other.tokenIndex; + compareValue = other.compareValue; + compareStrValue = NULL; + if (other.compareStrValue) + compareStrValue = strdup(other.compareStrValue); +} + +cCond::~cCond(void) { + free(expr); + free(compareStrValue); +} + +void cCond::Debug(void) { + esyslog("skindesigner: cond %s, operation %s, type %d", expr, + (operation == eCondOp::tAnd) ? "++" : "||", + (int)type); + if (constant) + esyslog("skindesigner: constant cond: %s", isTrue ? "TRUE" : "FALSE"); + if (tokenIndex >= 0) + esyslog("skindesigner: token index: %d", tokenIndex); + if (compareValue >= 0) + esyslog("skindesigner: compare value: %d", compareValue); + if (compareStrValue) + esyslog("skindesigner: compare string value: %d", compareStrValue); +} + +/****************************************************************** +* cCondition +******************************************************************/ +cCondition::cCondition(const char *expression) { + expr = strdup(expression); + globals = NULL; + tokenContainer = NULL; + loopInfo = NULL; +} + +cCondition::cCondition(const cCondition &other) { + expr = strdup(other.expr); + globals = NULL; + tokenContainer = NULL; + loopInfo = NULL; + for (cCond *cond = other.conds.First(); cond; cond = other.conds.Next(cond)) + conds.Add(new cCond(*cond)); +} + +cCondition::~cCondition(void) { + free(expr); +} + +void cCondition::Prepare(void) { + expr = RemoveSpace(expr); + Tokenize(); + PrepareTokens(); +} + +bool cCondition::True(void) { + if (conds.Count() == 0) + return true; + bool ok = true; + for (cCond *c = conds.First(); c; c = conds.Next(c)) { + bool condTrue = true; + //evaluate condition + if (c->constant) + { + condTrue = c->isTrue; + } + else if (c->type == eCondType::token) + { + if (c->tokenType == eCondTokenType::inttoken) { + int tokenVal = tokenContainer->IntToken(c->tokenIndex); + condTrue = (tokenVal > 0) ? true : false; + } else if (c->tokenType == eCondTokenType::stringtoken) { + char *tokenVal = tokenContainer->StringToken(c->tokenIndex); + if (tokenVal) + condTrue = (!strcmp(tokenVal, "1")) ? true : false; + } else if (c->tokenType == eCondTokenType::looptoken) { + if (loopInfo && loopInfo->row >= 0) { + char *tokenVal = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, c->tokenIndex); + if (tokenVal) + condTrue = (!strcmp(tokenVal, "1")) ? true : false; + } + } + + } + else if (c->type == eCondType::negtoken) + { + if (c->tokenType == eCondTokenType::inttoken) { + int tokenVal = tokenContainer->IntToken(c->tokenIndex); + condTrue = (tokenVal > 0) ? false : true; + } else if (c->tokenType == eCondTokenType::stringtoken) { + char *tokenVal = tokenContainer->StringToken(c->tokenIndex); + if (tokenVal) + condTrue = (!strcmp(tokenVal, "1")) ? false : true; + } else if (c->tokenType == eCondTokenType::looptoken) { + if (loopInfo && loopInfo->row >= 0) { + char *tokenVal = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, c->tokenIndex); + if (tokenVal) + condTrue = (!strcmp(tokenVal, "1")) ? false : true; + } + } + } + else if (c->type == eCondType::lowerInt || c->type == eCondType::equalInt || c->type == eCondType::greaterInt) + { + if (c->tokenType == eCondTokenType::inttoken) { + int tokenVal = tokenContainer->IntToken(c->tokenIndex); + if (c->type == eCondType::lowerInt) + condTrue = (tokenVal < c->compareValue) ? true : false; + else if (c->type == eCondType::equalInt) + condTrue = (tokenVal == c->compareValue) ? true : false; + else if (c->type == eCondType::greaterInt) + condTrue = (tokenVal > c->compareValue) ? true : false; + } else if (c->tokenType == eCondTokenType::stringtoken) { + char *tokenVal = tokenContainer->StringToken(c->tokenIndex); + if (tokenVal) { + int intVal = atoi(tokenVal); + if (c->type == eCondType::lowerInt) + condTrue = (intVal < c->compareValue) ? true : false; + else if (c->type == eCondType::equalInt) + condTrue = (intVal == c->compareValue) ? true : false; + else if (c->type == eCondType::greaterInt) + condTrue = (intVal > c->compareValue) ? true : false; + } + } else if (c->tokenType == eCondTokenType::looptoken) { + if (loopInfo && loopInfo->row >= 0) { + char *tokenVal = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, c->tokenIndex); + if (tokenVal) { + int intVal = atoi(tokenVal); + if (c->type == eCondType::lowerInt) + condTrue = (intVal < c->compareValue) ? true : false; + else if (c->type == eCondType::equalInt) + condTrue = (intVal == c->compareValue) ? true : false; + else if (c->type == eCondType::greaterInt) + condTrue = (intVal > c->compareValue) ? true : false; + } + } + } + } + else if (c->type == eCondType::isset || c->type == eCondType::empty) + { + if (c->tokenType == eCondTokenType::stringtoken) { + char *tokenVal = tokenContainer->StringToken(c->tokenIndex); + if (tokenVal) { + if (c->type == eCondType::isset) + condTrue = strlen(tokenVal) > 0 ? true : false; + else if (c->type == eCondType::empty) + condTrue = strlen(tokenVal) == 0 ? true : false; + } else { + if (c->type == eCondType::isset) + condTrue = false; + else if (c->type == eCondType::empty) + condTrue = true; + } + } else if (c->tokenType == eCondTokenType::looptoken) { + if (loopInfo && loopInfo->row >= 0) { + char *tokenVal = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, c->tokenIndex); + if (tokenVal) { + if (c->type == eCondType::isset) + condTrue = strlen(tokenVal) > 0 ? true : false; + else if (c->type == eCondType::empty) + condTrue = strlen(tokenVal) == 0 ? true : false; + } else { + if (c->type == eCondType::isset) + condTrue = false; + else if (c->type == eCondType::empty) + condTrue = true; + } + } + } + } + else if (c->type == eCondType::equalString || c->type == eCondType::notEqualString || c->type == eCondType::contains || c->type == eCondType::notContains) + { + if (c->tokenType == eCondTokenType::stringtoken) { + char *tokenVal = tokenContainer->StringToken(c->tokenIndex); + if (tokenVal) { + if (c->type == eCondType::equalString) + condTrue = !strcmp(tokenVal, c->compareStrValue) ? true : false; + else if (c->type == eCondType::notEqualString) + condTrue = strcmp(tokenVal, c->compareStrValue) ? true : false; + else if (c->type == eCondType::contains) + condTrue = strstr(tokenVal, c->compareStrValue) ? true : false; + else if (c->type == eCondType::notContains) + condTrue = !strstr(tokenVal, c->compareStrValue) ? true : false; + } + } else if (c->tokenType == eCondTokenType::looptoken) { + if (loopInfo && loopInfo->row >= 0) { + char *tokenVal = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, c->tokenIndex); + if (tokenVal) { + if (c->type == eCondType::equalString) + condTrue = !strcmp(tokenVal, c->compareStrValue) ? true : false; + else if (c->type == eCondType::notEqualString) + condTrue = strcmp(tokenVal, c->compareStrValue) ? true : false; + else if (c->type == eCondType::contains) + condTrue = strstr(tokenVal, c->compareStrValue) ? true : false; + else if (c->type == eCondType::notContains) + condTrue = !strstr(tokenVal, c->compareStrValue) ? true : false; + } + } + } + } //link + if (c->operation == eCondOp::tAnd) { + ok = ok && condTrue; + } else if (c->operation == eCondOp::tOr) { + ok = ok || condTrue; + } + } + return ok; +} + +void cCondition::Debug(void) { + esyslog("skindesigner: condition \"%s\"", expr); + for (cCond *c = conds.First(); c; c = conds.Next(c)) { + c->Debug(); + } + esyslog("skindesigner: condition is %s", True() ? "TRUE" : "FALSE"); +} + +void cCondition::Tokenize(void) { + char *condition = strdup(expr); + char delimiter[] = "+|"; + eCondOp operation = eCondOp::tAnd; + + char *cond = strtok(condition, delimiter); + while (cond) { + eCondType type = eCondType::token; + if (startswith(cond, "{") && endswith(cond, "}")) { + type = eCondType::token; + } else if (startswith(cond, "not{") && endswith(cond, "}")) { + type = eCondType::negtoken; + } else if (startswith(cond, "lt({") && endswith(cond, ")")) { + type = eCondType::lowerInt; + } else if (startswith(cond, "eq({") && endswith(cond, ")")) { + type = eCondType::equalInt; + } else if (startswith(cond, "gt({") && endswith(cond, ")")) { + type = eCondType::greaterInt; + } else if (startswith(cond, "isset{") && endswith(cond, "}")) { + type = eCondType::isset; + } else if (startswith(cond, "empty{") && endswith(cond, "}")) { + type = eCondType::empty; + } else if (startswith(cond, "strequal({") && endswith(cond, ")")) { + type = eCondType::equalString; + } else if (startswith(cond, "strnotequal({") && endswith(cond, ")")) { + type = eCondType::notEqualString; + } else if (startswith(cond, "strcontains({") && endswith(cond, ")")) { + type = eCondType::contains; + } else if (startswith(cond, "strnotcontains({") && endswith(cond, ")")) { + type = eCondType::notContains; + } else { + esyslog("skindesigner: invalid condition term %s", cond); + cond = strtok(NULL, delimiter); + continue; + } + cCond *c = new cCond(cond); + c->operation = operation; + c->type = type; + conds.Add(c); + if (expr[cond - condition + strlen(cond)] == '+') + operation = eCondOp::tAnd; + else + operation = eCondOp::tOr; + cond = strtok(NULL, delimiter); + } + free(condition); +} + +void cCondition::PrepareTokens(void) { + for (cCond *c = conds.First(); c; c = conds.Next(c)) { + switch (c->type) { + case eCondType::token: + case eCondType::negtoken: + SetTokenCond(c); + break; + case eCondType::lowerInt: + case eCondType::equalInt: + case eCondType::greaterInt: + SetIntegerCond(c); + break; + case eCondType::isset: + case eCondType::empty: + SetStringCond(c); + break; + case eCondType::equalString: + case eCondType::notEqualString: + case eCondType::contains: + case eCondType::notContains: + SetStringCompareCond(c); + break; + default: + break; + } + } +} + +void cCondition::SetTokenCond(cCond *c) { + if (c->type == eCondType::negtoken) { + ReplaceStart(c->expr, 3); + } + //check globals + int result = 0; + string tmp = c->expr; + tmp = tmp.substr(1, tmp.size()-2); + if (globals->GetInt(tmp, result)) { + c->constant = true; + if (result == 1 && c->type == eCondType::token) + c->isTrue = true; + if (result == 0 && c->type == eCondType::negtoken) + c->isTrue = true; + return; + } + SetTokenIndex(c, c->expr); +} + +void cCondition::SetIntegerCond(cCond *c) { + char *tokenStart = strchr(c->expr, '{'); + char *tokenEnd = strchr(c->expr, '}'); + if (!tokenStart || !tokenEnd) + return; + char token[200] = ""; + strncpy(token, tokenStart, tokenEnd - tokenStart + 1); + + char *condStart = strchr(c->expr, ','); + char *condEnd = strchr(c->expr, ')'); + char strCond[100] = ""; + strncpy(strCond, condStart + 1, condEnd - condStart - 1); + c->compareValue = atoi(strCond); + + //check globals + int result = 0; + if (globals->GetInt(token, result)) { + c->constant = true; + if (c->type == eCondType::lowerInt && result < c->compareValue) + c->isTrue = true; + else if (c->type == eCondType::equalInt && result == c->compareValue) + c->isTrue = true; + else if (c->type == eCondType::greaterInt && result > c->compareValue) + c->isTrue = true; + return; + } + SetTokenIndex(c, token); +} + +void cCondition::SetStringCond(cCond *c) { + ReplaceStart(c->expr, 5); + SetTokenIndex(c, c->expr); +} + +void cCondition::SetStringCompareCond(cCond *c) { + char *tokenStart = strchr(c->expr, '{'); + char *tokenEnd = strchr(c->expr, '}'); + if (!tokenStart || !tokenEnd) + return; + char token[200] = ""; + strncpy(token, tokenStart, tokenEnd - tokenStart + 1); + + char *condStart = strstr(c->expr, ",'"); + char *condEnd = strstr(c->expr, "')"); + char strCond[100] = ""; + strncpy(strCond, condStart + 2, condEnd - condStart - 2); + c->compareStrValue = strdup(strCond); + SetTokenIndex(c, token); +} + +void cCondition::SetTokenIndex(cCond *c, const char *token) { + int tokenIndex = tokenContainer->IntTokenIndex(token); + if (tokenIndex >= 0) { + c->tokenIndex = tokenIndex; + c->tokenType = eCondTokenType::inttoken; + return; + } + tokenIndex = tokenContainer->StringTokenIndex(token); + if (tokenIndex >= 0) { + c->tokenIndex = tokenIndex; + c->tokenType = eCondTokenType::stringtoken; + return; + } + tokenIndex = tokenContainer->LoopTokenIndex(token); + if (tokenIndex >= 0) { + c->tokenIndex = tokenIndex; + c->tokenType = eCondTokenType::looptoken; + } +} +/****************************************************************** +* cSummand +******************************************************************/ +cSummand::cSummand(const char *summand) { + this->summand = strdup(summand); +} + +cSummand::cSummand(const cSummand &other) { + summand = NULL; + if (other.summand) + summand = strdup(other.summand); + positive = other.positive; + for (cFactor *fac = other.factors.First(); fac; fac = other.factors.Next(fac)) { + factors.Add(new cFactor(*fac)); + } +} + +cSummand::~cSummand(void) { + free(summand); +} + +void cSummand::Debug(void) { + esyslog("skindesigner: summand %s, positive: %d", summand, positive); + for (cFactor *f = factors.First(); f; f = factors.Next(f)) { + const char *link = f->multiplication ? "multiplication" : "division"; + if (f->type == eFactorType::constant) + esyslog("skindesigner: constant factor %f, %s", f->constValue, link); + else if (f->type == eFactorType::inttoken) + esyslog("skindesigner: IntToken factor, index %d, %s", f->tokenIndex, link); + else if (f->type == eFactorType::stringtoken) + esyslog("skindesigner: StringToken factor, index %d, %s", f->tokenIndex, link); + else if (f->type == eFactorType::looptoken) + esyslog("skindesigner: LoopToken factor, index %d, %s", f->tokenIndex, link); + else if (f->type == eFactorType::xref) + esyslog("skindesigner: posx reference factor, %s, %p, %s, result: %f", f->funcRefName, f->funcRef, link, f->funcRef->FuncX()); + else if (f->type == eFactorType::yref) + esyslog("skindesigner: posy reference factor, %s, %p, %s, result: %f", f->funcRefName, f->funcRef, link, f->funcRef->FuncY()); + else if (f->type == eFactorType::widthref) + esyslog("skindesigner: width reference factor, %s, %p, %s, result: %f", f->funcRefName, f->funcRef, link, f->funcRef->FuncWidth()); + else if (f->type == eFactorType::heightref) + esyslog("skindesigner: height reference factor, %s, %p %s, result: %f", f->funcRefName, f->funcRef, link, f->funcRef->FuncHeight()); + else if (f->type == eFactorType::areawidth) + esyslog("skindesigner: {areawidth} factor, %s", link); + else if (f->type == eFactorType::areaheight) + esyslog("skindesigner: {areaheight} factor, %s", link); + else if (f->type == eFactorType::columnwidth) + esyslog("skindesigner: {columnwidth} factor, %s", link); + else if (f->type == eFactorType::rowheight) + esyslog("skindesigner: {rowheight} factor, %s", link); + } +} + +/****************************************************************** +* cNumericExpr +******************************************************************/ +cNumericExpr::cNumericExpr(const char *expression) { + expr = strdup(expression); + globals = NULL; + container = NULL; + tokenContainer = NULL; + loopInfo = NULL; + horizontal = true; + value = 0; + dynamic = false; +} + +cNumericExpr::cNumericExpr(const cNumericExpr &other) { + expr = strdup(other.expr); + globals = other.globals; + container = NULL; + tokenContainer = NULL; + loopInfo = NULL; + horizontal = other.horizontal; + value = other.value; + dynamic = other.dynamic; + for (cSummand *s = other.summands.First(); s; s = other.summands.Next(s)) { + summands.Add(new cSummand(*s)); + } +} + +cNumericExpr::~cNumericExpr(void) { + free(expr); +} + +/****************************************************************** +* Public Functions +******************************************************************/ +bool cNumericExpr::CacheStatic(void) { + expr = RemoveSpace(expr); + if (config.replaceDecPoint) + ReplaceDecimalpoint(expr); + + //first check if expression is already an valid integer + if (IsNumeric(expr)) { + value = atoi(expr); + return true; + } + + //check if expression is a percent expression + if (PercentValue(expr)) { + return true; + } + //if areawidth or height unknown, percent values have to be replaced + expr = ReplacePercentValue(expr); + //replace {areawidth} and {areaheight} + if (container->Width() >= 0) { + //esyslog("skindesigner: replacing areawidth %s", expr); + expr = ReplaceTokens(expr, "{areawidth}", container->Width()); + //esyslog("skindesigner: replaced areawidth %s", expr); + } + if (container->Height() >= 0) + expr = ReplaceTokens(expr, "{areaheight}", container->Height()); + + //replace globals + string tmp = expr; + globals->ReplaceIntVars(tmp); + globals->ReplaceDoubleVars(tmp); + free(expr); + expr = strdup(tmp.c_str()); + if (IsNumeric(expr)) { + value = atoi(expr); + return true; + } + //check if all variables are eliminated + if (IsNumericExpression(expr)) { + value = EvaluateExpression(expr); + return true; + } + //now we have a expression with runtime variables + dynamic = true; + return false; +} + +void cNumericExpr::PrepareTokens(void) { + CreateSummands(); + CreateFactors(); + ConsolidateFactors(); + ConsolidateSummand(); +} + +vector cNumericExpr::GetRefFactors(void) { + vector refFactors; + for (cSummand *s = summands.First(); s; s = summands.Next(s)) { + for (cFactor* f = s->factors.First(); f; f = s->factors.Next(f)) { + if (f->type >= eFactorType::xref) { + refFactors.push_back(f); + } + } + } + return refFactors; +} + +int cNumericExpr::Calculate(void) { + double result = 0.0f; + for (cSummand *s = summands.First(); s; s = summands.Next(s)) { + double factor = 1.0f; + for (cFactor *f = s->factors.First(); f; f = s->factors.Next(f)) { + double fac = 0.0f; + switch( f->type ) { + case eFactorType::constant: + fac = f->constValue; + break; + case eFactorType::stringtoken: { + char *val = tokenContainer->StringToken(f->tokenIndex); + if (val) + fac = atoi(val); + break; } + case eFactorType::inttoken: + fac = tokenContainer->IntToken(f->tokenIndex); + break; + case eFactorType::looptoken: + if (loopInfo && loopInfo->row >= 0) { + char *val = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, f->tokenIndex); + if (val) + fac = atoi(val); + } + break; + case eFactorType::xref: + if (f->funcRef) + fac = f->funcRef->FuncX(); + break; + case eFactorType::yref: + if (f->funcRef) + fac = f->funcRef->FuncY(); + break; + case eFactorType::widthref: + if (f->funcRef) + fac = f->funcRef->FuncWidth(); + break; + case eFactorType::heightref: + if (f->funcRef) + fac = f->funcRef->FuncHeight(); + break; + case eFactorType::areawidth: + fac = container->Width(); + break; + case eFactorType::areaheight: + fac = container->Height(); + break; + case eFactorType::columnwidth: + if (loopInfo) + fac = loopInfo->colWidth; + break; + case eFactorType::rowheight: + if (loopInfo) + fac = loopInfo->rowHeight; + break; + } + if (f->multiplication) + factor *= fac; + else if (fac) + factor /= fac; + } + if (s->positive) + result += factor; + else + result -= factor; + } + return (int)result; +} + + +void cNumericExpr::Debug(void) { + esyslog("skindesigner: Numeric Expression \"%s\", Result: %d", expr, Calculate()); + for (cSummand *s = summands.First(); s; s = summands.Next(s)) { + s->Debug(); + } +} + +/****************************************************************** +* Private Functions +******************************************************************/ +bool cNumericExpr::IsNumeric(const char *e) { + //negativ numbers + if (*e == '-') + ++e; + //empty + if (!*e) + return false; + while (*e) { + if (isdigit(*e) || *e == '.' || *e == ',') + ++e; + else + return false; + } + return true; +} + +bool cNumericExpr::IsNumericExpression(const char *e) { + if (!*e) + return false; + while (*e) { + if (isdigit(*e) || *e == '.' || *e == ',' || *e == '+' || *e == '-' || *e == '*' || *e == '/') + ++e; + else + return false; + } + return true; +} + +bool cNumericExpr::PercentValue(const char *e) { + const char *hit = strchr(e, '%'); + if (!hit) + return false; + char buffer[20] = ""; + if (strlen(e) > 20) + return false; + strncpy(buffer, e, strlen(e)-1); + buffer[strlen(e)-1] = '\0'; + int val = atoi(buffer); + bool ok = false; + if (horizontal && container->Width() > 0) { + value = container->Width() * val / 100; + ok = true; + } else if (!horizontal && container->Height() > 0){ + value = container->Height() * val / 100; + ok = true; + } + return ok; +} + +char *cNumericExpr::ReplacePercentValue(char *e) { + const char *hit = strchr(e, '%'); + if (!hit) + return e; + char buffer[20] = ""; + if (strlen(e) > 20) + return e; + strncpy(buffer, e, strlen(e)-1); + buffer[strlen(e)-1] = '\0'; + int val = atoi(buffer); + double percentVal = (double)val/100.0f; + + char replacement[50] = ""; + if (horizontal) { + sprintf(replacement, "%.5f*{areawidth}", percentVal); + } else { + sprintf(replacement, "%.5f*{areaheight}", percentVal); + } + + int len = strlen(replacement) + 1; + char *replaced = (char*)malloc(len); + memset(replaced, 0, len); + strcpy(replaced, replacement); + free(expr); + return replaced; +} + +char *cNumericExpr::ReplaceToken(char *e, const char* token, int val) { + char *tokenStart = strstr(e, token); + if (!tokenStart) { + return e; + } + char buffer[20] = ""; + sprintf(buffer, "%d", val); + size_t newSize = strlen(e) - strlen(token) + strlen(buffer) + 1; + char *replaced = (char*)malloc(newSize); + memset(replaced, 0, newSize); + size_t beginning = strlen(e) - strlen(tokenStart); + if (beginning > 0) + strncpy(replaced, e, beginning); + strcat(replaced, buffer); + strcat(replaced, tokenStart + strlen(token)); + free(e); + return replaced; +} + +char *cNumericExpr::ReplaceTokens(char *e, const char* token, int val) { + if (!e) + return e; + while (true) { + char *tokenStart = strstr(e, token); + if (!tokenStart) + break; + e = ReplaceToken(e, token, val); + } + return e; +} + +int cNumericExpr::EvaluateExpression(char* e) { + return round(ParseSummands(e)); +} + +double cNumericExpr::EvaluateExpressionDouble(char *e) { + return ParseSummands(e); +} + +double cNumericExpr::ParseAtom(char*& e) { + // Read the number from string + char* end_ptr; + double res = strtod(e, &end_ptr); + // Advance the pointer and return the result + e = end_ptr; + return res; +} + +// Parse multiplication and division +double cNumericExpr::ParseFactors(char*& e) { + double num1 = ParseAtom(e); + for(;;) { + // Save the operation + char op = *e; + if(op != '/' && op != '*') + return num1; + e++; + double num2 = ParseAtom(e); + // Perform the saved operation + if(op == '/') { + if (num2 != 0) { + num1 /= num2; + } + } else + num1 *= num2; + } +} + +// Parse addition and subtraction +double cNumericExpr::ParseSummands(char*& e) { + double num1 = ParseFactors(e); + for(;;) { + char op = *e; + if(op != '-' && op != '+') + return num1; + e++; + double num2 = ParseFactors(e); + if(op == '-') + num1 -= num2; + else + num1 += num2; + } +} + +void cNumericExpr::CreateSummands(void) { + char *sum = strdup(expr); + char delimiter[] = "+-"; + bool positive = true; + if (sum && *sum && *sum == '-') { + positive = false; + } + char *summand = strtok(sum, delimiter); + while (summand) { + cSummand *s = new cSummand(summand); + s->positive = positive; + summands.Add(s); + //check next sign + if (expr[summand - sum + strlen(summand)] == '-') + positive = false; + else + positive = true; + summand = strtok(NULL, delimiter); + } + free(sum); +} + +void cNumericExpr::CreateFactors(void) { + char delimiterFac[] = "*/"; + for (cSummand *s = summands.First(); s; s = summands.Next(s)) { + char *sum = strdup(s->summand); + if (IsNumericExpression(sum)) { + cFactor *f = new cFactor(); + f->constValue = EvaluateExpressionDouble(sum); + s->factors.Add(f); + free(sum); + continue; + } + bool multiplication = true; + char *fac = strtok(sum, delimiterFac); + while (fac) { + cFactor *f = new cFactor(); + if (IsNumeric(fac)) { + f->constValue = atof(fac); + f->multiplication = multiplication; + s->factors.Add(f); + } else { + //factor has to be a token or a function reference now + if (SetTokenFactor(f, fac)) { + f->multiplication = multiplication; + s->factors.Add(f); + } else if (SetReferenceFactor(f, fac)) { + f->multiplication = multiplication; + s->factors.Add(f); + } else if (SetGeometryFactor(f, fac)) { + f->multiplication = multiplication; + s->factors.Add(f); + } else { + esyslog("skindesigner: invalid factor %s in expression \"%s\"", fac, expr); + delete f; + } + } + //check next sign + if (s->summand[fac - sum + strlen(fac)] == '/') + multiplication = false; + else + multiplication = true; + fac = strtok(NULL, delimiterFac); + } + free(sum); + } +} + +bool cNumericExpr::SetTokenFactor(cFactor *f, char *tokenName) { + int tokenIndex = tokenContainer->IntTokenIndex(tokenName); + if (tokenIndex >= 0) { + f->tokenIndex = tokenIndex; + f->type = eFactorType::inttoken; + return true; + } + tokenIndex = tokenContainer->StringTokenIndex(tokenName); + if (tokenIndex >= 0) { + f->tokenIndex = tokenIndex; + f->type = eFactorType::stringtoken; + return true; + } + tokenIndex = tokenContainer->LoopTokenIndex(tokenName); + if (tokenIndex >= 0) { + f->tokenIndex = tokenIndex; + f->type = eFactorType::looptoken; + return true; + } + return false; +} + + +bool cNumericExpr::SetReferenceFactor(cFactor *f, char *tokenName) { + int start = 0; + if (startswith(tokenName, "{posx(") && endswith(tokenName, ")}")) { + start = 6; + f->type = eFactorType::xref; + } else if (startswith(tokenName, "{posy(") && endswith(tokenName, ")}")) { + start = 6; + f->type = eFactorType::yref; + } else if (startswith(tokenName, "{width(") && endswith(tokenName, ")}")) { + start = 7; + f->type = eFactorType::widthref; + } else if (startswith(tokenName, "{height(") && endswith(tokenName, ")}")) { + start = 8; + f->type = eFactorType::heightref; + } + + if (start == 0) + return false; + + tokenName += start; + f->funcRefName = strdup(tokenName); + ReplaceEnd(f->funcRefName, 2); + + return true; +} + +bool cNumericExpr::SetGeometryFactor(cFactor *f, char *tokenName) { + bool ok = false; + if (!strcmp(tokenName, "{areawidth}")) { + f->type = eFactorType::areawidth; + ok = true; + } else if (!strcmp(tokenName, "{areaheight}")) { + f->type = eFactorType::areaheight; + ok = true; + } else if (!strcmp(tokenName, "{columnwidth}")) { + f->type = eFactorType::columnwidth; + ok = true; + } else if (!strcmp(tokenName, "{rowheight}")) { + f->type = eFactorType::rowheight; + ok = true; + } + return ok; +} + +void cNumericExpr::ConsolidateSummand(void) { + cSummand *constSummand = NULL; + for (cSummand *s = summands.First(); s; s = summands.Next(s)) { + if (s->factors.Count() == 1 && s->factors.First()->type == eFactorType::constant) { + if (!constSummand) { + constSummand = s; + } else { + if (s->positive) + constSummand->factors.First()->constValue += s->factors.First()->constValue; + else + constSummand->factors.First()->constValue -= s->factors.First()->constValue; + summands.Del(s); + s = constSummand; + } + } + } +} + +void cNumericExpr::ConsolidateFactors(void) { + for (cSummand *s = summands.First(); s; s = summands.Next(s)) { + cFactor *constFactor = NULL; + for (cFactor *f = s->factors.First(); f; f = s->factors.Next(f)) { + if (f->type == eFactorType::constant) { + if (!constFactor) { + constFactor = f; + } else { + if (f->multiplication) + constFactor->constValue *= f->constValue; + else + constFactor->constValue /= f->constValue; + s->factors.Del(f); + f = constFactor; + } + } + } + } +} + +/****************************************************************** +* cColor +******************************************************************/ +cColor::cColor(const char *expression) { + globals = NULL; + expr = strdup(expression); + value = 0x00; +} + +cColor::cColor(const cColor &other) { + globals = other.globals; + expr = strdup(other.expr); + value = other.value; +} + +cColor::~cColor(void) { + free(expr); +} + +void cColor::Cache(void) { + tColor colVal = 0x00; + string tmp = expr; + if (globals->GetColor(tmp, colVal)) { + value = colVal; + return; + } + if (strlen(expr) != 8) + return; + std::stringstream str; + str << tmp; + colVal = 0x00; + str >> std::hex >> colVal; + value = colVal; +} + +tColor cColor::Color(void) { + return value; +} + +void cColor::Debug(void) { + esyslog("skindesigner: Color \"%s\", Value %x", expr, value); +} + +/****************************************************************** +* cTextExpr +******************************************************************/ +cTextExpr::cTextExpr(const char *expression) { + globals = NULL; + expr = strdup(expression); + tokenContainer = NULL; + loopInfo = NULL; +} + +cTextExpr::cTextExpr(const cTextExpr &other) { + globals = other.globals; + expr = strdup(other.expr); + tokenContainer = NULL; + loopInfo = NULL; + for (cTextToken* t = other.textTokens.First(); t; t = other.textTokens.Next(t)) { + textTokens.Add(new cTextToken(*t)); + } +} + +cTextExpr::~cTextExpr(void) { + free(expr); +} + +void cTextExpr::CorrectImagePath(void) { + //no absolute pathes allowed + if (!startswith(expr, "{")) { + esyslog("skindesigner: no absolute pathes allowed for images - %s", expr); + } + if (startswith(expr, "{ressourcedir}")) { + string tmp = expr; + tmp = tmp.replace(0, 14, *config.GetSkinRessourcePath()); + free(expr); + expr = strdup(tmp.c_str()); + } +} + + +void cTextExpr::Cache(void) { + Translate(); + Tokenize(); + PrepareTokens(); +} + +char *cTextExpr::DeterminateText(void) { + //calculate length of complete new string + int textLength = 0; + for (cTextToken* t = textTokens.First(); t; t = textTokens.Next(t)) { + if (t->type == eTexttokenType::constant) { + textLength += strlen(t->constValue); + } else if (t->type == eTexttokenType::stringtoken) { + char *str = tokenContainer->StringToken(t->tokenIndex); + if (str) + textLength += strlen(str); + } else if (t->type == eTexttokenType::inttoken) { + int value = tokenContainer->IntToken(t->tokenIndex); + if (value >= 0) { + cString str = cString::sprintf("%d", value); + textLength += strlen(*str); + } + } else if (t->type == eTexttokenType::looptoken && loopInfo && loopInfo->row >= 0) { + char *str = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, t->tokenIndex); + if (str) + textLength += strlen(str); + } else if (t->type == eTexttokenType::printftoken) { + DeterminatePrintfToken(t); + if (t->printfResult) + textLength += strlen(t->printfResult); + } else if (t->type == eTexttokenType::condstringtoken) { + char *str = tokenContainer->StringToken(t->tokenIndex); + if (str) { + textLength += strlen(str); + if (t->condStart) + textLength += strlen(t->condStart); + if (t->condEnd) + textLength += strlen(t->condEnd); + } + } else if (t->type == eTexttokenType::condinttoken) { + int value = tokenContainer->IntToken(t->tokenIndex); + if (value >= 0) { + cString str = cString::sprintf("%d", value); + textLength += strlen(*str); + if (t->condStart) + textLength += strlen(t->condStart); + if (t->condEnd) + textLength += strlen(t->condEnd); + } + } + } + + if (textLength <= 0) + return NULL; + + char *retVal = (char*)malloc(textLength+1); + memset(retVal, 0, textLength); + bool first = true; + for (cTextToken* t = textTokens.First(); t; t = textTokens.Next(t)) { + if (first) { + first = false; + if (t->type == eTexttokenType::constant) { + strcpy(retVal, t->constValue); + } else if (t->type == eTexttokenType::stringtoken) { + char *str = tokenContainer->StringToken(t->tokenIndex); + if (str) + strcpy(retVal, str); + } else if (t->type == eTexttokenType::inttoken) { + int value = tokenContainer->IntToken(t->tokenIndex); + if (value >= 0) { + cString str = cString::sprintf("%d", value); + strcpy(retVal, *str); + } + } else if (t->type == eTexttokenType::looptoken && loopInfo && loopInfo->row >= 0) { + char *str = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, t->tokenIndex); + if (str) + strcpy(retVal, str); + } else if (t->type == eTexttokenType::printftoken) { + if (t->printfResult) { + strcpy(retVal, t->printfResult); + free(t->printfResult); + t->printfResult = NULL; + } + } else if (t->type == eTexttokenType::condstringtoken) { + char *str = tokenContainer->StringToken(t->tokenIndex); + if (str) { + if (t->condStart) { + strcpy(retVal, t->condStart); + strcat(retVal, str); + } else { + strcpy(retVal, str); + } + if (t->condEnd) + strcat(retVal, t->condEnd); + } + } else if (t->type == eTexttokenType::condinttoken) { + int value = tokenContainer->IntToken(t->tokenIndex); + if (value >= 0) { + cString str = cString::sprintf("%d", value); + if (t->condStart) { + strcpy(retVal, t->condStart); + strcat(retVal, *str); + } else { + strcpy(retVal, *str); + } + if (t->condEnd) + strcat(retVal, t->condEnd); + } + } + } else { + if (t->type == eTexttokenType::constant) { + strcat(retVal, t->constValue); + } else if (t->type == eTexttokenType::stringtoken) { + char *str = tokenContainer->StringToken(t->tokenIndex); + if (str) + strcat(retVal, str); + } else if (t->type == eTexttokenType::inttoken) { + int value = tokenContainer->IntToken(t->tokenIndex); + cString str = cString::sprintf("%d", value); + strcat(retVal, *str); + } else if (t->type == eTexttokenType::looptoken && loopInfo && loopInfo->row >= 0) { + char *str = tokenContainer->LoopToken(loopInfo->index, loopInfo->row, t->tokenIndex); + if (str) + strcat(retVal, str); + } else if (t->type == eTexttokenType::printftoken) { + if (t->printfResult) { + strcat(retVal, t->printfResult); + free(t->printfResult); + t->printfResult = NULL; + } + } else if (t->type == eTexttokenType::condstringtoken) { + char *str = tokenContainer->StringToken(t->tokenIndex); + if (str) { + if (t->condStart) + strcat(retVal, t->condStart); + strcat(retVal, str); + if (t->condEnd) + strcat(retVal, t->condEnd); + } + } else if (t->type == eTexttokenType::condinttoken) { + int value = tokenContainer->IntToken(t->tokenIndex); + if (value >= 0) { + cString str = cString::sprintf("%d", value); + if (t->condStart) + strcat(retVal, t->condStart); + strcat(retVal, *str); + if (t->condEnd) + strcat(retVal, t->condEnd); + } + } + } + } + return retVal; +} + + +void cTextExpr::Debug(const char *exprName) { + esyslog("skindesigner: TextExpr %s: \"%s\"", exprName, expr); + char *res = DeterminateText(); + esyslog("skindesigner: Result: \"%s\"", res); + free(res); + for (cTextToken *t = textTokens.First(); t; t = textTokens.Next(t)) { + if (t->type == eTexttokenType::constant) + esyslog("skindesigner: constant token \"%s\"", t->constValue); + else if (t->type == eTexttokenType::stringtoken) + esyslog("skindesigner: string token %s, index %d", t->constValue, t->tokenIndex); + else if (t->type == eTexttokenType::inttoken) + esyslog("skindesigner: int token %s, index %d", t->constValue, t->tokenIndex); + else if (t->type == eTexttokenType::looptoken) + esyslog("skindesigner: loop token %s, index %d", t->constValue, t->tokenIndex); + else if (t->type == eTexttokenType::printftoken) + esyslog("skindesigner: printf token %s", t->constValue); + else if (t->type == eTexttokenType::condstringtoken || t->type == eTexttokenType::condinttoken) + esyslog("skindesigner: conditional token %s", t->constValue); + } +} + +void cTextExpr::Translate(void) { + string translated = ""; + if (!globals->Translate(expr, translated)) + return; + free(expr); + expr = strdup(translated.c_str()); +} + +void cTextExpr::Tokenize(void) { + char *head = expr; + char *tail = expr; + while (*tail) { + if (*tail == '|') { + char *begin = CopyTextPart(head, tail, false); + if (begin) { + cTextToken *t = new cTextToken(); + t->constValue = begin; + textTokens.Add(t); + } + head = tail; + tail++; + while (*tail) { + if (*tail == '|') { + char *token = CopyTextPart(head, tail); + cTextToken *t = new cTextToken(); + t->type = eTexttokenType::condstringtoken; + t->constValue = token; + textTokens.Add(t); + head = tail+1; + break; + } + tail++; + } + } else if (*tail == '{') { + char *begin = CopyTextPart(head, tail, false); + if (begin) { + cTextToken *t = new cTextToken(); + t->constValue = begin; + textTokens.Add(t); + } + head = tail; + tail++; + while (*tail) { + if (*tail == '}') { + char *token = CopyTextPart(head, tail); + cTextToken *t = new cTextToken(); + t->type = eTexttokenType::stringtoken; + t->constValue = token; + textTokens.Add(t); + head = tail+1; + break; + } + tail++; + } + } + tail++; + } + char *end = CopyTextPart(head, tail, false); + if (end) { + cTextToken *t = new cTextToken(); + t->constValue = end; + textTokens.Add(t); + } +} + +void cTextExpr::PrepareTokens(void) { + bool error = false; + for (cTextToken *t = textTokens.First(); t; t = textTokens.Next(t)) { + if (t->type == eTexttokenType::condstringtoken) { + ParseCondToken(t); + continue; + } else if (t->type != eTexttokenType::stringtoken) + continue; + if (ParsePrintfToken(t)) { + continue; + } + if (CheckGlobals(t)) { + continue; + } + int tokenIndex = tokenContainer->IntTokenIndex(t->constValue); + if (tokenIndex >= 0) { + t->tokenIndex = tokenIndex; + t->type = eTexttokenType::inttoken; + continue; + } + tokenIndex = tokenContainer->StringTokenIndex(t->constValue); + if (tokenIndex >= 0) { + t->tokenIndex = tokenIndex; + t->type = eTexttokenType::stringtoken; + continue; + } + tokenIndex = tokenContainer->LoopTokenIndex(t->constValue); + if (tokenIndex >= 0) { + t->tokenIndex = tokenIndex; + t->type = eTexttokenType::looptoken; + continue; + } + esyslog("skindesigner: invalid text token %s in expression \"%s\"", t->constValue, expr); + error = true; + break; + } + if (error) { + textTokens.Clear(); + } +} + +bool cTextExpr::CheckGlobals(cTextToken *t) { + if (!globals || !t->constValue) + return false; + + string name = t->constValue; + name = name.substr(1, name.size()-2); + string replacement = ""; + if (globals->GetString(name, replacement)) { + free(t->constValue); + t->constValue = strdup(replacement.c_str()); + t->type = eTexttokenType::constant; + return true; + } + int numReplacement = 0; + if (globals->GetInt(name, numReplacement)) { + free(t->constValue); + cString repl = cString::sprintf("%d", numReplacement); + t->constValue = strdup(*repl); + t->type = eTexttokenType::constant; + return true; + } + return false; +} + +bool cTextExpr::ParsePrintfToken(cTextToken *t) { + //check valid printftoken + char *start = strstr(t->constValue, "printf("); + if (!start) + return false; + char *end = strchr(start, ')'); + if (!end) + return false; + t->type = eTexttokenType::printftoken; + + //find printf expression + char *startExpr = strchr(t->constValue, '\''); + if (!startExpr) + return false; + char *endExpr = strchr(startExpr + 1, '\''); + if (!endExpr) + return false; + int expLen = endExpr - startExpr - 1; + char buffer[100]; + strncpy(buffer, startExpr+1, expLen); + buffer[expLen] = '\0'; + t->printfExpr = strdup(buffer); + + //find variables + char *startVar = strchr(t->constValue, ','); + if (!startVar) + return false; + startVar++; + vector varTokens; + char *nextVar = NULL; + while (nextVar = strchr(startVar, ',')) { + while(isspace(*startVar)) + startVar++; + int varLen = nextVar - startVar; + buffer[0] = '{'; + strncpy((char*)buffer + 1, startVar, varLen); + buffer[varLen+1] = '}'; + buffer[varLen+2] = '\0'; + int i = 1; + while(isspace(buffer[varLen-i])) { + buffer[varLen-i] = '}'; + buffer[varLen-i+1] = '\0'; + i++; + } + varTokens.push_back(buffer); + startVar = nextVar + 1; + } + if (startVar+1) { + int varLen = end - startVar; + buffer[0] = '{'; + strncpy((char*)buffer + 1, startVar + 1, varLen); + buffer[varLen] = '}'; + buffer[varLen+1] = '\0'; + varTokens.push_back(buffer); + } + //evaluate variables + bool ok = true; + for (size_t i=0; i < varTokens.size(); i++) { + sPrintfInfo info; + int tokenIndex = tokenContainer->IntTokenIndex(varTokens[i].c_str()); + if (tokenIndex >= 0) { + info.type = ePrintfVarType::inttoken; + info.index = tokenIndex; + t->printfVarIndices.push_back(info); + continue; + } + tokenIndex = tokenContainer->StringTokenIndex(varTokens[i].c_str()); + if (tokenIndex >= 0) { + info.type = ePrintfVarType::stringtoken; + info.index = tokenIndex; + t->printfVarIndices.push_back(info); + continue; + } + tokenIndex = tokenContainer->LoopTokenIndex(varTokens[i].c_str()); + if (tokenIndex >= 0) { + info.type = ePrintfVarType::looptoken; + info.index = tokenIndex; + t->printfVarIndices.push_back(info); + continue; + } + ok = false; + } + return ok; +} + +void cTextExpr::DeterminatePrintfToken(cTextToken *t) { + int numVars = t->printfVarIndices.size(); + vector results; + for (int i=0; i < numVars; i++) { + if (t->printfVarIndices[i].type == ePrintfVarType::inttoken) { + results.push_back(tokenContainer->IntToken(t->printfVarIndices[i].index)); + } else if (t->printfVarIndices[i].type == ePrintfVarType::stringtoken) { + if (tokenContainer->StringToken(t->printfVarIndices[i].index)) { + results.push_back(atoi(tokenContainer->StringToken(t->printfVarIndices[i].index))); + } + } else if (t->printfVarIndices[i].type == ePrintfVarType::looptoken && loopInfo && loopInfo->row >= 0) { + if (tokenContainer->LoopToken(loopInfo->index, loopInfo->row, t->printfVarIndices[i].index)) { + results.push_back(atoi(tokenContainer->LoopToken(loopInfo->index, loopInfo->row, t->printfVarIndices[i].index))); + } + } + } + + switch (numVars) { + case 1: + t->printfResult = strdup(*cString::sprintf(t->printfExpr, results[0])); + break; + case 2: + t->printfResult = strdup(*cString::sprintf(t->printfExpr, results[0], results[1])); + break; + case 3: + t->printfResult = strdup(*cString::sprintf(t->printfExpr, results[0], results[1], results[2])); + break; + case 4: + t->printfResult = strdup(*cString::sprintf(t->printfExpr, results[0], results[1], results[2], results[3])); + break; + case 5: + t->printfResult = strdup(*cString::sprintf(t->printfExpr, results[0], results[1], results[2], results[3], results[4])); + break; + case 6: + t->printfResult = strdup(*cString::sprintf(t->printfExpr, results[0], results[1], results[2], results[3], results[4], results[5])); + break; + default: + break; + } +} + +void cTextExpr::ParseCondToken(cTextToken *t) { + char *head = t->constValue; + char *tail = t->constValue; + head++; + tail++; + char *token = NULL; + while (*tail) { + if (*tail == '{') { + t->condStart = CopyTextPart(head, tail, false); + head = tail; + tail++; + while (*tail) { + if (*tail == '}') { + token = CopyTextPart(head, tail); + head = tail+1; + break; + } + tail++; + } + } + tail++; + } + tail--; + t->condEnd = CopyTextPart(head, tail, false); + if (!token) { + esyslog("skindesigner: invalid conditional texttoken %s in expression \"%s\"", t->constValue, expr); + return; + } + + int tokenIndex = tokenContainer->StringTokenIndex(token); + if (tokenIndex >= 0) { + t->tokenIndex = tokenIndex; + return; + } + + tokenIndex = tokenContainer->IntTokenIndex(token); + if (tokenIndex >= 0) { + t->tokenIndex = tokenIndex; + t->type = eTexttokenType::condinttoken; + return; + } + esyslog("skindesigner: invalid token %s in expression\"%s\"", token, expr); +} + +char *cTextExpr::CopyTextPart(char *start, char *stop, bool incLastChar) { + if (!start) + return NULL; + if (start >= stop) + return NULL; + char *val = NULL; + size_t len = 0; + if (stop) { + //defined end + len = stop - start + 1; + } else { + //search end of text + char *p = start; + while (*p) + len++; p++; + len++; + } + val = (char*)malloc(len+1); + memset(val, 0, len+1); + if (!incLastChar) + len--; + memcpy(val, start, len); + return val; +} diff --git a/coreengine/complextypes.h b/coreengine/complextypes.h new file mode 100644 index 0000000..7f03128 --- /dev/null +++ b/coreengine/complextypes.h @@ -0,0 +1,318 @@ +#ifndef __COMPLEXTYPES_H +#define __COMPLEXTYPES_H + +#include +#include +#include +#include +#include +#include "globals.h" +#include "../libskindesignerapi/tokencontainer.h" + +class cLoopInfo; +class cFunction; +/****************************************************************** +* helpers +******************************************************************/ +char *RemoveSpace(char *e); +void ReplaceDecimalpoint(char *e); +void ReplaceStart(char *e, int num); +void ReplaceEnd(char *e, int num); + +/****************************************************************** +* cCondition +******************************************************************/ +enum class eCondOp { + tAnd, + tOr +}; + +enum class eCondType { + token, + negtoken, + lowerInt, + equalInt, + greaterInt, + isset, + empty, + equalString, + notEqualString, + contains, + notContains +}; + +enum class eCondTokenType { + inttoken, + stringtoken, + looptoken +}; + +class cCond : public cListObject { +public: + cCond(const char *expression); + cCond(const cCond &other); + virtual ~cCond(void); + void Debug(void); + char *expr; + eCondOp operation; + eCondType type; + eCondTokenType tokenType; + bool constant; + bool isTrue; + int tokenIndex; + int compareValue; + char *compareStrValue; +}; + +class cCondition { +private: + char *expr; + cGlobals *globals; + skindesignerapi::cTokenContainer *tokenContainer; + cLoopInfo *loopInfo; + cList conds; + void Tokenize(void); + void PrepareTokens(void); + void SetTokenCond(cCond *c); + void SetIntegerCond(cCond *c); + void SetStringCond(cCond *c); + void SetStringCompareCond(cCond *c); + void SetTokenIndex(cCond *c, const char *token); +public: + cCondition(const char *expression); + cCondition(const cCondition &other); + virtual ~cCondition(void); + void SetGlobals(cGlobals *globals) { this->globals = globals; }; + void SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer) {this->tokenContainer = tokenContainer; }; + void SetLoopInfo(cLoopInfo *loopInfo) { this->loopInfo = loopInfo; }; + void Prepare(void); + bool True(void); + void Debug(void); +}; + +/****************************************************************** +* cNumericExpr +******************************************************************/ +enum class eFactorType { + constant = 0, + stringtoken, + inttoken, + looptoken, + xref, + yref, + widthref, + heightref, + areawidth, + areaheight, + columnwidth, + rowheight +}; + +class cFactor: public cListObject { +public: + cFactor(void) { + multiplication = true; + type = eFactorType::constant; + constValue = 1.0f; + tokenIndex = -1; + funcRefName = NULL; + funcRef = NULL; + }; + cFactor(const cFactor &other) { + multiplication = other.multiplication; + type = other.type; + constValue = other.constValue; + tokenIndex = other.tokenIndex; + funcRefName = NULL; + if (other.funcRefName) + funcRefName = strdup(other.funcRefName); + funcRef = other.funcRef; + } + ~cFactor(void) { + free(funcRefName); + }; + bool multiplication; + eFactorType type; + double constValue; + int tokenIndex; + char *funcRefName; + cFunction *funcRef; +}; + +class cSummand : public cListObject { +public: + cSummand(const char *summand); + cSummand(const cSummand &other); + ~cSummand(void); + void Debug(void); + char *summand; + bool positive; + cList factors; +}; + +class cNumericExpr { +private: + cGlobals *globals; + cRect *container; + skindesignerapi::cTokenContainer *tokenContainer; + cLoopInfo *loopInfo; + char *expr; + cList summands; + bool horizontal; + int value; + bool dynamic; + //common string functions + bool IsNumeric(const char *e); + bool IsNumericExpression(const char *e); + bool PercentValue(const char *e); + char *ReplacePercentValue(char *e); + char *ReplaceToken(char *e, const char* token, int value); + char *ReplaceTokens(char *e, const char* token, int value); + //calculate numeric expressions + int EvaluateExpression(char *e); + double EvaluateExpressionDouble(char *e); + double ParseAtom(char*& e); + double ParseFactors(char*& e); + double ParseSummands(char*& e); + //prepare expressions with tokens + void CreateSummands(void); + void CreateFactors(void); + bool SetTokenFactor(cFactor *f, char *tokenName); + bool SetReferenceFactor(cFactor *f, char *tokenName); + bool SetGeometryFactor(cFactor *f, char *tokenName); + void ConsolidateSummand(void); + void ConsolidateFactors(void); +public: + cNumericExpr(const char *expression); + cNumericExpr(const cNumericExpr &other); + virtual ~cNumericExpr(void); + void SetContainer(cRect *container) { this->container = container; }; + void SetGlobals(cGlobals *globals) { this->globals = globals; }; + void SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer) { this->tokenContainer = tokenContainer; }; + void SetLoopInfo(cLoopInfo *loopInfo) { this->loopInfo = loopInfo; }; + void SetVertical(void) { horizontal = false; }; + bool CacheStatic(void); + void PrepareTokens(void); + vector GetRefFactors(void); + int GetValue(void) { return value; }; + bool Dynamic(void) { return dynamic; }; + int Calculate(void); + void Debug(void); +}; + +/****************************************************************** +* cColor +******************************************************************/ +class cColor { +private: + cGlobals *globals; + char *expr; + tColor value; +public: + cColor(const char *expression); + cColor(const cColor &other); + virtual ~cColor(void); + void SetGlobals(cGlobals *globals) { this->globals = globals; }; + void Cache(void); + tColor Color(void); + void Debug(void); +}; + +/****************************************************************** +* cTextExpr +******************************************************************/ +enum class eTexttokenType { + constant = 0, + stringtoken, + inttoken, + looptoken, + printftoken, + condstringtoken, + condinttoken, +}; + +enum class ePrintfVarType { + stringtoken, + inttoken, + looptoken +}; + +struct sPrintfInfo { + ePrintfVarType type; + int index; +}; + +class cTextToken: public cListObject { +public: + cTextToken(void) { + type = eTexttokenType::constant; + constValue = NULL; + printfExpr = NULL; + printfResult = NULL; + tokenIndex = -1; + condStart = NULL; + condEnd = NULL; + }; + cTextToken(const cTextToken &other) { + type = other.type; + constValue = NULL; + if (other.constValue) + constValue = strdup(other.constValue); + printfExpr = NULL; + if (other.printfExpr) + printfExpr = strdup(other.printfExpr); + printfVarIndices = other.printfVarIndices; + printfResult = NULL; + if (other.printfResult) + printfResult = strdup(other.printfResult); + tokenIndex = other.tokenIndex; + condStart = NULL; + if (other.condStart) + condStart = strdup(other.condStart); + condEnd = NULL; + if (other.condEnd) + condEnd = strdup(other.condEnd); + }; + ~cTextToken(void) { + free(constValue); + free(printfExpr); + }; + eTexttokenType type; + char *constValue; + int tokenIndex; + char *printfExpr; + vector printfVarIndices; + char *printfResult; + char *condStart; + char *condEnd; +}; + +class cTextExpr { +private: + cGlobals *globals; + skindesignerapi::cTokenContainer *tokenContainer; + cLoopInfo *loopInfo; + char *expr; + cList textTokens; + void Translate(void); + void Tokenize(void); + void PrepareTokens(void); + bool CheckGlobals(cTextToken *t); + bool ParsePrintfToken(cTextToken *t); + void DeterminatePrintfToken(cTextToken *t); + void ParseCondToken(cTextToken *t); + char *CopyTextPart(char *start, char *stop, bool incLastChar= true); +public: + cTextExpr(const char *expression); + cTextExpr(const cTextExpr &other); + virtual ~cTextExpr(void); + void SetGlobals(cGlobals *globals) { this->globals = globals; }; + void SetTokenContainer(skindesignerapi::cTokenContainer *tokenContainer) { this->tokenContainer = tokenContainer; }; + void SetLoopInfo(cLoopInfo *loopInfo) { this->loopInfo = loopInfo; }; + void CorrectImagePath(void); + void Cache(void); + char *DeterminateText(void); + void Debug(const char *exprName); +}; + +#endif //__COMPLEXTYPES_H \ No newline at end of file diff --git a/coreengine/definitions.h b/coreengine/definitions.h new file mode 100644 index 0000000..9490097 --- /dev/null +++ b/coreengine/definitions.h @@ -0,0 +1,1746 @@ +#ifndef __DEFINITIONS_H +#define __DEFINITIONS_H + +#include +#include + +using namespace std; + +typedef pair stringpair; +typedef map stringmap; + +#define ATTR_UNKNOWN (-1) +#define ATTR_COND (-2) + +/****************************************************************** +* Views +*******************************************************************/ +enum class eViewType { + DisplayChannel, + DisplayMenu, + DisplayReplay, + DisplayVolume, + DisplayTracks, + DisplayMessage, + DisplayPlugin +}; +/****************************************************************** +* ViewElements DisplayChannel +*******************************************************************/ +enum class eVeDisplayChannel { + background = 0, + datetime, + time, + message, + devices, + currentweather, + customtokens, + channelinfo, + channelgroup, + epginfo, + progressbar, + statusinfo, + audioinfo, + screenresolution, + signalquality, + scrapercontent, + ecminfo, + count +}; +/****************************************************************** +* ViewElements DisplayMenu +*******************************************************************/ +enum class eVeDisplayMenu { + background = 0, + header, + datetime, + time, + sortmode, + colorbuttons, + message, + scrollbar, + count +}; + +enum class eVeDisplayMenuMain { + timers = eVeDisplayMenu::count, + devices, + currentweather, + currentschedule, + discusage, + systemload, + systemmemory, + temperatures, + vdrstatistics, + lastrecordings, + customtokens, + count +}; + +enum class eVeDisplayDetailedMenu { + detailheader = eVeDisplayMenu::count, + tablabels, + count +}; +/****************************************************************** +* Subviews DisplayMenu +*******************************************************************/ +enum class eSvDisplayMenu { + menudefault = 0, + main, + setup, + schedules, + channels, + timers, + recordings, + detailepg, + detailrec, + detailtext, + count +}; + +/****************************************************************** +* DisplayMessage +*******************************************************************/ +enum class eVeDisplayMessage { + background = 0, + message, + count +}; + +/****************************************************************** +* DisplayReplay +*******************************************************************/ +enum class eVeDisplayReplay { + background = 0, + backgroundmodeonly, + datetime, + time, + scrapercontent, + rectitle, + recinfo, + currenttime, + totaltime, + endtime, + progressbar, + cutmarks, + controlicons, + controliconsmodeonly, + progressmodeonly, + jump, + message, + onpause, + onpausemodeonly, + customtokens, + count +}; + +/****************************************************************** +* DisplayVolume +*******************************************************************/ +enum class eVeDisplayVolume { + background = 0, + volume, + count +}; + +/****************************************************************** +* DisplayTracks +*******************************************************************/ +enum class eVeDisplayTracks { + background = 0, + header, + count +}; + +/****************************************************************** +* Tokens common viewelements +*******************************************************************/ +enum class eBackgroundST { + count +}; + +enum class eBackgroundIT { + count +}; + +enum class eDateTimeST { + time = 0, + dayleadingzero, + dayname, + daynameshort, + month, + monthname, + monthnameshort, + count +}; + +enum class eDateTimeIT { + day = 0, + year, + count +}; + +enum class eTimeST { + count = 0 +}; + +enum class eTimeIT { + sec = 0, + min, + hour, + hmins, + count +}; + +enum class eMessageST { + text = 0, + count +}; + +enum class eMessageIT { + status = 0, + info, + warning, + error, + count +}; + +enum class eDevicesLT { + num = 0, + type, + istuned, + livetv, + recording, + hascam, + cam, + signalstrength, + signalquality, + channelnumber, + channelname, + channellogoexists, + channelid, + source, + count +}; + +enum class eDevicesIT { + numdevices = 0, + count +}; + +enum class eCurrentWeatherST { + timestamp = 0, + summary, + icon, + precipitationtype, + windbearingstring, + temperature, + apparenttemperature, + mintemperature, + maxtemperature, + precipitationintensity, + windspeed, + visibility, + pressure, + ozone, + count +}; + +enum class eCurrentWeatherIT { + precipitationprobability = 0, + humidity, + windbearing, + cloudcover, + count +}; + +enum class eScraperPosterBannerST { + posterpath = 0, + bannerpath, + mediapath, + count +}; + +enum class eScraperPosterBannerIT { + posterwidth = 0, + posterheight, + hasposter, + bannerwidth, + bannerheight, + hasbanner, + mediawidth, + mediaheight, + isbanner, + count +}; + +/****************************************************************** +* Tokens displaychannel viewelements +*******************************************************************/ +enum class eDCChannelInfoST { + channelnumber = 0, + channelname, + channelid, + count +}; + +enum class eDCChannelInfoIT { + channellogoexists = 0, + switching, + count +}; + +enum class eDCEpgInfoST { + currenttitle = 0, + currentsubtitle, + currentstart, + currentstop, + nexttitle, + nextsubtitle, + nextstart, + nextstop, + count +}; + +enum class eDCEpgInfoIT { + currentduration = 0, + currentdurationhours, + currentdurationminutes, + currentelapsed, + currentremaining, + nextduration, + nextdurationhours, + nextdurationminutes, + nextrecording, + currentrecording, + hasVPS, + count +}; + +enum class eDCProgressBarST { + start = 0, + stop, + count +}; + +enum class eDCProgressBarIT { + duration = 0, + elapsed, + remaining, + permashift, + livebuffer, + count +}; + +enum class eDCStatusInfoST { + count +}; + +enum class eDCStatusInfoIT { + isRadio = 0, + hasVT, + isStereo, + isDolby, + isEncrypted, + isRecording, + newmails, + count +}; + +enum class eDCAudioInfoST { + trackdesc = 0, + tracklang, + count +}; + +enum class eDCAudioInfoIT { + numaudiotracks = 0, + audiochannel, + count +}; + +enum class eDCEcmInfoST { + cardsystem = 0, + reader, + from, + protocol, + count +}; + +enum class eDCEcmInfoIT { + caid = 0, + pid, + prid, + ecmtime, + hops, + count +}; + +enum class eDCScreenResolutionST { + resolution = 0, + aspect, + count +}; + +enum class eDCScreenResolutionIT { + screenwidth = 0, + screenheight, + isHD, + isWideScreen, + count +}; + +enum class eDCChannelGroupST { + group = 0, + nextgroup, + prevgroup, + seppath, + count +}; + +enum class eDCChannelGroupIT { + prevAvailable = 0, + nextAvailable, + sepexists, + count +}; + +enum class eDCSignalQualityST { + count = 0 +}; + +enum class eDCSignalQualityIT { + signalstrength = 0, + signalquality, + count +}; + +/****************************************************************** +* Tokens displaymenu viewelements +*******************************************************************/ +enum class eDMHeaderST { + title = 0, + vdrversion, + icon, + freetime, + vdrusagestring, + channelname, + channelid, + count +}; + +enum class eDMHeaderIT { + hasicon = 0, + freepercent, + usedpercent, + freegb, + discalert, + channelnumber, + channellogoexists, + whatson, + whatsonnow, + whatsonnext, + whatsonfavorites, + count +}; + +enum class eDMSortmodeST { + count = 0 +}; + +enum class eDMSortmodeIT { + sortnumber = 0, + sortname, + sorttime, + sortprovider, + count +}; + +enum class eDMColorbuttonsST { + red = 0, + green, + yellow, + blue, + count +}; + +enum class eDMColorbuttonsIT { + red1 = 0, red2, red3, red4, + green1, green2, green3, green4, + yellow1, yellow2, yellow3, yellow4, + blue1, blue2, blue3, blue4, + count +}; + +enum class eDMScrollbarST { + count = 0 +}; + +enum class eDMScrollbarIT { + height = 0, + offset, + hasprev, + hasnext, + count +}; + +enum class eDMTimersIT { + numtimers = 0, + numtimerconflicts, + timer1exists, timer2exists, timer3exists, timer4exists, timer5exists, + timer6exists, timer7exists, timer8exists, timer9exists, timer10exists, + timer11exists, timer12exists, timer13exists, timer14exists, timer15exists, + count +}; + +enum class eDMTimersLT { + title = 0, + datetime, + recording, + channelname, + channelnumber, + channelid, + channellogoexists, + isremotetimer, + count +}; + +enum class eDMCurrentscheduleIT { + islivetv = eScraperPosterBannerIT::count, + duration, + durationhours, + minutes, + elapsed, + remaining, + count +}; + +enum class eDMCurrentscheduleST { + title = eScraperPosterBannerST::count, + subtitle, + start, + stop, + durationminutes, + count +}; + +enum class eDMLastrecordingsIT { + numtimers = 0, + count +}; + +enum class eDMLastrecordingsLT { + name = 0, + seriesname, + date, + time, + duration, + hasposter, + posterpath, + posterwidth, + posterheight, + count +}; + +enum class eDMDiscusageST { + freetime = 0, + vdrusagestring, + count +}; + +enum class eDMDiscusageIT { + freepercent = 0, + usedpercent, + freegb, + discalert, + count +}; + +enum class eDMSystemloadST { + load = 0, + count +}; + +enum class eDMSystemloadIT { + loadhand = 0, + count +}; + +enum class eDMSystemmemoryST { + count = 0 +}; + +enum class eDMSystemmemoryIT { + totalmem = 0, + usedmem, + usedmempercent, + count +}; + +enum class eDMVdrstatisticsST { + vdrcpu = 0, + vdrmem, + count +}; + +enum class eDMVdrstatisticsIT { + count = 0 +}; + +enum class eDMTemperaturesST { + count = 0 +}; + +enum class eDMTemperaturesIT { + cputemp = 0, + gputemp, + count +}; + +/****************************************************************** +* Tokens displaymenu listelements +*******************************************************************/ +enum class eLeMenuDefaultST { + column1 = 0, + column2, + column3, + column4, + column5, + column6, + count +}; + +enum class eLeMenuDefaultIT { + nummenuitem = 0, + current, + separator, + column2set, + column3set, + column4set, + column5set, + column6set, + column1x, + column2x, + column3x, + column4x, + column5x, + column6x, + column1width, + column2width, + column3width, + column4width, + column5width, + column6width, + column1pb, + column2pb, + column3pb, + column4pb, + column5pb, + column6pb, + column1pbtotalsize, + column2pbtotalsize, + column3pbtotalsize, + column4pbtotalsize, + column5pbtotalsize, + column6pbtotalsize, + column1pbsize, + column2pbsize, + column3pbsize, + column4pbsize, + column5pbsize, + column6pbsize, + setup, + commands, + fritzbox, + systeminfo, + mailbox, + neutrinoepg, + remotetimers, + count +}; + +enum class eLeMenuMainST { + label = 0, + number, + icon, + count +}; + +enum class eLeMenuMainIT { + nummenuitem = 0, + current, + separator, + count +}; + +enum class eCeMenuMainST { + label = 0, + number, + icon, + count +}; + +enum class eCeMenuMainIT { + menuitemx = 0, + menuitemy, + menuitemwidth, + menuitemheight, + count +}; + +enum class eLeMenuSchedulesST { + title = 0, + shorttext, + start, + stop, + day, + date, + durationminutes, + channelname, + channelid, + count +}; + +enum class eLeMenuSchedulesIT { + nummenuitem = 0, + current, + separator, + daynumeric, + month, + year, + running, + elapsed, + startsin, + duration, + durationhours, + channelnumber, + channellogoexists, + whatson, + whatsonnow, + whatsonnext, + whatsonfavorites, + timerpartitial, + timerfull, + hasVPS, + count +}; + +enum class eCeMenuSchedulesST { + title = 0, + shorttext, + description, + start, + stop, + day, + date, + channelname, + channelid, + posterpath, + bannerpath, + count +}; + +enum class eCeMenuSchedulesLT { + title = 0, + shorttext, + start, + stop, + count +}; + +enum class eCeMenuSchedulesIT { + menuitemx = 0, + menuitemy, + menuitemwidth, + menuitemheight, + daynumeric, + month, + year, + running, + elapsed, + duration, + durationhours, + durationminutes, + channelnumber, + channellogoexists, + hasposter, + posterwidth, + posterheight, + hasbanner, + bannerwidth, + bannerheight, + whatson, + whatsonnow, + whatsonnext, + whatsonfavorites, + timerpartitial, + timerfull, + count +}; + +enum class eLeMenuChannelsST { + name = 0, + channelid, + source, + sourcedescription, + position, + presenteventtitle, + presenteventstart, + presenteventstop, + count +}; + +enum class eLeMenuChannelsIT { + nummenuitem = 0, + current, + separator, + number, + transponder, + frequency, + channellogoexists, + isAtsc, + isCable, + isSat, + isTerr, + count +}; + +enum class eCeMenuChannelsST { + name = 0, + channelid, + source, + sourcedescription, + position, + presenteventtitle, + presenteventstart, + presenteventstop, + presenteventshorttext, + presenteventdescription, + presenteventday, + presenteventdate, + presenteventdurationminutes, + posterpath, + nexteventtitle, + nexteventstart, + nexteventstop, + nexteventshorttext, + nexteventdescription, + nexteventday, + nexteventdate, + nexteventdurationminutes, + count +}; + +enum class eCeMenuChannelsIT { + menuitemx = 0, + menuitemy, + menuitemwidth, + menuitemheight, + number, + transponder, + frequency, + channellogoexists, + isAtsc, + isCable, + isSat, + isTerr, + presenteventduration, + presenteventdurationhours, + presenteventelapsed, + hasposter, + posterwidth, + posterheight, + nexteventduration, + nexteventdurationhours, + count +}; + +enum class eCeMenuChannelsLT { + title = 0, + shorttext, + start, + stop, + count +}; + +enum class eLeMenuTimersST { + title = 0, + timerstart, + timerstop, + day, + dayname, + monthname, + channelname, + channelid, + eventtitle, + eventstart, + eventstop, + count +}; + +enum class eLeMenuTimersIT { + nummenuitem = 0, + current, + separator, + month, + year, + channellogoexists, + channelnumber, + flagactive, + flaginstant, + flagvps, + flagrecording, + flagpending, + count +}; + +enum class eCeMenuTimersST { + title = 0, + timerstart, + timerstop, + day, + dayname, + monthname, + channelname, + channelid, + eventtitle, + eventstart, + eventstop, + eventshorttext, + eventdescription, + posterpath, + count +}; + +enum class eCeMenuTimersIT { + menuitemx = 0, + menuitemy, + menuitemwidth, + menuitemheight, + month, + year, + channellogoexists, + channelnumber, + flagactive, + flaginstant, + flagvps, + flagrecording, + flagpending, + hasposter, + posterwidth, + posterheight, + count +}; + +enum class eLeMenuRecordingsST { + name = 0, + epgname, + shorttext, + description, + date, + time, + durationminutes, + durationeventminutes, + thumbnailpath, + posterpath, + count +}; + +enum class eLeMenuRecordingsIT { + nummenuitem = 0, + current, + isnew, + percentseen, + watched, + cutted, + folder, + daynumeric, + month, + year, + duration, + durationhours, + durationevent, + durationeventhours, + numrecordingsfolder, + newrecordingsfolder, + hasposterthumbnail, + thumbnailwidth, + thumbnailheight, + hasposter, + posterwidth, + posterheight, + count +}; + +enum class eCeMenuRecordingsST { + name = 0, + epgname, + shorttext, + description, + date, + time, + durationminutes, + durationeventminutes, + thumbnailpath, + posterpath, + count +}; + +enum class eCeMenuRecordingsIT { + menuitemx = 0, + menuitemy, + menuitemwidth, + menuitemheight, + isnew, + percentseen, + watched, + cutted, + folder, + daynumeric, + month, + year, + duration, + durationhours, + durationevent, + durationeventhours, + numrecordingsfolder, + newrecordingsfolder, + hasposterthumbnail, + thumbnailwidth, + thumbnailheight, + hasposter, + posterwidth, + posterheight, + count +}; + +/****************************************************************** +* Tokens displaymenu detailed views +*******************************************************************/ +enum class eScraperHeaderST { + posterpath = 0, + bannerpath, + count +}; + +enum class eScraperHeaderIT { + ismovie = 0, + isseries, + posteravailable, + posterwidth, + posterheight, + banneravailable, + bannerwidth, + bannerheight, + count +}; + +enum class eDmDetailedHeaderEpgST { + title = eScraperHeaderST::count, + shorttext, + start, + stop, + day, + date, + durationminutes, + vps, + channelname, + channelid, + epgpicpath, + count +}; + +enum class eDmDetailedHeaderEpgIT { + daynumeric = eScraperHeaderIT::count, + month, + year, + running, + elapsed, + duration, + durationhours, + channelnumber, + channellogoexists, + epgpicavailable, + count +}; + +enum class eDmDetailedHeaderRecST { + name = eScraperHeaderST::count, + epgname, + shorttext, + date, + time, + recimgpath, + recchannelname, + recchannelid, + durationminutes, + durationeventminutes, + count +}; + +enum class eDmDetailedHeaderRecIT { + daynumeric = eScraperHeaderIT::count, + month, + year, + duration, + durationhours, + durationevent, + durationeventhours, + recimgavailable, + recchannelnumber, + count +}; + +enum class eDmTabsIT { + count = 0, +}; + +enum class eDmTabsST { + currenttab = 0, + prevtab, + nexttab, + count +}; + +enum class eDmTabsLT { + title = 0, + current, + count +}; + +enum class eScraperST { + movietitle = 0, + movieoriginalTitle, + movietagline, + movieoverview, + moviegenres, + moviehomepage, + moviereleasedate, + moviepopularity, + movievoteaverage, + posterpath, + fanartpath, + moviecollectionName, + collectionposterpath, + collectionfanartpath, + seriesname, + seriesoverview, + seriesfirstaired, + seriesnetwork, + seriesgenre, + seriesrating, + seriesstatus, + episodetitle, + episodefirstaired, + episodegueststars, + episodeoverview, + episoderating, + episodeimagepath, + seasonposterpath, + seriesposter1path, + seriesposter2path, + seriesposter3path, + seriesfanart1path, + seriesfanart2path, + seriesfanart3path, + seriesbanner1path, + seriesbanner2path, + seriesbanner3path, + count +}; + +enum class eScraperIT { + ismovie = 0, + moviebudget, + movierevenue, + movieadult, + movieruntime, + isseries, + posterwidth, + posterheight, + fanartwidth, + fanartheight, + movieiscollection, + collectionposterwidth, + collectionposterheight, + collectionfanartwidth, + collectionfanartheight, + epgpicavailable, + episodenumber, + episodeseason, + episodeimagewidth, + episodeimageheight, + seasonposterwidth, + seasonposterheight, + seriesposter1width, + seriesposter1height, + seriesposter2width, + seriesposter2height, + seriesposter3width, + seriesposter3height, + seriesfanart1width, + seriesfanart1height, + seriesfanart2width, + seriesfanart2height, + seriesfanart3width, + seriesfanart3height, + seriesbanner1width, + seriesbanner1height, + seriesbanner2width, + seriesbanner2height, + seriesbanner3width, + seriesbanner3height, + count +}; + +enum class eScraperLT { + //actors + name = 0, + role, + thumb, + thumbwidth, + thumbheight, + count +}; + +enum class eDmDetailedEpgST { + title = eScraperST::count, + shorttext, + description, + start, + stop, + day, + date, + durationminutes, + vps, + channelname, + channelid, + epgpic1path, + epgpic2path, + epgpic3path, + count +}; + +enum class eDmDetailedEpgIT { + daynumeric = eScraperIT::count, + month, + year, + running, + elapsed, + duration, + durationhours, + channelnumber, + channellogoexists, + hasreruns, + epgpic1avaialble, + epgpic2avaialble, + epgpic3avaialble, + count +}; + +enum class eRerunsLT { + title = 0, + shorttext, + date, + day, + start, + stop, + channelname, + channelnumber, + channelid, + channellogoexists, + count +}; + +enum class eDmDetailedRecST { + name = eScraperST::count, + epgname, + shorttext, + description, + day, + date, + time, + durationminutes, + durationeventminutes, + recordingsize, + recordingsizecutted, + recordinglength, + recordinglengthcutted, + recordingbitrate, + recordingformat, + recchannelname, + recchannelid, + searchtimer, + recimg1path, + recimg2path, + recimg3path, + count +}; + +enum class eDmDetailedRecIT { + daynumeric = eScraperIT::count, + month, + year, + duration, + durationhours, + durationevent, + durationeventhours, + cutted, + recchannelnumber, + recimg1avaialble, + recimg2avaialble, + recimg3avaialble, + count +}; + +enum class eDmDetailedTextST { + text = 0, + count +}; + +enum class eDmSkinPreviewST { + menuheader = 0, + skinname, + author, + count +}; + +enum class eDmSkinPreviewFontsLT { + name = 0, + installed, + count +}; + +enum class eDmSkinPreviewPluginsLT { + name = 0, + count +}; + +enum class eDmSkinPreviewScreenshotsLT { + desc = 0, + path, + count +}; +/****************************************************************** +* Tokens DisplayReplay Viewelements +*******************************************************************/ +enum class eDRRecTitleST { + rectitle = 0, + recsubtitle, + recdate, + rectime, + count +}; + +enum class eDRRecInfoST { + resolution = 0, + aspect, + count +}; + +enum class eDRRecInfoIT { + screenwidth = 0, + screenheight, + isHD, + isWideScreen, + count +}; + +enum class eDRCurrentTimeST { + reccurrent = 0, + count +}; + +enum class eDRTotalTimeST { + rectotal = 0, + timeshifttotal, + count +}; + +enum class eDRTotalTimeIT { + timeshift = 0, + count +}; + +enum class eDREndTimeST { + recend = 0, + count +}; + +enum class eDRProgressbarIT { + current = 0, + total, + timeshift, + timeshifttotal, + count +}; + +enum class eDRCutmarksIT { + timeshift = 0, + count +}; + +enum class eDRCutmarksLT { + position = 0, + endposition, + total, + timeshifttotal, + active, + startmark, + count +}; + +enum class eDRControlIconsIT { + play = 0, + pause, + forward, + forward1x, + forward2x, + forward3x, + rewind, + rewind1x, + rewind2x, + rewind3x, + count +}; + +enum class eDRProgressModeonlyIT { + current = 0, + total, + count +}; + +enum class eDRProgressModeonlyST { + timecurrent = 0, + timetotal, + count +}; + +enum class eDRJumpST { + jump = 0, + count +}; + +enum class eDROnpauseST { + name = eScraperST::count, + shorttext, + description, + date, + time, + durationminutes, + durationeventminutes, + count +}; + +enum class eDROnpauseIT { + daynumeric = eScraperIT::count, + month, + year, + duration, + durationhours, + durationevent, + durationeventhours, + count +}; + +/****************************************************************** +* Tokens DisplayVolume Viewelements +*******************************************************************/ +enum class eDVVolumeIT { + volume = 0, + volpercent, + maxvolume, + mute, + count +}; + +/****************************************************************** +* Tokens DisplayTracks Viewelements +*******************************************************************/ +enum class eDTBackgroundIT { + numtracks = 0, + count +}; + +enum class eDTHeaderIT { + numtracks = 0, + isstereo, + isac3, + count +}; + +enum class eDTHeaderST { + title = 0, + count +}; + +enum class eLeDisplayTracksIT { + nummenuitem = 0, + current, + count +}; + +enum class eLeDisplayTracksST { + title = 0, + count +}; +/****************************************************************** +* Attributes +*******************************************************************/ +enum class eCommonAttribs { + x = 0, + y, + width, + height, + debug, + count +}; + +enum class eViewAttribs { + fadetime = 0, + shifttime, + shifttype, + shiftmode, + startx, + starty, + scaletvx, + scaletvy, + scaletvwidth, + scaletvheight, + orientation, + debuggrid, + hideroot, + count +}; + +enum class eViewElementAttribs { + delay = 0, + fadetime, + shifttime, + shifttype, + shiftmode, + startx, + starty, + mode, + orientation, + name, + count +}; + +enum class eViewListAttribs { + align = 0, + menuitemwidth, + determinatefont, + numlistelements, + orientation, + condition, + count +}; + +enum class eAreaAttribs { + layer = 0, + transparency, + mode, + orientation, + scrollelement, + scrollspeed, + delay, + background, + name, + scrollheight, + count +}; + +enum class eAreaContainerAttribs { + count = 0 +}; + +/****************************************************************** +* Functions +*******************************************************************/ +enum class eFillAttribs { + color = 0, + count +}; + +enum class eDrawRectangleAttribs { + align = 0, + valign, + color, + name, + animtype, + animfreq, + count +}; + +enum class eDrawEllipseAttribs { + align = 0, + valign, + color, + name, + quadrant, + animtype, + animfreq, + count +}; + +enum class eDrawSlopeAttribs { + align = 0, + valign, + color, + name, + type, + animtype, + animfreq, + count +}; + +enum class eDrawTextAttribs { + align = 0, + valign, + color, + font, + fontsize, + name, + text, + animtype, + animfreq, + count +}; + +enum class eDrawTextAttribsVertical { + align = 0, + valign, + direction, + color, + font, + fontsize, + name, + text, + animtype, + animfreq, + count +}; + +enum class eDrawTextBoxAttribs { + align = 0, + valign, + maxlines, + floatwidth, + floatheight, + floatmode, + color, + font, + fontsize, + name, + text, + count +}; + +enum class eDrawImageAttribs { + align = 0, + valign, + imagetype, + name, + cache, + path, + animtype, + animfreq, + count +}; + +enum class eLoopAttribs { + columnwidth = 0, + rowheight, + name, + orientation, + overflow, + maxitems, + count +}; + +/****************************************************************** +* Common Parameters +*******************************************************************/ +enum class eViewElementMode { + regular, + light +}; + +enum class eShiftType { + none = -1, + left, + right, + top, + bottom +}; + +enum class eShiftMode { + linear, + slowedDown +}; + +enum class eScrollMode { + none, + carriagereturn, + forthandback +}; + +enum class eScrollSpeed { + none, + slow, + medium, + fast +}; + +enum class eOrientation { + none, + horizontal, + vertical, + absolute +}; + +enum class eAlign { + left, + center, + right, + top, + bottom +}; + +enum class eAnimType { + none, + blink, + animated +}; + +enum class eImageType { + channellogo, + seplogo, + skinpart, + menuicon, + icon, + image +}; + +enum class eOverflowType { + none, + wrap, + cut +}; + +enum class eFloatMode { + none = -1, + topleft, + topright +}; + +enum class eDirection { + none = -1, + bottomup, + topdown +}; + + +#endif //__DEFINITIONS_H \ No newline at end of file diff --git a/coreengine/functions.c b/coreengine/functions.c new file mode 100644 index 0000000..f8b8d47 --- /dev/null +++ b/coreengine/functions.c @@ -0,0 +1,1565 @@ +#define __STL_CONFIG_H +#include "attribute.h" +#include "../config.h" + +/*************************************************************************** +* cFuncFill +***************************************************************************/ +cFuncFill::cFuncFill(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "Fill"; + SetAttributesDefs(); +} + +cFuncFill::cFuncFill(const cFuncFill &other) : cFunction(other) { + funcType = other.funcType; +} + +cFuncFill::~cFuncFill(void) { +} + +void cFuncFill::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown func Fill attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eFillAttribs::color)) { + SetColor(attVal); + } + } +} + +void cFuncFill::SetAttributesDefs(void) { + attribIDs.insert(pair("color", (int)eFillAttribs::color)); + attribNames.insert(pair((int)eFillAttribs::color, "color")); +} + +void cFuncFill::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeight) { + if (!color) + return; + p->Fill(color->Color()); +} + +/*************************************************************************** +* cFuncDrawRectangle +***************************************************************************/ +cFuncDrawRectangle::cFuncDrawRectangle(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "DrawRectangle"; + SetAttributesDefs(); +} + +cFuncDrawRectangle::cFuncDrawRectangle(const cFuncDrawRectangle &other) : cFunction(other) { + funcType = other.funcType; +} + +cFuncDrawRectangle::~cFuncDrawRectangle(void) { +} + +void cFuncDrawRectangle::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown func DrawRectangle attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eDrawRectangleAttribs::color)) { + SetColor(attVal); + } else if (IdEqual(id, (int)eDrawRectangleAttribs::name)) { + name = strdup(attVal); + } else if (IdEqual(id, (int)eDrawRectangleAttribs::align)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawRectangleAttribs::valign)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawRectangleAttribs::animtype)) { + SetAnimType(id, attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +void cFuncDrawRectangle::SetAttributesDefs(void) { + attribIDs.insert(pair("align", (int)eDrawRectangleAttribs::align)); + attribIDs.insert(pair("valign", (int)eDrawRectangleAttribs::valign)); + attribIDs.insert(pair("color", (int)eDrawRectangleAttribs::color)); + attribIDs.insert(pair("name", (int)eDrawRectangleAttribs::name)); + attribIDs.insert(pair("animtype", (int)eDrawRectangleAttribs::animtype)); + attribIDs.insert(pair("animfreq", (int)eDrawRectangleAttribs::animfreq)); + attribNames.insert(pair((int)eDrawRectangleAttribs::align, "align")); + attribNames.insert(pair((int)eDrawRectangleAttribs::valign, "valign")); + attribNames.insert(pair((int)eDrawRectangleAttribs::color, "color")); + attribNames.insert(pair((int)eDrawRectangleAttribs::name, "name")); + attribNames.insert(pair((int)eDrawRectangleAttribs::animtype, "animtype")); + attribNames.insert(pair((int)eDrawRectangleAttribs::animfreq, "animfreq")); +} + +void cFuncDrawRectangle::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeight) { + eAlign align = (eAlign)GetValue((int)eDrawRectangleAttribs::align); + eAlign valign = (eAlign)GetValue((int)eDrawRectangleAttribs::valign); + int x = GetX(align, x0, colWidth); + int y = GetY(valign, y0, rowHeight); + cRect rect(x, y, Width(), Height()); + p->DrawRectangle(rect, color->Color()); +} + +/*************************************************************************** +* cFuncDrawEllipse +***************************************************************************/ +cFuncDrawEllipse::cFuncDrawEllipse(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "DrawEllipse"; + SetAttributesDefs(); +} + +cFuncDrawEllipse::cFuncDrawEllipse(const cFuncDrawEllipse &other) : cFunction(other) { + funcType = other.funcType; +} + +cFuncDrawEllipse::~cFuncDrawEllipse(void) { +} + +void cFuncDrawEllipse::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown func DrawEllipse attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eDrawEllipseAttribs::color)) { + SetColor(attVal); + } else if (IdEqual(id, (int)eDrawEllipseAttribs::name)) { + name = strdup(attVal); + } else if (IdEqual(id, (int)eDrawEllipseAttribs::align)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawEllipseAttribs::valign)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawEllipseAttribs::animtype)) { + SetAnimType(id, attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +void cFuncDrawEllipse::SetAttributesDefs(void) { + attribIDs.insert(pair("align", (int)eDrawEllipseAttribs::align)); + attribIDs.insert(pair("valign", (int)eDrawEllipseAttribs::valign)); + attribIDs.insert(pair("color", (int)eDrawEllipseAttribs::color)); + attribIDs.insert(pair("name", (int)eDrawEllipseAttribs::name)); + attribIDs.insert(pair("quadrant", (int)eDrawEllipseAttribs::quadrant)); + attribIDs.insert(pair("animtype", (int)eDrawEllipseAttribs::animtype)); + attribIDs.insert(pair("animfreq", (int)eDrawEllipseAttribs::animfreq)); + attribNames.insert(pair((int)eDrawEllipseAttribs::align, "align")); + attribNames.insert(pair((int)eDrawEllipseAttribs::valign, "valign")); + attribNames.insert(pair((int)eDrawEllipseAttribs::color, "color")); + attribNames.insert(pair((int)eDrawEllipseAttribs::name, "name")); + attribNames.insert(pair((int)eDrawEllipseAttribs::quadrant, "quadrant")); + attribNames.insert(pair((int)eDrawEllipseAttribs::animtype, "animtype")); + attribNames.insert(pair((int)eDrawEllipseAttribs::animfreq, "animfreq")); +} + +void cFuncDrawEllipse::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeight) { + eAlign align = (eAlign)GetValue((int)eDrawEllipseAttribs::align); + eAlign valign = (eAlign)GetValue((int)eDrawEllipseAttribs::valign); + int x = GetX(align, x0, colWidth); + int y = GetY(valign, y0, rowHeight); + cRect rect(x, y, Width(), Height()); + int quadrant = GetValue((int)eDrawEllipseAttribs::quadrant); + p->DrawEllipse(rect, color->Color(), quadrant); +} + +/*************************************************************************** +* cFuncDrawSlope +***************************************************************************/ +cFuncDrawSlope::cFuncDrawSlope(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "DrawSlope"; + SetAttributesDefs(); +} + +cFuncDrawSlope::cFuncDrawSlope(const cFuncDrawSlope &other) : cFunction(other) { + funcType = other.funcType; +} + +cFuncDrawSlope::~cFuncDrawSlope(void) { +} + +void cFuncDrawSlope::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown func DrawSlope attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eDrawSlopeAttribs::color)) { + SetColor(attVal); + } else if (IdEqual(id, (int)eDrawSlopeAttribs::name)) { + name = strdup(attVal); + } else if (IdEqual(id, (int)eDrawSlopeAttribs::align)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawSlopeAttribs::valign)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawSlopeAttribs::animtype)) { + SetAnimType(id, attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +void cFuncDrawSlope::SetAttributesDefs(void) { + attribIDs.insert(pair("align", (int)eDrawSlopeAttribs::align)); + attribIDs.insert(pair("valign", (int)eDrawSlopeAttribs::valign)); + attribIDs.insert(pair("color", (int)eDrawSlopeAttribs::color)); + attribIDs.insert(pair("name", (int)eDrawSlopeAttribs::name)); + attribIDs.insert(pair("type", (int)eDrawSlopeAttribs::type)); + attribIDs.insert(pair("animtype", (int)eDrawSlopeAttribs::animtype)); + attribIDs.insert(pair("animfreq", (int)eDrawSlopeAttribs::animfreq)); + attribNames.insert(pair((int)eDrawSlopeAttribs::align, "align")); + attribNames.insert(pair((int)eDrawSlopeAttribs::valign, "valign")); + attribNames.insert(pair((int)eDrawSlopeAttribs::color, "color")); + attribNames.insert(pair((int)eDrawSlopeAttribs::name, "name")); + attribNames.insert(pair((int)eDrawSlopeAttribs::type, "type")); + attribNames.insert(pair((int)eDrawSlopeAttribs::animtype, "animtype")); + attribNames.insert(pair((int)eDrawSlopeAttribs::animfreq, "animfreq")); +} + +void cFuncDrawSlope::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeight) { + eAlign align = (eAlign)GetValue((int)eDrawSlopeAttribs::align); + eAlign valign = (eAlign)GetValue((int)eDrawSlopeAttribs::valign); + int x = GetX(align, x0, colWidth); + int y = GetY(valign, y0, rowHeight); + cRect rect(x, y, Width(), Height()); + int type = GetValue((int)eDrawSlopeAttribs::type); + p->DrawSlope(rect, color->Color(), type); +} + +/*************************************************************************** +* cTextDrawer +***************************************************************************/ +cMutex cTextDrawer::fontLock; + +cTextDrawer::cTextDrawer(void) { + font = NULL; + fontName = NULL; + fontSize = 0; +} + +cTextDrawer::~cTextDrawer(void) { + free(fontName); +} + +void cTextDrawer::CacheFont(cGlobals *globals, int size) { + //check if font name is a global token + if (startswith(fontName, "{") && endswith(fontName, "}")) { + string tmpFontName = ""; + if (globals->GetFont(fontName, tmpFontName)) { + free(fontName); + fontName = strdup(tmpFontName.c_str()); + } else { + esyslog("skindesigner: unknown font %s", fontName); + return; + } + } + if (size > 0) + LoadFont(size); +} + +void cTextDrawer::LoadFont(int size) { + if (!fontName) + return; + if (size <= 0) + return; + font = fontManager->Font(fontName, size); + if (font) + fontSize = size; +} + +int cTextDrawer::TextWidth(const char *text) { + int textWidth = 0; + fontLock.Lock(); + textWidth = font->Width(text); + fontLock.Unlock(); + return textWidth; +} + +int cTextDrawer::FontHeight(void) { + int fontHeight = 0; + fontLock.Lock(); + fontHeight = font->Height(); + fontLock.Unlock(); + return fontHeight; +} +/*************************************************************************** +* cFuncDrawText +***************************************************************************/ +cFuncDrawText::cFuncDrawText(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "DrawText"; + text = NULL; + SetAttributesDefs(); +} + +cFuncDrawText::cFuncDrawText(const cFuncDrawText &other) : cFunction(other) { + funcType = other.funcType; + fontName = NULL; + if (other.fontName) + fontName = strdup(other.fontName); + font = other.font; + text = NULL; + if (other.text) + text = new cTextExpr(*other.text); +} + +cFuncDrawText::~cFuncDrawText(void) { + delete text; +} + +void cFuncDrawText::SetLoopInfo(cLoopInfo *loopInfo) { + cFunction::SetLoopInfo(loopInfo); + if (text) + text->SetLoopInfo(loopInfo); +} + +void cFuncDrawText::SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer) { + cAttributes::SetTokenContainerDeep(tokenContainer); + if (text) { + text->SetTokenContainer(tokenContainer); + } +} + +void cFuncDrawText::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown func DrawText attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eDrawTextAttribs::color)) { + SetColor(attVal); + } else if (IdEqual(id, (int)eDrawTextAttribs::name)) { + name = strdup(attVal); + } else if (IdEqual(id, (int)eDrawTextAttribs::align)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawTextAttribs::valign)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawTextAttribs::animtype)) { + SetAnimType(id, attVal); + } else if (IdEqual(id, (int)eDrawTextAttribs::font)) { + fontName = strdup(attVal); + } else if (IdEqual(id, (int)eDrawTextAttribs::text)) { + text = new cTextExpr(attVal); + } else if (IdEqual(id, (int)eDrawTextAttribs::fontsize)) { + attribCtors[id] = new cNumericExpr(attVal); + attribCtors[id]->SetVertical(); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +void cFuncDrawText::Cache(void) { + cFunction::Cache(); + if (text) { + text->SetTokenContainer(tokenContainer); + text->SetGlobals(globals); + text->Cache(); + } + if (fontName) { + CacheFont(globals, GetValue((int)eDrawTextAttribs::fontsize)); + } +} + +void cFuncDrawText::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeight) { + if (!font) { + LoadFont(GetValue((int)eDrawTextAttribs::fontsize)); + if (!font) + return; + } + char *funcText = NULL; + if (text) + funcText = text->DeterminateText(); + if (!funcText) + return; + int maxTextWidth = Width(); + if (maxTextWidth > 0 && !scrolling) { + if (TextWidth(funcText) > maxTextWidth) { + funcText = Cut(funcText, maxTextWidth); + } + } else if (!scrolling) { + maxTextWidth = container.Width() - X(); + if (TextWidth(funcText) > maxTextWidth) { + funcText = Cut(funcText, maxTextWidth); + } + } + + eAlign horAlign = (eAlign)GetValue((int)eDrawTextAttribs::align); + eAlign verAlign = (eAlign)GetValue((int)eDrawTextAttribs::valign); + + int contWidth = colWidth > 0 ? colWidth : container.Width(); + int x = X() + x0; + if (horAlign == eAlign::right) { + x = x0 + contWidth - TextWidth(funcText); + } else if (horAlign == eAlign::center) { + x = x0 + (contWidth - TextWidth(funcText)) / 2; + } + + int contHeight = rowHeight > 0 ? rowHeight : container.Height(); + int y = Y() + y0; + if (verAlign == eAlign::bottom) { + y = y0 + contHeight - FontHeight(); + } else if (verAlign == eAlign::center) { + y = y0 + (contHeight - FontHeight()) / 2; + } + + p->DrawText(cPoint(x, y), funcText, color->Color(), clrTransparent, font); + free(funcText); +} + +int cFuncDrawText::FuncX(void) { + if (!font) + return 0; + char *funcText = NULL; + if (text) + funcText = text->DeterminateText(); + if (!funcText) + return 0; + eAlign horAlign = (eAlign)GetValue((int)eDrawTextAttribs::align); + int x = X(); + if (horAlign == eAlign::right) { + x = container.Width() - TextWidth(funcText); + } else if (horAlign == eAlign::center) { + x = (container.Width() - TextWidth(funcText)) / 2; + } + return x; +} + +int cFuncDrawText::FuncY(void) { + if (!font) + return 0; + eAlign verAlign = (eAlign)GetValue((int)eDrawTextAttribs::valign); + int y = Y(); + if (verAlign == eAlign::bottom) { + y = container.Height() - FontHeight(); + } else if (verAlign == eAlign::center) { + y = (container.Height() - FontHeight()) / 2; + } + return y; +} + +int cFuncDrawText::FuncWidth(void) { + if (!font) + return 0; + char *funcText = NULL; + if (text) + funcText = text->DeterminateText(); + if (!funcText) + return 0; + int textWidth = TextWidth(funcText); + free(funcText); + return textWidth; +} + +int cFuncDrawText::FuncHeight(void) { + if (!font) + return 0; + return FontHeight(); +} + +int cFuncDrawText::AvrgFontWidth(void) { + if (!font) + return 20; + return TextWidth("x")+3; +} + +const cFont *cFuncDrawText::GetFont(void) { + return font; +} + +void cFuncDrawText::Debug(void) { + cFunction::Debug(); + if (fontName) + esyslog("skindesigner: fontname: \"%s\"", fontName); + if (font) + esyslog("skindesigner: cached font name: \"%s\", size %d", font->FontName(), font->Height()); + if (text) + text->Debug("draw text"); +} + +void cFuncDrawText::SetAttributesDefs(void) { + attribIDs.insert(pair("align", (int)eDrawTextAttribs::align)); + attribIDs.insert(pair("valign", (int)eDrawTextAttribs::valign)); + attribIDs.insert(pair("color", (int)eDrawTextAttribs::color)); + attribIDs.insert(pair("font", (int)eDrawTextAttribs::font)); + attribIDs.insert(pair("fontsize", (int)eDrawTextAttribs::fontsize)); + attribIDs.insert(pair("name", (int)eDrawTextAttribs::name)); + attribIDs.insert(pair("text", (int)eDrawTextAttribs::text)); + attribIDs.insert(pair("animtype", (int)eDrawTextAttribs::animtype)); + attribIDs.insert(pair("animfreq", (int)eDrawTextAttribs::animfreq)); + attribNames.insert(pair((int)eDrawTextAttribs::align, "align")); + attribNames.insert(pair((int)eDrawTextAttribs::valign, "valign")); + attribNames.insert(pair((int)eDrawTextAttribs::color, "color")); + attribNames.insert(pair((int)eDrawTextAttribs::font, "font")); + attribNames.insert(pair((int)eDrawTextAttribs::fontsize, "fontsize")); + attribNames.insert(pair((int)eDrawTextAttribs::name, "name")); + attribNames.insert(pair((int)eDrawTextAttribs::text, "text")); + attribNames.insert(pair((int)eDrawTextAttribs::animtype, "animtype")); + attribNames.insert(pair((int)eDrawTextAttribs::animfreq, "animfreq")); +} + +char *cFuncDrawText::Cut(char *expr, int width) { + char *cutted = NULL; + int w = 3 * font->Width("."); + for (char *p = expr; *p; ) { + int sl = Utf8CharLen(p); + uint sym = Utf8CharGet(p, sl); + w += font->Width(sym); + if( w >= width ) { + cutted = (char*)malloc(p - expr + 4); + memset(cutted, 0, p - expr + 4); + strncpy(cutted, expr, p - expr); + cutted[p - expr] = '.'; + cutted[p - expr + 1] = '.'; + cutted[p - expr + 2] = '.'; + break; + } + p += sl; + } + if (cutted) { + free(expr); + return cutted; + } + return expr; +} + +/*************************************************************************** +* cFuncDrawTextVertical +***************************************************************************/ +cFuncDrawTextVertical::cFuncDrawTextVertical(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "DrawTextVertical"; + text = NULL; + SetAttributesDefs(); +} + +cFuncDrawTextVertical::cFuncDrawTextVertical(const cFuncDrawTextVertical &other) : cFunction(other) { + funcType = other.funcType; + fontName = NULL; + if (other.fontName) + fontName = strdup(other.fontName); + text = NULL; + if (other.text) + text = new cTextExpr(*other.text); +} + +cFuncDrawTextVertical::~cFuncDrawTextVertical(void) { + delete text; +} + +void cFuncDrawTextVertical::SetLoopInfo(cLoopInfo *loopInfo) { + cFunction::SetLoopInfo(loopInfo); + if (text) + text->SetLoopInfo(loopInfo); +} + +void cFuncDrawTextVertical::SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer) { + cAttributes::SetTokenContainerDeep(tokenContainer); + if (text) { + text->SetTokenContainer(tokenContainer); + } +} + +void cFuncDrawTextVertical::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown func DrawTextVertical attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eDrawTextAttribsVertical::color)) { + SetColor(attVal); + } else if (IdEqual(id, (int)eDrawTextAttribsVertical::name)) { + name = strdup(attVal); + } else if (IdEqual(id, (int)eDrawTextAttribsVertical::align)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawTextAttribsVertical::direction)) { + SetDirection(id, attVal); + } else if (IdEqual(id, (int)eDrawTextAttribsVertical::valign)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawTextAttribsVertical::animtype)) { + SetAnimType(id, attVal); + } else if (IdEqual(id, (int)eDrawTextAttribsVertical::font)) { + fontName = strdup(attVal); + } else if (IdEqual(id, (int)eDrawTextAttribsVertical::text)) { + text = new cTextExpr(attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +void cFuncDrawTextVertical::Cache(void) { + cFunction::Cache(); + if (text) { + text->SetTokenContainer(tokenContainer); + text->SetGlobals(globals); + text->Cache(); + } + if (fontName) { + CacheFont(globals, 0); + } +} + +void cFuncDrawTextVertical::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeight) { + char *funcText = NULL; + if (text) + funcText = text->DeterminateText(); + if (!funcText) + return; + int fontSize = GetValue((int)eDrawTextAttribsVertical::fontsize); + int direction = GetValue((int)eDrawTextAttribsVertical::direction); + tColor clr = color->Color(); + cImage *textVertical = imgCache->GetVerticalText(funcText, clr, fontName, fontSize, direction); + if (!textVertical) + return; + + eAlign horAlign = (eAlign)GetValue((int)eDrawTextAttribsVertical::align); + eAlign verAlign = (eAlign)GetValue((int)eDrawTextAttribsVertical::valign); + int x = 0; + int y = 0; + if (horAlign == eAlign::center) { + x = (container.Width() - textVertical->Width()) / 2; + } else if (horAlign == eAlign::right) { + x = container.Width() - textVertical->Width(); + } + if (verAlign == eAlign::center) { + y = (container.Height() - textVertical->Height()) / 2; + } else if (horAlign == eAlign::bottom) { + y = container.Height() - textVertical->Height(); + } + cPoint pos(x, y); + p->DrawImage(pos, *textVertical); + free(funcText); +} + +int cFuncDrawTextVertical::FuncWidth(void) { + char *funcText = NULL; + if (text) + funcText = text->DeterminateText(); + if (!funcText) + return 0; + int fontSize = GetValue((int)eDrawTextAttribsVertical::fontsize); + int direction = GetValue((int)eDrawTextAttribsVertical::direction); + tColor clr = color->Color(); + cImage *textVertical = imgCache->GetVerticalText(funcText, clr, fontName, fontSize, direction); + if (!textVertical) + return 0; + return textVertical->Width(); +} + +int cFuncDrawTextVertical::FuncHeight(void) { + char *funcText = NULL; + if (text) + funcText = text->DeterminateText(); + if (!funcText) + return 0; + int fontSize = GetValue((int)eDrawTextAttribsVertical::fontsize); + int direction = GetValue((int)eDrawTextAttribsVertical::direction); + tColor clr = color->Color(); + cImage *textVertical = imgCache->GetVerticalText(funcText, clr, fontName, fontSize, direction); + if (!textVertical) + return 0; + return textVertical->Height(); +} + +void cFuncDrawTextVertical::Debug(void) { + cFunction::Debug(); + if (fontName) + esyslog("skindesigner: fontname: \"%s\"", fontName); + if (text) + text->Debug("draw text"); +} + +void cFuncDrawTextVertical::SetAttributesDefs(void) { + attribIDs.insert(pair("align", (int)eDrawTextAttribsVertical::align)); + attribIDs.insert(pair("valign", (int)eDrawTextAttribsVertical::valign)); + attribIDs.insert(pair("direction", (int)eDrawTextAttribsVertical::direction)); + attribIDs.insert(pair("color", (int)eDrawTextAttribsVertical::color)); + attribIDs.insert(pair("font", (int)eDrawTextAttribsVertical::font)); + attribIDs.insert(pair("fontsize", (int)eDrawTextAttribsVertical::fontsize)); + attribIDs.insert(pair("name", (int)eDrawTextAttribsVertical::name)); + attribIDs.insert(pair("text", (int)eDrawTextAttribsVertical::text)); + attribIDs.insert(pair("animtype", (int)eDrawTextAttribsVertical::animtype)); + attribIDs.insert(pair("animfreq", (int)eDrawTextAttribsVertical::animfreq)); + attribNames.insert(pair((int)eDrawTextAttribsVertical::align, "align")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::valign, "valign")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::direction, "direction")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::color, "color")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::font, "font")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::fontsize, "fontsize")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::name, "name")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::text, "text")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::animtype, "animtype")); + attribNames.insert(pair((int)eDrawTextAttribsVertical::animfreq, "animfreq")); +} + +/*************************************************************************** +* cFuncDrawTextBox +***************************************************************************/ +cFuncDrawTextBox::cFuncDrawTextBox(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "DrawTextBox"; + text = NULL; + floater = NULL; + SetAttributesDefs(); +} + +cFuncDrawTextBox::cFuncDrawTextBox(const cFuncDrawTextBox &other) : cFunction(other) { + funcType = other.funcType; + fontName = NULL; + if (other.fontName) + fontName = strdup(other.fontName); + font = other.font; + text = NULL; + if (other.text) + text = new cTextExpr(*other.text); + floater = NULL; +} + +cFuncDrawTextBox::~cFuncDrawTextBox(void) { + delete text; + delete floater; +} + +void cFuncDrawTextBox::SetLoopInfo(cLoopInfo *loopInfo) { + cFunction::SetLoopInfo(loopInfo); + if (text) + text->SetLoopInfo(loopInfo); +} + +void cFuncDrawTextBox::SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer) { + cAttributes::SetTokenContainerDeep(tokenContainer); + if (text) { + text->SetTokenContainer(tokenContainer); + } +} + +void cFuncDrawTextBox::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown func DrawTextBox attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eDrawTextBoxAttribs::color)) { + SetColor(attVal); + } else if (IdEqual(id, (int)eDrawTextBoxAttribs::name)) { + name = strdup(attVal); + } else if (IdEqual(id, (int)eDrawTextBoxAttribs::align)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawTextBoxAttribs::valign)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawTextBoxAttribs::floatmode)) { + SetFloatMode(id, attVal); + } else if (IdEqual(id, (int)eDrawTextBoxAttribs::floatheight)) { + attribCtors[id] = new cNumericExpr(attVal); + attribCtors[id]->SetVertical(); + } else if (IdEqual(id, (int)eDrawTextBoxAttribs::font)) { + fontName = strdup(attVal); + } else if (IdEqual(id, (int)eDrawTextBoxAttribs::text)) { + text = new cTextExpr(attVal); + } else if (IdEqual(id, (int)eDrawTextBoxAttribs::fontsize)) { + attribCtors[id] = new cNumericExpr(attVal); + attribCtors[id]->SetVertical(); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +void cFuncDrawTextBox::Cache(void) { + cFunction::Cache(); + if (text) { + text->SetTokenContainer(tokenContainer); + text->SetGlobals(globals); + text->Cache(); + } + if (fontName) { + CacheFont(globals, GetValue((int)eDrawTextBoxAttribs::fontsize)); + } +} + +void cFuncDrawTextBox::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeight) { + if (!font) { + LoadFont(GetValue((int)eDrawTextBoxAttribs::fontsize)); + if (!font) + return; + } + SetFloater(); + eFloatMode mode = (eFloatMode)GetValue((int)eDrawTextBoxAttribs::floatmode); + int fontHeight = FontHeight(); + int lines = floater->Lines(); + eAlign align = (eAlign)GetValue((int)eDrawTextBoxAttribs::align); + int boxX = X() + x0; + int floatHeight = 0; + if ( mode == eFloatMode::topleft ) { + boxX += GetValue((int)eDrawTextBoxAttribs::floatwidth); + floatHeight = GetValue((int)eDrawTextBoxAttribs::floatheight); + } + eAlign valign = (eAlign)GetValue((int)eDrawTextBoxAttribs::valign); + int height = Height(); + if (height <= 0) + height = container.Height(); + int y = Y() + y0; + if (valign == eAlign::center) { + y = y0 + (height - fontHeight * lines) / 2; + } else if (valign == eAlign::bottom) { + y = y0 + height - fontHeight * lines; + } + int x = boxX; + for (int line=0; line < lines; line++) { + const char *lineText = floater->GetLine(line); + if (!lineText) + break; + if (align == eAlign::center) { + x = boxX + (Width() - TextWidth(lineText)) / 2; + } else if (align == eAlign::right) { + x = boxX + Width() - TextWidth(lineText); + } + p->DrawText(cPoint(x, y), lineText, color->Color(), clrTransparent, font); + y += fontHeight; + if ( mode == eFloatMode::topleft ) { + if ((line+1) * fontHeight >= floatHeight) + x = X() + x0; + } + } +} + +int cFuncDrawTextBox::FuncWidth(void) { + return Width(); +} + +int cFuncDrawTextBox::FuncHeight(void) { + if (!font) + return 0; + int boxHeight = Height(); + if (boxHeight > 0) + return boxHeight; + SetFloater(); + int lines = floater->Lines(); + return lines * FontHeight(); +} + +void cFuncDrawTextBox::Debug(void) { + cFunction::Debug(); + if (fontName) + esyslog("skindesigner: fontname: \"%s\"", fontName); + if (font) + esyslog("skindesigner: cached font name: \"%s\", size %d", font->FontName(), font->Height()); + if (text) + text->Debug("draw textbox"); +} + +void cFuncDrawTextBox::SetFloater(void) { + char *funcText = NULL; + if (text) + funcText = text->DeterminateText(); + int boxWidth = Width(); + int boxHeight = Height(); + int floatWidth = GetValue((int)eDrawTextBoxAttribs::floatwidth); + int floatHeight = GetValue((int)eDrawTextBoxAttribs::floatheight); + int maxLines = GetValue((int)eDrawTextBoxAttribs::maxlines); + delete floater; + floater = new cTextFloater(); + floater->Set(funcText, font, boxWidth, boxHeight, floatWidth, floatHeight, maxLines); + free(funcText); +} + +void cFuncDrawTextBox::SetAttributesDefs(void) { + attribIDs.insert(pair("align", (int)eDrawTextBoxAttribs::align)); + attribIDs.insert(pair("valign", (int)eDrawTextBoxAttribs::valign)); + attribIDs.insert(pair("maxlines", (int)eDrawTextBoxAttribs::maxlines)); + attribIDs.insert(pair("floatwidth", (int)eDrawTextBoxAttribs::floatwidth)); + attribIDs.insert(pair("floatheight", (int)eDrawTextBoxAttribs::floatheight)); + attribIDs.insert(pair("float", (int)eDrawTextBoxAttribs::floatmode)); + attribIDs.insert(pair("color", (int)eDrawTextBoxAttribs::color)); + attribIDs.insert(pair("font", (int)eDrawTextBoxAttribs::font)); + attribIDs.insert(pair("fontsize", (int)eDrawTextBoxAttribs::fontsize)); + attribIDs.insert(pair("name", (int)eDrawTextBoxAttribs::name)); + attribIDs.insert(pair("text", (int)eDrawTextBoxAttribs::text)); + attribNames.insert(pair((int)eDrawTextBoxAttribs::align, "align")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::valign, "valign")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::maxlines, "maxlines")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::floatwidth, "floatwidth")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::floatheight, "floatheight")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::floatmode, "float")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::color, "color")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::font, "font")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::fontsize, "fontsize")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::name, "name")); + attribNames.insert(pair((int)eDrawTextBoxAttribs::text, "text")); +} + +void cFuncDrawTextBox::SetFloatMode(int id, const char *val) { + eFloatMode mode = eFloatMode::none; + if (!strcmp(val, "topleft")) + mode = eFloatMode::topleft; + else if (!strcmp(val, "topright")) + mode = eFloatMode::topright; + attribs[id] = (int)mode; +} + +/*************************************************************************** +* cFuncDrawImage +***************************************************************************/ +cFuncDrawImage::cFuncDrawImage(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "DrawImage"; + path = NULL; + SetAttributesDefs(); +} + +cFuncDrawImage::cFuncDrawImage(const cFuncDrawImage &other) : cFunction(other) { + funcType = other.funcType; + path = NULL; + if (other.path) + path = new cTextExpr(*other.path); +} + +cFuncDrawImage::~cFuncDrawImage(void) { + delete path; +} + +void cFuncDrawImage::SetLoopInfo(cLoopInfo *loopInfo) { + cFunction::SetLoopInfo(loopInfo); + if (path) + path->SetLoopInfo(loopInfo); +} + +void cFuncDrawImage::SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer) { + cAttributes::SetTokenContainerDeep(tokenContainer); + if (path) { + path->SetTokenContainer(tokenContainer); + } +} + +void cFuncDrawImage::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown func DrawText attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eDrawImageAttribs::name)) { + name = strdup(attVal); + } else if (IdEqual(id, (int)eDrawImageAttribs::path)) { + path = new cTextExpr(attVal); + } else if (IdEqual(id, (int)eDrawImageAttribs::align)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawImageAttribs::valign)) { + SetAlign(id, attVal); + } else if (IdEqual(id, (int)eDrawImageAttribs::imagetype)) { + SetImageType(id, attVal); + } else if (IdEqual(id, (int)eDrawImageAttribs::animtype)) { + SetAnimType(id, attVal); + } else if (IdEqual(id, (int)eDrawImageAttribs::cache)) { + SetBool(id, attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +void cFuncDrawImage::Debug(void) { + cFunction::Debug(); + if (path) + path->Debug("image path"); +} + +void cFuncDrawImage::SetImageType(int id, const char *val) { + eImageType imgType = eImageType::image; + if (!strcmp(val, "channellogo")) + imgType = eImageType::channellogo; + else if (!strcmp(val, "seplogo")) + imgType = eImageType::seplogo; + else if (!strcmp(val, "skinpart")) + imgType = eImageType::skinpart; + else if (!strcmp(val, "menuicon")) + imgType = eImageType::menuicon; + else if (!strcmp(val, "icon")) + imgType = eImageType::icon; + attribs[id] = (int)imgType; +} + +void cFuncDrawImage::SetAttributesDefs(void) { + attribIDs.insert(pair("align", (int)eDrawImageAttribs::align)); + attribIDs.insert(pair("valign", (int)eDrawImageAttribs::valign)); + attribIDs.insert(pair("imagetype", (int)eDrawImageAttribs::imagetype)); + attribIDs.insert(pair("name", (int)eDrawImageAttribs::name)); + attribIDs.insert(pair("cache", (int)eDrawImageAttribs::cache)); + attribIDs.insert(pair("path", (int)eDrawImageAttribs::path)); + attribIDs.insert(pair("animtype", (int)eDrawImageAttribs::animtype)); + attribIDs.insert(pair("animfreq", (int)eDrawImageAttribs::animfreq)); + attribNames.insert(pair((int)eDrawImageAttribs::align, "align")); + attribNames.insert(pair((int)eDrawImageAttribs::valign, "valign")); + attribNames.insert(pair((int)eDrawImageAttribs::imagetype, "imagetype")); + attribNames.insert(pair((int)eDrawImageAttribs::name, "name")); + attribNames.insert(pair((int)eDrawImageAttribs::cache, "cache")); + attribNames.insert(pair((int)eDrawImageAttribs::path, "path")); + attribNames.insert(pair((int)eDrawImageAttribs::animtype, "animtype")); + attribNames.insert(pair((int)eDrawImageAttribs::animfreq, "animfreq")); +} + +void cFuncDrawImage::Cache(void) { + cFunction::Cache(); + if (path) { + int type = GetValue((int)eDrawImageAttribs::imagetype); + if (type == (int)eImageType::image) { + path->CorrectImagePath(); + } + path->SetGlobals(globals); + path->SetTokenContainer(tokenContainer); + path->Cache(); + } + + if (config.cacheImagesInitial) + PreCacheImage(); +} + +void cFuncDrawImage::PreCacheImage(void) { + int imgWidth = Width(); + int imgHeight = Height(); + char *imgPath = path->DeterminateText(); + if (!(imgWidth > 0 && imgHeight > 0)) + return; + + eImageType type = (eImageType)GetValue((int)eDrawImageAttribs::imagetype); + switch (type) { + case eImageType::channellogo: + imgCache->CacheLogo(imgWidth, imgHeight); + break; + case eImageType::skinpart: + if (imgPath) + imgCache->GetSkinpart(imgPath, imgWidth, imgHeight); + break; + case eImageType::icon: + case eImageType::menuicon: + if (imgPath) + imgCache->GetIcon(type, imgPath, imgWidth, imgHeight); + break; + default: + break; + } + free(imgPath); +} + +void cFuncDrawImage::Render(cPixmap *p, int x0, int y0, int colWidth, int rowHeight) { + if (!path) + return; + eAlign align = (eAlign)GetValue((int)eDrawImageAttribs::align); + eAlign valign = (eAlign)GetValue((int)eDrawImageAttribs::valign); + int x = GetX(align, x0, colWidth); + int y = GetY(valign, y0, rowHeight); + cPoint pos(x, y); + eImageType type = (eImageType)GetValue((int)eDrawImageAttribs::imagetype); + char *imgPath = path->DeterminateText(); + if (!imgPath) + return; + + switch (type) { + case eImageType::channellogo: { + cImage *logo = imgCache->GetLogo(imgPath, Width(), Height()); + if (logo) { + p->DrawImage(pos, *logo); + } + break; } + case eImageType::seplogo: { + cImage *sep = imgCache->GetSeparatorLogo(imgPath, Width(), Height()); + if (sep) { + p->DrawImage(pos, *sep); + } + break; } + case eImageType::skinpart: { + cCachedImage *img = imgCache->GetSkinpart(imgPath, Width(), Height()); + if (!img) break; + if (img->handle) { + p->DrawImage(pos, img->handle); + } else if (img->image) { + p->DrawImage(pos, *(img->image)); + } + break; } + case eImageType::icon: + case eImageType::menuicon: { + cCachedImage *img = imgCache->GetIcon(type, imgPath, Width(), Height()); + if (!img) break; + if (img->handle) { + p->DrawImage(pos, img->handle); + } else if (img->image) { + p->DrawImage(pos, *(img->image)); + } + break; } + case eImageType::image: { + cImageLoader imgLoader; + if (imgLoader.LoadImage(imgPath)) { + cImage *img = imgLoader.CreateImage(Width(), Height()); + if (!img) break; + p->DrawImage(pos, *img); + delete(img); + } + break; } + } + free(imgPath); +} + +/*************************************************************************** +* cFuncLoop +***************************************************************************/ +cFuncLoop::cFuncLoop(cArea *owner, int numAttributes) : cFunction(owner, numAttributes) { + funcType = "LoopFunc"; + SetAttributesDefs(); +} + +cFuncLoop::~cFuncLoop(void) { +} + +void cFuncLoop::Set(vector &attributes) { + for (vector::iterator att = attributes.begin(); att != attributes.end(); att++) { + const char *attName = (*att).first.c_str(); + const char *attVal = (*att).second.c_str(); + int id = AttributeId(attName); + if (id == ATTR_UNKNOWN) { + esyslog("skindesigner: unknown loopfunc attribute \"%s\" = \"%s\"", attName, attVal); + continue; + } + + if (SetCommon(id, attVal)) + continue; + if (IdEqual(id, (int)eLoopAttribs::name)) { + name = strdup(attVal); + } else if (IdEqual(id, (int)eLoopAttribs::orientation)) { + SetOrientation(id, attVal); + } else if (IdEqual(id, (int)eLoopAttribs::overflow)) { + SetOverflow(id, attVal); + } else { + attribCtors[id] = new cNumericExpr(attVal); + } + } +} + +void cFuncLoop::Cache(void) { + cFunction::Cache(); + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetGlobals(globals); + f->SetTokenContainer(tokenContainer); + f->Cache(); + } + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetLoopInfo(&loopInfo); + f->CacheFuncReferences(); + } +} + +void cFuncLoop::SetContainer(int x, int y, int width, int height) { + cAttributes::SetContainer(x, y, width, height); + int funcX = X(); + int funcY = Y(); + int funcWidth = Width(); + int funcHeight = Height(); + + int funcContainerX = (funcX > 0) ? x + funcX : x; + int funcContainerY = (funcY > 0) ? y + funcY : y; + int funcContainerWidth = (funcWidth > 0) ? funcWidth : width; + int funcContainerHeight = (funcHeight > 0) ? funcHeight : height; + + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->SetContainer(funcContainerX, funcContainerY, funcContainerWidth, funcContainerHeight); + } +} + + +void cFuncLoop::AddFunction(cFunction *f) { + functions.Add(f); +} + +cFunction *cFuncLoop::GetFunction(const char *name) { + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + const char *funcName = f->Name(); + if (funcName && !strcmp(funcName, name)) { + return f; + } + } + return NULL; +} + +void cFuncLoop::Render(cPixmap *p, int x0, int y0, int cw, int rh) { + int loopIndex = tokenContainer->LoopIndex(Name()); + if (loopIndex < 0) { + esyslog("skindesigner: unknown loop function \"%s\"", Name()); + return; + } + int numRows = tokenContainer->NumLoops(loopIndex); + int columnWidth = GetValue((int)eLoopAttribs::columnwidth); + int rowHeight = GetValue((int)eLoopAttribs::rowheight); + int maxItems = GetValue((int)eLoopAttribs::maxitems); + eOrientation orientation = (eOrientation)GetValue((int)eLoopAttribs::orientation); + eOverflowType overflow = (eOverflowType)GetValue((int)eLoopAttribs::overflow); + int loopWidth = Width(); + if (loopWidth <= 0) + loopWidth = container.Width(); + int loopHeight = Height(); + if (loopHeight <= 0) + loopHeight = container.Height(); + + loopInfo.colWidth = columnWidth; + loopInfo.rowHeight = rowHeight; + loopInfo.index = loopIndex; + + int loopX = X(); + int loopY = Y(); + int x = (loopX > 0) ? loopX : 0; + int y = (loopY > 0) ? loopY : 0; + for (int row = 0; row < numRows; ++row) { + if (maxItems > 0 && row >= maxItems) { + break; + } + loopInfo.row = row; + //check overflow cut + if (overflow == eOverflowType::cut) { + if (orientation == eOrientation::horizontal && (row * columnWidth > loopWidth)) { + return; + } else if (orientation == eOrientation::vertical && (row * rowHeight > loopHeight)) { + return; + } + } + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + if (f->DoDebug()) + f->Debug(); + if (!f->DoExecute()) + continue; + f->Render(p, x, y, columnWidth, rowHeight); + } + if (orientation == eOrientation::horizontal) { + if (columnWidth > 0) { + x += columnWidth; + } else { + x += ColumnWidth(); + } + //check overflow wrap + if (overflow == eOverflowType::wrap && orientation == eOrientation::horizontal) { + if (x + columnWidth - 10 > loopWidth) { + x = X(); + if (x < 0) x = 0; + y += rowHeight; + } + } + } else if (orientation == eOrientation::vertical) { + if (rowHeight > 0) { + y += rowHeight; + } else { + y += RowHeight(); + } + } + } +} + +int cFuncLoop::FuncWidth(void) { + loopInfo.row = 0; + int loopIndex = tokenContainer->LoopIndex(Name()); + if (loopIndex < 0) { + esyslog("skindesigner: unknown loop function \"%s\"", Name()); + return 0; + } + int numLoops = tokenContainer->NumLoops(loopIndex); + int columnWidth = GetValue((int)eLoopAttribs::columnwidth); + if (columnWidth <=0) + columnWidth = ColumnWidth(); + eOverflowType overflow = (eOverflowType)GetValue((int)eLoopAttribs::overflow); + if (overflow == eOverflowType::cut) { + int maxItems = GetValue((int)eLoopAttribs::maxitems); + numLoops = min(numLoops, maxItems); + } + if (numLoops > 0) + return numLoops * columnWidth; + return 0; +} + +int cFuncLoop::FuncHeight(void) { + loopInfo.row = 0; + int loopIndex = tokenContainer->LoopIndex(Name()); + if (loopIndex < 0) { + esyslog("skindesigner: unknown loop function \"%s\"", Name()); + return 0; + } + int numLoops = tokenContainer->NumLoops(loopIndex); + int rowHeight = GetValue((int)eLoopAttribs::rowheight); + if (rowHeight <=0) + rowHeight = RowHeight(); + + eOverflowType overflow = (eOverflowType)GetValue((int)eLoopAttribs::overflow); + if (overflow == eOverflowType::cut) { + int maxItems = GetValue((int)eLoopAttribs::maxitems); + numLoops = min(numLoops, maxItems); + } else if (overflow == eOverflowType::wrap) { + int loopWidth = Width(); + if (loopWidth <= 0) + loopWidth = container.Width(); + loopWidth++; + int columnWidth = GetValue((int)eLoopAttribs::columnwidth); + if (columnWidth <=0) + columnWidth = ColumnWidth(); + int itemsPerRow = loopWidth / columnWidth; + int rows = numLoops / itemsPerRow; + if (numLoops % itemsPerRow > 0) + rows++; + return rows * rowHeight; + } + if (numLoops > 0) + return numLoops * rowHeight; + return 0; +} + +void cFuncLoop::Debug(void) { + loopInfo.row = 0; + cFunction::Debug(); + dsyslog("skindesigner: loopfunc Functions:"); + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + f->Debug(); + } +} + +void cFuncLoop::SetAttributesDefs(void) { + attribIDs.insert(pair("columnwidth", (int)eLoopAttribs::columnwidth)); + attribIDs.insert(pair("rowheight", (int)eLoopAttribs::rowheight)); + attribIDs.insert(pair("name", (int)eLoopAttribs::name)); + attribIDs.insert(pair("orientation", (int)eLoopAttribs::orientation)); + attribIDs.insert(pair("overflow", (int)eLoopAttribs::overflow)); + attribIDs.insert(pair("maxitems", (int)eLoopAttribs::maxitems)); + attribNames.insert(pair((int)eLoopAttribs::columnwidth, "columnwidth")); + attribNames.insert(pair((int)eLoopAttribs::rowheight, "rowheight")); + attribNames.insert(pair((int)eLoopAttribs::name, "name")); + attribNames.insert(pair((int)eLoopAttribs::orientation, "orientation")); + attribNames.insert(pair((int)eLoopAttribs::overflow, "overflow")); + attribNames.insert(pair((int)eLoopAttribs::maxitems, "maxitems")); +} + +int cFuncLoop::ColumnWidth(void) { + int width = 0; + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + if (!f->DoExecute()) + continue; + int funcWidth = f->X() + f->FuncWidth(); + if (funcWidth > width) + width = funcWidth; + } + return width; +} + +int cFuncLoop::RowHeight(void) { + int height = 0; + for (cFunction *f = functions.First(); f; f = functions.Next(f)) { + if (!f->DoExecute()) + continue; + int funcHeight = f->Y() + f->FuncHeight(); + if (funcHeight > height) + height = funcHeight; + } + return height; +} + +// --- cTextFloater ---------------------------------------------------------- + +cTextFloater::cTextFloater(void) { + text = eol = NULL; + lines = 0; + lastLine = -1; +} + +cTextFloater::cTextFloater(const char *fext, const cFont *font, int width, int height, int floatWidth, int floatHeight, int maxLines) { + text = NULL; + Set(text, font, width, height, floatWidth, floatHeight, maxLines); +} + +cTextFloater::~cTextFloater() { + free(text); +} + +void cTextFloater::Set(const char *Text, const cFont *font, int width, int height, int floatWidth, int floatHeight, int maxLines) { + free(text); + text = Text ? strdup(Text) : NULL; + eol = NULL; + lines = 0; + lastLine = -1; + if (!text) + return; + lines = 1; + if (width <= 0) + return; + int lineHeight = font->Height(); + bool cut = false; + if (height > 0) + cut = true; + bool doFloat = false; + if (floatWidth > 0 && floatHeight > 0) + doFloat = true; + int textWidth = width; + if (doFloat) { + textWidth = width - floatWidth; + } + + char *Blank = NULL; + char *Delim = NULL; + int w = 0; + + stripspace(text); // strips trailing newlines + + for (char *p = text; *p; ) { + int sl = Utf8CharLen(p); + uint sym = Utf8CharGet(p, sl); + if (sym == '\n') { + if ((maxLines > 0) && (lines == maxLines)) { + while (*p) { + *p = 0; + p++; + } + return; + } + lines++; + if (cut) { + if (lines * lineHeight >= height) { + //remove last line, find last linebreak + p--; + int max = 100; + int i = 0; + while (*p) { + int sl = Utf8CharLen(p); + uint sym = Utf8CharGet(p, sl); + if (sym == '\n') + break; + p -= sl; + i++; + if (i > max) + break; + } + p++; + if (*p) { + *p = '.'; p++; + if (*p) { + *p = '.'; p++; + if (*p) { + *p = '.'; p++; + *p = 0; + } + } + } + break; + } + } + if (doFloat) { + if ((lines-1) * lineHeight >= floatHeight) { + textWidth = width; + } + } + w = 0; + Blank = Delim = NULL; + p++; + continue; + } else if (sl == 1 && isspace(sym)) + Blank = p; + + int cw = font->Width(sym); + if (w + cw > textWidth) { + if (Blank) { + *Blank = '\n'; + p = Blank; + continue; + } else if (w > 0) { // there has to be at least one character before the newline + // Here's the ugly part, where we don't have any whitespace to + // punch in a newline, so we need to make room for it: + if (Delim) + p = Delim + 1; // let's fall back to the most recent delimiter + char *s = MALLOC(char, strlen(text) + 2); // The additional '\n' plus the terminating '\0' + int l = p - text; + strncpy(s, text, l); + s[l] = '\n'; + strcpy(s + l + 1, p); + free(text); + text = s; + p = text + l; + continue; + } + } + w += cw; + if (strchr("-.,:;!?_", *p)) { + Delim = p; + Blank = NULL; + } + p += sl; + } +} + +const char *cTextFloater::Text(void) { + if (eol) { + *eol = '\n'; + eol = NULL; + } + return text; +} + +const char *cTextFloater::GetLine(int line) { + char *s = NULL; + if (line < lines) { + if (eol) { + *eol = '\n'; + if (line == lastLine + 1) + s = eol + 1; + eol = NULL; + } + if (!s) { + s = text; + for (int i = 0; i < line; i++) { + s = strchr(s, '\n'); + if (s) + s++; + else + break; + } + } + if (s) { + if ((eol = strchr(s, '\n')) != NULL) + *eol = 0; + } + lastLine = line; + } + return s; +} diff --git a/coreengine/functions.h b/coreengine/functions.h new file mode 100644 index 0000000..57cbe64 --- /dev/null +++ b/coreengine/functions.h @@ -0,0 +1,220 @@ +#ifndef __FUNCTIONS_H +#define __FUNCTIONS_H + +#include "functions.h" + +class cFuncFill : public cFunction { +private: + void SetAttributesDefs(void); +public: + cFuncFill(cArea *owner, int numAttributes); + cFuncFill(const cFuncFill &other); + virtual ~cFuncFill(void); + void Set(vector &attributes); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); +}; + +class cFuncDrawRectangle : public cFunction { +private: + void SetAttributesDefs(void); +public: + cFuncDrawRectangle(cArea *owner, int numAttributes); + cFuncDrawRectangle(const cFuncDrawRectangle &other); + virtual ~cFuncDrawRectangle(void); + void Set(vector &attributes); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); + bool Blinking(void) { return GetValue((int)eDrawRectangleAttribs::animtype) == (int)eAnimType::blink; }; + int BlinkFreq(void) { return GetValue((int)eDrawRectangleAttribs::animfreq); }; + int Align(void) { return GetValue((int)eDrawRectangleAttribs::align); }; + int Valign(void) { return GetValue((int)eDrawRectangleAttribs::valign); }; +}; + +class cFuncDrawEllipse : public cFunction { +private: + void SetAttributesDefs(void); +public: + cFuncDrawEllipse(cArea *owner, int numAttributes); + cFuncDrawEllipse(const cFuncDrawEllipse &other); + virtual ~cFuncDrawEllipse(void); + void Set(vector &attributes); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); + bool Blinking(void) { return GetValue((int)eDrawEllipseAttribs::animtype) == (int)eAnimType::blink; }; + int BlinkFreq(void) { return GetValue((int)eDrawEllipseAttribs::animfreq); }; + int Align(void) { return GetValue((int)eDrawEllipseAttribs::align); }; + int Valign(void) { return GetValue((int)eDrawEllipseAttribs::valign); }; +}; + +class cFuncDrawSlope : public cFunction { +private: + void SetAttributesDefs(void); +public: + cFuncDrawSlope(cArea *owner, int numAttributes); + cFuncDrawSlope(const cFuncDrawSlope &other); + virtual ~cFuncDrawSlope(void); + void Set(vector &attributes); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); + bool Blinking(void) { return GetValue((int)eDrawSlopeAttribs::animtype) == (int)eAnimType::blink; }; + int BlinkFreq(void) { return GetValue((int)eDrawSlopeAttribs::animfreq); }; + int Align(void) { return GetValue((int)eDrawSlopeAttribs::align); }; + int Valign(void) { return GetValue((int)eDrawSlopeAttribs::valign); }; +}; + +class cTextDrawer { +private: + static cMutex fontLock; +protected: + const cFont *font; + char *fontName; + int fontSize; + void CacheFont(cGlobals *globals, int size); + void LoadFont(int size); + int TextWidth(const char *text); + int FontHeight(void); +public: + cTextDrawer(void); + virtual ~cTextDrawer(void); +}; + +class cFuncDrawText : public cFunction, public cTextDrawer { +private: + cTextExpr *text; + void SetAttributesDefs(void); + char *Cut(char *expr, int width); +public: + cFuncDrawText(cArea *owner, int numAttributes); + cFuncDrawText(const cFuncDrawText &other); + virtual ~cFuncDrawText(void); + void SetLoopInfo(cLoopInfo *loopInfo); + void SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer); + void Set(vector &attributes); + void Cache(void); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); + int FuncX(void); + int FuncY(void); + int FuncWidth(void); + int FuncHeight(void); + int AvrgFontWidth(void); + const cFont *GetFont(void); + bool Blinking(void) { return GetValue((int)eDrawTextAttribs::animtype) == (int)eAnimType::blink; }; + int BlinkFreq(void) { return GetValue((int)eDrawTextAttribs::animfreq); }; + int Align(void) { return GetValue((int)eDrawTextAttribs::align); }; + int Valign(void) { return GetValue((int)eDrawTextAttribs::valign); }; + void Debug(void); +}; + +class cFuncDrawTextVertical : public cFunction, public cTextDrawer { +private: + cTextExpr *text; + void SetAttributesDefs(void); +public: + cFuncDrawTextVertical(cArea *owner, int numAttributes); + cFuncDrawTextVertical(const cFuncDrawTextVertical &other); + virtual ~cFuncDrawTextVertical(void); + void SetLoopInfo(cLoopInfo *loopInfo); + void SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer); + void Set(vector &attributes); + void Cache(void); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); + int FuncWidth(void); + int FuncHeight(void); + bool Blinking(void) { return GetValue((int)eDrawTextAttribsVertical::animtype) == (int)eAnimType::blink; }; + int BlinkFreq(void) { return GetValue((int)eDrawTextAttribsVertical::animfreq); }; + int Align(void) { return GetValue((int)eDrawTextAttribsVertical::align); }; + int Valign(void) { return GetValue((int)eDrawTextAttribsVertical::valign); }; + void Debug(void); +}; + +class cTextFloater; + +class cFuncDrawTextBox : public cFunction, public cTextDrawer { +private: + cTextExpr *text; + cTextFloater *floater; + void SetFloater(void); + void SetAttributesDefs(void); + void SetFloatMode(int id, const char *val); +public: + cFuncDrawTextBox(cArea *owner, int numAttributes); + cFuncDrawTextBox(const cFuncDrawTextBox &other); + virtual ~cFuncDrawTextBox(void); + void SetLoopInfo(cLoopInfo *loopInfo); + void SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer); + void Set(vector &attributes); + void Cache(void); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); + int FuncWidth(void); + int FuncHeight(void); + void Debug(void); +}; + +class cFuncDrawImage : public cFunction { +private: + cTextExpr *path; + void SetAttributesDefs(void); + void SetImageType(int id, const char *val); + void PreCacheImage(void); +public: + cFuncDrawImage(cArea *owner, int numAttributes); + cFuncDrawImage(const cFuncDrawImage &other); + virtual ~cFuncDrawImage(void); + void SetLoopInfo(cLoopInfo *loopInfo); + void SetTokenContainerDeep(skindesignerapi::cTokenContainer *tokenContainer); + void Set(vector &attributes); + void Cache(void); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); + bool Blinking(void) { return GetValue((int)eDrawImageAttribs::animtype) == (int)eAnimType::blink; }; + int BlinkFreq(void) { return GetValue((int)eDrawImageAttribs::animfreq); }; + int Align(void) { return GetValue((int)eDrawImageAttribs::align); }; + int Valign(void) { return GetValue((int)eDrawImageAttribs::valign); }; + void Debug(void); +}; + +class cFuncLoop : public cFunction { +private: + cLoopInfo loopInfo; + cList functions; + void SetAttributesDefs(void); + int ColumnWidth(void); + int RowHeight(void); +public: + cFuncLoop(cArea *owner, int numAttributes); + virtual ~cFuncLoop(void); + void Set(vector &attributes); + void SetContainer(int x, int y, int width, int height); + void Cache(void); + void AddFunction(cFunction *f); + cFunction *GetFunction(const char *name); + void Render(cPixmap *p, int x0 = 0, int y0 = 0, int colWidth = 0, int rowHeight = 0); + int FuncWidth(void); + int FuncHeight(void); + void Debug(void); +}; + +class cTextFloater { +private: + char *text; + char *eol; + int lines; + int lastLine; +public: + cTextFloater(void); + cTextFloater(const char *text, const cFont *font, int width, int height = 0, int floatWidth = 0, int floatHeight = 0, int maxLines = 0); + ~cTextFloater(); + void Set(const char *Text, const cFont *font, int width, int height = 0, int floatWidth = 0, int floatHeight = 0, int maxLines = 0); + ///< Wraps the Text to make it fit into the area defined by the given Width + ///< when displayed with the given Font. + ///< Wrapping is done by inserting the necessary number of newline + ///< characters into the string. + ///< if height is set, new lines are only set till height is reached + ///< if floatwidth and floatheight are set, the first lines (depending on + ///< size of floatheight) are set to floatwidth + const char *Text(void); + ///< Returns the full wrapped text. + int Lines(void) { return lines; } + ///< Returns the actual number of lines needed to display the full wrapped text. + const char *GetLine(int line); + ///< Returns the given Line. The first line is numbered 0. +}; + + +#endif //__FUNCTIONS_H \ No newline at end of file diff --git a/libtemplate/globals.c b/coreengine/globals.c similarity index 84% rename from libtemplate/globals.c rename to coreengine/globals.c index 3fd0705..bb50a41 100644 --- a/libtemplate/globals.c +++ b/coreengine/globals.c @@ -89,6 +89,7 @@ void cGlobals::ReplaceIntVars(string &value) { } bool cGlobals::GetInt(string name, int &val) { + DeleteCurledBrackets(name); map < string, int >::iterator hit = intVars.find(name); if (hit != intVars.end()) { val = hit->second; @@ -146,10 +147,10 @@ void cGlobals::ReplaceStringVars(string &value) { value = value.replace(foundToken, token.size(), it->second); } } - } -bool cGlobals::GetString(string &name, string &value) { +bool cGlobals::GetString(string name, string &value) { + DeleteCurledBrackets(name); map::iterator hit = stringVars.find(name); if (hit == stringVars.end()) return false; @@ -157,7 +158,6 @@ bool cGlobals::GetString(string &name, string &value) { return true; } - bool cGlobals::AddTranslation(string name, map < string, string > transl) { translations.erase(name); translations.insert(pair >(name, transl)); @@ -207,20 +207,20 @@ string cGlobals::DoTranslate(string token) { return translation; } -void cGlobals::AddCustomInt(string &name, int value) { - customIntTokens.erase(name); - customIntTokens.insert(pair(name, value)); +void cGlobals::AddCustomInt(int num, int value) { + customIntTokens.erase(num); + customIntTokens.insert(pair(num, value)); customTokenChange = time(0); } -void cGlobals::AddCustomString(string &name, string &value) { - customStringTokens.erase(name); - customStringTokens.insert(pair(name, value)); +void cGlobals::AddCustomString(int num, string &value) { + customStringTokens.erase(num); + customStringTokens.insert(pair(num, value)); customTokenChange = time(0); } -bool cGlobals::GetCustomInt(string name, int &val) { - map < string, int >::iterator hit = customIntTokens.find(name); +bool cGlobals::GetCustomInt(int num, int &val) { + map < int, int >::iterator hit = customIntTokens.find(num); if (hit != customIntTokens.end()) { val = hit->second; return true; @@ -228,12 +228,21 @@ bool cGlobals::GetCustomInt(string name, int &val) { return false; } -map cGlobals::GetCustomStringTokens(void) { +bool cGlobals::GetCustomString(int num, string &val) { + map < int, string >::iterator hit = customStringTokens.find(num); + if (hit != customStringTokens.end()) { + val = hit->second; + return true; + } + return false; +} + +map cGlobals::GetCustomStringTokens(void) { lastCustomTokenQuery = time(0); return customStringTokens; } -map cGlobals::GetCustomIntTokens(void) { +map cGlobals::GetCustomIntTokens(void) { lastCustomTokenQuery = time(0); return customIntTokens; } @@ -246,12 +255,16 @@ bool cGlobals::CustomTokenChange(void) { return false; } +void cGlobals::ResetCustomTokenChange(void) { + lastCustomTokenQuery = 0; +} + void cGlobals::ListCustomTokens(void) { - for (map::iterator it = customStringTokens.begin(); it != customStringTokens.end(); it++) { - dsyslog("skindesigner: custom string token \"%s\" = \"%s\"", (it->first).c_str(), (it->second).c_str()); + for (map::iterator it = customStringTokens.begin(); it != customStringTokens.end(); it++) { + dsyslog("skindesigner: custom string token %d = \"%s\"", it->first, (it->second).c_str()); } - for (map::iterator it = customIntTokens.begin(); it != customIntTokens.end(); it++) { - dsyslog("skindesigner: custom int token \"%s\" = \"%d\"", (it->first).c_str(), it->second); + for (map::iterator it = customIntTokens.begin(); it != customIntTokens.end(); it++) { + dsyslog("skindesigner: custom int token %d = \"%d\"", it->first, it->second); } } @@ -281,3 +294,12 @@ void cGlobals::Debug(void) { } } } + +void cGlobals::DeleteCurledBrackets(string &token) { + if (token.find("{") != 0) + return; + if (token.find("}") != token.size() - 1) + return; + token = token.substr(1, token.size() - 2); +} + diff --git a/libtemplate/globals.h b/coreengine/globals.h similarity index 74% rename from libtemplate/globals.h rename to coreengine/globals.h index 12ee917..13c4515 100644 --- a/libtemplate/globals.h +++ b/coreengine/globals.h @@ -10,6 +10,7 @@ #include #include #include +#include #include using namespace std; @@ -24,14 +25,15 @@ private: time_t lastCustomTokenQuery; string language; string DoTranslate(string token); + void DeleteCurledBrackets(string &token); map colors; map fonts; map intVars; map doubleVars; map stringVars; map > translations; - map customStringTokens; - map customIntTokens; + map customStringTokens; + map customIntTokens; public: cGlobals(void); virtual ~cGlobals(void) {}; @@ -47,15 +49,17 @@ public: void ReplaceDoubleVars(string &value); void AddString(string &name, string &value); void ReplaceStringVars(string &value); - bool GetString(string &name, string &value); + bool GetString(string name, string &value); bool AddTranslation(string name, map < string, string > transl); bool Translate(string text, string &translation); - void AddCustomInt(string &name, int value); - void AddCustomString(string &name, string &value); - bool GetCustomInt(string name, int &val); - map GetCustomStringTokens(void); - map GetCustomIntTokens(void); + void AddCustomInt(int num, int value); + void AddCustomString(int num, string &value); + bool GetCustomInt(int num, int &val); + bool GetCustomString(int num, string &val); + map GetCustomStringTokens(void); + map GetCustomIntTokens(void); bool CustomTokenChange(void); + void ResetCustomTokenChange(void); void ListCustomTokens(void); void Debug(void); }; diff --git a/coreengine/gridelement.c b/coreengine/gridelement.c new file mode 100644 index 0000000..223546e --- /dev/null +++ b/coreengine/gridelement.c @@ -0,0 +1,57 @@ +#include "gridelement.h" +#include "../config.h" + +cGridElement::cGridElement(void) { + current = false; + indexCurrent = -1; + viewId = -1; + plugId = -1; +} + +cGridElement::cGridElement(const cGridElement &other) : cViewElement(other) { + current = false; + viewId = other.viewId; + plugId = other.plugId; + tokenContainer = new skindesignerapi::cTokenContainer(*other.tokenContainer); + indexCurrent = other.indexCurrent; + InheritTokenContainerDeep(); +} + +cGridElement::~cGridElement(void) { +} + +void cGridElement::SetTokenContainer(void) { + skindesignerapi::cTokenContainer *tkGe = plgManager->GetTokenContainerGE(plugId, viewId, id); + if (!tkGe) + return; + tokenContainer = new skindesignerapi::cTokenContainer(*tkGe); + indexCurrent = tokenContainer->GetNumDefinedIntTokens(); + tokenContainer->DefineIntToken("{current}", indexCurrent); + InheritTokenContainer(); +} + +void cGridElement::Set(skindesignerapi::cTokenContainer *tk) { + tokenContainer->Clear(); + tokenContainer->SetTokens(tk); + SetDirty(); +} + +void cGridElement::SetCurrent(bool current) { + this->current = current; + SetDirty(); +} + +bool cGridElement::Parse(bool forced) { + if (!dirty) + return false; + tokenContainer->AddIntToken(indexCurrent, current); + return true; +} + +int cGridElement::Width(void) { + return container.Width(); +} + +int cGridElement::Height(void) { + return container.Height(); +} \ No newline at end of file diff --git a/coreengine/gridelement.h b/coreengine/gridelement.h new file mode 100644 index 0000000..6e94985 --- /dev/null +++ b/coreengine/gridelement.h @@ -0,0 +1,27 @@ +#ifndef __GRIDELEMENT_H +#define __GRIDELEMENT_H + +#include "viewelement.h" + +class cGridElement : public cViewElement { +private: + int viewId; + int plugId; + bool current; + int indexCurrent; +public: + cGridElement(void); + cGridElement(const cGridElement &other); + virtual ~cGridElement(void); + void SetPluginId(int plugId) { this->plugId = plugId; }; + void SetViewId(int viewId) { this->viewId = viewId; }; + void SetTokenContainer(void); + skindesignerapi::cTokenContainer *GetTokenContainer(void) { return tokenContainer; }; + void Set(skindesignerapi::cTokenContainer *tk); + void SetCurrent(bool current); + bool Parse(bool forced = true); + int Width(void); + int Height(void); +}; + +#endif //__GRIDELEMENT_H \ No newline at end of file diff --git a/coreengine/listelements.c b/coreengine/listelements.c new file mode 100644 index 0000000..04e3cf4 --- /dev/null +++ b/coreengine/listelements.c @@ -0,0 +1,1830 @@ +#include "listelements.h" +#include "../config.h" +#include +#include + +/****************************************************************** +* cListElement +******************************************************************/ +cListElement::cListElement(void) { + dirty = false; + num = -1; + current = false; + wasCurrent = false; + selectable = false; + currentElement = NULL; + menuCat = mcUnknown; +}; + +cListElement::cListElement(const cListElement &other) : cViewElement(other) { + num = -1; + current = false; + selectable = false; + currentElement = NULL; +} + +void cListElement::SetCurrent(bool cur) { + if (!cur && current) + wasCurrent = true; + else + wasCurrent = false; + current = cur; +} + +void cListElement::Close(void) { + if (current && currentElement) { + currentElement->Close(); + } + cViewElement::Close(); + dirty = false; +} + +void cListElement::Clear(void) { + if (current && currentElement) { + currentElement->Close(); + } + cViewElement::Clear(); + dirty = false; +} + +void cListElement::WakeCurrent(void) { + if (currentElement) { + currentElement->WakeUp(); + } +} + + +char *cListElement::ParseSeparator(const char *text) { + const char *start = text; + while (*start && (*start == '-' || *start == ' ' || *start == 9)) { + start++; + } + const char *end = start; + while (*end && *end != '-') { + end++; + } + int len = end - start; + char *ret = (char*)malloc(len); + memset(ret, 0, len); + strncpy(ret, start, len-1); + return ret; +} + +/****************************************************************** +* cCurrentElement +******************************************************************/ +cCurrentElement::cCurrentElement(void) { + listX = 0; + listY = 0; + listWidth = 0; + listHeight = 0; +} + +void cCurrentElement::SetListPosition(int x, int y, int width, int height) { + listX = x; + listY = y; + listWidth = width; + listHeight = height; +} + +void cCurrentElement::SetListTokens(skindesignerapi::cTokenContainer *tokenContainer) { + tokenContainer->AddIntToken(0, listX); + tokenContainer->AddIntToken(1, listY); + tokenContainer->AddIntToken(2, listWidth); + tokenContainer->AddIntToken(3, listHeight); +} + +/****************************************************************** +* cLeMenuDefault +******************************************************************/ +cLeMenuDefault::cLeMenuDefault(void) { + text = NULL; + colX = NULL; + colWidths = NULL; + plugName = NULL; +} + +cLeMenuDefault::cLeMenuDefault(const cLeMenuDefault &other) : cListElement(other) { + text = NULL; + colX = NULL; + colWidths = NULL; + plugName = NULL; +} + +cLeMenuDefault::~cLeMenuDefault(void) { + +} + +void cLeMenuDefault::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{column1}", (int)eLeMenuDefaultST::column1); + tokenContainer->DefineStringToken("{column2}", (int)eLeMenuDefaultST::column2); + tokenContainer->DefineStringToken("{column3}", (int)eLeMenuDefaultST::column3); + tokenContainer->DefineStringToken("{column4}", (int)eLeMenuDefaultST::column4); + tokenContainer->DefineStringToken("{column5}", (int)eLeMenuDefaultST::column5); + tokenContainer->DefineStringToken("{column6}", (int)eLeMenuDefaultST::column6); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeMenuDefaultIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeMenuDefaultIT::current); + tokenContainer->DefineIntToken("{separator}", (int)eLeMenuDefaultIT::separator); + tokenContainer->DefineIntToken("{column2set}", (int)eLeMenuDefaultIT::column2set); + tokenContainer->DefineIntToken("{column3set}", (int)eLeMenuDefaultIT::column3set); + tokenContainer->DefineIntToken("{column4set}", (int)eLeMenuDefaultIT::column4set); + tokenContainer->DefineIntToken("{column5set}", (int)eLeMenuDefaultIT::column5set); + tokenContainer->DefineIntToken("{column6set}", (int)eLeMenuDefaultIT::column6set); + tokenContainer->DefineIntToken("{column1x}", (int)eLeMenuDefaultIT::column1x); + tokenContainer->DefineIntToken("{column2x}", (int)eLeMenuDefaultIT::column2x); + tokenContainer->DefineIntToken("{column3x}", (int)eLeMenuDefaultIT::column3x); + tokenContainer->DefineIntToken("{column4x}", (int)eLeMenuDefaultIT::column4x); + tokenContainer->DefineIntToken("{column5x}", (int)eLeMenuDefaultIT::column5x); + tokenContainer->DefineIntToken("{column6x}", (int)eLeMenuDefaultIT::column6x); + tokenContainer->DefineIntToken("{column1width}", (int)eLeMenuDefaultIT::column1width); + tokenContainer->DefineIntToken("{column2width}", (int)eLeMenuDefaultIT::column2width); + tokenContainer->DefineIntToken("{column3width}", (int)eLeMenuDefaultIT::column3width); + tokenContainer->DefineIntToken("{column4width}", (int)eLeMenuDefaultIT::column4width); + tokenContainer->DefineIntToken("{column5width}", (int)eLeMenuDefaultIT::column5width); + tokenContainer->DefineIntToken("{column6width}", (int)eLeMenuDefaultIT::column6width); + tokenContainer->DefineIntToken("{column1pb}", (int)eLeMenuDefaultIT::column1pb); + tokenContainer->DefineIntToken("{column2pb}", (int)eLeMenuDefaultIT::column2pb); + tokenContainer->DefineIntToken("{column3pb}", (int)eLeMenuDefaultIT::column3pb); + tokenContainer->DefineIntToken("{column4pb}", (int)eLeMenuDefaultIT::column4pb); + tokenContainer->DefineIntToken("{column5pb}", (int)eLeMenuDefaultIT::column5pb); + tokenContainer->DefineIntToken("{column6pb}", (int)eLeMenuDefaultIT::column6pb); + tokenContainer->DefineIntToken("{column1pbtotalsize}", (int)eLeMenuDefaultIT::column1pbtotalsize); + tokenContainer->DefineIntToken("{column2pbtotalsize}", (int)eLeMenuDefaultIT::column2pbtotalsize); + tokenContainer->DefineIntToken("{column3pbtotalsize}", (int)eLeMenuDefaultIT::column3pbtotalsize); + tokenContainer->DefineIntToken("{column4pbtotalsize}", (int)eLeMenuDefaultIT::column4pbtotalsize); + tokenContainer->DefineIntToken("{column5pbtotalsize}", (int)eLeMenuDefaultIT::column5pbtotalsize); + tokenContainer->DefineIntToken("{column6pbtotalsize}", (int)eLeMenuDefaultIT::column6pbtotalsize); + tokenContainer->DefineIntToken("{column1pbsize}", (int)eLeMenuDefaultIT::column1pbsize); + tokenContainer->DefineIntToken("{column2pbsize}", (int)eLeMenuDefaultIT::column2pbsize); + tokenContainer->DefineIntToken("{column3pbsize}", (int)eLeMenuDefaultIT::column3pbsize); + tokenContainer->DefineIntToken("{column4pbsize}", (int)eLeMenuDefaultIT::column4pbsize); + tokenContainer->DefineIntToken("{column5pbsize}", (int)eLeMenuDefaultIT::column5pbsize); + tokenContainer->DefineIntToken("{column6pbsize}", (int)eLeMenuDefaultIT::column6pbsize); + tokenContainer->DefineIntToken("{setup}", (int)eLeMenuDefaultIT::setup); + tokenContainer->DefineIntToken("{commands}", (int)eLeMenuDefaultIT::commands); + tokenContainer->DefineIntToken("{fritzbox}", (int)eLeMenuDefaultIT::fritzbox); + tokenContainer->DefineIntToken("{systeminfo}", (int)eLeMenuDefaultIT::systeminfo); + tokenContainer->DefineIntToken("{mailbox}", (int)eLeMenuDefaultIT::mailbox); + tokenContainer->DefineIntToken("{neutrinoepg}", (int)eLeMenuDefaultIT::neutrinoepg); + tokenContainer->DefineIntToken("{remotetimers}", (int)eLeMenuDefaultIT::remotetimers); + InheritTokenContainer(); +} + +void cLeMenuDefault::SetListInfo(int *colX, int *colWidths) { + this->colX = colX; + this->colWidths = colWidths; +} + +void cLeMenuDefault::SetText(const char *text) { + dirty = true; + free(this->text); + this->text = strdup(text); +} + +bool cLeMenuDefault::Parse(bool forced) { + if (!dirty) + return false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::current, current); + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::separator, !selectable); + for (int i = 0; i < MAX_TABS; i++) { + bool colUsed = false; + const char *s = GetTabbedText(text, i); + if (s) { + tokenContainer->AddStringToken(i, s); + colUsed = true; + CheckProgressBar(s, i); + } + else + tokenContainer->AddStringToken(i, ""); + if (i > 0) + tokenContainer->AddIntToken(i + 2, colUsed); + tokenContainer->AddIntToken(i + 8, colX[i]); + tokenContainer->AddIntToken(i + 14, colWidths[i]); + } + SetMenuCategory(); + return true; +} + +const char *cLeMenuDefault::GetTabbedText(const char *s, int tab) { + if (!s) + return NULL; + static char buffer[1000]; + const char *a = s; + const char *b = strchrnul(a, '\t'); + while (*b && tab-- > 0) { + a = b + 1; + b = strchrnul(a, '\t'); + } + if (!*b) + return (tab <= 0) ? a : NULL; + unsigned int n = b - a; + if (n >= sizeof(buffer)) + n = sizeof(buffer) - 1; + strncpy(buffer, a, n); + buffer[n] = 0; + return buffer; +} + +void cLeMenuDefault::SetMenuCategory(void) { + if (menuCat >= mcPluginSetup && menuCat <= mcSetupPlugins) { + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::setup, 1); + return; + } else if (menuCat == mcCommand) { + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::commands, 1); + return; + } + + if (!plugName) { + return; + } + if (!strcmp(plugName, "fritzbox")) { + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::fritzbox, 1); + } else if (!strcmp(plugName, "systeminfo")) { + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::systeminfo, 1); + } else if (!strcmp(plugName, "mailbox")) { + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::mailbox, 1); + } else if (!strcmp(plugName, "neutrinoepg")) { + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::neutrinoepg, 1); + } else if (!strcmp(plugName, "remotetimers")) { + tokenContainer->AddIntToken((int)eLeMenuDefaultIT::remotetimers, 1); + } +} + +void cLeMenuDefault::CheckProgressBar(const char *text, int tab) { + const char *start = strchr(text, '['); + if (!start) + return; + const char *stop = strchr(text, ']'); + if (!stop) + return; + int total = stop - start - 1; + int len = 0; + char *s = (char*)start + 1; + while (*s && *s == '|') { + len++; + s++; + } + tokenContainer->AddIntToken(20 + tab, 1); + tokenContainer->AddIntToken(26 + tab, total); + tokenContainer->AddIntToken(32 + tab, len); +} + +/****************************************************************** +* cVeMenuMain +******************************************************************/ +cVeMenuMain::cVeMenuMain(void) { + text = NULL; + number = NULL; + label = NULL; +} + +cVeMenuMain::~cVeMenuMain(void) { + free(text); + free(number); + free(label); +} + +void cVeMenuMain::SplitText(void) { + char *start = skipspace(text); + bool found = false; + bool doBreak = false; + size_t i = 0; + char *c = start; + while (*c) { + if (i==0) { + //if text directly starts with nonnumeric, break + if (!(*c >= '0' && *c <= '9')) { + break; + } + } + if (found) { + //if current char is not a figure anymore, break + if (!(*c >= '0' && *c <= '9')) { + //there has to be a space after the menu item number + //plugins with figures in their name are eval :-) + if (*c != ' ') + found = false; + doBreak = true; + } + } + if (*c >= '0' && *c <= '9') { + found = true; + } + if (doBreak) + break; + if (i>4) + break; + c++; + i++; + } + + free(number); + free(label); + if (found) { + number = (char*)malloc(i+1); + memset(number, 0, i+1); + strncpy(number, start, i); + } else { + number = (char*)malloc(2); + memset(number, 0, 2); + strncpy(number, "", 1); + } + label = strdup(skipspace(c)); +} + +/****************************************************************** +* cLeMenuMain +******************************************************************/ +cLeMenuMain::cLeMenuMain(void) { + currentMain = NULL; +} + +cLeMenuMain::cLeMenuMain(const cLeMenuMain &other) : cListElement(other) { + text = NULL; + number = NULL; + label = NULL; + currentMain = NULL; +} + +cLeMenuMain::~cLeMenuMain(void) { +} + +void cLeMenuMain::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{label}", (int)eLeMenuMainST::label); + tokenContainer->DefineStringToken("{number}", (int)eLeMenuMainST::number); + tokenContainer->DefineStringToken("{icon}", (int)eLeMenuMainST::icon); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeMenuMainIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeMenuMainIT::current); + tokenContainer->DefineIntToken("{separator}", (int)eLeMenuMainIT::separator); + InheritTokenContainer(); +} + +void cLeMenuMain::ClearCurrentElement(void) { + if (wasCurrent && currentMain) { + currentMain->Close(); + } +} + +void cLeMenuMain::SetText(const char *text) { + dirty = true; + free(this->text); + this->text = strdup(text); +} + +bool cLeMenuMain::Parse(bool forced) { + if (!dirty) + return false; + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeMenuMainIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeMenuMainIT::current, current); + tokenContainer->AddIntToken((int)eLeMenuMainIT::separator, !selectable); + SplitText(); + tokenContainer->AddStringToken((int)eLeMenuMainST::number, number); + tokenContainer->AddStringToken((int)eLeMenuMainST::label, label); + tokenContainer->AddStringToken((int)eLeMenuMainST::icon, imgCache->GetIconName(label).c_str()); + return true; +} + +void cLeMenuMain::RenderCurrent(void) { + if (!currentMain) + return; + currentMain->SetText(text); + currentMain->SetListPosition(container.X(), container.Y(), container.Width(), container.Height()); + currentMain->Parse(); +} + +const char *cLeMenuMain::PluginName(void) { + if (!label) + return NULL; + for (int i = 0; ; i++) { + cPlugin *p = cPluginManager::GetPlugin(i); + if (p) { + const char *mainMenuEntry = p->MainMenuEntry(); + if (!mainMenuEntry) + continue; + if (!strcmp(mainMenuEntry, label)) { + return p->Name(); + } + } else + break; + } + return NULL; +} + +/****************************************************************** +* cCeMenuMain +******************************************************************/ +cCeMenuMain::cCeMenuMain(void) { + +} + +cCeMenuMain::~cCeMenuMain(void) { + +} + +void cCeMenuMain::SetText(const char *text) { + dirty = true; + free(this->text); + this->text = strdup(text); +} + +void cCeMenuMain::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{menuitemx}", (int)eCeMenuMainIT::menuitemx); + tokenContainer->DefineIntToken("{menuitemy}", (int)eCeMenuMainIT::menuitemy); + tokenContainer->DefineIntToken("{menuitemwidth}", (int)eCeMenuMainIT::menuitemwidth); + tokenContainer->DefineIntToken("{menuitemheight}", (int)eCeMenuMainIT::menuitemheight); + tokenContainer->DefineStringToken("{label}", (int)eCeMenuMainST::label); + tokenContainer->DefineStringToken("{number}", (int)eCeMenuMainST::number); + tokenContainer->DefineStringToken("{icon}", (int)eCeMenuMainST::icon); + InheritTokenContainer(); +} + +bool cCeMenuMain::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + tokenContainer->Clear(); + SplitText(); + SetListTokens(tokenContainer); + tokenContainer->AddStringToken((int)eLeMenuMainST::number, number); + tokenContainer->AddStringToken((int)eLeMenuMainST::label, label); + tokenContainer->AddStringToken((int)eLeMenuMainST::icon, imgCache->GetIconName(label).c_str()); + return true; +} + +/****************************************************************** +* cVeMenuSchedules +******************************************************************/ +cVeMenuSchedules::cVeMenuSchedules(void) { + event = NULL; + channel = NULL; + withDate = false; + timerMatch = tmNone; + epgSearchFav = false; +} + +/****************************************************************** +* cLeMenuSchedules +******************************************************************/ +cLeMenuSchedules::cLeMenuSchedules(void) { + currentSchedules = NULL; + menuCat = mcUnknown; +} + +cLeMenuSchedules::cLeMenuSchedules(const cLeMenuSchedules &other) : cListElement(other) { +} + +cLeMenuSchedules::~cLeMenuSchedules(void) { +} + +void cLeMenuSchedules::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{title}", (int)eLeMenuSchedulesST::title); + tokenContainer->DefineStringToken("{shorttext}", (int)eLeMenuSchedulesST::shorttext); + tokenContainer->DefineStringToken("{start}", (int)eLeMenuSchedulesST::start); + tokenContainer->DefineStringToken("{stop}", (int)eLeMenuSchedulesST::stop); + tokenContainer->DefineStringToken("{day}", (int)eLeMenuSchedulesST::day); + tokenContainer->DefineStringToken("{date}", (int)eLeMenuSchedulesST::date); + tokenContainer->DefineStringToken("{durationminutes}", (int)eLeMenuSchedulesST::durationminutes); + tokenContainer->DefineStringToken("{channelname}", (int)eLeMenuSchedulesST::channelname); + tokenContainer->DefineStringToken("{channelid}", (int)eLeMenuSchedulesST::channelid); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeMenuSchedulesIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeMenuSchedulesIT::current); + tokenContainer->DefineIntToken("{separator}", (int)eLeMenuSchedulesIT::separator); + tokenContainer->DefineIntToken("{daynumeric}", (int)eLeMenuSchedulesIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eLeMenuSchedulesIT::month); + tokenContainer->DefineIntToken("{year}", (int)eLeMenuSchedulesIT::year); + tokenContainer->DefineIntToken("{running}", (int)eLeMenuSchedulesIT::running); + tokenContainer->DefineIntToken("{elapsed}", (int)eLeMenuSchedulesIT::elapsed); + tokenContainer->DefineIntToken("{startsin}", (int)eLeMenuSchedulesIT::startsin); + tokenContainer->DefineIntToken("{duration}", (int)eLeMenuSchedulesIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eLeMenuSchedulesIT::durationhours); + tokenContainer->DefineIntToken("{channelnumber}", (int)eLeMenuSchedulesIT::channelnumber); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eLeMenuSchedulesIT::channellogoexists); + tokenContainer->DefineIntToken("{whatson}", (int)eLeMenuSchedulesIT::whatson); + tokenContainer->DefineIntToken("{whatsonnow}", (int)eLeMenuSchedulesIT::whatsonnow); + tokenContainer->DefineIntToken("{whatsonnext}", (int)eLeMenuSchedulesIT::whatsonnext); + tokenContainer->DefineIntToken("{whatsonfavorites}", (int)eLeMenuSchedulesIT::whatsonfavorites); + tokenContainer->DefineIntToken("{timerpartitial}", (int)eLeMenuSchedulesIT::timerpartitial); + tokenContainer->DefineIntToken("{timerfull}", (int)eLeMenuSchedulesIT::timerfull); + tokenContainer->DefineIntToken("{hasVPS}", (int)eLeMenuSchedulesIT::hasVPS); + InheritTokenContainer(); +} + +void cLeMenuSchedules::ClearCurrentElement(void) { + if (wasCurrent && currentSchedules) { + currentSchedules->Close(); + } +} + +void cLeMenuSchedules::Set(const cEvent *event, const cChannel *channel, bool withDate, eTimerMatch timerMatch) { + dirty = true; + this->event = event; + this->channel = channel; + this->withDate = withDate; + this->timerMatch = timerMatch; +} + +bool cLeMenuSchedules::Parse(bool forced) { + if (!dirty) + return false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::current, current); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::separator, !selectable); + + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::whatson, (menuCat == mcSchedule && !epgSearchFav) ? true : false); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::whatsonnow, menuCat == mcScheduleNow ? true : false); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::whatsonnext, menuCat == mcScheduleNext ? true : false); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::whatsonfavorites, epgSearchFav); + + if (timerMatch == tmFull) { + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerpartitial, false); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerfull, true); + } else if (timerMatch == tmPartial) { + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerpartitial, true); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerfull, false); + } else { + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerpartitial, false); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerfull, false); + } + + if (event) { + if (selectable) { + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::title, event->Title()); + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::shorttext, event->ShortText()); + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::start, *(event->GetTimeString())); + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::stop, *(event->GetEndTimeString())); + time_t startTime = event->StartTime(); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::day, *WeekDayName(startTime)); + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::date, *ShortDateString(startTime)); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::month, sStartTime->tm_mon+1); + + bool isRunning = false; + time_t now = time(NULL); + if ((now >= event->StartTime()) && (now <= event->EndTime())) + isRunning = true; + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::running, isRunning); + if (isRunning) { + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::elapsed, (now - event->StartTime())/60); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::startsin, 0); + } else { + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::elapsed, 0); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::startsin, (event->StartTime() - now)/60); + } + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::duration, event->Duration() / 60); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::durationhours, event->Duration() / 3600); + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::durationminutes, *cString::sprintf("%.2d", (event->Duration() / 60)%60)); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::hasVPS, (bool)event->Vps()); + } else { + char *sep = ParseSeparator(event->Title()); + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::title, sep); + free(sep); + } + } else if (!channel) { + //Hack für komischen patch von jinx + //stringTokens.insert(pair("title", dayseparator)); + } + if (channel) { + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::channelname, channel->Name()); + cString channelID = channel->GetChannelID().ToString(); + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::channelid, *channelID); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::channelnumber, channel->Number()); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::channellogoexists, imgCache->LogoExists(*channelID)); + if (!event && !selectable) { + tokenContainer->AddStringToken((int)eLeMenuSchedulesST::title, channel->Name()); + } + } + return true; +} + +void cLeMenuSchedules::RenderCurrent(void) { + if (!currentSchedules) + return; + currentSchedules->Set(event, channel, withDate, timerMatch, menuCat); + currentSchedules->SetEpgSearchFav(epgSearchFav); + currentSchedules->SetListPosition(container.X(), container.Y(), container.Width(), container.Height()); + currentSchedules->Parse(); +} + +/****************************************************************** +* cCeMenuSchedules +******************************************************************/ +cCeMenuSchedules::cCeMenuSchedules(void) { + schedulesIndex = -1; +} + +cCeMenuSchedules::~cCeMenuSchedules(void) { +} + +void cCeMenuSchedules::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{title}", (int)eCeMenuSchedulesST::title); + tokenContainer->DefineStringToken("{shorttext}", (int)eCeMenuSchedulesST::shorttext); + tokenContainer->DefineStringToken("{description}", (int)eCeMenuSchedulesST::description); + tokenContainer->DefineStringToken("{start}", (int)eCeMenuSchedulesST::start); + tokenContainer->DefineStringToken("{stop}", (int)eCeMenuSchedulesST::stop); + tokenContainer->DefineStringToken("{day}", (int)eCeMenuSchedulesST::day); + tokenContainer->DefineStringToken("{date}", (int)eCeMenuSchedulesST::date); + tokenContainer->DefineStringToken("{channelname}", (int)eCeMenuSchedulesST::channelname); + tokenContainer->DefineStringToken("{channelid}", (int)eCeMenuSchedulesST::channelid); + tokenContainer->DefineStringToken("{posterpath}", (int)eCeMenuSchedulesST::posterpath); + tokenContainer->DefineStringToken("{bannerpath}", (int)eCeMenuSchedulesST::bannerpath); + tokenContainer->DefineIntToken("{menuitemx}", (int)eCeMenuSchedulesIT::menuitemx); + tokenContainer->DefineIntToken("{menuitemy}", (int)eCeMenuSchedulesIT::menuitemy); + tokenContainer->DefineIntToken("{menuitemwidth}", (int)eCeMenuSchedulesIT::menuitemwidth); + tokenContainer->DefineIntToken("{menuitemheight}", (int)eCeMenuSchedulesIT::menuitemheight); + tokenContainer->DefineIntToken("{daynumeric}", (int)eCeMenuSchedulesIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eCeMenuSchedulesIT::month); + tokenContainer->DefineIntToken("{year}", (int)eCeMenuSchedulesIT::year); + tokenContainer->DefineIntToken("{running}", (int)eCeMenuSchedulesIT::running); + tokenContainer->DefineIntToken("{elapsed}", (int)eCeMenuSchedulesIT::elapsed); + tokenContainer->DefineIntToken("{duration}", (int)eCeMenuSchedulesIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eCeMenuSchedulesIT::durationhours); + tokenContainer->DefineIntToken("{durationminutes}", (int)eCeMenuSchedulesIT::durationminutes); + tokenContainer->DefineIntToken("{channelnumber}", (int)eCeMenuSchedulesIT::channelnumber); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eCeMenuSchedulesIT::channellogoexists); + tokenContainer->DefineIntToken("{hasposter}", (int)eCeMenuSchedulesIT::hasposter); + tokenContainer->DefineIntToken("{posterwidth}", (int)eCeMenuSchedulesIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eCeMenuSchedulesIT::posterheight); + tokenContainer->DefineIntToken("{hasbanner}", (int)eCeMenuSchedulesIT::hasbanner); + tokenContainer->DefineIntToken("{bannerwidth}", (int)eCeMenuSchedulesIT::bannerwidth); + tokenContainer->DefineIntToken("{bannerheight}", (int)eCeMenuSchedulesIT::bannerheight); + tokenContainer->DefineIntToken("{whatson}", (int)eCeMenuSchedulesIT::whatson); + tokenContainer->DefineIntToken("{whatsonnow}", (int)eCeMenuSchedulesIT::whatsonnow); + tokenContainer->DefineIntToken("{whatsonnext}", (int)eCeMenuSchedulesIT::whatsonnext); + tokenContainer->DefineIntToken("{whatsonfavorites}", (int)eCeMenuSchedulesIT::whatsonfavorites); + tokenContainer->DefineIntToken("{timerpartitial}", (int)eCeMenuSchedulesIT::timerpartitial); + tokenContainer->DefineIntToken("{timerfull}", (int)eCeMenuSchedulesIT::timerfull); + tokenContainer->DefineLoopToken("{schedule[title]}", (int)eCeMenuSchedulesLT::title); + tokenContainer->DefineLoopToken("{schedule[shorttext]}", (int)eCeMenuSchedulesLT::shorttext); + tokenContainer->DefineLoopToken("{schedule[start]}", (int)eCeMenuSchedulesLT::start); + tokenContainer->DefineLoopToken("{schedule[stop]}", (int)eCeMenuSchedulesLT::stop); + schedulesIndex = tokenContainer->LoopIndex("schedule"); + InheritTokenContainer(); +} + +void cCeMenuSchedules::Set(const cEvent *event, const cChannel *channel, bool withDate, eTimerMatch timerMatch, eMenuCategory menuCat) { + dirty = true; + this->menuCat = menuCat; + this->event = event; + this->channel = channel; + this->withDate = withDate; + this->timerMatch = timerMatch; +} + +bool cCeMenuSchedules::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + tokenContainer->Clear(); + SetListTokens(tokenContainer); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::whatson, (menuCat == mcSchedule && !epgSearchFav) ? true : false); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::whatsonnow, menuCat == mcScheduleNow ? true : false); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::whatsonnext, menuCat == mcScheduleNext ? true : false); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::whatsonfavorites, epgSearchFav); + if (timerMatch == tmFull) { + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerpartitial, false); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerfull, true); + } else if (timerMatch == tmPartial) { + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerpartitial, true); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerfull, false); + } else { + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerpartitial, false); + tokenContainer->AddIntToken((int)eLeMenuSchedulesIT::timerfull, false); + } + + if (event) { + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::title, event->Title()); + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::shorttext, event->ShortText()); + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::description, event->Description()); + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::start, *(event->GetTimeString())); + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::stop, *(event->GetEndTimeString())); + time_t startTime = event->StartTime(); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::day, *WeekDayName(startTime)); + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::date, *ShortDateString(startTime)); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::month, sStartTime->tm_mon+1); + bool isRunning = false; + time_t now = time(NULL); + if ((now >= event->StartTime()) && (now <= event->EndTime())) + isRunning = true; + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::running, isRunning); + if (isRunning) { + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::elapsed, (now - event->StartTime())/60); + } else { + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::elapsed, 0); + } + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::duration, event->Duration() / 60); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::durationhours, event->Duration() / 3600); + if (LoadFullScrapInfo(event, NULL)) + SetScraperPosterBanner(tokenContainer); + } + if (channel) { + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::channelname, channel->Name()); + cString channelID = channel->GetChannelID().ToString(); + tokenContainer->AddStringToken((int)eCeMenuSchedulesST::channelid, *channelID); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::channelnumber, channel->Number()); + tokenContainer->AddIntToken((int)eCeMenuSchedulesIT::channellogoexists, imgCache->LogoExists(*channelID)); + } + + if (menuCat == mcScheduleNow || menuCat == mcScheduleNext) { + int eventsAvailable = 0; + cSchedulesLock schedulesLock; + const cSchedules *schedules = cSchedules::Schedules(schedulesLock); + const cSchedule *schedule = NULL; + schedule = schedules->GetSchedule(channel); + if (schedule) { + for (const cEvent *e = schedule->GetPresentEvent(); e; e = schedule->Events()->Next(e)) { + eventsAvailable++; + if (eventsAvailable == 10) + break; + } + } + vector loopInfo; + loopInfo.push_back(eventsAvailable); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + + if (schedule) { + int num = 0; + for (const cEvent *e = schedule->GetPresentEvent(); e; e = schedule->Events()->Next(e)) { + if (num < 2) { + num++; + continue; + } + tokenContainer->AddLoopToken(schedulesIndex, num-2, (int)eCeMenuChannelsLT::title, e->Title()); + tokenContainer->AddLoopToken(schedulesIndex, num-2, (int)eCeMenuChannelsLT::shorttext, e->ShortText()); + tokenContainer->AddLoopToken(schedulesIndex, num-2, (int)eCeMenuChannelsLT::start, *(e->GetTimeString())); + tokenContainer->AddLoopToken(schedulesIndex, num-2, (int)eCeMenuChannelsLT::stop, *(e->GetEndTimeString())); + num++; + if (num > 11) + break; + } + } + } + return true; +} + +/****************************************************************** +* cLeMenuChannels +******************************************************************/ +cLeMenuChannels::cLeMenuChannels(void) { + currentChannel = NULL; + channel = NULL; + withProvider = false; +} + +cLeMenuChannels::cLeMenuChannels(const cLeMenuChannels &other) : cListElement(other) { + channel = NULL; + withProvider = false; +} + +cLeMenuChannels::~cLeMenuChannels(void) { +} + +void cLeMenuChannels::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{name}", (int)eLeMenuChannelsST::name); + tokenContainer->DefineStringToken("{channelid}", (int)eLeMenuChannelsST::channelid); + tokenContainer->DefineStringToken("{source}", (int)eLeMenuChannelsST::source); + tokenContainer->DefineStringToken("{sourcedescription}", (int)eLeMenuChannelsST::sourcedescription); + tokenContainer->DefineStringToken("{position}", (int)eLeMenuChannelsST::position); + tokenContainer->DefineStringToken("{presenteventtitle}", (int)eLeMenuChannelsST::presenteventtitle); + tokenContainer->DefineStringToken("{presenteventstart}", (int)eLeMenuChannelsST::presenteventstart); + tokenContainer->DefineStringToken("{presenteventstop}", (int)eLeMenuChannelsST::presenteventstop); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeMenuChannelsIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeMenuChannelsIT::current); + tokenContainer->DefineIntToken("{separator}", (int)eLeMenuChannelsIT::separator); + tokenContainer->DefineIntToken("{number}", (int)eLeMenuChannelsIT::number); + tokenContainer->DefineIntToken("{transponder}", (int)eLeMenuChannelsIT::transponder); + tokenContainer->DefineIntToken("{frequency}", (int)eLeMenuChannelsIT::frequency); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eLeMenuChannelsIT::channellogoexists); + tokenContainer->DefineIntToken("{isAtsc}", (int)eLeMenuChannelsIT::isAtsc); + tokenContainer->DefineIntToken("{isCable}", (int)eLeMenuChannelsIT::isCable); + tokenContainer->DefineIntToken("{isSat}", (int)eLeMenuChannelsIT::isSat); + tokenContainer->DefineIntToken("{isTerr}", (int)eLeMenuChannelsIT::isTerr); + InheritTokenContainer(); +} + +void cLeMenuChannels::ClearCurrentElement(void) { + if (wasCurrent && currentChannel) { + currentChannel->Close(); + } +} + +void cLeMenuChannels::Set(const cChannel *channel, bool withProvider) { + dirty = true; + this->channel = channel; + this->withProvider = withProvider; +} + +bool cLeMenuChannels::Parse(bool forced) { + if (!dirty) + return false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::current, current); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::separator, !selectable); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::number, channel->Number()); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::transponder, channel->Transponder()); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::frequency, channel->Frequency()); + + tokenContainer->AddStringToken((int)eLeMenuChannelsST::name, channel->Name()); + cString channelID = channel->GetChannelID().ToString(); + tokenContainer->AddStringToken((int)eLeMenuChannelsST::channelid, *channelID); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::channellogoexists, imgCache->LogoExists(*channelID)); + + //Channel Source Information + const cSource *source = Sources.Get(channel->Source()); + if (source) { + tokenContainer->AddStringToken((int)eLeMenuChannelsST::source, *cSource::ToString(source->Code())); + tokenContainer->AddStringToken((int)eLeMenuChannelsST::sourcedescription, source->Description()); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::isAtsc, source->IsAtsc(source->Code())); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::isCable, source->IsCable(source->Code())); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::isSat, source->IsSat(source->Code())); + tokenContainer->AddIntToken((int)eLeMenuChannelsIT::isTerr, source->IsTerr(source->Code())); + } + + //current schedule + cSchedulesLock schedulesLock; + const cSchedules *schedules = cSchedules::Schedules(schedulesLock); + const cSchedule *schedule = NULL; + schedule = schedules->GetSchedule(channel); + if (schedule) { + const cEvent *presentEvent = schedule->GetPresentEvent(); + if (presentEvent) { + tokenContainer->AddStringToken((int)eLeMenuChannelsST::presenteventtitle, presentEvent->Title()); + tokenContainer->AddStringToken((int)eLeMenuChannelsST::presenteventstart, *presentEvent->GetTimeString()); + tokenContainer->AddStringToken((int)eLeMenuChannelsST::presenteventstop, *presentEvent->GetEndTimeString()); + } + } + return true; +} + +void cLeMenuChannels::RenderCurrent(void) { + if (!currentChannel) + return; + currentChannel->Set(channel, withProvider); + currentChannel->SetListPosition(container.X(), container.Y(), container.Width(), container.Height()); + currentChannel->Parse(); +} + +/****************************************************************** +* cCeMenuChannels +******************************************************************/ +cCeMenuChannels::cCeMenuChannels(void) { + schedulesIndex = -1; + channel = NULL; + withProvider = false; +} + +cCeMenuChannels::~cCeMenuChannels(void) { +} + +void cCeMenuChannels::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{name}", (int)eCeMenuChannelsST::name); + tokenContainer->DefineStringToken("{channelid}", (int)eCeMenuChannelsST::channelid); + tokenContainer->DefineStringToken("{source}", (int)eCeMenuChannelsST::source); + tokenContainer->DefineStringToken("{sourcedescription}", (int)eCeMenuChannelsST::sourcedescription); + tokenContainer->DefineStringToken("{position}", (int)eCeMenuChannelsST::position); + tokenContainer->DefineStringToken("{presenteventtitle}", (int)eCeMenuChannelsST::presenteventtitle); + tokenContainer->DefineStringToken("{presenteventstart}", (int)eCeMenuChannelsST::presenteventstart); + tokenContainer->DefineStringToken("{presenteventstop}", (int)eCeMenuChannelsST::presenteventstop); + tokenContainer->DefineStringToken("{presenteventshorttext}", (int)eCeMenuChannelsST::presenteventshorttext); + tokenContainer->DefineStringToken("{presenteventdescription}", (int)eCeMenuChannelsST::presenteventdescription); + tokenContainer->DefineStringToken("{presenteventday}", (int)eCeMenuChannelsST::presenteventday); + tokenContainer->DefineStringToken("{presenteventdate}", (int)eCeMenuChannelsST::presenteventdate); + tokenContainer->DefineStringToken("{presenteventdurationminutes}", (int)eCeMenuChannelsST::presenteventdurationminutes); + tokenContainer->DefineStringToken("{posterpath}", (int)eCeMenuChannelsST::posterpath); + tokenContainer->DefineStringToken("{nexteventtitle}", (int)eCeMenuChannelsST::nexteventtitle); + tokenContainer->DefineStringToken("{nexteventstart}", (int)eCeMenuChannelsST::nexteventstart); + tokenContainer->DefineStringToken("{nexteventstop}", (int)eCeMenuChannelsST::nexteventstop); + tokenContainer->DefineStringToken("{nexteventshorttext}", (int)eCeMenuChannelsST::nexteventshorttext); + tokenContainer->DefineStringToken("{nexteventdescription}", (int)eCeMenuChannelsST::nexteventdescription); + tokenContainer->DefineStringToken("{nexteventdurationminutes}", (int)eCeMenuChannelsST::nexteventdurationminutes); + tokenContainer->DefineStringToken("{nexteventday}", (int)eCeMenuChannelsST::nexteventday); + tokenContainer->DefineStringToken("{nexteventdate}", (int)eCeMenuChannelsST::nexteventdate); + tokenContainer->DefineIntToken("{menuitemx}", (int)eCeMenuChannelsIT::menuitemx); + tokenContainer->DefineIntToken("{menuitemy}", (int)eCeMenuChannelsIT::menuitemy); + tokenContainer->DefineIntToken("{menuitemwidth}", (int)eCeMenuChannelsIT::menuitemwidth); + tokenContainer->DefineIntToken("{menuitemheight}", (int)eCeMenuChannelsIT::menuitemheight); + tokenContainer->DefineIntToken("{number}", (int)eCeMenuChannelsIT::number); + tokenContainer->DefineIntToken("{transponder}", (int)eCeMenuChannelsIT::transponder); + tokenContainer->DefineIntToken("{frequency}", (int)eCeMenuChannelsIT::frequency); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eCeMenuChannelsIT::channellogoexists); + tokenContainer->DefineIntToken("{isAtsc}", (int)eCeMenuChannelsIT::isAtsc); + tokenContainer->DefineIntToken("{isCable}", (int)eCeMenuChannelsIT::isCable); + tokenContainer->DefineIntToken("{isSat}", (int)eCeMenuChannelsIT::isSat); + tokenContainer->DefineIntToken("{isTerr}", (int)eCeMenuChannelsIT::isTerr); + tokenContainer->DefineIntToken("{presenteventelapsed}", (int)eCeMenuChannelsIT::presenteventelapsed); + tokenContainer->DefineIntToken("{presenteventduration}", (int)eCeMenuChannelsIT::presenteventduration); + tokenContainer->DefineIntToken("{presenteventdurationhours}", (int)eCeMenuChannelsIT::presenteventdurationhours); + tokenContainer->DefineIntToken("{hasposter}", (int)eCeMenuChannelsIT::hasposter); + tokenContainer->DefineIntToken("{posterwidth}", (int)eCeMenuChannelsIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eCeMenuChannelsIT::posterheight); + tokenContainer->DefineIntToken("{nexteventduration}", (int)eCeMenuChannelsIT::nexteventduration); + tokenContainer->DefineIntToken("{nexteventdurationhours}", (int)eCeMenuChannelsIT::nexteventdurationhours); + tokenContainer->DefineLoopToken("{schedule[title]}", (int)eCeMenuChannelsLT::title); + tokenContainer->DefineLoopToken("{schedule[shorttext]}", (int)eCeMenuChannelsLT::shorttext); + tokenContainer->DefineLoopToken("{schedule[start]}", (int)eCeMenuChannelsLT::start); + tokenContainer->DefineLoopToken("{schedule[stop]}", (int)eCeMenuChannelsLT::stop); + schedulesIndex = tokenContainer->LoopIndex("schedule"); + InheritTokenContainer(); +} + +void cCeMenuChannels::Set(const cChannel *channel, bool withProvider) { + dirty = true; + this->channel = channel; + this->withProvider = withProvider; +} + +bool cCeMenuChannels::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + + tokenContainer->Clear(); + + SetListTokens(tokenContainer); + + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::number, channel->Number()); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::transponder, channel->Transponder()); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::frequency, channel->Frequency()); + + tokenContainer->AddStringToken((int)eCeMenuChannelsST::name, channel->Name()); + cString channelID = channel->GetChannelID().ToString(); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::channelid, *channelID); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::channellogoexists, imgCache->LogoExists(*channelID)); + + //Channel Source Information + const cSource *source = Sources.Get(channel->Source()); + if (source) { + tokenContainer->AddStringToken((int)eCeMenuChannelsST::source, *cSource::ToString(source->Code())); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::sourcedescription, source->Description()); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::isAtsc, source->IsAtsc(source->Code())); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::isCable, source->IsCable(source->Code())); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::isSat, source->IsSat(source->Code())); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::isTerr, source->IsTerr(source->Code())); + } + + cSchedulesLock schedulesLock; + const cSchedules *schedules = cSchedules::Schedules(schedulesLock); + const cSchedule *schedule = NULL; + schedule = schedules->GetSchedule(channel); + if (schedule) { + const cEvent *presentEvent = schedule->GetPresentEvent(); + if (presentEvent) { + tokenContainer->AddStringToken((int)eCeMenuChannelsST::presenteventtitle, presentEvent->Title()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::presenteventshorttext, presentEvent->ShortText()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::presenteventdescription, presentEvent->Description()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::presenteventstart, *presentEvent->GetTimeString()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::presenteventstop, *presentEvent->GetEndTimeString()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::presenteventday, *WeekDayName(presentEvent->StartTime())); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::presenteventdate, *ShortDateString(presentEvent->StartTime())); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::presenteventelapsed, (time(0) - presentEvent->StartTime())/60); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::presenteventduration, presentEvent->Duration() / 60); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::presenteventdurationhours, presentEvent->Duration() / 3600); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::presenteventdurationminutes, *cString::sprintf("%.2d", (presentEvent->Duration() / 60)%60)); + //SetScraperPoster(presentEvent); + } + const cList *events = schedule->Events(); + if (events && presentEvent) { + const cEvent *nextEvent = events->Next(presentEvent); + if (nextEvent) { + tokenContainer->AddStringToken((int)eCeMenuChannelsST::nexteventtitle, nextEvent->Title()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::nexteventshorttext, nextEvent->ShortText()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::nexteventdescription, nextEvent->Description()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::nexteventstart, *nextEvent->GetTimeString()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::nexteventstop, *nextEvent->GetEndTimeString()); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::nexteventday, *WeekDayName(nextEvent->StartTime())); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::nexteventdate, *ShortDateString(nextEvent->StartTime())); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::nexteventduration, nextEvent->Duration() / 60); + tokenContainer->AddIntToken((int)eCeMenuChannelsIT::nexteventdurationhours, nextEvent->Duration() / 3600); + tokenContainer->AddStringToken((int)eCeMenuChannelsST::nexteventdurationminutes, *cString::sprintf("%.2d", (nextEvent->Duration() / 60)%60)); + } + } + } + + vector loopInfo; + int eventsAvailable = 0; + if (schedule) { + for (const cEvent *e = schedule->GetPresentEvent(); e; e = schedule->Events()->Next(e)) { + eventsAvailable++; + if (eventsAvailable == 10) + break; + } + } + loopInfo.push_back(eventsAvailable); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + + if (schedule) { + int num = 0; + for (const cEvent *e = schedule->GetPresentEvent(); e; e = schedule->Events()->Next(e)) { + if (num < 2) { + num++; + continue; + } + tokenContainer->AddLoopToken(schedulesIndex, num-2, (int)eCeMenuChannelsLT::title, e->Title()); + tokenContainer->AddLoopToken(schedulesIndex, num-2, (int)eCeMenuChannelsLT::shorttext, e->ShortText()); + tokenContainer->AddLoopToken(schedulesIndex, num-2, (int)eCeMenuChannelsLT::start, *(e->GetTimeString())); + tokenContainer->AddLoopToken(schedulesIndex, num-2, (int)eCeMenuChannelsLT::stop, *(e->GetEndTimeString())); + num++; + if (num > 11) + break; + } + } + return true; +} + +/****************************************************************** +* cLeMenuTimers +******************************************************************/ +cLeMenuTimers::cLeMenuTimers(void) { + currentTimer = NULL; + timer = NULL; +} + +cLeMenuTimers::~cLeMenuTimers(void) { +} + +void cLeMenuTimers::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{title}", (int)eLeMenuTimersST::title); + tokenContainer->DefineStringToken("{timerstart}", (int)eLeMenuTimersST::timerstart); + tokenContainer->DefineStringToken("{timerstop}", (int)eLeMenuTimersST::timerstop); + tokenContainer->DefineStringToken("{day}", (int)eLeMenuTimersST::day); + tokenContainer->DefineStringToken("{dayname}", (int)eLeMenuTimersST::dayname); + tokenContainer->DefineStringToken("{monthname}", (int)eLeMenuTimersST::monthname); + tokenContainer->DefineStringToken("{channelname}", (int)eLeMenuTimersST::channelname); + tokenContainer->DefineStringToken("{channelid}", (int)eLeMenuTimersST::channelid); + tokenContainer->DefineStringToken("{eventtitle}", (int)eLeMenuTimersST::eventtitle); + tokenContainer->DefineStringToken("{eventstart}", (int)eLeMenuTimersST::eventstart); + tokenContainer->DefineStringToken("{eventstop}", (int)eLeMenuTimersST::eventstop); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeMenuTimersIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeMenuTimersIT::current); + tokenContainer->DefineIntToken("{separator}", (int)eLeMenuTimersIT::separator); + tokenContainer->DefineIntToken("{month}", (int)eLeMenuTimersIT::month); + tokenContainer->DefineIntToken("{year}", (int)eLeMenuTimersIT::year); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eLeMenuTimersIT::channellogoexists); + tokenContainer->DefineIntToken("{channelnumber}", (int)eLeMenuTimersIT::channelnumber); + tokenContainer->DefineIntToken("{flagactive}", (int)eLeMenuTimersIT::flagactive); + tokenContainer->DefineIntToken("{flaginstant}", (int)eLeMenuTimersIT::flaginstant); + tokenContainer->DefineIntToken("{flagvps}", (int)eLeMenuTimersIT::flagvps); + tokenContainer->DefineIntToken("{flagrecording}", (int)eLeMenuTimersIT::flagrecording); + tokenContainer->DefineIntToken("{flagpending}", (int)eLeMenuTimersIT::flagpending); + InheritTokenContainer(); +} + +void cLeMenuTimers::ClearCurrentElement(void) { + if (wasCurrent && currentTimer) { + currentTimer->Close(); + } +} + +void cLeMenuTimers::Set(const cTimer *timer) { + this->timer = timer; + dirty = true; +} + +bool cLeMenuTimers::Parse(bool forced) { + if (!dirty) + return false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::current, current); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::separator, !selectable); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::flagactive, timer->HasFlags(tfActive)); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::flaginstant, timer->HasFlags(tfInstant)); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::flagvps, timer->HasFlags(tfVps)); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::flagrecording, timer->Recording()); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::flagpending, timer->Pending()); + + const char *file = Setup.FoldersInTimerMenu ? NULL : strrchr(timer->File(), FOLDERDELIMCHAR); + if (file && strcmp(file + 1, TIMERMACRO_TITLE) && strcmp(file + 1, TIMERMACRO_EPISODE)) + file++; + else + file = timer->File(); + tokenContainer->AddStringToken((int)eLeMenuTimersST::title, file); + tokenContainer->AddStringToken((int)eLeMenuTimersST::timerstart, *cString::sprintf("%02d:%02d", timer->Start() / 100, timer->Start() % 100)); + tokenContainer->AddStringToken((int)eLeMenuTimersST::timerstop, *cString::sprintf("%02d:%02d", timer->Stop() / 100, timer->Stop() % 100)); + + cString day(""); + cString dayName(""); + if (timer->WeekDays()) + day = timer->PrintDay(0, timer->WeekDays(), false); + else if (timer->Day() - time(NULL) < 28 * SECSINDAY) { + day = itoa(timer->GetMDay(timer->Day())); + dayName = WeekDayName(timer->Day()); + } else { + struct tm tm_r; + time_t Day = timer->Day(); + localtime_r(&Day, &tm_r); + char buffer[16]; + strftime(buffer, sizeof(buffer), "%Y%m%d", &tm_r); + day = buffer; + } + + struct tm tm_r; + time_t timerDate = timer->Day(); + localtime_r(&timerDate, &tm_r); + char buffer[4]; + strftime(buffer, sizeof(buffer), "%m", &tm_r); + int month = atoi(buffer); + char buffer2[6]; + strftime(buffer2, sizeof(buffer2), "%b", &tm_r); + char buffer3[6]; + strftime(buffer3, sizeof(buffer3), "%Y", &tm_r); + int year = atoi(buffer3); + + tokenContainer->AddStringToken((int)eLeMenuTimersST::day, *day); + tokenContainer->AddStringToken((int)eLeMenuTimersST::dayname, *dayName); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::month, month); + tokenContainer->AddStringToken((int)eLeMenuTimersST::monthname, buffer2); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::year, year); + + const cChannel *channel = timer->Channel(); + if (channel) { + tokenContainer->AddStringToken((int)eLeMenuTimersST::channelname, channel->Name()); + cString channelID = channel->GetChannelID().ToString(); + tokenContainer->AddStringToken((int)eLeMenuTimersST::channelid, *channelID); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::channellogoexists, imgCache->LogoExists(*channelID)); + tokenContainer->AddIntToken((int)eLeMenuTimersIT::channelnumber, channel->Number()); + } + + const cEvent *event = timer->Event(); + if (event) { + tokenContainer->AddStringToken((int)eLeMenuTimersST::eventtitle, event->Title()); + tokenContainer->AddStringToken((int)eLeMenuTimersST::eventstart, *event->GetTimeString()); + tokenContainer->AddStringToken((int)eLeMenuTimersST::eventstop, *event->GetEndTimeString()); + } + return true; +} + +void cLeMenuTimers::RenderCurrent(void) { + if (!currentTimer) + return; + currentTimer->Set(timer); + currentTimer->SetListPosition(container.X(), container.Y(), container.Width(), container.Height()); + currentTimer->Parse(); +} + +/****************************************************************** +* cCeMenuTimers +******************************************************************/ +cCeMenuTimers::cCeMenuTimers(void) { + timer = NULL; +} + +cCeMenuTimers::~cCeMenuTimers(void) { + +} + +void cCeMenuTimers::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{title}", (int)eCeMenuTimersST::title); + tokenContainer->DefineStringToken("{timerstart}", (int)eCeMenuTimersST::timerstart); + tokenContainer->DefineStringToken("{timerstop}", (int)eCeMenuTimersST::timerstop); + tokenContainer->DefineStringToken("{day}", (int)eCeMenuTimersST::day); + tokenContainer->DefineStringToken("{dayname}", (int)eCeMenuTimersST::dayname); + tokenContainer->DefineStringToken("{monthname}", (int)eCeMenuTimersST::monthname); + tokenContainer->DefineStringToken("{channelname}", (int)eCeMenuTimersST::channelname); + tokenContainer->DefineStringToken("{channelid}", (int)eCeMenuTimersST::channelid); + tokenContainer->DefineStringToken("{eventtitle}", (int)eCeMenuTimersST::eventtitle); + tokenContainer->DefineStringToken("{eventstart}", (int)eCeMenuTimersST::eventstart); + tokenContainer->DefineStringToken("{eventstop}", (int)eCeMenuTimersST::eventstop); + tokenContainer->DefineStringToken("{eventshorttext}", (int)eCeMenuTimersST::eventshorttext); + tokenContainer->DefineStringToken("{eventdescription}", (int)eCeMenuTimersST::eventdescription); + tokenContainer->DefineStringToken("{posterpath}", (int)eCeMenuTimersST::posterpath); + tokenContainer->DefineIntToken("{menuitemx}", (int)eCeMenuTimersIT::menuitemx); + tokenContainer->DefineIntToken("{menuitemy}", (int)eCeMenuTimersIT::menuitemy); + tokenContainer->DefineIntToken("{menuitemwidth}", (int)eCeMenuTimersIT::menuitemwidth); + tokenContainer->DefineIntToken("{menuitemheight}", (int)eCeMenuTimersIT::menuitemheight); + tokenContainer->DefineIntToken("{month}", (int)eCeMenuTimersIT::month); + tokenContainer->DefineIntToken("{year}", (int)eCeMenuTimersIT::year); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eCeMenuTimersIT::channellogoexists); + tokenContainer->DefineIntToken("{channelnumber}", (int)eCeMenuTimersIT::channelnumber); + tokenContainer->DefineIntToken("{flagactive}", (int)eCeMenuTimersIT::flagactive); + tokenContainer->DefineIntToken("{flaginstant}", (int)eCeMenuTimersIT::flaginstant); + tokenContainer->DefineIntToken("{flagvps}", (int)eCeMenuTimersIT::flagvps); + tokenContainer->DefineIntToken("{flagrecording}", (int)eCeMenuTimersIT::flagrecording); + tokenContainer->DefineIntToken("{flagpending}", (int)eCeMenuTimersIT::flagpending); + tokenContainer->DefineIntToken("{hasposter}", (int)eCeMenuTimersIT::hasposter); + tokenContainer->DefineIntToken("{posterwidth}", (int)eCeMenuTimersIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eCeMenuTimersIT::posterheight); + InheritTokenContainer(); +} + +void cCeMenuTimers::Set(const cTimer *timer) { + dirty = true; + this->timer = timer; +} + +bool cCeMenuTimers::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + + tokenContainer->Clear(); + + SetListTokens(tokenContainer); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::flagactive, timer->HasFlags(tfActive)); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::flaginstant, timer->HasFlags(tfInstant)); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::flagvps, timer->HasFlags(tfVps)); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::flagrecording, timer->Recording()); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::flagpending, timer->Pending()); + + const char *file = Setup.FoldersInTimerMenu ? NULL : strrchr(timer->File(), FOLDERDELIMCHAR); + if (file && strcmp(file + 1, TIMERMACRO_TITLE) && strcmp(file + 1, TIMERMACRO_EPISODE)) + file++; + else + file = timer->File(); + tokenContainer->AddStringToken((int)eCeMenuTimersST::title, file); + tokenContainer->AddStringToken((int)eCeMenuTimersST::timerstart, *cString::sprintf("%02d:%02d", timer->Start() / 100, timer->Start() % 100)); + tokenContainer->AddStringToken((int)eCeMenuTimersST::timerstop, *cString::sprintf("%02d:%02d", timer->Stop() / 100, timer->Stop() % 100)); + + cString day(""); + cString dayName(""); + if (timer->WeekDays()) + day = timer->PrintDay(0, timer->WeekDays(), false); + else if (timer->Day() - time(NULL) < 28 * SECSINDAY) { + day = itoa(timer->GetMDay(timer->Day())); + dayName = WeekDayName(timer->Day()); + } else { + struct tm tm_r; + time_t Day = timer->Day(); + localtime_r(&Day, &tm_r); + char buffer[16]; + strftime(buffer, sizeof(buffer), "%Y%m%d", &tm_r); + day = buffer; + } + + struct tm tm_r; + time_t timerDate = timer->Day(); + localtime_r(&timerDate, &tm_r); + char buffer[4]; + strftime(buffer, sizeof(buffer), "%m", &tm_r); + int month = atoi(buffer); + char buffer2[6]; + strftime(buffer2, sizeof(buffer2), "%b", &tm_r); + char buffer3[6]; + strftime(buffer3, sizeof(buffer3), "%Y", &tm_r); + int year = atoi(buffer3); + + tokenContainer->AddStringToken((int)eCeMenuTimersST::day, *day); + tokenContainer->AddStringToken((int)eCeMenuTimersST::dayname, *dayName); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::month, month); + tokenContainer->AddStringToken((int)eCeMenuTimersST::monthname, buffer2); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::year, year); + + const cChannel *channel = timer->Channel(); + if (channel) { + tokenContainer->AddStringToken((int)eCeMenuTimersST::channelname, channel->Name()); + cString channelID = channel->GetChannelID().ToString(); + tokenContainer->AddStringToken((int)eCeMenuTimersST::channelid, *channelID); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::channellogoexists, imgCache->LogoExists(*channelID)); + tokenContainer->AddIntToken((int)eCeMenuTimersIT::channelnumber, channel->Number()); + } + + const cEvent *event = timer->Event(); + if (event) { + tokenContainer->AddStringToken((int)eCeMenuTimersST::eventtitle, event->Title()); + tokenContainer->AddStringToken((int)eCeMenuTimersST::eventstart, *event->GetTimeString()); + tokenContainer->AddStringToken((int)eCeMenuTimersST::eventstop, *event->GetEndTimeString()); + tokenContainer->AddStringToken((int)eCeMenuTimersST::eventshorttext, event->ShortText()); + tokenContainer->AddStringToken((int)eCeMenuTimersST::eventdescription, event->Description()); + } + return true; +} + +/****************************************************************** +* cLeMenuRecordings +******************************************************************/ +cLeMenuRecordings::cLeMenuRecordings(void) { + currentRecording = NULL; + recording = NULL; + level = 0; + total = 0; + New = 0; +} + +cLeMenuRecordings::~cLeMenuRecordings(void) { +} + +void cLeMenuRecordings::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{name}", (int)eLeMenuRecordingsST::name); + tokenContainer->DefineStringToken("{epgname}", (int)eLeMenuRecordingsST::epgname); + tokenContainer->DefineStringToken("{shorttext}", (int)eLeMenuRecordingsST::shorttext); + tokenContainer->DefineStringToken("{description}", (int)eLeMenuRecordingsST::description); + tokenContainer->DefineStringToken("{date}", (int)eLeMenuRecordingsST::date); + tokenContainer->DefineStringToken("{time}", (int)eLeMenuRecordingsST::time); + tokenContainer->DefineStringToken("{durationminutes}", (int)eLeMenuRecordingsST::durationminutes); + tokenContainer->DefineStringToken("{durationeventminutes}", (int)eLeMenuRecordingsST::durationeventminutes); + tokenContainer->DefineStringToken("{thumbnailpath}", (int)eLeMenuRecordingsST::thumbnailpath); + tokenContainer->DefineStringToken("{posterpath}", (int)eLeMenuRecordingsST::posterpath); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeMenuRecordingsIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeMenuRecordingsIT::current); + tokenContainer->DefineIntToken("{new}", (int)eLeMenuRecordingsIT::isnew); + tokenContainer->DefineIntToken("{percentseen}", (int)eLeMenuRecordingsIT::percentseen); + tokenContainer->DefineIntToken("{watched}", (int)eLeMenuRecordingsIT::watched); + tokenContainer->DefineIntToken("{cutted}", (int)eLeMenuRecordingsIT::cutted); + tokenContainer->DefineIntToken("{folder}", (int)eLeMenuRecordingsIT::folder); + tokenContainer->DefineIntToken("{daynumeric}", (int)eLeMenuRecordingsIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eLeMenuRecordingsIT::month); + tokenContainer->DefineIntToken("{year}", (int)eLeMenuRecordingsIT::year); + tokenContainer->DefineIntToken("{duration}", (int)eLeMenuRecordingsIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eLeMenuRecordingsIT::durationhours); + tokenContainer->DefineIntToken("{durationevent}", (int)eLeMenuRecordingsIT::durationevent); + tokenContainer->DefineIntToken("{durationeventhours}", (int)eLeMenuRecordingsIT::durationeventhours); + tokenContainer->DefineIntToken("{numrecordingsfolder}", (int)eLeMenuRecordingsIT::numrecordingsfolder); + tokenContainer->DefineIntToken("{newrecordingsfolder}", (int)eLeMenuRecordingsIT::newrecordingsfolder); + tokenContainer->DefineIntToken("{hasposterthumbnail}", (int)eLeMenuRecordingsIT::hasposterthumbnail); + tokenContainer->DefineIntToken("{thumbnailwidth}", (int)eLeMenuRecordingsIT::thumbnailwidth); + tokenContainer->DefineIntToken("{thumbnailheight}", (int)eLeMenuRecordingsIT::thumbnailheight); + tokenContainer->DefineIntToken("{hasposter}", (int)eLeMenuRecordingsIT::hasposter); + tokenContainer->DefineIntToken("{posterwidth}", (int)eLeMenuRecordingsIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eLeMenuRecordingsIT::posterheight); + InheritTokenContainer(); +} + +void cLeMenuRecordings::ClearCurrentElement(void) { + if (wasCurrent && currentRecording) { + currentRecording->Close(); + } +} + +void cLeMenuRecordings::Set(const cRecording *recording, int level, int total, int New) { + this->recording = recording; + this->level = level; + this->total = total; + this->New = New; + dirty = true; +} + +bool cLeMenuRecordings::Parse(bool forced) { + if (!dirty) + return false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::current, current); + bool isFolder = (total > 0) ? true : false; + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::folder, isFolder); + + char *recName = RecName(recording->Name(), level); + tokenContainer->AddStringToken((int)eLeMenuRecordingsST::name, recName); + delete[] recName; + + const cRecording *usedRecording = recording; + + if (isFolder) { + char *folderName = FolderName(recording->Name(), level); + cRecordingsFolderInfo::cFolderInfo *folderInfo = recFolderInfo.Get(folderName); + delete[] folderName; + if (folderInfo) { + cRecording *newestRec = Recordings.GetByName(*folderInfo->LatestFileName); + if (newestRec) { + usedRecording = newestRec; + } + delete folderInfo; + } + } + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::isnew, usedRecording->IsNew()); + + int percSeen = 0; +#if APIVERSNUM < 20108 + percSeen = -1; +#else + percSeen = 0; + int framesSeen = usedRecording->GetResume(); + int framesTotal = usedRecording->NumFrames(); + if (framesTotal > 0) { + percSeen = (double)framesSeen / (double)framesTotal * 100; + } +#endif + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::percentseen, percSeen); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::newrecordingsfolder, New); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::numrecordingsfolder, total); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::cutted, usedRecording->IsEdited()); + + int recDuration = usedRecording->LengthInSeconds(); + bool watched = false; + if (usedRecording->IsEdited()) { + if (percSeen >= 85) + watched = true; + } else { + int watchedLimit = recDuration * 85 / 100 - (Setup.MarginStop + 5)*60; + int watchedTime = percSeen * recDuration / 100; + if (watchedLimit > 0 && watchedTime > 0 && (watchedTime > watchedLimit)) + watched = true; + } + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::watched, watched); + + const cEvent *event = NULL; + const cRecordingInfo *info = usedRecording->Info(); + if (!info) return true; + event = info->GetEvent(); + if (!event) return true; + + cString recDate = event->GetDateString(); + cString recTime = event->GetTimeString(); + if (strstr(*recDate, "1970")) { + time_t start = usedRecording->Start(); + recDate = DateString(start); + recTime = TimeString(start); + } + + time_t startTime = event->StartTime(); + if (!startTime) + startTime = usedRecording->Start(); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::month, sStartTime->tm_mon+1); + + int duration = event->Duration() / 60; + recDuration = (recDuration>0)?(recDuration / 60):0; + tokenContainer->AddStringToken((int)eLeMenuRecordingsST::date, *recDate); + tokenContainer->AddStringToken((int)eLeMenuRecordingsST::time, *recTime); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::duration, recDuration); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::durationhours, recDuration / 60); + tokenContainer->AddStringToken((int)eLeMenuRecordingsST::durationminutes, *cString::sprintf("%.2d", recDuration%60)); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::durationevent, duration); + tokenContainer->AddIntToken((int)eLeMenuRecordingsIT::durationeventhours, duration / 60); + tokenContainer->AddStringToken((int)eLeMenuRecordingsST::durationeventminutes, *cString::sprintf("%.2d", duration%60)); + + tokenContainer->AddStringToken((int)eLeMenuRecordingsST::shorttext, info->ShortText()); + tokenContainer->AddStringToken((int)eLeMenuRecordingsST::description, info->Description()); + + SetScraperRecordingPoster(tokenContainer, usedRecording, true); + + return true; +} + +void cLeMenuRecordings::RenderCurrent(void) { + if (!currentRecording) + return; + currentRecording->Set(recording, level, total, New); + currentRecording->SetListPosition(container.X(), container.Y(), container.Width(), container.Height()); + currentRecording->Parse(); +} + +char *cLeMenuRecordings::RecName(const char *path, int level) { + char *recName; + const char *startName = path; + for (int i = 0; i < level; i++) { + startName = strchr(startName, FOLDERDELIMCHAR); + startName++; + } + const char *endName = startName; + if (endName = strchr(endName, FOLDERDELIMCHAR)) { + int len = endName - startName; + recName = new char[len+1]; + strncpy(recName, startName, len); + recName[len] = 0; + } else { + recName = strdup(startName); + } + return recName; +} + +char *cLeMenuRecordings::FolderName(const char *path, int level) { + char *folderName; + const char *endName = path; + bool foundEnd = false; + for (int i = 0; i <= level; i++) { + endName = strchr(endName, FOLDERDELIMCHAR); + if (!endName) { + foundEnd = false; + } + foundEnd = true; + endName++; + } + if (foundEnd) { + int len = endName - path - 1; + folderName = new char[len+1]; + strncpy(folderName, path, len); + folderName[len] = 0; + } else { + folderName = strdup(path); + } + return folderName; +} + +/****************************************************************** +* cCeMenuRecordings +******************************************************************/ +cCeMenuRecordings::cCeMenuRecordings(void) { + recording = NULL; + level = 0; + total = 0; + New = 0; +} + +cCeMenuRecordings::~cCeMenuRecordings(void) { +} + +void cCeMenuRecordings::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{name}", (int)eCeMenuRecordingsST::name); + tokenContainer->DefineStringToken("{epgname}", (int)eCeMenuRecordingsST::epgname); + tokenContainer->DefineStringToken("{shorttext}", (int)eCeMenuRecordingsST::shorttext); + tokenContainer->DefineStringToken("{description}", (int)eCeMenuRecordingsST::description); + tokenContainer->DefineStringToken("{date}", (int)eCeMenuRecordingsST::date); + tokenContainer->DefineStringToken("{time}", (int)eCeMenuRecordingsST::time); + tokenContainer->DefineStringToken("{durationminutes}", (int)eCeMenuRecordingsST::durationminutes); + tokenContainer->DefineStringToken("{durationeventminutes}", (int)eCeMenuRecordingsST::durationeventminutes); + tokenContainer->DefineStringToken("{thumbnailpath}", (int)eCeMenuRecordingsST::thumbnailpath); + tokenContainer->DefineStringToken("{posterpath}", (int)eCeMenuRecordingsST::posterpath); + tokenContainer->DefineIntToken("{menuitemx}", (int)eCeMenuRecordingsIT::menuitemx); + tokenContainer->DefineIntToken("{menuitemy}", (int)eCeMenuRecordingsIT::menuitemy); + tokenContainer->DefineIntToken("{menuitemwidth}", (int)eCeMenuRecordingsIT::menuitemwidth); + tokenContainer->DefineIntToken("{menuitemheight}", (int)eCeMenuRecordingsIT::menuitemheight); + tokenContainer->DefineIntToken("{new}", (int)eCeMenuRecordingsIT::isnew); + tokenContainer->DefineIntToken("{percentseen}", (int)eCeMenuRecordingsIT::percentseen); + tokenContainer->DefineIntToken("{watched}", (int)eCeMenuRecordingsIT::watched); + tokenContainer->DefineIntToken("{cutted}", (int)eCeMenuRecordingsIT::cutted); + tokenContainer->DefineIntToken("{folder}", (int)eCeMenuRecordingsIT::folder); + tokenContainer->DefineIntToken("{daynumeric}", (int)eCeMenuRecordingsIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eCeMenuRecordingsIT::month); + tokenContainer->DefineIntToken("{year}", (int)eCeMenuRecordingsIT::year); + tokenContainer->DefineIntToken("{duration}", (int)eCeMenuRecordingsIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eCeMenuRecordingsIT::durationhours); + tokenContainer->DefineIntToken("{durationevent}", (int)eCeMenuRecordingsIT::durationevent); + tokenContainer->DefineIntToken("{durationeventhours}", (int)eCeMenuRecordingsIT::durationeventhours); + tokenContainer->DefineIntToken("{numrecordingsfolder}", (int)eCeMenuRecordingsIT::numrecordingsfolder); + tokenContainer->DefineIntToken("{newrecordingsfolder}", (int)eCeMenuRecordingsIT::newrecordingsfolder); + tokenContainer->DefineIntToken("{hasposterthumbnail}", (int)eCeMenuRecordingsIT::hasposterthumbnail); + tokenContainer->DefineIntToken("{thumbnailwidth}", (int)eCeMenuRecordingsIT::thumbnailwidth); + tokenContainer->DefineIntToken("{thumbnailheight}", (int)eCeMenuRecordingsIT::thumbnailheight); + tokenContainer->DefineIntToken("{hasposter}", (int)eCeMenuRecordingsIT::hasposter); + tokenContainer->DefineIntToken("{posterwidth}", (int)eCeMenuRecordingsIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eCeMenuRecordingsIT::posterheight); + InheritTokenContainer(); +} + +void cCeMenuRecordings::Set(const cRecording *recording, int level, int total, int New) { + this->recording = recording; + this->level = level; + this->total = total; + this->New = New; + dirty = true; +} + +bool cCeMenuRecordings::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + + tokenContainer->Clear(); + SetListTokens(tokenContainer); + bool isFolder = (total > 0) ? true : false; + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::folder, isFolder); + + string name = recording->Name() ? recording->Name() : ""; + string buffer = ""; + stringstream folderName; + try { + vector tokens; + istringstream f(name.c_str()); + string s; + int i=0; + while (getline(f, s, FOLDERDELIMCHAR)) { + tokens.push_back(s); + if (isFolder && i <= level) { + if (i > 0) + folderName << FOLDERDELIMCHAR; + folderName << s; + i++; + } + } + buffer = tokens.at(level); + if (!isFolder && recording->IsEdited()) { + buffer = buffer.substr(1); + } + } catch (...) { + buffer = name.c_str(); + } + + const cRecording *usedRecording = recording; + + if (isFolder) { + cRecordingsFolderInfo::cFolderInfo *folderInfo = recFolderInfo.Get(folderName.str().c_str()); + if (folderInfo) { + cRecording *newestRec = Recordings.GetByName(*folderInfo->LatestFileName); + if (newestRec) { + usedRecording = newestRec; + } + delete folderInfo; + } + } + + tokenContainer->AddStringToken((int)eCeMenuRecordingsST::name, buffer.c_str()); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::isnew, usedRecording->IsNew()); + + int percSeen = 0; +#if APIVERSNUM < 20108 + percSeen = -1; +#else + percSeen = 0; + int framesSeen = usedRecording->GetResume(); + int framesTotal = usedRecording->NumFrames(); + if (framesTotal > 0) { + percSeen = (double)framesSeen / (double)framesTotal * 100; + } +#endif + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::percentseen, percSeen); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::newrecordingsfolder, New); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::numrecordingsfolder, total); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::cutted, usedRecording->IsEdited()); + + int recDuration = usedRecording->LengthInSeconds(); + bool watched = false; + if (usedRecording->IsEdited()) { + if (percSeen >= 85) + watched = true; + } else { + int watchedLimit = recDuration * 85 / 100 - (Setup.MarginStop + 5)*60; + int watchedTime = percSeen * recDuration / 100; + if (watchedLimit > 0 && watchedTime > 0 && (watchedTime > watchedLimit)) + watched = true; + } + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::watched, watched); + + const cEvent *event = NULL; + const cRecordingInfo *info = usedRecording->Info(); + if (!info) return true; + event = info->GetEvent(); + if (!event) return true; + + cString recDate = event->GetDateString(); + cString recTime = event->GetTimeString(); + if (strstr(*recDate, "1970")) { + time_t start = usedRecording->Start(); + recDate = DateString(start); + recTime = TimeString(start); + } + + time_t startTime = event->StartTime(); + if (!startTime) + startTime = usedRecording->Start(); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::month, sStartTime->tm_mon+1); + + int duration = event->Duration() / 60; + recDuration = (recDuration>0)?(recDuration / 60):0; + tokenContainer->AddStringToken((int)eCeMenuRecordingsST::date, *recDate); + tokenContainer->AddStringToken((int)eCeMenuRecordingsST::time, *recTime); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::duration, recDuration); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::durationhours, recDuration / 60); + tokenContainer->AddStringToken((int)eCeMenuRecordingsST::durationminutes, *cString::sprintf("%.2d", recDuration%60)); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::durationevent, duration); + tokenContainer->AddIntToken((int)eCeMenuRecordingsIT::durationeventhours, duration / 60); + tokenContainer->AddStringToken((int)eCeMenuRecordingsST::durationeventminutes, *cString::sprintf("%.2d", duration%60)); + + tokenContainer->AddStringToken((int)eCeMenuRecordingsST::shorttext, info->ShortText()); + tokenContainer->AddStringToken((int)eCeMenuRecordingsST::description, info->Description()); + + SetScraperRecordingPoster(tokenContainer, usedRecording, false); + + return true; +} + +/****************************************************************** +* cLeMenuPlugin +******************************************************************/ +cLeMenuPlugin::cLeMenuPlugin(void) { + currentPlugin = NULL; + plugId = -1; + plugMenuId = -1; +} + +cLeMenuPlugin::~cLeMenuPlugin(void) { +} + +void cLeMenuPlugin::SetTokenContainer(void) { + if (plugId == -1 || plugMenuId == -1) + return; + skindesignerapi::cTokenContainer *tkPlugMenu = plgManager->GetTokenContainer(plugId, plugMenuId); + tokenContainer = new skindesignerapi::cTokenContainer(*tkPlugMenu); + InheritTokenContainer(); +} + +void cLeMenuPlugin::ClearCurrentElement(void) { + if (wasCurrent && currentPlugin) { + currentPlugin->Close(); + } +} + +void cLeMenuPlugin::Set(skindesignerapi::cTokenContainer *tk) { + tokenContainer->Clear(); + tokenContainer->SetTokens(tk); + dirty = true; +} + +bool cLeMenuPlugin::Parse(bool forced) { + if (!dirty) + return false; + tokenContainer->AddIntToken(0, current); + return true; +} + +void cLeMenuPlugin::RenderCurrent(void) { + if (!currentPlugin) + return; + currentPlugin->Set(tokenContainer); + currentPlugin->SetListPosition(container.X(), container.Y(), container.Width(), container.Height()); + currentPlugin->Parse(); +} + +/****************************************************************** +* cCeMenuPlugin +******************************************************************/ +cCeMenuPlugin::cCeMenuPlugin(void) { + plugId = -1; + plugMenuId = -1; +} + +cCeMenuPlugin::~cCeMenuPlugin(void) { +} + +void cCeMenuPlugin::SetTokenContainer(void) { + if (plugId == -1 || plugMenuId == -1) + return; + skindesignerapi::cTokenContainer *tkPlugMenu = plgManager->GetTokenContainer(plugId, plugMenuId); + tokenContainer = new skindesignerapi::cTokenContainer(*tkPlugMenu); + InheritTokenContainer(); +} + +void cCeMenuPlugin::Set(skindesignerapi::cTokenContainer *tk) { + tokenContainer->Clear(); + tokenContainer->SetTokens(tk); + dirty = true; +} + +bool cCeMenuPlugin::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + return true; +} + +/****************************************************************** +* cLeAudioTracks +******************************************************************/ +cLeAudioTracks::cLeAudioTracks(void) { + text = NULL; +} + +cLeAudioTracks::~cLeAudioTracks(void) { + free(text); +} + +void cLeAudioTracks::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{title}", (int)eLeDisplayTracksST::title); + tokenContainer->DefineIntToken("{nummenuitem}", (int)eLeDisplayTracksIT::nummenuitem); + tokenContainer->DefineIntToken("{current}", (int)eLeDisplayTracksIT::current); + InheritTokenContainer(); +} + +void cLeAudioTracks::Set(const char *text) { + if (!text) + return; + free(this->text); + this->text = strdup(text); + dirty = true; +} + +bool cLeAudioTracks::Parse(bool forced) { + if (!dirty) + return false; + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eLeDisplayTracksIT::nummenuitem, num); + tokenContainer->AddIntToken((int)eLeDisplayTracksIT::current, current); + tokenContainer->AddStringToken((int)eLeDisplayTracksST::title, text); + return true; +} \ No newline at end of file diff --git a/coreengine/listelements.h b/coreengine/listelements.h new file mode 100644 index 0000000..9fc0b27 --- /dev/null +++ b/coreengine/listelements.h @@ -0,0 +1,337 @@ +#ifndef __LISTELEMENTS_H +#define __LISTELEMENTS_H + +#include "viewelement.h" +#include "../extensions/scrapmanager.h" + +#define MAX_TABS 6 +/****************************************************************** +* cListElement +******************************************************************/ +class cListElement : public cViewElement { +protected: + eMenuCategory menuCat; + int num; + bool current; + bool wasCurrent; + bool selectable; + cViewElement *currentElement; + char *ParseSeparator(const char *text); +public: + cListElement(void); + cListElement(const cListElement &other); + virtual ~cListElement(void) {}; + void SetMenuCategory(eMenuCategory menuCat) { this->menuCat = menuCat; }; + void SetNumber(int number) { num = number; }; + void SetCurrent(bool cur); + bool Current(void) { return current; }; + void WakeCurrent(void); + void SetSelectable(bool sel) { selectable = sel; }; + bool DoScroll(void) { return current; }; + virtual void RenderCurrent(void) { }; + void Close(void); + void Clear(void); +}; + +/****************************************************************** +* cCurrentElement +******************************************************************/ +class cCurrentElement : public cViewElement { +protected: + int listX; + int listY; + int listWidth; + int listHeight; +public: + cCurrentElement(void); + virtual ~cCurrentElement(void) {}; + void SetListPosition(int x, int y, int width, int height); + void SetListTokens(skindesignerapi::cTokenContainer *tokenContainer); +}; + +/****************************************************************** +* cLeMenuDefault +******************************************************************/ +class cLeMenuDefault : public cListElement { +private: + char *text; + int *colX; + int *colWidths; + const char *plugName; + const char *GetTabbedText(const char *s, int tab); + void SetMenuCategory(void); + void CheckProgressBar(const char *text, int tab); +public: + cLeMenuDefault(void); + cLeMenuDefault(const cLeMenuDefault &other); + virtual ~cLeMenuDefault(void); + void SetListInfo(int *colX, int *colWidths); + void SetText(const char *text); + void SetPlugin(const char *plugName) { this->plugName = plugName; }; + void SetTokenContainer(void); + bool Parse(bool forced = true); +}; + +/****************************************************************** +* cVeMenuMain +******************************************************************/ +class cVeMenuMain { +protected: + char *text; + char *number; + char *label; + void SplitText(void); +public: + cVeMenuMain(void); + virtual ~cVeMenuMain(void); + void SetText(const char *text); +}; + +/****************************************************************** +* cLeMenuMain +******************************************************************/ +class cCeMenuMain; +class cLeMenuMain : public cListElement, public cVeMenuMain { +private: + cCeMenuMain *currentMain; +public: + cLeMenuMain(void); + cLeMenuMain(const cLeMenuMain &other); + virtual ~cLeMenuMain(void); + void SetTokenContainer(void); + void SetCurrentElement(cCeMenuMain *cur) { currentMain = cur; currentElement = (cViewElement*)cur; }; + void ClearCurrentElement(void); + void SetText(const char *text); + bool Parse(bool forced = true); + void RenderCurrent(void); + const char *PluginName(void); +}; + +/****************************************************************** +* cCeMenuMain +******************************************************************/ +class cCeMenuMain : public cCurrentElement, public cVeMenuMain { +private: +public: + cCeMenuMain(void); + virtual ~cCeMenuMain(void); + void SetTokenContainer(void); + void SetText(const char *text); + bool Parse(bool forced = true); +}; + +/****************************************************************** +* cVeMenuSchedules +******************************************************************/ +class cVeMenuSchedules { +protected: + const cEvent *event; + const cChannel *channel; + bool withDate; + eTimerMatch timerMatch; + bool epgSearchFav; +public: + cVeMenuSchedules(void); + virtual ~cVeMenuSchedules(void){}; + void SetEpgSearchFav(bool isFav) { epgSearchFav = isFav; }; +}; + +/****************************************************************** +* cLeMenuSchedules +******************************************************************/ +class cCeMenuSchedules; +class cLeMenuSchedules : public cListElement, public cVeMenuSchedules { +private: + cCeMenuSchedules *currentSchedules; +public: + cLeMenuSchedules(void); + cLeMenuSchedules(const cLeMenuSchedules &other); + virtual ~cLeMenuSchedules(void); + void SetTokenContainer(void); + void SetCurrentElement(cCeMenuSchedules *cur) { currentSchedules = cur; currentElement = (cViewElement*)cur; }; + void ClearCurrentElement(void); + void Set(const cEvent *event, const cChannel *channel, bool withDate, eTimerMatch timerMatch); + bool Parse(bool forced = true); + void RenderCurrent(void); +}; + +/****************************************************************** +* cCeMenuSchedules +******************************************************************/ +class cCeMenuSchedules : public cCurrentElement, public cVeMenuSchedules, public cScrapManager { +private: + eMenuCategory menuCat; + int schedulesIndex; +public: + cCeMenuSchedules(void); + virtual ~cCeMenuSchedules(void); + void SetTokenContainer(void); + void Set(const cEvent *event, const cChannel *channel, bool withDate, eTimerMatch timerMatch, eMenuCategory menuCat); + bool Parse(bool forced = true); +}; + +/****************************************************************** +* cLeMenuChannels +******************************************************************/ +class cCeMenuChannels; +class cLeMenuChannels : public cListElement { +private: + cCeMenuChannels *currentChannel; + const cChannel *channel; + bool withProvider; +public: + cLeMenuChannels(void); + cLeMenuChannels(const cLeMenuChannels &other); + virtual ~cLeMenuChannels(void); + void SetTokenContainer(void); + void SetCurrentElement(cCeMenuChannels *cur) { currentChannel = cur; currentElement = (cViewElement*)cur; }; + void ClearCurrentElement(void); + void Set(const cChannel *channel, bool withProvider); + bool Parse(bool forced = true); + void RenderCurrent(void); +}; + +/****************************************************************** +* cCeMenuChannels +******************************************************************/ +class cCeMenuChannels : public cCurrentElement { +private: + const cChannel *channel; + bool withProvider; + int schedulesIndex; +public: + cCeMenuChannels(void); + virtual ~cCeMenuChannels(void); + void SetTokenContainer(void); + void Set(const cChannel *channel, bool withProvider); + bool Parse(bool forced = true); +}; + +/****************************************************************** +* cLeMenuTimers +******************************************************************/ +class cCeMenuTimers; +class cLeMenuTimers : public cListElement { +private: + cCeMenuTimers *currentTimer; + const cTimer *timer; +public: + cLeMenuTimers(void); + virtual ~cLeMenuTimers(void); + void SetTokenContainer(void); + void SetCurrentElement(cCeMenuTimers *cur) { currentTimer = cur; currentElement = (cViewElement*)cur; }; + void ClearCurrentElement(void); + void Set(const cTimer *timer); + bool Parse(bool forced = true); + void RenderCurrent(void); +}; + +/****************************************************************** +* cCeMenuTimers +******************************************************************/ +class cCeMenuTimers : public cCurrentElement { +private: + const cTimer *timer; +public: + cCeMenuTimers(void); + virtual ~cCeMenuTimers(void); + void SetTokenContainer(void); + void Set(const cTimer *timer); + bool Parse(bool forced = true); +}; + +/****************************************************************** +* cLeMenuRecordings +******************************************************************/ +class cCeMenuRecordings; +class cLeMenuRecordings : public cListElement, public cScrapManager { +private: + cCeMenuRecordings *currentRecording; + const cRecording *recording; + int level; + int total; + int New; + char *RecName(const char *path, int level); + char *FolderName(const char *path, int level); +public: + cLeMenuRecordings(void); + virtual ~cLeMenuRecordings(void); + void SetTokenContainer(void); + void SetCurrentElement(cCeMenuRecordings *cur) { currentRecording = cur; currentElement = (cViewElement*)cur; }; + void ClearCurrentElement(void); + void Set(const cRecording *recording, int level, int total, int New); + bool Parse(bool forced = true); + void RenderCurrent(void); +}; + +/****************************************************************** +* cCeMenuRecordings +******************************************************************/ +class cCeMenuRecordings : public cCurrentElement, public cScrapManager { +private: + const cRecording *recording; + int level; + int total; + int New; +public: + cCeMenuRecordings(void); + virtual ~cCeMenuRecordings(void); + void SetTokenContainer(void); + void Set(const cRecording *recording, int level, int total, int New); + bool Parse(bool forced = true); +}; + +/****************************************************************** +* cLeMenuPlugin +******************************************************************/ +class cCeMenuPlugin; +class cLeMenuPlugin : public cListElement { +private: + int plugId; + int plugMenuId; + cCeMenuPlugin *currentPlugin; +public: + cLeMenuPlugin(void); + virtual ~cLeMenuPlugin(void); + void SetTokenContainer(void); + void SetPlugId(int id) { plugId = id; }; + void SetPlugMenuId(int id) { plugMenuId = id; }; + void SetCurrentElement(cCeMenuPlugin *cur) { currentPlugin = cur; currentElement = (cViewElement*)cur; }; + void ClearCurrentElement(void); + void Set(skindesignerapi::cTokenContainer *tk); + bool Parse(bool forced = true); + void RenderCurrent(void); +}; + +/****************************************************************** +* cCeMenuPlugin +******************************************************************/ +class cCeMenuPlugin : public cCurrentElement { +private: + int plugId; + int plugMenuId; +public: + cCeMenuPlugin(void); + virtual ~cCeMenuPlugin(void); + void SetTokenContainer(void); + void SetPlugId(int id) { plugId = id; }; + void SetPlugMenuId(int id) { plugMenuId = id; }; + void Set(skindesignerapi::cTokenContainer *tk); + bool Parse(bool forced = true); +}; + +/****************************************************************** +* cLeAudioTracks +******************************************************************/ +class cLeAudioTracks : public cListElement { +private: + char *text; +public: + cLeAudioTracks(void); + virtual ~cLeAudioTracks(void); + void SetTokenContainer(void); + void Set(const char *text); + bool Parse(bool forced = true); +}; + +#endif //__LISTELEMENTS_H \ No newline at end of file diff --git a/coreengine/osdwrapper.c b/coreengine/osdwrapper.c new file mode 100644 index 0000000..ec1119c --- /dev/null +++ b/coreengine/osdwrapper.c @@ -0,0 +1,71 @@ +#include "osdwrapper.h" + +cSdOsd::cSdOsd(void) { + osd = NULL; + flushLocked = false; +} + +cSdOsd::~cSdOsd(void) { + DeleteOsd(); +} + +void cSdOsd::Lock(void) { + mutex.Lock(); +} + +void cSdOsd::Unlock(void) { + mutex.Unlock(); +} + +void cSdOsd::LockFlush(void) { + Lock(); + flushLocked = true; + Unlock(); +} + +void cSdOsd::UnlockFlush(void) { + Lock(); + flushLocked = false; + Unlock(); +} + +bool cSdOsd::CreateOsd(int x, int y, int width, int height) { + cOsd *newOsd = cOsdProvider::NewOsd(cOsd::OsdLeft() + x, cOsd::OsdTop() + y); + if (newOsd) { + tArea Area = { 0, 0, width - 1, height - 1, 32 }; + if (newOsd->SetAreas(&Area, 1) == oeOk) { + Lock(); + osd = newOsd; + Unlock(); + return true; + } + } + return false; +} + +void cSdOsd::DeleteOsd(void) { + Lock(); + delete osd; + osd = NULL; + Unlock(); +} + +cPixmap *cSdOsd::CreatePixmap(int layer, cRect &viewPort, cRect &drawPort) { + if (osd) { + return osd->CreatePixmap(layer, viewPort, drawPort); + } + return NULL; +} + +void cSdOsd::DestroyPixmap(cPixmap *pix) { + if (osd) { + osd->DestroyPixmap(pix); + } +} + +void cSdOsd::Flush(void) { + Lock(); + if (osd && !flushLocked) + osd->Flush(); + Unlock(); +} diff --git a/coreengine/osdwrapper.h b/coreengine/osdwrapper.h new file mode 100644 index 0000000..ad0394d --- /dev/null +++ b/coreengine/osdwrapper.h @@ -0,0 +1,26 @@ +#ifndef __OSDWRAPPER_H +#define __OSDWRAPPER_H + +#include +#include + +class cSdOsd { +private: + cOsd *osd; + cMutex mutex; + bool flushLocked; +public: + cSdOsd(void); + virtual ~cSdOsd(void); + void Lock(void); + void Unlock(void); + void LockFlush(void); + void UnlockFlush(void); + bool CreateOsd(int x, int y, int width, int height); + void DeleteOsd(void); + cPixmap *CreatePixmap(int layer, cRect &viewPort, cRect &drawPort); + void DestroyPixmap(cPixmap *pix); + void Flush(void); +}; + +#endif //__OSDWRAPPER_H \ No newline at end of file diff --git a/coreengine/view.c b/coreengine/view.c new file mode 100644 index 0000000..8bfa22b --- /dev/null +++ b/coreengine/view.c @@ -0,0 +1,419 @@ +#include "../config.h" +#include "view.h" + +// --- cView ------------------------------------------------------------- + +cView::cView(void) { + globals = NULL; + viewName = NULL; + attribs = new cViewAttribs((int)eViewAttribs::count); + numViewElements = 0; + viewElements = NULL; + viewElementsHorizontal = NULL; + fader = NULL; + shifter = NULL; + currentTvFrame = NULL; + newTvFrame = NULL; + menuInit = false; +} + +cView::~cView() { + for (int i=0; i< numViewElements; i++) + delete viewElements[i]; + delete[] viewElements; + if (viewElementsHorizontal) { + for (int i=0; i< numViewElements; i++) + delete viewElementsHorizontal[i]; + delete[] viewElementsHorizontal; + } + delete attribs; + free(viewName); + delete fader; + delete shifter; + sdOsd.DeleteOsd(); +} + +/******************************************************************* +* Public Functions +*******************************************************************/ +bool cView::ReadFromXML(void) { + const char *xmlFile; + switch (viewId) { + case eViewType::DisplayChannel: + xmlFile = "displaychannel.xml"; + break; + case eViewType::DisplayMenu: + xmlFile = "displaymenu.xml"; + break; + case eViewType::DisplayMessage: + xmlFile = "displaymessage.xml"; + break; + case eViewType::DisplayReplay: + xmlFile = "displayreplay.xml"; + break; + case eViewType::DisplayVolume: + xmlFile = "displayvolume.xml"; + break; + case eViewType::DisplayTracks: + xmlFile = "displayaudiotracks.xml"; + break; + default: + return false; + } + cXmlParser parser; + parser.SetOsd(&sdOsd); + if (!parser.ReadView(this, xmlFile)) { + return false; + } + if (!parser.ParseView()) { + return false; + } + + //read additional plugin menu templates + bool ok = true; + if (viewId == eViewType::DisplayMenu) { + plgManager->InitPluginMenuIterator(); + map *plugMenus = NULL; + string plugName = ""; + int plugId = -1; + while ( plugMenus = plgManager->GetPluginMenus(plugName, plugId) ) { + for (map ::iterator it = plugMenus->begin(); it != plugMenus->end(); it++) { + int templateNumber = it->first; + int menuType = it->second.type; + cString templateName = cString::sprintf("plug-%s-%s", plugName.c_str(), it->second.tplname.c_str()); + if (parser.ReadPluginView(*templateName)) { + ok = parser.ParsePluginView(plugName, plugId, templateNumber, menuType); + } else { + dsyslog("skindesigner: template %s for plugin %s not available", *templateName, plugName.c_str()); + } + } + } + } + return ok; +} + +void cView::SetGlobals(cGlobals *globals) { + this->globals = globals; + attribs->SetGlobals(globals); + for (int i=0; i < numViewElements; ++i) { + if (viewElements[i]) { + viewElements[i]->SetGlobals(globals); + } + if (viewElementsHorizontal && viewElementsHorizontal[i]) { + viewElementsHorizontal[i]->SetGlobals(globals); + } + } +} + +void cView::SetContainer(int x, int y, int width, int height) { + container.SetX(x); + container.SetY(y); + container.SetWidth(width); + container.SetHeight(height); +} + +void cView::SetAttributes(vector &attributes) { + attribs->Set(attributes); +} + +void cView::AddViewElement(const char *sViewElement, cViewElement *viewElement) { + int id = ViewElementId(sViewElement); + if (id == ATTR_UNKNOWN) + return; + viewElement->SetId(id); + viewElement->SetTokenContainer(); + eOrientation orientation = viewElement->Orientation(); + if (viewElementsHorizontal && orientation == eOrientation::horizontal) { + viewElementsHorizontal[id] = viewElement; + } else { + viewElements[id] = viewElement; + } +} + +bool cView::ValidViewElement(const char *viewElement) { + if (ViewElementId(viewElement) != ATTR_UNKNOWN) + return true; + return false; +} + +bool cView::ValidViewList(const char *viewList) { + if (!strcmp(viewList, "menuitems")) + return true; + return false; +} + +void cView::PreCache(void) { + if (container.Width() == 0) { + SetContainer(0, 0, cOsd::OsdWidth(), cOsd::OsdHeight()); + attribs->SetContainer(0, 0, cOsd::OsdWidth(), cOsd::OsdHeight()); + attribs->Cache(); + } + //set frame for scaling tv picture + tvFrame = attribs->TvFrame(); + //cache viewelements + for (int i=0; i < numViewElements; i++) { + if (!viewElements[i]) + continue; + viewElements[i]->SetContainer(0, 0, attribs->Width(), attribs->Height()); + viewElements[i]->Cache(); + } + if (viewElementsHorizontal) { + for (int i=0; i < numViewElements; i++) { + if (!viewElementsHorizontal[i]) + continue; + viewElementsHorizontal[i]->SetContainer(0, 0, attribs->Width(), attribs->Height()); + viewElementsHorizontal[i]->Cache(); + } + } + + //cleanup viewelements + for (int i=0; i < numViewElements; i++) { + if (!viewElements[i]) + continue; + if (!viewElements[i]->Execute()) { + delete viewElements[i]; + viewElements[i] = NULL; + } + } + if (viewElementsHorizontal) { + for (int i=0; i < numViewElements; i++) { + if (!viewElementsHorizontal[i]) + continue; + if (!viewElementsHorizontal[i]->Execute()) { + delete viewElementsHorizontal[i]; + viewElementsHorizontal[i] = NULL; + } + } + } + //set viewelement objects for each view + SetViewElementObjects(); +} + +bool cView::Init(void) { + int osdX = attribs->X(); + int osdY = attribs->Y(); + int osdWidth = attribs->Width(); + int osdHeight = attribs->Height(); + return sdOsd.CreateOsd(osdX, osdY, osdWidth, osdHeight); +} + +void cView::Clear(int ve) { + if (!viewElements[ve]) + return; + viewElements[ve]->Clear(); +} + +void cView::Render(int ve, bool force) { + if (!viewElements[ve]) + return; + if (viewElements[ve]->Parse(force)) + viewElements[ve]->Render(); +} + +void cView::Close(void) { + delete fader; + fader = NULL; + delete shifter; + shifter = NULL; + if (initFinished && ShiftTime() > 0) { + cRect shiftbox = CoveredArea(); + cPoint ref = cPoint(shiftbox.X(), shiftbox.Y()); + cPoint end = ShiftStart(shiftbox); + shifter = new cAnimation((cShiftable*)this, end, ref, false); + shifter->Shift(); + delete shifter; + shifter = NULL; + } else if (initFinished && FadeTime() > 0) { + fader = new cAnimation((cFadable*)this, false); + fader->Fade(); + delete fader; + fader = NULL; + } + if (initFinished) + UnScaleTv(); + ClearVariables(); + for (int i=0; i < numViewElements; i++) { + if (!viewElements[i]) + continue; + viewElements[i]->Close(); + } + sdOsd.DeleteOsd(); +} + +int cView::FadeTime(void) { + return attribs->FadeTime(); +} + +void cView::SetTransparency(int transparency, bool force) { + for (int i = 0; i < numViewElements; i++) { + if (viewElements[i] && (!viewElements[i]->Fading() || force)) { + viewElements[i]->SetTransparency(transparency); + } + } +} + +int cView::ShiftTime(void) { + return attribs->ShiftTime(); +} + +int cView::ShiftMode(void) { + return attribs->ShiftMode(); +} + +void cView::SetPosition(cPoint &position, cPoint &reference, bool force) { + for (int i = 0; i < numViewElements; i++) { + if (viewElements[i] && (!viewElements[i]->Shifting() || force)) { + viewElements[i]->SetPosition(position, reference); + } + } +} + +void cView::Flush(void) { + if (init) { + init = false; + StartAnimation(); + menuInit = true; + //LockFlush was set at startup of view to avoid display + //of not positioned pixmaps for shifting and fading + sdOsd.UnlockFlush(); + } + if (menuInit) { + ScaleTv(); + WakeViewElements(); + menuInit = false; + } + sdOsd.Flush(); +} + +void cView::Debug(void) { + esyslog("skindesigner: ---> view %s", viewName); + for (int i=0; i < numViewElements; i++) { + if (!viewElements[i]) + continue; + esyslog("skindesigner: debugging ve %d", i); + viewElements[i]->Debug(true); + } +} + +/******************************************************************* +* Protected Functions +*******************************************************************/ +void cView::ClearVariables(void) { + init = true; + initFinished = false; + newTvFrame = NULL; + currentTvFrame = NULL; + menuInit = false; +} + +int cView::ViewElementId(const char *name) { + map::iterator hit = viewElementNames.find(name); + if (hit != viewElementNames.end()) + return (int)hit->second; + return ATTR_UNKNOWN; +} + +void cView::StartAnimation(void) { + if (ShiftTime() > 0) { + cRect shiftbox = CoveredArea(); + cPoint ref = cPoint(shiftbox.X(), shiftbox.Y()); + cPoint start = ShiftStart(shiftbox); + SetPosition(start, ref); + shifter = new cAnimation((cShiftable*)this, start, ref, true); + shifter->Start(); + } else if (FadeTime() > 0) { + if (fader) + return; + SetTransparency(100); + sdOsd.Flush(); + fader = new cAnimation((cFadable*)this, true); + fader->Start(); + } + initFinished = true; +} + +void cView::WakeViewElements(void) { + for (int i = 0; i < numViewElements; i++) { + if (viewElements[i]) { + viewElements[i]->WakeUp(); + } + } + if (!viewElementsHorizontal) + return; + for (int i = 0; i < numViewElements; i++) { + if (viewElementsHorizontal[i]) { + viewElementsHorizontal[i]->WakeUp(); + } + } +} + +cPoint cView::ShiftStart(cRect &shiftbox) { + eShiftType type = (eShiftType)attribs->ShiftType(); + cPoint start; + if (type == eShiftType::none) { + start = attribs->ShiftStartpoint(); + } else if (type == eShiftType::left) { + start.SetX(-shiftbox.Width()); + start.SetY(shiftbox.Y()); + } else if (type == eShiftType::right) { + start.SetX(attribs->Width()); + start.SetY(shiftbox.Y()); + } else if (type == eShiftType::top) { + start.SetX(shiftbox.X()); + start.SetY(-shiftbox.Height()); + } else if (type == eShiftType::bottom) { + start.SetX(shiftbox.X()); + start.SetY(attribs->Height()); + } + return start; +} + +cRect cView::CoveredArea(void) { + cRect unionArea; + for (int i = 0; i < numViewElements; i++) { + if (viewElements[i] && !viewElements[i]->Shifting()) { + unionArea.Combine(viewElements[i]->CoveredArea()); + } + } + return unionArea; +} + +void cView::ScaleTv(void) { + bool scale = false; + if (newTvFrame) { + if (currentTvFrame) { + if (*newTvFrame != *currentTvFrame) { + scale = true; + } + } else { + scale = true; + } + currentTvFrame = newTvFrame; + } else { + if (tvFrame != cRect::Null) { + scale = true; + currentTvFrame = &tvFrame; + } + } + if (currentTvFrame && scale) { + DoScaleTv(currentTvFrame); + } +} + +void cView::UnScaleTv(void) { + if (currentTvFrame) { + DoScaleTv(&cRect::Null); + currentTvFrame = NULL; + } +} + +void cView::DoScaleTv(const cRect *frame) { + if (*frame == cRect::Null) { + cDevice::PrimaryDevice()->ScaleVideo(cRect::Null); + } else { + cRect scalingWindow = cDevice::PrimaryDevice()->CanScaleVideo(*frame); + if (scalingWindow != cRect::Null) { + cDevice::PrimaryDevice()->ScaleVideo(scalingWindow); + } + } +} diff --git a/coreengine/view.h b/coreengine/view.h new file mode 100644 index 0000000..b6ee0e6 --- /dev/null +++ b/coreengine/view.h @@ -0,0 +1,93 @@ +#ifndef __VIEW_H +#define __VIEW_H + +#include +#include +#include +#include +#include + +#include "osdwrapper.h" +#include "globals.h" +#include "../libskindesignerapi/tokencontainer.h" +#include "viewelementplugin.h" +#include "viewelementscommon.h" +#include "viewelementsdisplaychannel.h" +#include "viewelementsdisplaymenu.h" +#include "viewelementsdisplayreplay.h" +#include "viewelementsdisplaytracks.h" +#include "viewlist.h" +class cView; +#include "xmlparser.h" +#include "animation.h" + +using namespace std; + +class cView : public cFadable, public cShiftable { +private: + void DoScaleTv(const cRect *frame); +protected: + cSdOsd sdOsd; + cViewAttribs *attribs; + cRect container; + bool init; + bool initFinished; + eViewType viewId; + cGlobals *globals; + char *viewName; + int numViewElements; + cViewElement **viewElements; + cViewElement **viewElementsHorizontal; + map viewElementNames; + cAnimation *fader; + cAnimation *shifter; + cRect tvFrame; + cRect *currentTvFrame; + cRect *newTvFrame; + bool menuInit; + int ViewElementId(const char *name); + virtual void ClearVariables(void); + virtual void SetViewElementObjects(void) { }; + virtual void StartAnimation(void); + virtual void WakeViewElements(void); + cPoint ShiftStart(cRect &shiftbox); + virtual cRect CoveredArea(void); + void ScaleTv(void); + void UnScaleTv(void); +public: + cView(void); + virtual ~cView(void); + //Loading and Caching functionality + bool ReadFromXML(void); + virtual void SetGlobals(cGlobals *globals); + const char *GetViewName(void) { return viewName; }; + void SetContainer(int x, int y, int width, int height); + void SetAttributes(vector &attributes); + void AddViewElement(const char *sViewElement, cViewElement *viewElement); + bool ValidViewElement(const char *viewElement); + virtual void AddViewList(cViewList *viewList) { }; + bool ValidViewList(const char *viewList); + virtual void PreCache(void); + cRect *GetTvFrame(void) { return &tvFrame; }; + virtual const cFont *GetTextAreaFont(void) { return NULL; }; + virtual int GetTextAreaWidth(void) { return 0; }; + virtual int GetListWidth(void) { return 0; }; + //View API + virtual bool Init(void); + void Clear(int ve); + void Render(int ve, bool force = false); + virtual void Close(void); + virtual void Flush(void); + virtual void Debug(void); + bool Detached(void) { return false; }; + int Delay(void) { return 0; }; + //Fadable + int FadeTime(void); + virtual void SetTransparency(int transparency, bool force = false); + //Shiftable + int ShiftTime(void); + int ShiftMode(void); + virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false); +}; + +#endif //__VIEW_H diff --git a/coreengine/viewdetail.c b/coreengine/viewdetail.c new file mode 100644 index 0000000..334cf5d --- /dev/null +++ b/coreengine/viewdetail.c @@ -0,0 +1,978 @@ +#include "viewdetail.h" +#include "../config.h" +/****************************************************************** +* cViewDetail +******************************************************************/ +cViewDetail::cViewDetail(void) { + activeTab = NULL; + activeTabIndex = -1; + numTabs = 0; + plugId = -1; + plugMenuId = -1; +} + +cViewDetail::~cViewDetail(void) { +} + +void cViewDetail::SetActiveTab(void) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + if (node->ActiveTab()) { + activeTab = dynamic_cast(node); + activeTabIndex = 0; + return; + } + } +} + +int cViewDetail::GetWidth(void) { + cAreaNode *node = areaNodes.First(); + if (!node) + return 0; + return node->GetWidth(); +} + +void cViewDetail::ResetTabs(void) { + activeTab = NULL; + activeTabIndex = -1; +} + +void cViewDetail::Clear(void) { + cViewElement::Close(); +} + +void cViewDetail::Close(void) { + cViewElement::Close(); + activeTab = NULL; + activeTabIndex = -1; + numTabs = 0; +} + +void cViewDetail::Render(void) { + if (!dirty || blocked) + return; + + if (attribs->DoDebug()) + Debug(); + + if (!activeTab) + SetActiveTab(); + if (!activeTab) + return; + + activeTab->Clear(); + if (activeTab->Execute()) { + activeTab->Render(); + } + + dirty = false; +} + +void cViewDetail::Scrollbar(int &barheight, int &offset, bool &end) { + if (!activeTab) + return; + cRect tabViewPort = activeTab->ViewPort(); + cRect tabDrawPort = activeTab->DrawPort(); + int totalHeight = tabDrawPort.Height(); + int screenHeight = tabViewPort.Height(); + int y = (-1)*tabDrawPort.Y(); + if (totalHeight == 0) { + return; + } + if (totalHeight <= screenHeight) + barheight = 1000; + else { + barheight = (double)screenHeight / (double) totalHeight * 1000; + } + offset = (double)y / (double) totalHeight * 1000; + end = true; +} + +bool cViewDetail::ScrollUp(bool page) { + if (!activeTab) + return false; + cRect tabDrawPort = activeTab->DrawPort(); + int scrollStep = activeTab->ScrollStep(); + if (page) { + cRect tabViewPort = activeTab->ViewPort(); + scrollStep = tabViewPort.Height(); + } + int aktHeight = tabDrawPort.Y(); + if (aktHeight >= 0) { + return false; + } + int newY = aktHeight + scrollStep; + if (newY > 0) + newY = 0; + cPoint dp(0, newY); + activeTab->SetDrawPort(dp); + return true; +} + +bool cViewDetail::ScrollDown(bool page) { + if (!activeTab) + return false; + cRect tabViewPort = activeTab->ViewPort(); + cRect tabDrawPort = activeTab->DrawPort(); + int scrollStep = activeTab->ScrollStep(); + if (page) { + scrollStep = tabViewPort.Height(); + } + int aktHeight = tabDrawPort.Y(); + int totalHeight = tabDrawPort.Height(); + int screenHeight = tabViewPort.Height(); + + if (totalHeight - ((-1)*aktHeight) == screenHeight) { + return false; + } + int newY = aktHeight - scrollStep; + if ((-1)*newY > totalHeight - screenHeight) + newY = (-1)*(totalHeight - screenHeight); + cPoint dp(0, newY); + activeTab->SetDrawPort(dp); + return true; +} + +int cViewDetail::GetTabs(vector &tabs) { + int i=0; + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + if (!node->Execute()) + continue; + tabs.push_back(node->Name()); + if (node->ActiveTab()) { + activeTabIndex = i; + } + i++; + } + numTabs = i; + return activeTabIndex; +} + +void cViewDetail::NextTab(void) { + cArea *nextActiveTab = NULL; + for (cAreaNode *node = areaNodes.Next(activeTab); node; node = areaNodes.Next(node)) { + if (node->Execute()) { + nextActiveTab = dynamic_cast(node); + activeTabIndex++; + break; + } + } + if (!nextActiveTab) { + nextActiveTab = dynamic_cast(areaNodes.First()); + activeTabIndex = 0; + } + activeTab = nextActiveTab; +} + +void cViewDetail::PrevTab(void) { + cArea *prevActiveTab = NULL; + for (cAreaNode *node = areaNodes.Prev(activeTab); node; node = areaNodes.Prev(node)) { + if (node->Execute()) { + prevActiveTab = dynamic_cast(node); + activeTabIndex--; + break; + } + } + if (!prevActiveTab) { + int numActiveTabs = 0; + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + if (node->Execute()) { + numActiveTabs++; + } + } + for (cAreaNode *node = areaNodes.Last(); node; node = areaNodes.Prev(node)) { + if (node->Execute()) { + prevActiveTab = dynamic_cast(node); + activeTabIndex = numActiveTabs-1; + break; + } + } + } + activeTab = prevActiveTab; +} + +void cViewDetail::SetTransparency(int transparency, bool forceDetached) { + if (activeTab) + activeTab->SetTransparency(transparency); +} + +/****************************************************************** +* cViewDetailEpg +******************************************************************/ +cViewDetailEpg::cViewDetailEpg(void) { + event = NULL; + rerunsIndex = -1; + actorsIndex = -1; +} + +cViewDetailEpg::~cViewDetailEpg(void) { +} + +void cViewDetailEpg::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{title}", (int)eDmDetailedEpgST::title); + tokenContainer->DefineStringToken("{shorttext}", (int)eDmDetailedEpgST::shorttext); + tokenContainer->DefineStringToken("{description}", (int)eDmDetailedEpgST::description); + tokenContainer->DefineStringToken("{start}", (int)eDmDetailedEpgST::start); + tokenContainer->DefineStringToken("{stop}", (int)eDmDetailedEpgST::stop); + tokenContainer->DefineStringToken("{day}", (int)eDmDetailedEpgST::day); + tokenContainer->DefineStringToken("{date}", (int)eDmDetailedEpgST::date); + tokenContainer->DefineStringToken("{durationminutes}", (int)eDmDetailedEpgST::durationminutes); + tokenContainer->DefineStringToken("{vps}", (int)eDmDetailedEpgST::vps); + tokenContainer->DefineStringToken("{channelname}", (int)eDmDetailedEpgST::channelname); + tokenContainer->DefineStringToken("{channelid}", (int)eDmDetailedEpgST::channelid); + tokenContainer->DefineStringToken("{epgpic1path}", (int)eDmDetailedEpgST::epgpic1path); + tokenContainer->DefineStringToken("{epgpic2path}", (int)eDmDetailedEpgST::epgpic2path); + tokenContainer->DefineStringToken("{epgpic3path}", (int)eDmDetailedEpgST::epgpic3path); + tokenContainer->DefineStringToken("{movietitle}", (int)eScraperST::movietitle); + tokenContainer->DefineStringToken("{movieoriginalTitle}", (int)eScraperST::movieoriginalTitle); + tokenContainer->DefineStringToken("{movietagline}", (int)eScraperST::movietagline); + tokenContainer->DefineStringToken("{movieoverview}", (int)eScraperST::movieoverview); + tokenContainer->DefineStringToken("{moviegenres}", (int)eScraperST::moviegenres); + tokenContainer->DefineStringToken("{moviehomepage}", (int)eScraperST::moviehomepage); + tokenContainer->DefineStringToken("{moviereleasedate}", (int)eScraperST::moviereleasedate); + tokenContainer->DefineStringToken("{moviepopularity}", (int)eScraperST::moviepopularity); + tokenContainer->DefineStringToken("{movievoteaverage}", (int)eScraperST::movievoteaverage); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperST::posterpath); + tokenContainer->DefineStringToken("{fanartpath}", (int)eScraperST::fanartpath); + tokenContainer->DefineStringToken("{moviecollectionName}", (int)eScraperST::moviecollectionName); + tokenContainer->DefineStringToken("{collectionposterpath}", (int)eScraperST::collectionposterpath); + tokenContainer->DefineStringToken("{collectionfanartpath}", (int)eScraperST::collectionfanartpath); + tokenContainer->DefineStringToken("{seriesname}", (int)eScraperST::seriesname); + tokenContainer->DefineStringToken("{seriesoverview}", (int)eScraperST::seriesoverview); + tokenContainer->DefineStringToken("{seriesfirstaired}", (int)eScraperST::seriesfirstaired); + tokenContainer->DefineStringToken("{seriesnetwork}", (int)eScraperST::seriesnetwork); + tokenContainer->DefineStringToken("{seriesgenre}", (int)eScraperST::seriesgenre); + tokenContainer->DefineStringToken("{seriesrating}", (int)eScraperST::seriesrating); + tokenContainer->DefineStringToken("{seriesstatus}", (int)eScraperST::seriesstatus); + tokenContainer->DefineStringToken("{episodetitle}", (int)eScraperST::episodetitle); + tokenContainer->DefineStringToken("{episodefirstaired}", (int)eScraperST::episodefirstaired); + tokenContainer->DefineStringToken("{episodegueststars}", (int)eScraperST::episodegueststars); + tokenContainer->DefineStringToken("{episodeoverview}", (int)eScraperST::episodeoverview); + tokenContainer->DefineStringToken("{episoderating}", (int)eScraperST::episoderating); + tokenContainer->DefineStringToken("{episodeimagepath}", (int)eScraperST::episodeimagepath); + tokenContainer->DefineStringToken("{seasonposterpath}", (int)eScraperST::seasonposterpath); + tokenContainer->DefineStringToken("{seriesposter1path}", (int)eScraperST::seriesposter1path); + tokenContainer->DefineStringToken("{seriesposter2path}", (int)eScraperST::seriesposter2path); + tokenContainer->DefineStringToken("{seriesposter3path}", (int)eScraperST::seriesposter3path); + tokenContainer->DefineStringToken("{seriesfanart1path}", (int)eScraperST::seriesfanart1path); + tokenContainer->DefineStringToken("{seriesfanart2path}", (int)eScraperST::seriesfanart2path); + tokenContainer->DefineStringToken("{seriesfanart3path}", (int)eScraperST::seriesfanart3path); + tokenContainer->DefineStringToken("{seriesbanner1path}", (int)eScraperST::seriesbanner1path); + tokenContainer->DefineStringToken("{seriesbanner2path}", (int)eScraperST::seriesbanner2path); + tokenContainer->DefineStringToken("{seriesbanner3path}", (int)eScraperST::seriesbanner3path); + tokenContainer->DefineIntToken("{daynumeric}", (int)eDmDetailedEpgIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eDmDetailedEpgIT::month); + tokenContainer->DefineIntToken("{year}", (int)eDmDetailedEpgIT::year); + tokenContainer->DefineIntToken("{running}", (int)eDmDetailedEpgIT::running); + tokenContainer->DefineIntToken("{elapsed}", (int)eDmDetailedEpgIT::elapsed); + tokenContainer->DefineIntToken("{duration}", (int)eDmDetailedEpgIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eDmDetailedEpgIT::durationhours); + tokenContainer->DefineIntToken("{channelnumber}", (int)eDmDetailedEpgIT::channelnumber); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eDmDetailedEpgIT::channellogoexists); + tokenContainer->DefineIntToken("{hasreruns}", (int)eDmDetailedEpgIT::hasreruns); + tokenContainer->DefineIntToken("{epgpic1avaialble}", (int)eDmDetailedEpgIT::epgpic1avaialble); + tokenContainer->DefineIntToken("{epgpic2avaialble}", (int)eDmDetailedEpgIT::epgpic2avaialble); + tokenContainer->DefineIntToken("{epgpic3avaialble}", (int)eDmDetailedEpgIT::epgpic3avaialble); + tokenContainer->DefineIntToken("{ismovie}", (int)eScraperIT::ismovie); + tokenContainer->DefineIntToken("{moviebudget}", (int)eScraperIT::moviebudget); + tokenContainer->DefineIntToken("{movierevenue}", (int)eScraperIT::movierevenue); + tokenContainer->DefineIntToken("{movieadult}", (int)eScraperIT::movieadult); + tokenContainer->DefineIntToken("{movieruntime}", (int)eScraperIT::movieruntime); + tokenContainer->DefineIntToken("{isseries}", (int)eScraperIT::isseries); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperIT::posterheight); + tokenContainer->DefineIntToken("{fanartwidth}", (int)eScraperIT::fanartwidth); + tokenContainer->DefineIntToken("{fanartheight}", (int)eScraperIT::fanartheight); + tokenContainer->DefineIntToken("{movieiscollection}", (int)eScraperIT::movieiscollection); + tokenContainer->DefineIntToken("{collectionposterwidth}", (int)eScraperIT::collectionposterwidth); + tokenContainer->DefineIntToken("{collectionposterheight}", (int)eScraperIT::collectionposterheight); + tokenContainer->DefineIntToken("{collectionfanartwidth}", (int)eScraperIT::collectionfanartwidth); + tokenContainer->DefineIntToken("{collectionfanartheight}", (int)eScraperIT::collectionfanartheight); + tokenContainer->DefineIntToken("{epgpicavailable}", (int)eScraperIT::epgpicavailable); + tokenContainer->DefineIntToken("{episodenumber}", (int)eScraperIT::episodenumber); + tokenContainer->DefineIntToken("{episodeseason}", (int)eScraperIT::episodeseason); + tokenContainer->DefineIntToken("{episodeimagewidth}", (int)eScraperIT::episodeimagewidth); + tokenContainer->DefineIntToken("{episodeimageheight}", (int)eScraperIT::episodeimageheight); + tokenContainer->DefineIntToken("{seasonposterwidth}", (int)eScraperIT::seasonposterwidth); + tokenContainer->DefineIntToken("{seasonposterheight}", (int)eScraperIT::seasonposterheight); + tokenContainer->DefineIntToken("{seriesposter1width}", (int)eScraperIT::seriesposter1width); + tokenContainer->DefineIntToken("{seriesposter1height}", (int)eScraperIT::seriesposter1height); + tokenContainer->DefineIntToken("{seriesposter2width}", (int)eScraperIT::seriesposter2width); + tokenContainer->DefineIntToken("{seriesposter2height}", (int)eScraperIT::seriesposter2height); + tokenContainer->DefineIntToken("{seriesposter3width}", (int)eScraperIT::seriesposter3width); + tokenContainer->DefineIntToken("{seriesposter3height}", (int)eScraperIT::seriesposter3height); + tokenContainer->DefineIntToken("{seriesfanart1width}", (int)eScraperIT::seriesfanart1width); + tokenContainer->DefineIntToken("{seriesfanart1height}", (int)eScraperIT::seriesfanart1height); + tokenContainer->DefineIntToken("{seriesfanart2width}", (int)eScraperIT::seriesfanart2width); + tokenContainer->DefineIntToken("{seriesfanart2height}", (int)eScraperIT::seriesfanart2height); + tokenContainer->DefineIntToken("{seriesfanart3width}", (int)eScraperIT::seriesfanart3width); + tokenContainer->DefineIntToken("{seriesfanart3height}", (int)eScraperIT::seriesfanart3height); + tokenContainer->DefineIntToken("{seriesbanner1width}", (int)eScraperIT::seriesbanner1width); + tokenContainer->DefineIntToken("{seriesbanner1height}", (int)eScraperIT::seriesbanner1height); + tokenContainer->DefineIntToken("{seriesbanner2width}", (int)eScraperIT::seriesbanner2width); + tokenContainer->DefineIntToken("{seriesbanner2height}", (int)eScraperIT::seriesbanner2height); + tokenContainer->DefineIntToken("{seriesbanner3width}", (int)eScraperIT::seriesbanner3width); + tokenContainer->DefineIntToken("{seriesbanner3height}", (int)eScraperIT::seriesbanner3height); + tokenContainer->DefineLoopToken("{reruns[title]}", (int)eRerunsLT::title); + tokenContainer->DefineLoopToken("{reruns[shorttext]}", (int)eRerunsLT::shorttext); + tokenContainer->DefineLoopToken("{reruns[date]}", (int)eRerunsLT::date); + tokenContainer->DefineLoopToken("{reruns[day]}", (int)eRerunsLT::day); + tokenContainer->DefineLoopToken("{reruns[start]}", (int)eRerunsLT::start); + tokenContainer->DefineLoopToken("{reruns[stop]}", (int)eRerunsLT::stop); + tokenContainer->DefineLoopToken("{reruns[channelname]}", (int)eRerunsLT::channelname); + tokenContainer->DefineLoopToken("{reruns[channelnumber]}", (int)eRerunsLT::channelnumber); + tokenContainer->DefineLoopToken("{reruns[channelid]}", (int)eRerunsLT::channelid); + tokenContainer->DefineLoopToken("{reruns[channellogoexists]}", (int)eRerunsLT::channellogoexists); + tokenContainer->DefineLoopToken("{actors[name]}", (int)eScraperLT::name); + tokenContainer->DefineLoopToken("{actors[role]}", (int)eScraperLT::role); + tokenContainer->DefineLoopToken("{actors[thumb]}", (int)eScraperLT::thumb); + tokenContainer->DefineLoopToken("{actors[thumbwidth]}", (int)eScraperLT::thumbwidth); + tokenContainer->DefineLoopToken("{actors[thumbheight]}", (int)eScraperLT::thumbheight); + rerunsIndex = tokenContainer->LoopIndex("reruns"); + actorsIndex = tokenContainer->LoopIndex("actors"); + InheritTokenContainer(); +} + +bool cViewDetailEpg::Parse(bool forced) { + if (!cViewElement::Parse()) + return false; + if (!event) + return false; + + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::title, event->Title()); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::shorttext, event->ShortText()); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::description, event->Description()); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::start, *(event->GetTimeString())); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::stop, *(event->GetEndTimeString())); + time_t startTime = event->StartTime(); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::day, *WeekDayName(startTime)); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::date, *ShortDateString(startTime)); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::month, sStartTime->tm_mon+1); + const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); + if (channel) { + tokenContainer->AddStringToken((int)eDmDetailedEpgST::channelname, channel->Name()); + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::channelnumber, channel->Number()); + } + cString channelID = event->ChannelID().ToString(); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::channelid, *channelID); + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::channellogoexists, imgCache->LogoExists(*channelID)); + + bool isRunning = false; + time_t now = time(NULL); + if ((now >= event->StartTime()) && (now <= event->EndTime())) + isRunning = true; + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::running, isRunning); + if (isRunning) { + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::elapsed, (now - event->StartTime())/60); + } else { + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::elapsed, 0); + } + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::duration, event->Duration() / 60); + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::durationhours, event->Duration() / 3600); + tokenContainer->AddStringToken((int)eDmDetailedEpgST::durationminutes, *cString::sprintf("%.2d", (event->Duration() / 60)%60)); + if (event->Vps()) + tokenContainer->AddStringToken((int)eDmDetailedEpgST::vps, *event->GetVpsString()); + + cList *reruns = LoadReruns(); + int numReruns = NumReruns(reruns); + vector loopInfo; + //num reruns + loopInfo.push_back(numReruns); + //num actors + bool scrapInfoAvailable = LoadFullScrapInfo(event, NULL); + int numActors = NumActors(); + loopInfo.push_back(numActors); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + if (numReruns > 0) { + tokenContainer->AddIntToken((int)eDmDetailedEpgIT::hasreruns, 1); + SetReruns(reruns); + } + if (scrapInfoAvailable) { + SetFullScrapInfo(tokenContainer, actorsIndex); + } + SetDirty(); + return true; +} + +cList *cViewDetailEpg::LoadReruns(void) { + cPlugin *epgSearchPlugin = cPluginManager::GetPlugin("epgsearch"); + if (!epgSearchPlugin) + return NULL; + + if (isempty(event->Title())) + return NULL; + + Epgsearch_searchresults_v1_0 data; + data.query = (char*)event->Title(); + data.mode = 0; + data.channelNr = 0; + data.useTitle = true; + data.useSubTitle = true; + data.useDescription = false; + + cList *result = NULL; + if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) + result = data.pResultList; + return result; +} + +int cViewDetailEpg::NumReruns(cList *reruns) { + if (!reruns || reruns->Count() < 2) + return 0; + + int maxNumReruns = config.rerunAmount; + int rerunDistance = config.rerunDistance * 3600; + int rerunMaxChannel = config.rerunMaxChannel; + + int i = 0; + for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) { + time_t eventStart = event->StartTime(); + time_t rerunStart = r->event->StartTime(); + cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true); + //check for identical event + if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart)) + continue; + //check for timely distance + if (rerunDistance > 0) + if (rerunStart - eventStart < rerunDistance) + continue; + //check for maxchannel + if (rerunMaxChannel > 0) + if (channel && channel->Number() > rerunMaxChannel) + continue; + i++; + } + return i; +} + +void cViewDetailEpg::SetReruns(cList *reruns) { + if (!reruns || reruns->Count() < 2) + return; + + int maxNumReruns = config.rerunAmount; + int rerunDistance = config.rerunDistance * 3600; + int rerunMaxChannel = config.rerunMaxChannel; + + int i = 0; + for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = reruns->First(); r && i < maxNumReruns; r = reruns->Next(r)) { + time_t eventStart = event->StartTime(); + time_t rerunStart = r->event->StartTime(); + cChannel *channel = Channels.GetByChannelID(r->event->ChannelID(), true, true); + //check for identical event + if ((event->ChannelID() == r->event->ChannelID()) && (eventStart == rerunStart)) + continue; + //check for timely distance + if (rerunDistance > 0) + if (rerunStart - eventStart < rerunDistance) + continue; + //check for maxchannel + if (rerunMaxChannel > 0) + if (channel && channel->Number() > rerunMaxChannel) + continue; + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::title, r->event->Title()); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::shorttext, r->event->ShortText()); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::start, *(r->event->GetTimeString())); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::stop, *(r->event->GetEndTimeString())); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::date, *ShortDateString(r->event->StartTime())); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::day, *WeekDayName(r->event->StartTime())); + cString channelID = r->event->ChannelID().ToString(); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelid, *channelID); + bool logoExists = imgCache->LogoExists(*channelID); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channellogoexists, logoExists ? "1" : "0"); + if (channel) { + cString channelNumber = cString::sprintf("%d", channel->Number()); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelname, channel->ShortName(true)); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelnumber, *channelNumber); + } else { + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelname, ""); + tokenContainer->AddLoopToken(rerunsIndex, i, (int)eRerunsLT::channelnumber, ""); + } + i++; + } +} + +/****************************************************************** +* cViewDetailRec +******************************************************************/ +cViewDetailRec::cViewDetailRec(void) { + recording = NULL; + actorsIndex = -1; +} + +cViewDetailRec::~cViewDetailRec(void) { +} + +void cViewDetailRec::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{name}", (int)eDmDetailedRecST::name); + tokenContainer->DefineStringToken("{epgname}", (int)eDmDetailedRecST::epgname); + tokenContainer->DefineStringToken("{shorttext}", (int)eDmDetailedRecST::shorttext); + tokenContainer->DefineStringToken("{description}", (int)eDmDetailedRecST::description); + tokenContainer->DefineStringToken("{day}", (int)eDmDetailedRecST::day); + tokenContainer->DefineStringToken("{date}", (int)eDmDetailedRecST::date); + tokenContainer->DefineStringToken("{time}", (int)eDmDetailedRecST::time); + tokenContainer->DefineStringToken("{durationminutes}", (int)eDmDetailedRecST::durationminutes); + tokenContainer->DefineStringToken("{durationeventminutes}", (int)eDmDetailedRecST::durationeventminutes); + tokenContainer->DefineStringToken("{recchannelname}", (int)eDmDetailedRecST::recchannelname); + tokenContainer->DefineStringToken("{recchannelid}", (int)eDmDetailedRecST::recchannelid); + tokenContainer->DefineStringToken("{recordingsize}", (int)eDmDetailedRecST::recordingsize); + tokenContainer->DefineStringToken("{recordingsizecutted}", (int)eDmDetailedRecST::recordingsizecutted); + tokenContainer->DefineStringToken("{recordinglength}", (int)eDmDetailedRecST::recordinglength); + tokenContainer->DefineStringToken("{recordinglengthcutted}", (int)eDmDetailedRecST::recordinglengthcutted); + tokenContainer->DefineStringToken("{recordingbitrate}", (int)eDmDetailedRecST::recordingbitrate); + tokenContainer->DefineStringToken("{recordingformat}", (int)eDmDetailedRecST::recordingformat); + tokenContainer->DefineStringToken("{searchtimer}", (int)eDmDetailedRecST::searchtimer); + tokenContainer->DefineStringToken("{recimg1path}", (int)eDmDetailedRecST::recimg1path); + tokenContainer->DefineStringToken("{recimg2path}", (int)eDmDetailedRecST::recimg2path); + tokenContainer->DefineStringToken("{recimg3path}", (int)eDmDetailedRecST::recimg3path); + tokenContainer->DefineStringToken("{movietitle}", (int)eScraperST::movietitle); + tokenContainer->DefineStringToken("{movieoriginalTitle}", (int)eScraperST::movieoriginalTitle); + tokenContainer->DefineStringToken("{movietagline}", (int)eScraperST::movietagline); + tokenContainer->DefineStringToken("{movieoverview}", (int)eScraperST::movieoverview); + tokenContainer->DefineStringToken("{moviegenres}", (int)eScraperST::moviegenres); + tokenContainer->DefineStringToken("{moviehomepage}", (int)eScraperST::moviehomepage); + tokenContainer->DefineStringToken("{moviereleasedate}", (int)eScraperST::moviereleasedate); + tokenContainer->DefineStringToken("{moviepopularity}", (int)eScraperST::moviepopularity); + tokenContainer->DefineStringToken("{movievoteaverage}", (int)eScraperST::movievoteaverage); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperST::posterpath); + tokenContainer->DefineStringToken("{fanartpath}", (int)eScraperST::fanartpath); + tokenContainer->DefineStringToken("{moviecollectionName}", (int)eScraperST::moviecollectionName); + tokenContainer->DefineStringToken("{collectionposterpath}", (int)eScraperST::collectionposterpath); + tokenContainer->DefineStringToken("{collectionfanartpath}", (int)eScraperST::collectionfanartpath); + tokenContainer->DefineStringToken("{seriesname}", (int)eScraperST::seriesname); + tokenContainer->DefineStringToken("{seriesoverview}", (int)eScraperST::seriesoverview); + tokenContainer->DefineStringToken("{seriesfirstaired}", (int)eScraperST::seriesfirstaired); + tokenContainer->DefineStringToken("{seriesnetwork}", (int)eScraperST::seriesnetwork); + tokenContainer->DefineStringToken("{seriesgenre}", (int)eScraperST::seriesgenre); + tokenContainer->DefineStringToken("{seriesrating}", (int)eScraperST::seriesrating); + tokenContainer->DefineStringToken("{seriesstatus}", (int)eScraperST::seriesstatus); + tokenContainer->DefineStringToken("{episodetitle}", (int)eScraperST::episodetitle); + tokenContainer->DefineStringToken("{episodefirstaired}", (int)eScraperST::episodefirstaired); + tokenContainer->DefineStringToken("{episodegueststars}", (int)eScraperST::episodegueststars); + tokenContainer->DefineStringToken("{episodeoverview}", (int)eScraperST::episodeoverview); + tokenContainer->DefineStringToken("{episoderating}", (int)eScraperST::episoderating); + tokenContainer->DefineStringToken("{episodeimagepath}", (int)eScraperST::episodeimagepath); + tokenContainer->DefineStringToken("{seasonposterpath}", (int)eScraperST::seasonposterpath); + tokenContainer->DefineStringToken("{seriesposter1path}", (int)eScraperST::seriesposter1path); + tokenContainer->DefineStringToken("{seriesposter2path}", (int)eScraperST::seriesposter2path); + tokenContainer->DefineStringToken("{seriesposter3path}", (int)eScraperST::seriesposter3path); + tokenContainer->DefineStringToken("{seriesfanart1path}", (int)eScraperST::seriesfanart1path); + tokenContainer->DefineStringToken("{seriesfanart2path}", (int)eScraperST::seriesfanart2path); + tokenContainer->DefineStringToken("{seriesfanart3path}", (int)eScraperST::seriesfanart3path); + tokenContainer->DefineStringToken("{seriesbanner1path}", (int)eScraperST::seriesbanner1path); + tokenContainer->DefineStringToken("{seriesbanner2path}", (int)eScraperST::seriesbanner2path); + tokenContainer->DefineStringToken("{seriesbanner3path}", (int)eScraperST::seriesbanner3path); + tokenContainer->DefineIntToken("{daynumeric}", (int)eDmDetailedRecIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eDmDetailedRecIT::month); + tokenContainer->DefineIntToken("{year}", (int)eDmDetailedRecIT::year); + tokenContainer->DefineIntToken("{duration}", (int)eDmDetailedRecIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eDmDetailedRecIT::durationhours); + tokenContainer->DefineIntToken("{durationevent}", (int)eDmDetailedRecIT::durationevent); + tokenContainer->DefineIntToken("{durationeventhours}", (int)eDmDetailedRecIT::durationeventhours); + tokenContainer->DefineIntToken("{recchannelnumber}", (int)eDmDetailedRecIT::recchannelnumber); + tokenContainer->DefineIntToken("{cutted}", (int)eDmDetailedRecIT::cutted); + tokenContainer->DefineIntToken("{recimg1avaialble}", (int)eDmDetailedRecIT::recimg1avaialble); + tokenContainer->DefineIntToken("{recimg2avaialble}", (int)eDmDetailedRecIT::recimg2avaialble); + tokenContainer->DefineIntToken("{recimg3avaialble}", (int)eDmDetailedRecIT::recimg3avaialble); + tokenContainer->DefineIntToken("{ismovie}", (int)eScraperIT::ismovie); + tokenContainer->DefineIntToken("{moviebudget}", (int)eScraperIT::moviebudget); + tokenContainer->DefineIntToken("{movierevenue}", (int)eScraperIT::movierevenue); + tokenContainer->DefineIntToken("{movieadult}", (int)eScraperIT::movieadult); + tokenContainer->DefineIntToken("{movieruntime}", (int)eScraperIT::movieruntime); + tokenContainer->DefineIntToken("{isseries}", (int)eScraperIT::isseries); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperIT::posterheight); + tokenContainer->DefineIntToken("{fanartwidth}", (int)eScraperIT::fanartwidth); + tokenContainer->DefineIntToken("{fanartheight}", (int)eScraperIT::fanartheight); + tokenContainer->DefineIntToken("{movieiscollection}", (int)eScraperIT::movieiscollection); + tokenContainer->DefineIntToken("{collectionposterwidth}", (int)eScraperIT::collectionposterwidth); + tokenContainer->DefineIntToken("{collectionposterheight}", (int)eScraperIT::collectionposterheight); + tokenContainer->DefineIntToken("{collectionfanartwidth}", (int)eScraperIT::collectionfanartwidth); + tokenContainer->DefineIntToken("{collectionfanartheight}", (int)eScraperIT::collectionfanartheight); + tokenContainer->DefineIntToken("{epgpicavailable}", (int)eScraperIT::epgpicavailable); + tokenContainer->DefineIntToken("{episodenumber}", (int)eScraperIT::episodenumber); + tokenContainer->DefineIntToken("{episodeseason}", (int)eScraperIT::episodeseason); + tokenContainer->DefineIntToken("{episodeimagewidth}", (int)eScraperIT::episodeimagewidth); + tokenContainer->DefineIntToken("{episodeimageheight}", (int)eScraperIT::episodeimageheight); + tokenContainer->DefineIntToken("{seasonposterwidth}", (int)eScraperIT::seasonposterwidth); + tokenContainer->DefineIntToken("{seasonposterheight}", (int)eScraperIT::seasonposterheight); + tokenContainer->DefineIntToken("{seriesposter1width}", (int)eScraperIT::seriesposter1width); + tokenContainer->DefineIntToken("{seriesposter1height}", (int)eScraperIT::seriesposter1height); + tokenContainer->DefineIntToken("{seriesposter2width}", (int)eScraperIT::seriesposter2width); + tokenContainer->DefineIntToken("{seriesposter2height}", (int)eScraperIT::seriesposter2height); + tokenContainer->DefineIntToken("{seriesposter3width}", (int)eScraperIT::seriesposter3width); + tokenContainer->DefineIntToken("{seriesposter3height}", (int)eScraperIT::seriesposter3height); + tokenContainer->DefineIntToken("{seriesfanart1width}", (int)eScraperIT::seriesfanart1width); + tokenContainer->DefineIntToken("{seriesfanart1height}", (int)eScraperIT::seriesfanart1height); + tokenContainer->DefineIntToken("{seriesfanart2width}", (int)eScraperIT::seriesfanart2width); + tokenContainer->DefineIntToken("{seriesfanart2height}", (int)eScraperIT::seriesfanart2height); + tokenContainer->DefineIntToken("{seriesfanart3width}", (int)eScraperIT::seriesfanart3width); + tokenContainer->DefineIntToken("{seriesfanart3height}", (int)eScraperIT::seriesfanart3height); + tokenContainer->DefineIntToken("{seriesbanner1width}", (int)eScraperIT::seriesbanner1width); + tokenContainer->DefineIntToken("{seriesbanner1height}", (int)eScraperIT::seriesbanner1height); + tokenContainer->DefineIntToken("{seriesbanner2width}", (int)eScraperIT::seriesbanner2width); + tokenContainer->DefineIntToken("{seriesbanner2height}", (int)eScraperIT::seriesbanner2height); + tokenContainer->DefineIntToken("{seriesbanner3width}", (int)eScraperIT::seriesbanner3width); + tokenContainer->DefineIntToken("{seriesbanner3height}", (int)eScraperIT::seriesbanner3height); + tokenContainer->DefineLoopToken("{actors[name]}", (int)eScraperLT::name); + tokenContainer->DefineLoopToken("{actors[role]}", (int)eScraperLT::role); + tokenContainer->DefineLoopToken("{actors[thumb]}", (int)eScraperLT::thumb); + tokenContainer->DefineLoopToken("{actors[thumbwidth]}", (int)eScraperLT::thumbwidth); + tokenContainer->DefineLoopToken("{actors[thumbheight]}", (int)eScraperLT::thumbheight); + actorsIndex = tokenContainer->LoopIndex("actors"); + InheritTokenContainer(); +} + +bool cViewDetailRec::Parse(bool forced) { + if (!cViewElement::Parse()) + return false; + if (!recording) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDmDetailedRecST::name, recording->Name()); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::cutted, recording->IsEdited()); + + const cRecordingInfo *info = recording->Info(); + if (info) { + tokenContainer->AddStringToken((int)eDmDetailedRecST::epgname, info->Title()); + tokenContainer->AddStringToken((int)eDmDetailedRecST::shorttext, info->ShortText()); + tokenContainer->AddStringToken((int)eDmDetailedRecST::description, info->Description()); + const cEvent *event = info->GetEvent(); + if (event) { + cString recDate = event->GetDateString(); + cString recTime = event->GetTimeString(); + if (strstr(*recDate, "1970")) { + time_t start = recording->Start(); + recDate = DateString(start); + recTime = TimeString(start); + } + int duration = event->Duration() / 60; + int recDuration = recording->LengthInSeconds(); + recDuration = (recDuration>0) ? (recDuration / 60) : 0; + tokenContainer->AddStringToken((int)eDmDetailedRecST::date, *recDate); + tokenContainer->AddStringToken((int)eDmDetailedRecST::time, *recTime); + time_t startTime = event->StartTime(); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::month, sStartTime->tm_mon+1); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::duration, recDuration); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::durationhours, recDuration / 60); + tokenContainer->AddStringToken((int)eDmDetailedRecST::durationminutes, *cString::sprintf("%.2d", recDuration%60)); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::durationevent, duration); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::durationeventhours, duration / 60); + tokenContainer->AddStringToken((int)eDmDetailedRecST::durationeventminutes, *cString::sprintf("%.2d", duration%60)); + } + } + SetRecInfos(); + SetRecordingImages(recording->FileName()); + + vector loopInfo; + bool scrapInfoAvailable = LoadFullScrapInfo(NULL, recording); + int numActors = NumActors(); + loopInfo.push_back(numActors); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + if (scrapInfoAvailable) { + SetFullScrapInfo(tokenContainer, actorsIndex); + } + + SetDirty(); + return true; +} + +void cViewDetailRec::SetRecInfos(void) { + unsigned long long nRecSize = -1; + unsigned long long nFileSize[1000]; + nFileSize[0] = 0; + int i = 0; + struct stat filebuf; + cString filename; + int rc = 0; + do { + if (recording->IsPesRecording()) + filename = cString::sprintf("%s/%03d.vdr", recording->FileName(), ++i); + else + filename = cString::sprintf("%s/%05d.ts", recording->FileName(), ++i); + rc = stat(filename, &filebuf); + if (rc == 0) + nFileSize[i] = nFileSize[i-1] + filebuf.st_size; + else + if (ENOENT != errno) { + nRecSize = -1; + } + } while (i <= 999 && !rc); + nRecSize = nFileSize[i-1]; + + cMarks marks; + bool fHasMarks = marks.Load(recording->FileName(), recording->FramesPerSecond(), recording->IsPesRecording()) && marks.Count(); + cIndexFile *index = new cIndexFile(recording->FileName(), false, recording->IsPesRecording()); + + int nCutLength = 0; + long nCutInFrame = 0; + unsigned long long nRecSizeCut = nRecSize < 0 ? -1 : 0; + unsigned long long nCutInOffset = 0; + + if (fHasMarks && index) { + uint16_t FileNumber; + off_t FileOffset; + + bool fCutIn = true; + cMark *mark = marks.First(); + while (mark) { + int pos = mark->Position(); + index->Get(pos, &FileNumber, &FileOffset); //TODO: will disc spin up? + if (fCutIn) { + nCutInFrame = pos; + fCutIn = false; + if (nRecSize >= 0) + nCutInOffset = nFileSize[FileNumber-1] + FileOffset; + } else { + nCutLength += pos - nCutInFrame; + fCutIn = true; + if (nRecSize >= 0) + nRecSizeCut += nFileSize[FileNumber-1] + FileOffset - nCutInOffset; + } + cMark *nextmark = marks.Next(mark); + mark = nextmark; + } + if (!fCutIn) { + nCutLength += index->Last() - nCutInFrame; + index->Get(index->Last() - 1, &FileNumber, &FileOffset); + if (nRecSize >= 0) + nRecSizeCut += nFileSize[FileNumber-1] + FileOffset - nCutInOffset; + } + } + + if (nRecSize < 0) { + if ((nRecSize = ReadSizeVdr(recording->FileName())) < 0) { + nRecSize = DirSizeMB(recording->FileName()); + } + } + if (nRecSize >= 0) { + cString strRecSize = ""; + cString strRecSizeCut = ""; + + if (fHasMarks) { + if (nRecSize > MEGABYTE(1023)) { + strRecSize = cString::sprintf("%.2f GB", (float)nRecSize / MEGABYTE(1024)); + strRecSizeCut = cString::sprintf("%.2f GB", (float)nRecSizeCut / MEGABYTE(1024)); + } else { + strRecSize = cString::sprintf("%lld MB", nRecSize / MEGABYTE(1)); + strRecSizeCut = cString::sprintf("%lld MB", nRecSizeCut / MEGABYTE(1)); + } + } else { + if (nRecSize > MEGABYTE(1023)) { + strRecSize = cString::sprintf("%.2f GB", (float)nRecSize / MEGABYTE(1024)); + strRecSizeCut = strRecSize; + } else { + strRecSize = cString::sprintf("%lld MB", nRecSize / MEGABYTE(1)); + strRecSizeCut = strRecSize; + } + } + tokenContainer->AddStringToken((int)eDmDetailedRecST::recordingsize, *strRecSize); + tokenContainer->AddStringToken((int)eDmDetailedRecST::recordingsizecutted, *strRecSizeCut); + } + + const cRecordingInfo *info = recording->Info(); + if (info) { + cChannel *channel = Channels.GetByChannelID(info->ChannelID()); + if (channel) { + tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelname, channel->Name()); + tokenContainer->AddStringToken((int)eDmDetailedRecST::recchannelid, *channel->GetChannelID().ToString()); + tokenContainer->AddIntToken((int)eDmDetailedRecIT::recchannelnumber, channel->Number()); + } + } + + + if (index) { + int nLastIndex = index->Last(); + if (nLastIndex) { + string strLength = *IndexToHMSF(nLastIndex, false, recording->FramesPerSecond()); + string strLengthCutted = ""; + if (fHasMarks) { + strLengthCutted = *IndexToHMSF(nCutLength, false, recording->FramesPerSecond()); + } else { + strLengthCutted = strLength; + } + string strBitrate = *cString::sprintf("%.2f MBit/s", (float)nRecSize / nLastIndex * recording->FramesPerSecond() * 8 / MEGABYTE(1)); + tokenContainer->AddStringToken((int)eDmDetailedRecST::recordinglength, strLength.c_str()); + tokenContainer->AddStringToken((int)eDmDetailedRecST::recordinglengthcutted, strLengthCutted.c_str()); + tokenContainer->AddStringToken((int)eDmDetailedRecST::recordingbitrate, strBitrate.c_str()); + } + delete index; + } + + tokenContainer->AddStringToken((int)eDmDetailedRecST::recordingformat, recording->IsPesRecording() ? "PES" : "TS"); + + bool searchTimerFound = false; + if (info) { + const char *aux = NULL; + aux = info->Aux(); + if (aux) { + string strAux = aux; + string auxEpgsearch = StripXmlTag(strAux, "epgsearch"); + if (!auxEpgsearch.empty()) { + string searchTimer = StripXmlTag(auxEpgsearch, "searchtimer"); + if (!searchTimer.empty()) { + tokenContainer->AddStringToken((int)eDmDetailedRecST::searchtimer, searchTimer.c_str()); + searchTimerFound = true; + } + } + } + } + if (!searchTimerFound) + tokenContainer->AddStringToken((int)eDmDetailedRecST::searchtimer, "n.a."); +} + +int cViewDetailRec::ReadSizeVdr(const char *strPath) { + int dirSize = -1; + char buffer[20]; + char *strFilename = NULL; + if (-1 != asprintf(&strFilename, "%s/size.vdr", strPath)) { + struct stat st; + if (stat(strFilename, &st) == 0) { + int fd = open(strFilename, O_RDONLY); + if (fd >= 0) { + if (safe_read(fd, &buffer, sizeof(buffer)) >= 0) { + dirSize = atoi(buffer); + } + close(fd); + } + } + free(strFilename); + } + return dirSize; +} + +string cViewDetailRec::StripXmlTag(string &Line, const char *Tag) { + // set the search strings + stringstream strStart, strStop; + strStart << "<" << Tag << ">"; + strStop << ""; + // find the strings + string::size_type locStart = Line.find(strStart.str()); + string::size_type locStop = Line.find(strStop.str()); + if (locStart == string::npos || locStop == string::npos) + return ""; + // extract relevant text + int pos = locStart + strStart.str().size(); + int len = locStop - pos; + return len < 0 ? "" : Line.substr(pos, len); +} + +void cViewDetailRec::SetRecordingImages(const char *recPath) { + if (!recPath) { + return; + } + DIR *dirHandle; + struct dirent *dirEntry; + dirHandle = opendir(recPath); + if (!dirHandle) { + return; + } + int picsFound = 0; + int indexStr = (int)eDmDetailedRecST::recimg1path; + int indexInt = (int)eDmDetailedRecIT::recimg1avaialble; + while ( 0 != (dirEntry = readdir(dirHandle))) { + if (endswith(dirEntry->d_name, "jpg")) { + tokenContainer->AddStringToken(indexStr, *cString::sprintf("%s/%s", recPath, dirEntry->d_name)); + tokenContainer->AddIntToken(indexInt, 1); + picsFound++; + } + if (picsFound == 3) { + break; + } + } + closedir(dirHandle); +} + +/****************************************************************** +* cViewDetailText +******************************************************************/ +cViewDetailText::cViewDetailText(void) { + text = NULL; +} + +cViewDetailText::~cViewDetailText(void) { +} + +void cViewDetailText::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{text}", (int)eDmDetailedTextST::text); + InheritTokenContainer(); +} + +bool cViewDetailText::Parse(bool forced) { + if (!cViewElement::Parse()) + return false; + if (!text) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDmDetailedTextST::text, text); + SetDirty(); + return true; +} + +/****************************************************************** +* cViewDetailPlugin +******************************************************************/ +cViewDetailPlugin::cViewDetailPlugin(void) { +} + +cViewDetailPlugin::~cViewDetailPlugin(void) { +} + +void cViewDetailPlugin::SetTokenContainer(void) { + if (plugId == -1 || plugMenuId == -1) + return; + skindesignerapi::cTokenContainer *tkPlugMenu = plgManager->GetTokenContainer(plugId, plugMenuId); + tokenContainer = new skindesignerapi::cTokenContainer(*tkPlugMenu); + InheritTokenContainer(); +} + +void cViewDetailPlugin::Set(skindesignerapi::cTokenContainer *tk) { + tokenContainer->Clear(); + tokenContainer->SetTokens(tk); +} + +bool cViewDetailPlugin::Parse(bool forced) { + if (!cViewElement::Parse()) + return false; + SetDirty(); + return true; +} + +/****************************************************************** +* cViewDetailAdvancedPlugin +******************************************************************/ +cViewDetailAdvancedPlugin::cViewDetailAdvancedPlugin(int viewId, int plugId) { + this->plugId = plugId; + plugViewId = viewId; +} + +cViewDetailAdvancedPlugin::~cViewDetailAdvancedPlugin(void) { +} + +void cViewDetailAdvancedPlugin::SetTokenContainer(void) { + if (plugId == -1 || plugViewId == -1) + return; + skindesignerapi::cTokenContainer *tkDetail = plgManager->GetTokenContainerTab(plugId, plugViewId); + tokenContainer = new skindesignerapi::cTokenContainer(*tkDetail); + InheritTokenContainer(); +} + +void cViewDetailAdvancedPlugin::Set(skindesignerapi::cTokenContainer *tk) { + tokenContainer->Clear(); + tokenContainer->SetTokens(tk); +} + +bool cViewDetailAdvancedPlugin::Parse(bool forced) { + if (!cViewElement::Parse()) + return false; + SetDirty(); + return true; +} diff --git a/coreengine/viewdetail.h b/coreengine/viewdetail.h new file mode 100644 index 0000000..9fb63e6 --- /dev/null +++ b/coreengine/viewdetail.h @@ -0,0 +1,114 @@ +#ifndef __VIEWDETAIL_H +#define __VIEWDETAIL_H + +#include "../services/epgsearch.h" +#include "../extensions/scrapmanager.h" +#include "viewelement.h" +/****************************************************************** +* cViewDetail +******************************************************************/ +class cViewDetail : public cViewElement, public cScrapManager { +protected: + int plugId; + int plugMenuId; + cArea *activeTab; + int activeTabIndex; + int numTabs; + void SetActiveTab(void); +public: + cViewDetail(void); + virtual ~cViewDetail(void); + void SetPlugId(int id) { plugId = id; }; + void SetPlugMenuId(int id) { plugMenuId = id; }; + int GetWidth(void); + void ResetTabs(void); + void Clear(void); + void Close(void); + void Render(void); + void Scrollbar(int &barheight, int &offset, bool &end); + bool ScrollUp(bool page = false); + bool ScrollDown(bool page = false); + int GetTabs(vector &tabs); + int NumTabs(void) { return numTabs; }; + int ActiveTab(void) { return activeTabIndex; }; + void NextTab(void); + void PrevTab(void); + void SetTransparency(int transparency, bool forceDetached = false); +}; +/****************************************************************** +* cViewDetailEpg +******************************************************************/ +class cViewDetailEpg : public cViewDetail { +protected: + const cEvent *event; + int rerunsIndex; + int actorsIndex; + cList *LoadReruns(void); + int NumReruns(cList *reruns); + void SetReruns(cList *reruns); +public: + cViewDetailEpg(void); + virtual ~cViewDetailEpg(void); + void SetTokenContainer(void); + void SetEvent(const cEvent *event) { this->event = event; }; + bool Parse(bool forced = false); +}; +/****************************************************************** +* cViewDetailRec +******************************************************************/ +class cViewDetailRec : public cViewDetail { +protected: + const cRecording *recording; + int actorsIndex; + void SetRecInfos(void); + int ReadSizeVdr(const char *strPath); + string StripXmlTag(string &Line, const char *Tag); + void SetRecordingImages(const char *recPath); +public: + cViewDetailRec(void); + virtual ~cViewDetailRec(void); + void SetTokenContainer(void); + void SetRecording(const cRecording *recording) { this->recording = recording; }; + bool Parse(bool forced = false); +}; +/****************************************************************** +* cViewDetailText +******************************************************************/ +class cViewDetailText : public cViewDetail { +protected: + const char *text; +public: + cViewDetailText(void); + virtual ~cViewDetailText(void); + void SetTokenContainer(void); + void SetText(const char *text) { this->text = text; }; + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cViewDetailPlugin +******************************************************************/ +class cViewDetailPlugin : public cViewDetail { +protected: +public: + cViewDetailPlugin(void); + virtual ~cViewDetailPlugin(void); + void SetTokenContainer(void); + void Set(skindesignerapi::cTokenContainer *tk); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cViewDetailAdvancedPlugin +******************************************************************/ +class cViewDetailAdvancedPlugin : public cViewDetail { +protected: + int plugViewId; +public: + cViewDetailAdvancedPlugin(int viewId, int plugId); + virtual ~cViewDetailAdvancedPlugin(void); + void SetTokenContainer(void); + void Set(skindesignerapi::cTokenContainer *tk); + bool Parse(bool forced = false); +}; +#endif //__VIEWDETAIL_H \ No newline at end of file diff --git a/coreengine/viewdisplaychannel.c b/coreengine/viewdisplaychannel.c new file mode 100644 index 0000000..9be9393 --- /dev/null +++ b/coreengine/viewdisplaychannel.c @@ -0,0 +1,199 @@ +#include "viewdisplaychannel.h" +#include "../config.h" + +/************************************************************************************ +* cViewChannel +************************************************************************************/ + +cViewChannel::cViewChannel(void) { + veCustomTokens = NULL; + ClearVariables(); + viewId = eViewType::DisplayChannel; + viewName = strdup("displaychannel"); + numViewElements = (int)eVeDisplayChannel::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + SetViewElements(); + veMessage = NULL; + veChannelInfo = NULL; + veChannelGroup = NULL; + veEpgInfo = NULL; + veProgressBar = NULL; + veStatusInfo = NULL; + veScraperContent = NULL; + veEcmInfo = NULL; +} + +cViewChannel::~cViewChannel() { +} + +void cViewChannel::SetViewElements(void) { + viewElementNames.insert(pair("background", (int)eVeDisplayChannel::background)); + viewElementNames.insert(pair("channelgroup", (int)eVeDisplayChannel::channelgroup)); + viewElementNames.insert(pair("channelinfo", (int)eVeDisplayChannel::channelinfo)); + viewElementNames.insert(pair("epginfo", (int)eVeDisplayChannel::epginfo)); + viewElementNames.insert(pair("progressbar", (int)eVeDisplayChannel::progressbar)); + viewElementNames.insert(pair("statusinfo", (int)eVeDisplayChannel::statusinfo)); + viewElementNames.insert(pair("audioinfo", (int)eVeDisplayChannel::audioinfo)); + viewElementNames.insert(pair("ecminfo", (int)eVeDisplayChannel::ecminfo)); + viewElementNames.insert(pair("screenresolution", (int)eVeDisplayChannel::screenresolution)); + viewElementNames.insert(pair("signalquality", (int)eVeDisplayChannel::signalquality)); + viewElementNames.insert(pair("devices", (int)eVeDisplayChannel::devices)); + viewElementNames.insert(pair("currentweather", (int)eVeDisplayChannel::currentweather)); + viewElementNames.insert(pair("scrapercontent", (int)eVeDisplayChannel::scrapercontent)); + viewElementNames.insert(pair("datetime", (int)eVeDisplayChannel::datetime)); + viewElementNames.insert(pair("time", (int)eVeDisplayChannel::time)); + viewElementNames.insert(pair("message", (int)eVeDisplayChannel::message)); + viewElementNames.insert(pair("customtokens", (int)eVeDisplayChannel::customtokens)); +} + +void cViewChannel::SetViewElementObjects(void) { + for (int i = 0; i < numViewElements; i++) { + if (!viewElements[i]) + continue; + if (dynamic_cast(viewElements[i])) + { + veMessage = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) { + + veChannelInfo = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veChannelGroup = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veEpgInfo = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veProgressBar = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veStatusInfo = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veScraperContent = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veEcmInfo = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veCustomTokens = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + viewElements[i]->SetDetached(); + } + } +} + +void cViewChannel::ClearVariables(void) { + cView::ClearVariables(); + channelChange = false; + displayChannelGroups = false; + if (veCustomTokens) + veCustomTokens->Reset(); +} + +void cViewChannel::SetChannel(const cChannel *channel, int number) { + channelChange = true; + bool wasChannelGroups = displayChannelGroups; + displayChannelGroups = false; + + if (veChannelInfo) { + veChannelInfo->Set(channel, number); + } + + if (channel) { + if (!channel->GroupSep()) { + if (wasChannelGroups) + Clear((int)eVeDisplayChannel::channelgroup); + if (veStatusInfo) + veStatusInfo->Set(channel); + if (veEcmInfo) + veEcmInfo->Set(channel); + } else { + displayChannelGroups = true; + Clear((int)eVeDisplayChannel::channelinfo); + Clear((int)eVeDisplayChannel::epginfo); + Clear((int)eVeDisplayChannel::statusinfo); + Clear((int)eVeDisplayChannel::progressbar); + Clear((int)eVeDisplayChannel::screenresolution); + Clear((int)eVeDisplayChannel::signalquality); + Clear((int)eVeDisplayChannel::audioinfo); + Clear((int)eVeDisplayChannel::ecminfo); + Clear((int)eVeDisplayChannel::devices); + Clear((int)eVeDisplayChannel::customtokens); + if (veChannelGroup) + veChannelGroup->Set(channel); + } + } +} + +void cViewChannel::SetEvents(const cEvent *present, const cEvent *following) { + Clear((int)eVeDisplayChannel::epginfo); + Clear((int)eVeDisplayChannel::progressbar); + Clear((int)eVeDisplayChannel::scrapercontent); + if (veProgressBar) + veProgressBar->Set(present); + + if (!present && !following) + return; + + if (veEpgInfo) + veEpgInfo->Set(present, following); + + if (veScraperContent) + veScraperContent->Set(present); +} + +void cViewChannel::SetMessage(eMessageType type, const char *text) { + if (veMessage) { + if (text) + veMessage->Set(type, text); + else + veMessage->Clear(); + } +} + +void cViewChannel::Flush(void) { + if (init) { + sdOsd.LockFlush(); + Render((int)eVeDisplayChannel::background); + Render((int)eVeDisplayChannel::progressbar); + Render((int)eVeDisplayChannel::currentweather); + } + + if (!displayChannelGroups) { + //normal display + Render((int)eVeDisplayChannel::channelinfo); + Render((int)eVeDisplayChannel::epginfo); + Render((int)eVeDisplayChannel::statusinfo); + Render((int)eVeDisplayChannel::scrapercontent); + Render((int)eVeDisplayChannel::progressbar, channelChange); + Render((int)eVeDisplayChannel::screenresolution); + Render((int)eVeDisplayChannel::signalquality); + Render((int)eVeDisplayChannel::audioinfo); + Render((int)eVeDisplayChannel::ecminfo); + Render((int)eVeDisplayChannel::devices); + Render((int)eVeDisplayChannel::customtokens); + Render((int)eVeDisplayChannel::message); + } else { + //channelgroup display + Render((int)eVeDisplayChannel::channelgroup); + } + Render((int)eVeDisplayChannel::datetime); + Render((int)eVeDisplayChannel::time); + channelChange = false; + cView::Flush(); +} + diff --git a/coreengine/viewdisplaychannel.h b/coreengine/viewdisplaychannel.h new file mode 100644 index 0000000..d42f8ce --- /dev/null +++ b/coreengine/viewdisplaychannel.h @@ -0,0 +1,31 @@ +#ifndef __VIEWDISPLAYCHANNEL_H +#define __VIEWDISPLAYCHANNEL_H + +#include "view.h" + +class cViewChannel : public cView { +private: + cVeMessage *veMessage; + cVeCustomTokens *veCustomTokens; + cVeDcChannelInfo *veChannelInfo; + cVeDcChannelGroup *veChannelGroup; + cVeDcEpgInfo *veEpgInfo; + cVeDcProgressBar *veProgressBar; + cVeDcStatusInfo *veStatusInfo; + cVeDcScraperContent *veScraperContent; + cVeDcEcmInfo *veEcmInfo; + bool channelChange; + bool displayChannelGroups; + void SetViewElements(void); + void ClearVariables(void); + void SetViewElementObjects(void); +public: + cViewChannel(void); + virtual ~cViewChannel(void); + void SetChannel(const cChannel *channel, int number); + void SetEvents(const cEvent *present, const cEvent *following); + void SetMessage(eMessageType type, const char *text); + void Flush(void); +}; + +#endif //__VIEWDISPLAYCHANNEL_H \ No newline at end of file diff --git a/coreengine/viewdisplaymenu.c b/coreengine/viewdisplaymenu.c new file mode 100644 index 0000000..d65b145 --- /dev/null +++ b/coreengine/viewdisplaymenu.c @@ -0,0 +1,1705 @@ +#include "viewdisplaymenu.h" +#include "../config.h" + +/************************************************************************************ +* cViewMenu +************************************************************************************/ +cViewMenu::cViewMenu(void) { + menuDefault = NULL; + menuMain = NULL; + menuSetup = NULL; + menuSchedules = NULL; + menuChannels = NULL; + menuTimers = NULL; + menuRecordings = NULL; + menuDetailedEpg = NULL; + menuDetailedRec = NULL; + menuDetailedText = NULL; + ClearVariables(); + viewId = eViewType::DisplayMenu; + viewName = strdup("displaymenu"); + numViewElements = (int)eVeDisplayMenu::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + viewElementsHorizontal = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElementsHorizontal[i] = NULL; + } + SetViewElements(); + int numPluginMenus = plgManager->GetNumPluginMenus(); + numSubviews = (int)eSvDisplayMenu::count + numPluginMenus; + subViews = new cSubView*[numSubviews]; + for (int i=0; i < numSubviews; i++) { + subViews[i] = NULL; + } + SetSubViews(); + menuCat = mcUnknown; + plugName = NULL; +} + +cViewMenu::~cViewMenu() { + for (int i=0; i< numSubviews; i++) + delete subViews[i]; + delete[] subViews; +} + +void cViewMenu::SetGlobals(cGlobals *globals) { + cView::SetGlobals(globals); + for (int i=0; i < numSubviews; ++i) { + if (subViews[i]) { + subViews[i]->SetGlobals(globals); + } + } +} + +void cViewMenu::PreCache(void) { + cView::PreCache(); + for (int i=0; i < numSubviews; i++) { + if (subViews[i]) { + subViews[i]->SetContainer(0, 0, attribs->Width(), attribs->Height()); + subViews[i]->PreCache(); + //setting default viewelements for subviews + for (int ve = (int)eVeDisplayMenu::background; ve < (int)eVeDisplayMenu::count; ve++) { + if (viewElements[ve] && !subViews[i]->ViewElementSet(ve)) { + subViews[i]->SetViewElement((eVeDisplayMenu)ve, viewElements[ve]); + } + } + for (int ve = (int)eVeDisplayMenu::background; ve < (int)eVeDisplayMenu::count; ve++) { + if (viewElementsHorizontal[ve] && !subViews[i]->ViewElementHorizontalSet(ve)) { + subViews[i]->SetViewElementHorizontal((eVeDisplayMenu)ve, viewElementsHorizontal[ve]); + } + } + } + } +} + +void cViewMenu::SetViewElementObjects(void) { + //setting subviews + for (int i=0; i < numSubviews; i++) { + if (!subViews[i]) + continue; + if (i == (int)eSvDisplayMenu::menudefault) + menuDefault = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::main) + menuMain = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::setup) + menuSetup = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::schedules) + menuSchedules = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::channels) + menuChannels = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::timers) + menuTimers = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::recordings) + menuRecordings = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::detailepg) + menuDetailedEpg = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::detailrec) + menuDetailedRec = dynamic_cast(subViews[i]); + else if (i == (int)eSvDisplayMenu::detailtext) + menuDetailedText = dynamic_cast(subViews[i]); + } +} + +void cViewMenu::SetViewElements(void) { + viewElementNames.insert(pair("background", (int)eVeDisplayMenu::background)); + viewElementNames.insert(pair("header", (int)eVeDisplayMenu::header)); + viewElementNames.insert(pair("datetime", (int)eVeDisplayMenu::datetime)); + viewElementNames.insert(pair("time", (int)eVeDisplayMenu::time)); + viewElementNames.insert(pair("colorbuttons", (int)eVeDisplayMenu::colorbuttons)); + viewElementNames.insert(pair("message", (int)eVeDisplayMenu::message)); + viewElementNames.insert(pair("scrollbar", (int)eVeDisplayMenu::scrollbar)); + viewElementNames.insert(pair("sortmode", (int)eVeDisplayMenu::sortmode)); +} + +void cViewMenu::SetSubViews(void) { + //adding VDR submenus + subviewNames.insert(pair("menudefault", (int)eSvDisplayMenu::menudefault)); + subviewNames.insert(pair("menumain", (int)eSvDisplayMenu::main)); + subviewNames.insert(pair("menusetup", (int)eSvDisplayMenu::setup)); + subviewNames.insert(pair("menuschedules", (int)eSvDisplayMenu::schedules)); + subviewNames.insert(pair("menuchannels", (int)eSvDisplayMenu::channels)); + subviewNames.insert(pair("menutimers", (int)eSvDisplayMenu::timers)); + subviewNames.insert(pair("menurecordings", (int)eSvDisplayMenu::recordings)); + subviewNames.insert(pair("menudetailedepg", (int)eSvDisplayMenu::detailepg)); + subviewNames.insert(pair("menudetailedrecording", (int)eSvDisplayMenu::detailrec)); + subviewNames.insert(pair("menudetailedtext", (int)eSvDisplayMenu::detailtext)); + //adding additional plugin subviews + int subViewNumber = (int)eSvDisplayMenu::count; + map *plugMenus = NULL; + string plugName = ""; + int plugId = -1; + plgManager->InitPluginMenuIterator(); + while ( plugMenus = plgManager->GetPluginMenus(plugName, plugId) ) { + for (map ::iterator it = plugMenus->begin(); it != plugMenus->end(); it++) { + int menuNumber = it->first; + cString menuName = cString::sprintf("menuplugin-%s-%d", plugName.c_str(), menuNumber); + subviewNames.insert(pair(*menuName, subViewNumber)); + plgManager->AddSubviewMapping(plugId, menuNumber, subViewNumber); + subViewNumber++; + } + } +} + +void cViewMenu::ClearVariables(void) { + cView::ClearVariables(); + menuChange = true; + listChange = true; + detailViewInit = false; + menuCat = mcUnknown; + pluginIdSet = false; + plugId = -1; + plugMenuId = -1; + activeSubview = NULL; + activeSubviewLast = NULL; +} + +int cViewMenu::SubviewId(const char *name) { + map::iterator hit = subviewNames.find(name); + if (hit != subviewNames.end()) + return (int)hit->second; + return ATTR_UNKNOWN; +} + +bool cViewMenu::ValidSubView(const char *subView) { + if (SubviewId(subView) != ATTR_UNKNOWN) + return true; + return false; +} + +cSubView *cViewMenu::CreateSubview(const char *name) { + cSubView *sv = NULL; + if (!strcmp(name, "menudefault")) + sv = new cViewMenuDefault(name); + else if (!strcmp(name, "menumain")) + sv = new cViewMenuMain(name); + else if (!strcmp(name, "menusetup")) + sv = new cViewMenuSetup(name); + else if (!strcmp(name, "menuschedules")) + sv = new cViewMenuSchedules(name); + else if (!strcmp(name, "menuchannels")) + sv = new cViewMenuChannels(name); + else if (!strcmp(name, "menutimers")) + sv = new cViewMenuTimers(name); + else if (!strcmp(name, "menurecordings")) + sv = new cViewMenuRecordings(name); + else if (!strcmp(name, "menudetailedepg")) + sv = new cViewMenuDetail(name); + else if (!strcmp(name, "menudetailedrecording")) + sv = new cViewMenuDetail(name); + else if (!strcmp(name, "menudetailedtext")) + sv = new cViewMenuDetail(name); + return sv; +} + +cSubView *cViewMenu::CreatePluginview(const char *plugname, int plugId, int menuNumber, int menuType) { + cString menuName = cString::sprintf("menuplugin-%s-%d", plugname, menuNumber); + cSubView *pv = NULL; + if (menuType == skindesignerapi::mtList) + pv = new cViewMenuPlugin(*menuName); + else if (menuType == skindesignerapi::mtText) + pv = new cViewMenuDetail(*menuName); + if (pv) { + pv->SetPlugId(plugId); + pv->SetPlugMenuId(menuNumber); + } + return pv; +} + + +void cViewMenu::AddPluginview(cSubView *plugView) { + int id = SubviewId(plugView->GetViewName()); + if (id == ATTR_UNKNOWN) + return; + subViews[id] = plugView; +} + +void cViewMenu::AddSubview(const char *sSubView, cSubView *subView) { + int id = SubviewId(sSubView); + if (id == ATTR_UNKNOWN) + return; + subViews[id] = subView; +} + +/* eMenuCategory: + -1 mcUndefined, + 0 mcUnknown, + 1 mcMain, + 2 mcSchedule, + 3 mcScheduleNow, + 4 mcScheduleNext, + 5 mcChannel, + 6 mcChannelEdit, + 7 mcTimer, + 8 mcTimerEdit, + 9 mcRecording, + 10 mcRecordingInfo, + 11 mcRecordingEdit, + 12 mcPlugin, + 13 mcPluginSetup, + 14 mcSetup, + 15 mcSetupOsd, + 16 mcSetupEpg, + 17 mcSetupDvb, + 18 mcSetupLnb, + 19 mcSetupCam, + 20 mcSetupRecord, + 21 mcSetupReplay, + 22 mcSetupMisc, + 23 mcSetupPlugins, + 24 mcCommand, + 25 mcEvent, + 26 mcText, + 27 mcFolder, + 28 mcCam +*/ +void cViewMenu::SetSubView(eMenuCategory MenuCat) { + //menuCat --> old menucat + //MenuCat --> new menucat + if (menuCat == mcMain) { + cViewMenuMain *menuMain = dynamic_cast(activeSubview); + if (menuMain) { + plugName = menuMain->GetPlugin(); + } + } + //first check plugin menu + if (MenuCat == mcPlugin) { + bool plugMenuFound = SetPluginSubView(MenuCat); + if (plugMenuFound) { + menuCat = MenuCat; + return; + } + } + //then check regular menus + bool catChange = false; + if (menuCat != MenuCat) { + catChange = true; + } else { + return; + } + cSubView *newSubview = NULL; + menuCat = MenuCat; + switch (MenuCat) { + case mcMain: + newSubview = subViews[(int)eSvDisplayMenu::main]; + break; + case mcSchedule: + case mcScheduleNow: + case mcScheduleNext: + newSubview = subViews[(int)eSvDisplayMenu::schedules]; + break; + case mcChannel: + newSubview = subViews[(int)eSvDisplayMenu::channels]; + break; + case mcTimer: + newSubview = subViews[(int)eSvDisplayMenu::timers]; + break; + case mcRecording: + newSubview = subViews[(int)eSvDisplayMenu::recordings]; + break; + case mcSetup: + newSubview = subViews[(int)eSvDisplayMenu::setup]; + break; + case mcEvent: + newSubview = subViews[(int)eSvDisplayMenu::detailepg]; + break; + case mcRecordingInfo: + newSubview = subViews[(int)eSvDisplayMenu::detailrec]; + break; + case mcText: + newSubview = subViews[(int)eSvDisplayMenu::detailtext]; + break; + default: + newSubview = subViews[(int)eSvDisplayMenu::menudefault]; + //setting plugin name for detecting plugins in default menus + cViewMenuDefault *menuDefault = dynamic_cast(newSubview); + if (menuDefault) { + menuDefault->SetPlugin(plugName); + } + break; + }; + if (catChange) { + menuChange = true; + activeSubview->Clear(); + activeSubviewLast = activeSubview; + activeSubview = newSubview; + if (!activeSubview) + activeSubview = subViews[(int)eSvDisplayMenu::menudefault]; + activeSubview->SetMenuCategory(MenuCat); + } +} + +bool cViewMenu::SetPluginSubView(eMenuCategory menuCat) { + if (!pluginIdSet) + return false; + cSubView *newSubview = NULL; + if (plugId >= 0 && plugMenuId >= 0) { + int subViewId = plgManager->GetSubviewId(plugId, plugMenuId); + if (subViewId >= 0 && subViews[subViewId]) { + newSubview = subViews[subViewId]; + menuChange = true; + activeSubview->Clear(); + activeSubviewLast = activeSubview; + activeSubview = newSubview; + activeSubview->SetMenuCategory(menuCat); + return true; + } + } + return false; +} + +void cViewMenu::WakeViewElements(void) { + cView::WakeViewElements(); + if (activeSubview) + activeSubview->WakeViewElements(); +} + + +void cViewMenu::SetSortMode(eMenuSortMode sortMode) { + if (activeSubview) + activeSubview->SetSortMode(sortMode); +} + +void cViewMenu::SetPluginMenu(int plugId, int plugMenuId) { + this->plugId = plugId; + this->plugMenuId = plugMenuId; + pluginIdSet = true; +} + +int cViewMenu::NumListItems(void) { + return activeSubview->NumListItems(); +} + +eMenuOrientation cViewMenu::MenuOrientation(void) { + return activeSubview->MenuOrientation(); +} + +const cFont *cViewMenu::GetTextAreaFont(void) { + return activeSubview->GetTextAreaFont(); +} + +int cViewMenu::GetTextAreaWidth(void) { + if (!menuDetailedText) + return 0; + return menuDetailedText->GetWidth(); +} + +int cViewMenu::GetListWidth(void) { + return activeSubview->GetListWidth(); +} + +void cViewMenu::SetTitleHeader(const char *title) { + activeSubview->SetTitle(title); +} + +void cViewMenu::SetMessage(eMessageType type, const char *text) { + activeSubview->SetMessage(type, text); +} + +void cViewMenu::SetChannelHeader(const cEvent *event) { + if (menuChange && menuCat == mcSchedule) { + const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); + if (channel) + activeSubview->SetChannel(channel); + } +} + +void cViewMenu::SetMenuButtons(const char *red, const char *green, const char *yellow, const char *blue) { + activeSubview->SetMenuButtons(red, green, yellow, blue); +} + +void cViewMenu::SetScrollbar(int total, int offset) { + activeSubview->SetScrollbar(total, offset); +} + +void cViewMenu::SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5) { + menuDefault->SetTabs(tab1, tab2, tab3, tab4, tab5); +} + +void cViewMenu::SetItem(const char *text, int index, bool current, bool selectable) { + if (menuCat == mcMain && menuMain) { + menuMain->SetItem(text, index, current, selectable); + } else if (menuCat == mcSetup && menuSetup) { + menuSetup->SetItem(text, index, current, selectable); + } else { + menuDefault->SetItem(text, index, current, selectable); + } + listChange = true; +} + +bool cViewMenu::SetItemEvent(const cEvent *event, int index, bool current, bool selectable, + const cChannel *channel, bool withDate, eTimerMatch timerMatch) { + if (!menuSchedules) + return false; + menuSchedules->SetItem(event, index, current, selectable, channel, withDate, timerMatch); + listChange = true; + return true; +} + +bool cViewMenu::SetItemTimer(const cTimer *timer, int index, bool current, bool selectable) { + if (!menuTimers) + return false; + menuTimers->SetItem(timer, index, current, selectable); + listChange = true; + return true; +} + +bool cViewMenu::SetItemChannel(const cChannel *channel, int index, bool current, bool selectable, bool withProvider) { + if (!menuChannels) + return false; + menuChannels->SetItem(channel, index, current, selectable, withProvider); + listChange = true; + return true; +} + +bool cViewMenu::SetItemRecording(const cRecording *recording, int index, bool current, bool selectable, int level, int total, int New) { + if (!menuRecordings) + return false; + menuRecordings->SetItem(recording, index, current, selectable, level, total, New); + listChange = true; + return true; +} + +bool cViewMenu::SetItemPlugin(skindesignerapi::cTokenContainer *tk, int index, bool current, bool selectable) { + cViewMenuPlugin *menuPlugin = dynamic_cast(activeSubview); + if (!menuPlugin) { + return false; + } + menuPlugin->SetItem(tk, index, current, selectable); + listChange = true; + return true; +} + +void cViewMenu::SetEvent(const cEvent *event) { + menuDetailedEpg->SetEvent(event); + detailViewInit = true; +} + +void cViewMenu::SetRecording(const cRecording *recording) { + menuDetailedRec->SetRecording(recording); + detailViewInit = true; +} + +void cViewMenu::SetText(const char *text) { + menuDetailedText->SetText(text); + detailViewInit = true; +} + +bool cViewMenu::SetPluginText(skindesignerapi::cTokenContainer *tk) { + cViewMenuDetail *menuPlugin = dynamic_cast(activeSubview); + if (!menuPlugin) { + return false; + } + menuPlugin->SetPluginText(tk); + detailViewInit = true; + return true; +} + +void cViewMenu::SetCurrentRecording(const char *currentRec) { + if (menuMain) { + menuMain->SetCurrentRecording(currentRec); } +} + +void cViewMenu::KeyDetailView(bool up, bool page) { + cViewMenuDetail *detailView = dynamic_cast(activeSubview); + if (!detailView) + return; + if (up && page) { + detailView->KeyLeft(); + } else if (!up && page) { + detailView->KeyRight(); + } else if (up && !page) { + detailView->KeyUp(); + } else if (!up && !page) { + detailView->KeyDown(); + } +} + +bool cViewMenu::Init(void) { + activeSubview = subViews[(int)eSvDisplayMenu::main]; + return cView::Init(); +} + +void cViewMenu::Close(void) { + delete fader; + fader = NULL; + if (FadeTime() > 0) { + fader = new cAnimation((cFadable*)this, false); + fader->Fade(); + delete fader; + fader = NULL; + } + for (int i=0; i < numSubviews; i++) { + if (subViews[i]) { + subViews[i]->Close(); + } + } + for (int i=0; i < numViewElements; i++) { + if (viewElements[i]) { + viewElements[i]->Close(); + } + if (viewElementsHorizontal[i]) { + viewElementsHorizontal[i]->Close(); + } + } + UnScaleTv(); + ClearVariables(); + sdOsd.DeleteOsd(); +} + +void cViewMenu::Clear(void) { + activeSubview->ClearViewList(); +} + +void cViewMenu::Flush(void) { + if (init) { + sdOsd.LockFlush(); + } + bool staticInitiated = false; + if (menuChange) { + newTvFrame = activeSubview->GetTvFrame(); + menuInit = true; + activeSubview->DrawStaticVEs(); + pluginIdSet = false; + menuChange = false; + staticInitiated = true; + } + if (listChange) { + activeSubview->DrawList(); + listChange = false; + } + if (detailViewInit) { + if (!staticInitiated) + activeSubview->DrawStaticVEs(); + activeSubview->DrawDetailedView(); + pluginIdSet = false; + detailViewInit = false; + } + activeSubview->DrawDynamicVEs(); + cView::Flush(); +} + +void cViewMenu::SetTransparency(int transparency, bool forceDetached) { + activeSubview->SetTransparency(transparency, forceDetached); + if (menuDetailedEpg) + menuDetailedEpg->SetTransparency(transparency); + if (menuDetailedRec) + menuDetailedRec->SetTransparency(transparency); + if (menuDetailedText) + menuDetailedText->SetTransparency(transparency); +} + +void cViewMenu::Debug(void) { + cView::Debug(); + for (int i=0; i < numSubviews; i++) { + if (subViews[i]) { + subViews[i]->Debug(); + } + } +} + +/*********************************************************** +* cSubView +***********************************************************/ +cSubView::cSubView(const char *name) { + menuCat = mcUnknown; + plugId = -1; + plugMenuId = -1; + this->viewName = strdup(name); + numViewElements = (int)eVeDisplayMenu::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + viewElementsHorizontal = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElementsHorizontal[i] = NULL; + } + background = NULL; + header = NULL; + datetime = NULL; + time = NULL; + message = NULL; + sortmode = NULL; + colorbuttons = NULL; + scrollbar = NULL; + viewList = NULL; + viewListVertical = NULL; + viewListHorizontal = NULL; + SetViewElements(); +} + +cSubView::~cSubView(void) { + delete viewListHorizontal; + delete viewListVertical; +} + +void cSubView::SetGlobals(cGlobals *globals) { + cView::SetGlobals(globals); + if (viewListVertical) + viewListVertical->SetGlobals(globals); + if (viewListHorizontal) + viewListHorizontal->SetGlobals(globals); +} + +void cSubView::PreCache(void) { + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->Cache(); + cView::PreCache(); + if (viewListVertical) { + viewListVertical->SetPlugId(plugId); + viewListVertical->SetPlugMenuId(plugMenuId); + viewListVertical->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + viewListVertical->PreCache(); + } + if (viewListHorizontal) { + viewListHorizontal->SetPlugId(plugId); + viewListHorizontal->SetPlugMenuId(plugMenuId); + viewListHorizontal->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + viewListHorizontal->PreCache(); + } +} + +bool cSubView::ViewElementSet(int ve) { + if (ve >= 0 && ve < (int)eVeDisplayMenu::count && viewElements[ve]) + return true; + return false; +} + +bool cSubView::ViewElementHorizontalSet(int ve) { + if (ve >= 0 && ve < (int)eVeDisplayMenu::count && viewElementsHorizontal[ve]) + return true; + return false; +} + +void cSubView::SetViewElement(eVeDisplayMenu ve, cViewElement *viewElement) { + switch (ve) { + case eVeDisplayMenu::background: + if (!background) + background = viewElement; + break; + case eVeDisplayMenu::header: + if (!header) + header = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::datetime: + if (!datetime) + datetime = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::time: + if (!time) + time = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::message: + if (!message) + message = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::sortmode: + if (!sortmode) + sortmode = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::colorbuttons: + if (!colorbuttons) + colorbuttons = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::scrollbar: + if (!scrollbar) + scrollbar = dynamic_cast(viewElement); + break; + default: + break; + }; +} + +void cSubView::SetViewElementHorizontal(eVeDisplayMenu ve, cViewElement *viewElement) { + eOrientation orientation = attribs->Orientation(); + if (orientation != eOrientation::horizontal) + return; + switch (ve) { + case eVeDisplayMenu::background: + if (!background) + background = viewElement; + break; + case eVeDisplayMenu::header: + if (!header) + header = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::datetime: + if (!datetime) + datetime = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::time: + if (!time) + time = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::message: + if (!message) + message = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::sortmode: + if (!sortmode) + sortmode = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::colorbuttons: + if (!colorbuttons) + colorbuttons = dynamic_cast(viewElement); + break; + case eVeDisplayMenu::scrollbar: + if (!scrollbar) + scrollbar = dynamic_cast(viewElement); + break; + default: + break; + }; +} + +void cSubView::AddViewList(cViewList *viewList) { + eOrientation orientation = viewList->Orientation(); + if (orientation == eOrientation::vertical) { + viewListVertical = viewList; + } else if (orientation == eOrientation::horizontal) { + viewListHorizontal = viewList; + } else { + viewListVertical = viewList; + } +} + +int cSubView::NumListItems(void) { + if (viewList) + return viewList->NumItems(); + return 0; +} + +eMenuOrientation cSubView::MenuOrientation(void) { + eOrientation orientation = attribs->Orientation(); + if (orientation == eOrientation::horizontal) + return moHorizontal; + return moVertical; +} + +void cSubView::SetTitle(const char *title) { + if (header) { + header->SetTitle(title); + } +} + +void cSubView::SetChannel(const cChannel *channel) { + if (header) { + header->SetChannel(channel); + } +} + +void cSubView::SetMessage(eMessageType type, const char *text) { + if (!message) + return; + if (!text) { + message->Clear(); + message->Hide(); + return; + } + message->Set(type, text); + message->Show(); + if (message->Parse()) + message->Render(); +} + +void cSubView::SetMenuButtons(const char *red, const char *green, const char *yellow, const char *blue) { + if (!colorbuttons) + return; + colorbuttons->SetButtons(red, green, yellow, blue); + if (colorbuttons->Parse()) { + colorbuttons->Show(); + colorbuttons->Render(); + } +} + +void cSubView::SetScrollbar(int total, int offset) { + if (!scrollbar) + return; + scrollbar->SetList(total, offset, NumListItems()); + if (scrollbar->Parse()) { + scrollbar->Show(); + scrollbar->Render(); + } +} + +void cSubView::SetSortMode(eMenuSortMode sortMode) { + if (!sortmode) + return; + sortmode->Set(sortMode); + if (sortmode->Parse()) { + sortmode->Show(); + sortmode->Render(); + } +} + +void cSubView::Close(void) { + ClearVariables(); + for (int i=0; i < numViewElements; i++) { + if (!viewElements[i]) + continue; + viewElements[i]->Close(); + } + for (int i=0; i < numViewElements; i++) { + if (!viewElementsHorizontal[i]) + continue; + viewElementsHorizontal[i]->Close(); + } + if (viewList) + viewList->Close(); +} + +void cSubView::ClearViewList(void) { + if (viewList) + viewList->Clear(); +} + +void cSubView::WakeViewElements(void) { + for (int i = 0; i < numViewElements; i++) { + if (viewElements[i]) { + viewElements[i]->WakeUp(); + } + if (viewElementsHorizontal[i]) { + viewElementsHorizontal[i]->WakeUp(); + } + } +} + +void cSubView::Clear(void) { + if (background) background->Hide(); + if (datetime) datetime->Hide(); + if (time) time->Hide(); + if (header) header->Hide(); + if (colorbuttons) colorbuttons->Hide(); + if (scrollbar) scrollbar->Hide(); + if (sortmode) { + sortmode->Reset(); + sortmode->Hide(); + } + + if (viewList) viewList->Close(); +} + +void cSubView::DrawStaticVEs(void) { + if (background) { + background->Show(); + background->Render(); + } + if (header) { + header->Show(); + header->Set(menuCat); + if (header->Parse()) + header->Render(); + } +} + +void cSubView::DrawDynamicVEs(void) { + if (datetime) { + datetime->Show(); + if (datetime->Parse()) + datetime->Render(); + } + if (time) { + time->Show(); + if (time->Parse()) { + time->Render(); + } + } +} + +void cSubView::DrawList(void) { + if (viewList) { + viewList->Draw(menuCat); + } +} + +void cSubView::SetTransparency(int transparency, bool forceDetached) { + for (int i = 0; i < numViewElements; i++) { + if (viewElements[i] && (!viewElements[i]->Detached() || forceDetached)) { + viewElements[i]->SetTransparency(transparency); + } + if (viewElementsHorizontal[i] && (!viewElementsHorizontal[i]->Detached() || forceDetached)) { + viewElementsHorizontal[i]->SetTransparency(transparency); + } + } + if (viewList) + viewList->SetTransparency(transparency); +} +/*********************************************************** +* Protected Functions +***********************************************************/ +void cSubView::SetViewElementObjects(void) { + eOrientation orientation = attribs->Orientation(); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::background]) + background = viewElementsHorizontal[(int)eVeDisplayMenu::background]; + else if (viewElements[(int)eVeDisplayMenu::background]) + background = viewElements[(int)eVeDisplayMenu::background]; + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::header]) + header = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenu::header]); + else if (viewElements[(int)eVeDisplayMenu::header]) + header = dynamic_cast(viewElements[(int)eVeDisplayMenu::header]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::datetime]) + datetime = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenu::datetime]); + else if (viewElements[(int)eVeDisplayMenu::datetime]) + datetime = dynamic_cast(viewElements[(int)eVeDisplayMenu::datetime]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::time]) + time = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenu::time]); + else if (viewElements[(int)eVeDisplayMenu::time]) + time = dynamic_cast(viewElements[(int)eVeDisplayMenu::time]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::message]) + message = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenu::message]); + else if (viewElements[(int)eVeDisplayMenu::message]) + message = dynamic_cast(viewElements[(int)eVeDisplayMenu::message]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::sortmode]) + sortmode = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenu::sortmode]); + else if (viewElements[(int)eVeDisplayMenu::sortmode]) + sortmode = dynamic_cast(viewElements[(int)eVeDisplayMenu::sortmode]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::colorbuttons]) + colorbuttons = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenu::colorbuttons]); + else if (viewElements[(int)eVeDisplayMenu::colorbuttons]) + colorbuttons = dynamic_cast(viewElements[(int)eVeDisplayMenu::colorbuttons]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenu::scrollbar]) + scrollbar = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenu::scrollbar]); + else if (viewElements[(int)eVeDisplayMenu::scrollbar]) + scrollbar = dynamic_cast(viewElements[(int)eVeDisplayMenu::scrollbar]); + + + if (attribs->Orientation() == eOrientation::horizontal) + viewList = viewListHorizontal; + else + viewList = viewListVertical; +} + +void cSubView::SetViewElements(void) { + viewElementNames.insert(pair("background", (int)eVeDisplayMenu::background)); + viewElementNames.insert(pair("header", (int)eVeDisplayMenu::header)); + viewElementNames.insert(pair("datetime", (int)eVeDisplayMenu::datetime)); + viewElementNames.insert(pair("time", (int)eVeDisplayMenu::time)); + viewElementNames.insert(pair("colorbuttons", (int)eVeDisplayMenu::colorbuttons)); + viewElementNames.insert(pair("message", (int)eVeDisplayMenu::message)); + viewElementNames.insert(pair("scrollbar", (int)eVeDisplayMenu::scrollbar)); + viewElementNames.insert(pair("sortmode", (int)eVeDisplayMenu::sortmode)); +} + +/*********************************************************** +* cViewMenuDefault +***********************************************************/ +cViewMenuDefault::cViewMenuDefault(const char *name) : cSubView(name) { + listDefault = NULL; +} + +cViewMenuDefault::~cViewMenuDefault(void) { +} + +void cViewMenuDefault::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + listDefault = dynamic_cast(viewList); +} + +void cViewMenuDefault::SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5) { + if (listDefault) + listDefault->SetTabs(tab1, tab2, tab3, tab4, tab5); +} + +void cViewMenuDefault::SetPlugin(const char *plugName) { + listDefault->SetPlugin(plugName); +} + +void cViewMenuDefault::SetItem(const char *text, int index, bool current, bool selectable) { + listDefault->Set(text, index, current, selectable); +} + +const cFont *cViewMenuDefault::GetTextAreaFont(void) { + if (!listDefault) + return NULL; + return listDefault->GetListFont(); +} + +int cViewMenuDefault::GetListWidth(void) { + if (!listDefault) + return 0; + return listDefault->GetListWidth(); +} + +/************************************************************************************ +* cViewMenuMain +************************************************************************************/ +cViewMenuMain::cViewMenuMain(const char *name) : cSubView(name) { + for (int i=0; i < numViewElements; i++) { + delete viewElements[i]; + } + delete[] viewElements; + numViewElements = (int)eVeDisplayMenuMain::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + delete[] viewElementsHorizontal; + viewElementsHorizontal = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElementsHorizontal[i] = NULL; + } + listMain = NULL; + timers = NULL; + devices = NULL; + weather = NULL; + discusage = NULL; + load = NULL; + memory = NULL; + vdrstats = NULL; + temperatures = NULL; + currentSchedule = NULL; + lastRecordings = NULL; + customTokens = NULL; + lastDrawDynamic = 0; + SetViewElements(); +} + +cViewMenuMain::~cViewMenuMain() { +} + +void cViewMenuMain::ClearVariables(void) { + init = true; +} + +void cViewMenuMain::SetViewElements(void) { + viewElementNames.insert(pair("timers", (int)eVeDisplayMenuMain::timers)); + viewElementNames.insert(pair("devices", (int)eVeDisplayMenuMain::devices)); + viewElementNames.insert(pair("currentweather", (int)eVeDisplayMenuMain::currentweather)); + viewElementNames.insert(pair("currentschedule", (int)eVeDisplayMenuMain::currentschedule)); + viewElementNames.insert(pair("discusage", (int)eVeDisplayMenuMain::discusage)); + viewElementNames.insert(pair("systemload", (int)eVeDisplayMenuMain::systemload)); + viewElementNames.insert(pair("systemmemory", (int)eVeDisplayMenuMain::systemmemory)); + viewElementNames.insert(pair("vdrstatistics", (int)eVeDisplayMenuMain::vdrstatistics)); + viewElementNames.insert(pair("temperatures", (int)eVeDisplayMenuMain::temperatures)); + viewElementNames.insert(pair("lastrecordings", (int)eVeDisplayMenuMain::lastrecordings)); + viewElementNames.insert(pair("customtokens", (int)eVeDisplayMenuMain::customtokens)); +} + +void cViewMenuMain::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + eOrientation orientation = attribs->Orientation(); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::timers]) + timers = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::timers]); + else if (viewElements[(int)eVeDisplayMenuMain::timers]) + timers = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::timers]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::devices]) + devices = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::devices]); + else if (viewElements[(int)eVeDisplayMenuMain::devices]) + devices = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::devices]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::currentweather]) + weather = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::currentweather]); + else if (viewElements[(int)eVeDisplayMenuMain::currentweather]) + weather = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::currentweather]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::currentschedule]) + currentSchedule = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::currentschedule]); + else if (viewElements[(int)eVeDisplayMenuMain::currentschedule]) + currentSchedule = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::currentschedule]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::discusage]) + discusage = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::discusage]); + else if (viewElements[(int)eVeDisplayMenuMain::discusage]) + discusage = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::discusage]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::systemload]) + load = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::systemload]); + else if (viewElements[(int)eVeDisplayMenuMain::systemload]) + load = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::systemload]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::systemmemory]) + memory = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::systemmemory]); + else if (viewElements[(int)eVeDisplayMenuMain::systemmemory]) + memory = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::systemmemory]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::vdrstatistics]) + vdrstats = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::vdrstatistics]); + else if (viewElements[(int)eVeDisplayMenuMain::vdrstatistics]) + vdrstats = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::vdrstatistics]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::temperatures]) + temperatures = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::temperatures]); + else if (viewElements[(int)eVeDisplayMenuMain::temperatures]) + temperatures = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::temperatures]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::lastrecordings]) + lastRecordings = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::lastrecordings]); + else if (viewElements[(int)eVeDisplayMenuMain::lastrecordings]) + lastRecordings = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::lastrecordings]); + + if (orientation == eOrientation::horizontal && viewElementsHorizontal[(int)eVeDisplayMenuMain::customtokens]) + customTokens = dynamic_cast(viewElementsHorizontal[(int)eVeDisplayMenuMain::customtokens]); + else if (viewElements[(int)eVeDisplayMenuMain::customtokens]) + customTokens = dynamic_cast(viewElements[(int)eVeDisplayMenuMain::customtokens]); + + if (devices) devices->SetDetached(); + if (weather) weather->SetDetached(); + if (discusage) discusage->SetDetached(); + if (load) load->SetDetached(); + if (memory) memory->SetDetached(); + if (vdrstats) vdrstats->SetDetached(); + if (temperatures) temperatures->SetDetached(); + if (timers) timers->SetDetached(); + if (currentSchedule) currentSchedule->SetDetached(); + if (lastRecordings) lastRecordings->SetDetached(); + if (customTokens) customTokens->SetDetached(); + + listMain = dynamic_cast(viewList); +} + +void cViewMenuMain::Clear(void) { + cSubView::Clear(); + lastDrawDynamic = 0; + + if (devices) + devices->Hide(); + + if (weather) + weather->Hide(); + + if (discusage) + discusage->Hide(); + + if (load) { + load->Reset(); + load->Hide(); + } + + if (memory) { + memory->Reset(); + memory->Hide(); + } + + if (vdrstats) { + vdrstats->Reset(); + vdrstats->Hide(); + } + + if (temperatures) { + temperatures->Reset(); + temperatures->Hide(); + } + + if (timers) { + timers->Hide(); + } + + if (currentSchedule) { + currentSchedule->Hide(); + } + + if (lastRecordings) { + lastRecordings->Hide(); + } + + if (customTokens) { + customTokens->Reset(); + customTokens->Hide(); + } +} + +void cViewMenuMain::SetItem(const char *text, int index, bool current, bool selectable) { + listMain->Set(text, index, current, selectable); +} + +void cViewMenuMain::SetCurrentRecording(const char *currentRec) { + if (currentSchedule) + currentSchedule->SetRecording(currentRec); +} + +void cViewMenuMain::DrawStaticVEs(void) { + cSubView::DrawStaticVEs(); + if (weather) { + weather->Show(); + if (weather->Parse()) + weather->Render(); + } + if (discusage) { + discusage->Show(); + if (discusage->Parse()) + discusage->Render(); + } + if (timers) { + timers->Show(); + if (timers->Parse()) + timers->Render(); + } + if (currentSchedule) { + currentSchedule->Show(); + if (currentSchedule->Parse()) + currentSchedule->Render(); + } + if (lastRecordings) { + lastRecordings->Show(); + if (lastRecordings->Parse()) + lastRecordings->Render(); + } +} + +void cViewMenuMain::DrawDynamicVEs(void) { + cSubView::DrawDynamicVEs(); + //draw main menu dynamic elements + //only every 3 seconds + uint64_t now = cTimeMs::Now(); + if (now - lastDrawDynamic < 3000) + return; + else { + lastDrawDynamic = now; + } + + if (devices) { + devices->Show(); + if (devices->Parse()) + devices->Render(); + } + if (load) { + load->Show(); + if (load->Parse()) + load->Render(); + } + if (memory) { + memory->Show(); + if (memory->Parse()) + memory->Render(); + } + if (vdrstats) { + vdrstats->Show(); + if (vdrstats->Parse()) + vdrstats->Render(); + } + if (temperatures) { + temperatures->Show(); + if (temperatures->Parse()) + temperatures->Render(); + } + if (customTokens) { + customTokens->Show(); + if (customTokens->Parse()) + customTokens->Render(); + } +} + +const char *cViewMenuMain::GetPlugin(void) { + return listMain->GetPlugin(); +} + +/*********************************************************** +* cViewMenuSetup +***********************************************************/ +cViewMenuSetup::cViewMenuSetup(const char *name) : cSubView(name) { + listSetup = NULL; +} + +cViewMenuSetup::~cViewMenuSetup(void) { + +} + +void cViewMenuSetup::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + listSetup = dynamic_cast(viewList); +} + +void cViewMenuSetup::SetItem(const char *text, int index, bool current, bool selectable) { + listSetup->Set(text, index, current, selectable); +} + +/*********************************************************** +* cViewMenuSchedules +***********************************************************/ +cViewMenuSchedules::cViewMenuSchedules(const char *name) : cSubView(name) { + listSchedules = NULL; +} + +cViewMenuSchedules::~cViewMenuSchedules(void) { +} + +void cViewMenuSchedules::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + listSchedules = dynamic_cast(viewList); +} + +void cViewMenuSchedules::SetItem(const cEvent *event, int index, bool current, bool selectable, + const cChannel *channel, bool withDate, eTimerMatch timerMatch) { + + bool epgSearchFavMenu = (menuCat == mcSchedule && channel) ? true : false; + listSchedules->IsEpgSearchFav(epgSearchFavMenu); + if (header) header->IsEpgSearchFav(epgSearchFavMenu); + listSchedules->Set(event, index, current, selectable, channel, withDate, timerMatch); +} + +/*********************************************************** +* cViewMenuChannels +***********************************************************/ +cViewMenuChannels::cViewMenuChannels(const char *name) : cSubView(name) { + listChannels = NULL; +} + +cViewMenuChannels::~cViewMenuChannels(void) { +} + +void cViewMenuChannels::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + listChannels = dynamic_cast(viewList); +} + +void cViewMenuChannels::SetItem(const cChannel *channel, int index, bool current, bool selectable, bool withProvider) { + listChannels->Set(channel, index, current, selectable, withProvider); +} + +/*********************************************************** +* cViewMenuTimers +***********************************************************/ +cViewMenuTimers::cViewMenuTimers(const char *name) : cSubView(name) { + listTimers = NULL; +} + +cViewMenuTimers::~cViewMenuTimers(void) { +} + +void cViewMenuTimers::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + listTimers = dynamic_cast(viewList); +} + +void cViewMenuTimers::SetItem(const cTimer *timer, int index, bool current, bool selectable) { + listTimers->Set(timer, index, current, selectable); +} + +/*********************************************************** +* cViewMenuRecordings +***********************************************************/ +cViewMenuRecordings::cViewMenuRecordings(const char *name) : cSubView(name) { + listRecordings = NULL; +} + +cViewMenuRecordings::~cViewMenuRecordings(void) { +} + +void cViewMenuRecordings::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + listRecordings = dynamic_cast(viewList); +} + +void cViewMenuRecordings::SetItem(const cRecording *recording, int index, bool current, bool selectable, int level, int total, int New) { + listRecordings->Set(recording, index, current, selectable, level, total, New); +} + +/*********************************************************** +* cViewMenuPlugin +***********************************************************/ +cViewMenuPlugin::cViewMenuPlugin(const char *name) : cSubView(name) { + listPlugin = NULL; +} + +cViewMenuPlugin::~cViewMenuPlugin(void) { +} + +void cViewMenuPlugin::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + listPlugin = dynamic_cast(viewList); +} + +void cViewMenuPlugin::SetItem(skindesignerapi::cTokenContainer *tk, int index, bool current, bool selectable) { + listPlugin->Set(tk, index, current, selectable); +} + +/*********************************************************** +* cViewMenuDetail +***********************************************************/ +cViewMenuDetail::cViewMenuDetail(const char *name) : cSubView(name) { + firstTab = true; + for (int i=0; i < numViewElements; i++) { + delete viewElements[i]; + } + delete[] viewElements; + numViewElements = (int)eVeDisplayDetailedMenu::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + delete[] viewElementsHorizontal; + viewElementsHorizontal = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElementsHorizontal[i] = NULL; + } + SetViewElements(); + detailedheaderEpg = NULL; + detailedheaderRec = NULL; + detailedheaderPlug = NULL; + tablabels = NULL; + detailViewEpg = NULL; + detailViewRec = NULL; + detailViewText = NULL; + detailViewPlugin = NULL; + SetDetailedView(); +} + +cViewMenuDetail::~cViewMenuDetail(void) { +} + +void cViewMenuDetail::SetDetailedView(void) { + if (!strcmp(viewName, "menudetailedepg")) { + detailViewEpg = new cViewDetailEpg(); + detailView = detailViewEpg; + } else if (!strcmp(viewName, "menudetailedrecording")) { + detailViewRec = new cViewDetailRec(); + detailView = detailViewRec; + } else if (!strcmp(viewName, "menudetailedtext")) { + detailViewText = new cViewDetailText(); + detailView = detailViewText; + } else if (startswith(viewName, "menuplugin")) { + detailViewPlugin = new cViewDetailPlugin(); + detailView = detailViewPlugin; + } else { + esyslog("skindesigner: invalid detailedview %s", viewName); + } + if (detailView) { + detailView->SetOsd(&sdOsd); + } +} + +void cViewMenuDetail::AddTab(cArea *tab) { + if (firstTab) { + tab->SetActiveTab(true); + firstTab = false; + } + detailView->AddArea(tab); +} + +void cViewMenuDetail::SetGlobals(cGlobals *globals) { + cView::SetGlobals(globals); + detailView->SetGlobals(globals); +} + +void cViewMenuDetail::PreCache(void) { + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->Cache(); + if (plugId >= 0 && plugMenuId >= 0) { + cVeDmDetailheaderPlugin *dhPlug = dynamic_cast(viewElements[(int)eVeDisplayDetailedMenu::detailheader]); + dhPlug->SetPlugId(plugId); + dhPlug->SetPlugMenuId(plugMenuId); + dhPlug->SetTokenContainer(); + } + cView::PreCache(); + detailView->SetPlugId(plugId); + detailView->SetPlugMenuId(plugMenuId); + detailView->SetTokenContainer(); + detailView->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + detailView->Cache(); +} + +int cViewMenuDetail::GetWidth(void) { + return detailView->GetWidth(); +} + +void cViewMenuDetail::SetViewElements(void) { + viewElementNames.insert(pair("detailheader", (int)eVeDisplayDetailedMenu::detailheader)); + viewElementNames.insert(pair("tablabels", (int)eVeDisplayDetailedMenu::tablabels)); +} + +void cViewMenuDetail::SetViewElementObjects(void) { + cSubView::SetViewElementObjects(); + if (viewElements[(int)eVeDisplayDetailedMenu::detailheader]) { + if (!strcmp(viewName, "menudetailedepg")) + detailedheaderEpg = dynamic_cast(viewElements[(int)eVeDisplayDetailedMenu::detailheader]); + else if (!strcmp(viewName, "menudetailedrecording")) + detailedheaderRec = dynamic_cast(viewElements[(int)eVeDisplayDetailedMenu::detailheader]); + else if (startswith(viewName, "menuplugin")) + detailedheaderPlug = dynamic_cast(viewElements[(int)eVeDisplayDetailedMenu::detailheader]); + } + + if (viewElements[(int)eVeDisplayDetailedMenu::tablabels]) + tablabels = dynamic_cast(viewElements[(int)eVeDisplayDetailedMenu::tablabels]); +} + +void cViewMenuDetail::SetEvent(const cEvent *event) { + if (detailedheaderEpg) + detailedheaderEpg->SetEvent(event); + if (detailViewEpg) + detailViewEpg->SetEvent(event); +} + +void cViewMenuDetail::SetRecording(const cRecording *recording) { + if (detailedheaderRec) + detailedheaderRec->SetRecording(recording); + if (detailViewRec) + detailViewRec->SetRecording(recording); +} + +void cViewMenuDetail::SetText(const char *text) { + if (detailViewText) + detailViewText->SetText(text); +} + +void cViewMenuDetail::SetPluginText(skindesignerapi::cTokenContainer *tk) { + if (detailedheaderPlug) + detailedheaderPlug->Set(tk); + if (detailViewPlugin) + detailViewPlugin->Set(tk); +} + +void cViewMenuDetail::Clear(void) { + cSubView::Close(); + if (detailedheaderEpg) { + detailedheaderEpg->Close(); + } else if (detailedheaderRec) { + detailedheaderRec->Close(); + } else if (detailedheaderPlug) { + detailedheaderPlug->Close(); + } + if (header) { + header->Hide(); + } + if (detailView) { + detailView->Close(); + } +} + +void cViewMenuDetail::Close(void) { + cSubView::Close(); + if (detailView) { + detailView->Close(); + } +} + +void cViewMenuDetail::DrawStaticVEs(void) { + cSubView::DrawStaticVEs(); + if (detailedheaderEpg && detailedheaderEpg->Parse()) { + detailedheaderEpg->Render(); + } else if (detailedheaderRec && detailedheaderRec->Parse()) { + detailedheaderRec->Render(); + } else if (detailedheaderPlug && detailedheaderPlug->Parse()) { + detailedheaderPlug->Render(); + } +} + +void cViewMenuDetail::DrawDynamicVEs(void) { + if (datetime) { + datetime->Show(); + if (datetime->Parse()) + datetime->Render(); + } + if (time) { + time->Show(); + if (time->Parse()) + time->Render(); + } +} + +void cViewMenuDetail::DrawDetailedView(void) { + detailView->Clear(); + detailView->ResetTabs(); + if (detailView->Parse()) { + detailView->Render(); + } + if (scrollbar) { + scrollbar->Show(); + DrawScrollbar(); + } + vector tabs; + int activeTab = detailView->GetTabs(tabs); + if (tablabels) { + tablabels->SetTabs(tabs); + tablabels->SetActiveTab(activeTab); + if (tablabels->Parse()) + tablabels->Render(); + } +} + +void cViewMenuDetail::KeyLeft(void) { + if (detailView->NumTabs() > 1) { + detailView->Clear(); + detailView->PrevTab(); + detailView->SetDirty(); + if (tablabels) { + tablabels->Clear(); + tablabels->SetActiveTab(detailView->ActiveTab()); + if (tablabels->Parse()) + tablabels->Render(); + } + sdOsd.Flush(); + detailView->Render(); + if (scrollbar) { + DrawScrollbar(); + } + } else { + //scroll page + if (detailView->ScrollUp(true)) { + if (scrollbar) + DrawScrollbar(); + } + } +} + +void cViewMenuDetail::KeyRight(void) { + if (detailView->NumTabs() > 1) { + detailView->Clear(); + detailView->NextTab(); + detailView->SetDirty(); + if (tablabels) { + tablabels->Clear(); + tablabels->SetActiveTab(detailView->ActiveTab()); + if (tablabels->Parse()) + tablabels->Render(); + } + sdOsd.Flush(); + detailView->Render(); + if (scrollbar) { + DrawScrollbar(); + } + + } else { + //scroll page + if (detailView->ScrollDown(true)) { + if (scrollbar) + DrawScrollbar(); + } + } +} + +void cViewMenuDetail::KeyUp(void) { + if (detailView->ScrollUp()) { + if (scrollbar) + DrawScrollbar(); + } +} + +void cViewMenuDetail::KeyDown(void) { + if (scrollbar && detailView->ScrollDown()) { + if (scrollbar) + DrawScrollbar(); + } +} + +void cViewMenuDetail::SetTransparency(int transparency, bool forceDetached) { + if (detailedheaderEpg) + detailedheaderEpg->SetTransparency(transparency); + if (detailedheaderRec) + detailedheaderRec->SetTransparency(transparency); + if (tablabels) + tablabels->SetTransparency(transparency); + if (detailView) + detailView->SetTransparency(transparency); +} + +void cViewMenuDetail::DrawScrollbar(void) { + int barheight = 0; + int offset = 0; + bool end = true; + detailView->Scrollbar(barheight, offset, end); + scrollbar->SetDetail(barheight, offset, end); + scrollbar->Render(); +} diff --git a/coreengine/viewdisplaymenu.h b/coreengine/viewdisplaymenu.h new file mode 100644 index 0000000..1658f72 --- /dev/null +++ b/coreengine/viewdisplaymenu.h @@ -0,0 +1,316 @@ +#ifndef __VIEWDISPLAYMENU_H +#define __VIEWDISPLAYMENU_H + +#include "view.h" +#include "viewdetail.h" + +/*********************************************************** +* cViewMenu +***********************************************************/ +class cSubView; +class cViewMenuDefault; +class cViewMenuMain; +class cViewMenuSetup; +class cViewMenuSchedules; +class cViewMenuChannels; +class cViewMenuTimers; +class cViewMenuRecordings; +class cViewMenuDetail; + +class cViewMenu : public cView { +protected: + map subviewNames; + cSubView **subViews; + int numSubviews; + cSubView *activeSubview; + cSubView *activeSubviewLast; + cViewMenuDefault *menuDefault; + cViewMenuMain *menuMain; + cViewMenuSetup *menuSetup; + cViewMenuSchedules *menuSchedules; + cViewMenuChannels *menuChannels; + cViewMenuTimers *menuTimers; + cViewMenuRecordings *menuRecordings; + cViewMenuDetail *menuDetailedEpg; + cViewMenuDetail *menuDetailedRec; + cViewMenuDetail *menuDetailedText; + eMenuCategory menuCat; + //name of current plugin for menu icon + const char *plugName; + //external plugin menus + bool pluginIdSet; + int plugId; + int plugMenuId; + //status variables + bool menuChange; + bool listChange; + bool detailViewInit; + void SetViewElements(void); + void SetViewElementObjects(void); + void SetSubViews(void); + void ClearVariables(void); + int SubviewId(const char *name); + bool SetPluginSubView(eMenuCategory menuCat); + void WakeViewElements(void); +public: + cViewMenu(void); + virtual ~cViewMenu(void); + void SetGlobals(cGlobals *globals); + void PreCache(void); + bool ValidSubView(const char *subView); + static cSubView *CreateSubview(const char *name); + static cSubView *CreatePluginview(const char *plugname, int plugId, int menuNumber, int menuType); + void AddSubview(const char *sSubView, cSubView *subView); + void AddPluginview(cSubView *plugView); + void SetSubView(eMenuCategory MenuCat); + void SetSortMode(eMenuSortMode sortMode); + void SetPluginMenu(int plugId, int plugMenuId); + int NumListItems(void); + eMenuOrientation MenuOrientation(void); + const cFont *GetTextAreaFont(void); + int GetTextAreaWidth(void); + int GetListWidth(void); + void SetTitleHeader(const char *title); + void SetChannelHeader(const cEvent *event); + void SetMessage(eMessageType type, const char *text); + void SetMenuButtons(const char *red, const char *green, const char *yellow, const char *blue); + void SetScrollbar(int total, int offset); + void SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5); + void SetItem(const char *text, int index, bool current, bool selectable); + bool SetItemEvent(const cEvent *event, int index, bool current, bool selectable, const cChannel *channel, bool withDate, eTimerMatch timerMatch); + bool SetItemTimer(const cTimer *timer, int index, bool current, bool selectable); + bool SetItemChannel(const cChannel *channel, int index, bool current, bool selectable, bool withProvider); + bool SetItemRecording(const cRecording *recording, int index, bool current, bool selectable, int level, int total, int New); + bool SetItemPlugin(skindesignerapi::cTokenContainer *tk, int index, bool current, bool selectable); + void SetEvent(const cEvent *event); + void SetRecording(const cRecording *recording); + void SetText(const char *text); + bool SetPluginText(skindesignerapi::cTokenContainer *tk); + void SetCurrentRecording(const char *currentRec); + void KeyDetailView(bool up, bool page); + bool Init(void); + void Close(void); + void Clear(void); + void Flush(void); + void SetTransparency(int transparency, bool forceDetached = false); + void Debug(void); +}; + +/*********************************************************** +* cSubView +***********************************************************/ +class cSubView : public cView { +protected: + eMenuCategory menuCat; + int plugId; + int plugMenuId; + cViewList *viewList; + cViewList *viewListVertical; + cViewList *viewListHorizontal; + cViewElement *background; + cVeDmHeader *header; + cVeDateTime *datetime; + cVeTime *time; + cVeMessage *message; + cVeDmSortmode *sortmode; + cVeDmColorbuttons *colorbuttons; + cVeDmScrollbar *scrollbar; + virtual void SetViewElementObjects(void); + virtual void SetViewElements(void); +public: + cSubView(const char *name); + virtual ~cSubView(void); + virtual void SetGlobals(cGlobals *globals); + virtual void PreCache(void); + bool ViewElementSet(int ve); + bool ViewElementHorizontalSet(int ve); + void SetViewElement(eVeDisplayMenu ve, cViewElement *viewElement); + void SetViewElementHorizontal(eVeDisplayMenu ve, cViewElement *viewElement); + void AddViewList(cViewList *viewList); + virtual void AddTab(cArea *tab) {}; + int NumListItems(void); + eMenuOrientation MenuOrientation(void); + void SetMenuCategory(eMenuCategory menuCat) { this->menuCat = menuCat; }; + void SetPlugId(int id) { plugId = id; }; + void SetPlugMenuId(int id) { plugMenuId = id; }; + void SetTitle(const char *title); + void SetMessage(eMessageType type, const char *text); + void SetChannel(const cChannel *channel); + void SetMenuButtons(const char *red, const char *green, const char *yellow, const char *blue); + void SetScrollbar(int total, int offset); + void SetSortMode(eMenuSortMode sortMode); + virtual void Close(void); + virtual void Clear(void); + void ClearViewList(void); + void WakeViewElements(void); + virtual void DrawStaticVEs(void); + virtual void DrawDynamicVEs(void); + void DrawList(void); + virtual void DrawDetailedView(void) {}; + virtual void UpdateDetailedView(void) {}; + void SetTransparency(int transparency, bool forceDetached = false); +}; +/*********************************************************** +* cViewMenuDefault +***********************************************************/ +class cViewMenuDefault : public cSubView { +private: + cViewListDefault *listDefault; + void SetViewElementObjects(void); +public: + cViewMenuDefault(const char *name); + virtual ~cViewMenuDefault(void); + void SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5); + void SetPlugin(const char *plugName); + void SetItem(const char *text, int index, bool current, bool selectable); + const cFont *GetTextAreaFont(void); + int GetListWidth(void); +}; +/*********************************************************** +* cViewMenuMain +***********************************************************/ +class cViewMenuMain : public cSubView { +private: + cViewListMain *listMain; + cVeDmTimers *timers; + cVeDevices *devices; + cVeCurrentWeather *weather; + cVeDmDiscusage *discusage; + cVeDmSystemload *load; + cVeDmSystemmemory *memory; + cVeDmVdrstatistics *vdrstats; + cVeDmTemperatures *temperatures; + cVeDmCurrentschedule *currentSchedule; + cVeDmLastrecordings *lastRecordings; + cVeCustomTokens *customTokens; + uint64_t lastDrawDynamic; + void ClearVariables(void); + void SetViewElements(void); + void SetViewElementObjects(void); +public: + cViewMenuMain(const char *name); + virtual ~cViewMenuMain(void); + void Clear(void); + void SetItem(const char *text, int index, bool current, bool selectable); + void SetCurrentRecording(const char *currentRec); + void DrawStaticVEs(void); + void DrawDynamicVEs(void); + const char *GetPlugin(void); +}; +/*********************************************************** +* cViewMenuSetup +***********************************************************/ +class cViewMenuSetup : public cSubView { +private: + cViewListMain *listSetup; + void SetViewElementObjects(void); +public: + cViewMenuSetup(const char *name); + virtual ~cViewMenuSetup(void); + void SetItem(const char *text, int index, bool current, bool selectable); +}; +/*********************************************************** +* cViewMenuSchedules +***********************************************************/ +class cViewMenuSchedules : public cSubView { +private: + cViewListSchedules *listSchedules; + void SetViewElementObjects(void); +public: + cViewMenuSchedules(const char *name); + virtual ~cViewMenuSchedules(void); + void SetItem(const cEvent *event, int index, bool current, bool selectable, const cChannel *channel, bool withDate, eTimerMatch timerMatch); +}; +/*********************************************************** +* cViewMenuChannels +***********************************************************/ +class cViewMenuChannels : public cSubView { +private: + cViewListChannels *listChannels; + void SetViewElementObjects(void); +public: + cViewMenuChannels(const char *name); + virtual ~cViewMenuChannels(void); + void SetItem(const cChannel *channel, int index, bool current, bool selectable, bool withProvider); +}; +/*********************************************************** +* cViewMenuTimers +***********************************************************/ +class cViewMenuTimers : public cSubView { +private: + cViewListTimers *listTimers; + void SetViewElementObjects(void); +public: + cViewMenuTimers(const char *name); + virtual ~cViewMenuTimers(void); + void SetItem(const cTimer *timer, int index, bool current, bool selectable); +}; +/*********************************************************** +* cViewMenuRecordings +***********************************************************/ +class cViewMenuRecordings : public cSubView { +private: + cViewListRecordings *listRecordings; + void SetViewElementObjects(void); +public: + cViewMenuRecordings(const char *name); + virtual ~cViewMenuRecordings(void); + void SetItem(const cRecording *recording, int index, bool current, bool selectable, int level, int total, int New); +}; + +/*********************************************************** +* cViewMenuPlugins +***********************************************************/ +class cViewMenuPlugin : public cSubView { +private: + cViewListPlugin *listPlugin; + void SetViewElementObjects(void); +public: + cViewMenuPlugin(const char *name); + virtual ~cViewMenuPlugin(void); + void SetItem(skindesignerapi::cTokenContainer *tk, int index, bool current, bool selectable); +}; + +/*********************************************************** +* cViewMenuDetail +***********************************************************/ +class cViewMenuDetail : public cSubView { +private: + bool firstTab; + cVeDmDetailheaderEpg *detailedheaderEpg; + cVeDmDetailheaderRec *detailedheaderRec; + cVeDmDetailheaderPlugin *detailedheaderPlug; + cVeDmTablabels *tablabels; + cViewDetail *detailView; + cViewDetailEpg *detailViewEpg; + cViewDetailRec *detailViewRec; + cViewDetailText *detailViewText; + cViewDetailPlugin *detailViewPlugin; + void SetDetailedView(void); + void SetViewElements(void); + void SetViewElementObjects(void); + void DrawScrollbar(void); +public: + cViewMenuDetail(const char *name); + virtual ~cViewMenuDetail(void); + void SetGlobals(cGlobals *globals); + void AddTab(cArea *tab); + void PreCache(void); + int GetWidth(void); + void SetEvent(const cEvent *event); + void SetRecording(const cRecording *recording); + void SetText(const char *text); + void SetPluginText(skindesignerapi::cTokenContainer *tk); + void Clear(void); + void Close(void); + void DrawStaticVEs(void); + void DrawDynamicVEs(void); + void DrawDetailedView(void); + void KeyLeft(void); + void KeyRight(void); + void KeyUp(void); + void KeyDown(void); + void SetTransparency(int transparency, bool forceDetached = false); +}; + +#endif //__VIEWDISPLAYMENU_H \ No newline at end of file diff --git a/coreengine/viewdisplaymessage.c b/coreengine/viewdisplaymessage.c new file mode 100644 index 0000000..a9613fa --- /dev/null +++ b/coreengine/viewdisplaymessage.c @@ -0,0 +1,54 @@ +#include "viewdisplaymessage.h" +#include "../config.h" + +/************************************************************************************ +* cViewMessage +************************************************************************************/ + +cViewMessage::cViewMessage(void) { + ClearVariables(); + viewId = eViewType::DisplayMessage; + viewName = strdup("displaymessage"); + numViewElements = (int)eVeDisplayMessage::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + SetViewElements(); + veMessage = NULL; +} + +cViewMessage::~cViewMessage() { +} + +void cViewMessage::SetViewElements(void) { + viewElementNames.insert(pair("background", (int)eVeDisplayMessage::background)); + viewElementNames.insert(pair("message", (int)eVeDisplayMessage::message)); +} + +void cViewMessage::SetViewElementObjects(void) { + if (!viewElements[(int)eVeDisplayMessage::message]) + return; + veMessage = dynamic_cast(viewElements[(int)eVeDisplayMessage::message]); +} + +void cViewMessage::ClearVariables(void) { + init = true; +} + +void cViewMessage::SetMessage(eMessageType type, const char *text) { + if (!text) + veMessage->Clear(); + else + veMessage->Set(type, text); +} + +void cViewMessage::Flush(void) { + if (init) { + sdOsd.LockFlush(); + Render((int)eVeDisplayMessage::background); + } + Render((int)eVeDisplayMessage::message); + cView::Flush(); +} + diff --git a/coreengine/viewdisplaymessage.h b/coreengine/viewdisplaymessage.h new file mode 100644 index 0000000..44f4608 --- /dev/null +++ b/coreengine/viewdisplaymessage.h @@ -0,0 +1,19 @@ +#ifndef __VIEWDISPLAYMESSAGE_H +#define __VIEWDISPLAYMESSAGE_H + +#include "view.h" + +class cViewMessage : public cView { +private: + cVeMessage *veMessage; + void SetViewElements(void); + void SetViewElementObjects(void); + void ClearVariables(void); +public: + cViewMessage(void); + virtual ~cViewMessage(void); + void SetMessage(eMessageType type, const char *text); + void Flush(void); +}; + +#endif //__VIEWDISPLAYMESSAGE_H \ No newline at end of file diff --git a/coreengine/viewdisplayplugin.c b/coreengine/viewdisplayplugin.c new file mode 100644 index 0000000..1619944 --- /dev/null +++ b/coreengine/viewdisplayplugin.c @@ -0,0 +1,556 @@ +#include "viewdisplayplugin.h" +#include "../config.h" +/*********************************************************** +* cViewPlugin +***********************************************************/ +cViewPlugin::cViewPlugin(int id, int plugId) { + this->id = id; + this->plugId = plugId; + viewId = eViewType::DisplayPlugin; + viewName = strdup("displayplugin"); + if (id == 0) + numViews = plgManager->GetNumSubviews(plugId) + 1; + else + numViews = 1; + views = new cViewPlugin*[numViews]; + views[0] = this; + for (int i=1; i < numViews; i++) { + views[i] = NULL; + } + numViewElements = plgManager->GetNumViewElements(plugId, id); + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + SetViewElements(); + numViewGrids = plgManager->GetNumViewGrids(plugId, id); + viewGrids = new cViewGrid*[numViewGrids]; + for (int i=0; i < numViewGrids; i++) { + viewGrids[i] = NULL; + } + SetViewGrids(); + tabView = NULL; + viewChanged = true; + newViewId = 0; +} + +cViewPlugin::~cViewPlugin(void) { + for (int i=0; i< numViewGrids; i++) + delete viewGrids[i]; + delete[] viewGrids; + delete tabView; + for (int i=1; i < numViews; i++) { + delete views[i]; + } + delete[] views; +} + +/*********************************************************** +* Public Functions +***********************************************************/ +bool cViewPlugin::ReadFromXML(const char *plugName, const char *tplName, cSdOsd *osd) { + cString xmlFile = cString::sprintf("plug-%s-%s", plugName, tplName); + cXmlParser parser; + if (osd) + parser.SetOsd(osd); + else + parser.SetOsd(&sdOsd); + if (!parser.ReadView(this, *xmlFile)) { + return false; + } + if (!parser.ParsePluginView()) { + return false; + } + return true; +} + +bool cViewPlugin::ReadSubViews(const char *plugName) { + plgManager->InitPluginSubviewIterator(plugId); + int svId = -1; + string svTpl = ""; + while (plgManager->GetNextSubView(svId, svTpl)) { + cViewPlugin *plugSubView = new cViewPlugin(svId, plugId); + if (!plugSubView->ReadFromXML(plugName, svTpl.c_str(), &sdOsd)) + return false; + views[svId] = plugSubView; + } + return true; +} + + +void cViewPlugin::SetGlobals(cGlobals *globals) { + cView::SetGlobals(globals); + for (int i=0; i < numViewGrids; i++) { + if (viewGrids[i]) + viewGrids[i]->SetGlobals(globals); + } + for (int i=1; i < numViews; i++) { + views[i]->SetGlobals(globals); + } + if (tabView) { + tabView->SetGlobals(globals); + } +} + +void cViewPlugin::AddViewElement(cVePlugin *viewElement) { + int veId = ViewElementId(viewElement->Name()); + if (veId == ATTR_UNKNOWN) + return; + viewElement->SetId(veId); + viewElement->SetPluginId(plugId); + viewElement->SetViewId(id); + viewElement->SetTokenContainer(); + viewElements[veId] = viewElement; +} + +void cViewPlugin::AddViewGrid(cViewGrid *viewGrid) { + int gId = GridId(viewGrid->Name()); + if (gId == ATTR_UNKNOWN) + return; + viewGrid->SetId(gId); + viewGrid->SetPluginId(plugId); + viewGrid->SetViewId(id); + viewGrid->SetTokenContainer(); + viewGrids[gId] = viewGrid; +} + +void cViewPlugin::AddTab(cArea *tab) { + if (!tabView) { + tabView = new cPluginTabView(id, plugId); + tabView->SetOsd(&sdOsd); + } + tabView->AddTab(tab); +} + +void cViewPlugin::AddScrollbar(cVeDmScrollbar *scrollbar) { + if (!tabView) { + tabView = new cPluginTabView(id, plugId); + tabView->SetOsd(&sdOsd); + } + int id = ViewElementId("scrollbar"); + scrollbar->SetId(id); + scrollbar->SetTokenContainer(); + tabView->AddScrollbar(scrollbar); +} + +void cViewPlugin::AddTablabels(cVeDmTablabels *tablabels) { + if (!tabView) { + tabView = new cPluginTabView(id, plugId); + tabView->SetOsd(&sdOsd); + } + int id = ViewElementId("tablabels"); + tablabels->SetId(id); + tablabels->SetTokenContainer(); + tabView->AddTablabels(tablabels); +} + +void cViewPlugin::PreCache(void) { + if (container.Width() > 0) { + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->Cache(); + } + cView::PreCache(); + for (int i=0; i < numViewGrids; i++) { + if (viewGrids[i]) { + viewGrids[i]->SetContainer(0, 0, attribs->Width(), attribs->Height()); + viewGrids[i]->PreCache(); + } + } + for (int i=1; i < numViews; i++) { + views[i]->SetContainer(0, 0, attribs->Width(), attribs->Height()); + views[i]->PreCache(); + } + if (tabView) { + tabView->PreCache(0, 0, attribs->Width(), attribs->Height()); + } +} + +cVePlugin *cViewPlugin::GetViewElement(int veId) { + if (!viewElements[veId]) + return NULL; + cVePlugin *ve = dynamic_cast(viewElements[veId]); + return ve; +} + +cViewGrid *cViewPlugin::GetViewGrid(int gId) { + return viewGrids[gId]; +} + +cPluginTabView *cViewPlugin::GetViewTab(void) { + return tabView; +} + +void cViewPlugin::Hide(void) { + for (int i=0; i < numViewGrids; i++) { + if (viewGrids[i]) + viewGrids[i]->Hide(); + } + for (int i=0; i < numViewElements; i++) { + if (viewElements[i]) + viewElements[i]->Hide(); + } +} + +void cViewPlugin::Show(void) { + for (int i=0; i < numViewGrids; i++) { + if (viewGrids[i]) + viewGrids[i]->Show(); + } + for (int i=0; i < numViewElements; i++) { + if (viewElements[i]) + viewElements[i]->Show(); + } +} +/*********************************************************** +* libskindesigner api interface +***********************************************************/ +bool cViewPlugin::InitOsd(void) { + return Init(); +} + +void cViewPlugin::CloseOsd(void) { + viewChanged = true; + newViewId = 0; + Close(); + for (int i=0 ; i < numViewGrids; i++) { + if (viewGrids[i]) + viewGrids[i]->Close(); + } + for (int i=1 ; i < numViews; i++) { + if (views[i]) + views[i]->Close(); + } +} + +void cViewPlugin::Deactivate(int viewId, bool hide) { + for (int i=0; i < numViewElements; i++) { + if (viewElements[i]) + viewElements[i]->StopScrolling(false); + } + if (hide) + views[viewId]->Hide(); +} + +void cViewPlugin::Activate(int viewId) { + viewChanged = true; + newViewId = viewId; + views[viewId]->Show(); +} + +void cViewPlugin::SetViewElementTokens(int veId, int viewId, skindesignerapi::cTokenContainer *tk) { + cVePlugin *ve = views[viewId]->GetViewElement(veId); + if (!ve) + return; + ve->Set(tk); +} + +void cViewPlugin::ClearViewElement(int veId, int viewId) { + cVePlugin *ve = views[viewId]->GetViewElement(veId); + if (!ve) + return; + ve->StopScrolling(); + ve->Clear(); +} + +void cViewPlugin::DisplayViewElement(int veId, int viewId) { + cVePlugin *ve = views[viewId]->GetViewElement(veId); + if (!ve) + return; + if (ve->Parse()) + ve->Render(); +} + +void cViewPlugin::SetGrid(long gId, int viewId, int viewGridId, double x, double y, double width, double height, skindesignerapi::cTokenContainer *tk){ + cViewGrid *grid = views[viewId]->GetViewGrid(viewGridId); + if (!grid) + return; + grid->CheckSize(gId); + grid->PositionGrid(gId, x, y, width, height); + if (tk) { + //only set tokens new if necessary + grid->SetTokens(gId, tk); + } +} + +void cViewPlugin::SetGridCurrent(long gId, int viewId, int viewGridId, bool current) { + if (gId < 0) + return; + cViewGrid *grid = views[viewId]->GetViewGrid(viewGridId); + if (!grid) + return; + grid->SetCurrentGrid(gId, current); +} + +void cViewPlugin::DeleteGrid(long gId, int viewId, int viewGridId) { + cViewGrid *grid = views[viewId]->GetViewGrid(viewGridId); + if (!grid) + return; + grid->DeleteGrid(gId); +} + +void cViewPlugin::DisplayGrids(int viewId, int viewGridId) { + cViewGrid *grid = views[viewId]->GetViewGrid(viewGridId); + if (!grid) + return; + grid->Render(); +} + +void cViewPlugin::ClearGrids(int viewId, int viewGridId) { + cViewGrid *grid = views[viewId]->GetViewGrid(viewGridId); + if (!grid) + return; + grid->ClearGrids(); +} + +void cViewPlugin::SetTabTokens(int viewId, skindesignerapi::cTokenContainer *tk) { + cPluginTabView *tab = views[viewId]->GetViewTab(); + if (!tab) + return; + tab->SetOsd(&sdOsd); + tab->Set(tk); +} + +void cViewPlugin::TabLeft(int viewId) { + cPluginTabView *tab = views[viewId]->GetViewTab(); + if (!tab) + return; + tab->KeyLeft(); +} + +void cViewPlugin::TabRight(int viewId) { + cPluginTabView *tab = views[viewId]->GetViewTab(); + if (!tab) + return; + tab->KeyRight(); +} + +void cViewPlugin::TabUp(int viewId) { + cPluginTabView *tab = views[viewId]->GetViewTab(); + if (!tab) + return; + tab->KeyUp(); +} + +void cViewPlugin::TabDown(int viewId) { + cPluginTabView *tab = views[viewId]->GetViewTab(); + if (!tab) + return; + tab->KeyDown(); +} + +void cViewPlugin::DisplayTabs(int viewId) { + cPluginTabView *tab = views[viewId]->GetViewTab(); + if (!tab) + return; + tab->Render(); +} + +void cViewPlugin::ClearTab(int viewId) { + cPluginTabView *tab = views[viewId]->GetViewTab(); + if (!tab) + return; + tab->Clear(); +} + +void cViewPlugin::Flush(void) { + if (viewChanged) { + viewChanged = false; + newTvFrame = views[newViewId]->GetTvFrame(); + menuInit = true; + } + cView::Flush(); +} + +bool cViewPlugin::ChannelLogoExists(string channelId) { + return imgCache->LogoExists(channelId); +} + +string cViewPlugin::GetEpgImagePath(void) { + return *config.epgImagePath; +} + +/*********************************************************** +* Private Functions +***********************************************************/ +void cViewPlugin::SetViewElements(void) { + plgManager->InitViewElementIterator(plugId, id); + int veId = -1; + string veName = ""; + while (plgManager->GetNextViewElement(veId, veName)) { + viewElementNames.insert(pair(veName, veId)); + } +} + +void cViewPlugin::SetViewGrids(void) { + plgManager->InitViewGridIterator(plugId, id); + int gId = -1; + string gName = ""; + while (plgManager->GetNextViewGrid(gId, gName)) { + gridNames.insert(pair(gName, gId)); + } +} + +int cViewPlugin::GridId(const char *name) { + map::iterator hit = gridNames.find(name); + if (hit != gridNames.end()) + return (int)hit->second; + return ATTR_UNKNOWN; +} + +/*********************************************************** +* cPluginTabView +***********************************************************/ +cPluginTabView::cPluginTabView(int viewId, int plugId) { + sdOsd = NULL; + init = true; + drawScrollbar = true; + scrollbar = NULL; + tablabels = NULL; + detailView = new cViewDetailAdvancedPlugin(viewId, plugId); + firstTab = true; +} + +cPluginTabView::~cPluginTabView(void) { + delete scrollbar; + delete tablabels; + delete detailView; +} + +void cPluginTabView::SetGlobals(cGlobals *globals) { + detailView->SetGlobals(globals); + if (scrollbar) + scrollbar->SetGlobals(globals); + if (tablabels) + tablabels->SetGlobals(globals); +} + +void cPluginTabView::AddTab(cArea *tab) { + if (firstTab) { + tab->SetActiveTab(true); + firstTab = false; + } + detailView->AddArea(tab); +} + +void cPluginTabView::AddScrollbar(cVeDmScrollbar *scrollbar) { + this->scrollbar = scrollbar; +} + +void cPluginTabView::AddTablabels(cVeDmTablabels *tablabels) { + this->tablabels = tablabels; +} + +void cPluginTabView::PreCache(int containerX, int containerY, int containerWidth, int containerHeight) { + detailView->SetOsd(sdOsd); + detailView->SetTokenContainer(); + detailView->SetContainer(containerX, containerY, containerWidth, containerHeight); + detailView->Cache(); + if (scrollbar) { + scrollbar->SetContainer(containerX, containerY, containerWidth, containerHeight); + scrollbar->Cache(); + } + if (tablabels) { + tablabels->SetContainer(containerX, containerY, containerWidth, containerHeight); + tablabels->Cache(); + } +} + +void cPluginTabView::Set(skindesignerapi::cTokenContainer *tk) { + detailView->Set(tk); +} + +void cPluginTabView::Render(void) { + detailView->Render(); + if (drawScrollbar) { + drawScrollbar = false; + DrawScrollbar(); + } + if (!init) + return; + init = false; + vector tabs; + int activeTab = detailView->GetTabs(tabs); + if (tablabels) { + tablabels->SetTabs(tabs); + tablabels->SetActiveTab(activeTab); + if (tablabels->Parse()) + tablabels->Render(); + } +} + +void cPluginTabView::Clear(void) { + init = true; + drawScrollbar = true; + detailView->ResetTabs(); + detailView->Close(); + if (tablabels) + tablabels->Close(); + if (scrollbar) + scrollbar->Close(); +} + +void cPluginTabView::KeyLeft(void) { + if (detailView->NumTabs() > 1) { + detailView->Clear(); + detailView->PrevTab(); + detailView->SetDirty(); + if (tablabels) { + tablabels->Clear(); + tablabels->SetActiveTab(detailView->ActiveTab()); + if (tablabels->Parse()) + tablabels->Render(); + } + sdOsd->Flush(); + drawScrollbar = true; + } else { + //scroll page + if (detailView->ScrollUp(true)) { + drawScrollbar = true; + } + } +} + +void cPluginTabView::KeyRight(void) { + if (detailView->NumTabs() > 1) { + detailView->Clear(); + detailView->NextTab(); + detailView->SetDirty(); + if (tablabels) { + tablabels->Clear(); + tablabels->SetActiveTab(detailView->ActiveTab()); + if (tablabels->Parse()) + tablabels->Render(); + } + sdOsd->Flush(); + drawScrollbar = true; + } else { + //scroll page + if (detailView->ScrollDown(true)) { + drawScrollbar = true; + } + } +} + +void cPluginTabView::KeyUp(void) { + if (detailView->ScrollUp()) { + drawScrollbar = true; + } +} + +void cPluginTabView::KeyDown(void) { + if (detailView->ScrollDown()) { + drawScrollbar = true; + } +} + +void cPluginTabView::DrawScrollbar(void) { + if (!scrollbar) + return; + int barheight = 0; + int offset = 0; + bool end = true; + detailView->Scrollbar(barheight, offset, end); + scrollbar->SetDetail(barheight, offset, end); + scrollbar->Render(); +} + diff --git a/coreengine/viewdisplayplugin.h b/coreengine/viewdisplayplugin.h new file mode 100644 index 0000000..4d9cd59 --- /dev/null +++ b/coreengine/viewdisplayplugin.h @@ -0,0 +1,101 @@ +#ifndef __VIEWDISPLAYPLUGIN_H +#define __VIEWDISPLAYPLUGIN_H + +#include "view.h" +#include "viewdetail.h" +#include "viewelementsdisplaymenu.h" +#include "viewgrid.h" +#include "../libskindesignerapi/skindesignerapi.h" + +class cPluginTabView; +/*********************************************************** +* cViewPlugin +***********************************************************/ +class cViewPlugin : public cView, public skindesignerapi::ISkinDisplayPlugin { +private: + int id; + int plugId; + int numViews; + cViewPlugin **views; + int numViewGrids; + cViewGrid **viewGrids; + map gridNames; + cPluginTabView *tabView; + bool viewChanged; + int newViewId; + void SetViewElements(void); + void SetViewGrids(void); + int GridId(const char *name); +public: + cViewPlugin(int id, int plugId); + ~cViewPlugin(void); + //Internal Interface + bool ReadFromXML(const char *plugName, const char *tplName, cSdOsd *osd = NULL); + bool ReadSubViews(const char *plugName); + void AddViewElement(cVePlugin *viewElement); + void AddViewGrid(cViewGrid *viewGrid); + void AddTab(cArea *tab); + void AddScrollbar(cVeDmScrollbar *scrollbar); + void AddTablabels(cVeDmTablabels *tablabels); + void SetGlobals(cGlobals *globals); + void PreCache(void); + cVePlugin *GetViewElement(int veId); + cViewGrid *GetViewGrid(int gId); + cPluginTabView *GetViewTab(void); + void Hide(void); + void Show(void); + //libskindesigner api interface + bool InitOsd(void); + void CloseOsd(void); + void Deactivate(int viewId, bool hide); + void Activate(int viewId); + void SetViewElementTokens(int veId, int viewId, skindesignerapi::cTokenContainer *tk); + void ClearViewElement(int veId, int viewId); + void DisplayViewElement(int veId, int viewId); + void SetGrid(long gId, int viewId, int viewGridId, double x, double y, double width, double height, skindesignerapi::cTokenContainer *tk); + void SetGridCurrent(long gId, int viewId, int viewGridId, bool current); + void DeleteGrid(long gId, int viewId, int viewGridId); + void DisplayGrids(int viewId, int viewGridId); + void ClearGrids(int viewId, int viewGridId); + void SetTabTokens(int viewId, skindesignerapi::cTokenContainer *tk); + void TabLeft(int viewId); + void TabRight(int viewId); + void TabUp(int viewId); + void TabDown(int viewId); + void DisplayTabs(int viewId); + void ClearTab(int viewId); + void Flush(void); + bool ChannelLogoExists(string channelId); + string GetEpgImagePath(void); +}; +/*********************************************************** +* cPluginTabView +***********************************************************/ +class cPluginTabView { +private: + cSdOsd *sdOsd; + bool init; + bool drawScrollbar; + bool firstTab; + cVeDmScrollbar *scrollbar; + cVeDmTablabels *tablabels; + cViewDetailAdvancedPlugin *detailView; + void DrawScrollbar(void); +public: + cPluginTabView(int viewId, int plugId); + ~cPluginTabView(void); + void SetGlobals(cGlobals *globals); + void SetOsd(cSdOsd *osd) { sdOsd = osd; }; + void AddTab(cArea *tab); + void AddScrollbar(cVeDmScrollbar *scrollbar); + void AddTablabels(cVeDmTablabels *tablabels); + void PreCache(int containerX, int containerY, int containerWidth, int containerHeight); + void Set(skindesignerapi::cTokenContainer *tk); + void Render(void); + void Clear(void); + void KeyLeft(void); + void KeyRight(void); + void KeyUp(void); + void KeyDown(void); +}; +#endif //__VIEWDISPLAYPLUGIN_H \ No newline at end of file diff --git a/coreengine/viewdisplayreplay.c b/coreengine/viewdisplayreplay.c new file mode 100644 index 0000000..503b72f --- /dev/null +++ b/coreengine/viewdisplayreplay.c @@ -0,0 +1,314 @@ +#include "viewdisplayreplay.h" + +/************************************************************************************ +* cViewReplay +************************************************************************************/ + +cViewReplay::cViewReplay(void) { + veCustomTokens = NULL; + veEndTime = NULL; + veMessage = NULL; + veScraperContent = NULL; + veRecTitle = NULL; + veRecInfo = NULL; + veCurrentTime = NULL; + veTotalTime = NULL; + veProgressbar = NULL; + veCutMarks = NULL; + veProgressModeOnly = NULL; + veControlIcons = NULL; + veControlIconsModeOnly = NULL; + veJump = NULL; + veOnPause = NULL; + veOnPauseModeOnly = NULL; + ClearVariables(); + viewId = eViewType::DisplayReplay; + viewName = strdup("displayreplay"); + numViewElements = (int)eVeDisplayReplay::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + SetViewElements(); +} + +cViewReplay::~cViewReplay() { +} + +void cViewReplay::SetViewElements(void) { + viewElementNames.insert(pair("background", (int)eVeDisplayReplay::background)); + viewElementNames.insert(pair("backgroundmodeonly", (int)eVeDisplayReplay::backgroundmodeonly)); + viewElementNames.insert(pair("datetime", (int)eVeDisplayReplay::datetime)); + viewElementNames.insert(pair("time", (int)eVeDisplayReplay::time)); + viewElementNames.insert(pair("scrapercontent", (int)eVeDisplayReplay::scrapercontent)); + viewElementNames.insert(pair("rectitle", (int)eVeDisplayReplay::rectitle)); + viewElementNames.insert(pair("recinfo", (int)eVeDisplayReplay::recinfo)); + viewElementNames.insert(pair("currenttime", (int)eVeDisplayReplay::currenttime)); + viewElementNames.insert(pair("endtime", (int)eVeDisplayReplay::endtime)); + viewElementNames.insert(pair("totaltime", (int)eVeDisplayReplay::totaltime)); + viewElementNames.insert(pair("progressbar", (int)eVeDisplayReplay::progressbar)); + viewElementNames.insert(pair("cutmarks", (int)eVeDisplayReplay::cutmarks)); + viewElementNames.insert(pair("cutmarks", (int)eVeDisplayReplay::cutmarks)); + viewElementNames.insert(pair("controlicons", (int)eVeDisplayReplay::controlicons)); + viewElementNames.insert(pair("controliconsmodeonly", (int)eVeDisplayReplay::controliconsmodeonly)); + viewElementNames.insert(pair("progressmodeonly", (int)eVeDisplayReplay::progressmodeonly)); + viewElementNames.insert(pair("jump", (int)eVeDisplayReplay::jump)); + viewElementNames.insert(pair("message", (int)eVeDisplayReplay::message)); + viewElementNames.insert(pair("onpause", (int)eVeDisplayReplay::onpause)); + viewElementNames.insert(pair("onpausemodeonly", (int)eVeDisplayReplay::onpausemodeonly)); + viewElementNames.insert(pair("customtokens", (int)eVeDisplayReplay::customtokens)); +} + +void cViewReplay::SetViewElementObjects(void) { + for (int i = 0; i < numViewElements; i++) { + if (!viewElements[i]) + continue; + if (dynamic_cast(viewElements[i])) + { + veMessage = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veScraperContent = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veCustomTokens = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veRecTitle = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veRecInfo = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veCurrentTime = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veTotalTime = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veEndTime = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veProgressbar = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veCutMarks = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veProgressModeOnly = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i]) && (i == (int)eVeDisplayReplay::controlicons)) + { + veControlIcons = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i]) && i == (int)eVeDisplayReplay::controliconsmodeonly) + { + veControlIconsModeOnly = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i])) + { + veJump = dynamic_cast(viewElements[i]); + } + else if (dynamic_cast(viewElements[i]) && i == (int)eVeDisplayReplay::onpause) + { + veOnPause = dynamic_cast(viewElements[i]); + veOnPause->SetDetached(); + veOnPause->UnsetWaitOnWakeup(); + } + else if (dynamic_cast(viewElements[i]) && i == (int)eVeDisplayReplay::onpausemodeonly) + { + veOnPauseModeOnly = dynamic_cast(viewElements[i]); + veOnPauseModeOnly->SetDetached(); + veOnPauseModeOnly->UnsetWaitOnWakeup(); + } + } +} + +void cViewReplay::ClearVariables(void) { + cView::ClearVariables(); + modeOnly = false; + lastFlush = 0; + message = false; + reclength = -1; + timeShiftActive = false; + timeShiftFramesTotal = -1; + timeShiftLength = -1; + timeShiftDuration = ""; + if (veCustomTokens) + veCustomTokens->Reset(); + if (veEndTime) + veEndTime->Set(cString("")); + if (veCutMarks) + veCutMarks->Reset(); +} + +void cViewReplay::SetTimeShift(int framesTotal, int timeShiftLength) { + timeShiftActive = true; + timeShiftFramesTotal = framesTotal; + this->timeShiftLength = timeShiftLength; + int mins = (timeShiftLength / 60) % 60; + int hours = (timeShiftLength / 3600) % 24; + timeShiftDuration = cString::sprintf("%d:%02d", hours, mins); +} + +void cViewReplay::SetRecording(const cRecording *recording) { + if (veRecTitle) { + veRecTitle->Set(recording); + } + if (veRecInfo) { + veRecInfo->Set(recording); + } + if (veScraperContent) { + veScraperContent->Set(recording); + } +} + +void cViewReplay::SetTitle(const char *title) { + if (veRecTitle) { + veRecTitle->Set(title); + } +} + +void cViewReplay::SetCurrent(const char *current) { + if (veCurrentTime) + veCurrentTime->Set(current); + Render((int)eVeDisplayReplay::currenttime); + //good place to refresh these viewelements + //since SetCurrent is called every second + Render((int)eVeDisplayReplay::datetime); + Render((int)eVeDisplayReplay::time); + Render((int)eVeDisplayChannel::customtokens); +} + +void cViewReplay::SetTotal(const char *total) { + if (veTotalTime) + veTotalTime->Set(total, timeShiftActive, *timeShiftDuration); + Render((int)eVeDisplayReplay::totaltime); +} + +void cViewReplay::SetEndTime(int current, int total) { + if (!veEndTime) + return; + int totalLength = total; + int recordingLength = reclength; + if (timeShiftActive && timeShiftFramesTotal > 0) { + totalLength = timeShiftFramesTotal; + recordingLength = timeShiftLength; + } + double rest = (double)(totalLength - current) / (double)totalLength; + time_t end = time(0) + rest*recordingLength; + veEndTime->Set(TimeString(end)); + Render((int)eVeDisplayReplay::endtime); +} + +void cViewReplay::SetProgressbar(int current, int total) { + if (veProgressbar) + veProgressbar->Set(current, total, timeShiftActive, timeShiftFramesTotal); + Render((int)eVeDisplayReplay::progressbar); +} + +void cViewReplay::SetMarks(const cMarks *marks, int current, int total) { + if (veCutMarks) + veCutMarks->Set(marks, current, total, timeShiftActive, timeShiftFramesTotal); + Render((int)eVeDisplayReplay::cutmarks); +} + +void cViewReplay::SetControlIcons(bool play, bool forward, int speed) { + if (!modeOnly) { + if (veControlIcons) + veControlIcons->Set(play, forward, speed); + Render((int)eVeDisplayReplay::controlicons); + } else { + if (veControlIconsModeOnly) + veControlIconsModeOnly->Set(play, forward, speed); + Render((int)eVeDisplayReplay::controliconsmodeonly); + } + +} + +void cViewReplay::SetJump(const char *jump) { + if (veJump) { + if (!jump) + veJump->Clear(); + else + veJump->Set(jump); + } + Render((int)eVeDisplayReplay::jump); +} + +void cViewReplay::SetMessage(eMessageType type, const char *text) { + if (veMessage) { + if (text) + veMessage->Set(type, text); + else + veMessage->Clear(); + } + Render((int)eVeDisplayReplay::message); +} + +void cViewReplay::StartOnPause(const char *recfilename) { + cVeDrOnPause *onPause = (!modeOnly) ? veOnPause : veOnPauseModeOnly; + if (!onPause) + return; + onPause->Set(recfilename); + onPause->Parse(true); +} + +void cViewReplay::ClearOnPause(void) { + cVeDrOnPause *onPause = (!modeOnly) ? veOnPause : veOnPauseModeOnly; + if (!onPause) + return; + onPause->Close(); +} + +void cViewReplay::Flush(void) { + if (init) { + sdOsd.LockFlush(); + if (!modeOnly) { + Render((int)eVeDisplayReplay::background); + Render((int)eVeDisplayReplay::rectitle); + Render((int)eVeDisplayReplay::recinfo); + Render((int)eVeDisplayReplay::scrapercontent); + } else { + Render((int)eVeDisplayReplay::backgroundmodeonly); + } + } + + if (modeOnly) { + SetProgressModeOnly(); + } + + cView::Flush(); +} + +void cViewReplay::SetProgressModeOnly(void) { + if (!veProgressModeOnly) + return; + time_t now = time(0); + if (now == lastFlush) { + return; + } + lastFlush = now; + + cControl *control = cControl::Control(); + if (!control) + return; + double fps = control->FramesPerSecond(); + int current = 0; + int total = 0; + if (!control->GetIndex(current, total)) + return; + veProgressModeOnly->Set(fps, current, total); + if (veProgressModeOnly->Parse()) + veProgressModeOnly->Render(); +} \ No newline at end of file diff --git a/coreengine/viewdisplayreplay.h b/coreengine/viewdisplayreplay.h new file mode 100644 index 0000000..74ed10b --- /dev/null +++ b/coreengine/viewdisplayreplay.h @@ -0,0 +1,57 @@ +#ifndef __VIEWDISPLAYREPLAY_H +#define __VIEWDISPLAYREPLAY_H + +#include "view.h" + +class cViewReplay : public cView { +private: + cVeMessage *veMessage; + cVeCustomTokens *veCustomTokens; + cVeDrRecTitle *veRecTitle; + cVeDrRecInfo *veRecInfo; + cVeDrScraperContent *veScraperContent; + cVeDrCurrentTime *veCurrentTime; + cVeDrTotalTime *veTotalTime; + cVeDrEndTime *veEndTime; + cVeDrProgressBar *veProgressbar; + cVeDrCutMarks *veCutMarks; + cVeDrProgressModeonly *veProgressModeOnly; + cVeDrControlIcons *veControlIcons; + cVeDrControlIcons *veControlIconsModeOnly; + cVeDrJump *veJump; + cVeDrOnPause *veOnPause; + cVeDrOnPause *veOnPauseModeOnly; + bool modeOnly; + time_t lastFlush; + bool message; + int reclength; + bool timeShiftActive; + int timeShiftFramesTotal; + int timeShiftLength; + cString timeShiftDuration; + void SetViewElements(void); + void ClearVariables(void); + void SetViewElementObjects(void); + void SetProgressModeOnly(void); +public: + cViewReplay(void); + virtual ~cViewReplay(void); + void SetModeOnly(bool modeOnly) { this->modeOnly = modeOnly; }; + void SetRecordingLength(int length) { reclength = length; }; + void SetTimeShift(int framesTotal, int timeShiftLength); + void SetRecording(const cRecording *recording); + void SetTitle(const char *title); + void SetCurrent(const char *current); + void SetTotal(const char *total); + void SetEndTime(int current, int total); + void SetProgressbar(int current, int total); + void SetMarks(const cMarks *marks, int current, int total); + void SetControlIcons(bool play, bool forward, int speed); + void SetJump(const char *jump); + void SetMessage(eMessageType type, const char *text); + void StartOnPause(const char *recfilename); + void ClearOnPause(void); + void Flush(void); +}; + +#endif //__VIEWDISPLAYREPLAY_H1 \ No newline at end of file diff --git a/coreengine/viewdisplaytracks.c b/coreengine/viewdisplaytracks.c new file mode 100644 index 0000000..15ff584 --- /dev/null +++ b/coreengine/viewdisplaytracks.c @@ -0,0 +1,122 @@ +#include "viewdisplaytracks.h" +#include "../config.h" + +/************************************************************************************ +* cViewTracks +************************************************************************************/ + +cViewTracks::cViewTracks(void) { + ClearVariables(); + viewId = eViewType::DisplayTracks; + viewName = strdup("displayaudiotracks"); + numViewElements = (int)eVeDisplayTracks::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + viewList = NULL; + veBackground = NULL; + veHeader = NULL; + SetViewElements(); +} + +cViewTracks::~cViewTracks() { +} + +void cViewTracks::SetViewElements(void) { + viewElementNames.insert(pair("background", (int)eVeDisplayTracks::background)); + viewElementNames.insert(pair("header", (int)eVeDisplayTracks::header)); +} + +void cViewTracks::SetViewElementObjects(void) { + if (viewElements[(int)eVeDisplayTracks::background]) + veBackground = dynamic_cast(viewElements[(int)eVeDisplayTracks::background]); + if (viewElements[(int)eVeDisplayTracks::header]) + veHeader = dynamic_cast(viewElements[(int)eVeDisplayTracks::header]); +} + +void cViewTracks::ClearVariables(void) { + init = true; + change = true; +} + +void cViewTracks::Close(void) { + delete fader; + fader = NULL; + if (FadeTime() > 0) { + fader = new cAnimation((cFadable*)this, false); + fader->Fade(); + delete fader; + fader = NULL; + } + for (int i=0; i < numViewElements; i++) { + if (viewElements[i]) { + viewElements[i]->Close(); + } + } + if (viewList) { + viewList->Close(); + } + ClearVariables(); + sdOsd.DeleteOsd(); +} + +void cViewTracks::AddViewList(cViewList *viewList) { + this->viewList = dynamic_cast(viewList); +} + +void cViewTracks::PreCache(void) { + cView::PreCache(); + if (viewList) { + viewList->SetContainer(0, 0, attribs->Width(), attribs->Height()); + viewList->SetGlobals(globals); + viewList->PreCache(); + } +} + +void cViewTracks::SetTitle(const char *title) { + if (veHeader) + veHeader->SetTitle(title); + change = true; +} + +void cViewTracks::SetNumtracks(int numTracks) { + if (veBackground) + veBackground->Set(numTracks); + if (veHeader) + veHeader->SetNumtracks(numTracks); + if (viewList) + viewList->SetNumtracks(numTracks); +} + +void cViewTracks::SetAudiochannel(int audioChannel) { + if (veHeader) + veHeader->SetAudiochannel(audioChannel); + change = true; +} + +void cViewTracks::SetTracks(const char * const *tracks) { + if (viewList) + viewList->SetTracks(tracks); + change = true; +} + +void cViewTracks::SetCurrentTrack(int index) { + if (viewList) + viewList->SetCurrentTrack(index); + change = true; +} + +void cViewTracks::Flush(void) { + if (init) { + sdOsd.LockFlush(); + Render((int)eVeDisplayTracks::background); + } + if (change) { + Render((int)eVeDisplayTracks::header); + if (viewList) + viewList->Draw(); + change = false; + } + cView::Flush(); +} diff --git a/coreengine/viewdisplaytracks.h b/coreengine/viewdisplaytracks.h new file mode 100644 index 0000000..c3aea1f --- /dev/null +++ b/coreengine/viewdisplaytracks.h @@ -0,0 +1,29 @@ +#ifndef __VIEWDISPLAYTRACKS_H +#define __VIEWDISPLAYTRACKS_H + +#include "view.h" + +class cViewTracks : public cView { +private: + cViewListAudioTracks *viewList; + cVeDtBackground *veBackground; + cVeDtHeader *veHeader; + bool change; + void SetViewElements(void); + void SetViewElementObjects(void); + void ClearVariables(void); +public: + cViewTracks(void); + virtual ~cViewTracks(void); + void Close(void); + void AddViewList(cViewList *viewList); + void PreCache(void); + void SetTitle(const char *title); + void SetNumtracks(int numTracks); + void SetTracks(const char * const *tracks); + void SetAudiochannel(int audioChannel); + void SetCurrentTrack(int index); + void Flush(void); +}; + +#endif //__VIEWDISPLAYTRACKS_H \ No newline at end of file diff --git a/coreengine/viewdisplayvolume.c b/coreengine/viewdisplayvolume.c new file mode 100644 index 0000000..2764a67 --- /dev/null +++ b/coreengine/viewdisplayvolume.c @@ -0,0 +1,52 @@ +#include "viewdisplayvolume.h" + +/************************************************************************************ +* cViewVolume +************************************************************************************/ + +cViewVolume::cViewVolume(void) { + viewId = eViewType::DisplayVolume; + viewName = strdup("displayvolume"); + numViewElements = (int)eVeDisplayVolume::count; + viewElements = new cViewElement*[numViewElements]; + for (int i=0; i < numViewElements; i++) { + viewElements[i] = NULL; + } + SetViewElements(); + ClearVariables(); + veVolume = NULL; +} + +cViewVolume::~cViewVolume() { +} + +void cViewVolume::SetViewElements(void) { + viewElementNames.insert(pair("background", (int)eVeDisplayVolume::background)); + viewElementNames.insert(pair("volume", (int)eVeDisplayVolume::volume)); +} + +void cViewVolume::SetViewElementObjects(void) { + if (!viewElements[(int)eVeDisplayVolume::volume]) + return; + veVolume = dynamic_cast(viewElements[(int)eVeDisplayVolume::volume]); +} + +void cViewVolume::ClearVariables(void) { + init = true; +} + +void cViewVolume::SetVolume(int current, int total, bool mute) { + if (veVolume) + veVolume->Set(current, total, mute); +} + +void cViewVolume::Flush(void) { + if (init) { + sdOsd.LockFlush(); + Render((int)eVeDisplayVolume::background); + } + Render((int)eVeDisplayVolume::volume); + cView::Flush(); +} + + diff --git a/coreengine/viewdisplayvolume.h b/coreengine/viewdisplayvolume.h new file mode 100644 index 0000000..b65b3fd --- /dev/null +++ b/coreengine/viewdisplayvolume.h @@ -0,0 +1,19 @@ +#ifndef __VIEWDISPLAYVOLUME_H +#define __VIEWDISPLAYVOLUME_H + +#include "view.h" + +class cViewVolume : public cView { +private: + cVeVolume *veVolume; + void SetViewElements(void); + void SetViewElementObjects(void); + void ClearVariables(void); +public: + cViewVolume(void); + virtual ~cViewVolume(void); + void SetVolume(int current, int total, bool mute); + void Flush(void); +}; + +#endif //__VIEWDISPLAYVOLUME_H \ No newline at end of file diff --git a/coreengine/viewelement.c b/coreengine/viewelement.c new file mode 100644 index 0000000..5f6f04b --- /dev/null +++ b/coreengine/viewelement.c @@ -0,0 +1,532 @@ +#include "viewelement.h" +#include "../config.h" + +/****************************************************************** +* cViewElement +******************************************************************/ +cViewElement::cViewElement(void) { + sdOsd = NULL; + id = -1; + dirty = true; + init = true; + drawn = false; + scrollingStarted = false; + blocked = false; + detached = false; + waitOnWakeup = true; + startAnimation = true; + globals = NULL; + tokenContainer = NULL; + attribs = new cViewElementAttribs((int)eViewElementAttribs::count); + detacher = NULL; + fader = NULL; + shifter = NULL; +} + +cViewElement::cViewElement(const cViewElement &other) { + sdOsd = other.sdOsd; + id = other.id; + dirty = other.dirty; + init = other.init; + drawn = false; + scrollingStarted = false; + blocked = false; + detached = false; + waitOnWakeup = true; + startAnimation = true; + globals = other.globals; + container.Set(other.container.X(), other.container.Y(), other.container.Width(), other.container.Height()); + tokenContainer = NULL; + attribs = new cViewElementAttribs(*other.attribs); + + for (cAreaNode *node = other.areaNodes.First(); node; node = other.areaNodes.Next(node)) { + if (cArea *a = dynamic_cast(node)) { + areaNodes.Add(new cArea(*a)); + } else if (cAreaContainer *ac = dynamic_cast(node)) { + areaNodes.Add(new cAreaContainer(*ac)); + } + } + + detacher = NULL; + fader = NULL; + shifter = NULL; +} + +cViewElement::~cViewElement(void) { + delete attribs; + delete detacher; + delete fader; + delete shifter; + delete tokenContainer; +} + +/****************************************************************** +* Public Functions +******************************************************************/ +cViewElement *cViewElement::CreateViewElement(const char *name, const char *viewname) { + cViewElement *e = NULL; + + //common view elements + if (!strcmp(name, "background") && strcmp(viewname, "displayaudiotracks")) + e = new cViewElement(); + else if (!strcmp(name, "datetime")) + e = new cVeDateTime(); + else if (!strcmp(name, "time")) + e = new cVeTime(); + else if (!strcmp(name, "message")) + e = new cVeMessage(); + else if (!strcmp(name, "devices")) + e = new cVeDevices(); + else if (!strcmp(name, "currentweather")) + e = new cVeCurrentWeather(); + else if (!strcmp(name, "customtokens")) + e = new cVeCustomTokens(); + + //displaychannel viewelements + else if (!strcmp(name, "channelinfo")) + e = new cVeDcChannelInfo(); + else if (!strcmp(name, "channelgroup")) + e = new cVeDcChannelGroup(); + else if (!strcmp(name, "epginfo")) + e = new cVeDcEpgInfo(); + else if (!strcmp(name, "progressbar") && !strcmp(viewname, "displaychannel")) + e = new cVeDcProgressBar(); + else if (!strcmp(name, "statusinfo")) + e = new cVeDcStatusInfo(); + else if (!strcmp(name, "audioinfo")) + e = new cVeDcAudioInfo(); + else if (!strcmp(name, "screenresolution")) + e = new cVeDcScreenResolution(); + else if (!strcmp(name, "signalquality")) + e = new cVeDcSignalQuality(); + else if (!strcmp(name, "scrapercontent") && !strcmp(viewname, "displaychannel")) + e = new cVeDcScraperContent(); + else if (!strcmp(name, "ecminfo")) + e = new cVeDcEcmInfo(); + + //displaymenu viewelements + else if (!strcmp(name, "header") && strcmp(viewname, "displayaudiotracks")) + e = new cVeDmHeader(); + else if (!strcmp(name, "sortmode")) + e = new cVeDmSortmode(); + else if (!strcmp(name, "colorbuttons")) + e = new cVeDmColorbuttons(); + else if (!strcmp(name, "scrollbar")) + e = new cVeDmScrollbar(); + else if (!strcmp(name, "timers")) + e = new cVeDmTimers(); + else if (!strcmp(name, "currentschedule")) + e = new cVeDmCurrentschedule(); + else if (!strcmp(name, "discusage")) + e = new cVeDmDiscusage(); + else if (!strcmp(name, "systemload")) + e = new cVeDmSystemload(); + else if (!strcmp(name, "systemmemory")) + e = new cVeDmSystemmemory(); + else if (!strcmp(name, "temperatures")) + e = new cVeDmTemperatures(); + else if (!strcmp(name, "vdrstatistics")) + e = new cVeDmVdrstatistics(); + else if (!strcmp(name, "lastrecordings")) + e = new cVeDmLastrecordings(); + else if (!strcmp(name, "detailheaderepg")) + e = new cVeDmDetailheaderEpg(); + else if (!strcmp(name, "detailheaderrec")) + e = new cVeDmDetailheaderRec(); + else if (!strcmp(name, "detailheaderplugin")) + e = new cVeDmDetailheaderPlugin(); + else if (!strcmp(name, "tablabels")) + e = new cVeDmTablabels(); + + //displayreplay viewelements + else if (!strcmp(name, "backgroundmodeonly")) + e = new cViewElement(); + else if (!strcmp(name, "rectitle")) + e = new cVeDrRecTitle(); + else if (!strcmp(name, "recinfo")) + e = new cVeDrRecInfo(); + else if (!strcmp(name, "currenttime")) + e = new cVeDrCurrentTime(); + else if (!strcmp(name, "totaltime")) + e = new cVeDrTotalTime(); + else if (!strcmp(name, "endtime")) + e = new cVeDrEndTime(); + else if (!strcmp(name, "progressbar") && !strcmp(viewname, "displayreplay")) + e = new cVeDrProgressBar(); + else if (!strcmp(name, "cutmarks")) + e = new cVeDrCutMarks(); + else if (!strcmp(name, "controlicons")) + e = new cVeDrControlIcons(); + else if (!strcmp(name, "controliconsmodeonly")) + e = new cVeDrControlIcons(); + else if (!strcmp(name, "progressmodeonly")) + e = new cVeDrProgressModeonly(); + else if (!strcmp(name, "jump")) + e = new cVeDrJump(); + else if (!strcmp(name, "onpause")) + e = new cVeDrOnPause(); + else if (!strcmp(name, "onpausemodeonly")) + e = new cVeDrOnPause(); + else if (!strcmp(name, "scrapercontent") && !strcmp(viewname, "displayreplay")) + e = new cVeDrScraperContent(); + + //displayvolume viewelements + else if (!strcmp(name, "volume")) + e = new cVeVolume(); + + //displayvolume viewelements + else if (!strcmp(name, "background") && !strcmp(viewname, "displayaudiotracks")) + e = new cVeDtBackground(); + else if (!strcmp(name, "header") && !strcmp(viewname, "displayaudiotracks")) + e = new cVeDtHeader(); + + //default + else { + dsyslog("skindesigner: unknown view element %s", name); + e = new cViewElement(); + } + + return e; +} + +void cViewElement::SetGlobals(cGlobals *globals) { + this->globals = globals; + attribs->SetGlobals(globals); + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetGlobals(globals); + } +} + +void cViewElement::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + InheritTokenContainer(); +} + +bool cViewElement::Detached(void) { + return detached; +} + +void cViewElement::SetContainer(int x, int y, int width, int height) { + container.SetX(x); + container.SetY(y); + container.SetWidth(width); + container.SetHeight(height); +} + +void cViewElement::SetAttributes(vector &attributes) { + attribs->Set(attributes); +} + +void cViewElement::AddArea(cAreaNode *area) { + areaNodes.Add(area); +} + +void cViewElement::SetAreaX(int x) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetX(x); + } +} + +void cViewElement::SetAreaY(int y) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetY(y); + } +} + +void cViewElement::SetAreaWidth(int width) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetWidth(width); + } +} + +void cViewElement::SetAreaHeight(int height) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetHeight(height); + } +} + +void cViewElement::SetPosition(int newX, int newY, int newWidth, int newHeight) { + cRect newPos(newX, newY, newWidth, newHeight); + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetViewPort(newPos); + } +} + +void cViewElement::Cache(void) { + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->Cache(); + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + node->Cache(); + } +} + +bool cViewElement::Execute(void) { + return attribs->DoExecute(); +} + +void cViewElement::Clear(void) { + tokenContainer->Clear(); + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + sdOsd->Lock(); + node->Clear(); + sdOsd->Unlock(); + } + dirty = false; + drawn = false; + scrollingStarted = false; +} + +void cViewElement::Hide(void) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + sdOsd->Lock(); + node->Hide(); + sdOsd->Unlock(); + } + init = true; + StopScrolling(); +} + +void cViewElement::Show(void) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + sdOsd->Lock(); + node->Show(); + sdOsd->Unlock(); + } +} + +void cViewElement::WakeUp(void) { + if (!detacher || !waitOnWakeup) { + return; + } + detacher->WakeUp(); +} + +void cViewElement::Close(void) { + delete detacher; + detacher = NULL; + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + sdOsd->Lock(); + node->Close(); + sdOsd->Unlock(); + } + StopScrolling(); + dirty = true; + init = true; + startAnimation = true; + drawn = false; + scrollingStarted = false; + blocked = false; +} + +void cViewElement::Render(void) { + if (!dirty || blocked) + return; + + if (attribs->DoDebug()) + Debug(); + + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + //Check redraw of already scrolling list element + if (drawn && scrollingStarted && node->Scrolling()) { + if (DoScroll()) { + //current list element + continue; + } else { + //not current list element anymore + scrollingStarted = false; + } + } + sdOsd->Lock(); + node->Clear(); + sdOsd->Unlock(); + if (!node->Execute()) + continue; + if (node->BackgroundArea() && drawn) + continue; + sdOsd->Lock(); + node->Render(); + sdOsd->Unlock(); + + if (DoScroll() && node->Scrolling()) { + cArea *scrollArea = node->ScrollingArea(); + if (scrollArea) { + scrollingStarted = true; + cAnimation *scroller = new cAnimation(scrollArea); + scrollers.Add(scroller); + scroller->Start(); + } + } + } + dirty = false; + drawn = true; + if (startAnimation) { + startAnimation = false; + StartAnimation(); + } +} + +void cViewElement::StopScrolling(bool deletePixmaps) { + for (cAnimation *scroller = scrollers.First(); scroller; scroller = scrollers.Next(scroller)) { + scroller->Stop(deletePixmaps); + } + scrollers.Clear(); +} + +void cViewElement::ParseDetached(void) { + Parse(true); +} + +void cViewElement::RenderDetached(void) { + blocked = false; + Render(); +} + +bool cViewElement::Shifting(void) { + if (attribs->ShiftTime() >= 0) { + return true; + } + return false; +} + +bool cViewElement::Fading(void) { + if (attribs->FadeTime() >= 0) { + return true; + } + return false; +} + +int cViewElement::FadeTime(void) { + return attribs->FadeTime(); +} + +int cViewElement::ShiftTime(void) { + return attribs->ShiftTime(); +} + +int cViewElement::ShiftMode(void) { + return attribs->ShiftMode(); +} + +void cViewElement::StartAnimation(void) { + if (ShiftTime() > 0) { + cRect shiftbox = CoveredArea(); + cPoint ref = cPoint(shiftbox.X(), shiftbox.Y()); + cPoint start = ShiftStart(shiftbox); + SetPosition(start, ref); + sdOsd->Flush(); + delete shifter; + shifter = new cAnimation((cShiftable*)this, start, ref, true); + shifter->Start(); + } else if (FadeTime() > 0) { + SetTransparency(100); + sdOsd->Flush(); + delete fader; + fader = new cAnimation((cFadable*)this, true); + fader->Start(); + } +} + +void cViewElement::SetTransparency(int transparency, bool force) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + sdOsd->Lock(); + node->SetTransparency(transparency); + sdOsd->Unlock(); + } +} + +void cViewElement::SetPosition(cPoint &position, cPoint &reference, bool force) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + sdOsd->Lock(); + node->SetPosition(position, reference); + sdOsd->Unlock(); + } +} + +cRect cViewElement::CoveredArea(void) { + cRect unionArea; + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + unionArea.Combine(node->CoveringArea()); + } + return unionArea; +} + +void cViewElement::Flush(void) { + sdOsd->Flush(); +} + +bool cViewElement::Parse(bool forced) { + if (blocked && !forced) { + return false; + } + if (!Detached() || !init) { + return true; + } + delete detacher; + detacher = new cAnimation((cDetachable*)this, waitOnWakeup, startAnimation); + detacher->Start(); + startAnimation = false; + init = false; + blocked = true; + return false; +} + +cFunction *cViewElement::GetFunction(const char *name) { + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + if (cFunction *f = node->GetFunction(name)) + return f; + } + return NULL; +} + +void cViewElement::Debug(bool full) { + esyslog("skindesigner: ---> viewElement %d", id); + tokenContainer->Debug(); + esyslog("skindesigner: container %d %d %dx%d", container.X(), container.Y(), container.Width(), container.Height()); + attribs->Debug(); + if (!full) + return; + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->Debug(full); + } +} + +/****************************************************************** +* protected Functions +******************************************************************/ +void cViewElement::InheritTokenContainer(void) { + tokenContainer->CreateContainers(); + attribs->SetTokenContainer(tokenContainer); + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetTokenContainer(tokenContainer); + } +} + +void cViewElement::InheritTokenContainerDeep(void) { + tokenContainer->CreateContainers(); + attribs->SetTokenContainerDeep(tokenContainer); + for (cAreaNode *node = areaNodes.First(); node; node = areaNodes.Next(node)) { + node->SetTokenContainerDeep(tokenContainer); + } +} + +cPoint cViewElement::ShiftStart(cRect &shiftbox) { + eShiftType type = (eShiftType)attribs->ShiftType(); + cPoint start; + if (type == eShiftType::none) { + start = attribs->ShiftStartpoint(); + } else if (type == eShiftType::left) { + start.SetX(-shiftbox.Width()); + start.SetY(shiftbox.Y()); + } else if (type == eShiftType::right) { + start.SetX(cOsd::OsdWidth()); + start.SetY(shiftbox.Y()); + } else if (type == eShiftType::top) { + start.SetX(shiftbox.X()); + start.SetY(-shiftbox.Height()); + } else if (type == eShiftType::bottom) { + start.SetX(shiftbox.X()); + start.SetY(cOsd::OsdHeight()); + } + return start; +} \ No newline at end of file diff --git a/coreengine/viewelement.h b/coreengine/viewelement.h new file mode 100644 index 0000000..af12a6c --- /dev/null +++ b/coreengine/viewelement.h @@ -0,0 +1,93 @@ +#ifndef __VIEWELEMENT_H +#define __VIEWELEMENT_H + +#include +#include +#include +#include +#include +#include "osdwrapper.h" +#include "globals.h" +#include "../libskindesignerapi/tokencontainer.h" +#include "area.h" +#include "animation.h" + +/****************************************************************** +* cViewElement +******************************************************************/ +class cViewElement : public cDetachable, public cFadable, public cShiftable { +protected: + cSdOsd *sdOsd; + int id; + bool init; + bool drawn; + bool dirty; + bool blocked; + bool detached; + bool waitOnWakeup; + bool scrollingStarted; + bool startAnimation; + cGlobals *globals; + cRect container; + cViewElementAttribs *attribs; + cList areaNodes; + skindesignerapi::cTokenContainer *tokenContainer; + cList scrollers; + cAnimation *detacher; + cAnimation *fader; + cAnimation *shifter; + void InheritTokenContainer(void); + void InheritTokenContainerDeep(void); + virtual bool DoScroll(void) { return true; }; + cPoint ShiftStart(cRect &shiftbox); +public: + cViewElement(void); + cViewElement(const cViewElement &other); + virtual ~cViewElement(void); + void SetOsd(cSdOsd *osd) { sdOsd = osd; }; + static cViewElement *CreateViewElement(const char *name, const char *viewname); + void SetId(int id) { this->id = id; }; + void SetGlobals(cGlobals *globals); + virtual void SetTokenContainer(void); + void SetDetached(void) { detached = true; }; + void UnsetWaitOnWakeup(void) { waitOnWakeup = false; }; + bool Detached(void); + void SetContainer(int x, int y, int width, int height); + void SetAttributes(vector &attributes); + void AddArea(cAreaNode *area); + void SetAreaX(int x); + void SetAreaY(int y); + void SetAreaWidth(int width); + void SetAreaHeight(int height); + void Cache(void); + virtual void Close(void); + virtual void Clear(void); + void Hide(void); + void Show(void); + void WakeUp(void); + bool Execute(void); + void SetDirty(void) { dirty = true; }; + bool Dirty(void) { return dirty; }; + void SetPosition(int newX, int newY, int newWidth, int newHeight); + virtual void Render(void); + void StopScrolling(bool deletePixmaps = true); + eOrientation Orientation(void) { return attribs->Orientation(); }; + virtual int Delay(void) { return attribs->Delay(); }; + void ParseDetached(void); + void RenderDetached(void); + bool Shifting(void); + bool Fading(void); + int FadeTime(void); + int ShiftTime(void); + int ShiftMode(void); + void StartAnimation(void); + virtual void SetTransparency(int transparency, bool force = false); + virtual void SetPosition(cPoint &position, cPoint &reference, bool force = false); + cRect CoveredArea(void); + void Flush(void); + virtual bool Parse(bool forced = false); + cFunction *GetFunction(const char *name); + virtual void Debug(bool full = false); +}; + +#endif //__VIEWELEMENT_H \ No newline at end of file diff --git a/coreengine/viewelementplugin.c b/coreengine/viewelementplugin.c new file mode 100644 index 0000000..7d50a82 --- /dev/null +++ b/coreengine/viewelementplugin.c @@ -0,0 +1,36 @@ +#include "viewelementplugin.h" +#include "../config.h" + +cVePlugin::cVePlugin(void) { + plugId = -1; + viewId = -1; +} + +cVePlugin::~cVePlugin(void) { +} + +void cVePlugin::Close(void) { + cViewElement::Close(); +} + +void cVePlugin::SetTokenContainer(void) { + skindesignerapi::cTokenContainer *tkVe = plgManager->GetTokenContainerVE(plugId, viewId, id); + if (!tkVe) + return; + tokenContainer = new skindesignerapi::cTokenContainer(*tkVe); + InheritTokenContainer(); +} + +void cVePlugin::Set(skindesignerapi::cTokenContainer *tk) { + tokenContainer->Clear(); + tokenContainer->SetTokens(tk); + SetDirty(); +} + +bool cVePlugin::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!dirty) + return false; + return true; +} diff --git a/coreengine/viewelementplugin.h b/coreengine/viewelementplugin.h new file mode 100644 index 0000000..8e2d5f1 --- /dev/null +++ b/coreengine/viewelementplugin.h @@ -0,0 +1,22 @@ +#ifndef __VIEWELEMENTPLUGIN_H +#define __VIEWELEMENTPLUGIN_H + +#include "viewelement.h" + +class cVePlugin : public cViewElement { +private: + int plugId; + int viewId; +public: + cVePlugin(void); + virtual ~cVePlugin(void); + void SetPluginId(int plugId) { this->plugId = plugId; }; + void SetViewId(int viewId) { this->viewId = viewId; }; + void Close(void); + void SetTokenContainer(void); + void Set(skindesignerapi::cTokenContainer *tk); + bool Parse(bool forced = false); + const char *Name(void) { return attribs->Name(); }; +}; + +#endif //__VIEWELEMENTPLUGIN_H diff --git a/coreengine/viewelementscommon.c b/coreengine/viewelementscommon.c new file mode 100644 index 0000000..92538e5 --- /dev/null +++ b/coreengine/viewelementscommon.c @@ -0,0 +1,531 @@ +#include "viewelementscommon.h" +#include "../config.h" +#include "../services/weatherforecast.h" + +/****************************************************************** +* cVeDateTime +******************************************************************/ +cVeDateTime::cVeDateTime(void) { + lastMinute = -1; +} + +cVeDateTime::~cVeDateTime(void) { +} + +void cVeDateTime::Close(void) { + lastMinute = -1; + cViewElement::Close(); +} + +void cVeDateTime::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{time}", (int)eDateTimeST::time); + tokenContainer->DefineStringToken("{dayleadingzero}", (int)eDateTimeST::dayleadingzero); + tokenContainer->DefineStringToken("{dayname}", (int)eDateTimeST::dayname); + tokenContainer->DefineStringToken("{daynameshort}", (int)eDateTimeST::daynameshort); + tokenContainer->DefineStringToken("{month}", (int)eDateTimeST::month); + tokenContainer->DefineStringToken("{monthname}", (int)eDateTimeST::monthname); + tokenContainer->DefineStringToken("{monthnameshort}", (int)eDateTimeST::monthnameshort); + tokenContainer->DefineIntToken("{day}", (int)eDateTimeIT::day); + tokenContainer->DefineIntToken("{year}", (int)eDateTimeIT::year); + InheritTokenContainer(); +} + +bool cVeDateTime::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + time_t t = time(0); // get time now + struct tm * now = localtime(&t); + int min = now->tm_min; + if (!forced && min == lastMinute) { + return false; + } + lastMinute = min; + SetDirty(); + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDateTimeIT::year, now->tm_year + 1900); + tokenContainer->AddIntToken((int)eDateTimeIT::day, now->tm_mday); + + char monthname[20]; + char monthshort[10]; + strftime(monthshort, sizeof(monthshort), "%b", now); + strftime(monthname, sizeof(monthname), "%B", now); + + tokenContainer->AddStringToken((int)eDateTimeST::monthname, monthname); + tokenContainer->AddStringToken((int)eDateTimeST::monthnameshort, monthshort); + tokenContainer->AddStringToken((int)eDateTimeST::month, *cString::sprintf("%02d", now->tm_mon + 1)); + tokenContainer->AddStringToken((int)eDateTimeST::dayleadingzero, *cString::sprintf("%02d", now->tm_mday)); + tokenContainer->AddStringToken((int)eDateTimeST::dayname, *WeekDayNameFull(now->tm_wday)); + tokenContainer->AddStringToken((int)eDateTimeST::daynameshort, *WeekDayName(now->tm_wday)); + tokenContainer->AddStringToken((int)eDateTimeST::time, *TimeString(t)); + return true; +} + +/****************************************************************** +* cVeTime +******************************************************************/ +cVeTime::cVeTime(void) { + lastSecond = -1; +} + +cVeTime::~cVeTime(void) { +} + +void cVeTime::Close(void) { + lastSecond = -1; + cViewElement::Close(); +} + +void cVeTime::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{sec}", (int)eTimeIT::sec); + tokenContainer->DefineIntToken("{min}", (int)eTimeIT::min); + tokenContainer->DefineIntToken("{hour}", (int)eTimeIT::hour); + tokenContainer->DefineIntToken("{hmins}", (int)eTimeIT::hmins); + InheritTokenContainer(); +} + +bool cVeTime::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + time_t t = time(0); // get time now + struct tm * now = localtime(&t); + int sec = now->tm_sec; + if (!forced && sec == lastSecond) { + return false; + } + lastSecond = sec; + SetDirty(); + + int min = now->tm_min; + int hour = now->tm_hour; + int hourMinutes = hour%12 * 5 + min / 12; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eTimeIT::sec, sec); + tokenContainer->AddIntToken((int)eTimeIT::min, min); + tokenContainer->AddIntToken((int)eTimeIT::hour, hour); + tokenContainer->AddIntToken((int)eTimeIT::hmins, hourMinutes); + return true; +} +/****************************************************************** +* cVeMessage +******************************************************************/ +cVeMessage::cVeMessage(void) { + changed = false; + text = NULL; + type = mtStatus; +} + +cVeMessage::~cVeMessage(void) { + free(text); +} + +void cVeMessage::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{text}", (int)eMessageST::text); + tokenContainer->DefineIntToken("{status}", (int)eMessageIT::status); + tokenContainer->DefineIntToken("{info}", (int)eMessageIT::info); + tokenContainer->DefineIntToken("{warning}", (int)eMessageIT::warning); + tokenContainer->DefineIntToken("{error}", (int)eMessageIT::error); + InheritTokenContainer(); +} + +void cVeMessage::Set(eMessageType type, const char *text) { + if (!text) + return; + free(this->text); + this->text = strdup(text); + this->type = type; + changed = true; +} + +bool cVeMessage::Parse(bool forced) { + if (!cViewElement::Parse(forced) || !changed) + return false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eMessageIT::status, (type == mtStatus) ? true : false); + tokenContainer->AddIntToken((int)eMessageIT::info, (type == mtInfo) ? true : false); + tokenContainer->AddIntToken((int)eMessageIT::warning, (type == mtWarning) ? true : false); + tokenContainer->AddIntToken((int)eMessageIT::error, (type == mtError) ? true : false); + tokenContainer->AddStringToken((int)eMessageST::text, text); + SetDirty(); + changed = false; + return true; +} + +/****************************************************************** +* cVeDevices +******************************************************************/ +cVeDevices::cVeDevices(void) { + lastRefresh = 0; + initial = true; + devicesIndex = -1; + lastSignalStrength = NULL; + lastSignalQuality = NULL; + recDevices = NULL; +} + +cVeDevices::~cVeDevices(void) { + mutexDevices.Lock(); + delete[] lastSignalStrength; + lastSignalStrength = NULL; + delete[] lastSignalQuality; + lastSignalQuality = NULL; + delete[] recDevices; + recDevices = NULL; + mutexDevices.Unlock(); +} + +void cVeDevices::Init(void) { + light = (attribs->Mode() == (int)eViewElementMode::light) ? true : false; + int totalDevices = cDevice::NumDevices(); + for (int i = 0; i < totalDevices; i++) { + const cDevice *device = cDevice::GetDevice(i); + if (!device || !device->NumProvidedSystems()) { + continue; + } + devices.push_back(i); + } + numDevices = devices.size(); + lastSignalStrength = new int[numDevices]; + lastSignalQuality = new int[numDevices]; + recDevices = new bool[numDevices]; + mutexDevices.Lock(); + for (int i=0; iDefineIntToken("{numdevices}", (int)eDevicesIT::numdevices); + tokenContainer->DefineLoopToken("{devices[num]}", (int)eDevicesLT::num); + tokenContainer->DefineLoopToken("{devices[type]}", (int)eDevicesLT::type); + tokenContainer->DefineLoopToken("{devices[istuned]}", (int)eDevicesLT::istuned); + tokenContainer->DefineLoopToken("{devices[livetv]}", (int)eDevicesLT::livetv); + tokenContainer->DefineLoopToken("{devices[recording]}", (int)eDevicesLT::recording); + tokenContainer->DefineLoopToken("{devices[hascam]}", (int)eDevicesLT::hascam); + tokenContainer->DefineLoopToken("{devices[cam]}", (int)eDevicesLT::cam); + tokenContainer->DefineLoopToken("{devices[signalstrength]}", (int)eDevicesLT::signalstrength); + tokenContainer->DefineLoopToken("{devices[signalquality]}", (int)eDevicesLT::signalquality); + tokenContainer->DefineLoopToken("{devices[channelnumber]}", (int)eDevicesLT::channelnumber); + tokenContainer->DefineLoopToken("{devices[channelname]}", (int)eDevicesLT::channelname); + tokenContainer->DefineLoopToken("{devices[channellogoexists]}", (int)eDevicesLT::channellogoexists); + tokenContainer->DefineLoopToken("{devices[channelid]}", (int)eDevicesLT::channelid); + tokenContainer->DefineLoopToken("{devices[source]}", (int)eDevicesLT::source); + + devicesIndex = tokenContainer->LoopIndex("devices"); + InheritTokenContainer(); +} + +bool cVeDevices::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (initial) { + Init(); + initial = false; + } else { + //in light modus content is static + if (light) + return false; + //check if drawing is necessary + if (lastRefresh - cTimeMs::Now() < 500) + return false; + bool changed = false; + for (int i = 0; i < numDevices; i++) { + const cDevice *device = cDevice::GetDevice(devices[i]); + if (!device || !device->NumProvidedSystems()) { + continue; + } + int signalStrength = device->SignalStrength(); + int signalQuality = device->SignalQuality(); + int lastSigStr = 0; + int lastSigQual = 0; + mutexDevices.Lock(); + if (lastSignalStrength && lastSignalQuality) { + lastSigStr = lastSignalStrength[i]; + lastSigQual = lastSignalQuality[i]; + } + mutexDevices.Unlock(); + if ((signalStrength != lastSigStr) || (signalQuality != lastSigQual)) { + changed = true; + break; + } + } + if (!changed) { + return false; + } + } + + //check device which currently displays live tv + int deviceLiveTV = -1; + cDevice *primaryDevice = cDevice::PrimaryDevice(); + if (primaryDevice) { + if (!primaryDevice->Replaying() || primaryDevice->Transferring()) + deviceLiveTV = cDevice::ActualDevice()->DeviceNumber(); + else + deviceLiveTV = primaryDevice->DeviceNumber(); + } + //check currently recording devices + for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) { + if (!timer->Recording()) { + continue; + } + if (cRecordControl *RecordControl = cRecordControls::GetRecordControl(timer)) { + const cDevice *recDevice = RecordControl->Device(); + if (recDevice) { + mutexDevices.Lock(); + if (recDevices) + recDevices[recDevice->DeviceNumber()] = true; + mutexDevices.Unlock(); + } + } + } + + //create loop container + tokenContainer->Clear(); + + vector loopInfo; + loopInfo.push_back(numDevices); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + tokenContainer->AddIntToken((int)eDevicesIT::numdevices, numDevices); + + for (int i = 0; i < numDevices; i++) { + const cDevice *device = cDevice::GetDevice(devices[i]); + if (!device || !device->NumProvidedSystems()) { + continue; + } + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::num, *cString::sprintf("%d", i)); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::type, *(device->DeviceType())); + + cCamSlot *camSlot = device->CamSlot(); + int camNumber = -1; + if (camSlot) { + camNumber = camSlot->SlotNumber(); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::hascam, "1"); + } else { + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::hascam, "0"); + } + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::cam, *cString::sprintf("%d", camNumber)); + + int signalStrength = 0; + int signalQuality = 0; + if (!light) { + signalStrength = device->SignalStrength(); + signalQuality = device->SignalQuality(); + } + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::signalstrength, *cString::sprintf("%d", signalStrength)); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::signalstrength, *cString::sprintf("%d", signalQuality)); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::livetv, i == deviceLiveTV ? "1" : "0"); + + bool isRecording = false; + mutexDevices.Lock(); + if (recDevices && recDevices[i]) + isRecording = true; + mutexDevices.Unlock(); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::recording, isRecording ? "1" : "0"); + + const cChannel *channel = device->GetCurrentlyTunedTransponder(); + const cSource *source = (channel) ? Sources.Get(channel->Source()) : NULL; + if (channel && channel->Number() > 0) { + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::channelnumber, *cString::sprintf("%d", channel->Number())); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::channelname, channel->Name()); + string channelID = *(channel->GetChannelID().ToString()); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::channelid, channelID.c_str()); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::channellogoexists, imgCache->LogoExists(channelID) ? "1" : "0"); + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::istuned, "1"); + } else { + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::istuned, "0"); + } + + tokenContainer->AddLoopToken(devicesIndex, i, (int)eDevicesLT::source, source ? source->Description() : ""); + + mutexDevices.Lock(); + if (lastSignalStrength) + lastSignalStrength[i] = signalStrength; + if (lastSignalQuality) + lastSignalQuality[i] = signalQuality; + mutexDevices.Unlock(); + } + + SetDirty(); + lastRefresh = cTimeMs::Now(); + return true; +} +/****************************************************************** +* cVeCurrentWeather +******************************************************************/ +cVeCurrentWeather::cVeCurrentWeather(void) { +} + +cVeCurrentWeather::~cVeCurrentWeather(void) { +} + +void cVeCurrentWeather::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{timestamp}", (int)eCurrentWeatherST::timestamp); + tokenContainer->DefineStringToken("{summary}", (int)eCurrentWeatherST::summary); + tokenContainer->DefineStringToken("{icon}", (int)eCurrentWeatherST::icon); + tokenContainer->DefineStringToken("{precipitationtype}", (int)eCurrentWeatherST::precipitationtype); + tokenContainer->DefineStringToken("{windbearingstring}", (int)eCurrentWeatherST::windbearingstring); + tokenContainer->DefineStringToken("{temperature}", (int)eCurrentWeatherST::temperature); + tokenContainer->DefineStringToken("{apparenttemperature}", (int)eCurrentWeatherST::apparenttemperature); + tokenContainer->DefineStringToken("{mintemperature}", (int)eCurrentWeatherST::mintemperature); + tokenContainer->DefineStringToken("{maxtemperature}", (int)eCurrentWeatherST::maxtemperature); + tokenContainer->DefineStringToken("{precipitationintensity}", (int)eCurrentWeatherST::precipitationintensity); + tokenContainer->DefineStringToken("{windspeed}", (int)eCurrentWeatherST::windspeed); + tokenContainer->DefineStringToken("{visibility}", (int)eCurrentWeatherST::visibility); + tokenContainer->DefineStringToken("{pressure}", (int)eCurrentWeatherST::pressure); + tokenContainer->DefineStringToken("{ozone}", (int)eCurrentWeatherST::ozone); + tokenContainer->DefineIntToken("{precipitationprobability}", (int)eCurrentWeatherIT::precipitationprobability); + tokenContainer->DefineIntToken("{humidity}", (int)eCurrentWeatherIT::humidity); + tokenContainer->DefineIntToken("{windbearing}", (int)eCurrentWeatherIT::windbearing); + tokenContainer->DefineIntToken("{cloudcover}", (int)eCurrentWeatherIT::cloudcover); + InheritTokenContainer(); +} + +bool cVeCurrentWeather::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + static cPlugin *pWeatherForecast = cPluginManager::GetPlugin("weatherforecast"); + if (!pWeatherForecast) + return false; + cServiceCurrentWeather currentWeather; + if (!pWeatherForecast->Service("GetCurrentWeather", ¤tWeather)) { + return false; + } + SetDirty(); + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eCurrentWeatherST::timestamp, currentWeather.timeStamp.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::temperature, currentWeather.temperature.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::apparenttemperature, currentWeather.apparentTemperature.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::mintemperature, currentWeather.minTemperature.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::maxtemperature, currentWeather.maxTemperature.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::summary, currentWeather.summary.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::icon, currentWeather.icon.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::precipitationintensity, currentWeather.precipitationIntensity.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::precipitationtype, currentWeather.precipitationType.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::windspeed, currentWeather.windSpeed.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::windbearingstring, currentWeather.windBearingString.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::visibility, currentWeather.visibility.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::pressure, currentWeather.pressure.c_str()); + tokenContainer->AddStringToken((int)eCurrentWeatherST::ozone, currentWeather.ozone.c_str()); + tokenContainer->AddIntToken((int)eCurrentWeatherIT::precipitationprobability, currentWeather.precipitationProbability); + tokenContainer->AddIntToken((int)eCurrentWeatherIT::humidity, currentWeather.humidity); + tokenContainer->AddIntToken((int)eCurrentWeatherIT::windbearing, currentWeather.windBearing); + tokenContainer->AddIntToken((int)eCurrentWeatherIT::cloudcover, currentWeather.cloudCover); + return true; +} +/****************************************************************** +* cVeCustomTokens +******************************************************************/ +cVeCustomTokens::cVeCustomTokens(void) { +} + +cVeCustomTokens::~cVeCustomTokens(void) { +} + +void cVeCustomTokens::Reset(void) { + globals->ResetCustomTokenChange(); +} + +void cVeCustomTokens::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + int numTokens = config.numCustomTokens; + for (int i=0; i < numTokens; i++) { + cString nameIntToken = cString::sprintf("{customint%d}", i+1); + cString nameStringToken = cString::sprintf("{customstring%d}", i+1); + tokenContainer->DefineStringToken(*nameStringToken, i); + tokenContainer->DefineIntToken(*nameIntToken, i); + } + InheritTokenContainer(); +} + +bool cVeCustomTokens::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + + if (!globals->CustomTokenChange()) + return false; + + tokenContainer->Clear(); + map customStringTokens = globals->GetCustomStringTokens(); + for (map::iterator it = customStringTokens.begin(); it != customStringTokens.end(); it++) { + int index = it->first; + if (index > 0 && index <= config.numCustomTokens) { + tokenContainer->AddStringToken(index-1, it->second.c_str()); + } + } + map customIntTokkens = globals-> GetCustomIntTokens(); + for (map::iterator it = customIntTokkens.begin(); it != customIntTokkens.end(); it++) { + int index = it->first; + if (index > 0 && index <= config.numCustomTokens) { + tokenContainer->AddIntToken(index-1, it->second); + } + } + SetDirty(); + return true; +} + +/****************************************************************** +* cVeVolume +******************************************************************/ +cVeVolume::cVeVolume(void) { + current = 0; + total = 0; + mute = false; + changed = true; +} + +cVeVolume::~cVeVolume(void) { +} + +void cVeVolume::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{volume}", (int)eDVVolumeIT::volume); + tokenContainer->DefineIntToken("{volpercent}", (int)eDVVolumeIT::volpercent); + tokenContainer->DefineIntToken("{maxvolume}", (int)eDVVolumeIT::maxvolume); + tokenContainer->DefineIntToken("{mute}", (int)eDVVolumeIT::mute); + InheritTokenContainer(); +} + +void cVeVolume::Set(int current, int total, bool mute) { + this->current = current; + this->total = total; + this->mute = mute; + changed = true; +} + +bool cVeVolume::Parse(bool forced) { + if (!cViewElement::Parse(forced) || !changed) + return false; + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDVVolumeIT::volume, current); + tokenContainer->AddIntToken((int)eDVVolumeIT::maxvolume, total); + tokenContainer->AddIntToken((int)eDVVolumeIT::volpercent, (double)current *100 / (double)total); + tokenContainer->AddIntToken((int)eDVVolumeIT::mute, mute); + changed = false; + SetDirty(); + return true; +} \ No newline at end of file diff --git a/coreengine/viewelementscommon.h b/coreengine/viewelementscommon.h new file mode 100644 index 0000000..b373bc9 --- /dev/null +++ b/coreengine/viewelementscommon.h @@ -0,0 +1,110 @@ +#ifndef __VIEWELEMENTSCOMMON_H +#define __VIEWELEMENTSCOMMON_H + +#include +#include "viewelement.h" + +/****************************************************************** +* cVeDateTime +******************************************************************/ +class cVeDateTime : public cViewElement { +private: + int lastMinute; +public: + cVeDateTime(void); + virtual ~cVeDateTime(void); + void Close(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeTime +******************************************************************/ +class cVeTime : public cViewElement { +private: + int lastSecond; +public: + cVeTime(void); + virtual ~cVeTime(void); + void Close(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeMessage +******************************************************************/ +class cVeMessage : public cViewElement { +private: + bool changed; + eMessageType type; + char *text; +public: + cVeMessage(void); + virtual ~cVeMessage(void); + void SetTokenContainer(void); + void Set(eMessageType type, const char *text); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeDevices +******************************************************************/ +class cVeDevices : public cViewElement { +private: + bool light; + time_t lastRefresh; + vector devices; + bool initial; + int devicesIndex; + cMutex mutexDevices; + int numDevices; + int* lastSignalStrength; + int* lastSignalQuality; + bool* recDevices; + void Init(void); +public: + cVeDevices(void); + virtual ~cVeDevices(void); + void Close(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeCurrentWeather +******************************************************************/ +class cVeCurrentWeather : public cViewElement { +private: +public: + cVeCurrentWeather(void); + virtual ~cVeCurrentWeather(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeCustomTokens +******************************************************************/ +class cVeCustomTokens : public cViewElement { +private: +public: + cVeCustomTokens(void); + virtual ~cVeCustomTokens(void); + void Reset(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeVolume +******************************************************************/ +class cVeVolume : public cViewElement { +private: + int current; + int total; + bool mute; + bool changed; +public: + cVeVolume(void); + virtual ~cVeVolume(void); + void SetTokenContainer(void); + void Set(int current, int total, bool mute); + bool Parse(bool forced = false); +}; +#endif //__VIEWELEMENTSCOMMON_H \ No newline at end of file diff --git a/coreengine/viewelementsdisplaychannel.c b/coreengine/viewelementsdisplaychannel.c new file mode 100644 index 0000000..b523435 --- /dev/null +++ b/coreengine/viewelementsdisplaychannel.c @@ -0,0 +1,650 @@ +#include "viewelementsdisplaychannel.h" +#include "../config.h" +#include "../extensions/helpers.h" +#include "../extensions/timers.h" +#include "../services/scraper2vdr.h" + +/****************************************************************** +* cVeDcChannelInfo +******************************************************************/ +cVeDcChannelInfo::cVeDcChannelInfo(void) { +} + +cVeDcChannelInfo::~cVeDcChannelInfo(void) { +} + +void cVeDcChannelInfo::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{channelnumber}", (int)eDCChannelInfoST::channelnumber); + tokenContainer->DefineStringToken("{channelname}", (int)eDCChannelInfoST::channelname); + tokenContainer->DefineStringToken("{channelid}", (int)eDCChannelInfoST::channelid); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eDCChannelInfoIT::channellogoexists); + tokenContainer->DefineIntToken("{switching}", (int)eDCChannelInfoIT::switching); + InheritTokenContainer(); +} + +void cVeDcChannelInfo::Set(const cChannel *c, int number) { + cString channelNumber(""); + cString channelName(""); + cString channelId(""); + if (c) { + channelName = c->Name() ? c->Name() : ""; + channelId = c->GetChannelID().ToString(); + if (!c->GroupSep()) { + channelNumber = cString::sprintf("%d%s", c->Number(), number ? "-" : ""); + } + } else if (number) { + channelNumber = cString::sprintf("%d-", number); + } else { + channelName = ChannelString(NULL, 0); + } + + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDCChannelInfoST::channelnumber, *channelNumber); + tokenContainer->AddStringToken((int)eDCChannelInfoST::channelname, *channelName); + tokenContainer->AddStringToken((int)eDCChannelInfoST::channelid, *channelId); + bool logoExists = imgCache->LogoExists(*channelId); + tokenContainer->AddIntToken((int)eDCChannelInfoIT::channellogoexists, logoExists); + tokenContainer->AddIntToken((int)eDCChannelInfoIT::switching, (number > 0)?true:false); + + SetDirty(); +} + +/****************************************************************** +* cVeDcChannelGroup +******************************************************************/ +cVeDcChannelGroup::cVeDcChannelGroup(void) { +} + +cVeDcChannelGroup::~cVeDcChannelGroup(void) { +} + +void cVeDcChannelGroup::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{group}", (int)eDCChannelGroupST::group); + tokenContainer->DefineStringToken("{nextgroup}", (int)eDCChannelGroupST::nextgroup); + tokenContainer->DefineStringToken("{prevgroup}", (int)eDCChannelGroupST::prevgroup); + tokenContainer->DefineStringToken("{seppath}", (int)eDCChannelGroupST::seppath); + tokenContainer->DefineIntToken("{prevAvailable}", (int)eDCChannelGroupIT::prevAvailable); + tokenContainer->DefineIntToken("{nextAvailable}", (int)eDCChannelGroupIT::nextAvailable); + tokenContainer->DefineIntToken("{sepexists}", (int)eDCChannelGroupIT::sepexists); + InheritTokenContainer(); +} + +void cVeDcChannelGroup::Set(const cChannel *c) { + const char *sep = c->Name(); + bool sepExists = imgCache->SeparatorLogoExists(sep); + + const char *prevChannelSep = GetChannelSep(c, true); + const char *nextChannelSep = GetChannelSep(c, false); + + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDCChannelGroupST::group, sep); + tokenContainer->AddStringToken((int)eDCChannelGroupST::nextgroup, nextChannelSep ? nextChannelSep : ""); + tokenContainer->AddStringToken((int)eDCChannelGroupST::prevgroup, prevChannelSep ? prevChannelSep : ""); + tokenContainer->AddStringToken((int)eDCChannelGroupST::seppath, sepExists ? sep : ""); + tokenContainer->AddIntToken((int)eDCChannelGroupIT::prevAvailable, (prevChannelSep)?true:false); + tokenContainer->AddIntToken((int)eDCChannelGroupIT::nextAvailable, (nextChannelSep)?true:false); + tokenContainer->AddIntToken((int)eDCChannelGroupIT::sepexists, sepExists); + + SetDirty(); +} + +const char *cVeDcChannelGroup::GetChannelSep(const cChannel *c, bool prev) { + const cChannel *sep = prev ? Channels.Prev(c) : + Channels.Next(c); + for (; sep; (prev)?(sep = Channels.Prev(sep)):(sep = Channels.Next(sep))) { + if (sep->GroupSep()) { + return sep->Name(); + } + } + return NULL; +} +/****************************************************************** +* cVeDcEpgInfo +******************************************************************/ +cVeDcEpgInfo::cVeDcEpgInfo(void) { +} + +cVeDcEpgInfo::~cVeDcEpgInfo(void) { +} + +void cVeDcEpgInfo::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{currenttitle}", (int)eDCEpgInfoST::currenttitle); + tokenContainer->DefineStringToken("{currentsubtitle}", (int)eDCEpgInfoST::currentsubtitle); + tokenContainer->DefineStringToken("{currentstart}", (int)eDCEpgInfoST::currentstart); + tokenContainer->DefineStringToken("{currentstop}", (int)eDCEpgInfoST::currentstop); + tokenContainer->DefineStringToken("{nexttitle}", (int)eDCEpgInfoST::nexttitle); + tokenContainer->DefineStringToken("{nextsubtitle}", (int)eDCEpgInfoST::nextsubtitle); + tokenContainer->DefineStringToken("{nextstart}", (int)eDCEpgInfoST::nextstart); + tokenContainer->DefineStringToken("{nextstop}", (int)eDCEpgInfoST::nextstop); + tokenContainer->DefineIntToken("{currentduration}", (int)eDCEpgInfoIT::currentduration); + tokenContainer->DefineIntToken("{currentdurationhours}", (int)eDCEpgInfoIT::currentdurationhours); + tokenContainer->DefineIntToken("{currentdurationminutes}", (int)eDCEpgInfoIT::currentdurationminutes); + tokenContainer->DefineIntToken("{currentelapsed}", (int)eDCEpgInfoIT::currentelapsed); + tokenContainer->DefineIntToken("{currentremaining}", (int)eDCEpgInfoIT::currentremaining); + tokenContainer->DefineIntToken("{nextduration}", (int)eDCEpgInfoIT::nextduration); + tokenContainer->DefineIntToken("{nextdurationhours}", (int)eDCEpgInfoIT::nextdurationhours); + tokenContainer->DefineIntToken("{nextdurationminutes}", (int)eDCEpgInfoIT::nextdurationminutes); + tokenContainer->DefineIntToken("{nextrecording}", (int)eDCEpgInfoIT::nextrecording); + tokenContainer->DefineIntToken("{currentrecording}", (int)eDCEpgInfoIT::currentrecording); + tokenContainer->DefineIntToken("{hasVPS}", (int)eDCEpgInfoIT::hasVPS); + InheritTokenContainer(); +} + +void cVeDcEpgInfo::Set(const cEvent *p, const cEvent *f) { + tokenContainer->Clear(); + if (p) { + tokenContainer->AddStringToken((int)eDCEpgInfoST::currenttitle, p->Title()); + tokenContainer->AddStringToken((int)eDCEpgInfoST::currentsubtitle, p->ShortText()); + tokenContainer->AddStringToken((int)eDCEpgInfoST::currentstart, *p->GetTimeString()); + tokenContainer->AddStringToken((int)eDCEpgInfoST::currentstop, *p->GetEndTimeString()); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentduration, p->Duration() / 60); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentdurationhours, p->Duration() / 3600); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentdurationminutes, (p->Duration() / 60) % 60); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentelapsed, (int)round((time(NULL) - p->StartTime())/60)); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentremaining, (int)round((p->EndTime() - time(NULL))/60)); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::currentrecording, EventHasTimer(p)); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::hasVPS, (bool)p->Vps()); + } + if (f) { + tokenContainer->AddStringToken((int)eDCEpgInfoST::nexttitle, f->Title()); + tokenContainer->AddStringToken((int)eDCEpgInfoST::nextsubtitle, f->ShortText()); + tokenContainer->AddStringToken((int)eDCEpgInfoST::nextstart, *f->GetTimeString()); + tokenContainer->AddStringToken((int)eDCEpgInfoST::nextstop, *f->GetEndTimeString()); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextduration, f->Duration() / 60); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextdurationhours, f->Duration() / 3600); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::nextdurationminutes, (f->Duration() / 60) % 60); + tokenContainer->AddIntToken((int)eDCEpgInfoIT::hasVPS, (bool)f->Vps()); + } + SetDirty(); +} + +bool cVeDcEpgInfo::EventHasTimer(const cEvent *e) { + if (!e) return false; + cGlobalSortedTimers SortedTimers;// local and remote timers + bool hasTimer = e->HasTimer(); + for (int i = 0; i < SortedTimers.Size() && !hasTimer; i++) + if (const cTimer *Timer = SortedTimers[i]) + if (Timer->Channel()->GetChannelID() == e->ChannelID()) + if (const cEvent *timerEvent = Timer->Event()) + if (e->EventID() == timerEvent->EventID()) + hasTimer = true; + return hasTimer; +} + +/****************************************************************** +* cVeDcProgressBar +******************************************************************/ +cVeDcProgressBar::cVeDcProgressBar(void) { + currentLast = -1; + startTime = -1; + duration = -1; +} + +cVeDcProgressBar::~cVeDcProgressBar(void) { +} + +void cVeDcProgressBar::Close(void) { + currentLast = -1; + startTime = -1; + duration = -1; + cViewElement::Close(); +} + +void cVeDcProgressBar::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{start}", (int)eDCProgressBarST::start); + tokenContainer->DefineStringToken("{stop}", (int)eDCProgressBarST::stop); + tokenContainer->DefineIntToken("{duration}", (int)eDCProgressBarIT::duration); + tokenContainer->DefineIntToken("{elapsed}", (int)eDCProgressBarIT::elapsed); + tokenContainer->DefineIntToken("{remaining}", (int)eDCProgressBarIT::remaining); + tokenContainer->DefineIntToken("{permashift}", (int)eDCProgressBarIT::permashift); + tokenContainer->DefineIntToken("{livebuffer}", (int)eDCProgressBarIT::livebuffer); + InheritTokenContainer(); +} + +void cVeDcProgressBar::Set(const cEvent *p) { + if (!p) { + startTime = -1; + duration = -1; + return; + } + startTime = p->StartTime(); + duration = p->Duration(); + + int current = 0; + time_t t = time(NULL); + if (t > startTime) + current = t - startTime; + + currentLast = current; + SetDirty(); + + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDCProgressBarST::start, *p->GetTimeString()); + tokenContainer->AddStringToken((int)eDCProgressBarST::stop, *p->GetEndTimeString()); + tokenContainer->AddIntToken((int)eDCProgressBarIT::duration, duration); + tokenContainer->AddIntToken((int)eDCProgressBarIT::elapsed, current); + tokenContainer->AddIntToken((int)eDCProgressBarIT::remaining, duration - current); + int liveBuffer = GetLiveBuffer(); + if (liveBuffer >= 0) { + tokenContainer->AddIntToken((int)eDCProgressBarIT::permashift, 1); + tokenContainer->AddIntToken((int)eDCProgressBarIT::livebuffer, liveBuffer); + } else { + tokenContainer->AddIntToken((int)eDCProgressBarIT::permashift, 0); + } +} + +bool cVeDcProgressBar::Parse(bool force) { + if (!cViewElement::Parse(force)) + return false; + int current = 0; + time_t t = time(NULL); + if (t > startTime) + current = t - startTime; + if (!(current > currentLast + 3) && !force && !Dirty()) + return false; + SetDirty(); + if (duration <= 0) { + tokenContainer->AddIntToken((int)eDCProgressBarIT::duration, 0); + tokenContainer->AddIntToken((int)eDCProgressBarIT::elapsed, 0); + tokenContainer->AddIntToken((int)eDCProgressBarIT::remaining, 0); + } else { + tokenContainer->AddIntToken((int)eDCProgressBarIT::duration, duration); + tokenContainer->AddIntToken((int)eDCProgressBarIT::elapsed, current); + tokenContainer->AddIntToken((int)eDCProgressBarIT::remaining, duration - current); + int liveBuffer = GetLiveBuffer(); + if (liveBuffer >= 0) { + tokenContainer->AddIntToken((int)eDCProgressBarIT::permashift, 1); + tokenContainer->AddIntToken((int)eDCProgressBarIT::livebuffer, liveBuffer); + } else { + tokenContainer->AddIntToken((int)eDCProgressBarIT::permashift, 0); + } + } + return true; +} + +int cVeDcProgressBar::GetLiveBuffer(void) { + static cPlugin *pPermashift = cPluginManager::GetPlugin("permashift"); + if (!pPermashift) { + return -1; + } + int buffer = 0; + if (pPermashift->Service("Permashift-GetUsedBufferSecs-v1", &buffer)) { + return buffer; + } + return -1; +} +/****************************************************************** +* cVeDcStatusInfo +******************************************************************/ +cVeDcStatusInfo::cVeDcStatusInfo(void) { +} + +cVeDcStatusInfo::~cVeDcStatusInfo(void) { +} + +void cVeDcStatusInfo::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{isRadio}", (int)eDCStatusInfoIT::isRadio); + tokenContainer->DefineIntToken("{hasVT}", (int)eDCStatusInfoIT::hasVT); + tokenContainer->DefineIntToken("{isStereo}", (int)eDCStatusInfoIT::isStereo); + tokenContainer->DefineIntToken("{isDolby}", (int)eDCStatusInfoIT::isDolby); + tokenContainer->DefineIntToken("{isEncrypted}", (int)eDCStatusInfoIT::isEncrypted); + tokenContainer->DefineIntToken("{isRecording}", (int)eDCStatusInfoIT::isRecording); + tokenContainer->DefineIntToken("{newmails}", (int)eDCStatusInfoIT::newmails); + InheritTokenContainer(); +} + +void cVeDcStatusInfo::Set(const cChannel *c) { + bool isRadio = !c->Vpid() && c->Apid(0); + bool hasVT = c->Vpid() && c->Tpid(); + bool isStereo = c->Apid(0); + bool isDolby = c->Dpid(0); + bool isEncrypted = c->Ca(); + bool isRecording = cRecordControls::Active(); + cGlobalSortedTimers SortedTimers;// local and remote timers + for (int i = 0; i < SortedTimers.Size() && !isRecording; i++) + if (const cTimer *Timer = SortedTimers[i]) + if (Timer->Recording()) + isRecording = true; + + tokenContainer->AddIntToken((int)eDCStatusInfoIT::isRadio, isRadio); + tokenContainer->AddIntToken((int)eDCStatusInfoIT::hasVT, hasVT); + tokenContainer->AddIntToken((int)eDCStatusInfoIT::isStereo, isStereo); + tokenContainer->AddIntToken((int)eDCStatusInfoIT::isDolby, isDolby); + tokenContainer->AddIntToken((int)eDCStatusInfoIT::isEncrypted, isEncrypted); + tokenContainer->AddIntToken((int)eDCStatusInfoIT::isRecording, isRecording); + tokenContainer->AddIntToken((int)eDCStatusInfoIT::newmails, CheckMails()); + SetDirty(); +} + +bool cVeDcStatusInfo::CheckMails(void) { + static cPlugin *pMailbox = cPluginManager::GetPlugin("mailbox"); + if (!pMailbox) { + return false; + } + bool newMail = false; + if (pMailbox->Service("MailBox-HasNewMail-1.0", &newMail)) { + return newMail; + } + return false; +} + +/****************************************************************** +* cVeDcAudioInfo +******************************************************************/ +cVeDcAudioInfo::cVeDcAudioInfo(void) { + lastNumAudioTracks = -1; + lastAudioChannel = -1; + lastTracDesc = NULL; + lastTrackLang = NULL; +} + +cVeDcAudioInfo::~cVeDcAudioInfo(void) { +} + +void cVeDcAudioInfo::Close(void) { + lastNumAudioTracks = -1; + lastAudioChannel = -1; + free(lastTracDesc); + lastTracDesc = NULL; + free(lastTrackLang); + lastTrackLang = NULL; + cViewElement::Close(); +} + +void cVeDcAudioInfo::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{trackdesc}", (int)eDCAudioInfoST::trackdesc); + tokenContainer->DefineStringToken("{tracklang}", (int)eDCAudioInfoST::tracklang); + tokenContainer->DefineIntToken("{numaudiotracks}", (int)eDCAudioInfoIT::numaudiotracks); + tokenContainer->DefineIntToken("{audiochannel}", (int)eDCAudioInfoIT::audiochannel); + InheritTokenContainer(); +} + +bool cVeDcAudioInfo::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + int numAudioTracks = 0; + int audioChannel = -1; + const char *trackDescription = ""; + const char *trackLanguage = ""; + + cDevice *device = cDevice::PrimaryDevice(); + if (device) { + numAudioTracks = device->NumAudioTracks(); + audioChannel = device->GetAudioChannel(); + if (numAudioTracks > 0) { + const tTrackId *track = device->GetTrack(device->GetCurrentAudioTrack()); + if (track) { + trackDescription = track->description ? track->description : ""; + trackLanguage = track->language ? track->language : ""; + } + } + } + if ( !Dirty() && !forced && lastNumAudioTracks == numAudioTracks + && lastAudioChannel == audioChannel + && lastTracDesc && !strcmp(trackDescription, lastTracDesc) + && lastTrackLang && !strcmp(trackLanguage, lastTrackLang)) { + return false; + } + + lastNumAudioTracks = numAudioTracks; + lastAudioChannel = audioChannel; + free(lastTracDesc); + lastTracDesc = strdup(trackDescription); + free(lastTrackLang); + lastTrackLang = strdup(trackLanguage); + SetDirty(); + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDCAudioInfoIT::numaudiotracks, numAudioTracks); + tokenContainer->AddIntToken((int)eDCAudioInfoIT::audiochannel, audioChannel); + tokenContainer->AddStringToken((int)eDCAudioInfoST::trackdesc, trackDescription); + tokenContainer->AddStringToken((int)eDCAudioInfoST::tracklang, trackLanguage); + return true; +} +/****************************************************************** +* cVeDcScreenResolution +******************************************************************/ +cVeDcScreenResolution::cVeDcScreenResolution(void) { + lastScreenWidth = -1; + lastScreenHeight = -1; +} + +cVeDcScreenResolution::~cVeDcScreenResolution(void) { +} + +void cVeDcScreenResolution::Close(void) { + lastScreenWidth = -1; + lastScreenHeight = -1; + cViewElement::Close(); +} + +void cVeDcScreenResolution::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{resolution}", (int)eDCScreenResolutionST::resolution); + tokenContainer->DefineStringToken("{aspect}", (int)eDCScreenResolutionST::aspect); + tokenContainer->DefineIntToken("{screenwidth}", (int)eDCScreenResolutionIT::screenwidth); + tokenContainer->DefineIntToken("{screenheight}", (int)eDCScreenResolutionIT::screenheight); + tokenContainer->DefineIntToken("{isHD}", (int)eDCScreenResolutionIT::isHD); + tokenContainer->DefineIntToken("{isWideScreen}", (int)eDCScreenResolutionIT::isWideScreen); + InheritTokenContainer(); +} + +bool cVeDcScreenResolution::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + int screenWidth = 0; + int screenHeight = 0; + double aspect = 0; + + cDevice::PrimaryDevice()->GetVideoSize(screenWidth, screenHeight, aspect); + + if ((lastScreenWidth == screenWidth) && (lastScreenHeight == screenHeight)) + return false; + + if ((screenWidth == 0) && (screenHeight == 0)) + return false; + + lastScreenWidth = screenWidth; + lastScreenHeight = screenHeight; + SetDirty(); + + bool isHD = false; + string resName = GetScreenResolutionString(screenWidth, screenHeight, &isHD); + + bool isWideScreen = false; + string aspectName = GetScreenAspectString(aspect, &isWideScreen); + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDCScreenResolutionIT::screenwidth, screenWidth); + tokenContainer->AddIntToken((int)eDCScreenResolutionIT::screenheight, screenHeight); + tokenContainer->AddIntToken((int)eDCScreenResolutionIT::isHD, isHD); + tokenContainer->AddIntToken((int)eDCScreenResolutionIT::isWideScreen, isWideScreen); + tokenContainer->AddStringToken((int)eDCScreenResolutionST::resolution, resName.c_str()); + tokenContainer->AddStringToken((int)eDCScreenResolutionST::aspect, aspectName.c_str()); + return true; +} +/****************************************************************** +* cVeDcSignalQuality +******************************************************************/ +cVeDcSignalQuality::cVeDcSignalQuality(void) { + lastSignalDisplay = -1; + lastSignalStrength = -1; + lastSignalQuality = -1; +} + +cVeDcSignalQuality::~cVeDcSignalQuality(void) { +} + +void cVeDcSignalQuality::Close(void) { + lastSignalDisplay = -1; + lastSignalStrength = -1; + lastSignalQuality = -1; + cViewElement::Close(); +} + +void cVeDcSignalQuality::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{signalstrength}", (int)eDCSignalQualityIT::signalstrength); + tokenContainer->DefineIntToken("{signalquality}", (int)eDCSignalQualityIT::signalquality); + InheritTokenContainer(); +} + +bool cVeDcSignalQuality::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + time_t now = time(NULL); + if (now == lastSignalDisplay) + return false; + lastSignalDisplay = now; + + int signalStrength = cDevice::ActualDevice()->SignalStrength(); + int signalQuality = cDevice::ActualDevice()->SignalQuality(); + + if (signalStrength < 0) signalStrength = 0; + if (signalQuality < 0) signalQuality = 0; + + if (signalStrength == 0 && signalQuality==0) + return false; + + if ((lastSignalStrength == signalStrength) && (lastSignalQuality == signalQuality)) + return false; + SetDirty(); + lastSignalStrength = signalStrength; + lastSignalQuality = signalQuality; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDCSignalQualityIT::signalstrength, signalStrength); + tokenContainer->AddIntToken((int)eDCSignalQualityIT::signalquality, signalQuality); + return true; +} + +/****************************************************************** +* cVeDcScraperContent +******************************************************************/ +cVeDcScraperContent::cVeDcScraperContent(void) { +} + +cVeDcScraperContent::~cVeDcScraperContent(void) { +} + +void cVeDcScraperContent::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperPosterBannerST::posterpath); + tokenContainer->DefineStringToken("{bannerpath}", (int)eScraperPosterBannerST::bannerpath); + tokenContainer->DefineStringToken("{mediapath}", (int)eScraperPosterBannerST::mediapath); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperPosterBannerIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperPosterBannerIT::posterheight); + tokenContainer->DefineIntToken("{hasPoster}", (int)eScraperPosterBannerIT::hasposter); + tokenContainer->DefineIntToken("{bannerwidth}", (int)eScraperPosterBannerIT::bannerwidth); + tokenContainer->DefineIntToken("{bannerheight}", (int)eScraperPosterBannerIT::bannerheight); + tokenContainer->DefineIntToken("{hasBanner}", (int)eScraperPosterBannerIT::hasbanner); + tokenContainer->DefineIntToken("{mediawidth}", (int)eScraperPosterBannerIT::mediawidth); + tokenContainer->DefineIntToken("{mediaheight}", (int)eScraperPosterBannerIT::mediaheight); + tokenContainer->DefineIntToken("{isbanner}", (int)eScraperPosterBannerIT::isbanner); + InheritTokenContainer(); +} + +void cVeDcScraperContent::Set(const cEvent *e) { + tokenContainer->Clear(); + SetPosterBanner(tokenContainer, e, NULL); + SetDirty(); +} + +/****************************************************************** +* cVeDcScreenResolution +******************************************************************/ +cVeDcEcmInfo::cVeDcEcmInfo(void) { + channelSid = -1; + lastEcmInfo.hops = -1; + lastEcmInfo.ecmtime = -1; + lastEcmInfo.caid = -1; + lastEcmInfo.pid = -1; + lastEcmInfo.prid = -1; +} + +cVeDcEcmInfo::~cVeDcEcmInfo(void) { +} + +void cVeDcEcmInfo::Close(void) { + channelSid = -1; + lastEcmInfo.hops = -1; + lastEcmInfo.ecmtime = -1; + lastEcmInfo.caid = -1; + lastEcmInfo.pid = -1; + lastEcmInfo.prid = -1; + cViewElement::Close(); +} + +void cVeDcEcmInfo::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{cardsystem}", (int)eDCEcmInfoST::cardsystem); + tokenContainer->DefineStringToken("{reader}", (int)eDCEcmInfoST::reader); + tokenContainer->DefineStringToken("{from}", (int)eDCEcmInfoST::from); + tokenContainer->DefineStringToken("{protocol}", (int)eDCEcmInfoST::protocol); + tokenContainer->DefineIntToken("{caid}", (int)eDCEcmInfoIT::caid); + tokenContainer->DefineIntToken("{pid}", (int)eDCEcmInfoIT::pid); + tokenContainer->DefineIntToken("{prid}", (int)eDCEcmInfoIT::prid); + tokenContainer->DefineIntToken("{ecmtime}", (int)eDCEcmInfoIT::ecmtime); + tokenContainer->DefineIntToken("{hops}", (int)eDCEcmInfoIT::hops); + InheritTokenContainer(); +} + +void cVeDcEcmInfo::Set(const cChannel *c) { + channelSid = c->Sid(); +} + +bool cVeDcEcmInfo::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + static cPlugin *pDVBApi = cPluginManager::GetPlugin("dvbapi"); + if (!pDVBApi) + return false; + if (channelSid < 0) + return false; + + sDVBAPIEcmInfo ecmInfo; + ecmInfo.sid = channelSid; + + if (!pDVBApi->Service("GetEcmInfo", &ecmInfo)) { + return false; + } + + if (ecmInfo.hops < 0 || ecmInfo.ecmtime <= 0 || ecmInfo.ecmtime > 100000) + return false; + if (CompareECMInfos(&ecmInfo)) + return false; + lastEcmInfo = ecmInfo; + SetDirty(); + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDCEcmInfoIT::caid, ecmInfo.caid); + tokenContainer->AddIntToken((int)eDCEcmInfoIT::pid, ecmInfo.pid); + tokenContainer->AddIntToken((int)eDCEcmInfoIT::prid, ecmInfo.prid); + tokenContainer->AddIntToken((int)eDCEcmInfoIT::ecmtime, ecmInfo.ecmtime); + tokenContainer->AddIntToken((int)eDCEcmInfoIT::hops, ecmInfo.hops); + tokenContainer->AddStringToken((int)eDCEcmInfoST::cardsystem, *ecmInfo.cardsystem); + tokenContainer->AddStringToken((int)eDCEcmInfoST::reader, *ecmInfo.reader); + tokenContainer->AddStringToken((int)eDCEcmInfoST::from, *ecmInfo.from); + tokenContainer->AddStringToken((int)eDCEcmInfoST::protocol, *ecmInfo.protocol); + return true; +} + +bool cVeDcEcmInfo::CompareECMInfos(sDVBAPIEcmInfo *ecmInfo) { + if (ecmInfo->caid != lastEcmInfo.caid) + return false; + if (ecmInfo->pid != lastEcmInfo.pid) + return false; + if (ecmInfo->prid != lastEcmInfo.prid) + return false; + if (ecmInfo->ecmtime != lastEcmInfo.ecmtime) + return false; + if (ecmInfo->hops != lastEcmInfo.hops) + return false; + return true; +} diff --git a/coreengine/viewelementsdisplaychannel.h b/coreengine/viewelementsdisplaychannel.h new file mode 100644 index 0000000..b4a2fbd --- /dev/null +++ b/coreengine/viewelementsdisplaychannel.h @@ -0,0 +1,145 @@ +#ifndef __VIEWELEMENTSDC_H +#define __VIEWELEMENTSDC_H + +#include "viewelement.h" +#include "../extensions/scrapmanager.h" +#include "../services/dvbapi.h" + +/****************************************************************** +* cVeDcChannelInfo +******************************************************************/ +class cVeDcChannelInfo : public cViewElement { +private: +public: + cVeDcChannelInfo(void); + virtual ~cVeDcChannelInfo(void); + void SetTokenContainer(void); + void Set(const cChannel *c, int number); +}; +/****************************************************************** +* cVeDcChannelGroup +******************************************************************/ +class cVeDcChannelGroup : public cViewElement { +private: + const char *GetChannelSep(const cChannel *c, bool prev); +public: + cVeDcChannelGroup(void); + virtual ~cVeDcChannelGroup(void); + void SetTokenContainer(void); + void Set(const cChannel *c); +}; +/****************************************************************** +* cVeDcEpgInfo +******************************************************************/ +class cVeDcEpgInfo : public cViewElement { +private: + bool EventHasTimer(const cEvent *e); +public: + cVeDcEpgInfo(void); + virtual ~cVeDcEpgInfo(void); + void SetTokenContainer(void); + void Set(const cEvent *p, const cEvent *f); +}; +/****************************************************************** +* cVeDcProgressBar +******************************************************************/ +class cVeDcProgressBar : public cViewElement { +private: + int currentLast; + int startTime; + int duration; + int GetLiveBuffer(void); +public: + cVeDcProgressBar(void); + virtual ~cVeDcProgressBar(void); + void Close(void); + void SetTokenContainer(void); + void Set(const cEvent *p); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeDcStatusInfo +******************************************************************/ +class cVeDcStatusInfo : public cViewElement { +private: + bool CheckMails(void); +public: + cVeDcStatusInfo(void); + virtual ~cVeDcStatusInfo(void); + void SetTokenContainer(void); + void Set(const cChannel *c); +}; +/****************************************************************** +* cVeDcAudioInfo +******************************************************************/ +class cVeDcAudioInfo : public cViewElement { +private: + int lastNumAudioTracks; + int lastAudioChannel; + char *lastTracDesc; + char *lastTrackLang; +public: + cVeDcAudioInfo(void); + virtual ~cVeDcAudioInfo(void); + void Close(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeDcScreenResolution +******************************************************************/ +class cVeDcScreenResolution : public cViewElement { +private: + int lastScreenWidth; + int lastScreenHeight; +public: + cVeDcScreenResolution(void); + virtual ~cVeDcScreenResolution(void); + void Close(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeDcSignalQuality +******************************************************************/ +class cVeDcSignalQuality : public cViewElement { +private: + int lastSignalDisplay; + int lastSignalStrength; + int lastSignalQuality; +public: + cVeDcSignalQuality(void); + virtual ~cVeDcSignalQuality(void); + void Close(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; +/****************************************************************** +* cVeDcScraperContent +******************************************************************/ +class cVeDcScraperContent : public cViewElement, public cScrapManager { +private: +public: + cVeDcScraperContent(void); + virtual ~cVeDcScraperContent(void); + void SetTokenContainer(void); + void Set(const cEvent *e); +}; +/****************************************************************** +* cVeDcEcmInfo +******************************************************************/ +class cVeDcEcmInfo : public cViewElement { +private: + int channelSid; + sDVBAPIEcmInfo lastEcmInfo; + bool CompareECMInfos(sDVBAPIEcmInfo *ecmInfo); +public: + cVeDcEcmInfo(void); + virtual ~cVeDcEcmInfo(void); + void Close(void); + void SetTokenContainer(void); + void Set(const cChannel *c); + bool Parse(bool forced = false); +}; + +#endif //__VIEWELEMENTSDC_H \ No newline at end of file diff --git a/coreengine/viewelementsdisplaymenu.c b/coreengine/viewelementsdisplaymenu.c new file mode 100644 index 0000000..52e2996 --- /dev/null +++ b/coreengine/viewelementsdisplaymenu.c @@ -0,0 +1,1232 @@ +#define __STL_CONFIG_H +#include "viewelementsdisplaymenu.h" +#include "../config.h" +#include +#include "../extensions/timers.h" +#include "../extensions/helpers.h" +#include +#include +#include + +/****************************************************************** +* cVeDmHeader +******************************************************************/ +cVeDmHeader::cVeDmHeader(void) { + title = NULL; + channelName = NULL; + channelNumber = 0; + channelId = NULL; + epgSearchFav = false; +} + +cVeDmHeader::~cVeDmHeader(void) { + free(title); + free(channelName); + free(channelId); +} + +void cVeDmHeader::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{title}", (int)eDMHeaderST::title); + tokenContainer->DefineStringToken("{vdrversion}", (int)eDMHeaderST::vdrversion); + tokenContainer->DefineStringToken("{icon}", (int)eDMHeaderST::icon); + tokenContainer->DefineStringToken("{freetime}", (int)eDMHeaderST::freetime); + tokenContainer->DefineStringToken("{vdrusagestring}", (int)eDMHeaderST::vdrusagestring); + tokenContainer->DefineStringToken("{channelname}", (int)eDMHeaderST::channelname); + tokenContainer->DefineStringToken("{channelid}", (int)eDMHeaderST::channelid); + tokenContainer->DefineIntToken("{hasicon}", (int)eDMHeaderIT::hasicon); + tokenContainer->DefineIntToken("{freepercent}", (int)eDMHeaderIT::freepercent); + tokenContainer->DefineIntToken("{usedpercent}", (int)eDMHeaderIT::usedpercent); + tokenContainer->DefineIntToken("{freegb}", (int)eDMHeaderIT::freegb); + tokenContainer->DefineIntToken("{discalert}", (int)eDMHeaderIT::discalert); + tokenContainer->DefineIntToken("{channelnumber}", (int)eDMHeaderIT::channelnumber); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eDMHeaderIT::channellogoexists); + tokenContainer->DefineIntToken("{whatson}", (int)eDMHeaderIT::whatson); + tokenContainer->DefineIntToken("{whatsonnow}", (int)eDMHeaderIT::whatsonnow); + tokenContainer->DefineIntToken("{whatsonnext}", (int)eDMHeaderIT::whatsonnext); + tokenContainer->DefineIntToken("{whatsonfavorites}", (int)eDMHeaderIT::whatsonfavorites); + InheritTokenContainer(); +} + +void cVeDmHeader::SetTitle(const char *title) { + this->title = strdup(title); + free(channelName); + channelName = NULL; + channelNumber = 0; + free(channelId); + channelId = NULL; +} + +void cVeDmHeader::SetChannel(const cChannel *channel) { + channelNumber = channel->Number(); + free(channelName); + free(channelId); + channelName = strdup(channel->Name()); + channelId = strdup(*(channel->GetChannelID().ToString())); +} + +void cVeDmHeader::Set(eMenuCategory menuCat) { + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDMHeaderST::title, title); + tokenContainer->AddStringToken((int)eDMHeaderST::vdrversion, VDRVERSION); + + tokenContainer->AddIntToken((int)eDMHeaderIT::whatson, (menuCat == mcSchedule && !epgSearchFav) ? true : false); + tokenContainer->AddIntToken((int)eDMHeaderIT::whatsonnow, menuCat == mcScheduleNow ? true : false); + tokenContainer->AddIntToken((int)eDMHeaderIT::whatsonnext, menuCat == mcScheduleNext ? true : false); + tokenContainer->AddIntToken((int)eDMHeaderIT::whatsonfavorites, epgSearchFav); + + //check for standard menu entries + bool hasIcon = false; + + string icon = imgCache->GetIconName(title, menuCat); + if (imgCache->MenuIconExists(icon)) + hasIcon = true; + + tokenContainer->AddStringToken((int)eDMHeaderST::icon, icon.c_str()); + tokenContainer->AddIntToken((int)eDMHeaderIT::hasicon, hasIcon); + + //Disc Usage + tokenContainer->AddStringToken((int)eDMHeaderST::vdrusagestring, *cVideoDiskUsage::String()); + tokenContainer->AddStringToken((int)eDMHeaderST::freetime, *cString::sprintf("%02d:%02d", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60)); + int discUsage = cVideoDiskUsage::UsedPercent(); + bool discAlert = (discUsage > 95) ? true : false; + int freeGB = cVideoDiskUsage::FreeMB() / 1024; + tokenContainer->AddIntToken((int)eDMHeaderIT::usedpercent, discUsage); + tokenContainer->AddIntToken((int)eDMHeaderIT::freepercent, 100-discUsage); + tokenContainer->AddIntToken((int)eDMHeaderIT::discalert, discAlert); + tokenContainer->AddIntToken((int)eDMHeaderIT::freegb, freeGB); + + if (channelName && channelId) { + tokenContainer->AddStringToken((int)eDMHeaderST::channelname, channelName); + tokenContainer->AddStringToken((int)eDMHeaderST::channelid, channelId); + tokenContainer->AddIntToken((int)eDMHeaderIT::channelnumber, channelNumber); + tokenContainer->AddIntToken((int)eDMHeaderIT::channellogoexists, imgCache->LogoExists(channelId)); + } + SetDirty(); +} + +/****************************************************************** +* cVeDmSortmode +******************************************************************/ +cVeDmSortmode::cVeDmSortmode(void) { + sortMode = msmUnknown; + lastSortMode = msmUnknown; +} + +cVeDmSortmode::~cVeDmSortmode(void) { +} + +void cVeDmSortmode::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{sortnumber}", (int)eDMSortmodeIT::sortnumber); + tokenContainer->DefineIntToken("{sortname}", (int)eDMSortmodeIT::sortname); + tokenContainer->DefineIntToken("{sorttime}", (int)eDMSortmodeIT::sorttime); + tokenContainer->DefineIntToken("{sortprovider}", (int)eDMSortmodeIT::sortprovider); + InheritTokenContainer(); +} + +void cVeDmSortmode::Set(eMenuSortMode sortMode) { + this->sortMode = sortMode; +} + +bool cVeDmSortmode::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + + if (sortMode == lastSortMode) { + return false; + } + lastSortMode = sortMode; + + bool sortNumber = (sortMode == msmNumber) ? true : false; + bool sortName = (sortMode == msmName) ? true : false; + bool sortTime = (sortMode == msmTime) ? true : false; + bool sortProvider = (sortMode == msmProvider) ? true : false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDMSortmodeIT::sortnumber, sortNumber); + tokenContainer->AddIntToken((int)eDMSortmodeIT::sortname, sortName); + tokenContainer->AddIntToken((int)eDMSortmodeIT::sorttime, sortTime); + tokenContainer->AddIntToken((int)eDMSortmodeIT::sortprovider, sortProvider); + SetDirty(); + return true; +} +/****************************************************************** +* cVeDmColorbuttons +******************************************************************/ +cVeDmColorbuttons::cVeDmColorbuttons(void) { + changed = false; + red = NULL; + green = NULL; + yellow = NULL; + blue = NULL; +} + +cVeDmColorbuttons::~cVeDmColorbuttons(void) { + free(red); + free(yellow); + free(green); + free(blue); +} + +void cVeDmColorbuttons::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{red}", (int)eDMColorbuttonsST::red); + tokenContainer->DefineStringToken("{green}", (int)eDMColorbuttonsST::green); + tokenContainer->DefineStringToken("{yellow}", (int)eDMColorbuttonsST::yellow); + tokenContainer->DefineStringToken("{blue}", (int)eDMColorbuttonsST::blue); + tokenContainer->DefineIntToken("{red1}", (int)eDMColorbuttonsIT::red1); + tokenContainer->DefineIntToken("{red2}", (int)eDMColorbuttonsIT::red2); + tokenContainer->DefineIntToken("{red3}", (int)eDMColorbuttonsIT::red3); + tokenContainer->DefineIntToken("{red4}", (int)eDMColorbuttonsIT::red4); + tokenContainer->DefineIntToken("{green1}", (int)eDMColorbuttonsIT::green1); + tokenContainer->DefineIntToken("{green2}", (int)eDMColorbuttonsIT::green2); + tokenContainer->DefineIntToken("{green3}", (int)eDMColorbuttonsIT::green3); + tokenContainer->DefineIntToken("{green4}", (int)eDMColorbuttonsIT::green4); + tokenContainer->DefineIntToken("{yellow1}", (int)eDMColorbuttonsIT::yellow1); + tokenContainer->DefineIntToken("{yellow2}", (int)eDMColorbuttonsIT::yellow2); + tokenContainer->DefineIntToken("{yellow3}", (int)eDMColorbuttonsIT::yellow3); + tokenContainer->DefineIntToken("{yellow4}", (int)eDMColorbuttonsIT::yellow4); + tokenContainer->DefineIntToken("{blue1}", (int)eDMColorbuttonsIT::blue1); + tokenContainer->DefineIntToken("{blue2}", (int)eDMColorbuttonsIT::blue2); + tokenContainer->DefineIntToken("{blue3}", (int)eDMColorbuttonsIT::blue3); + tokenContainer->DefineIntToken("{blue4}", (int)eDMColorbuttonsIT::blue4); + InheritTokenContainer(); +} + +void cVeDmColorbuttons::SetButtons(const char *red, const char *green, const char *yellow, const char *blue) { + free(this->red); + free(this->yellow); + free(this->green); + free(this->blue); + this->red = NULL; + this->green = NULL; + this->yellow = NULL; + this->blue = NULL; + if (red) this->red = strdup(red); + if (green) this->green = strdup(green); + if (yellow) this->yellow = strdup(yellow); + if (blue) this->blue = strdup(blue); + changed = true; +} + +bool cVeDmColorbuttons::Parse(bool forced) { + if (!cViewElement::Parse(forced) || !changed) + return false; + + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDMColorbuttonsST::red, red); + tokenContainer->AddStringToken((int)eDMColorbuttonsST::green, green); + tokenContainer->AddStringToken((int)eDMColorbuttonsST::yellow, yellow); + tokenContainer->AddStringToken((int)eDMColorbuttonsST::blue, blue); + + int colorKeys[4] = { Setup.ColorKey0, Setup.ColorKey1, Setup.ColorKey2, Setup.ColorKey3 }; + + for (int button = 1; button < 5; button++) { + bool isRed = false; + bool isGreen = false; + bool isYellow = false; + bool isBlue = false; + switch (colorKeys[button-1]) { + case 0: + isRed = true; + break; + case 1: + isGreen = true; + break; + case 2: + isYellow = true; + break; + case 3: + isBlue = true; + break; + default: + break; + } + int tokRed = button - 1; + int tokGreen = 3 + button; + int tokYellow = 7 + button; + int tokBlue = 11 + button; + tokenContainer->AddIntToken(tokRed, isRed); + tokenContainer->AddIntToken(tokGreen, isGreen); + tokenContainer->AddIntToken(tokYellow, isYellow); + tokenContainer->AddIntToken(tokBlue, isBlue); + } + SetDirty(); + changed = false; + return true; +} + +/****************************************************************** +* cVeDmScrollbar +******************************************************************/ +cVeDmScrollbar::cVeDmScrollbar(void) { +} + +cVeDmScrollbar::~cVeDmScrollbar(void) { +} + +void cVeDmScrollbar::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{height}", (int)eDMScrollbarIT::height); + tokenContainer->DefineIntToken("{offset}", (int)eDMScrollbarIT::offset); + tokenContainer->DefineIntToken("{hasprev}", (int)eDMScrollbarIT::hasprev); + tokenContainer->DefineIntToken("{hasnext}", (int)eDMScrollbarIT::hasnext); + InheritTokenContainer(); +} + +void cVeDmScrollbar::SetList(int numDisplayed, int offset, int numMax) { + if (numDisplayed < 1) + return; + + int barHeight = 0; + if (numDisplayed < numMax) + barHeight = 1000; + else + barHeight = (double)numMax * 1000 / (double)numDisplayed; + + int barOffset = (double)offset * 1000 / (double)numDisplayed; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDMScrollbarIT::height, barHeight); + tokenContainer->AddIntToken((int)eDMScrollbarIT::offset, barOffset); + tokenContainer->AddIntToken((int)eDMScrollbarIT::hasprev, (offset == 0) ? 0 : 1); + tokenContainer->AddIntToken((int)eDMScrollbarIT::hasnext, (offset + numMax == numDisplayed) ? 0 : 1); + SetDirty(); +} + +void cVeDmScrollbar::SetDetail(int height, int offset, bool end) { + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDMScrollbarIT::height, height); + tokenContainer->AddIntToken((int)eDMScrollbarIT::offset, offset); + tokenContainer->AddIntToken((int)eDMScrollbarIT::hasprev, (offset == 0) ? 0 : 1); + tokenContainer->AddIntToken((int)eDMScrollbarIT::hasnext, (end) ? 0 : 1); + SetDirty(); +} + +/****************************************************************** +* cVeDmTimers +******************************************************************/ +cVeDmTimers::cVeDmTimers(void) { + timerIndex = -1; +} + +cVeDmTimers::~cVeDmTimers(void) { +} + +void cVeDmTimers::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineLoopToken("{timers[title]}", (int)eDMTimersLT::title); + tokenContainer->DefineLoopToken("{timers[datetime]}", (int)eDMTimersLT::datetime); + tokenContainer->DefineLoopToken("{timers[recording]}", (int)eDMTimersLT::recording); + tokenContainer->DefineLoopToken("{timers[channelname]}", (int)eDMTimersLT::channelname); + tokenContainer->DefineLoopToken("{timers[channelnumber]}", (int)eDMTimersLT::channelnumber); + tokenContainer->DefineLoopToken("{timers[channelid]}", (int)eDMTimersLT::channelid); + tokenContainer->DefineLoopToken("{timers[channellogoexists]}", (int)eDMTimersLT::channellogoexists); + tokenContainer->DefineLoopToken("{timers[isremotetimer]}", (int)eDMTimersLT::isremotetimer); + tokenContainer->DefineIntToken("{numtimers}", (int)eDMTimersIT::numtimers); + tokenContainer->DefineIntToken("{numtimerconflicts}", (int)eDMTimersIT::numtimerconflicts); + tokenContainer->DefineIntToken("{timer1exists}", (int)eDMTimersIT::timer1exists); + tokenContainer->DefineIntToken("{timer2exists}", (int)eDMTimersIT::timer2exists); + tokenContainer->DefineIntToken("{timer3exists}", (int)eDMTimersIT::timer3exists); + tokenContainer->DefineIntToken("{timer4exists}", (int)eDMTimersIT::timer4exists); + tokenContainer->DefineIntToken("{timer5exists}", (int)eDMTimersIT::timer5exists); + tokenContainer->DefineIntToken("{timer6exists}", (int)eDMTimersIT::timer6exists); + tokenContainer->DefineIntToken("{timer7exists}", (int)eDMTimersIT::timer7exists); + tokenContainer->DefineIntToken("{timer8exists}", (int)eDMTimersIT::timer8exists); + tokenContainer->DefineIntToken("{timer9exists}", (int)eDMTimersIT::timer9exists); + tokenContainer->DefineIntToken("{timer10exists}", (int)eDMTimersIT::timer10exists); + tokenContainer->DefineIntToken("{timer11exists}", (int)eDMTimersIT::timer11exists); + tokenContainer->DefineIntToken("{timer12exists}", (int)eDMTimersIT::timer12exists); + tokenContainer->DefineIntToken("{timer13exists}", (int)eDMTimersIT::timer13exists); + tokenContainer->DefineIntToken("{timer14exists}", (int)eDMTimersIT::timer14exists); + tokenContainer->DefineIntToken("{timer15exists}", (int)eDMTimersIT::timer15exists); + timerIndex = tokenContainer->LoopIndex("timers"); + InheritTokenContainer(); +} + +bool cVeDmTimers::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + + tokenContainer->Clear(); + cGlobalSortedTimers SortedTimers;// local and remote timers + int numTimers = SortedTimers.Size(); + tokenContainer->AddIntToken((int)eDMTimersIT::numtimers, numTimers); + tokenContainer->AddIntToken((int)eDMTimersIT::numtimerconflicts, SortedTimers.NumTimerConfilicts()); + for (int i=0; i<15; i++) { + if (i < numTimers) { + tokenContainer->AddIntToken(i+2, true); + } else { + tokenContainer->AddIntToken(i+2, false); + } + } + + vector timerInfo; + timerInfo.push_back(numTimers); + tokenContainer->CreateLoopTokenContainer(&timerInfo); + + for (int i = 0; i < numTimers; i++) { + if (i >=15) + break; + const cTimer *Timer = SortedTimers[i]; + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::isremotetimer, SortedTimers.IsRemoteTimer(i) ? "1" : "0"); + const cEvent *event = Timer->Event(); + if (event) { + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::title, event->Title()); + } else { + const char *File = Setup.FoldersInTimerMenu ? NULL : strrchr(Timer->File(), FOLDERDELIMCHAR); + if (File && strcmp(File + 1, TIMERMACRO_TITLE) && strcmp(File + 1, TIMERMACRO_EPISODE)) + File++; + else + File = Timer->File(); + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::title, File); + } + const cChannel *channel = Timer->Channel(); + if (channel) { + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::channelname, channel->Name()); + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::channelnumber, *cString::sprintf("%d", channel->Number())); + cString channelID = channel->GetChannelID().ToString(); + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::channelid, *channelID); + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::channellogoexists, imgCache->LogoExists(*channelID) ? "1" : "0"); + } + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::recording, Timer->Recording() ? "1" : "0"); + + cString timerDate(""); + if (Timer->Recording()) { + timerDate = cString::sprintf("-%s", *TimeString(Timer->StopTime())); + } else { + time_t Now = time(NULL); + cString Today = WeekDayName(Now); + cString Time = TimeString(Timer->StartTime()); + cString Day = WeekDayName(Timer->StartTime()); + if (Timer->StartTime() > Now + 6 * SECSINDAY) { + time_t ttm = Timer->StartTime(); + struct tm * timerTime = localtime(&ttm); + timerDate = cString::sprintf("%02d.%02d %s", timerTime->tm_mday, timerTime->tm_mon + 1, *Time); + } else if (strcmp(Day, Today) != 0) + timerDate = cString::sprintf("%s %s", *Day, *Time); + else + timerDate = Time; + if (Timer->Flags() & tfVps) + timerDate = cString::sprintf("VPS %s", *timerDate); + } + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::datetime, *timerDate); + tokenContainer->AddLoopToken(timerIndex, i, (int)eDMTimersLT::isremotetimer, SortedTimers.IsRemoteTimer(i) ? "1" : "0"); + } + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDmCurrentschedule +******************************************************************/ +cVeDmCurrentschedule::cVeDmCurrentschedule(void) { + rec = NULL; +} + +cVeDmCurrentschedule::~cVeDmCurrentschedule(void) { +} + +void cVeDmCurrentschedule::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{title}", (int)eDMCurrentscheduleST::title); + tokenContainer->DefineStringToken("{subtitle}", (int)eDMCurrentscheduleST::subtitle); + tokenContainer->DefineStringToken("{start}", (int)eDMCurrentscheduleST::start); + tokenContainer->DefineStringToken("{stop}", (int)eDMCurrentscheduleST::stop); + tokenContainer->DefineStringToken("{durationminutes}", (int)eDMCurrentscheduleST::durationminutes); + tokenContainer->DefineStringToken("{mediapath}", (int)eScraperPosterBannerST::mediapath); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperPosterBannerST::posterpath); + tokenContainer->DefineStringToken("{bannerpath}", (int)eScraperPosterBannerST::bannerpath); + tokenContainer->DefineIntToken("{islivetv}", (int)eDMCurrentscheduleIT::islivetv); + tokenContainer->DefineIntToken("{duration}", (int)eDMCurrentscheduleIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eDMCurrentscheduleIT::durationhours); + tokenContainer->DefineIntToken("{minutes}", (int)eDMCurrentscheduleIT::minutes); + tokenContainer->DefineIntToken("{elapsed}", (int)eDMCurrentscheduleIT::elapsed); + tokenContainer->DefineIntToken("{remaining}", (int)eDMCurrentscheduleIT::remaining); + tokenContainer->DefineIntToken("{mediawidth}", (int)eScraperPosterBannerIT::mediawidth); + tokenContainer->DefineIntToken("{mediaheight}", (int)eScraperPosterBannerIT::mediaheight); + tokenContainer->DefineIntToken("{isbanner}", (int)eScraperPosterBannerIT::isbanner); + tokenContainer->DefineIntToken("{hasposter}", (int)eScraperPosterBannerIT::hasposter); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperPosterBannerIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperPosterBannerIT::posterheight); + tokenContainer->DefineIntToken("{hasBanner}", (int)eScraperPosterBannerIT::hasbanner); + tokenContainer->DefineIntToken("{bannerwidth}", (int)eScraperPosterBannerIT::bannerwidth); + tokenContainer->DefineIntToken("{bannerheight}", (int)eScraperPosterBannerIT::bannerheight); + InheritTokenContainer(); +} + +void cVeDmCurrentschedule::SetRecording(const char *currentRec) { + rec = currentRec; +} + +bool cVeDmCurrentschedule::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + + cDevice *device = cDevice::PrimaryDevice(); + const cChannel *channel = NULL; + if (!device->Replaying() || device->Transferring()) { + channel = Channels.GetByNumber(device->CurrentChannel()); + } + if (channel) { + ParseFromChannel(channel); + } else { + if (!rec) + return true; + const cRecording *recording = new cRecording(rec); + if (recording) { + ParseFromRecording(recording); + delete recording; + } + } + SetDirty(); + return true; +} + +void cVeDmCurrentschedule::ParseFromChannel(const cChannel *channel) { + const cEvent *event = NULL; + cSchedulesLock SchedulesLock; + if (const cSchedules *Schedules = cSchedules::Schedules(SchedulesLock)) + if (const cSchedule *Schedule = Schedules->GetSchedule(channel)) + event = Schedule->GetPresentEvent(); + if (!event) + return; + + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::islivetv, 1); + tokenContainer->AddStringToken((int)eDMCurrentscheduleST::title, event->Title()); + tokenContainer->AddStringToken((int)eDMCurrentscheduleST::subtitle, event->ShortText()); + tokenContainer->AddStringToken((int)eDMCurrentscheduleST::start, *event->GetTimeString()); + tokenContainer->AddStringToken((int)eDMCurrentscheduleST::stop, *event->GetEndTimeString()); + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::duration, event->Duration() / 60); + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::durationhours, event->Duration() / 3600); + tokenContainer->AddStringToken((int)eDMCurrentscheduleST::durationminutes, *cString::sprintf("%.2d", (event->Duration() / 60)%60)); + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::elapsed, (int)round((time(NULL) - event->StartTime())/60)); + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::remaining, (int)round((event->EndTime() - time(NULL))/60)); + SetPosterBanner(tokenContainer, event, NULL); +} + +void cVeDmCurrentschedule::ParseFromRecording(const cRecording *recording) { + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::islivetv, 0); + string recFullName = recording->Name() ? recording->Name() : ""; + string recName = ""; + string recFolder = ""; + RecName(recFullName, recName, recFolder); + tokenContainer->AddStringToken((int)eDMCurrentscheduleST::title, recName.c_str()); + const cRecordingInfo *info = recording->Info(); + if (info) + tokenContainer->AddStringToken((int)eDMCurrentscheduleST::subtitle, info->ShortText()); + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::duration, recording->LengthInSeconds() / 60); + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::durationhours, recording->LengthInSeconds() / 3600); + tokenContainer->AddStringToken((int)eDMCurrentscheduleST::durationminutes, *cString::sprintf("%.2d", (recording->LengthInSeconds() / 60)%60)); + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::elapsed, 0); + tokenContainer->AddIntToken((int)eDMCurrentscheduleIT::remaining, 0); + SetPosterBanner(tokenContainer, NULL, recording); +} + +void cVeDmCurrentschedule::RecName(string &path, string &name, string &folder) { + size_t delim = path.find_last_of('~'); + if (delim == string::npos) { + name = path; + if (name.find('%') == 0) { + name = name.substr(1); + } + return; + } + name = path.substr(delim+1); + if (name.find('%') == 0) { + name = name.substr(1); + } + folder = path.substr(0, delim); + size_t delim2 = folder.find_last_of('~'); + if (delim2 == string::npos) { + return; + } + folder = folder.substr(delim2+1); +} +/****************************************************************** +* cVeDmDiscusage +******************************************************************/ +cVeDmDiscusage::cVeDmDiscusage(void) { +} + +cVeDmDiscusage::~cVeDmDiscusage(void) { +} + +void cVeDmDiscusage::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{freetime}", (int)eDMDiscusageST::freetime); + tokenContainer->DefineStringToken("{vdrusagestring}", (int)eDMDiscusageST::vdrusagestring); + tokenContainer->DefineIntToken("{freepercent}", (int)eDMDiscusageIT::freepercent); + tokenContainer->DefineIntToken("{usedpercent}", (int)eDMDiscusageIT::usedpercent); + tokenContainer->DefineIntToken("{freegb}", (int)eDMDiscusageIT::freegb); + tokenContainer->DefineIntToken("{discalert}", (int)eDMDiscusageIT::discalert); + InheritTokenContainer(); +} + +bool cVeDmDiscusage::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDMDiscusageST::vdrusagestring, *cVideoDiskUsage::String()); + tokenContainer->AddStringToken((int)eDMDiscusageST::freetime, *cString::sprintf("%02d:%02d", cVideoDiskUsage::FreeMinutes() / 60, cVideoDiskUsage::FreeMinutes() % 60)); + int discUsage = cVideoDiskUsage::UsedPercent(); + bool discAlert = (discUsage > 95) ? true : false; + int freeGB = cVideoDiskUsage::FreeMB() / 1024; + tokenContainer->AddIntToken((int)eDMDiscusageIT::usedpercent, discUsage); + tokenContainer->AddIntToken((int)eDMDiscusageIT::freepercent, 100-discUsage); + tokenContainer->AddIntToken((int)eDMDiscusageIT::discalert, discAlert); + tokenContainer->AddIntToken((int)eDMDiscusageIT::freegb, freeGB); + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDmSystemload +******************************************************************/ +cVeDmSystemload::cVeDmSystemload(void) { + lastSystemLoad = -1.0f; +} + +cVeDmSystemload::~cVeDmSystemload(void) { +} + +void cVeDmSystemload::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{load}", (int)eDMSystemloadST::load); + tokenContainer->DefineIntToken("{loadhand}", (int)eDMSystemloadIT::loadhand); + InheritTokenContainer(); +} + +bool cVeDmSystemload::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + double systemLoad; + if (getloadavg(&systemLoad, 1) <= 0) + return false; + if (lastSystemLoad == systemLoad && !forced) + return false; + + lastSystemLoad = systemLoad; + + string load = *cString::sprintf("%.2f", systemLoad); + int loadHand = systemLoad * 1000; + int loadHandValue = 0; + if (loadHand > 2500) + loadHandValue = 2525; + else { + int loadHandDec = loadHand - (loadHand / 100) * 100; + if (loadHandDec <= 12) + loadHandDec = 0; + else if (loadHandDec <= 37) + loadHandDec = 25; + else if (loadHandDec <= 62) + loadHandDec = 50; + else if (loadHandDec <= 87) + loadHandDec = 75; + else + loadHandDec = 0; + loadHandValue = loadHand / 100 * 100 + loadHandDec; + } + tokenContainer->AddStringToken((int)eDMSystemloadST::load, *cString::sprintf("%.2f", systemLoad)); + tokenContainer->AddIntToken((int)eDMSystemloadIT::loadhand, loadHandValue); + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDmSystemmemory +******************************************************************/ +cVeDmSystemmemory::cVeDmSystemmemory(void) { + lastMemUsage = -1; +} + +cVeDmSystemmemory::~cVeDmSystemmemory(void) { +} + +void cVeDmSystemmemory::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{totalmem}", (int)eDMSystemmemoryIT::totalmem); + tokenContainer->DefineIntToken("{usedmem}", (int)eDMSystemmemoryIT::usedmem); + tokenContainer->DefineIntToken("{usedmempercent}", (int)eDMSystemmemoryIT::usedmempercent); + InheritTokenContainer(); +} + +bool cVeDmSystemmemory::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + + struct sysinfo memInfo; + sysinfo (&memInfo); + long long totalMem = memInfo.totalram; + totalMem += memInfo.totalswap; + totalMem *= memInfo.mem_unit; + int totalMemMB = totalMem / 1024 / 1024; + long long usedMem = memInfo.totalram - memInfo.freeram; + usedMem += memInfo.totalswap - memInfo.freeswap; + usedMem *= memInfo.mem_unit; + int usedMemMB = usedMem / 1024 / 1024; + + if (lastMemUsage == usedMemMB) { + return false; + } + lastMemUsage = usedMemMB; + tokenContainer->AddIntToken((int)eDMSystemmemoryIT::totalmem, totalMemMB); + tokenContainer->AddIntToken((int)eDMSystemmemoryIT::usedmem, usedMemMB); + if (totalMemMB > 0) + tokenContainer->AddIntToken((int)eDMSystemmemoryIT::usedmempercent, usedMemMB * 100 / totalMemMB); + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDmTemperatures +******************************************************************/ +cVeDmTemperatures::cVeDmTemperatures(void) { + Reset(); +} + +cVeDmTemperatures::~cVeDmTemperatures(void) { +} + +void cVeDmTemperatures::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{cputemp}", (int)eDMTemperaturesIT::cputemp); + tokenContainer->DefineIntToken("{gputemp}", (int)eDMTemperaturesIT::gputemp); + InheritTokenContainer(); +} + +bool cVeDmTemperatures::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + + cString execCommand = cString::sprintf("cd \"%s/\"; \"%s/temperatures\"", SCRIPTFOLDER, SCRIPTFOLDER); + int ok = system(*execCommand); + if (ok) {} + + string tempCPU, tempGPU; + int cpu, gpu; + + cString itemFilename = cString::sprintf("%s/cpu", SCRIPTOUTPUTPATH ); + ifstream file(*itemFilename, ifstream::in); + if( file.is_open() ) { + std::getline(file, tempCPU); + if (tempCPU.size() > 2) { + cpu = atoi(tempCPU.substr(0,2).c_str()); + } else + cpu = 0; + file.close(); + } else { + cpu = 0; + } + + itemFilename = cString::sprintf("%s/gpu", SCRIPTOUTPUTPATH ); + ifstream file2(*itemFilename, ifstream::in); + if( file2.is_open() ) { + std::getline(file2, tempGPU); + if (tempGPU.size() > 2) { + gpu = atoi(tempGPU.substr(0,2).c_str()); + } else + gpu = 0; + file2.close(); + } else { + gpu = 0; + } + + if ((lastCpuTemp == cpu) && (lastGpuTemp == gpu)) + return false; + lastCpuTemp = cpu; + lastGpuTemp = gpu; + + tokenContainer->AddIntToken((int)eDMTemperaturesIT::cputemp, cpu); + tokenContainer->AddIntToken((int)eDMTemperaturesIT::gputemp, gpu); + SetDirty(); + return true; +} +/****************************************************************** +* cVeDmVdrstatistics +******************************************************************/ +cVeDmVdrstatistics::cVeDmVdrstatistics(void) { + Reset(); +} + +cVeDmVdrstatistics::~cVeDmVdrstatistics(void) { +} + +void cVeDmVdrstatistics::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{vdrcpu}", (int)eDMVdrstatisticsST::vdrcpu); + tokenContainer->DefineStringToken("{vdrmem}", (int)eDMVdrstatisticsST::vdrmem); + InheritTokenContainer(); +} + +bool cVeDmVdrstatistics::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + + cString execCommand = cString::sprintf("cd \"%s/\"; \"%s/vdrstats\"", SCRIPTFOLDER, SCRIPTFOLDER); + int ok = system(*execCommand); + if (ok) {} + + string vdrCPU = ""; + string vdrMEM = ""; + + cString itemFilename = cString::sprintf("%s/vdrcpu", SCRIPTOUTPUTPATH ); + ifstream file(*itemFilename, ifstream::in); + if( file.is_open() ) { + std::getline(file, vdrCPU); + file.close(); + } + + itemFilename = cString::sprintf("%s/vdrmem", SCRIPTOUTPUTPATH ); + ifstream file2(*itemFilename, ifstream::in); + if( file2.is_open() ) { + std::getline(file2, vdrMEM); + file2.close(); + } + + if (vdrCPU.size() == 0 || vdrMEM.size() == 0) + return false; + + if (!lastVdrCPU.compare(vdrCPU) && !lastVdrMEM.compare(vdrMEM)) { + return false; + } + lastVdrCPU = vdrCPU; + lastVdrMEM = vdrMEM; + + tokenContainer->AddStringToken((int)eDMVdrstatisticsST::vdrcpu, vdrCPU.c_str()); + tokenContainer->AddStringToken((int)eDMVdrstatisticsST::vdrmem, vdrMEM.c_str()); + SetDirty(); + return true; +} +/****************************************************************** +* cVeDmLastrecordings +******************************************************************/ +cVeDmLastrecordings::cVeDmLastrecordings(void) { + recIndex = -1; +} + +cVeDmLastrecordings::~cVeDmLastrecordings(void) { +} + +void cVeDmLastrecordings::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{numtimers}", (int)eDMLastrecordingsIT::numtimers); + tokenContainer->DefineLoopToken("{recordings[name]}", (int)eDMLastrecordingsLT::name); + tokenContainer->DefineLoopToken("{recordings[seriesname]}", (int)eDMLastrecordingsLT::seriesname); + tokenContainer->DefineLoopToken("{recordings[date]}", (int)eDMLastrecordingsLT::date); + tokenContainer->DefineLoopToken("{recordings[time]}", (int)eDMLastrecordingsLT::time); + tokenContainer->DefineLoopToken("{recordings[duration]}", (int)eDMLastrecordingsLT::duration); + tokenContainer->DefineLoopToken("{recordings[hasposter]}", (int)eDMLastrecordingsLT::hasposter); + tokenContainer->DefineLoopToken("{recordings[posterpath]}", (int)eDMLastrecordingsLT::posterpath); + tokenContainer->DefineLoopToken("{recordings[posterwidth]}", (int)eDMLastrecordingsLT::posterwidth); + tokenContainer->DefineLoopToken("{recordings[posterheight]}", (int)eDMLastrecordingsLT::posterheight); + recIndex = tokenContainer->LoopIndex("recordings"); + InheritTokenContainer(); +} + +bool cVeDmLastrecordings::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + + cGlobalSortedTimers SortedTimers;// local and remote timers + int numTimers = SortedTimers.Size(); + //set number of timers so that it is possible to adapt this viewelement accordingly + tokenContainer->AddIntToken((int)eDMLastrecordingsIT::numtimers, numTimers); + + list orderedRecs; + + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { + if (orderedRecs.size() == 0) { + orderedRecs.push_back(recording); + continue; + } + bool inserted = false; + for (list::iterator it = orderedRecs.begin(); it != orderedRecs.end(); it++) { + const cRecording *orderedRec = *it; + if (recording->Start() >= orderedRec->Start()) { + orderedRecs.insert(it, recording); + inserted = true; + break; + } + } + if (!inserted) { + orderedRecs.push_back(recording); + } + } + + int MAX_RECORDINGS = 10; + int availableRecordings = orderedRecs.size(); + int numRecordings = min(MAX_RECORDINGS, availableRecordings); + if (!numRecordings) + return true; + + vector loopInfo; + loopInfo.push_back(numRecordings); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + + int i = 0; + for (list::iterator it = orderedRecs.begin(); it != orderedRecs.end(); it++) { + const cRecording *recording = *it; +#if APIVERSNUM >= 20101 + if (recording->IsInUse()) { + continue; + } +#endif + string recFullPath = recording->Name() ? recording->Name() : ""; + string recName = ""; + string recPath = ""; + RecName(recFullPath, recName, recPath); + cString recDuration = cString::sprintf("%d", recording->LengthInSeconds()/60); + + string posterPath = ""; + int posterWidth = 0; + int posterHeight = 0; + bool hasPoster = false; + RecPoster(recording, posterWidth, posterHeight, posterPath, hasPoster); + + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::name, recName.c_str()); + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::seriesname, recPath.c_str()); + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::date, *ShortDateString(recording->Start())); + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::time, *TimeString(recording->Start())); + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::duration, *recDuration); + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::hasposter, hasPoster ? "1" : "0"); + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::posterpath, posterPath.c_str()); + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::posterwidth, *cString::sprintf("%d", posterWidth)); + tokenContainer->AddLoopToken(recIndex, i, (int)eDMLastrecordingsLT::posterheight, *cString::sprintf("%d", posterHeight)); + + i++; + if (i == MAX_RECORDINGS) + break; + } + SetDirty(); + return true; +} + +void cVeDmLastrecordings::RecName(string &path, string &name, string &folder) { + size_t delim = path.find_last_of('~'); + if (delim == string::npos) { + name = path; + if (name.find('%') == 0) { + name = name.substr(1); + } + return; + } + name = path.substr(delim+1); + if (name.find('%') == 0) { + name = name.substr(1); + } + folder = path.substr(0, delim); + size_t delim2 = folder.find_last_of('~'); + if (delim2 == string::npos) { + return; + } + folder = folder.substr(delim2+1); +} +/****************************************************************** +* cVeDmDetailheaderEpg +******************************************************************/ +cVeDmDetailheaderEpg::cVeDmDetailheaderEpg(void) { + event = NULL; +} + +cVeDmDetailheaderEpg::~cVeDmDetailheaderEpg(void) { +} + +void cVeDmDetailheaderEpg::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperHeaderST::posterpath); + tokenContainer->DefineStringToken("{bannerpath}", (int)eScraperHeaderST::bannerpath); + tokenContainer->DefineStringToken("{title}", (int)eDmDetailedHeaderEpgST::title); + tokenContainer->DefineStringToken("{shorttext}", (int)eDmDetailedHeaderEpgST::shorttext); + tokenContainer->DefineStringToken("{start}", (int)eDmDetailedHeaderEpgST::start); + tokenContainer->DefineStringToken("{stop}", (int)eDmDetailedHeaderEpgST::stop); + tokenContainer->DefineStringToken("{day}", (int)eDmDetailedHeaderEpgST::day); + tokenContainer->DefineStringToken("{date}", (int)eDmDetailedHeaderEpgST::date); + tokenContainer->DefineStringToken("{durationminutes}", (int)eDmDetailedHeaderEpgST::durationminutes); + tokenContainer->DefineStringToken("{vps}", (int)eDmDetailedHeaderEpgST::vps); + tokenContainer->DefineStringToken("{channelname}", (int)eDmDetailedHeaderEpgST::channelname); + tokenContainer->DefineStringToken("{channelid}", (int)eDmDetailedHeaderEpgST::channelid); + tokenContainer->DefineStringToken("{epgpicpath}", (int)eDmDetailedHeaderEpgST::epgpicpath); + tokenContainer->DefineIntToken("{ismovie}", (int)eScraperHeaderIT::ismovie); + tokenContainer->DefineIntToken("{isseries}", (int)eScraperHeaderIT::isseries); + tokenContainer->DefineIntToken("{posteravailable}", (int)eScraperHeaderIT::posteravailable); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperHeaderIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperHeaderIT::posterheight); + tokenContainer->DefineIntToken("{banneravailable}", (int)eScraperHeaderIT::banneravailable); + tokenContainer->DefineIntToken("{bannerwidth}", (int)eScraperHeaderIT::bannerwidth); + tokenContainer->DefineIntToken("{bannerheight}", (int)eScraperHeaderIT::bannerheight); + tokenContainer->DefineIntToken("{daynumeric}", (int)eDmDetailedHeaderEpgIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eDmDetailedHeaderEpgIT::month); + tokenContainer->DefineIntToken("{year}", (int)eDmDetailedHeaderEpgIT::year); + tokenContainer->DefineIntToken("{running}", (int)eDmDetailedHeaderEpgIT::running); + tokenContainer->DefineIntToken("{elapsed}", (int)eDmDetailedHeaderEpgIT::elapsed); + tokenContainer->DefineIntToken("{duration}", (int)eDmDetailedHeaderEpgIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eDmDetailedHeaderEpgIT::durationhours); + tokenContainer->DefineIntToken("{channelnumber}", (int)eDmDetailedHeaderEpgIT::channelnumber); + tokenContainer->DefineIntToken("{channellogoexists}", (int)eDmDetailedHeaderEpgIT::channellogoexists); + tokenContainer->DefineIntToken("{epgpicavailable}", (int)eDmDetailedHeaderEpgIT::epgpicavailable); + InheritTokenContainer(); +} + +void cVeDmDetailheaderEpg::SetEvent(const cEvent *event) { + this->event = event; +} + +bool cVeDmDetailheaderEpg::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!event) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::title, event->Title()); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::shorttext, event->ShortText()); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::start, *(event->GetTimeString())); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::stop, *(event->GetEndTimeString())); + time_t startTime = event->StartTime(); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::day, *WeekDayName(startTime)); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::date, *ShortDateString(startTime)); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::month, sStartTime->tm_mon+1); + const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); + if (channel) { + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::channelname, channel->Name()); + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::channelnumber, channel->Number()); + } + cString channelID = event->ChannelID().ToString(); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::channelid, *channelID); + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::channellogoexists, imgCache->LogoExists(*channelID)); + + bool isRunning = false; + time_t now = time(NULL); + if ((now >= event->StartTime()) && (now <= event->EndTime())) + isRunning = true; + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::running, isRunning); + if (isRunning) { + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::elapsed, (now - event->StartTime())/60); + } else { + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::elapsed, 0); + } + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::duration, event->Duration() / 60); + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::durationhours, event->Duration() / 3600); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::durationminutes, *cString::sprintf("%.2d", (event->Duration() / 60)%60)); + if (event->Vps()) + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::vps, *event->GetVpsString()); + + cString epgImageName = cString::sprintf("%d", event->EventID()); + bool epgPicAvailable = FileExists(*config.epgImagePath, *epgImageName, "jpg"); + if (epgPicAvailable) { + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::epgpicavailable, true); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::epgpicpath, *cString::sprintf("%s%s.jpg", *config.epgImagePath, *epgImageName)); + } else { + epgImageName = cString::sprintf("%d_0", event->EventID()); + epgPicAvailable = FileExists(*config.epgImagePath, *epgImageName, "jpg"); + if (epgPicAvailable) { + tokenContainer->AddIntToken((int)eDmDetailedHeaderEpgIT::epgpicavailable, true); + tokenContainer->AddStringToken((int)eDmDetailedHeaderEpgST::epgpicpath, *cString::sprintf("%s%s.jpg", *config.epgImagePath, *epgImageName)); + } + } + bool scrapInfoAvailable = LoadFullScrapInfo(event, NULL); + if (scrapInfoAvailable) { + SetHeaderScrapInfo(tokenContainer); + } + + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDmDetailheaderRec +******************************************************************/ +cVeDmDetailheaderRec::cVeDmDetailheaderRec(void) { +} + +cVeDmDetailheaderRec::~cVeDmDetailheaderRec(void) { +} + +void cVeDmDetailheaderRec::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperHeaderST::posterpath); + tokenContainer->DefineStringToken("{bannerpath}", (int)eScraperHeaderST::bannerpath); + tokenContainer->DefineStringToken("{name}", (int)eDmDetailedHeaderRecST::name); + tokenContainer->DefineStringToken("{epgname}", (int)eDmDetailedHeaderRecST::epgname); + tokenContainer->DefineStringToken("{shorttext}", (int)eDmDetailedHeaderRecST::shorttext); + tokenContainer->DefineStringToken("{date}", (int)eDmDetailedHeaderRecST::date); + tokenContainer->DefineStringToken("{time}", (int)eDmDetailedHeaderRecST::time); + tokenContainer->DefineStringToken("{recimgpath}", (int)eDmDetailedHeaderRecST::recimgpath); + tokenContainer->DefineStringToken("{recchannelname}", (int)eDmDetailedHeaderRecST::recchannelname); + tokenContainer->DefineStringToken("{recchannelid}", (int)eDmDetailedHeaderRecST::recchannelid); + tokenContainer->DefineStringToken("{durationminutes}", (int)eDmDetailedHeaderRecST::durationminutes); + tokenContainer->DefineStringToken("{durationeventminutes}", (int)eDmDetailedHeaderRecST::durationeventminutes); + tokenContainer->DefineIntToken("{ismovie}", (int)eScraperHeaderIT::ismovie); + tokenContainer->DefineIntToken("{isseries}", (int)eScraperHeaderIT::isseries); + tokenContainer->DefineIntToken("{posteravailable}", (int)eScraperHeaderIT::posteravailable); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperHeaderIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperHeaderIT::posterheight); + tokenContainer->DefineIntToken("{banneravailable}", (int)eScraperHeaderIT::banneravailable); + tokenContainer->DefineIntToken("{bannerwidth}", (int)eScraperHeaderIT::bannerwidth); + tokenContainer->DefineIntToken("{bannerheight}", (int)eScraperHeaderIT::bannerheight); + tokenContainer->DefineIntToken("{daynumeric}", (int)eDmDetailedHeaderRecIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eDmDetailedHeaderRecIT::month); + tokenContainer->DefineIntToken("{year}", (int)eDmDetailedHeaderRecIT::year); + tokenContainer->DefineIntToken("{duration}", (int)eDmDetailedHeaderRecIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eDmDetailedHeaderRecIT::durationhours); + tokenContainer->DefineIntToken("{durationevent}", (int)eDmDetailedHeaderRecIT::durationevent); + tokenContainer->DefineIntToken("{durationeventhours}", (int)eDmDetailedHeaderRecIT::durationeventhours); + tokenContainer->DefineIntToken("{recimgavailable}", (int)eDmDetailedHeaderRecIT::recimgavailable); + tokenContainer->DefineIntToken("{recchannelnumber}", (int)eDmDetailedHeaderRecIT::recchannelnumber); + InheritTokenContainer(); +} + +void cVeDmDetailheaderRec::SetRecording(const cRecording *recording) { + this->recording = recording; +} + +bool cVeDmDetailheaderRec::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + if (!recording) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::name, recording->Name()); + + const cRecordingInfo *info = recording->Info(); + if (info) { + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::epgname, info->Title()); + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::shorttext, info->ShortText()); + const cEvent *event = info->GetEvent(); + if (event) { + cString recDate = event->GetDateString(); + cString recTime = event->GetTimeString(); + if (strstr(*recDate, "1970")) { + time_t start = recording->Start(); + recDate = DateString(start); + recTime = TimeString(start); + } + int duration = event->Duration() / 60; + int recDuration = recording->LengthInSeconds(); + recDuration = (recDuration > 0) ? (recDuration / 60) : 0; + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::date, *recDate); + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::time, *recTime); + time_t startTime = event->StartTime(); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::month, sStartTime->tm_mon+1); + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::duration, recDuration); + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::durationhours, recDuration / 60); + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::durationminutes, *cString::sprintf("%.2d", recDuration%60)); + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::durationevent, duration); + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::durationeventhours, duration / 60); + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::durationeventminutes, *cString::sprintf("%.2d", duration%60)); + } + cChannel *channel = Channels.GetByChannelID(info->ChannelID()); + if (channel) { + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelname, channel->Name()); + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recchannelid, *channel->GetChannelID().ToString()); + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::recchannelnumber, channel->Number()); + } + } + string recImage = ""; + string path = recording->FileName() ? recording->FileName() : ""; + string extension = ".jpg"; + if (FirstFileInFolder(path, extension, recImage)) { + tokenContainer->AddIntToken((int)eDmDetailedHeaderRecIT::recimgavailable, 1); + tokenContainer->AddStringToken((int)eDmDetailedHeaderRecST::recimgpath, *cString::sprintf("%s/%s", path.c_str(), recImage.c_str())); + } + bool scrapInfoAvailable = LoadFullScrapInfo(NULL, recording); + if (scrapInfoAvailable) { + SetHeaderScrapInfo(tokenContainer); + } + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDmDetailheaderPlugin +******************************************************************/ +cVeDmDetailheaderPlugin::cVeDmDetailheaderPlugin(void) { + plugId = -1; + plugMenuId = -1; +} + +cVeDmDetailheaderPlugin::~cVeDmDetailheaderPlugin(void) { +} + +void cVeDmDetailheaderPlugin::SetTokenContainer(void) { + if (plugId == -1 || plugMenuId == -1) + return; + skindesignerapi::cTokenContainer *tkPlugMenu = plgManager->GetTokenContainer(plugId, plugMenuId); + tokenContainer = new skindesignerapi::cTokenContainer(*tkPlugMenu); + InheritTokenContainer(); +} + +void cVeDmDetailheaderPlugin::Set(skindesignerapi::cTokenContainer *tk) { + tokenContainer->Clear(); + tokenContainer->SetTokens(tk); +} + +bool cVeDmDetailheaderPlugin::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + SetDirty(); + return true; +} +/****************************************************************** +* cVeDmTablabels +******************************************************************/ +cVeDmTablabels::cVeDmTablabels(void) { + tabIndex = -1; + activeTab = -1; +} + +cVeDmTablabels::~cVeDmTablabels(void) { +} + +void cVeDmTablabels::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineLoopToken("{tabs[title]}", (int)eDmTabsLT::title); + tokenContainer->DefineLoopToken("{tabs[current]}", (int)eDmTabsLT::current); + tokenContainer->DefineStringToken("{currenttab}", (int)eDmTabsST::currenttab); + tokenContainer->DefineStringToken("{prevtab}", (int)eDmTabsST::prevtab); + tokenContainer->DefineStringToken("{nexttab}", (int)eDmTabsST::nexttab); + tabIndex = tokenContainer->LoopIndex("tabs"); + InheritTokenContainer(); +} + +void cVeDmTablabels::SetTabs(vector &newTabs) { + tabs.clear(); + for (vector::iterator it = newTabs.begin(); it != newTabs.end(); it++) { + tabs.push_back(*it); + } + SetDirty(); +} + +bool cVeDmTablabels::Parse(bool forced) { + tokenContainer->Clear(); + int numTabs = tabs.size(); + vector loopInfo; + loopInfo.push_back(numTabs); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + for (int i = 0; i < numTabs; i++) { + if (i == activeTab) { + tokenContainer->AddLoopToken(tabIndex, i, (int)eDmTabsLT::current, "1"); + + } else { + tokenContainer->AddLoopToken(tabIndex, i, (int)eDmTabsLT::current, "0"); + } + tokenContainer->AddLoopToken(tabIndex, i, (int)eDmTabsLT::title, tabs[i]); + } + + if (activeTab >= 0 && activeTab < numTabs) { + tokenContainer->AddStringToken((int)eDmTabsST::currenttab, tabs[activeTab]); + tokenContainer->AddStringToken((int)eDmTabsST::prevtab, (activeTab == 0) ? tabs[numTabs-1] : tabs[activeTab-1]); + tokenContainer->AddStringToken((int)eDmTabsST::nexttab, (activeTab == numTabs-1) ? tabs[0] : tabs[activeTab+1]); + } + return true; +} + + + diff --git a/coreengine/viewelementsdisplaymenu.h b/coreengine/viewelementsdisplaymenu.h new file mode 100644 index 0000000..20b1bed --- /dev/null +++ b/coreengine/viewelementsdisplaymenu.h @@ -0,0 +1,250 @@ +#ifndef __VIEWELEMENTSDM_H +#define __VIEWELEMENTSDM_H + +#include "viewelement.h" +#include "../extensions/scrapmanager.h" + +/****************************************************************** +* cVeDmHeader +******************************************************************/ +class cVeDmHeader : public cViewElement { +private: + char *title; + char *channelName; + int channelNumber; + char *channelId; + bool epgSearchFav; +public: + cVeDmHeader(void); + virtual ~cVeDmHeader(void); + void SetTokenContainer(void); + void SetTitle(const char *title); + void SetChannel(const cChannel *channel); + void Set(eMenuCategory menuCat); + void IsEpgSearchFav(bool isFav) { epgSearchFav = isFav;} ; +}; + +/****************************************************************** +* cVeDmSortmode +******************************************************************/ +class cVeDmSortmode : public cViewElement { +private: + eMenuSortMode sortMode; + eMenuSortMode lastSortMode; +public: + cVeDmSortmode(void); + virtual ~cVeDmSortmode(void); + void Reset(void) { lastSortMode = msmUnknown; } + void SetTokenContainer(void); + void Set(eMenuSortMode sortMode); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmColorbuttons +******************************************************************/ +class cVeDmColorbuttons : public cViewElement { +private: + bool changed; + char *red; + char *green; + char *yellow; + char *blue; +public: + cVeDmColorbuttons(void); + virtual ~cVeDmColorbuttons(void); + void SetTokenContainer(void); + void SetButtons(const char *red, const char *green, const char *yellow, const char *blue); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmScrollbar +******************************************************************/ +class cVeDmScrollbar : public cViewElement { +private: +public: + cVeDmScrollbar(void); + virtual ~cVeDmScrollbar(void); + void SetTokenContainer(void); + void SetList(int numDisplayed, int offset, int numMax); + void SetDetail(int height, int offset, bool end); +}; + + +/****************************************************************** +* cVeDmTimers +******************************************************************/ +class cVeDmTimers : public cViewElement { +private: + int timerIndex; +public: + cVeDmTimers(void); + virtual ~cVeDmTimers(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmCurrentschedule +******************************************************************/ +class cVeDmCurrentschedule : public cViewElement, public cScrapManager { +private: + const char *rec; + void ParseFromChannel(const cChannel *channel); + void ParseFromRecording(const cRecording *recording); + void RecName(string &path, string &name, string &folder); +public: + cVeDmCurrentschedule(void); + virtual ~cVeDmCurrentschedule(void); + void SetTokenContainer(void); + void SetRecording(const char *currentRec); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmDiscusage +******************************************************************/ +class cVeDmDiscusage : public cViewElement { +private: +public: + cVeDmDiscusage(void); + virtual ~cVeDmDiscusage(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmSystemload +******************************************************************/ +class cVeDmSystemload : public cViewElement { +private: + double lastSystemLoad; +public: + cVeDmSystemload(void); + virtual ~cVeDmSystemload(void); + void Reset(void) { lastSystemLoad = -1.0f; } + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmSystemmemory +******************************************************************/ +class cVeDmSystemmemory : public cViewElement { +private: + int lastMemUsage; +public: + cVeDmSystemmemory(void); + virtual ~cVeDmSystemmemory(void); + void Reset(void) { lastMemUsage = -1; } + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmTemperatures +******************************************************************/ +class cVeDmTemperatures : public cViewElement { +private: + int lastCpuTemp; + int lastGpuTemp; +public: + cVeDmTemperatures(void); + virtual ~cVeDmTemperatures(void); + void Reset(void) { lastCpuTemp = -1; lastGpuTemp = -1; } + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmVdrstatistics +******************************************************************/ +class cVeDmVdrstatistics : public cViewElement { +private: + string lastVdrCPU; + string lastVdrMEM; +public: + cVeDmVdrstatistics(void); + virtual ~cVeDmVdrstatistics(void); + void Reset(void) { lastVdrCPU = "undefined"; lastVdrMEM = "undefined"; } + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmLastrecordings +******************************************************************/ +class cVeDmLastrecordings : public cViewElement, public cScrapManager { +private: + int recIndex; + void RecName(string &path, string &name, string &folder); +public: + cVeDmLastrecordings(void); + virtual ~cVeDmLastrecordings(void); + void SetTokenContainer(void); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmDetailheaderEpg +******************************************************************/ +class cVeDmDetailheaderEpg : public cViewElement, public cScrapManager { +private: + const cEvent *event; +public: + cVeDmDetailheaderEpg(void); + virtual ~cVeDmDetailheaderEpg(void); + void SetTokenContainer(void); + void SetEvent(const cEvent *event); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmDetailheaderRec +******************************************************************/ +class cVeDmDetailheaderRec : public cViewElement, public cScrapManager { +private: + const cRecording *recording; +public: + cVeDmDetailheaderRec(void); + virtual ~cVeDmDetailheaderRec(void); + void SetTokenContainer(void); + void SetRecording(const cRecording *rec); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmDetailheaderPlugin +******************************************************************/ +class cVeDmDetailheaderPlugin : public cViewElement { +private: + int plugId; + int plugMenuId; +public: + cVeDmDetailheaderPlugin(void); + virtual ~cVeDmDetailheaderPlugin(void); + void SetPlugId(int id) { plugId = id; }; + void SetPlugMenuId(int id) { plugMenuId = id; }; + void SetTokenContainer(void); + void Set(skindesignerapi::cTokenContainer *tk); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDmTablabels +******************************************************************/ +class cVeDmTablabels : public cViewElement { +private: + int tabIndex; + int activeTab; + vector tabs; +public: + cVeDmTablabels(void); + virtual ~cVeDmTablabels(void); + void SetTokenContainer(void); + void SetTabs(vector &newTabs); + void SetActiveTab(int activeTab) { SetDirty(); this->activeTab = activeTab; }; + bool Parse(bool forced = false); +}; +#endif //__VIEWELEMENTSDM_H \ No newline at end of file diff --git a/coreengine/viewelementsdisplayreplay.c b/coreengine/viewelementsdisplayreplay.c new file mode 100644 index 0000000..06ec8f8 --- /dev/null +++ b/coreengine/viewelementsdisplayreplay.c @@ -0,0 +1,816 @@ +#include "viewelementsdisplayreplay.h" +#include "../config.h" +#include "../extensions/helpers.h" +#include "../services/scraper2vdr.h" + +/****************************************************************** +* cVeDrRecTitle +******************************************************************/ +cVeDrRecTitle::cVeDrRecTitle(void) { + recording = NULL; + title = NULL; +} + +cVeDrRecTitle::~cVeDrRecTitle(void) { + free(title); +} + +void cVeDrRecTitle::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{rectitle}", (int)eDRRecTitleST::rectitle); + tokenContainer->DefineStringToken("{recsubtitle}", (int)eDRRecTitleST::recsubtitle); + tokenContainer->DefineStringToken("{recdate}", (int)eDRRecTitleST::recdate); + tokenContainer->DefineStringToken("{rectime}", (int)eDRRecTitleST::rectime); + InheritTokenContainer(); +} + +void cVeDrRecTitle::Set(const cRecording *recording) { + this->recording = recording; +} + +void cVeDrRecTitle::Set(const char *title) { + if (!title) + return; + free(this->title); + this->title = strdup(title); +} + +bool cVeDrRecTitle::Parse(bool force) { + if (!cViewElement::Parse(force)) + return false; + if (!recording && !title) + return false; + + tokenContainer->Clear(); + if (recording) { + const char *recName = NULL; + const cRecordingInfo *recInfo = recording->Info(); + if (recInfo) + recName = recInfo->Title(); + if (!recName) + recName = recording->Name(); + tokenContainer->AddStringToken((int)eDRRecTitleST::rectitle, recName); + tokenContainer->AddStringToken((int)eDRRecTitleST::recsubtitle, recInfo ? recInfo->ShortText() : ""); + tokenContainer->AddStringToken((int)eDRRecTitleST::recdate, *ShortDateString(recording->Start())); + tokenContainer->AddStringToken((int)eDRRecTitleST::rectime, *TimeString(recording->Start())); + } else if (title) { + tokenContainer->AddStringToken((int)eDRRecTitleST::rectitle, title); + } + + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDrRecInfo +******************************************************************/ +cVeDrRecInfo::cVeDrRecInfo(void) { + recording = NULL; +} + +cVeDrRecInfo::~cVeDrRecInfo(void) { +} + +void cVeDrRecInfo::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{resolution}", (int)eDRRecInfoST::resolution); + tokenContainer->DefineStringToken("{aspect}", (int)eDRRecInfoST::aspect); + tokenContainer->DefineIntToken("{screenwidth}", (int)eDRRecInfoIT::screenwidth); + tokenContainer->DefineIntToken("{screenheight}", (int)eDRRecInfoIT::screenheight); + tokenContainer->DefineIntToken("{isHD}", (int)eDRRecInfoIT::isHD); + tokenContainer->DefineIntToken("{isWideScreen}", (int)eDRRecInfoIT::isWideScreen); + InheritTokenContainer(); +} + +void cVeDrRecInfo::Set(const cRecording *recording) { + this->recording = recording; +} + +bool cVeDrRecInfo::Parse(bool force) { + if (!cViewElement::Parse(force)) + return false; + if (!recording) + return false; + + int screenWidth = 0; + int screenHeight = 0; + double aspect = 0; + cDevice::PrimaryDevice()->GetVideoSize(screenWidth, screenHeight, aspect); + bool isHD = false; + string resName = GetScreenResolutionString(screenWidth, screenHeight, &isHD); + bool isWideScreen = false; + string aspectName = GetScreenAspectString(aspect, &isWideScreen); + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDRRecInfoIT::screenwidth, screenWidth); + tokenContainer->AddIntToken((int)eDRRecInfoIT::screenheight, screenHeight); + tokenContainer->AddIntToken((int)eDRRecInfoIT::isHD, isHD); + tokenContainer->AddIntToken((int)eDRRecInfoIT::isWideScreen, isWideScreen); + tokenContainer->AddStringToken((int)eDRRecInfoST::resolution, resName.c_str()); + tokenContainer->AddStringToken((int)eDRRecInfoST::aspect, aspectName.c_str()); + + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDrCurrentTime +******************************************************************/ +cVeDrCurrentTime::cVeDrCurrentTime(void) { + changed = true; + current = NULL; +} + +cVeDrCurrentTime::~cVeDrCurrentTime(void) { + free(current); +} + +void cVeDrCurrentTime::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{reccurrent}", (int)eDRCurrentTimeST::reccurrent); + InheritTokenContainer(); +} + +void cVeDrCurrentTime::Set(const char *current) { + if (!current) + return; + free(this->current); + this->current = strdup(current); + changed = true; +} + +bool cVeDrCurrentTime::Parse(bool force) { + if (!cViewElement::Parse(force) || !changed) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDRCurrentTimeST::reccurrent, current); + SetDirty(); + changed = false; + return true; +} + +/****************************************************************** +* cVeDrTotalTime +******************************************************************/ +cVeDrTotalTime::cVeDrTotalTime(void) { + changed = true; + total = NULL; + timeshiftActive = false; + timeshiftDuration = NULL; +} + +cVeDrTotalTime::~cVeDrTotalTime(void) { + free(total); + free(timeshiftDuration); +} + +void cVeDrTotalTime::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{rectotal}", (int)eDRTotalTimeST::rectotal); + tokenContainer->DefineStringToken("{timeshifttotal}", (int)eDRTotalTimeST::timeshifttotal); + tokenContainer->DefineIntToken("{timeshift}", (int)eDRTotalTimeIT::timeshift); + InheritTokenContainer(); +} + +void cVeDrTotalTime::Set(const char *total, bool timeshiftActive, const char *timeshiftDuration) { + if (!total) + return; + free(this->total); + this->total = strdup(total); + this->timeshiftActive = timeshiftActive; + free(this->timeshiftDuration); + this->timeshiftDuration = NULL; + if (timeshiftDuration) + this->timeshiftDuration = strdup(timeshiftDuration); + changed = true; +} + +bool cVeDrTotalTime::Parse(bool force) { + if (!cViewElement::Parse(force) || !changed) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDRTotalTimeST::rectotal, total); + tokenContainer->AddStringToken((int)eDRTotalTimeST::timeshifttotal, timeshiftDuration); + tokenContainer->AddIntToken((int)eDRTotalTimeIT::timeshift, timeshiftActive); + SetDirty(); + changed = false; + return true; +} + +/****************************************************************** +* cVeDrEndTime +******************************************************************/ +cVeDrEndTime::cVeDrEndTime(void) { + end = ""; +} + +cVeDrEndTime::~cVeDrEndTime(void) { +} + +void cVeDrEndTime::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{recend}", (int)eDREndTimeST::recend); + InheritTokenContainer(); +} + +void cVeDrEndTime::Set(cString end) { + if (strcmp(*this->end, *end)) { + this->end = end; + changed = true; + } +} + +bool cVeDrEndTime::Parse(bool force) { + if (!cViewElement::Parse(force) || !changed) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDREndTimeST::recend, *end); + SetDirty(); + changed = false; + return true; +} + +/****************************************************************** +* cVeDrProgressBar +******************************************************************/ +cVeDrProgressBar::cVeDrProgressBar(void) { + current = -1; + total = -1; + timeshiftActive = false; + timeshiftTotal = -1; + changed = true; +} + +cVeDrProgressBar::~cVeDrProgressBar(void) { +} + +void cVeDrProgressBar::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{current}", (int)eDRProgressbarIT::current); + tokenContainer->DefineIntToken("{total}", (int)eDRProgressbarIT::total); + tokenContainer->DefineIntToken("{timeshift}", (int)eDRProgressbarIT::timeshift); + tokenContainer->DefineIntToken("{timeshifttotal}", (int)eDRProgressbarIT::timeshifttotal); + InheritTokenContainer(); +} + +void cVeDrProgressBar::Set(int current, int total, bool timeshiftActive, int timeshiftTotal) { + if (this->current == current) + return; + this->current = current; + this->total = total; + this->timeshiftActive = timeshiftActive; + this->timeshiftTotal = timeshiftTotal; + changed = true; +} + +bool cVeDrProgressBar::Parse(bool force) { + if (!cViewElement::Parse(force) || !changed) + return false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDRProgressbarIT::current, current); + tokenContainer->AddIntToken((int)eDRProgressbarIT::total, total); + tokenContainer->AddIntToken((int)eDRProgressbarIT::timeshift, timeshiftActive); + tokenContainer->AddIntToken((int)eDRProgressbarIT::timeshifttotal, timeshiftTotal); + + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDrCutMarks +******************************************************************/ +cVeDrCutMarks::cVeDrCutMarks(void) { + cutmarksIndex = -1; + lastMarks = NULL; + Reset(); +} + +cVeDrCutMarks::~cVeDrCutMarks(void) { + delete[] lastMarks; +} + +void cVeDrCutMarks::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{timeshift}", (int)eDRCutmarksIT::timeshift); + tokenContainer->DefineLoopToken("{marks[position]}", (int)eDRCutmarksLT::position); + tokenContainer->DefineLoopToken("{marks[endposition]}", (int)eDRCutmarksLT::endposition); + tokenContainer->DefineLoopToken("{marks[total]}", (int)eDRCutmarksLT::total); + tokenContainer->DefineLoopToken("{marks[timeshifttotal]}", (int)eDRCutmarksLT::timeshifttotal); + tokenContainer->DefineLoopToken("{marks[active]}", (int)eDRCutmarksLT::active); + tokenContainer->DefineLoopToken("{marks[startmark]}", (int)eDRCutmarksLT::startmark); + cutmarksIndex = tokenContainer->LoopIndex("marks"); + InheritTokenContainer(); +} + +void cVeDrCutMarks::Set(const cMarks *marks, int current, int total, bool timeshiftActive, int timeshiftTotal) { + this->marks = marks; + this->current = current; + this->total = total; + this->timeshiftActive = timeshiftActive; + this->timeshiftTotal = timeshiftTotal; +} + +void cVeDrCutMarks::Reset(void) { + marks = NULL; + current = -1; + total = -1; + numMarksLast = 0; + delete[] lastMarks; + lastMarks = NULL; + markActive = -1; + timeshiftActive = false; + timeshiftTotal = -1; +} + +bool cVeDrCutMarks::Parse(bool force) { + if (!cViewElement::Parse(force)) + return false; + if (!marks || !MarksChanged()) { + return false; + } + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDRCutmarksIT::timeshift, timeshiftActive); + int numMarks = marks->Count(); + vector cutmarksInfo; + cutmarksInfo.push_back(numMarks); + tokenContainer->CreateLoopTokenContainer(&cutmarksInfo); + cString tot = cString::sprintf("%d", total); + cString timeshifttot = cString::sprintf("%d",timeshiftTotal); + int i = 0; + bool isStartMark = true; + for (const cMark *m = marks->First(); m; m = marks->Next(m)) { + tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::position, *cString::sprintf("%d", m->Position())); + tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::total, *tot); + if (timeshiftActive) { + tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::timeshifttotal, *timeshifttot); + } + tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::startmark, isStartMark ? "1" : "0"); + tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::active, (m->Position() == current) ? "1" : "0"); + const cMark *m2 = marks->Next(m); + if (m2) { + tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::endposition, *cString::sprintf("%d", m2->Position())); + } else { + tokenContainer->AddLoopToken(cutmarksIndex, i, (int)eDRCutmarksLT::endposition, *tot); + } + i++; + isStartMark = !isStartMark; + } + SetDirty(); + return true; +} + +bool cVeDrCutMarks::MarksChanged(void) { + bool redraw = false; + //if mark was active, we redraw always + if (markActive >= 0) { + markActive = -1; + redraw = true; + } + //check if current position in recording hits mark exactly + for (const cMark *m = marks->First(); m; m = marks->Next(m)) { + if (m->Position() == current) { + markActive = current; + redraw = true; + break; + } + } + if (redraw) + return true; + //if number of marks has changed, redraw + int numMarks = marks->Count(); + if (numMarks != numMarksLast) { + RememberMarks(); + return true; + } + if (!lastMarks) + return false; + //if position has changed, redraw + int i=0; + for (const cMark *m = marks->First(); m; m = marks->Next(m)) { + if (m->Position() != lastMarks[i]) { + RememberMarks(); + return true; + } + i++; + } + return false; +} + +void cVeDrCutMarks::RememberMarks(void) { + if (!marks) + return; + numMarksLast = marks->Count(); + if (numMarksLast < 1) + return; + delete[] lastMarks; + lastMarks = new int[numMarksLast]; + int i=0; + for (const cMark *m = marks->First(); m; m = marks->Next(m)) { + lastMarks[i] = m->Position(); + i++; + } +} + +/****************************************************************** +* cVeDrControlIcons +******************************************************************/ +cVeDrControlIcons::cVeDrControlIcons(void) { + play = false; + forward = false; + speed = 0; + changed = true; +} + +cVeDrControlIcons::~cVeDrControlIcons(void) { +} + +void cVeDrControlIcons::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{play}", (int)eDRControlIconsIT::play); + tokenContainer->DefineIntToken("{pause}", (int)eDRControlIconsIT::pause); + tokenContainer->DefineIntToken("{forward}", (int)eDRControlIconsIT::forward); + tokenContainer->DefineIntToken("{forward1x}", (int)eDRControlIconsIT::forward1x); + tokenContainer->DefineIntToken("{forward2x}", (int)eDRControlIconsIT::forward2x); + tokenContainer->DefineIntToken("{forward3x}", (int)eDRControlIconsIT::forward3x); + tokenContainer->DefineIntToken("{rewind}", (int)eDRControlIconsIT::rewind); + tokenContainer->DefineIntToken("{rewind1x}", (int)eDRControlIconsIT::rewind1x); + tokenContainer->DefineIntToken("{rewind2x}", (int)eDRControlIconsIT::rewind2x); + tokenContainer->DefineIntToken("{rewind3x}", (int)eDRControlIconsIT::rewind3x); + InheritTokenContainer(); +} + +void cVeDrControlIcons::Set(bool play, bool forward, int speed) { + this->play = play; + this->forward = forward; + this->speed = speed; + changed = true; +} + +bool cVeDrControlIcons::Parse(bool force) { + if (!cViewElement::Parse(force) || !changed) + return false; + + bool isPlay = false; + bool isPause = false; + bool isFF = false; + bool isFF1x = false; + bool isFF2x = false; + bool isFF3x = false; + bool isRew = false; + bool isRew1x = false; + bool isRew2x = false; + bool isRew3x = false; + + if (speed == -1) { + if (play) { + isPlay = true; + } else { + isPause = true; + } + } else if (forward) { + if (!play) { + isPause = true; + } + if (speed == 1) { + isFF1x = true; + } else if (speed == 2) { + isFF2x = true; + } else if (speed == 3) { + isFF3x = true; + } else { + isFF = true; + } + } else { + if (!play) { + isPause = true; + } + if (speed == 1) { + isRew1x = true; + } else if (speed == 2) { + isRew2x = true; + } else if (speed == 3) { + isRew3x = true; + } else { + isRew = true; + } + } + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDRControlIconsIT::play, isPlay); + tokenContainer->AddIntToken((int)eDRControlIconsIT::pause, isPause); + tokenContainer->AddIntToken((int)eDRControlIconsIT::forward, isFF); + tokenContainer->AddIntToken((int)eDRControlIconsIT::forward1x, isFF1x); + tokenContainer->AddIntToken((int)eDRControlIconsIT::forward2x, isFF2x); + tokenContainer->AddIntToken((int)eDRControlIconsIT::forward3x, isFF3x); + tokenContainer->AddIntToken((int)eDRControlIconsIT::rewind, isRew); + tokenContainer->AddIntToken((int)eDRControlIconsIT::rewind1x, isRew1x); + tokenContainer->AddIntToken((int)eDRControlIconsIT::rewind2x, isRew2x); + tokenContainer->AddIntToken((int)eDRControlIconsIT::rewind3x, isRew3x); + SetDirty(); + changed = false; + return true; +} + +/****************************************************************** +* cVeDrProgressModeonly +******************************************************************/ +cVeDrProgressModeonly::cVeDrProgressModeonly(void) { + fps = 0.0f; + current = 0; + total = 0; + changed = true; +} + +cVeDrProgressModeonly::~cVeDrProgressModeonly(void) { +} + +void cVeDrProgressModeonly::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{current}", (int)eDRProgressModeonlyIT::current); + tokenContainer->DefineIntToken("{total}", (int)eDRProgressModeonlyIT::total); + tokenContainer->DefineStringToken("{timecurrent}", (int)eDRProgressModeonlyST::timecurrent); + tokenContainer->DefineStringToken("{timetotal}", (int)eDRProgressModeonlyST::timetotal); + InheritTokenContainer(); +} + +void cVeDrProgressModeonly::Set(double fps, int current, int total) { + if (this->current == current) + return; + this->fps = fps; + this->current = current; + this->total = total; + changed = true; +} + +bool cVeDrProgressModeonly::Parse(bool force) { + if (!cViewElement::Parse(force) || !changed) + return false; + + string cur = GetTimeString((double)current / fps); + string tot = GetTimeString((double)total / fps); + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDRProgressModeonlyIT::current, current); + tokenContainer->AddIntToken((int)eDRProgressModeonlyIT::total, total); + tokenContainer->AddStringToken((int)eDRProgressModeonlyST::timecurrent, cur.c_str()); + tokenContainer->AddStringToken((int)eDRProgressModeonlyST::timetotal, tot.c_str()); + + SetDirty(); + changed = false; + return true; +} + +/****************************************************************** +* cVeDrJump +******************************************************************/ +cVeDrJump::cVeDrJump(void) { + jump = NULL; + changed = false; +} + +cVeDrJump::~cVeDrJump(void) { + free(jump); +} + +void cVeDrJump::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{jump}", (int)eDRJumpST::jump); + InheritTokenContainer(); +} + +void cVeDrJump::Set(const char *jump) { + if (!jump) + return; + free(this->jump); + this->jump = strdup(jump); + changed = true; +} + +bool cVeDrJump::Parse(bool force) { + if (!cViewElement::Parse(force) || !changed) + return false; + + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDRJumpST::jump, jump); + changed = false; + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDrOnPause +******************************************************************/ +cVeDrOnPause::cVeDrOnPause(void) { + actorsIndex = -1; + recfilename = NULL; +} + +cVeDrOnPause::~cVeDrOnPause(void) { + free(recfilename); +} + +void cVeDrOnPause::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{name}", (int)eDROnpauseST::name); + tokenContainer->DefineStringToken("{shorttext}", (int)eDROnpauseST::shorttext); + tokenContainer->DefineStringToken("{description}", (int)eDROnpauseST::description); + tokenContainer->DefineStringToken("{date}", (int)eDROnpauseST::date); + tokenContainer->DefineStringToken("{time}", (int)eDROnpauseST::time); + tokenContainer->DefineStringToken("{durationminutes}", (int)eDROnpauseST::durationminutes); + tokenContainer->DefineStringToken("{durationeventminutes}", (int)eDROnpauseST::durationeventminutes); + tokenContainer->DefineIntToken("{daynumeric}", (int)eDROnpauseIT::daynumeric); + tokenContainer->DefineIntToken("{month}", (int)eDROnpauseIT::month); + tokenContainer->DefineIntToken("{year}", (int)eDROnpauseIT::year); + tokenContainer->DefineIntToken("{duration}", (int)eDROnpauseIT::duration); + tokenContainer->DefineIntToken("{durationhours}", (int)eDROnpauseIT::durationhours); + tokenContainer->DefineIntToken("{durationevent}", (int)eDROnpauseIT::durationevent); + tokenContainer->DefineIntToken("{durationeventhours}", (int)eDROnpauseIT::durationeventhours); + tokenContainer->DefineStringToken("{movietitle}", (int)eScraperST::movietitle); + tokenContainer->DefineStringToken("{movieoriginalTitle}", (int)eScraperST::movieoriginalTitle); + tokenContainer->DefineStringToken("{movietagline}", (int)eScraperST::movietagline); + tokenContainer->DefineStringToken("{movieoverview}", (int)eScraperST::movieoverview); + tokenContainer->DefineStringToken("{moviegenres}", (int)eScraperST::moviegenres); + tokenContainer->DefineStringToken("{moviehomepage}", (int)eScraperST::moviehomepage); + tokenContainer->DefineStringToken("{moviereleasedate}", (int)eScraperST::moviereleasedate); + tokenContainer->DefineStringToken("{moviepopularity}", (int)eScraperST::moviepopularity); + tokenContainer->DefineStringToken("{movievoteaverage}", (int)eScraperST::movievoteaverage); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperST::posterpath); + tokenContainer->DefineStringToken("{fanartpath}", (int)eScraperST::fanartpath); + tokenContainer->DefineStringToken("{moviecollectionName}", (int)eScraperST::moviecollectionName); + tokenContainer->DefineStringToken("{collectionposterpath}", (int)eScraperST::collectionposterpath); + tokenContainer->DefineStringToken("{collectionfanartpath}", (int)eScraperST::collectionfanartpath); + tokenContainer->DefineStringToken("{seriesname}", (int)eScraperST::seriesname); + tokenContainer->DefineStringToken("{seriesoverview}", (int)eScraperST::seriesoverview); + tokenContainer->DefineStringToken("{seriesfirstaired}", (int)eScraperST::seriesfirstaired); + tokenContainer->DefineStringToken("{seriesnetwork}", (int)eScraperST::seriesnetwork); + tokenContainer->DefineStringToken("{seriesgenre}", (int)eScraperST::seriesgenre); + tokenContainer->DefineStringToken("{seriesrating}", (int)eScraperST::seriesrating); + tokenContainer->DefineStringToken("{seriesstatus}", (int)eScraperST::seriesstatus); + tokenContainer->DefineStringToken("{episodetitle}", (int)eScraperST::episodetitle); + tokenContainer->DefineStringToken("{episodefirstaired}", (int)eScraperST::episodefirstaired); + tokenContainer->DefineStringToken("{episodegueststars}", (int)eScraperST::episodegueststars); + tokenContainer->DefineStringToken("{episodeoverview}", (int)eScraperST::episodeoverview); + tokenContainer->DefineStringToken("{episoderating}", (int)eScraperST::episoderating); + tokenContainer->DefineStringToken("{episodeimagepath}", (int)eScraperST::episodeimagepath); + tokenContainer->DefineStringToken("{seasonposterpath}", (int)eScraperST::seasonposterpath); + tokenContainer->DefineStringToken("{seriesposter1path}", (int)eScraperST::seriesposter1path); + tokenContainer->DefineStringToken("{seriesposter2path}", (int)eScraperST::seriesposter2path); + tokenContainer->DefineStringToken("{seriesposter3path}", (int)eScraperST::seriesposter3path); + tokenContainer->DefineStringToken("{seriesfanart1path}", (int)eScraperST::seriesfanart1path); + tokenContainer->DefineStringToken("{seriesfanart2path}", (int)eScraperST::seriesfanart2path); + tokenContainer->DefineStringToken("{seriesfanart3path}", (int)eScraperST::seriesfanart3path); + tokenContainer->DefineStringToken("{seriesbanner1path}", (int)eScraperST::seriesbanner1path); + tokenContainer->DefineStringToken("{seriesbanner2path}", (int)eScraperST::seriesbanner2path); + tokenContainer->DefineStringToken("{seriesbanner3path}", (int)eScraperST::seriesbanner3path); + tokenContainer->DefineIntToken("{ismovie}", (int)eScraperIT::ismovie); + tokenContainer->DefineIntToken("{moviebudget}", (int)eScraperIT::moviebudget); + tokenContainer->DefineIntToken("{movierevenue}", (int)eScraperIT::movierevenue); + tokenContainer->DefineIntToken("{movieadult}", (int)eScraperIT::movieadult); + tokenContainer->DefineIntToken("{movieruntime}", (int)eScraperIT::movieruntime); + tokenContainer->DefineIntToken("{isseries}", (int)eScraperIT::isseries); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperIT::posterheight); + tokenContainer->DefineIntToken("{fanartwidth}", (int)eScraperIT::fanartwidth); + tokenContainer->DefineIntToken("{fanartheight}", (int)eScraperIT::fanartheight); + tokenContainer->DefineIntToken("{movieiscollection}", (int)eScraperIT::movieiscollection); + tokenContainer->DefineIntToken("{collectionposterwidth}", (int)eScraperIT::collectionposterwidth); + tokenContainer->DefineIntToken("{collectionposterheight}", (int)eScraperIT::collectionposterheight); + tokenContainer->DefineIntToken("{collectionfanartwidth}", (int)eScraperIT::collectionfanartwidth); + tokenContainer->DefineIntToken("{collectionfanartheight}", (int)eScraperIT::collectionfanartheight); + tokenContainer->DefineIntToken("{epgpicavailable}", (int)eScraperIT::epgpicavailable); + tokenContainer->DefineIntToken("{episodenumber}", (int)eScraperIT::episodenumber); + tokenContainer->DefineIntToken("{episodeseason}", (int)eScraperIT::episodeseason); + tokenContainer->DefineIntToken("{episodeimagewidth}", (int)eScraperIT::episodeimagewidth); + tokenContainer->DefineIntToken("{episodeimageheight}", (int)eScraperIT::episodeimageheight); + tokenContainer->DefineIntToken("{seasonposterwidth}", (int)eScraperIT::seasonposterwidth); + tokenContainer->DefineIntToken("{seasonposterheight}", (int)eScraperIT::seasonposterheight); + tokenContainer->DefineIntToken("{seriesposter1width}", (int)eScraperIT::seriesposter1width); + tokenContainer->DefineIntToken("{seriesposter1height}", (int)eScraperIT::seriesposter1height); + tokenContainer->DefineIntToken("{seriesposter2width}", (int)eScraperIT::seriesposter2width); + tokenContainer->DefineIntToken("{seriesposter2height}", (int)eScraperIT::seriesposter2height); + tokenContainer->DefineIntToken("{seriesposter3width}", (int)eScraperIT::seriesposter3width); + tokenContainer->DefineIntToken("{seriesposter3height}", (int)eScraperIT::seriesposter3height); + tokenContainer->DefineIntToken("{seriesfanart1width}", (int)eScraperIT::seriesfanart1width); + tokenContainer->DefineIntToken("{seriesfanart1height}", (int)eScraperIT::seriesfanart1height); + tokenContainer->DefineIntToken("{seriesfanart2width}", (int)eScraperIT::seriesfanart2width); + tokenContainer->DefineIntToken("{seriesfanart2height}", (int)eScraperIT::seriesfanart2height); + tokenContainer->DefineIntToken("{seriesfanart3width}", (int)eScraperIT::seriesfanart3width); + tokenContainer->DefineIntToken("{seriesfanart3height}", (int)eScraperIT::seriesfanart3height); + tokenContainer->DefineIntToken("{seriesbanner1width}", (int)eScraperIT::seriesbanner1width); + tokenContainer->DefineIntToken("{seriesbanner1height}", (int)eScraperIT::seriesbanner1height); + tokenContainer->DefineIntToken("{seriesbanner2width}", (int)eScraperIT::seriesbanner2width); + tokenContainer->DefineIntToken("{seriesbanner2height}", (int)eScraperIT::seriesbanner2height); + tokenContainer->DefineIntToken("{seriesbanner3width}", (int)eScraperIT::seriesbanner3width); + tokenContainer->DefineIntToken("{seriesbanner3height}", (int)eScraperIT::seriesbanner3height); + tokenContainer->DefineLoopToken("{actors[name]}", (int)eScraperLT::name); + tokenContainer->DefineLoopToken("{actors[role]}", (int)eScraperLT::role); + tokenContainer->DefineLoopToken("{actors[thumb]}", (int)eScraperLT::thumb); + tokenContainer->DefineLoopToken("{actors[thumbwidth]}", (int)eScraperLT::thumbwidth); + tokenContainer->DefineLoopToken("{actors[thumbheight]}", (int)eScraperLT::thumbheight); + actorsIndex = tokenContainer->LoopIndex("actors"); + InheritTokenContainer(); +} + +void cVeDrOnPause::Set(const char *recfilename) { + if (!recfilename) + return; + free(this->recfilename); + this->recfilename = strdup(recfilename); +} + +bool cVeDrOnPause::Parse(bool force) { + if (!cViewElement::Parse(force)) + return false; + if (!recfilename) + return false; + const cRecording *recording = new cRecording(recfilename); + if (!recording) + return false; + tokenContainer->Clear(); + tokenContainer->AddStringToken((int)eDROnpauseST::name, recording->Name()); + const cRecordingInfo *info = recording->Info(); + if (info) { + tokenContainer->AddStringToken((int)eDROnpauseST::shorttext, info->ShortText()); + tokenContainer->AddStringToken((int)eDROnpauseST::description, info->Description()); + const cEvent *event = info->GetEvent(); + if (event) { + string recDate = *(event->GetDateString()); + string recTime = *(event->GetTimeString()); + if (recDate.find("1970") != string::npos) { + time_t start = recording->Start(); + recDate = *DateString(start); + recTime = *TimeString(start); + } + tokenContainer->AddStringToken((int)eDROnpauseST::date, recDate.c_str()); + tokenContainer->AddStringToken((int)eDROnpauseST::time, recTime.c_str()); + time_t startTime = event->StartTime(); + struct tm * sStartTime = localtime(&startTime); + tokenContainer->AddIntToken((int)eDROnpauseIT::year, sStartTime->tm_year + 1900); + tokenContainer->AddIntToken((int)eDROnpauseIT::daynumeric, sStartTime->tm_mday); + tokenContainer->AddIntToken((int)eDROnpauseIT::month, sStartTime->tm_mon+1); + int duration = event->Duration() / 60; + int recDuration = recording->LengthInSeconds(); + recDuration = (recDuration>0)?(recDuration / 60):0; + tokenContainer->AddIntToken((int)eDROnpauseIT::duration, recDuration); + tokenContainer->AddIntToken((int)eDROnpauseIT::durationhours, recDuration / 60); + tokenContainer->AddStringToken((int)eDROnpauseST::durationminutes, *cString::sprintf("%.2d", recDuration%60)); + tokenContainer->AddIntToken((int)eDROnpauseIT::durationevent, duration); + tokenContainer->AddIntToken((int)eDROnpauseIT::durationeventhours, duration / 60); + tokenContainer->AddStringToken((int)eDROnpauseST::durationeventminutes, *cString::sprintf("%.2d", duration%60)); + } + } + + vector loopInfo; + bool scrapInfoAvailable = LoadFullScrapInfo(NULL, recording); + int numActors = NumActors(); + loopInfo.push_back(numActors); + tokenContainer->CreateLoopTokenContainer(&loopInfo); + if (scrapInfoAvailable) { + SetFullScrapInfo(tokenContainer, actorsIndex); + } + + SetDirty(); + delete recording; + return true; +} + +/****************************************************************** +* cVeDrScraperContent +******************************************************************/ +cVeDrScraperContent::cVeDrScraperContent(void) { + recording = NULL; +} + +cVeDrScraperContent::~cVeDrScraperContent(void) { +} + +void cVeDrScraperContent::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineStringToken("{posterpath}", (int)eScraperPosterBannerST::posterpath); + tokenContainer->DefineStringToken("{bannerpath}", (int)eScraperPosterBannerST::bannerpath); + tokenContainer->DefineStringToken("{mediapath}", (int)eScraperPosterBannerST::mediapath); + tokenContainer->DefineIntToken("{posterwidth}", (int)eScraperPosterBannerIT::posterwidth); + tokenContainer->DefineIntToken("{posterheight}", (int)eScraperPosterBannerIT::posterheight); + tokenContainer->DefineIntToken("{hasPoster}", (int)eScraperPosterBannerIT::hasposter); + tokenContainer->DefineIntToken("{bannerwidth}", (int)eScraperPosterBannerIT::bannerwidth); + tokenContainer->DefineIntToken("{bannerheight}", (int)eScraperPosterBannerIT::bannerheight); + tokenContainer->DefineIntToken("{hasBanner}", (int)eScraperPosterBannerIT::hasbanner); + tokenContainer->DefineIntToken("{mediawidth}", (int)eScraperPosterBannerIT::mediawidth); + tokenContainer->DefineIntToken("{mediaheight}", (int)eScraperPosterBannerIT::mediaheight); + tokenContainer->DefineIntToken("{isbanner}", (int)eScraperPosterBannerIT::isbanner); + InheritTokenContainer(); +} + +void cVeDrScraperContent::Set(const cRecording *recording) { + this->recording = recording; +} + +bool cVeDrScraperContent::Parse(bool force) { + if (!cViewElement::Parse(force)) + return false; + if (!recording) + return false; + SetPosterBanner(tokenContainer, NULL, recording); + SetDirty(); + return true; +} diff --git a/coreengine/viewelementsdisplayreplay.h b/coreengine/viewelementsdisplayreplay.h new file mode 100644 index 0000000..fc25655 --- /dev/null +++ b/coreengine/viewelementsdisplayreplay.h @@ -0,0 +1,206 @@ +#ifndef __VIEWELEMENTSDR_H +#define __VIEWELEMENTSDR_H + +#include "viewelement.h" +#include "../extensions/scrapmanager.h" + +/****************************************************************** +* cVeDrRecTitle +******************************************************************/ +class cVeDrRecTitle : public cViewElement { +private: + const cRecording *recording; + char *title; +public: + cVeDrRecTitle(void); + virtual ~cVeDrRecTitle(void); + void SetTokenContainer(void); + void Set(const cRecording *recording); + void Set(const char *title); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrRecInfo +******************************************************************/ +class cVeDrRecInfo : public cViewElement { +private: + const cRecording *recording; +public: + cVeDrRecInfo(void); + virtual ~cVeDrRecInfo(void); + void SetTokenContainer(void); + void Set(const cRecording *recording); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrCurrentTime +******************************************************************/ +class cVeDrCurrentTime : public cViewElement { +private: + bool changed; + char *current; +public: + cVeDrCurrentTime(void); + virtual ~cVeDrCurrentTime(void); + void SetTokenContainer(void); + void Set(const char *current); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrTotalTime +******************************************************************/ +class cVeDrTotalTime : public cViewElement { +private: + bool changed; + char *total; + bool timeshiftActive; + char *timeshiftDuration; +public: + cVeDrTotalTime(void); + virtual ~cVeDrTotalTime(void); + void SetTokenContainer(void); + void Set(const char *total, bool timeshiftActive, const char *timeshiftDuration); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrEndTime +******************************************************************/ +class cVeDrEndTime : public cViewElement { +private: + cString end; + bool changed; +public: + cVeDrEndTime(void); + virtual ~cVeDrEndTime(void); + void SetTokenContainer(void); + void Set(cString end); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrProgressBar +******************************************************************/ +class cVeDrProgressBar : public cViewElement { +private: + int current; + int total; + bool timeshiftActive; + int timeshiftTotal; + bool changed; +public: + cVeDrProgressBar(void); + virtual ~cVeDrProgressBar(void); + void SetTokenContainer(void); + void Set(int current, int total, bool timeshiftActive, int timeshiftTotal); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrCutMarks +******************************************************************/ +class cVeDrCutMarks : public cViewElement { +private: + int cutmarksIndex; + const cMarks *marks; + int current; + int total; + bool timeshiftActive; + int timeshiftTotal; + int numMarksLast; + int *lastMarks; + int markActive; + bool MarksChanged(void); + void RememberMarks(void); +public: + cVeDrCutMarks(void); + virtual ~cVeDrCutMarks(void); + void SetTokenContainer(void); + void Set(const cMarks *marks, int current, int total, bool timeshiftActive, int timeshiftTotal); + void Reset(void); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrControlIcons +******************************************************************/ +class cVeDrControlIcons : public cViewElement { +private: + bool play; + bool forward; + int speed; + bool changed; +public: + cVeDrControlIcons(void); + virtual ~cVeDrControlIcons(void); + void SetTokenContainer(void); + void Set(bool play, bool forward, int speed); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrProgressModeonly +******************************************************************/ +class cVeDrProgressModeonly : public cViewElement { +private: + double fps; + int current; + int total; + bool changed; +public: + cVeDrProgressModeonly(void); + virtual ~cVeDrProgressModeonly(void); + void SetTokenContainer(void); + void Set(double fps, int current, int total); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrJump +******************************************************************/ +class cVeDrJump : public cViewElement { +private: + char *jump; + bool changed; +public: + cVeDrJump(void); + virtual ~cVeDrJump(void); + void SetTokenContainer(void); + void Set(const char *jump); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrOnPause +******************************************************************/ +class cVeDrOnPause : public cViewElement, public cScrapManager { +private: + int actorsIndex; + char *recfilename; +public: + cVeDrOnPause(void); + virtual ~cVeDrOnPause(void); + int Delay(void) { return attribs->Delay() * 1000; }; + void SetTokenContainer(void); + void Set(const char *recfilename); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDrScraperContent +******************************************************************/ +class cVeDrScraperContent : public cViewElement, public cScrapManager { +private: + const cRecording *recording; +public: + cVeDrScraperContent(void); + virtual ~cVeDrScraperContent(void); + void SetTokenContainer(void); + void Set(const cRecording *recording); + bool Parse(bool forced = false); +}; + +#endif //__VIEWELEMENTSDR_H \ No newline at end of file diff --git a/coreengine/viewelementsdisplaytracks.c b/coreengine/viewelementsdisplaytracks.c new file mode 100644 index 0000000..d5ef124 --- /dev/null +++ b/coreengine/viewelementsdisplaytracks.c @@ -0,0 +1,84 @@ +#include "viewelementsdisplaytracks.h" + +/****************************************************************** +* cVeDtBackground +******************************************************************/ +cVeDtBackground::cVeDtBackground(void) { + numTracks = 0; +} + +cVeDtBackground::~cVeDtBackground(void) { +} + +void cVeDtBackground::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{numtracks}", (int)eDTBackgroundIT::numtracks); + InheritTokenContainer(); +} + +void cVeDtBackground::Set(int numTracks) { + this->numTracks = numTracks; +} + +bool cVeDtBackground::Parse(bool forced) { + if (!cViewElement::Parse(forced)) + return false; + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDTBackgroundIT::numtracks, numTracks); + SetDirty(); + return true; +} + +/****************************************************************** +* cVeDtHeader +******************************************************************/ +cVeDtHeader::cVeDtHeader(void) { + title = NULL; + audioChannel = 0; + numTracks = 0; + changed = true; +} + +cVeDtHeader::~cVeDtHeader(void) { + free(title); +} + +void cVeDtHeader::SetTokenContainer(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{numtracks}", (int)eDTHeaderIT::numtracks); + tokenContainer->DefineIntToken("{isstereo}", (int)eDTHeaderIT::isstereo); + tokenContainer->DefineIntToken("{isac3}", (int)eDTHeaderIT::isac3); + tokenContainer->DefineStringToken("{title}", (int)eDTHeaderST::title); + InheritTokenContainer(); +} + +void cVeDtHeader::SetTitle(const char *title) { + if (!title) + return; + free(this->title); + this->title = strdup(title); + changed = true; +} + +void cVeDtHeader::SetNumtracks(int numTracks) { + this->numTracks = numTracks; + changed = true; +} + +void cVeDtHeader::SetAudiochannel(int audioChannel) { + this->audioChannel = audioChannel; + changed = true; +} + +bool cVeDtHeader::Parse(bool forced) { + if (!cViewElement::Parse(forced) || !changed) + return false; + + tokenContainer->Clear(); + tokenContainer->AddIntToken((int)eDTHeaderIT::numtracks, numTracks); + tokenContainer->AddIntToken((int)eDTHeaderIT::isstereo, (audioChannel < 0) ? false : true); + tokenContainer->AddIntToken((int)eDTHeaderIT::isac3, (audioChannel < 0) ? true : false); + tokenContainer->AddStringToken((int)eDTHeaderST::title, title); + SetDirty(); + return true; +} \ No newline at end of file diff --git a/coreengine/viewelementsdisplaytracks.h b/coreengine/viewelementsdisplaytracks.h new file mode 100644 index 0000000..7529855 --- /dev/null +++ b/coreengine/viewelementsdisplaytracks.h @@ -0,0 +1,40 @@ +#ifndef __VIEWELEMENTSDT_H +#define __VIEWELEMENTSDT_H + +#include +#include "viewelement.h" + +/****************************************************************** +* cVeDtBackground +******************************************************************/ +class cVeDtBackground : public cViewElement { +private: + int numTracks; +public: + cVeDtBackground(void); + virtual ~cVeDtBackground(void); + void SetTokenContainer(void); + void Set(int numTracks); + bool Parse(bool forced = false); +}; + +/****************************************************************** +* cVeDtHeader +******************************************************************/ +class cVeDtHeader : public cViewElement { +private: + char *title; + int audioChannel; + int numTracks; + bool changed; +public: + cVeDtHeader(void); + virtual ~cVeDtHeader(void); + void SetTokenContainer(void); + void SetTitle(const char *title); + void SetNumtracks(int numTracks); + void SetAudiochannel(int audioChannel); + bool Parse(bool forced = false); +}; + +#endif //__VIEWELEMENTSDT_H \ No newline at end of file diff --git a/coreengine/viewgrid.c b/coreengine/viewgrid.c new file mode 100644 index 0000000..6f28ef4 --- /dev/null +++ b/coreengine/viewgrid.c @@ -0,0 +1,188 @@ +#include "viewgrid.h" +#include "../extensions/helpers.h" + +cViewGrid::cViewGrid(void) { + id = -1; + plugId = -1; + viewId = -1; + globals = NULL; + attribs = new cViewElementAttribs((int)eViewElementAttribs::count); + gridTpl = NULL; + gridsize = GRIDSIZE; + grid = new cGridElement*[gridsize]; + for (int i=0; i < gridsize; i++) { + grid[i] = NULL; + } + gridMin = 0; + gridMax = -1; +} + +cViewGrid::~cViewGrid(void) { + delete attribs; + delete gridTpl; +} + +void cViewGrid::SetGlobals(cGlobals *globals) { + this->globals = globals; +} + +void cViewGrid::SetContainer(int x, int y, int width, int height) { + container.SetX(x); + container.SetY(y); + container.SetWidth(width); + container.SetHeight(height); +} + +void cViewGrid::SetAttributes(vector &attributes) { + attribs->Set(attributes); +} + +void cViewGrid::AddGridElement(cGridElement *gridElement) { + gridTpl = gridElement; +} + +const char *cViewGrid::Name(void) { + return attribs->Name(); +} + +void cViewGrid::SetTokenContainer(void) { + if (!gridTpl) + return; + gridTpl->SetId(id); + gridTpl->SetPluginId(plugId); + gridTpl->SetViewId(viewId); + gridTpl->SetTokenContainer(); +} + +void cViewGrid::PreCache(void) { + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->SetGlobals(globals); + attribs->Cache(); + gridTpl->SetGlobals(globals); + gridTpl->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + gridTpl->Cache(); + +} + +void cViewGrid::CheckSize(int id) { + if (id < gridsize) + return; + int newgridsize = gridsize + GRIDSIZE; + while (newgridsize < id) + newgridsize += gridsize; + cGridElement **gridNew = new cGridElement*[newgridsize]; + int i=0; + bool foundFirst = false; + for (; i < gridsize; i++) { + if (!foundFirst && grid[i]) { + foundFirst = true; + gridMin = i; + } + gridNew[i] = grid[i]; + } + gridsize = newgridsize; + for (; i < gridsize; i++) { + gridNew[i] = NULL; + } + delete[] grid; + grid = gridNew; +} + +void cViewGrid::SetTokens(int gId, skindesignerapi::cTokenContainer *tk) { + if (!grid[gId]) { + return; + } + grid[gId]->Set(tk); +} + +void cViewGrid::PositionGrid(int gId, double x, double y, double width, double height) { + int gridX = attribs->X() + x * attribs->Width(); + int gridY = attribs->Y() + y * attribs->Height(); + int gridWidth = width * attribs->Width(); + int gridHeight = height * attribs->Height(); + if (!grid[gId]) { + if (gId >= gridMax) + gridMax = gId+1; + grid[gId] = CreateGrid(gridX, gridY, gridWidth, gridHeight); + } else { + if (grid[gId]->Width() == gridWidth && grid[gId]->Height() == gridHeight) { + grid[gId]->SetPosition(gridX, gridY, gridWidth, gridHeight); + } else { + cGridElement *ge = CreateGrid(gridX, gridY, gridWidth, gridHeight); + ge->Set(grid[gId]->GetTokenContainer()); + grid[gId]->Close(); + delete grid[gId]; + grid[gId] = ge; + } + grid[gId]->SetDirty(); + } +} + +void cViewGrid::SetCurrentGrid(int gId, bool current) { + if (gId >= 0 && grid[gId]) { + grid[gId]->SetCurrent(current); + } +} + +void cViewGrid::DeleteGrid(int gId) { + if (!grid[gId]) + return; + grid[gId]->Close(); + delete grid[gId]; + grid[gId] = NULL; +} + +void cViewGrid::ClearGrids(void) { + for (int i = 0; i < gridsize; i++) { + if (!grid[i]) + continue; + grid[i]->Close(); + delete grid[i]; + grid[i] = NULL; + } +} + +void cViewGrid::Render(void) { + for (int i = gridMin; i < gridMax; i++) { + if (grid[i] && grid[i]->Parse()) { + grid[i]->Render(); + } + } +} + +cGridElement *cViewGrid::CreateGrid(int x, int y, int width, int height) { + cGridElement *ge = new cGridElement(*gridTpl); + ge->SetAreaX(x); + ge->SetAreaY(y); + ge->SetAreaWidth(width); + ge->SetAreaHeight(height); + return ge; +} + +void cViewGrid::Close(void) { + ClearGrids(); + gridsize = GRIDSIZE; + delete[] grid; + grid = new cGridElement*[gridsize]; + for (int i=0; i < gridsize; i++) { + grid[i] = NULL; + } + gridMin = 0; + gridMax = -1; +} + +void cViewGrid::Hide(void) { + for (int i = 0; i < gridsize; i++) { + if (grid[i]) { + grid[i]->Hide(); + } + } +} + +void cViewGrid::Show(void) { + for (int i = 0; i < gridsize; i++) { + if (grid[i]) { + grid[i]->Show(); + } + } +} diff --git a/coreengine/viewgrid.h b/coreengine/viewgrid.h new file mode 100644 index 0000000..1bcbd74 --- /dev/null +++ b/coreengine/viewgrid.h @@ -0,0 +1,47 @@ +#ifndef __VIEWGRID_H +#define __VIEWGRID_H + +#define GRIDSIZE 500 + +#include "gridelement.h" + +class cViewGrid { +protected: + cRect container; + cGlobals *globals; + cViewElementAttribs *attribs; + cGridElement *gridTpl; + int gridsize; + cGridElement **grid; + int gridMin; + int gridMax; + int id; + int viewId; + int plugId; + cGridElement *CreateGrid(int x, int y, int width, int height); +public: + cViewGrid(void); + virtual ~cViewGrid(void); + void SetGlobals(cGlobals *globals); + void SetContainer(int x, int y, int width, int height); + void SetAttributes(vector &attributes); + void SetId(int id) { this->id = id; }; + void SetPluginId(int plugId) { this->plugId = plugId; }; + void SetViewId(int viewId) { this->viewId = viewId; }; + void AddGridElement(cGridElement *gridElement); + const char *Name(void); + void SetTokenContainer(void); + void PreCache(void); + void CheckSize(int id); + void SetTokens(int gId, skindesignerapi::cTokenContainer *tk); + void PositionGrid(int gId, double x, double y, double width, double height); + void SetCurrentGrid(int gId, bool current); + void DeleteGrid(int gId); + void ClearGrids(void); + void Render(void); + void Close(void); + void Hide(void); + void Show(void); +}; + +#endif //__VIEWGRID_H \ No newline at end of file diff --git a/coreengine/viewlist.c b/coreengine/viewlist.c new file mode 100644 index 0000000..1d20eea --- /dev/null +++ b/coreengine/viewlist.c @@ -0,0 +1,899 @@ +#include "viewlist.h" + +cViewList::cViewList(void) { + globals = NULL; + attribs = new cViewListAttribs((int)eViewListAttribs::count); + numElements = 0; + listElement = NULL; + currentElement = NULL; + listElements = NULL; + plugId = -1; + plugMenuId = -1; +} + +cViewList::~cViewList(void) { + delete attribs; + delete listElement; + delete currentElement; + if (listElements) { + for (int i=0; i < numElements; ++i) { + if (listElements[i]) { + delete listElements[i]; + listElements[i] = NULL; + } + } + } + delete[] listElements; +} + +void cViewList::SetGlobals(cGlobals *globals) { + this->globals = globals; + if (listElement) + listElement->SetGlobals(globals); + if (currentElement) + currentElement->SetGlobals(globals); +} + +void cViewList::SetContainer(int x, int y, int width, int height) { + container.SetX(x); + container.SetY(y); + container.SetWidth(width); + container.SetHeight(height); +} + +void cViewList::SetAttributes(vector &attributes) { + attribs->Set(attributes); +} + +cViewList *cViewList::CreateViewList(const char *name) { + cViewList *l = NULL; + if (!strcmp(name, "menudefault")) + l = new cViewListDefault(); + else if (!strcmp(name, "menumain")) + l = new cViewListMain(); + else if (!strcmp(name, "menusetup")) + l = new cViewListMain(); + else if (!strcmp(name, "menuschedules")) + l = new cViewListSchedules(); + else if (!strcmp(name, "menutimers")) + l = new cViewListTimers(); + else if (!strcmp(name, "menuchannels")) + l = new cViewListChannels(); + else if (!strcmp(name, "menurecordings")) + l = new cViewListRecordings(); + else if (!strcmp(name, "displayaudiotracks")) + l = new cViewListAudioTracks(); + else if (startswith(name, "menuplugin")) + l = new cViewListPlugin(); + else + esyslog("skindesigner: unknown viewlist %s", name); + return l; +} + +cViewElement *cViewList::CreateListElement(const char *name) { + cViewElement *le = NULL; + if (!strcmp(name, "menudefault")) + le = new cLeMenuDefault(); + else if (!strcmp(name, "menumain")) + le = new cLeMenuMain(); + else if (!strcmp(name, "menusetup")) + le = new cLeMenuMain(); + else if (!strcmp(name, "menuschedules")) + le = new cLeMenuSchedules(); + else if (!strcmp(name, "menutimers")) + le = new cLeMenuTimers(); + else if (!strcmp(name, "menuchannels")) + le = new cLeMenuChannels(); + else if (!strcmp(name, "menurecordings")) + le = new cLeMenuRecordings(); + else if (!strcmp(name, "displayaudiotracks")) + le = new cLeAudioTracks(); + else if (startswith(name, "menuplugin")) + le = new cLeMenuPlugin(); + else + esyslog("skindesigner: unknown viewlist %s", name); + return le; +} + +cViewElement *cViewList::CreateCurrentElement(const char *name) { + cViewElement *ce = NULL; + if (!strcmp(name, "menumain")) + ce = new cCeMenuMain(); + else if (!strcmp(name, "menusetup")) + ce = new cCeMenuMain(); + else if (!strcmp(name, "menuschedules")) + ce = new cCeMenuSchedules(); + else if (!strcmp(name, "menutimers")) + ce = new cCeMenuTimers(); + else if (!strcmp(name, "menuchannels")) + ce = new cCeMenuChannels(); + else if (!strcmp(name, "menurecordings")) + ce = new cCeMenuRecordings(); + else if (startswith(name, "menuplugin")) + ce = new cCeMenuPlugin(); + else + esyslog("skindesigner: unknown viewlist %s", name); + return ce; +} + +void cViewList::AddListElement(cViewElement *listElement) { + this->listElement = listElement; + listElement->SetTokenContainer(); +} + +void cViewList::AddCurrentElement(cViewElement *currentElement) { + this->currentElement = currentElement; + currentElement->SetTokenContainer(); +} + +void cViewList::PreCache(void) { + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->SetGlobals(globals); + attribs->Cache(); + numElements = attribs->NumListElements(); + orientation = attribs->Orientation(); + eAlign align = attribs->Align(); + int x = attribs->X(); + int y = attribs->Y(); + int width = attribs->Width(); + int height = attribs->Height(); + + int step = 0; + if (orientation == eOrientation::vertical) { + step = height / numElements; + } else { + step = width / numElements; + } + + int start = 0; + if (align == eAlign::center) { + if (orientation == eOrientation::vertical) { + start = y + (height - numElements * step) / 2; + } else { + start = x + (width - numElements * step) / 2; + } + } else if (align == eAlign::bottom) { + start = y + height - numElements * step; + } else if (align == eAlign::right) { + start = x + width - numElements * step; + } + Prepare(start, step); +} + +int cViewList::NumItems(void) { + return numElements; +} + +eOrientation cViewList::Orientation(void) { + return attribs->Orientation(); +} + +void cViewList::Draw(eMenuCategory menuCat) { + int current = -1; + for (int i = 0; i < numElements; i++) { + listElements[i]->SetMenuCategory(menuCat); + if (listElements[i]->Parse()) { + listElements[i]->Render(); + if (listElements[i]->Current()) { + listElements[i]->RenderCurrent(); + current = i; + } + } + } + if (current >= 0 && listElements[current]) { + listElements[current]->WakeCurrent(); + } + +} + +void cViewList::Clear(void) { + if (!listElements) + return; + for (int i = 0; i < numElements; i++) { + listElements[i]->StopScrolling(); + listElements[i]->Clear(); + } +} + +void cViewList::Close(void) { + if (!listElements) + return; + for (int i = 0; i < numElements; i++) { + listElements[i]->StopScrolling(); + listElements[i]->Close(); + } +} + +void cViewList::SetTransparency(int transparency) { + for (int i = 0; i < numElements; i++) { + if (listElements[i]) { + listElements[i]->SetTransparency(transparency); + } + } +} + +void cViewList::Debug(void) { +} + +/****************************************************************** +* cViewListDefault +******************************************************************/ +cViewListDefault::cViewListDefault(void) { + listDefault = NULL; + colX = NULL; + colWidths = NULL; + avrgFontWidth = 0; + listFont = NULL; + plugName = NULL; +} + +cViewListDefault::~cViewListDefault(void) { + delete[] listDefault; + delete[] colX; + delete[] colWidths; +} + +void cViewListDefault::Prepare(int start, int step) { + if (!listElement) + return; + + cLeMenuDefault *tpl = dynamic_cast(listElement); + if (!tpl) return; + listDefault = new cLeMenuDefault*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listDefault[i] = new cLeMenuDefault(*tpl); + listElements[i] = listDefault[i]; + listDefault[i]->SetNumber(i); + listDefault[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listDefault[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listDefault[i]->SetAreaWidth(width); + } + listDefault[i]->SetContainer(x, y, width, height); + listDefault[i]->Cache(); + pos += step; + } + + //Setting average font width + avrgFontWidth = 20; + const char *determinateFont = attribs->DeterminateFont(); + if (!determinateFont) { + return; + } + cFunction *f = listDefault[0]->GetFunction(determinateFont); + if (!f) + return; + cFuncDrawText *fdt = dynamic_cast(f); + if (!fdt) { + return; + } + avrgFontWidth = fdt->AvrgFontWidth(); + listFont = fdt->GetFont(); + colX = new int[MAX_TABS]; + colWidths = new int[MAX_TABS]; + for (int i=0; i < MAX_TABS; i++) { + colX[i] = 0; + colWidths[i] = 0; + } + for (int i = 0; i < numElements; i++) { + listDefault[i]->SetListInfo(colX, colWidths); + } +} + +void cViewListDefault::SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5) { + int itemWidth = attribs->MenuItemWidth(); + if (!tab1) { + colX[0] = 0; + colWidths[0] = itemWidth; + for (int i = 1; i < MAX_TABS; i++) { + colX[i] = 0; + colWidths[i] = 0; + } + } else { + colX[0] = 0; + colX[1] = tab1 ? colX[0] + tab1 : 0; + colX[2] = tab2 ? colX[1] + tab2 : 0; + colX[3] = tab3 ? colX[2] + tab3 : 0; + colX[4] = tab4 ? colX[3] + tab4 : 0; + colX[5] = tab5 ? colX[4] + tab5 : 0; + for (int i = 1; i < MAX_TABS; i++) + colX[i] *= avrgFontWidth; + + bool end = false; + for (int i = 0; i < MAX_TABS; i++) { + if ( i < MAX_TABS -1 && colX[i+1] > 0) { + colWidths[i] = colX[i+1] - colX[i]; + } else if (!end) { + end = true; + colWidths[i] = itemWidth - colX[i]; + } else { + colWidths[i] = 0; + } + } + } +} + +void cViewListDefault::Set(const char *text, int index, bool current, bool selectable) { + if (!current) + listDefault[index]->StopScrolling(); + listDefault[index]->SetCurrent(current); + listDefault[index]->SetSelectable(selectable); + listDefault[index]->SetPlugin(plugName); + listDefault[index]->SetText(text); +} + +const cFont *cViewListDefault::GetListFont(void) { + return listFont; +}; + +int cViewListDefault::GetListWidth(void) { + return attribs->MenuItemWidth(); +} + +/****************************************************************** +* cViewListMain +******************************************************************/ +cViewListMain::cViewListMain(void) { + listMain = NULL; + currentMain = NULL; +} + +cViewListMain::~cViewListMain(void) { + delete[] listMain; +} + +void cViewListMain::Prepare(int start, int step) { + if (!listElement) + return; + + cLeMenuMain *tpl = dynamic_cast(listElement); + if (!tpl) return; + + listMain = new cLeMenuMain*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listMain[i] = new cLeMenuMain(*tpl); + listElements[i] = listMain[i]; + listMain[i]->SetNumber(i); + listMain[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listMain[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listMain[i]->SetAreaWidth(width); + } + listMain[i]->SetContainer(x, y, width, height); + listMain[i]->Cache(); + pos += step; + } + + if (!currentElement) return; + currentMain = dynamic_cast(currentElement); + if (!currentMain) return; + + currentMain->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + currentMain->SetDetached(); + currentMain->Cache(); + for (int i = 0; i < numElements; i++) { + listMain[i]->SetCurrentElement(currentMain); + } +} + +void cViewListMain::Set(const char *text, int index, bool current, bool selectable) { + if (!current) + listMain[index]->StopScrolling(); + listMain[index]->SetCurrent(current); + listMain[index]->ClearCurrentElement(); + listMain[index]->SetSelectable(selectable); + listMain[index]->SetText(text); +} + +const char *cViewListMain::GetPlugin(void) { + for (int i = 0; i < numElements; i++) { + if (listMain[i] && listMain[i]->Current()) { + return listMain[i]->PluginName(); + } + } + return NULL; +} +/****************************************************************** +* cViewListSchedules +******************************************************************/ +cViewListSchedules::cViewListSchedules(void) { + listSchedules = NULL; + currentSchedules = NULL; + epgSearchFav = false; +} + +cViewListSchedules::~cViewListSchedules(void) { + delete[] listSchedules; +} + +void cViewListSchedules::Prepare(int start, int step) { + if (!listElement) + return; + + cLeMenuSchedules *tpl = dynamic_cast(listElement); + if (!tpl) return; + + listSchedules = new cLeMenuSchedules*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listSchedules[i] = new cLeMenuSchedules(*tpl); + listElements[i] = listSchedules[i]; + listSchedules[i]->SetNumber(i); + listSchedules[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listSchedules[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listSchedules[i]->SetAreaWidth(width); + } + listSchedules[i]->SetContainer(x, y, width, height); + listSchedules[i]->Cache(); + pos += step; + } + + if (!currentElement) return; + currentSchedules = dynamic_cast(currentElement); + if (!currentSchedules) return; + + currentSchedules->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + currentSchedules->SetDetached(); + currentSchedules->Cache(); + for (int i = 0; i < numElements; i++) { + listSchedules[i]->SetCurrentElement(currentSchedules); + } +} + +void cViewListSchedules::Set(const cEvent *event, int index, bool current, bool selectable, + const cChannel *channel, bool withDate, eTimerMatch timerMatch) { + if (!current) + listSchedules[index]->StopScrolling(); + listSchedules[index]->SetCurrent(current); + listSchedules[index]->ClearCurrentElement(); + listSchedules[index]->SetSelectable(selectable); + listSchedules[index]->SetEpgSearchFav(epgSearchFav); + listSchedules[index]->Set(event, channel, withDate, timerMatch); +} + +/****************************************************************** +* cViewListTimers +******************************************************************/ +cViewListTimers::cViewListTimers(void) { + listTimers = NULL; + currentTimer = NULL; +} + +cViewListTimers::~cViewListTimers(void) { + delete[] listTimers; +} + +void cViewListTimers::Prepare(int start, int step) { + if (!listElement) + return; + + cLeMenuTimers *tpl = dynamic_cast(listElement); + if (!tpl) return; + + listTimers = new cLeMenuTimers*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listTimers[i] = new cLeMenuTimers(*tpl); + listElements[i] = listTimers[i]; + listTimers[i]->SetNumber(i); + listTimers[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listTimers[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listTimers[i]->SetAreaWidth(width); + } + listTimers[i]->SetContainer(x, y, width, height); + listTimers[i]->Cache(); + pos += step; + } + + if (!currentElement) return; + currentTimer = dynamic_cast(currentElement); + if (!currentTimer) return; + + currentTimer->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + currentTimer->SetDetached(); + currentTimer->Cache(); + for (int i = 0; i < numElements; i++) { + listTimers[i]->SetCurrentElement(currentTimer); + } +} + +void cViewListTimers::Set(const cTimer *timer, int index, bool current, bool selectable) { + if (!current) + listTimers[index]->StopScrolling(); + listTimers[index]->SetCurrent(current); + listTimers[index]->ClearCurrentElement(); + listTimers[index]->SetSelectable(selectable); + listTimers[index]->Set(timer); +} + +/****************************************************************** +* cViewListChannels +******************************************************************/ +cViewListChannels::cViewListChannels(void) { + listChannels = NULL; + currentChannel = NULL; +} + +cViewListChannels::~cViewListChannels(void) { + delete[] listChannels; +} + +void cViewListChannels::Prepare(int start, int step) { + if (!listElement) + return; + + cLeMenuChannels *tpl = dynamic_cast(listElement); + if (!tpl) return; + + listChannels = new cLeMenuChannels*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listChannels[i] = new cLeMenuChannels(*tpl); + listElements[i] = listChannels[i]; + listChannels[i]->SetNumber(i); + listChannels[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listChannels[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listChannels[i]->SetAreaWidth(width); + } + listChannels[i]->SetContainer(x, y, width, height); + listChannels[i]->Cache(); + pos += step; + } + + if (!currentElement) return; + currentChannel = dynamic_cast(currentElement); + if (!currentChannel) return; + + currentChannel->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + currentChannel->SetDetached(); + currentChannel->Cache(); + for (int i = 0; i < numElements; i++) { + listChannels[i]->SetCurrentElement(currentChannel); + } +} + +void cViewListChannels::Set(const cChannel *channel, int index, bool current, bool selectable, bool withProvider) { + if (!current) + listChannels[index]->StopScrolling(); + listChannels[index]->SetCurrent(current); + listChannels[index]->ClearCurrentElement(); + listChannels[index]->SetSelectable(selectable); + listChannels[index]->Set(channel, withProvider); +} + +/****************************************************************** +* cViewListRecordings +******************************************************************/ +cViewListRecordings::cViewListRecordings(void) { + listRecordings = NULL; + currentRecording = NULL; +} + +cViewListRecordings::~cViewListRecordings(void) { + delete[] listRecordings; +} + +void cViewListRecordings::Prepare(int start, int step) { + if (!listElement) + return; + + cLeMenuRecordings *tpl = dynamic_cast(listElement); + if (!tpl) return; + + listRecordings = new cLeMenuRecordings*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listRecordings[i] = new cLeMenuRecordings(*tpl); + listElements[i] = listRecordings[i]; + listRecordings[i]->SetNumber(i); + listRecordings[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listRecordings[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listRecordings[i]->SetAreaWidth(width); + } + listRecordings[i]->SetContainer(x, y, width, height); + listRecordings[i]->Cache(); + pos += step; + } + + if (!currentElement) return; + currentRecording = dynamic_cast(currentElement); + if (!currentRecording) return; + + currentRecording->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + currentRecording->SetDetached(); + currentRecording->Cache(); + for (int i = 0; i < numElements; i++) { + listRecordings[i]->SetCurrentElement(currentRecording); + } +} + +void cViewListRecordings::Set(const cRecording *recording, int index, bool current, bool selectable, int level, int total, int New) { + if (!current) + listRecordings[index]->StopScrolling(); + listRecordings[index]->SetCurrent(current); + listRecordings[index]->ClearCurrentElement(); + listRecordings[index]->SetSelectable(selectable); + listRecordings[index]->Set(recording, level, total, New); +} + +/****************************************************************** +* cViewListPlugin +******************************************************************/ +cViewListPlugin::cViewListPlugin(void) { + listPlugin = NULL; + currentPlugin = NULL; +} + +cViewListPlugin::~cViewListPlugin(void) { + delete[] listPlugin; +} + +void cViewListPlugin::Prepare(int start, int step) { + if (!listElement) + return; + + if (!listElement) + return; + + cLeMenuPlugin *tpl = dynamic_cast(listElement); + if (!tpl) return; + + listPlugin = new cLeMenuPlugin*[numElements]; + listElements = new cListElement*[numElements]; + int pos = start; + + for (int i = 0; i < numElements; i++) { + listPlugin[i] = new cLeMenuPlugin(*tpl); + listElements[i] = listPlugin[i]; + listPlugin[i]->SetNumber(i); + listPlugin[i]->SetPlugId(plugId); + listPlugin[i]->SetPlugMenuId(plugMenuId); + listPlugin[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listPlugin[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listPlugin[i]->SetAreaWidth(width); + } + listPlugin[i]->SetContainer(x, y, width, height); + listPlugin[i]->Cache(); + pos += step; + } + + if (!currentElement) return; + currentPlugin = dynamic_cast(currentElement); + if (!currentPlugin) return; + + currentPlugin->SetContainer(attribs->X(), attribs->Y(), attribs->Width(), attribs->Height()); + currentPlugin->SetPlugId(plugId); + currentPlugin->SetPlugMenuId(plugMenuId); + currentPlugin->SetTokenContainer(); + currentPlugin->SetDetached(); + currentPlugin->Cache(); + for (int i = 0; i < numElements; i++) { + listPlugin[i]->SetCurrentElement(currentPlugin); + } +} + +void cViewListPlugin::Set(skindesignerapi::cTokenContainer *tk, int index, bool current, bool selectable) { + if (!current) + listPlugin[index]->StopScrolling(); + listPlugin[index]->SetCurrent(current); + listPlugin[index]->ClearCurrentElement(); + listPlugin[index]->SetSelectable(selectable); + listPlugin[index]->Set(tk); +} + +/****************************************************************** +* cViewListAudioTracks +******************************************************************/ +cViewListAudioTracks::cViewListAudioTracks(void) { + listAudioTracks = NULL; + numTracks = 0; + tokenContainer = NULL; +} + +cViewListAudioTracks::~cViewListAudioTracks(void) { + delete[] listAudioTracks; + delete tokenContainer; +} + +void cViewListAudioTracks::Close(void) { + if (!listElements) + return; + for (int i = 0; i < numElements; i++) { + delete listAudioTracks[i]; + } + delete[] listAudioTracks; + listAudioTracks = NULL; + } + +void cViewListAudioTracks::PreCache(void) { + tokenContainer = new skindesignerapi::cTokenContainer(); + tokenContainer->DefineIntToken("{numelements}", 0); + tokenContainer->CreateContainers(); + attribs->SetTokenContainer(tokenContainer); + attribs->SetContainer(container.X(), container.Y(), container.Width(), container.Height()); + attribs->SetGlobals(globals); + attribs->Cache(); +} + +void cViewListAudioTracks::SetNumtracks(int numTracks) { + this->numTracks = numTracks; + tokenContainer->Clear(); + tokenContainer->AddIntToken(0, numTracks); +} + +void cViewListAudioTracks::SetTracks(const char * const *tracks) { + if (numTracks <= 0) + return; + orientation = attribs->Orientation(); + eAlign align = attribs->Align(); + int x = attribs->X(); + int y = attribs->Y(); + int width = attribs->Width(); + int height = attribs->Height(); + + int step = 0; + if (orientation == eOrientation::vertical) { + step = height / numTracks; + } else { + step = width / numTracks; + } + + int start = 0; + if (align == eAlign::center) { + if (orientation == eOrientation::vertical) { + start = y + (height - numTracks * step) / 2; + } else { + start = x + (width - numTracks * step) / 2; + } + } else if (align == eAlign::bottom) { + start = y + height - numTracks * step; + } else if (align == eAlign::right) { + start = x + width - numTracks * step; + } else if (align == eAlign::top) { + start = y; + } + + cLeAudioTracks *tpl = dynamic_cast(listElement); + if (!tpl) return; + + listAudioTracks = new cLeAudioTracks*[numTracks]; + listElements = new cListElement*[numTracks]; + int pos = start; + + for (int i = 0; i < numTracks; i++) { + listAudioTracks[i] = new cLeAudioTracks(*tpl); + listElements[i] = listAudioTracks[i]; + listAudioTracks[i]->SetNumber(i); + listAudioTracks[i]->SetTokenContainer(); + int x, y, width, height; + if (orientation == eOrientation::vertical) { + x = attribs->X(); + y = pos; + width = attribs->Width(); + height = step; + listAudioTracks[i]->SetAreaHeight(height); + } else { + x = pos; + y = attribs->Y(); + width = step; + height = attribs->Height(); + listAudioTracks[i]->SetAreaWidth(width); + } + listAudioTracks[i]->SetContainer(x, y, width, height); + listAudioTracks[i]->Cache(); + pos += step; + } + for (int i=0; i < numTracks; i++) { + listAudioTracks[i]->Set(tracks[i]); + listAudioTracks[i]->SetSelectable(true); + } +} + +void cViewListAudioTracks::SetCurrentTrack(int index) { + for (int i = 0; i < numTracks; i++) { + if (i != index) { + listAudioTracks[i]->SetCurrent(false); + listAudioTracks[i]->SetDirty(); + listAudioTracks[i]->StopScrolling(); + } + } + listAudioTracks[index]->SetCurrent(true); + listAudioTracks[index]->SetDirty(); +} + +void cViewListAudioTracks::Draw(void) { + for (int i = 0; i < numTracks; i++) { + if (listAudioTracks[i]->Parse()) { + listAudioTracks[i]->Render(); + } + } +} \ No newline at end of file diff --git a/coreengine/viewlist.h b/coreengine/viewlist.h new file mode 100644 index 0000000..aadb5ed --- /dev/null +++ b/coreengine/viewlist.h @@ -0,0 +1,155 @@ +#ifndef __VIEWLIST_H +#define __VIEWLIST_H + +#include "globals.h" +#include "../libskindesignerapi/tokencontainer.h" +#include "listelements.h" +#include "area.h" + +class cViewList { +protected: + int plugId; + int plugMenuId; + cViewListAttribs *attribs; + cRect container; + cGlobals *globals; + int numElements; + eOrientation orientation; + cViewElement *listElement; + cViewElement *currentElement; + cListElement **listElements; + virtual void Prepare(int start, int step) {}; +public: + cViewList(void); + virtual ~cViewList(void); + void SetGlobals(cGlobals *globals); + void SetContainer(int x, int y, int width, int height); + void SetAttributes(vector &attributes); + void SetPlugId(int id) { plugId = id; }; + void SetPlugMenuId(int id) { plugMenuId = id; }; + static cViewList *CreateViewList(const char *name); + static cViewElement *CreateListElement(const char *name); + static cViewElement *CreateCurrentElement(const char *name); + void AddListElement(cViewElement *listElement); + void AddCurrentElement(cViewElement *currentElement); + virtual void PreCache(void); + int NumItems(void); + eOrientation Orientation(void); + void Draw(eMenuCategory menuCat); + void Clear(void); + virtual void Close(void); + void SetTransparency(int transparency); + void Debug(void); +}; + +class cViewListDefault : public cViewList { +private: + cLeMenuDefault **listDefault; + int avrgFontWidth; + const cFont *listFont; + int *colX; + int *colWidths; + const char *plugName; +protected: + void Prepare(int start, int step); +public: + cViewListDefault(void); + virtual ~cViewListDefault(void); + void SetTabs(int tab1, int tab2, int tab3, int tab4, int tab5); + void SetPlugin(const char *plugName) { this->plugName = plugName; }; + void Set(const char *text, int index, bool current, bool selectable); + const cFont *GetListFont(void); + int GetListWidth(void); +}; + +class cViewListMain : public cViewList { +private: + cLeMenuMain **listMain; + cCeMenuMain *currentMain; +protected: + void Prepare(int start, int step); +public: + cViewListMain(void); + virtual ~cViewListMain(void); + void Set(const char *text, int index, bool current, bool selectable); + const char *GetPlugin(void); +}; + +class cViewListSchedules : public cViewList { +private: + cLeMenuSchedules **listSchedules; + cCeMenuSchedules *currentSchedules; + bool epgSearchFav; +protected: + void Prepare(int start, int step); +public: + cViewListSchedules(void); + virtual ~cViewListSchedules(void); + void IsEpgSearchFav(bool isFav) { epgSearchFav = isFav; }; + void Set(const cEvent *event, int index, bool current, bool selectable, const cChannel *channel, bool withDate, eTimerMatch timerMatch); +}; + +class cViewListTimers : public cViewList { +private: + cLeMenuTimers **listTimers; + cCeMenuTimers *currentTimer; +protected: + void Prepare(int start, int step); +public: + cViewListTimers(void); + virtual ~cViewListTimers(void); + void Set(const cTimer *timer, int index, bool current, bool selectable); +}; + +class cViewListChannels : public cViewList { +private: + cLeMenuChannels **listChannels; + cCeMenuChannels *currentChannel; +protected: + void Prepare(int start, int step); +public: + cViewListChannels(void); + virtual ~cViewListChannels(void); + void Set(const cChannel *channel, int index, bool current, bool selectable, bool withProvider); +}; + +class cViewListRecordings : public cViewList { +private: + cLeMenuRecordings **listRecordings; + cCeMenuRecordings *currentRecording; +protected: + void Prepare(int start, int step); +public: + cViewListRecordings(void); + virtual ~cViewListRecordings(void); + void Set(const cRecording *recording, int index, bool current, bool selectable, int level, int total, int New); +}; + +class cViewListPlugin : public cViewList { +private: + cLeMenuPlugin **listPlugin; + cCeMenuPlugin *currentPlugin; +protected: + void Prepare(int start, int step); +public: + cViewListPlugin(void); + virtual ~cViewListPlugin(void); + void Set(skindesignerapi::cTokenContainer *tk, int index, bool current, bool selectable); +}; + +class cViewListAudioTracks : public cViewList { +private: + skindesignerapi::cTokenContainer *tokenContainer; + int numTracks; + cLeAudioTracks **listAudioTracks; +public: + cViewListAudioTracks(void); + virtual ~cViewListAudioTracks(void); + void Close(void); + void PreCache(void); + void SetNumtracks(int numTracks); + void SetTracks(const char * const *tracks); + void SetCurrentTrack(int index); + void Draw(void); +}; +#endif //__VIEWLIST_H \ No newline at end of file diff --git a/libtemplate/xmlparser.c b/coreengine/xmlparser.c similarity index 61% rename from libtemplate/xmlparser.c rename to coreengine/xmlparser.c index 8db3d3d..617313a 100644 --- a/libtemplate/xmlparser.c +++ b/coreengine/xmlparser.c @@ -1,10 +1,11 @@ #include "xmlparser.h" #include "../config.h" -#include "../libcore/helpers.h" +#include "../extensions/helpers.h" using namespace std; cXmlParser::cXmlParser(void) { + sdOsd = NULL; view = NULL; globals = NULL; skinSetup = NULL; @@ -16,7 +17,7 @@ cXmlParser::~cXmlParser() { /********************************************************************* * PUBLIC Functions *********************************************************************/ -bool cXmlParser::ReadView(cTemplateView *view, string xmlFile) { +bool cXmlParser::ReadView(cView *view, string xmlFile) { if (!view) return false; this->view = view; @@ -27,7 +28,7 @@ bool cXmlParser::ReadView(cTemplateView *view, string xmlFile) { return false; if (! SetDocument() ) return false; - if (! CheckNodeName(view->GetViewName()) ) + if (! CheckNodeName( view->GetViewName() )) return false; return true; } @@ -35,37 +36,72 @@ bool cXmlParser::ReadView(cTemplateView *view, string xmlFile) { bool cXmlParser::ParseView(void) { if (!view) return false; - vector rootAttribs = ParseAttributes(); - ValidateAttributes(NodeName(), rootAttribs); - view->SetParameters(rootAttribs); + view->SetAttributes(rootAttribs); + + cViewMenu *menuView = dynamic_cast(view); + cViewTracks *tracksView = dynamic_cast(view); if (!LevelDown()) return false; do { - - if (view->ValidSubView(NodeName())) { - ParseSubView(); - } else if (view->ValidViewElement(NodeName())) { - ParseViewElement(); - } else if (view->ValidViewList(NodeName())) { - ParseViewList(); - } else if (view->ValidViewGrid(NodeName())) { - ParseGrid(); - } else if (CheckNodeName("tab")) { - ParseViewTab(view); + if (view->ValidViewElement(NodeName())) { + ParseViewElement(NodeName()); + } else if (menuView) { + if (menuView->ValidSubView(NodeName())) { + ParseSubView(NodeName()); + } else if (view->ValidViewList(NodeName())) { + ParseViewList(); + } else { + esyslog("skindesigner: unknown node %s", NodeName()); + return false; + } + } else if (tracksView) { + if (view->ValidViewList(NodeName())) { + ParseViewList(); + } else { + esyslog("skindesigner: unknown node %s", NodeName()); + return false; + } } else { + esyslog("skindesigner: unknown view %s", NodeName()); return false; } - } while (NextNode()); return true; - } -bool cXmlParser::ReadPluginView(string plugName, int templateNumber, string templateName) { +bool cXmlParser::ParsePluginView(void) { + if (!view) + return false; + vector rootAttribs = ParseAttributes(); + view->SetAttributes(rootAttribs); + + if (!LevelDown()) + return false; + + do { + if (CheckNodeName("viewelement")) { + ParsePluginViewElement(); + } else if (CheckNodeName("grid")) { + ParseGrid(); + } else if (CheckNodeName("tab")) { + ParseViewTabPlugin(); + } else if (CheckNodeName("scrollbar")) { + ParsePluginViewElement(true, false); + } else if (CheckNodeName("tablabels")) { + ParsePluginViewElement(false, true); + } else { + esyslog("skindesigner: unknown node %s in plugin view", NodeName()); + } + } while (NextNode()); + + return true; +} + +bool cXmlParser::ReadPluginView(string templateName) { string xmlPath = GetPath(templateName); DeleteDocument(); if (! ReadXMLFile(xmlPath.c_str()) ) @@ -77,30 +113,34 @@ bool cXmlParser::ReadPluginView(string plugName, int templateNumber, string temp return true; } -bool cXmlParser::ParsePluginView(string plugName, int templateNumber) { - cTemplateView *plugView = new cTemplateViewMenu(); - view->AddPluginView(plugName, templateNumber, plugView); - - vector attribs = ParseAttributes(); - ValidateAttributes(NodeName(), attribs); - plugView->SetParameters(attribs); +bool cXmlParser::ParsePluginView(string plugName, int plugId, int menuNumber, int menuType) { + if (!view) + return false; + cViewMenu *menuView = dynamic_cast(view); + if (!menuView) { + return false; + } + vector > attribs = ParseAttributes(); if (!LevelDown()) return false; + + cSubView *plugView = cViewMenu::CreatePluginview(plugName.c_str(), plugId, menuNumber, menuType); + plugView->SetAttributes(attribs); + menuView->AddPluginview(plugView); do { - if (plugView->ValidViewElement(NodeName())) { - ParseViewElement(plugView); + ParseViewElement(NodeName(), plugView); } else if (plugView->ValidViewList(NodeName())) { ParseViewList(plugView); } else if (CheckNodeName("tab")) { - ParseViewTab(plugView); + ParseViewTab(plugView); } else { + esyslog("skindesigner: error - unknown %s", NodeName()); return false; } - } while (NextNode()); - + LevelUp(); return true; } @@ -164,24 +204,25 @@ bool cXmlParser::ParseSkinSetup(string skin) { /********************************************************************* * PRIVATE Functions *********************************************************************/ - -bool cXmlParser::ParseSubView(void) { +bool cXmlParser::ParseSubView(string name) { if (!view) return false; - - cTemplateView *subView = new cTemplateViewMenu(); - view->AddSubView(NodeName(), subView); - - vector > subViewAttribs = ParseAttributes(); - ValidateAttributes(NodeName(), subViewAttribs); - subView->SetParameters(subViewAttribs); + cViewMenu *menuView = dynamic_cast(view); + if (!menuView) { + return false; + } + vector > attribs = ParseAttributes(); if (!LevelDown()) return false; - do { + cSubView *subView = cViewMenu::CreateSubview(name.c_str()); + subView->SetAttributes(attribs); + menuView->AddSubview(name.c_str(), subView); + + do { if (subView->ValidViewElement(NodeName())) { - ParseViewElement(subView); + ParseViewElement(NodeName(), subView); } else if (subView->ValidViewList(NodeName())) { ParseViewList(subView); } else if (CheckNodeName("tab")) { @@ -189,70 +230,133 @@ bool cXmlParser::ParseSubView(void) { } else { return false; } - } while (NextNode()); LevelUp(); return true; - } -void cXmlParser::ParseViewElement(cTemplateView *subView) { + +void cXmlParser::ParseViewElement(string name, cView *subView) { if (!view) return; - const char *viewElementName = NodeName(); vector attributes = ParseAttributes(); - ValidateAttributes("viewelement", attributes); if (!LevelDown()) return; - cTemplateViewElement *viewElement = new cTemplateViewElement(); - viewElement->SetParameters(attributes); + //correct detailheader name + if (subView) { + if (!strcmp(subView->GetViewName(), "menudetailedepg") && !name.compare("detailheader")) { + name = "detailheaderepg"; + } else if (!strcmp(subView->GetViewName(), "menudetailedrecording") && !name.compare("detailheader")) { + name = "detailheaderrec"; + } else if (startswith(subView->GetViewName(), "menuplugin") && !name.compare("detailheader")) { + name = "detailheaderplugin"; + } + } + cViewElement *viewElement = cViewElement::CreateViewElement(name.c_str(), view->GetViewName()); + if (!viewElement) { + LevelUp(); + return; + } + + viewElement->SetOsd(sdOsd); + viewElement->SetAttributes(attributes); do { if (!CheckNodeName("areacontainer") && !CheckNodeName("area") && !CheckNodeName("areascroll")) { esyslog("skindesigner: invalid tag \"%s\" in viewelement", NodeName()); continue; } - cTemplatePixmapNode *pix = NULL; + cAreaNode *area = NULL; if (CheckNodeName("area") || CheckNodeName("areascroll")) { - pix = ParseArea(); + area = ParseArea(); } else { - pix = ParseAreaContainer(); + area = ParseAreaContainer(); } - pix->SetGlobals(globals); - viewElement->AddPixmap(pix); + viewElement->AddArea(area); } while (NextNode()); + LevelUp(); if (subView) subView->AddViewElement(viewElementName, viewElement); else view->AddViewElement(viewElementName, viewElement); + } -void cXmlParser::ParseViewList(cTemplateView *subView) { +void cXmlParser::ParsePluginViewElement(bool isScrollbar, bool isTabLabels) { if (!view) return; - - vector attribs = ParseAttributes(); - ValidateAttributes(NodeName(), attribs); + cViewPlugin *pluginView = dynamic_cast(view); + if (!pluginView) + return; - cTemplateViewList *viewList = new cTemplateViewList(); - viewList->SetGlobals(globals); - viewList->SetParameters(attribs); + vector attributes = ParseAttributes(); + + if (!LevelDown()) + return; + + cViewElement *viewElement = NULL; + if (isScrollbar) { + viewElement = new cVeDmScrollbar(); + } else if (isTabLabels) { + viewElement = new cVeDmTablabels(); + } else { + viewElement = new cVePlugin(); + } + + viewElement->SetOsd(sdOsd); + viewElement->SetAttributes(attributes); + do { + if (!CheckNodeName("areacontainer") && !CheckNodeName("area") && !CheckNodeName("areascroll")) { + esyslog("skindesigner: invalid tag \"%s\" in viewelement", NodeName()); + continue; + } + cAreaNode *area = NULL; + if (CheckNodeName("area") || CheckNodeName("areascroll")) { + area = ParseArea(); + } else { + area = ParseAreaContainer(); + } + viewElement->AddArea(area); + } while (NextNode()); + + LevelUp(); + + if (isScrollbar) { + pluginView->AddScrollbar(dynamic_cast(viewElement)); + } else if (isTabLabels) { + pluginView->AddTablabels(dynamic_cast(viewElement)); + } else { + pluginView->AddViewElement(dynamic_cast(viewElement)); + } +} + +void cXmlParser::ParseViewList(cView *subView) { + if (!view) + return; + + const char *name = NULL; + if (subView) + name = subView->GetViewName(); + else + name = view->GetViewName(); + + vector attribs = ParseAttributes(); + cViewList *viewList = cViewList::CreateViewList(name); + viewList->SetAttributes(attribs); if (!LevelDown()) return; do { if (CheckNodeName("currentelement")) { - - cTemplateViewElement *currentElement = new cTemplateViewElement(); - vector attribsCur = ParseAttributes(); - ValidateAttributes(NodeName(), attribsCur); - currentElement->SetGlobals(globals); - currentElement->SetParameters(attribsCur); + cViewElement *currentElement = cViewList::CreateCurrentElement(name); + currentElement->SetOsd(sdOsd); + vector attribsList = ParseAttributes(); + currentElement->SetAttributes(attribsList); if (!LevelDown()) continue; do { @@ -260,24 +364,21 @@ void cXmlParser::ParseViewList(cTemplateView *subView) { esyslog("skindesigner: invalid tag \"%s\" in viewelement", NodeName()); continue; } - cTemplatePixmapNode *pix = NULL; + cAreaNode *area = NULL; if (CheckNodeName("area") || CheckNodeName("areascroll")) { - pix = ParseArea(); + area = ParseArea(); } else { - pix = ParseAreaContainer(); + area = ParseAreaContainer(); } - currentElement->AddPixmap(pix); + currentElement->AddArea(area); } while (NextNode()); LevelUp(); viewList->AddCurrentElement(currentElement); - } else if (CheckNodeName("listelement")) { - - cTemplateViewElement *listElement = new cTemplateViewElement(); + cViewElement *listElement = cViewList::CreateListElement(name); + listElement->SetOsd(sdOsd); vector attribsList = ParseAttributes(); - ValidateAttributes(NodeName(), attribsList); - listElement->SetGlobals(globals); - listElement->SetParameters(attribsList); + listElement->SetAttributes(attribsList); if (!LevelDown()) return; do { @@ -285,110 +386,128 @@ void cXmlParser::ParseViewList(cTemplateView *subView) { esyslog("skindesigner: invalid tag \"%s\" in viewelement", NodeName()); continue; } - cTemplatePixmapNode *pix = NULL; + cAreaNode *area = NULL; if (CheckNodeName("area") || CheckNodeName("areascroll")) { - pix = ParseArea(); + area = ParseArea(); } else { - pix = ParseAreaContainer(); + area = ParseAreaContainer(); } - listElement->AddPixmap(pix); + listElement->AddArea(area); } while (NextNode()); LevelUp(); viewList->AddListElement(listElement); } - } while (NextNode()); LevelUp(); - + if (subView) - subView->AddViewList(NodeName(), viewList); + subView->AddViewList(viewList); else - view->AddViewList(NodeName(), viewList); + view->AddViewList(viewList); + } -void cXmlParser::ParseViewTab(cTemplateView *subView) { +void cXmlParser::ParseViewTab(cView *subView) { if (!view || !subView) return; - + cSubView *menuSubView = dynamic_cast(subView); + if (!menuSubView) { + return; + } vector attribs = ParseAttributes(); - ValidateAttributes(NodeName(), attribs); + cArea *tab = new cArea(); + tab->SetOsd(sdOsd); + tab->SetTab(); + tab->SetAttributes(attribs); + ParseFunctionCalls(tab); + menuSubView->AddTab(tab); +} - cTemplateViewTab *viewTab = new cTemplateViewTab(); - viewTab->SetGlobals(globals); - viewTab->SetParameters(attribs); - viewTab->SetScrolling(); - ParseFunctionCalls(viewTab); - subView->AddViewTab(viewTab); +void cXmlParser::ParseViewTabPlugin(void) { + if (!view) + return; + cViewPlugin *plugView = dynamic_cast(view); + if (!plugView) { + return; + } + vector attribs = ParseAttributes(); + cArea *tab = new cArea(); + tab->SetOsd(sdOsd); + tab->SetTab(); + tab->SetAttributes(attribs); + ParseFunctionCalls(tab); + plugView->AddTab(tab); } void cXmlParser::ParseGrid(void) { if (!view) return; + cViewPlugin *pluginView = dynamic_cast(view); + if (!pluginView) + return; vector attributes = ParseAttributes(); - ValidateAttributes(NodeName(), attributes); if (!LevelDown()) return; - cTemplateViewGrid *viewGrid = new cTemplateViewGrid(); - viewGrid->SetParameters(attributes); + cViewGrid *viewGrid = new cViewGrid(); + viewGrid->SetAttributes(attributes); + cGridElement *gridElement = new cGridElement(); + gridElement->SetOsd(sdOsd); do { - if (!CheckNodeName("areacontainer") && !CheckNodeName("area") && !CheckNodeName("areascroll")) { esyslog("skindesigner: invalid tag \"%s\" in grid", NodeName()); continue; } - cTemplatePixmapNode *pix = NULL; + cAreaNode *area = NULL; if (CheckNodeName("area") || CheckNodeName("areascroll")) { - pix = ParseArea(); + area = ParseArea(); } else { - pix = ParseAreaContainer(); + area = ParseAreaContainer(); } - pix->SetGlobals(globals); - viewGrid->AddPixmap(pix); + gridElement->AddArea(area); } while (NextNode()); LevelUp(); - view->AddGrid(viewGrid); + viewGrid->AddGridElement(gridElement); + pluginView->AddViewGrid(viewGrid); } -cTemplatePixmap *cXmlParser::ParseArea(void) { +cArea *cXmlParser::ParseArea(void) { vector attribs = ParseAttributes(); - ValidateAttributes(NodeName(), attribs); - - cTemplatePixmap *pix = new cTemplatePixmap(); + cArea *area = new cArea(); + area->SetOsd(sdOsd); if (CheckNodeName("areascroll")) { - pix->SetScrolling(); + area->SetScrolling(); } - pix->SetParameters(attribs); - ParseFunctionCalls(pix); - return pix; + area->SetAttributes(attribs); + ParseFunctionCalls(area); + return area; } -cTemplatePixmapContainer *cXmlParser::ParseAreaContainer(void) { +cAreaContainer *cXmlParser::ParseAreaContainer(void) { vector attribs = ParseAttributes(); - ValidateAttributes(NodeName(), attribs); - cTemplatePixmapContainer *pixContainer = new cTemplatePixmapContainer(); - pixContainer->SetParameters(attribs); + cAreaContainer *areaContainer = new cAreaContainer(); + areaContainer->SetAttributes(attribs); if (!LevelDown()) - return pixContainer; + return areaContainer; do { if (!CheckNodeName("area") && !CheckNodeName("areascroll")) { esyslog("skindesigner: invalid tag \"%s\" in areacontainer", NodeName()); continue; } - cTemplatePixmap *pix = ParseArea(); - pixContainer->AddPixmap(pix); + cArea *area = ParseArea(); + areaContainer->AddArea(area); } while (NextNode()); LevelUp(); - return pixContainer; + return areaContainer; } -void cXmlParser::ParseFunctionCalls(cTemplatePixmap *pix) { +void cXmlParser::ParseFunctionCalls(cArea *area) { if (!view) return; if (!LevelDown()) @@ -396,31 +515,28 @@ void cXmlParser::ParseFunctionCalls(cTemplatePixmap *pix) { do { if (CheckNodeName("loop")) { vector attribs = ParseAttributes(); - ValidateAttributes(NodeName(), attribs); - cTemplateLoopFunction *loopFunc = new cTemplateLoopFunction(); - loopFunc->SetParameters(attribs); - ParseLoopFunctionCalls(loopFunc); - pix->AddLoopFunction(loopFunc); - } else if (view->ValidFunction(NodeName())) { + cFunction *f = area->AddFunction(NodeName(), attribs); + cFuncLoop *loopFunc = dynamic_cast(f); + if (!loopFunc) + continue; + ParseLoopFunctionCalls(area, loopFunc); + } else if (area->ValidFunction(NodeName())) { vector attribs = ParseAttributes(); - ValidateAttributes(NodeName(), attribs); - pix->AddFunction(NodeName(), attribs); + area->AddFunction(NodeName(), attribs); } - } while (NextNode()); LevelUp(); } -void cXmlParser::ParseLoopFunctionCalls(cTemplateLoopFunction *loopFunc) { +void cXmlParser::ParseLoopFunctionCalls(cArea *area, cFuncLoop *loopFunc) { if (!view) return; if (!LevelDown()) return; do { - if (view->ValidFunction(NodeName())) { + if (area->ValidFunction(NodeName())) { vector attribs = ParseAttributes(); - ValidateAttributes(NodeName(), attribs); - loopFunc->AddFunction(NodeName(), attribs); + area->AddFunction(NodeName(), attribs, loopFunc); } } while (NextNode()); LevelUp(); @@ -610,21 +726,6 @@ void cXmlParser::ParseSetupParameter(void) { skinSetup->SetParameter(paramType, paramName, paramDisplayText, paramHelpText, paramMin, paramMax, paramValue, paramOptions); } -void cXmlParser::ValidateAttributes(const char *nodeName, vector &attributes) { - bool repeat = true; - while (repeat) { - repeat = false; - for (vector::iterator it = attributes.begin(); it != attributes.end(); it++) { - string attributeName = (*it).first; - if (!view->ValidAttribute(nodeName, attributeName.c_str())) { - attributes.erase(it); - repeat = true; - break; - } - } - } -} - string cXmlParser::GetPath(string xmlFile) { string activeSkin = Setup.OSDSkin; string activeTheme = Setup.OSDTheme; diff --git a/libtemplate/xmlparser.h b/coreengine/xmlparser.h similarity index 55% rename from libtemplate/xmlparser.h rename to coreengine/xmlparser.h index 3dd0705..398700e 100644 --- a/libtemplate/xmlparser.h +++ b/coreengine/xmlparser.h @@ -9,12 +9,11 @@ #include #include #include -#include "../libcore/libxmlwrapper.h" -#include "templateview.h" -#include "templateviewlist.h" -#include "templateviewgrid.h" -#include "templateviewtab.h" -#include "../libcore/skinsetup.h" +#include "../extensions/libxmlwrapper.h" +#include "osdwrapper.h" +#include "view.h" +#include "viewlist.h" +#include "../extensions/skinsetup.h" using namespace std; @@ -22,19 +21,22 @@ using namespace std; class cXmlParser : public cLibXMLWrapper { private: - cTemplateView *view; + cSdOsd *sdOsd; + cView *view; cGlobals *globals; cSkinSetup *skinSetup; //parsing views - bool ParseSubView(void); - void ParseViewElement(cTemplateView *subView = NULL); - void ParseViewList(cTemplateView *subView = NULL); - void ParseViewTab(cTemplateView *subView); + bool ParseSubView(string name); + void ParseViewElement(string name, cView *subView = NULL); + void ParsePluginViewElement(bool isScrollbar = false, bool isTabLabels = false); + void ParseViewList(cView *subView = NULL); + void ParseViewTab(cView *subView); + void ParseViewTabPlugin(void); void ParseGrid(void); - cTemplatePixmap *ParseArea(void); - cTemplatePixmapContainer *ParseAreaContainer(void); - void ParseFunctionCalls(cTemplatePixmap *pix); - void ParseLoopFunctionCalls(cTemplateLoopFunction *loopFunc); + cArea *ParseArea(void); + cAreaContainer *ParseAreaContainer(void); + void ParseFunctionCalls(cArea *area); + void ParseLoopFunctionCalls(cArea *area, cFuncLoop *loopFunc); //parsing globals void ParseGlobalColors(void); void InsertColor(string name, string value); @@ -46,17 +48,19 @@ private: void ParseSetupMenu(void); void ParseSetupParameter(void); //helpers - void ValidateAttributes(const char *nodeName, vector &attributes); string GetPath(string xmlFile); public: cXmlParser(void); virtual ~cXmlParser(void); + void SetOsd(cSdOsd *osd) { sdOsd = osd; }; //reading views - bool ReadView(cTemplateView *view, string xmlFile); + bool ReadView(cView *view, string xmlFile); bool ParseView(void); - //reading plugin views - bool ReadPluginView(string plugName, int templateNumber, string templateName); - bool ParsePluginView(string plugName, int templateNumber); + //Parse advanced plugin view + bool ParsePluginView(void); + //reading basic plugin menu views + bool ReadPluginView(string templateName); + bool ParsePluginView(string plugName, int plugId, int menuNumber, int menuType); //reading globals bool ReadGlobals(cGlobals *globals, string xmlFile); bool ParseGlobals(void); diff --git a/designer.c b/designer.c index 9af6e7e..b3b5052 100644 --- a/designer.c +++ b/designer.c @@ -1,5 +1,5 @@ #include "designer.h" -#include "libcore/helpers.h" +#include "extensions/helpers.h" cSkinDesigner::cSkinDesigner(string skin) : cSkin(skin.c_str(), &::Theme) { init = true; @@ -9,13 +9,12 @@ cSkinDesigner::cSkinDesigner(string skin) : cSkin(skin.c_str(), &::Theme) { useBackupSkin = false; globals = NULL; - channelTemplate = NULL; - menuTemplate = NULL; - messageTemplate = NULL; - replayTemplate = NULL; - volumeTemplate = NULL; - audiotracksTemplate = NULL; - + channelView = NULL; + menuView = NULL; + messageView = NULL; + replayView = NULL; + volumeView = NULL; + tracksView = NULL; currentMenu = NULL; dsyslog("skindesigner: skin %s started", skin.c_str()); @@ -24,7 +23,7 @@ cSkinDesigner::cSkinDesigner(string skin) : cSkin(skin.c_str(), &::Theme) { cSkinDesigner::~cSkinDesigner(void) { if (globals) delete globals; - DeleteTemplates(); + DeleteViews(); if (backupSkin) delete backupSkin; } @@ -36,9 +35,9 @@ const char *cSkinDesigner::Description(void) { cSkinDisplayChannel *cSkinDesigner::DisplayChannel(bool WithInfo) { currentMenu = NULL; cSkinDisplayChannel *displayChannel = NULL; + Init(); if (!useBackupSkin) { - Init(); - displayChannel = new cSDDisplayChannel(channelTemplate, WithInfo); + displayChannel = new cSDDisplayChannel(channelView, WithInfo); } else { displayChannel = backupSkin->DisplayChannel(WithInfo); } @@ -49,7 +48,7 @@ cSkinDisplayMenu *cSkinDesigner::DisplayMenu(void) { if (!useBackupSkin) { cSDDisplayMenu *displayMenu = NULL; Init(); - displayMenu = new cSDDisplayMenu(menuTemplate); + displayMenu = new cSDDisplayMenu(menuView); currentMenu = displayMenu; return displayMenu; } else { @@ -64,7 +63,7 @@ cSkinDisplayReplay *cSkinDesigner::DisplayReplay(bool ModeOnly) { cSkinDisplayReplay *displayReplay = NULL; if (!useBackupSkin) { Init(); - displayReplay = new cSDDisplayReplay(replayTemplate, ModeOnly); + displayReplay = new cSDDisplayReplay(replayView, ModeOnly); } else { displayReplay = backupSkin->DisplayReplay(ModeOnly); } @@ -76,7 +75,7 @@ cSkinDisplayVolume *cSkinDesigner::DisplayVolume(void) { cSkinDisplayVolume *displayVolume = NULL; if (!useBackupSkin) { Init(); - displayVolume = new cSDDisplayVolume(volumeTemplate); + displayVolume = new cSDDisplayVolume(volumeView); } else { displayVolume = backupSkin->DisplayVolume(); } @@ -88,7 +87,7 @@ cSkinDisplayTracks *cSkinDesigner::DisplayTracks(const char *Title, int NumTrack cSkinDisplayTracks *displayTracks = NULL; if (!useBackupSkin) { Init(); - displayTracks = new cSDDisplayTracks(audiotracksTemplate, Title, NumTracks, Tracks); + displayTracks = new cSDDisplayTracks(tracksView, Title, NumTracks, Tracks); } else { displayTracks = backupSkin->DisplayTracks(Title, NumTracks, Tracks); } @@ -100,28 +99,13 @@ cSkinDisplayMessage *cSkinDesigner::DisplayMessage(void) { cSkinDisplayMessage *displayMessage = NULL; if (!useBackupSkin) { Init(); - displayMessage = new cSDDisplayMessage(messageTemplate); + displayMessage = new cSDDisplayMessage(messageView); } else { displayMessage = backupSkin->DisplayMessage(); } return displayMessage; } -cSkinDisplayPlugin *cSkinDesigner::DisplayPlugin(string pluginName, int viewID, int subViewID) { - currentMenu = NULL; - if (useBackupSkin) - return NULL; - Init(); - map< string, map >::iterator hit = pluginTemplates.find(pluginName); - if (hit == pluginTemplates.end()) - return NULL; - map ::iterator hit2 = (hit->second).find(viewID); - if (hit2 == (hit->second).end()) - return NULL; - return new cSkinDisplayPlugin(hit2->second, subViewID); -} - - void cSkinDesigner::Reload(void) { dsyslog("skindesigner: forcing full reload of templates"); if (cOsd::IsOpen()) { @@ -130,14 +114,14 @@ void cSkinDesigner::Reload(void) { } cStopWatch watch; - bool ok = LoadTemplates(); + bool ok = LoadViews(); if (!ok) { esyslog("skindesigner: error during loading of templates - using LCARS as backup"); if (!backupSkin) backupSkin = new cSkinLCARS(); useBackupSkin = true; } else { - CacheTemplates(); + CacheViews(); useBackupSkin = false; watch.Stop("templates reloaded and cache created"); } @@ -147,38 +131,62 @@ void cSkinDesigner::ListAvailableFonts(void) { fontManager->ListAvailableFonts(); } -bool cSkinDesigner::SetCustomToken(string option) { +bool cSkinDesigner::SetCustomIntToken(string option) { splitstring s(option.c_str()); vector flds = s.split('=', 0); - if (flds.size() != 2) return false; - - string key = trim(flds[0]); + int key = atoi(trim(flds[0]).c_str()); string val = trim(flds[1]); - if (!globals) return true; - - if (isNumber(val)) { + if (key > 0 && isNumber(val)) { globals->AddCustomInt(key, atoi(val.c_str())); } else { - globals->AddCustomString(key, val); + return false; } return true; } +bool cSkinDesigner::SetCustomStringToken(string option) { + splitstring s(option.c_str()); + vector flds = s.split('=', 0); + if (flds.size() != 2) + return false; + int key = atoi(trim(flds[0]).c_str()); + string val = trim(flds[1]); + if (!globals) + return true; + if (key > 0) + globals->AddCustomString(key, val); + else + return false; + return true; +} + void cSkinDesigner::ListCustomTokens(void) { if (!globals) return; globals->ListCustomTokens(); } +skindesignerapi::ISkinDisplayPlugin *cSkinDesigner::GetDisplayPlugin(int plugId) { + map::iterator hit = pluginViews.find(plugId); + if (hit == pluginViews.end()) + return NULL; + return hit->second; +} + /********************************************************************************* * PRIVATE FUNCTIONS *********************************************************************************/ void cSkinDesigner::Init(void) { - if (init || config.OsdSizeChanged() || config.SkinChanged() || config.OsdLanguageChanged() || config.setupCloseDoReload) { + if ( init + || config.OsdSizeChanged() + || config.SkinChanged() + || config.OsdLanguageChanged() || + config.setupCloseDoReload ) + { config.setupCloseDoReload = false; if (init) { config.SetSkin(); @@ -188,7 +196,8 @@ void cSkinDesigner::Init(void) { dsyslog("skindesigner: initializing skin %s", skin.c_str()); config.CheckDecimalPoint(); - + plgManager->Reset(); + if (fontManager) delete fontManager; fontManager = new cFontManager(); @@ -198,69 +207,63 @@ void cSkinDesigner::Init(void) { imgCache->SetPathes(); cStopWatch watch; - bool ok = LoadTemplates(); + bool ok = LoadViews(); if (!ok) { esyslog("skindesigner: error during loading of templates - using LCARS as backup"); backupSkin = new cSkinLCARS(); useBackupSkin = true; } else { - CacheTemplates(); - watch.Stop("templates loaded and cache created"); + CacheViews(); + watch.Stop("templates loaded and caches created"); } init = false; - } else if (config.OsdFontsChanged()) { + } + else if (config.OsdFontsChanged()) + { dsyslog("skindesigner: reloading fonts"); if (fontManager) delete fontManager; fontManager = new cFontManager(); cStopWatch watch; - bool ok = LoadTemplates(); + bool ok = LoadViews(); if (!ok) { esyslog("skindesigner: error during loading of templates - using LCARS as backup"); backupSkin = new cSkinLCARS(); useBackupSkin = true; } else { - CacheTemplates(); - watch.Stop("templates loaded and cache created"); + CacheViews(); + watch.Stop("templates loaded and caches created"); } } } -void cSkinDesigner::DeleteTemplates(void) { - if (channelTemplate) { - delete channelTemplate; - channelTemplate = NULL; +void cSkinDesigner::DeleteViews(void) { + delete channelView; + channelView = NULL; + + delete menuView; + menuView = NULL; + + delete messageView; + messageView = NULL; + + delete replayView; + replayView = NULL; + + delete volumeView; + volumeView = NULL; + + delete tracksView; + tracksView = NULL; + + for (map::iterator it = pluginViews.begin(); it != pluginViews.end(); it++) { + cViewPlugin *plugView = it->second; + delete plugView; } - if (menuTemplate) { - delete menuTemplate; - menuTemplate = NULL; - } - if (messageTemplate) { - delete messageTemplate; - messageTemplate = NULL; - } - if (replayTemplate) { - delete replayTemplate; - replayTemplate = NULL; - } - if (volumeTemplate) { - delete volumeTemplate; - volumeTemplate = NULL; - } - if (audiotracksTemplate) { - delete audiotracksTemplate; - audiotracksTemplate = NULL; - } - for (map< string, map >::iterator plugs = pluginTemplates.begin(); plugs !=pluginTemplates.end(); plugs++) { - map plugTpls = plugs->second; - for (map ::iterator tpl = plugTpls.begin(); tpl != plugTpls.end(); tpl++) { - delete tpl->second; - } - } - pluginTemplates.clear(); + pluginViews.clear(); } -bool cSkinDesigner::LoadTemplates(void) { +bool cSkinDesigner::LoadViews(void) { if (globals) delete globals; globals = new cGlobals(); @@ -276,142 +279,102 @@ bool cSkinDesigner::LoadTemplates(void) { skinSetup->AddToGlobals(globals); } - DeleteTemplates(); + DeleteViews(); - channelTemplate = new cTemplate(vtDisplayChannel); - channelTemplate->SetGlobals(globals); - ok = channelTemplate->ReadFromXML(); + channelView = new cViewChannel(); + ok = channelView->ReadFromXML(); if (!ok) { esyslog("skindesigner: error reading displaychannel template, aborting"); - DeleteTemplates(); + DeleteViews(); return false; } - channelTemplate->Translate(); + channelView->SetGlobals(globals); - menuTemplate = new cTemplate(vtDisplayMenu); - menuTemplate->SetGlobals(globals); - ok = menuTemplate->ReadFromXML(); + menuView = new cViewMenu(); + ok = menuView->ReadFromXML(); if (!ok) { esyslog("skindesigner: error reading displaymenu template, aborting"); - DeleteTemplates(); + DeleteViews(); return false; } - menuTemplate->Translate(); + menuView->SetGlobals(globals); - messageTemplate = new cTemplate(vtDisplayMessage); - messageTemplate->SetGlobals(globals); - ok = messageTemplate->ReadFromXML(); + messageView = new cViewMessage(); + ok = messageView->ReadFromXML(); if (!ok) { esyslog("skindesigner: error reading displaymessage template, aborting"); - DeleteTemplates(); + DeleteViews(); return false; } - messageTemplate->Translate(); + messageView->SetGlobals(globals); - replayTemplate = new cTemplate(vtDisplayReplay); - replayTemplate->SetGlobals(globals); - ok = replayTemplate->ReadFromXML(); + replayView = new cViewReplay(); + ok = replayView->ReadFromXML(); if (!ok) { esyslog("skindesigner: error reading displayreplay template, aborting"); - DeleteTemplates(); + DeleteViews(); return false; } - replayTemplate->Translate(); + replayView->SetGlobals(globals); - volumeTemplate = new cTemplate(vtDisplayVolume); - volumeTemplate->SetGlobals(globals); - ok = volumeTemplate->ReadFromXML(); + volumeView = new cViewVolume(); + ok = volumeView->ReadFromXML(); if (!ok) { esyslog("skindesigner: error reading displayvolume template, aborting"); - DeleteTemplates(); + DeleteViews(); return false; } - volumeTemplate->Translate(); + volumeView->SetGlobals(globals); - audiotracksTemplate = new cTemplate(vtDisplayAudioTracks); - audiotracksTemplate->SetGlobals(globals); - ok = audiotracksTemplate->ReadFromXML(); + tracksView = new cViewTracks(); + ok = tracksView->ReadFromXML(); if (!ok) { esyslog("skindesigner: error reading displayaudiotracks template, aborting"); - DeleteTemplates(); + DeleteViews(); return false; } - audiotracksTemplate->Translate(); + tracksView->SetGlobals(globals); - config.InitPluginViewIterator(); - map *plugViews = NULL; - string plugName; - while ( plugViews = config.GetPluginViews(plugName) ) { - for (map ::iterator v = plugViews->begin(); v != plugViews->end(); v++) { - int viewID = v->first; - stringstream templateName; - templateName << "plug-" << plugName << "-" << v->second.c_str(); - cTemplate *plgTemplate = new cTemplate(vtDisplayPlugin, plugName, viewID); - plgTemplate->SetGlobals(globals); - ok = plgTemplate->ReadFromXML(templateName.str()); - if (!ok) { - esyslog("skindesigner: error reading plugin %s template", plugName.c_str()); - delete plgTemplate; - pluginTemplates.erase(plugName); - break; - } - ok = plgTemplate->SetSubViews(plugName, viewID); - if (!ok) { - delete plgTemplate; - pluginTemplates.erase(plugName); - break; - } - plgTemplate->Translate(); - map< string, map >::iterator hit = pluginTemplates.find(plugName); - if (hit == pluginTemplates.end()) { - map plugTemplates; - plugTemplates.insert(pair(v->first, plgTemplate)); - pluginTemplates.insert(pair >(plugName, plugTemplates)); - } else { - (hit->second).insert(pair(v->first, plgTemplate)); - } - } - } + LoadPluginViews(); dsyslog("skindesigner: templates successfully validated and parsed"); return true; } -void cSkinDesigner::CacheTemplates(void) { - channelTemplate->PreCache(); - menuTemplate->PreCache(); - messageTemplate->PreCache(); - replayTemplate->PreCache(); - volumeTemplate->PreCache(); - audiotracksTemplate->PreCache(); - for (map< string, map >::iterator plugs = pluginTemplates.begin(); plugs != pluginTemplates.end(); plugs++) { - for (map ::iterator plugTplts = plugs->second.begin(); plugTplts != plugs->second.end(); plugTplts++) { - (plugTplts->second)->PreCache(); +void cSkinDesigner::LoadPluginViews(void) { + plgManager->InitPluginViewIterator(); + string plugName = ""; + string viewTpl = ""; + int plugId = -1; + while ( plgManager->GetNextPluginView(plugName, plugId, viewTpl) ) { + cViewPlugin *plugView = new cViewPlugin(0, plugId); + bool ok = plugView->ReadFromXML(plugName.c_str(), viewTpl.c_str()); + if (!ok) { + esyslog("skindesigner: error during loading templates for plugin %s", plugName.c_str()); + continue; } - } - dsyslog("skindesigner: templates cached"); - fontManager->DeleteFonts(); - fontManager->CacheFonts(channelTemplate); - fontManager->CacheFonts(menuTemplate); - fontManager->CacheFonts(messageTemplate); - fontManager->CacheFonts(replayTemplate); - fontManager->CacheFonts(volumeTemplate); - fontManager->CacheFonts(audiotracksTemplate); - dsyslog("skindesigner: fonts cached"); - dsyslog("skindesigner: caching images..."); - imgCache->Clear(); - imgCache->SetPathes(); - channelTemplate->CacheImages(); - menuTemplate->CacheImages(); - messageTemplate->CacheImages(); - replayTemplate->CacheImages(); - volumeTemplate->CacheImages(); - audiotracksTemplate->CacheImages(); - for (map< string, map >::iterator plugs = pluginTemplates.begin(); plugs != pluginTemplates.end(); plugs++) { - for (map ::iterator plugTplts = plugs->second.begin(); plugTplts != plugs->second.end(); plugTplts++) { - (plugTplts->second)->CacheImages(); + ok = plugView->ReadSubViews(plugName.c_str()); + if (!ok) { + esyslog("skindesigner: error during loading templates for plugin %s", plugName.c_str()); + continue; } + plugView->SetGlobals(globals); + pluginViews.insert(pair(plugId, plugView)); } +} + +void cSkinDesigner::CacheViews(void) { + channelView->PreCache(); + menuView->PreCache(); + messageView->PreCache(); + replayView->PreCache(); + volumeView->PreCache(); + tracksView->PreCache(); + for (map::iterator it = pluginViews.begin(); it != pluginViews.end(); it++) { + cViewPlugin *plugView = it->second; + plugView->PreCache(); + } + dsyslog("skindesigner: templates and images cached"); imgCache->Debug(false); } diff --git a/designer.h b/designer.h index 7a32235..18c94d2 100644 --- a/designer.h +++ b/designer.h @@ -4,15 +4,19 @@ class cSkinDesigner; #include "config.h" -#include "libtemplate/template.h" -#include "libtemplate/xmlparser.h" +#include "coreengine/viewdisplaychannel.h" +#include "coreengine/viewdisplaymenu.h" +#include "coreengine/viewdisplayreplay.h" +#include "coreengine/viewdisplayvolume.h" +#include "coreengine/viewdisplaytracks.h" +#include "coreengine/viewdisplaymessage.h" +#include "coreengine/viewdisplayplugin.h" #include "displaychannel.h" #include "displaymenu.h" #include "displayreplay.h" #include "displayvolume.h" #include "displaytracks.h" #include "displaymessage.h" -#include "displayplugin.h" #include class cSkinDesigner : public cSkin { @@ -22,19 +26,20 @@ private: cSkinLCARS *backupSkin; bool useBackupSkin; cGlobals *globals; - cTemplate *channelTemplate; - cTemplate *menuTemplate; - cTemplate *messageTemplate; - cTemplate *replayTemplate; - cTemplate *volumeTemplate; - cTemplate *audiotracksTemplate; - map< string, map > pluginTemplates; + cViewChannel *channelView; + cViewMenu *menuView; + cViewMessage *messageView; + cViewReplay *replayView; + cViewVolume *volumeView; + cViewTracks *tracksView; cSDDisplayMenu *currentMenu; + map pluginViews; void Init(void); void ReloadCaches(void); - void DeleteTemplates(void); - bool LoadTemplates(void); - void CacheTemplates(void); + void DeleteViews(void); + bool LoadViews(void); + void LoadPluginViews(void); + void CacheViews(void); public: cSkinDesigner(string skin); virtual ~cSkinDesigner(void); @@ -45,13 +50,14 @@ public: virtual cSkinDisplayVolume *DisplayVolume(void); virtual cSkinDisplayTracks *DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks); virtual cSkinDisplayMessage *DisplayMessage(void); - virtual cSkinDisplayPlugin *DisplayPlugin(string pluginName, int viewID, int subViewID); void ActivateBackupSkin(void) { useBackupSkin = true; }; void Reload(void); void ListAvailableFonts(void); - bool SetCustomToken(string option); + bool SetCustomIntToken(string option); + bool SetCustomStringToken(string option); void ListCustomTokens(void); cSDDisplayMenu *GetDisplayMenu(void) { return currentMenu; }; + skindesignerapi::ISkinDisplayPlugin *GetDisplayPlugin(int plugId); }; #endif //__SKINDESIGNER_H diff --git a/displaychannel.c b/displaychannel.c index ff18da7..0b2fbdc 100644 --- a/displaychannel.c +++ b/displaychannel.c @@ -1,220 +1,36 @@ #include "displaychannel.h" -#include "libcore/timers.h" -cSDDisplayChannel::cSDDisplayChannel(cTemplate *channelTemplate, bool WithInfo) { - channelView = NULL; - - if (!channelTemplate) { - doOutput = false; - return; - } else { - doOutput = true; - } - groupSep = false; - present = NULL; - currentLast = 0; - channelChange = false; - initial = true; - devicesLast = cTimeMs::Now(); - currentChannelSid = -1; - isEncrypted = false; - - channelView = new cDisplayChannelView(channelTemplate->GetRootView()); - if (!channelView->createOsd()) { - doOutput = false; - return; - } - channelView->DrawDebugGrid(); +cSDDisplayChannel::cSDDisplayChannel(cViewChannel *channelView, bool WithInfo) { + view = channelView; + ok = view->Init(); + if (!ok) + esyslog("skindesigner: Error initiating displaychannel view - aborting"); } cSDDisplayChannel::~cSDDisplayChannel() { - if (channelView) - delete channelView; + view->Close(); } void cSDDisplayChannel::SetChannel(const cChannel *Channel, int Number) { - if (!doOutput) + if (!ok) return; - channelChange = true; - groupSep = false; - - cString ChannelNumber(""); - cString ChannelName(""); - cString ChannelID(""); - currentChannelSid = -1; - isEncrypted = false; - - if (Channel) { - ChannelName = Channel->Name() ? Channel->Name() : ""; - ChannelID = Channel->GetChannelID().ToString(); - currentChannelSid = Channel->Sid(); - isEncrypted = Channel->Ca(); - if (!Channel->GroupSep()) { - ChannelNumber = cString::sprintf("%d%s", Channel->Number(), Number ? "-" : ""); - } else { - groupSep = true; - } - } else if (Number) { - ChannelNumber = cString::sprintf("%d-", Number); - } else { - ChannelName = ChannelString(NULL, 0); - } - - channelView->ClearChannel(); - channelView->ClearEPGInfo(); - channelView->ClearStatusIcons(); - channelView->ClearChannelGroups(); - channelView->ClearScraperContent(); - channelView->ClearAudioInfo(); - channelView->ClearEncryptionInfo(); - if (!groupSep) { - channelView->DrawChannel(ChannelNumber, ChannelName, ChannelID, (Number > 0)?true:false); - channelView->DrawProgressBarBack(); - channelView->DrawSignalBackground(); - if (Channel) { - channelView->DrawStatusIcons(Channel); - channelView->DrawAudioInfo(); - } - } else { - channelView->ClearSignal(); - channelView->ClearSignalBackground(); - channelView->ClearProgressBar(); - channelView->ClearProgressBarBack(); - if (Channel) - channelView->DrawChannelGroups(Channel, ChannelName); - } - + view->SetChannel(Channel, Number); } void cSDDisplayChannel::SetEvents(const cEvent *Present, const cEvent *Following) { - if (!doOutput) + if (!ok) return; - - present = Present; - channelView->ClearProgressBar(); - if (!groupSep) { - channelView->ClearEPGInfo(); - } - - cGlobalSortedTimers SortedTimers;// local and remote timers - - bool recPresent = false; - if (Present) { - if (!groupSep) { - SetProgressBar(Present); - } - eTimerMatch TimerMatch = tmNone; - const cTimer *Timer = Timers.GetMatch(Present, &TimerMatch); - if (Timer && Timer->Recording()) { - recPresent = true; - } - for (int i = 0; i < SortedTimers.Size() && !recPresent; i++) - if (const cTimer *Timer = SortedTimers[i]) - if (Timer->Channel()->GetChannelID() == Present->ChannelID()) - if (const cEvent *timerEvent = Timer->Event()) - if (Present->EventID() == timerEvent->EventID()) - recPresent = Timer->Recording(); - - } - bool recFollowing = false; - if (Following) { - recFollowing = Following->HasTimer(); - for (int i = 0; i < SortedTimers.Size() && !recFollowing; i++) - if (const cTimer *Timer = SortedTimers[i]) - if (Timer->Channel()->GetChannelID() == Following->ChannelID()) - if (const cEvent *timerEvent = Timer->Event()) - if (Following->EventID() == timerEvent->EventID()) - recFollowing = true; - } - - if (Present || Following) { - channelView->DrawEPGInfo(Present, Following, recPresent, recFollowing); - channelView->DrawScraperContent(Present); - } + view->SetEvents(Present, Following); } -void cSDDisplayChannel::SetProgressBar(const cEvent *present) { - int Current = 0; - int Total = 0; - time_t t = time(NULL); - if (t > present->StartTime()) - Current = t - present->StartTime(); - Total = present->Duration(); - if ((Current > currentLast + 3) || initial || channelChange) { - currentLast = Current; - cString start = present->GetTimeString(); - cString stop = present->GetEndTimeString(); - channelView->DrawProgressBar(start, stop, Current, Total); - } -} - - void cSDDisplayChannel::SetMessage(eMessageType Type, const char *Text) { - if (!doOutput) + if (!ok) return; - channelView->ClearChannel(); - channelView->ClearEPGInfo(); - channelView->ClearStatusIcons(); - channelView->ClearScreenResolution(); - channelView->ClearProgressBar(); - channelView->ClearProgressBarBack(); - channelView->ClearSignal(); - channelView->ClearSignalBackground(); - channelView->ClearScraperContent(); - channelView->ClearAudioInfo(); - channelView->DisplayMessage(Type, Text); - groupSep = true; + view->SetMessage(Type, Text); } void cSDDisplayChannel::Flush(void) { - if (!doOutput) + if (!ok) return; - - if (initial) { - channelView->DrawBackground(); - channelView->DrawSignalBackground(); - channelView->DrawCurrentWeather(); - } - - if (initial || channelView->CustomTokenChange()) { - channelView->DrawCustomTokens(); - } - - if (initial || channelChange) { - channelView->DrawDate(); - } - channelView->DrawTime(); - - if (present) { - SetProgressBar(present); - } else { - channelView->ClearProgressBar(); - } - - if (!groupSep) { - channelView->DrawScreenResolution(); - channelView->DrawSignal(); - channelView->DrawAudioInfo(); - if (initial || cTimeMs::Now() - devicesLast > 500) { - channelView->DrawDevices(initial); - devicesLast = cTimeMs::Now(); - } - if (isEncrypted) { - channelView->DrawEncryptionInfo(currentChannelSid); - } - } else { - channelView->ClearStatusIcons(); - channelView->ClearScreenResolution(); - channelView->ClearSignal(); - channelView->ClearSignalBackground(); - channelView->ClearDevices(); - } - - if (initial) { - channelView->DoStart(); - } - - initial = false; - channelChange = false; - channelView->Flush(); + view->Flush(); } diff --git a/displaychannel.h b/displaychannel.h index b8d8973..f116f2c 100644 --- a/displaychannel.h +++ b/displaychannel.h @@ -1,34 +1,21 @@ #ifndef __DISPLAYCHANNEL_H #define __DISPLAYCHANNEL_H -#include +#include #include "config.h" -#include "libtemplate/template.h" -#include "views/displaychannelview.h" +#include "coreengine/definitions.h" +#include "coreengine/viewdisplaychannel.h" class cSDDisplayChannel : public cSkinDisplayChannel { private: - cDisplayChannelView *channelView; - bool doOutput; - bool initial; - bool groupSep; - bool channelChange; - time_t lastSignalDisplay; - int lastSignalStrength; - int lastSignalQuality; - int lastScreenWidth; - int currentLast; - uint64_t devicesLast; - const cEvent *present; - int currentChannelSid; - int isEncrypted; - void SetProgressBar(const cEvent *present); + cViewChannel *view; + bool ok; public: - cSDDisplayChannel(cTemplate *channelTemplate, bool WithInfo); + cSDDisplayChannel(cViewChannel *channelView, bool WithInfo); virtual ~cSDDisplayChannel(); virtual void SetChannel(const cChannel *Channel, int Number); virtual void SetEvents(const cEvent *Present, const cEvent *Following); virtual void SetMessage(eMessageType Type, const char *Text); virtual void Flush(void); }; -#endif //__DISPLAYCHANNEL_H \ No newline at end of file +#endif //__DISPLAYCHANNEL_H diff --git a/displaymenu.c b/displaymenu.c index 2e78793..c2cd486 100644 --- a/displaymenu.c +++ b/displaymenu.c @@ -1,345 +1,174 @@ -#include #include "displaymenu.h" -#include "libcore/helpers.h" -cSDDisplayMenu::cSDDisplayMenu(cTemplate *menuTemplate) { - textAreaFont = NULL; - rootView = NULL; - doOutput = true; - state = vsInit; - pluginMenu = -1; - pluginName = ""; - pluginMenuType = mtUnknown; - if (!menuTemplate) { - doOutput = false; - dsyslog("skindesigner: displayMenu no valid template - aborting"); - return; +cSDDisplayMenu::cSDDisplayMenu(cViewMenu *menuView) { + view = menuView; + bool ok = false; + if (view) + ok = view->Init(); + if (ok) { + SetCurrentRecording(); + } else { + esyslog("skindesigner: Error initiating displaymenu view - aborting"); } - rootView = new cDisplayMenuRootView(menuTemplate->GetRootView()); - if (!rootView->createOsd()) { - doOutput = false; - return; - } - SetCurrentRecording(); - rootView->DrawDebugGrid(); } cSDDisplayMenu::~cSDDisplayMenu() { - if (rootView) - delete rootView; - if (textAreaFont) - delete textAreaFont; + if (view) + view->Close(); } void cSDDisplayMenu::Scroll(bool Up, bool Page) { - if (!doOutput) - return; - rootView->KeyInput(Up, Page); + if (view) + view->KeyDetailView(Up, Page); } int cSDDisplayMenu::MaxItems(void) { - if (!doOutput) - return 0; - int maxItems = rootView->GetMaxItems(); - return maxItems; + if (view) + return view->NumListItems(); + return 0; } void cSDDisplayMenu::Clear(void) { - if (!doOutput) - return; - rootView->Clear(); + if (view) + view->Clear(); } void cSDDisplayMenu::SetMenuCategory(eMenuCategory MenuCat) { - if (!doOutput) - return; - rootView->SetMenu(MenuCat, (state == vsInit) ? true : false); - cSkinDisplayMenu::SetMenuCategory(MenuCat); - if (state != vsInit) - state = vsMenuInit; + if (view) + view->SetSubView(MenuCat); } void cSDDisplayMenu::SetMenuSortMode(eMenuSortMode MenuSortMode) { - if (!doOutput) - return; - rootView->SetSortMode(MenuSortMode); + if (view) + view->SetSortMode(MenuSortMode); } eMenuOrientation cSDDisplayMenu::MenuOrientation(void) { - if (!doOutput) - return moVertical; - return rootView->MenuOrientation(); + if (view) + return view->MenuOrientation(); + return moVertical; } -void cSDDisplayMenu::SetPluginMenu(string name, int menu, int type, bool init) { - pluginName = name; - pluginMenu = menu; - pluginMenuType = (ePluginMenuType)type; - rootView->SetPluginMenu(pluginName, pluginMenu, pluginMenuType); - if (!init) { - rootView->SetMenu(mcPlugin, false); - } +void cSDDisplayMenu::SetPluginMenu(int plugId, int menuId, int type, bool init) { + if (view) + view->SetPluginMenu(plugId, menuId); } void cSDDisplayMenu::SetTitle(const char *Title) { - if (!doOutput) - return; - rootView->SetTitle(Title); + if (view) + view->SetTitleHeader(Title); } void cSDDisplayMenu::SetButtons(const char *Red, const char *Green, const char *Yellow, const char *Blue) { - if (!doOutput) - return; - rootView->SetButtonTexts(Red, Green, Yellow, Blue); - if (state != vsInit && MenuCategory() != mcMain) - state = vsMenuInit; + if (view) + view->SetMenuButtons(Red, Green, Yellow, Blue); } void cSDDisplayMenu::SetMessage(eMessageType Type, const char *Text) { - if (!doOutput) - return; - rootView->SetMessage(Type, Text); - rootView->DoFlush(); + if (view) + view->SetMessage(Type, Text); } bool cSDDisplayMenu::SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch) { - if (!doOutput) - return true; - if (!rootView->SubViewAvailable()) + if (!view) return false; - if (config.blockFlush) - rootView->LockFlush(); - bool isFav = false; - if (MenuCategory() == mcSchedule && Channel) { - isFav = true; - rootView->SetEpgSearchFavorite(); + if (Index == 0) { + view->SetChannelHeader(Event); } - const cChannel *channel = Channel; - if (MenuCategory() == mcSchedule) { - if (!channel) { - channel = rootView->GetChannel(); - } - if (!channel && Event) { - channel = Channels.GetByChannelID(Event->ChannelID()); - } - rootView->SetChannel(channel); - } - - cDisplayMenuListView *list = rootView->GetListView(); - if (!list) - return false; - list->AddSchedulesMenuItem(Index, Event, channel, TimerMatch, MenuCategory(), isFav, Current, Selectable, ""); - if (state == vsIdle) - state = vsMenuUpdate; - return true; + return view->SetItemEvent(Event, Index, Current, Selectable, Channel, WithDate, TimerMatch); } bool cSDDisplayMenu::SetItemTimer(const cTimer *Timer, int Index, bool Current, bool Selectable) { - if (!doOutput) - return true; - if (!rootView->SubViewAvailable()) + if (!view) return false; - if (config.blockFlush) - rootView->LockFlush(); - cDisplayMenuListView *list = rootView->GetListView(); - if (!list) - return false; - list->AddTimersMenuItem(Index, Timer, Current, Selectable); - if (state == vsIdle) - state = vsMenuUpdate; - return true; + return view->SetItemTimer(Timer, Index, Current, Selectable); } bool cSDDisplayMenu::SetItemChannel(const cChannel *Channel, int Index, bool Current, bool Selectable, bool WithProvider) { - if (!doOutput) - return true; - if (!rootView->SubViewAvailable()) + if (!view) return false; - if (config.blockFlush) - rootView->LockFlush(); - cDisplayMenuListView *list = rootView->GetListView(); - if (!list) - return false; - list->AddChannelsMenuItem(Index, Channel, WithProvider, Current, Selectable); - if (state == vsIdle) - state = vsMenuUpdate; - return true; + return view->SetItemChannel(Channel, Index, Current, Selectable, WithProvider); } bool cSDDisplayMenu::SetItemRecording(const cRecording *Recording, int Index, bool Current, bool Selectable, int Level, int Total, int New) { - if (!doOutput) - return true; - if (!rootView->SubViewAvailable()) + if (!view) return false; - if (config.blockFlush) - rootView->LockFlush(); - cDisplayMenuListView *list = rootView->GetListView(); - if (!list) - return false; - - list->AddRecordingMenuItem(Index, Recording, Level, Total, New, Current, Selectable); - if (state == vsIdle) - state = vsMenuUpdate; - return true; -} - -bool cSDDisplayMenu::SetItemPlugin(map *stringTokens, map *intTokens, map > > *loopTokens, int Index, bool Current, bool Selectable) { - if (!doOutput) - return true; - if (!rootView->SubViewAvailable()) - return false; - if (config.blockFlush) - rootView->LockFlush(); - cDisplayMenuListView *list = rootView->GetListView(); - if (!list) - return false; - list->AddPluginMenuItem(stringTokens, intTokens, loopTokens, Index, Current, Selectable); - if (state == vsIdle) - state = vsMenuUpdate; - return true; + return view->SetItemRecording(Recording, Index, Current, Selectable, Level, Total, New); } void cSDDisplayMenu::SetItem(const char *Text, int Index, bool Current, bool Selectable) { - if (!doOutput) + if (!view) return; - //esyslog("skindesigner: %s %d - %s", Current ? "----->" : "", Index, Text); - cDisplayMenuListView *list = rootView->GetListView(); - if (!list) { - return; - } - if (config.blockFlush) - rootView->LockFlush(); - eMenuCategory cat = MenuCategory(); - if (cat == mcMain && rootView->SubViewAvailable()) { - string plugName = list->AddMainMenuItem(Index, Text, Current, Selectable); - if (Current) { - rootView->SetSelectedPluginMainMenu(plugName); - } - } else if (cat == mcSetup && rootView->SubViewAvailable()) { - list->AddSetupMenuItem(Index, Text, Current, Selectable); - } else if ((cat == mcSchedule || cat == mcScheduleNow || cat == mcScheduleNext) && rootView->SubViewAvailable()) { - list->AddSchedulesMenuItem(Index, NULL, NULL, tmNone, MenuCategory(), false, Current, Selectable, Text ? Text : ""); - } else { - rootView->CorrectDefaultMenu(); - string *tabTexts = new string[MaxTabs]; - for (int i=0; iAddDefaultMenuItem(Index, tabTexts, Current, Selectable); - SetEditableWidth( rootView->GetListViewWidth() / 2); - } - if (state == vsIdle) - state = vsMenuUpdate; + view->SetItem(Text, Index, Current, Selectable); + SetEditableWidth(view->GetListWidth() / 2); +} + +bool cSDDisplayMenu::SetItemPlugin(skindesignerapi::cTokenContainer *tk, int Index, bool Current, bool Selectable) { + if (!view) + return false; + bool ok = view->SetItemPlugin(tk, Index, Current, Selectable); + return ok; } void cSDDisplayMenu::SetTabs(int Tab1, int Tab2, int Tab3, int Tab4, int Tab5) { - if (!doOutput) - return; - rootView->SetTabs(Tab1, Tab2, Tab3, Tab4, Tab5); + if (view) + view->SetTabs(Tab1, Tab2, Tab3, Tab4, Tab5); } int cSDDisplayMenu::GetTextAreaWidth(void) const { - int areaWidth = rootView->GetTextAreaWidth(); - return areaWidth; + if (view) + return view->GetTextAreaWidth(); + return 0; } const cFont *cSDDisplayMenu::GetTextAreaFont(bool FixedFont) const { - if (textAreaFont) - return textAreaFont; - textAreaFont = rootView->GetTextAreaFont(); - return textAreaFont; + if (view) + return view->GetTextAreaFont(); + return NULL; } void cSDDisplayMenu::SetScrollbar(int Total, int Offset) { - if (!doOutput) - return; - rootView->RenderMenuScrollBar(Total, Offset); + if (view) + view->SetScrollbar(Total, Offset); } void cSDDisplayMenu::SetEvent(const cEvent *Event) { - if (!doOutput) - return; - rootView->SetDetailedViewEvent(Event); - state = vsMenuDetail; + if (view) + view->SetEvent(Event); } void cSDDisplayMenu::SetRecording(const cRecording *Recording) { - if (!doOutput) - return; - rootView->SetDetailedViewRecording(Recording); - state = vsMenuDetail; + if (view) + view->SetRecording(Recording); } void cSDDisplayMenu::SetText(const char *Text, bool FixedFont) { - if (!doOutput) - return; - rootView->SetDetailedViewText(Text); - state = vsMenuDetail; + if (view) + view->SetText(Text); } -bool cSDDisplayMenu::SetPluginText(map *stringTokens, map *intTokens, map > > *loopTokens) { - if (!doOutput) - return true; - bool tmplOk = rootView->SetDetailedViewPlugin(stringTokens, intTokens, loopTokens); - state = vsMenuDetail; - return tmplOk; +bool cSDDisplayMenu::SetPluginText(skindesignerapi::cTokenContainer *tk) { + bool ok = false; + if (view) + ok = view->SetPluginText(tk); + return ok; } void cSDDisplayMenu::Flush(void) { - if (!doOutput) - return; - bool doFlush = false; - if (state == vsInit) { - rootView->Start(); - rootView->RenderMenuItems(); - doFlush = true; - } else if (state == vsMenuInit) { - rootView->Render(); - rootView->RenderMenuItems(); - doFlush = true; - } else if (state == vsMenuUpdate) { - rootView->RenderMenuItems(); - doFlush = true; - } else if (state == vsMenuDetail) { - rootView->OpenFlush(); - rootView->Render(); - rootView->DoFlush(); - rootView->RenderDetailView(); - rootView->DoFlush(); - } - - if (rootView->RenderDynamicElements()) { - doFlush = true; - } - - if (doFlush) { - if (config.blockFlush) - rootView->OpenFlush(); - rootView->DoFlush(); - } - state = vsIdle; + if (view) + view->Flush(); } void cSDDisplayMenu::SetCurrentRecording(void) { cControl *control = cControl::Control(); if (!control) { + view->SetCurrentRecording(NULL); return; } const cRecording *recording = control->GetRecording(); if (!recording) { + view->SetCurrentRecording(NULL); return; } - string recFileName = ""; - if (recording->FileName()) { - recFileName = recording->FileName(); - } - rootView->SetCurrentRecording(recFileName); -} + view->SetCurrentRecording(recording->FileName()); +} \ No newline at end of file diff --git a/displaymenu.h b/displaymenu.h index 6600a9a..4f49d8c 100644 --- a/displaymenu.h +++ b/displaymenu.h @@ -11,31 +11,16 @@ enum eMenuOrientation { #endif #include "libskindesignerapi/skindesignerapi.h" -#include "libtemplate/template.h" -#include "views/displaymenurootview.h" - -enum eViewState { - vsInit, - vsMenuInit, - vsMenuUpdate, - vsMenuDetail, - vsIdle -}; +#include +#include "coreengine/viewdisplaymenu.h" class cSDDisplayMenu : public skindesignerapi::ISDDisplayMenu { private: - cDisplayMenuRootView *rootView; - eViewState state; - bool doOutput; - string pluginName; - int pluginMenu; - ePluginMenuType pluginMenuType; - mutable cFont *textAreaFont; + cViewMenu *view; + bool ok; void SetCurrentRecording(void); -protected: - int Tab(int n); public: - cSDDisplayMenu(cTemplate *menuTemplate); + cSDDisplayMenu(cViewMenu *menuView); virtual ~cSDDisplayMenu(); virtual void Scroll(bool Up, bool Page); virtual int MaxItems(void); @@ -43,21 +28,21 @@ public: virtual void SetMenuCategory(eMenuCategory MenuCat); virtual void SetMenuSortMode(eMenuSortMode MenuSortMode); virtual eMenuOrientation MenuOrientation(void); - virtual void SetPluginMenu(string name, int menu, int type, bool init); + virtual void SetPluginMenu(int plugId, int menuId, int type, bool init); virtual void SetTitle(const char *Title); virtual void SetButtons(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL); virtual void SetMessage(eMessageType Type, const char *Text); - virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable); virtual bool SetItemEvent(const cEvent *Event, int Index, bool Current, bool Selectable, const cChannel *Channel, bool WithDate, eTimerMatch TimerMatch); virtual bool SetItemTimer(const cTimer *Timer, int Index, bool Current, bool Selectable); virtual bool SetItemChannel(const cChannel *Channel, int Index, bool Current, bool Selectable, bool WithProvider); virtual bool SetItemRecording(const cRecording *Recording, int Index, bool Current, bool Selectable, int Level, int Total, int New); - virtual bool SetItemPlugin(map *stringTokens, map *intTokens, map > > *loopTokens, int Index, bool Current, bool Selectable); + virtual void SetItem(const char *Text, int Index, bool Current, bool Selectable); + virtual bool SetItemPlugin(skindesignerapi::cTokenContainer *tk, int Index, bool Current, bool Selectable); virtual void SetScrollbar(int Total, int Offset); virtual void SetEvent(const cEvent *Event); virtual void SetRecording(const cRecording *Recording); virtual void SetText(const char *Text, bool FixedFont); - virtual bool SetPluginText(map *stringTokens, map *intTokens, map > > *loopTokens); + virtual bool SetPluginText(skindesignerapi::cTokenContainer *tk); virtual void Flush(void); virtual void SetTabs(int Tab1, int Tab2 = 0, int Tab3 = 0, int Tab4 = 0, int Tab5 = 0); virtual int GetTextAreaWidth(void) const; diff --git a/displaymessage.c b/displaymessage.c index c125fd3..535f6d5 100644 --- a/displaymessage.c +++ b/displaymessage.c @@ -1,46 +1,25 @@ #include "displaymessage.h" -cSDDisplayMessage::cSDDisplayMessage(cTemplate *messageTemplate) { - messageView = NULL; - doOutput = true; - initial = true; - if (!messageTemplate) { - doOutput = false; - esyslog("skindesigner: displayMessage no valid template - aborting"); - return; - } - messageView = new cDisplayMessageView(messageTemplate->GetRootView()); - if (!messageView->createOsd()) { - doOutput = false; - return; - } - messageView->DrawDebugGrid(); - messageView->DrawBackground(); +cSDDisplayMessage::cSDDisplayMessage(cViewMessage *messageView) { + view = messageView; + ok = view->Init(); + if (!ok) + esyslog("skindesigner: Error initiating displaymessage view - aborting"); } cSDDisplayMessage::~cSDDisplayMessage() { - if (messageView) - delete messageView; + view->Close(); } void cSDDisplayMessage::SetMessage(eMessageType Type, const char *Text) { - if (!doOutput) + if (!ok) return; - messageView->ClearMessage(); - if (!Text) { - return; - } - messageView->DrawMessage(Type, Text); + view->SetMessage(Type, Text); } void cSDDisplayMessage::Flush(void) { - if (!doOutput) + if (!ok) return; - if (initial) { - messageView->DoFadeIn(); - initial = false; - } else { - messageView->Flush(); - } + view->Flush(); } diff --git a/displaymessage.h b/displaymessage.h index f1fd01b..e6e46c6 100644 --- a/displaymessage.h +++ b/displaymessage.h @@ -1,22 +1,18 @@ #ifndef __DISPLAYMESSAGE_H #define __DISPLAYMESSAGE_H -#include -#include #include "config.h" -#include "libtemplate/template.h" -#include "views/displaymessageview.h" +#include "coreengine/viewdisplaymessage.h" class cSDDisplayMessage : public cSkinDisplayMessage { private: - cDisplayMessageView *messageView; - bool doOutput; - bool initial; + cViewMessage *view; + bool ok; public: - cSDDisplayMessage(cTemplate *messageTemplate); + cSDDisplayMessage(cViewMessage *messageView); virtual ~cSDDisplayMessage(); virtual void SetMessage(eMessageType Type, const char *Text); virtual void Flush(void); }; -#endif //__DISPLAYMESSAGE_H \ No newline at end of file +#endif //__DISPLAYMESSAGE_H diff --git a/displayplugin.c b/displayplugin.c deleted file mode 100644 index 35e92e7..0000000 --- a/displayplugin.c +++ /dev/null @@ -1,201 +0,0 @@ -#include "config.h" -#include "displayplugin.h" - -cSkinDisplayPlugin::cSkinDisplayPlugin(cTemplate *pluginTemplate, int subViewID) { - if (!pluginTemplate) { - doOutput = false; - return; - } else { - doOutput = true; - } - initial = true; - if (subViewID > -1) { - cTemplateView *subView = pluginTemplate->GetRootView()->GetSubView((eSubView)subViewID); - if (!subView) { - doOutput = false; - return; - } - pluginView = new cDisplayPluginView(subView, false); - } else { - pluginView = new cDisplayPluginView(pluginTemplate->GetRootView(), true); - } - if (!pluginView->createOsd() && subViewID < 0) { - doOutput = false; - return; - } - pluginView->DrawDebugGrid(); -} - -cSkinDisplayPlugin::~cSkinDisplayPlugin(void) { - if (pluginView) { - delete pluginView; - pluginView = NULL; - } -} - -void cSkinDisplayPlugin::Deactivate(bool hide) { - if (!doOutput) { - return; - } - pluginView->Deactivate(hide); -} - -void cSkinDisplayPlugin::Activate(void) { - if (!doOutput) { - return; - } - pluginView->Activate(); -} - - -void cSkinDisplayPlugin::ClearViewElement(int id) { - if (!doOutput) { - return; - } - pluginView->CleanViewElement(id); -} - -void cSkinDisplayPlugin::DisplayViewElement(int id) { - if (!doOutput) { - return; - } - pluginView->DisplayViewElement(id); -} - -void cSkinDisplayPlugin::SetViewElementIntTokens(map *intTokens) { - if (pluginView) - pluginView->SetIntTokens(intTokens); -} - -void cSkinDisplayPlugin::SetViewElementStringTokens(map *stringTokens) { - if (pluginView) - pluginView->SetStringTokens(stringTokens); -} - -void cSkinDisplayPlugin::SetViewElementLoopTokens(map > > *loopTokens) { - if (pluginView) - pluginView->SetLoopTokens(loopTokens); -} - -void cSkinDisplayPlugin::InitGrids(int viewGridID) { - if (!doOutput) { - return; - } - pluginView->InitGrids(viewGridID); -} - -void cSkinDisplayPlugin::SetGrid(int viewGridID, long gridID, - double x, double y, double width, double height, - map *intTokens, map *stringTokens) { - if (!doOutput) { - return; - } - pluginView->SetGrid(viewGridID, gridID, x, y, width, height, intTokens, stringTokens); -} - -void cSkinDisplayPlugin::SetGridCurrent(int viewGridID, long gridID, bool current) { - if (!doOutput) { - return; - } - pluginView->SetGridCurrent(viewGridID, gridID, current); -} - -void cSkinDisplayPlugin::DeleteGrid(int viewGridID, long gridID) { - if (!doOutput) { - return; - } - pluginView->DeleteGrid(viewGridID, gridID); -} - -void cSkinDisplayPlugin::DisplayGrids(int viewGridID) { - if (!doOutput) { - return; - } - pluginView->DisplayGrids(viewGridID); -} - -void cSkinDisplayPlugin::ClearGrids(int viewGridID) { - if (!doOutput) { - return; - } - pluginView->ClearGrids(viewGridID); -} - -void cSkinDisplayPlugin::SetTabIntTokens(map *intTokens) { - if (!doOutput) { - return; - } - pluginView->SetTabIntTokens(intTokens); -} - -void cSkinDisplayPlugin::SetTabStringTokens(map *stringTokens) { - if (!doOutput) { - return; - } - pluginView->SetTabStringTokens(stringTokens); -} - -void cSkinDisplayPlugin::SetTabLoopTokens(map > > *loopTokens) { - if (!doOutput) { - return; - } - pluginView->SetTabLoopTokens(loopTokens); -} - -void cSkinDisplayPlugin::SetTabs(void) { - if (!doOutput) { - return; - } - pluginView->SetTabs(); -} - -void cSkinDisplayPlugin::TabLeft(void) { - if (!doOutput) { - return; - } - pluginView->TabLeft(); -} - -void cSkinDisplayPlugin::TabRight(void) { - if (!doOutput) { - return; - } - pluginView->TabRight(); -} - -void cSkinDisplayPlugin::TabUp(void) { - if (!doOutput) { - return; - } - pluginView->TabUp(); -} - -void cSkinDisplayPlugin::TabDown(void) { - if (!doOutput) { - return; - } - pluginView->TabDown(); -} - -void cSkinDisplayPlugin::DisplayTabs(void) { - if (!doOutput) { - return; - } - pluginView->DisplayTab(); -} - -void cSkinDisplayPlugin::Flush(void) { - if (initial) { - pluginView->DoStart(); - initial = false; - } - pluginView->Flush(); -} - -bool cSkinDisplayPlugin::ChannelLogoExists(string channelId) { - return imgCache->LogoExists(channelId); -} - -string cSkinDisplayPlugin::GetEpgImagePath(void) { - return *config.epgImagePath; -} \ No newline at end of file diff --git a/displayplugin.h b/displayplugin.h deleted file mode 100644 index 092c0a9..0000000 --- a/displayplugin.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef __DISPLAYPLUGIN_H -#define __DISPLAYPLUGIN_H - -#include "libskindesignerapi/skindesignerapi.h" -#include "libtemplate/template.h" -#include "views/displaypluginview.h" - -class cSkinDisplayPlugin : public skindesignerapi::ISkinDisplayPlugin { -private: - bool doOutput; - bool initial; - cDisplayPluginView *pluginView; -public: - cSkinDisplayPlugin(void) {}; - cSkinDisplayPlugin(cTemplate *pluginTemplate, int subViewID); - virtual ~cSkinDisplayPlugin(void); - virtual void Deactivate(bool hide); - virtual void Activate(void); - virtual void ClearViewElement(int id); - virtual void DisplayViewElement(int id); - virtual void SetViewElementIntTokens(map *intTokens); - virtual void SetViewElementStringTokens(map *stringTokens); - virtual void SetViewElementLoopTokens(map > > *loopTokens); - virtual void InitGrids(int viewGridID); - virtual void SetGrid(int viewGridID, long gridID, double x, double y, double width, double height, map *intTokens, map *stringTokens); - virtual void SetGridCurrent(int viewGridID, long gridID, bool current); - virtual void DeleteGrid(int viewGridID, long gridID); - virtual void DisplayGrids(int viewGridID); - virtual void ClearGrids(int viewGridID); - virtual void SetTabIntTokens(map *intTokens); - virtual void SetTabStringTokens(map *stringTokens); - virtual void SetTabLoopTokens(map > > *loopTokens); - virtual void SetTabs(void); - virtual void TabLeft(void); - virtual void TabRight(void); - virtual void TabUp(void); - virtual void TabDown(void); - virtual void DisplayTabs(void); - virtual void Flush(void); - virtual bool ChannelLogoExists(string channelId); - virtual string GetEpgImagePath(void); -}; - -#endif //__DISPLAYPLUGIN_H diff --git a/displayreplay.c b/displayreplay.c index b57a696..02df55a 100644 --- a/displayreplay.c +++ b/displayreplay.c @@ -1,129 +1,84 @@ #define __STL_CONFIG_H -#include #include "displayreplay.h" -cSDDisplayReplay::cSDDisplayReplay(cTemplate *replayTemplate, bool ModeOnly) { - doOutput = true; - initial = true; - initialModeSet = false; - modeOnly = ModeOnly; - replayView = NULL; - if (!replayTemplate) { - doOutput = false; - esyslog("skindesigner: displayReplay no valid template - aborting"); - return; - } - replayView = new cDisplayReplayView(replayTemplate->GetRootView()); - if (!replayView->createOsd()) { - doOutput = false; - return; - } - replayView->DrawDebugGrid(); +cSDDisplayReplay::cSDDisplayReplay(cViewReplay *replayView, bool ModeOnly) { + init = true; + view = replayView; + ok = view->Init(); + if (!ok) + esyslog("skindesigner: Error initiating displayreplay view - aborting"); + view->SetModeOnly(ModeOnly); } cSDDisplayReplay::~cSDDisplayReplay() { - if (replayView) - delete replayView; + view->Close(); } void cSDDisplayReplay::SetRecording(const cRecording *Recording) { - if (!doOutput || !Recording) - return; - if (initial) { - replayView->SetRecordingLength(Recording->LengthInSeconds()); - SetTimeShiftValues(Recording); + if (ok) { + view->SetRecording(Recording); + if (init) { + view->SetRecordingLength(Recording->LengthInSeconds()); + SetTimeShiftValues(Recording); + init = false; + } } - replayView->DrawTitle(Recording); - replayView->DrawRecordingInformation(Recording); - replayView->DrawScraperContent(Recording); } void cSDDisplayReplay::SetTitle(const char *Title) { - if (!doOutput || !Title) - return; - replayView->DrawTitle(Title); + view->SetTitle(Title); } void cSDDisplayReplay::SetMode(bool Play, bool Forward, int Speed) { - if (!doOutput) + if (!ok) return; if (!Play && Speed < 0) { - string recFileName = ""; cControl *control = cControl::Control(); if (control) { const cRecording *recording = control->GetRecording(); - if (recording && recording->FileName()) - recFileName = recording->FileName(); + if (recording && recording->FileName()) { + view->StartOnPause(recording->FileName()); + } } - replayView->DrawOnPause(recFileName, modeOnly); } else { - replayView->ClearOnPause(); + view->ClearOnPause(); } - replayView->DrawControlIcons(Play, Forward, Speed, modeOnly); - initialModeSet = true; + view->SetControlIcons(Play, Forward, Speed); } void cSDDisplayReplay::SetProgress(int Current, int Total) { - if (!doOutput) - return; - replayView->DelayOnPause(); - replayView->DrawProgressBar(Current, Total); - replayView->DrawMarks(marks, Current, Total); - replayView->DrawEndTime(Current, Total); + if (ok) { + view->SetProgressbar(Current, Total); + view->SetMarks(marks, Current, Total); + view->SetEndTime(Current, Total); + } } void cSDDisplayReplay::SetCurrent(const char *Current) { - if (!doOutput) - return; - replayView->DrawCurrent(Current); + if (ok) + view->SetCurrent(Current); } void cSDDisplayReplay::SetTotal(const char *Total) { - if (!doOutput) - return; - replayView->DrawTotal(Total); + if (ok) + view->SetTotal(Total); } void cSDDisplayReplay::SetJump(const char *Jump) { - if (!doOutput) - return; - replayView->DrawJump(Jump); + if (ok) + view->SetJump(Jump); } void cSDDisplayReplay::SetMessage(eMessageType Type, const char *Text) { - if (!doOutput) - return; - replayView->DrawMessage(Type, Text); + if (ok) + view->SetMessage(Type, Text); } void cSDDisplayReplay::Flush(void) { - if (!doOutput) + if (!ok) return; - if (!modeOnly) { - replayView->DrawDate(); - replayView->DrawTime(); - } - if (modeOnly) { - cControl *control = cControl::Control(); - if (control) { - double fps = control->FramesPerSecond(); - int current = 0; - int total = 0; - if (control->GetIndex(current, total)) - replayView->DrawProgressModeOnly(fps, current, total); - } - } - if (initial && initialModeSet) { - replayView->DrawBackground(modeOnly); - replayView->DrawCustomTokens(); - replayView->DoFadeIn(); - initial = false; - } else { - if (replayView->CustomTokenChange()) - replayView->DrawCustomTokens(); - replayView->Flush(); - } + view->Flush(); } void cSDDisplayReplay::SetTimeShiftValues(const cRecording *recording) { @@ -146,5 +101,5 @@ void cSDDisplayReplay::SetTimeShiftValues(const cRecording *recording) { time_t recordingStart = time(0) - recording->LengthInSeconds(); int framesTotal = (liveEventStop - recordingStart)*fps; int recLength = liveEventStop - recordingStart; - replayView->SetTimeShift(framesTotal, recLength); + view->SetTimeShift(framesTotal, recLength); } diff --git a/displayreplay.h b/displayreplay.h index 04840c5..2c4fa77 100644 --- a/displayreplay.h +++ b/displayreplay.h @@ -2,21 +2,17 @@ #define __DISPLAYREPLAY_H #include -#include #include "config.h" -#include "libtemplate/template.h" -#include "views/displayreplayview.h" +#include "coreengine/viewdisplayreplay.h" class cSDDisplayReplay : public cSkinDisplayReplay { private: - cDisplayReplayView *replayView; - bool initial; - bool initialModeSet; - bool doOutput; - bool modeOnly; + bool ok; + bool init; + cViewReplay *view; void SetTimeShiftValues(const cRecording *recording); public: - cSDDisplayReplay(cTemplate *replayTemplate, bool ModeOnly); + cSDDisplayReplay(cViewReplay *replayView, bool ModeOnly); virtual ~cSDDisplayReplay(); virtual void SetRecording(const cRecording *Recording); virtual void SetTitle(const char *Title); @@ -29,4 +25,4 @@ public: virtual void Flush(void); }; -#endif //__DISPLAYREPLAY_H \ No newline at end of file +#endif //__DISPLAYREPLAY_H diff --git a/displaytracks.c b/displaytracks.c index 184163d..a7420f6 100644 --- a/displaytracks.c +++ b/displaytracks.c @@ -1,59 +1,31 @@ #include "displaytracks.h" - -cSDDisplayTracks::cSDDisplayTracks(cTemplate *audiotracksTemplate, const char *Title, int NumTracks, const char * const *Tracks) { - initial = true; - numTracks = NumTracks; - tracksView = NULL; - doOutput = true; - currentTrack = 0; - menuTitle = Title; - if (!audiotracksTemplate) { - esyslog("skindesigner: displayTracks no valid template - aborting"); - doOutput = false; - return; - } - tracksView = new cDisplayAudiotracksView(NumTracks, audiotracksTemplate->GetRootView()); - if (!tracksView->createOsd()) { - doOutput = false; - return; - } - tracksView->DrawDebugGrid(); - tracksView->DrawBackground(); - - cDisplayMenuListView *list = tracksView->GetListView(); - if (list) { - for (int i = 0; i < NumTracks; i++) { - list->AddTracksMenuItem(i, Tracks[i], (i==currentTrack)?true:false, true); - } - } +cSDDisplayTracks::cSDDisplayTracks(cViewTracks *tracksView, const char *Title, int NumTracks, const char * const *Tracks) { + view = tracksView; + ok = view->Init(); + if (!ok) + esyslog("skindesigner: Error initiating displaytracks view - aborting"); + view->SetTitle(Title); + view->SetNumtracks(NumTracks); + view->SetTracks(Tracks); } cSDDisplayTracks::~cSDDisplayTracks() { - if (tracksView) - delete tracksView; + view->Close(); } void cSDDisplayTracks::SetTrack(int Index, const char * const *Tracks) { - cDisplayMenuListView *list = tracksView->GetListView(); - if (list) { - list->AddTracksMenuItem(currentTrack, Tracks[currentTrack], false, true); - list->AddTracksMenuItem(Index, Tracks[Index], true, true); - currentTrack = Index; - } + if (ok) + view->SetCurrentTrack(Index); } void cSDDisplayTracks::SetAudioChannel(int AudioChannel) { - tracksView->DrawHeader(menuTitle, AudioChannel); + if (ok) + view->SetAudiochannel(AudioChannel); } void cSDDisplayTracks::Flush(void) { - if (!doOutput) + if (!ok) return; - if (initial) { - tracksView->DoFadeIn(); - } - initial = false; - tracksView->RenderMenuItems(); - tracksView->Flush(); + view->Flush(); } diff --git a/displaytracks.h b/displaytracks.h index 4dd978c..b4555c5 100644 --- a/displaytracks.h +++ b/displaytracks.h @@ -2,21 +2,15 @@ #define __DISPLAYTRACKS_H #include -#include #include "config.h" -#include "libtemplate/template.h" -#include "views/displayaudiotracksview.h" +#include "coreengine/viewdisplaytracks.h" class cSDDisplayTracks : public cSkinDisplayTracks { private: - cDisplayAudiotracksView *tracksView; - bool initial; - int numTracks; - bool doOutput; - int currentTrack; - const char *menuTitle; + cViewTracks *view; + bool ok; public: - cSDDisplayTracks(cTemplate *audiotracksTemplate, const char *Title, int NumTracks, const char * const *Tracks); + cSDDisplayTracks(cViewTracks *tracksView, const char *Title, int NumTracks, const char * const *Tracks); virtual ~cSDDisplayTracks(); virtual void SetTrack(int Index, const char * const *Tracks); virtual void SetAudioChannel(int AudioChannel); @@ -24,4 +18,4 @@ public: }; -#endif //__DISPLAYTRACKS_H \ No newline at end of file +#endif //__DISPLAYTRACKS_H diff --git a/displayvolume.c b/displayvolume.c index d50e470..02e61d5 100644 --- a/displayvolume.c +++ b/displayvolume.c @@ -1,44 +1,26 @@ #include "displayvolume.h" #include "config.h" -#include "libcore/helpers.h" -cSDDisplayVolume::cSDDisplayVolume(cTemplate *volumeTemplate) { - volumeView = NULL; - doOutput = true; - initial = true; - if (!volumeTemplate) { - doOutput = false; - esyslog("skindesigner: displayVolume no valid template - aborting"); - return; - } - volumeView = new cDisplayVolumeView(volumeTemplate->GetRootView()); - if (!volumeView->createOsd()) { - doOutput = false; - } else { - volumeView->DrawDebugGrid(); - volumeView->DrawBackground(); - } +cSDDisplayVolume::cSDDisplayVolume(cViewVolume *volumeView) { + view = volumeView; + ok = view->Init(); + if (!ok) + esyslog("skindesigner: Error initiating displayvolume view - aborting"); } cSDDisplayVolume::~cSDDisplayVolume() { - if (volumeView) - delete volumeView; + view->Close(); } void cSDDisplayVolume::SetVolume(int Current, int Total, bool Mute) { - if (!doOutput) + if (!ok) return; - volumeView->DrawVolume(Current, Total, Mute); + view->SetVolume(Current, Total, Mute); } void cSDDisplayVolume::Flush(void) { - if (!doOutput) + if (!ok) return; - if (initial) { - volumeView->DoFadeIn(); - initial = false; - } else { - volumeView->Flush(); - } + view->Flush(); } diff --git a/displayvolume.h b/displayvolume.h index 1bfc877..4dde35a 100644 --- a/displayvolume.h +++ b/displayvolume.h @@ -1,21 +1,18 @@ #ifndef __DISPLAYVOLUME_H #define __DISPLAYVOLUME_H -#include #include "config.h" -#include "libtemplate/template.h" -#include "views/displayvolumeview.h" +#include "coreengine/viewdisplayvolume.h" class cSDDisplayVolume : public cSkinDisplayVolume { private: - cDisplayVolumeView *volumeView; - bool doOutput; - bool initial; + cViewVolume *view; + bool ok; public: - cSDDisplayVolume(cTemplate *volumeTemplate); + cSDDisplayVolume(cViewVolume *volumeView); virtual ~cSDDisplayVolume(); virtual void SetVolume(int Current, int Total, bool Mute); virtual void Flush(void); }; -#endif //__DISPLAYVOLUME_H \ No newline at end of file +#endif //__DISPLAYVOLUME_H diff --git a/dtd/displaychannel.dtd b/dtd/displaychannel.dtd index 589f372..9fb6ada 100644 --- a/dtd/displaychannel.dtd +++ b/dtd/displaychannel.dtd @@ -26,79 +26,162 @@ - @@ -269,6 +306,7 @@ y CDATA #REQUIRED width CDATA #REQUIRED height CDATA #REQUIRED + orientation CDATA #IMPLIED fadetime CDATA #IMPLIED scaletvx CDATA #IMPLIED scaletvy CDATA #IMPLIED @@ -285,6 +323,7 @@ y CDATA #REQUIRED width CDATA #REQUIRED height CDATA #REQUIRED + orientation CDATA #IMPLIED fadetime CDATA #IMPLIED scaletvx CDATA #IMPLIED scaletvy CDATA #IMPLIED @@ -299,6 +338,7 @@ y CDATA #REQUIRED width CDATA #REQUIRED height CDATA #REQUIRED + orientation CDATA #IMPLIED fadetime CDATA #IMPLIED scaletvx CDATA #IMPLIED scaletvy CDATA #IMPLIED @@ -313,6 +353,7 @@ y CDATA #REQUIRED width CDATA #REQUIRED height CDATA #REQUIRED + orientation CDATA #IMPLIED fadetime CDATA #IMPLIED scaletvx CDATA #IMPLIED scaletvy CDATA #IMPLIED @@ -327,6 +368,7 @@ y CDATA #REQUIRED width CDATA #REQUIRED height CDATA #REQUIRED + orientation CDATA #IMPLIED fadetime CDATA #IMPLIED scaletvx CDATA #IMPLIED scaletvy CDATA #IMPLIED @@ -341,6 +383,7 @@ y CDATA #REQUIRED width CDATA #REQUIRED height CDATA #REQUIRED + orientation CDATA #IMPLIED fadetime CDATA #IMPLIED scaletvx CDATA #IMPLIED scaletvy CDATA #IMPLIED @@ -355,6 +398,7 @@ y CDATA #REQUIRED width CDATA #REQUIRED height CDATA #REQUIRED + orientation CDATA #IMPLIED fadetime CDATA #IMPLIED scaletvx CDATA #IMPLIED scaletvy CDATA #IMPLIED @@ -429,10 +473,16 @@ diff --git a/dtd/displaymenuplugin.dtd b/dtd/displaymenuplugin.dtd index 168d047..845f90d 100644 --- a/dtd/displaymenuplugin.dtd +++ b/dtd/displaymenuplugin.dtd @@ -13,49 +13,87 @@ scaletvy CDATA #IMPLIED scaletvwidth CDATA #IMPLIED scaletvheight CDATA #IMPLIED + orientation CDATA #IMPLIED debuggrid CDATA #IMPLIED > @@ -85,7 +123,7 @@ diff --git a/dtd/displayreplay.dtd b/dtd/displayreplay.dtd index f15fb74..91c23cc 100644 --- a/dtd/displayreplay.dtd +++ b/dtd/displayreplay.dtd @@ -27,29 +27,56 @@ @@ -138,6 +242,11 @@ debug CDATA #IMPLIED delay CDATA #REQUIRED fadetime CDATA #IMPLIED + shifttime CDATA #IMPLIED + shifttype CDATA #IMPLIED + shiftmode CDATA #IMPLIED + startx CDATA #IMPLIED + starty CDATA #IMPLIED condition CDATA #IMPLIED > @@ -146,11 +255,23 @@ debug CDATA #IMPLIED delay CDATA #REQUIRED fadetime CDATA #IMPLIED + shifttime CDATA #IMPLIED + shifttype CDATA #IMPLIED + shiftmode CDATA #IMPLIED + startx CDATA #IMPLIED + starty CDATA #IMPLIED condition CDATA #IMPLIED > diff --git a/dtd/functions.dtd b/dtd/functions.dtd index 7b08437..b7b4e0a 100644 --- a/dtd/functions.dtd +++ b/dtd/functions.dtd @@ -90,8 +90,8 @@ #include #include +#include "../coreengine/definitions.h" using namespace std; diff --git a/libcore/curlfuncs.c b/extensions/curlfuncs.c similarity index 100% rename from libcore/curlfuncs.c rename to extensions/curlfuncs.c diff --git a/libcore/curlfuncs.h b/extensions/curlfuncs.h similarity index 100% rename from libcore/curlfuncs.h rename to extensions/curlfuncs.h diff --git a/libcore/extrecinfo.c b/extensions/extrecinfo.c similarity index 100% rename from libcore/extrecinfo.c rename to extensions/extrecinfo.c diff --git a/libcore/extrecinfo.h b/extensions/extrecinfo.h similarity index 100% rename from libcore/extrecinfo.h rename to extensions/extrecinfo.h diff --git a/libcore/fontmanager.c b/extensions/fontmanager.c similarity index 87% rename from libcore/fontmanager.c rename to extensions/fontmanager.c index 2f1e79c..47e2885 100644 --- a/libcore/fontmanager.c +++ b/extensions/fontmanager.c @@ -7,38 +7,13 @@ using namespace std; cMutex cFontManager::mutex; -cFontManager::cFontManager() { +cFontManager::cFontManager(void) { } -cFontManager::~cFontManager() { +cFontManager::~cFontManager(void) { DeleteFonts(); } -void cFontManager::CacheFonts(cTemplate *tpl) { - cMutexLock MutexLock(&mutex); - - vector< pair > usedFonts = tpl->GetUsedFonts(); - - cStringList availableFonts; - cFont::GetAvailableFontNames(&availableFonts); - - for (vector< pair >::iterator ft = usedFonts.begin(); ft != usedFonts.end(); ft++) { - string fontName = ft->first; - int fontSize = ft->second; - if (fontSize < 1) { - continue; - } - - int fontAvailable = availableFonts.Find(fontName.c_str()); - if (fontAvailable == -1) { - esyslog("skindesigner: font %s not available, skipping", fontName.c_str()); - continue; - } - - InsertFont(fontName, fontSize); - } -} - void cFontManager::Debug(void) { dsyslog("skindesigner: fontmanager fonts available:"); for (map < string, map< int, cFont* > >::iterator fts = fonts.begin(); fts != fonts.end(); fts++) { diff --git a/libcore/fontmanager.h b/extensions/fontmanager.h similarity index 86% rename from libcore/fontmanager.h rename to extensions/fontmanager.h index 1dbdcde..c71d465 100644 --- a/libcore/fontmanager.h +++ b/extensions/fontmanager.h @@ -6,8 +6,6 @@ #include #include -#include "../libtemplate/template.h" - using namespace std; class cFontManager { @@ -20,11 +18,10 @@ private: cFont *GetFont(string name, int size); int GetFontHeight(const char *name, int height, int charWidth = 0); public: - cFontManager(); - ~cFontManager(); + cFontManager(void); + ~cFontManager(void); void Lock(void) { mutex.Lock(); }; void Unlock(void) { mutex.Unlock(); }; - void CacheFonts(cTemplate *tpl); void DeleteFonts(void); int Width(string fontName, int fontSize, const char *text); int Height(string fontName, int fontSize); diff --git a/libcore/helpers.c b/extensions/helpers.c similarity index 83% rename from libcore/helpers.c rename to extensions/helpers.c index e195c37..00c13d2 100644 --- a/libcore/helpers.c +++ b/extensions/helpers.c @@ -51,35 +51,6 @@ int Minimum(int a, int b, int c, int d, int e, int f) { return min; } -string CutText(string &text, int width, string fontName, int fontSize) { - if (width <= fontManager->Font(fontName, fontSize)->Size()) - return text.c_str(); - fontManager->Lock(); - cTextWrapper twText; - twText.Set(text.c_str(), fontManager->Font(fontName, fontSize), width); - fontManager->Unlock(); - string cuttedTextNative = twText.GetLine(0); - stringstream sstrText; - sstrText << cuttedTextNative << "..."; - string cuttedText = sstrText.str(); - int actWidth = fontManager->Width(fontName, fontSize, cuttedText.c_str()); - if (actWidth > width) { - int overlap = actWidth - width; - int charWidth = fontManager->Width(fontName, fontSize, "."); - if (charWidth == 0) - charWidth = 1; - int cutChars = overlap / charWidth; - if (cutChars > 0) { - cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars); - stringstream sstrText2; - sstrText2 << cuttedTextNative << "..."; - cuttedText = sstrText2.str(); - } - } - return cuttedText; -} - - string StrToLowerCase(string str) { string lowerCase = str; const int length = lowerCase.length(); @@ -107,7 +78,7 @@ bool FileExists(const string &fullpath) { return true; } if (config.debugImageLoading) { - dsyslog("skindesigner: did not found %s", fullpath.c_str()); + dsyslog("skindesigner: did not find %s", fullpath.c_str()); } return false; } @@ -120,7 +91,7 @@ bool FileExists(const string &path, const string &name, const string &ext) { return true; } if (config.debugImageLoading) { - dsyslog("skindesigner: did not found %s", fileName.str().c_str()); + dsyslog("skindesigner: did not find %s", fileName.str().c_str()); } return false; } diff --git a/libcore/helpers.h b/extensions/helpers.h similarity index 94% rename from libcore/helpers.h rename to extensions/helpers.h index 74ed7d3..b059a16 100644 --- a/libcore/helpers.h +++ b/extensions/helpers.h @@ -1,6 +1,8 @@ #ifndef __HELPERS_H #define __HELPERS_H +#include +#include #include #include #include "../config.h" @@ -9,7 +11,6 @@ cPlugin *GetScraperPlugin(void); cSize ScaleToFit(int widthMax, int heightMax, int widthOriginal, int heightOriginal); int Minimum(int a, int b, int c, int d, int e, int f); -std::string CutText(string &text, int width, string fontName, int fontSize); std::string StrToLowerCase(string str); bool isNumber(const string& s); bool IsToken(const string& token); diff --git a/libcore/imagecache.c b/extensions/imagecache.c similarity index 79% rename from libcore/imagecache.c rename to extensions/imagecache.c index fe07e98..d8c89c8 100644 --- a/libcore/imagecache.c +++ b/extensions/imagecache.c @@ -58,7 +58,10 @@ void cImageCache::CacheLogo(int width, int height) { return; int logosCached = 0; - + + if (config.numLogosMax && config.numLogosMax < (int)channelLogoCache.size()) + return; + for (const cChannel *channel = Channels.First(); channel; channel = Channels.Next(channel)) { if (logosCached >= config.numLogosPerSizeInitial) break; @@ -77,6 +80,8 @@ void cImageCache::CacheLogo(int width, int height) { cImage *image = CreateImage(width, height); channelLogoCache.insert(pair(logoName.str(), image)); } + if (config.numLogosMax && config.numLogosMax < (int)channelLogoCache.size()) + return; } } @@ -172,24 +177,34 @@ void cImageCache::CacheIcon(eImageType type, string name, int width, int height) GetIcon(type, name, width, height); } -cImage *cImageCache::GetIcon(eImageType type, string name, int width, int height) { +cCachedImage *cImageCache::GetIcon(eImageType type, string name, int width, int height) { if (width < 1 || width > 1920 || height < 1 || height > 1080) return NULL; cMutexLock MutexLock(&mutex); stringstream iconName; iconName << name << "_" << width << "x" << height; - map::iterator hit = iconCache.find(iconName.str()); + map::iterator hit = iconCache.find(iconName.str()); if (hit != iconCache.end()) { - return (cImage*)hit->second; + return (cCachedImage*)hit->second; } else { bool success = LoadIcon(type, name); if (!success) return NULL; cImage *image = CreateImage(width, height, true); - iconCache.insert(pair(iconName.str(), image)); + cCachedImage *cachedImg = new cCachedImage(); + cachedImg->size = image->Width() * image->Height() * sizeof(tColor); + int handle = cOsdProvider::StoreImage(*image); + if (handle) { + cachedImg->handle = handle; + delete image; + } else { + cachedImg->image = image; + } + + iconCache.insert(pair(iconName.str(), cachedImg)); hit = iconCache.find(iconName.str()); if (hit != iconCache.end()) { - return (cImage*)hit->second; + return (cCachedImage*)hit->second; } } return NULL; @@ -321,24 +336,33 @@ void cImageCache::CacheSkinpart(string name, int width, int height) { GetSkinpart(name, width, height); } -cImage *cImageCache::GetSkinpart(string name, int width, int height) { +cCachedImage *cImageCache::GetSkinpart(string name, int width, int height) { if (width < 1 || width > 1920 || height < 1 || height > 1080) return NULL; cMutexLock MutexLock(&mutex); stringstream iconName; iconName << name << "_" << width << "x" << height; - map::iterator hit = skinPartsCache.find(iconName.str()); + map::iterator hit = skinPartsCache.find(iconName.str()); if (hit != skinPartsCache.end()) { - return (cImage*)hit->second; + return (cCachedImage*)hit->second; } else { bool success = LoadSkinpart(name); if (!success) return NULL; cImage *image = CreateImage(width, height, false); - skinPartsCache.insert(pair(iconName.str(), image)); + cCachedImage *cachedImg = new cCachedImage(); + cachedImg->size = image->Width() * image->Height() * sizeof(tColor); + int handle = cOsdProvider::StoreImage(*image); + if (handle) { + cachedImg->handle = handle; + delete image; + } else { + cachedImg->image = image; + } + skinPartsCache.insert(pair(iconName.str(), cachedImg)); hit = skinPartsCache.find(iconName.str()); if (hit != skinPartsCache.end()) { - return (cImage*)hit->second; + return (cCachedImage*)hit->second; } } return NULL; @@ -368,9 +392,9 @@ cImage *cImageCache::GetVerticalText(string text, tColor color, string font, int bool cImageCache::LoadIcon(eImageType type, string name) { cString subdir(""); - if (type == itMenuIcon) + if (type == eImageType::menuicon) subdir = "menuicons"; - else if (type == itIcon) + else if (type == eImageType::icon) subdir = "icons"; //first check in theme specific icon path @@ -452,8 +476,8 @@ bool cImageCache::LoadSkinpart(string name) { } void cImageCache::Clear(void) { - for(map::const_iterator it = iconCache.begin(); it != iconCache.end(); it++) { - cImage *img = (cImage*)it->second; + for(map::const_iterator it = iconCache.begin(); it != iconCache.end(); it++) { + cCachedImage *img = (cCachedImage*)it->second; delete img; } iconCache.clear(); @@ -464,8 +488,8 @@ void cImageCache::Clear(void) { } channelLogoCache.clear(); - for(map::const_iterator it = skinPartsCache.begin(); it != skinPartsCache.end(); it++) { - cImage *img = (cImage*)it->second; + for(map::const_iterator it = skinPartsCache.begin(); it != skinPartsCache.end(); it++) { + cCachedImage *img = (cCachedImage*)it->second; delete img; } skinPartsCache.clear(); @@ -478,60 +502,78 @@ void cImageCache::Clear(void) { } void cImageCache::Debug(bool full) { - int sizeIconCache = 0; + float sizeIconCacheInternal = 0; + float sizeIconCacheExternal = 0; int numIcons = 0; - GetIconCacheSize(numIcons, sizeIconCache); - dsyslog("skindesigner: cached %d icons - size %d byte", numIcons, sizeIconCache); + GetIconCacheSize(numIcons, sizeIconCacheInternal, sizeIconCacheExternal); + dsyslog("skindesigner: cached %d icons - size internal mem %.2fMB, high level mem %.2fMB", numIcons, sizeIconCacheInternal, sizeIconCacheExternal); if (full) { - for(std::map::const_iterator it = iconCache.begin(); it != iconCache.end(); it++) { + for(std::map::const_iterator it = iconCache.begin(); it != iconCache.end(); it++) { string name = it->first; - dsyslog("skindesigner: cached icon %s", name.c_str()); + cCachedImage *img = (cCachedImage*)it->second; + dsyslog("skindesigner: cached icon %s, handle %d", name.c_str(), img->handle); } } - int sizeLogoCache = 0; + float sizeLogoCache = 0; int numLogos = 0; GetLogoCacheSize(numLogos, sizeLogoCache); - dsyslog("skindesigner: cached %d logos - size %d byte", numLogos, sizeLogoCache); + dsyslog("skindesigner: cached %d logos - size %.2fMB internal mem", numLogos, sizeLogoCache); if (full) { for(std::map::const_iterator it = channelLogoCache.begin(); it != channelLogoCache.end(); it++) { string name = it->first; dsyslog("skindesigner: cached logo %s", name.c_str()); } } - - int sizeSkinpartCache = 0; + float sizeSkinpartCacheInternal = 0; + float sizeSkinpartCacheExternal = 0; int numSkinparts = 0; - GetSkinpartsCacheSize(numSkinparts, sizeSkinpartCache); - dsyslog("skindesigner: cached %d skinparts - size %d byte", numSkinparts, sizeSkinpartCache); + GetSkinpartsCacheSize(numSkinparts, sizeSkinpartCacheInternal, sizeSkinpartCacheExternal); + dsyslog("skindesigner: cached %d skinparts - size internal mem %.2fMB, high level mem %.2fMB", numSkinparts, sizeSkinpartCacheInternal, sizeSkinpartCacheExternal); if (full) { - for(std::map::const_iterator it = skinPartsCache.begin(); it != skinPartsCache.end(); it++) { + for(std::map::const_iterator it = skinPartsCache.begin(); it != skinPartsCache.end(); it++) { string name = it->first; dsyslog("skindesigner: cached skinpart %s", name.c_str()); } } } -void cImageCache::GetIconCacheSize(int &num, int &size) { +void cImageCache::GetIconCacheSize(int &num, float &sizeInternal, float &sizeExternal) { num = iconCache.size(); - for (map::iterator icon = iconCache.begin(); icon != iconCache.end(); icon++) { - cImage* img = icon->second; - size += img->Width() * img->Height() * sizeof(tColor); + int sizeByteInternal = 0; + int sizeByteExternal = 0; + for (map::iterator icon = iconCache.begin(); icon != iconCache.end(); icon++) { + cCachedImage* img = icon->second; + if (img->image) + sizeByteInternal += img->size; + else + sizeByteExternal += img->size; } + sizeInternal = sizeByteInternal / 1024.0f / 1024.0f; + sizeExternal = sizeByteExternal / 1024.0f / 1024.0f; } -void cImageCache::GetLogoCacheSize(int &num, int &size) { +void cImageCache::GetLogoCacheSize(int &num, float &size) { num = channelLogoCache.size(); + int sizeByte = 0; for (map::iterator logo = channelLogoCache.begin(); logo != channelLogoCache.end(); logo++) { cImage* img = logo->second; - size += img->Width() * img->Height() * sizeof(tColor); + sizeByte += img->Width() * img->Height() * sizeof(tColor); } + size = sizeByte / 1024.0f; } -void cImageCache::GetSkinpartsCacheSize(int &num, int &size) { +void cImageCache::GetSkinpartsCacheSize(int &num, float &sizeInternal, float &sizeExternal) { num = skinPartsCache.size(); - for (map::iterator skinpart = skinPartsCache.begin(); skinpart != skinPartsCache.end(); skinpart++) { - cImage* img = skinpart->second; - size += img->Width() * img->Height() * sizeof(tColor); - } + int sizeByteInternal = 0; + int sizeByteExternal = 0; + for (map::iterator skinpart = skinPartsCache.begin(); skinpart != skinPartsCache.end(); skinpart++) { + cCachedImage* img = skinpart->second; + if (img->image) + sizeByteInternal += img->size; + else + sizeByteExternal += img->size; + } + sizeInternal = sizeByteInternal / 1024.0f / 1024.0f; + sizeExternal = sizeByteExternal / 1024.0f / 1024.0f; } diff --git a/libcore/imagecache.h b/extensions/imagecache.h similarity index 67% rename from libcore/imagecache.h rename to extensions/imagecache.h index e11f295..13f882b 100644 --- a/libcore/imagecache.h +++ b/extensions/imagecache.h @@ -7,7 +7,25 @@ #include #include #include "imageloader.h" -#include "../libtemplate/templatefunction.h" +#include "../coreengine/definitions.h" + +class cCachedImage { +public: + int handle; + cImage *image; + int size; + cCachedImage(void) { + handle = 0; + image = NULL; + size = 0; + }; + ~cCachedImage(void) { + if (handle) + cOsdProvider::DropImage(handle); + if (image) + delete image; + }; +}; class cImageCache : public cImageLoader { public: @@ -24,20 +42,20 @@ public: bool SeparatorLogoExists(string name); //icons void CacheIcon(eImageType type, string path, int width, int height); - cImage *GetIcon(eImageType type, string name, int width, int height); + cCachedImage *GetIcon(eImageType type, string name, int width, int height); string GetIconName(string label, eMenuCategory cat = mcUndefined, string plugName = ""); bool MenuIconExists(string name); //skinparts void CacheSkinpart(string path, int width, int height); - cImage *GetSkinpart(string name, int width, int height); + cCachedImage *GetSkinpart(string name, int width, int height); //cairo special images cImage *GetVerticalText(string text, tColor color, string font, int size, int direction); //helpers void Clear(void); void Debug(bool full); - void GetIconCacheSize(int &num, int &size); - void GetLogoCacheSize(int &num, int &size); - void GetSkinpartsCacheSize(int &num, int &size); + void GetIconCacheSize(int &num, float &sizeInternal, float &sizeExternal); + void GetLogoCacheSize(int &num, float &size); + void GetSkinpartsCacheSize(int &num, float &sizeInternal, float &sizeExternal); private: static cMutex mutex; static string items[16]; @@ -48,9 +66,9 @@ private: string iconPathTheme; string skinPartsPathTheme; string svgTemplatePath; - map iconCache; + map iconCache; map channelLogoCache; - map skinPartsCache; + map skinPartsCache; map cairoImageCache; bool LoadIcon(eImageType type, string name); bool LoadLogo(const cChannel *channel); diff --git a/libcore/imageloader.c b/extensions/imageloader.c similarity index 100% rename from libcore/imageloader.c rename to extensions/imageloader.c diff --git a/libcore/imageloader.h b/extensions/imageloader.h similarity index 100% rename from libcore/imageloader.h rename to extensions/imageloader.h diff --git a/libcore/libxmlwrapper.c b/extensions/libxmlwrapper.c similarity index 95% rename from libcore/libxmlwrapper.c rename to extensions/libxmlwrapper.c index 0a93dfd..117815e 100644 --- a/libcore/libxmlwrapper.c +++ b/extensions/libxmlwrapper.c @@ -1,4 +1,4 @@ -#include "../libcore/helpers.h" +#include "helpers.h" #include "libxmlwrapper.h" void SkinDesignerXMLErrorHandler (void * userData, xmlErrorPtr error) { diff --git a/libcore/libxmlwrapper.h b/extensions/libxmlwrapper.h similarity index 85% rename from libcore/libxmlwrapper.h rename to extensions/libxmlwrapper.h index 0ace267..3971bb9 100644 --- a/libcore/libxmlwrapper.h +++ b/extensions/libxmlwrapper.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -12,8 +13,8 @@ #include using namespace std; - -#include "../views/viewhelpers.h" +typedef pair stringpair; +typedef map stringmap; class cLibXMLWrapper { private: diff --git a/extensions/pluginmanager.c b/extensions/pluginmanager.c new file mode 100644 index 0000000..2f839f8 --- /dev/null +++ b/extensions/pluginmanager.c @@ -0,0 +1,301 @@ +#include "pluginmanager.h" + +cSDPluginManager::cSDPluginManager(void) { + lastId = 0; + subviewsfound = false; +} + +cSDPluginManager::~cSDPluginManager(void) { +} + +void cSDPluginManager::Reset(void) { + subViewMapping.clear(); +} + +void cSDPluginManager::RegisterBasicPlugin(skindesignerapi::cPluginStructure *plugStructure) { + dsyslog("skindesigner: plugin %s uses libskindesigner API Version %s", + plugStructure->name.c_str(), + plugStructure->libskindesignerAPIVersion.c_str()); + plugStructure->id = lastId; + registeredPlugins.insert(pair(lastId, plugStructure->name)); + lastId++; + map< int, skindesignerapi::sPlugMenu > menusNew; + for (map< int, skindesignerapi::sPlugMenu >::iterator it = plugStructure->menus.begin(); it != plugStructure->menus.end(); it++) { + int key = it->first; + skindesignerapi::sPlugMenu menu = it->second; + skindesignerapi::sPlugMenu menuNew; + menuNew.type = menu.type; + menuNew.tplname = menu.tplname; + menuNew.tokenContainer = new skindesignerapi::cTokenContainer(*menu.tokenContainer); + menusNew.insert(pair(key, menuNew)); + } + pluginMenus.insert(pair< int, map < int, skindesignerapi::sPlugMenu > >(plugStructure->id, menusNew)); + + if (plugStructure->menus.size() > 0) + dsyslog("skindesigner: plugin %s has registered %ld menus", plugStructure->name.c_str(), plugStructure->menus.size()); + +} + +int cSDPluginManager::GetNumPluginMenus(void) { + int numMenusTotal = 0; + for (map < int, map < int, skindesignerapi::sPlugMenu > >::iterator it = pluginMenus.begin(); it != pluginMenus.end(); it++) { + numMenusTotal += (it->second).size(); + } + return numMenusTotal; +} + +void cSDPluginManager::InitPluginMenuIterator(void) { + plugMenuIt = pluginMenus.begin(); +} + +map *cSDPluginManager::GetPluginMenus(string &name, int &id) { + if (plugMenuIt == pluginMenus.end()) + return NULL; + id = plugMenuIt->first; + map::iterator hit = registeredPlugins.find(id); + if (hit != registeredPlugins.end()) + name = hit->second; + map *templates = &plugMenuIt->second; + plugMenuIt++; + return templates; +} + +skindesignerapi::cTokenContainer *cSDPluginManager::GetTokenContainer(int plugId, int plugMenuId) { + map >::iterator hit = pluginMenus.find(plugId); + if (hit == pluginMenus.end()) + return NULL; + map::iterator hit2 = (hit->second).find(plugMenuId); + if (hit2 == (hit->second).end()) + return NULL; + skindesignerapi::cTokenContainer *tk = hit2->second.tokenContainer; + return tk; +} + +void cSDPluginManager::AddSubviewMapping(int plugId, int plugMenuId, int subViewId) { + map >::iterator hit = subViewMapping.find(plugId); + if (hit == subViewMapping.end()) { + map menus; + menus.insert(pair(plugMenuId, subViewId)); + subViewMapping.insert(pair >(plugId, menus)); + } else { + (hit->second).insert(pair(plugMenuId, subViewId)); + } +} + +int cSDPluginManager::GetSubviewId(int plugId, int plugMenuId) { + map >::iterator hit = subViewMapping.find(plugId); + if (hit == subViewMapping.end()) + return -1; + map::iterator hit2 = (hit->second).find(plugMenuId); + if (hit2 == (hit->second).end()) + return -1; + return hit2->second; +} + +void cSDPluginManager::RegisterAdvancedPlugin(skindesignerapi::cPluginStructure *plugStructure) { + dsyslog("skindesigner: plugin %s uses libskindesigner API Version %s", + plugStructure->name.c_str(), + plugStructure->libskindesignerAPIVersion.c_str()); + plugStructure->id = lastId; + registeredPlugins.insert(pair(lastId, plugStructure->name)); + lastId++; + + rootviews.insert(pair(plugStructure->id, plugStructure->rootview)); + subviews.insert(pair >(plugStructure->id, plugStructure->subviews)); + + multimap< int, skindesignerapi::sPlugViewElement > viewelementsNew; + for (map< int, skindesignerapi::sPlugViewElement >::iterator it = plugStructure->viewelements.begin(); it != plugStructure->viewelements.end(); it++) { + int key = it->first; + skindesignerapi::sPlugViewElement ve = it->second; + skindesignerapi::sPlugViewElement veNew; + veNew.id = ve.id; + veNew.viewId = ve.viewId; + veNew.name = ve.name; + veNew.tokenContainer = new skindesignerapi::cTokenContainer(*ve.tokenContainer); + viewelementsNew.insert(pair(key, veNew)); + } + viewelements.insert(pair< int, multimap < int, skindesignerapi::sPlugViewElement > >(plugStructure->id, viewelementsNew)); + + multimap< int, skindesignerapi::sPlugViewGrid > viewgridsNew; + for (map< int, skindesignerapi::sPlugViewGrid >::iterator it = plugStructure->viewgrids.begin(); it != plugStructure->viewgrids.end(); it++) { + int key = it->first; + skindesignerapi::sPlugViewGrid vg = it->second; + skindesignerapi::sPlugViewGrid vgNew; + vgNew.id = vg.id; + vgNew.viewId = vg.viewId; + vgNew.name = vg.name; + vgNew.tokenContainer = new skindesignerapi::cTokenContainer(*vg.tokenContainer); + viewgridsNew.insert(pair(key, vgNew)); + } + viewgrids.insert(pair< int, multimap < int, skindesignerapi::sPlugViewGrid > >(plugStructure->id, viewgridsNew)); + + map< int, skindesignerapi::cTokenContainer* > viewtabsNew; + for (map::iterator it = plugStructure->viewtabs.begin(); it != plugStructure->viewtabs.end(); it++) { + int id = it->first; + skindesignerapi::cTokenContainer *tk = it->second; + viewtabsNew.insert(pair(id, new skindesignerapi::cTokenContainer(*tk))); + } + viewtabs.insert(pair< int, map >(plugStructure->id, viewtabsNew)); + + if (plugStructure->rootview.size() > 0) + dsyslog("skindesigner: plugin %s has registered %ld views with %ld viewelements and %ld viewgrids", + plugStructure->name.c_str(), + 1 + plugStructure->subviews.size(), + plugStructure->viewelements.size(), + plugStructure->viewgrids.size()); +} + +void cSDPluginManager::InitPluginViewIterator(void) { + rootViewsIt = rootviews.begin(); +} + +bool cSDPluginManager::GetNextPluginView(string &plugName, int &plugId, string &tplName) { + if (rootViewsIt == rootviews.end()) + return false; + plugId = rootViewsIt->first; + tplName = rootViewsIt->second; + map::iterator hit = registeredPlugins.find(plugId); + if (hit != registeredPlugins.end()) + plugName = hit->second; + rootViewsIt++; + return true; +} + +int cSDPluginManager::GetNumSubviews(int plugId) { + map< int, map< int, string > >::iterator hit = subviews.find(plugId); + if (hit == subviews.end()) + return 0; + return (hit->second).size(); +} + +void cSDPluginManager::InitPluginSubviewIterator(int plugId) { + map< int, map< int, string > >::iterator hit = subviews.find(plugId); + if (hit == subviews.end()) { + subviewsfound = false; + return; + } + subviewsCurrent = hit->second; + subviewsfound = true; + svIt = subviewsCurrent.begin(); +} + +bool cSDPluginManager::GetNextSubView(int &id, string &tplname) { + if (!subviewsfound) + return false; + if( svIt == subviewsCurrent.end() ) { + return false; + } + id = svIt->first; + tplname = svIt->second; + svIt++; + return true; +} + +int cSDPluginManager::GetNumViewElements(int plugId, int viewId) { + map< int, multimap< int, skindesignerapi::sPlugViewElement > >::iterator hit = viewelements.find(plugId); + if (hit == viewelements.end()) + return 0; + multimap *plugVEs = &hit->second; + pair::iterator, multimap::iterator> range; + range = plugVEs->equal_range(viewId); + int numVEs = 0; + for (multimap::iterator it=range.first; it!=range.second; ++it) { + numVEs++; + } + return numVEs; +} + +void cSDPluginManager::InitViewElementIterator(int plugId, int viewId) { + map< int, multimap< int, skindesignerapi::sPlugViewElement > >::iterator hit = viewelements.find(plugId); + if (hit == viewelements.end()) + return; + multimap *plugVEs = &hit->second; + veRange = plugVEs->equal_range(viewId); + veIt = veRange.first; +} + +bool cSDPluginManager::GetNextViewElement(int &veId, string &veName) { + if (veIt == veRange.second) + return false; + skindesignerapi::sPlugViewElement *ve = &veIt->second; + veId = ve->id; + veName = ve->name; + veIt++; + return true; +} + +skindesignerapi::cTokenContainer *cSDPluginManager::GetTokenContainerVE(int plugId, int viewId, int veId) { + map< int, multimap< int, skindesignerapi::sPlugViewElement > >::iterator hit = viewelements.find(plugId); + if (hit == viewelements.end()) + return NULL; + multimap *plugVEs = &hit->second; + for (multimap::iterator it = plugVEs->begin(); it != plugVEs->end(); it++) { + int view = it->first; + if (view != viewId) + continue; + skindesignerapi::sPlugViewElement *ve = &it->second; + if (ve->id == veId) + return ve->tokenContainer; + } + return NULL; +} + +int cSDPluginManager::GetNumViewGrids(int plugId, int viewId) { + map< int, multimap< int, skindesignerapi::sPlugViewGrid > >::iterator hit = viewgrids.find(plugId); + if (hit == viewgrids.end()) + return 0; + multimap *plugVGs = &hit->second; + pair::iterator, multimap::iterator> range; + range = plugVGs->equal_range(viewId); + int numVGs = 0; + for (multimap::iterator it=range.first; it!=range.second; ++it) { + numVGs++; + } + return numVGs; +} + +void cSDPluginManager::InitViewGridIterator(int plugId, int viewId) { + map< int, multimap< int, skindesignerapi::sPlugViewGrid > >::iterator hit = viewgrids.find(plugId); + if (hit == viewgrids.end()) + return; + multimap *plugGEs = &hit->second; + gRange = plugGEs->equal_range(viewId); + gIt = gRange.first; +} + +bool cSDPluginManager::GetNextViewGrid(int &gId, string &gName) { + if (gIt == gRange.second) + return false; + skindesignerapi::sPlugViewGrid *ge = &gIt->second; + gId = ge->id; + gName = ge->name; + gIt++; + return true; +} + +skindesignerapi::cTokenContainer *cSDPluginManager::GetTokenContainerGE(int plugId, int viewId, int gId) { + map< int, multimap< int, skindesignerapi::sPlugViewGrid > >::iterator hit = viewgrids.find(plugId); + if (hit == viewgrids.end()) + return NULL; + multimap *plugGEs = &hit->second; + for (multimap::iterator it = plugGEs->begin(); it != plugGEs->end(); it++) { + int view = it->first; + if (view != viewId) + continue; + skindesignerapi::sPlugViewGrid *g = &it->second; + if (g->id == gId) + return g->tokenContainer; + } + return NULL; +} + +skindesignerapi::cTokenContainer *cSDPluginManager::GetTokenContainerTab(int plugId, int viewId) { + map< int, map< int, skindesignerapi::cTokenContainer* > >::iterator hit = viewtabs.find(plugId); + if (hit == viewtabs.end()) + return NULL; + map< int, skindesignerapi::cTokenContainer* > *tabs = &hit->second; + map< int, skindesignerapi::cTokenContainer* >::iterator hit2 = tabs->find(viewId); + if (hit2 == tabs->end()) + return NULL; + return (hit2->second); +} diff --git a/extensions/pluginmanager.h b/extensions/pluginmanager.h new file mode 100644 index 0000000..399c1d8 --- /dev/null +++ b/extensions/pluginmanager.h @@ -0,0 +1,71 @@ +#ifndef __PLUGINMANAGER_H +#define __PLUGINMANAGER_H + +#include +#include +#include "libskindesignerapi/skindesignerapi.h" + +using namespace std; + +class cSDPluginManager { +private: + int lastId; + //plugin id --> plugin name + map < int, string > registeredPlugins; + //Basic Plugin Interface + //plugin id --> plugin definition + map < int, map < int, skindesignerapi::sPlugMenu > > pluginMenus; + map < int, map < int, skindesignerapi::sPlugMenu > >::iterator plugMenuIt; + //plugin id - menuId --> subviewid + map < int, map > subViewMapping; + + //Advanced Plugin Interface + //plugin id --> rootview templatename definition + map< int, string > rootviews; + map< int, string >::iterator rootViewsIt; + //plugin id --> subviewid /templatename definition + map< int, map< int, string > > subviews; + map< int, string> subviewsCurrent; + map< int, string>::iterator svIt; + bool subviewsfound; + //plugin id --> view id --> viewelement definition + map< int, multimap< int, skindesignerapi::sPlugViewElement > > viewelements; + pair::iterator, multimap::iterator> veRange; + multimap::iterator veIt; + //plugin id --> view id --> viewgrid definition + map< int, multimap< int, skindesignerapi::sPlugViewGrid > > viewgrids; + pair::iterator, multimap::iterator> gRange; + multimap::iterator gIt; + //plugin id --> view id --> tokencontainer of detailedview definition + map< int, map< int, skindesignerapi::cTokenContainer* > > viewtabs; +public: + cSDPluginManager(void); + ~cSDPluginManager(void); + void Reset(void); + //Basic Plugin Interface + void RegisterBasicPlugin(skindesignerapi::cPluginStructure *plugStructure); + int GetNumPluginMenus(void); + void InitPluginMenuIterator(void); + map *GetPluginMenus(string &name, int &id); + skindesignerapi::cTokenContainer *GetTokenContainer(int plugId, int plugMenuId); + void AddSubviewMapping(int plugId, int plugMenuId, int subViewId); + int GetSubviewId(int plugId, int plugMenuId); + //Advanced Plugin Interface + void RegisterAdvancedPlugin(skindesignerapi::cPluginStructure *plugStructure); + void InitPluginViewIterator(void); + bool GetNextPluginView(string &plugName, int &plugId, string &tplName); + int GetNumSubviews(int plugId); + void InitPluginSubviewIterator(int plugId); + bool GetNextSubView(int &id, string &tplname); + int GetNumViewElements(int plugId, int viewId); + void InitViewElementIterator(int plugId, int viewId); + bool GetNextViewElement(int &veId, string &veName); + skindesignerapi::cTokenContainer *GetTokenContainerVE(int plugId, int viewId, int veId); + int GetNumViewGrids(int plugId, int viewId); + void InitViewGridIterator(int plugId, int viewId); + bool GetNextViewGrid(int &gId, string &gName); + skindesignerapi::cTokenContainer *GetTokenContainerGE(int plugId, int viewId, int gId); + skindesignerapi::cTokenContainer *GetTokenContainerTab(int plugId, int viewId); +}; + +#endif //__PLUGINMANAGER_H \ No newline at end of file diff --git a/libcore/recfolderinfo.c b/extensions/recfolderinfo.c similarity index 100% rename from libcore/recfolderinfo.c rename to extensions/recfolderinfo.c diff --git a/libcore/recfolderinfo.h b/extensions/recfolderinfo.h similarity index 100% rename from libcore/recfolderinfo.h rename to extensions/recfolderinfo.h diff --git a/extensions/scrapmanager.c b/extensions/scrapmanager.c new file mode 100644 index 0000000..8452d75 --- /dev/null +++ b/extensions/scrapmanager.c @@ -0,0 +1,359 @@ +#include "scrapmanager.h" +#include "../coreengine/definitions.h" +#include "helpers.h" + +cPlugin *cScrapManager::pScraper = NULL; + +cScrapManager::cScrapManager(void) { + if (!pScraper) { + pScraper = GetScraperPlugin(); + } + movie = NULL; + series = NULL; +} + +cScrapManager::~cScrapManager(void) { + delete movie; + delete series; +} + +bool cScrapManager::LoadFullScrapInfo(const cEvent *event, const cRecording *recording) { + if (!pScraper) { + return false; + } + delete movie; + movie = NULL; + delete series; + series = NULL; + + ScraperGetEventType getType; + getType.event = event; + getType.recording = recording; + if (!pScraper->Service("GetEventType", &getType)) { + return false; + } + if (getType.type == tMovie) { + movie = new cMovie(); + movie->movieId = getType.movieId; + pScraper->Service("GetMovie", movie); + return true; + } else if (getType.type == tSeries) { + series = new cSeries(); + series->seriesId = getType.seriesId; + series->episodeId = getType.episodeId; + pScraper->Service("GetSeries", series); + return true; + } + return false; +} + +void cScrapManager::SetFullScrapInfo(skindesignerapi::cTokenContainer *tk, int actorsIndex) { + if (series) { + tk->AddIntToken((int)eScraperIT::ismovie, 0); + tk->AddIntToken((int)eScraperIT::isseries, 1); + SetSeries(tk, actorsIndex); + } else if (movie) { + tk->AddIntToken((int)eScraperIT::ismovie, 1); + tk->AddIntToken((int)eScraperIT::isseries, 0); + SetMovie(tk, actorsIndex); + } else { + tk->AddIntToken((int)eScraperIT::ismovie, 0); + tk->AddIntToken((int)eScraperIT::isseries, 0); + } +} + + +int cScrapManager::NumActors(void) { + if (series) { + return series->actors.size(); + } else if (movie) { + return movie->actors.size(); + } + return 0; +} + +void cScrapManager::SetHeaderScrapInfo(skindesignerapi::cTokenContainer *tk) { + if (series) { + tk->AddIntToken((int)eScraperHeaderIT::ismovie, 0); + tk->AddIntToken((int)eScraperHeaderIT::isseries, 1); + vector::iterator poster = series->posters.begin(); + if (poster != series->posters.end()) { + tk->AddIntToken((int)eScraperHeaderIT::posteravailable, true); + tk->AddIntToken((int)eScraperHeaderIT::posterwidth, (*poster).width); + tk->AddIntToken((int)eScraperHeaderIT::posterheight, (*poster).height); + tk->AddStringToken((int)eScraperHeaderST::posterpath, (*poster).path.c_str()); + } + vector::iterator banner = series->banners.begin(); + if (banner != series->banners.end()) { + tk->AddIntToken((int)eScraperHeaderIT::banneravailable, true); + tk->AddIntToken((int)eScraperHeaderIT::bannerwidth, (*banner).width); + tk->AddIntToken((int)eScraperHeaderIT::bannerheight, (*banner).height); + tk->AddStringToken((int)eScraperHeaderST::bannerpath, (*banner).path.c_str()); + } + } else if (movie) { + tk->AddIntToken((int)eScraperHeaderIT::ismovie, 1); + tk->AddIntToken((int)eScraperHeaderIT::isseries, 0); + tk->AddIntToken((int)eScraperHeaderIT::posteravailable, true); + tk->AddIntToken((int)eScraperHeaderIT::banneravailable, false); + tk->AddIntToken((int)eScraperHeaderIT::posterwidth, movie->poster.width); + tk->AddIntToken((int)eScraperHeaderIT::posterheight, movie->poster.height); + tk->AddStringToken((int)eScraperHeaderST::posterpath, movie->poster.path.c_str()); + } else { + tk->AddIntToken((int)eScraperHeaderIT::ismovie, 0); + tk->AddIntToken((int)eScraperHeaderIT::isseries, 0); + } +} + +void cScrapManager::SetScraperPosterBanner(skindesignerapi::cTokenContainer *tk) { + if (movie) { + tk->AddIntToken((int)eCeMenuSchedulesIT::hasposter, 1); + tk->AddStringToken((int)eCeMenuSchedulesST::posterpath, movie->poster.path.c_str()); + tk->AddIntToken((int)eCeMenuSchedulesIT::posterwidth, movie->poster.width); + tk->AddIntToken((int)eCeMenuSchedulesIT::posterheight, movie->poster.height); + } else if (series) { + vector::iterator poster = series->posters.begin(); + if (poster != series->posters.end()) { + tk->AddIntToken((int)eCeMenuSchedulesIT::hasposter, 1); + tk->AddIntToken((int)eCeMenuSchedulesIT::posterwidth, (*poster).width); + tk->AddIntToken((int)eCeMenuSchedulesIT::posterheight, (*poster).height); + tk->AddStringToken((int)eCeMenuSchedulesST::posterpath, (*poster).path.c_str()); + } + vector::iterator banner = series->banners.begin(); + if (banner != series->banners.end()) { + tk->AddIntToken((int)eCeMenuSchedulesIT::hasbanner, 1); + tk->AddIntToken((int)eCeMenuSchedulesIT::bannerwidth, (*banner).width); + tk->AddIntToken((int)eCeMenuSchedulesIT::bannerheight, (*banner).height); + tk->AddStringToken((int)eCeMenuSchedulesST::bannerpath, (*banner).path.c_str()); + } + } +} + +void cScrapManager::SetScraperRecordingPoster(skindesignerapi::cTokenContainer *tk, const cRecording *recording, bool isListElement) { + if (!pScraper) { + return; + } + ScraperGetPosterThumb call; + call.event = NULL; + call.recording = recording; + if (pScraper->Service("GetPosterThumb", &call)) { + if (isListElement) { + tk->AddIntToken((int)eLeMenuRecordingsIT::hasposterthumbnail, FileExists(call.poster.path)); + tk->AddIntToken((int)eLeMenuRecordingsIT::thumbnailwidth, call.poster.width); + tk->AddIntToken((int)eLeMenuRecordingsIT::thumbnailheight, call.poster.height); + tk->AddStringToken((int)eLeMenuRecordingsST::thumbnailpath, call.poster.path.c_str()); + } else { + tk->AddIntToken((int)eCeMenuRecordingsIT::hasposterthumbnail, FileExists(call.poster.path)); + tk->AddIntToken((int)eCeMenuRecordingsIT::thumbnailwidth, call.poster.width); + tk->AddIntToken((int)eCeMenuRecordingsIT::thumbnailheight, call.poster.height); + tk->AddStringToken((int)eCeMenuRecordingsST::thumbnailpath, call.poster.path.c_str()); + } + } + + ScraperGetPoster call2; + call2.event = NULL; + call2.recording = recording; + if (pScraper->Service("GetPoster", &call2)) { + if (isListElement) { + tk->AddIntToken((int)eLeMenuRecordingsIT::hasposter, FileExists(call2.poster.path)); + tk->AddIntToken((int)eLeMenuRecordingsIT::posterwidth, call2.poster.width); + tk->AddIntToken((int)eLeMenuRecordingsIT::posterheight, call2.poster.height); + tk->AddStringToken((int)eLeMenuRecordingsST::posterpath, call2.poster.path.c_str()); + } else { + tk->AddIntToken((int)eCeMenuRecordingsIT::hasposter, FileExists(call2.poster.path)); + tk->AddIntToken((int)eCeMenuRecordingsIT::posterwidth, call2.poster.width); + tk->AddIntToken((int)eCeMenuRecordingsIT::posterheight, call2.poster.height); + tk->AddStringToken((int)eCeMenuRecordingsST::posterpath, call2.poster.path.c_str()); + } + } +} + +cPlugin *cScrapManager::GetScraperPlugin(void) { + static cPlugin *pScraper = cPluginManager::GetPlugin("scraper2vdr"); + if( !pScraper ) // if it doesn't exit, try tvscraper + pScraper = cPluginManager::GetPlugin("tvscraper"); + return pScraper; +} + +void cScrapManager::SetMovie(skindesignerapi::cTokenContainer *tk, int actorsIndex) { + tk->AddStringToken((int)eScraperST::movietitle, movie->title.c_str()); + tk->AddStringToken((int)eScraperST::movieoriginalTitle, movie->originalTitle.c_str()); + tk->AddStringToken((int)eScraperST::movietagline, movie->tagline.c_str()); + tk->AddStringToken((int)eScraperST::movieoverview, movie->overview.c_str()); + tk->AddStringToken((int)eScraperST::moviegenres, movie->genres.c_str()); + tk->AddStringToken((int)eScraperST::moviehomepage, movie->homepage.c_str()); + tk->AddStringToken((int)eScraperST::moviereleasedate, movie->releaseDate.c_str()); + tk->AddStringToken((int)eScraperST::moviepopularity, *cString::sprintf("%f", movie->popularity)); + tk->AddStringToken((int)eScraperST::movievoteaverage, *cString::sprintf("%f", movie->voteAverage)); + tk->AddStringToken((int)eScraperST::posterpath, movie->poster.path.c_str()); + tk->AddStringToken((int)eScraperST::fanartpath, movie->fanart.path.c_str()); + tk->AddStringToken((int)eScraperST::collectionposterpath, movie->collectionPoster.path.c_str()); + tk->AddStringToken((int)eScraperST::collectionfanartpath, movie->collectionFanart.path.c_str()); + tk->AddIntToken((int)eScraperIT::movieadult, movie->adult); + tk->AddIntToken((int)eScraperIT::moviebudget, movie->budget); + tk->AddIntToken((int)eScraperIT::movierevenue, movie->revenue); + tk->AddIntToken((int)eScraperIT::movieruntime, movie->runtime); + tk->AddIntToken((int)eScraperIT::posterwidth, movie->poster.width); + tk->AddIntToken((int)eScraperIT::posterheight, movie->poster.height); + tk->AddIntToken((int)eScraperIT::fanartwidth, movie->fanart.width); + tk->AddIntToken((int)eScraperIT::fanartheight, movie->fanart.height); + tk->AddIntToken((int)eScraperIT::collectionposterwidth, movie->collectionPoster.width); + tk->AddIntToken((int)eScraperIT::collectionposterheight, movie->collectionPoster.height); + tk->AddIntToken((int)eScraperIT::collectionfanartwidth, movie->collectionFanart.width); + tk->AddIntToken((int)eScraperIT::collectionfanartheight, movie->collectionFanart.height); + if (movie->collectionPoster.path.size() > 0) + tk->AddIntToken((int)eScraperIT::movieiscollection, 1); + int i=0; + for (vector::iterator act = movie->actors.begin(); act != movie->actors.end(); act++) { + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::name, (*act).name.c_str()); + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::role, (*act).role.c_str()); + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumb, (*act).actorThumb.path.c_str()); + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbwidth, *cString::sprintf("%d", (*act).actorThumb.width)); + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbheight, *cString::sprintf("%d", (*act).actorThumb.height)); + i++; + } +} + +void cScrapManager::SetSeries(skindesignerapi::cTokenContainer *tk, int actorsIndex) { + //Series Basics + tk->AddStringToken((int)eScraperST::seriesname, series->name.c_str()); + tk->AddStringToken((int)eScraperST::seriesoverview, series->overview.c_str()); + tk->AddStringToken((int)eScraperST::seriesfirstaired, series->firstAired.c_str()); + tk->AddStringToken((int)eScraperST::seriesnetwork, series->network.c_str()); + tk->AddStringToken((int)eScraperST::seriesgenre, series->genre.c_str()); + tk->AddStringToken((int)eScraperST::seriesrating, *cString::sprintf("%f", series->rating)); + tk->AddStringToken((int)eScraperST::seriesstatus, series->status.c_str()); + //Episode Information + tk->AddIntToken((int)eScraperIT::episodenumber, series->episode.number); + tk->AddIntToken((int)eScraperIT::episodeseason, series->episode.season); + tk->AddStringToken((int)eScraperST::episodetitle, series->episode.name.c_str()); + tk->AddStringToken((int)eScraperST::episodefirstaired, series->episode.firstAired.c_str()); + tk->AddStringToken((int)eScraperST::episodegueststars, series->episode.guestStars.c_str()); + tk->AddStringToken((int)eScraperST::episodeoverview, series->episode.overview.c_str()); + tk->AddStringToken((int)eScraperST::episoderating, *cString::sprintf("%f", series->episode.rating)); + tk->AddIntToken((int)eScraperIT::episodeimagewidth, series->episode.episodeImage.width); + tk->AddIntToken((int)eScraperIT::episodeimageheight, series->episode.episodeImage.height); + tk->AddStringToken((int)eScraperST::episodeimagepath, series->episode.episodeImage.path.c_str()); + //Seasonposter + tk->AddIntToken((int)eScraperIT::seasonposterwidth, series->seasonPoster.width); + tk->AddIntToken((int)eScraperIT::seasonposterheight, series->seasonPoster.height); + tk->AddStringToken((int)eScraperST::seasonposterpath, series->seasonPoster.path.c_str()); + //Posters + int indexInt = (int)eScraperIT::seriesposter1width; + int indexStr = (int)eScraperST::seriesposter1path; + for(vector::iterator poster = series->posters.begin(); poster != series->posters.end(); poster++) { + tk->AddIntToken(indexInt, (*poster).width); + tk->AddIntToken(indexInt+1, (*poster).height); + tk->AddStringToken(indexStr, (*poster).path.c_str()); + indexInt += 2; + indexStr++; + } + //Banners + indexInt = (int)eScraperIT::seriesbanner1width; + indexStr = (int)eScraperST::seriesbanner1path; + for(vector::iterator banner = series->banners.begin(); banner != series->banners.end(); banner++) { + tk->AddIntToken(indexInt, (*banner).width); + tk->AddIntToken(indexInt+1, (*banner).height); + tk->AddStringToken(indexStr, (*banner).path.c_str()); + indexInt += 2; + indexStr++; + } + //Fanarts + indexInt = (int)eScraperIT::seriesfanart1width; + indexStr = (int)eScraperST::seriesfanart1path; + for(vector::iterator fanart = series->fanarts.begin(); fanart != series->fanarts.end(); fanart++) { + tk->AddIntToken(indexInt, (*fanart).width); + tk->AddIntToken(indexInt+1, (*fanart).height); + tk->AddStringToken(indexStr, (*fanart).path.c_str()); + indexInt += 2; + indexStr++; + } + //Actors + int i=0; + for (vector::iterator act = series->actors.begin(); act != series->actors.end(); act++) { + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::name, (*act).name.c_str()); + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::role, (*act).role.c_str()); + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumb, (*act).actorThumb.path.c_str()); + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbwidth, *cString::sprintf("%d", (*act).actorThumb.width)); + tk->AddLoopToken(actorsIndex, i, (int)eScraperLT::thumbheight, *cString::sprintf("%d", (*act).actorThumb.height)); + i++; + } +} + +void cScrapManager::RecPoster(const cRecording *rec, int &posterWidth, int &posterHeight, string &path, bool &hasPoster) { + if (!pScraper) { + return; + } + ScraperGetPoster callPoster; + callPoster.event = NULL; + callPoster.recording = rec; + if (pScraper->Service("GetPoster", &callPoster)) { + posterWidth = callPoster.poster.width; + posterHeight = callPoster.poster.height; + path = callPoster.poster.path; + if (path.size() > 0) + hasPoster = true; + } +} + +void cScrapManager::SetPosterBanner(skindesignerapi::cTokenContainer *tk, const cEvent *event, const cRecording *recording) { + if (!pScraper) { + return; + } + int mediaWidth = 0; + int mediaHeight = 0; + string mediaPath = ""; + bool isBanner = false; + int posterWidth = 0; + int posterHeight = 0; + string posterPath = ""; + bool hasPoster = false; + int bannerWidth = 0; + int bannerHeight = 0; + string bannerPath = ""; + bool hasBanner = false; + + ScraperGetPosterBannerV2 call; + call.event = event; + call.recording = recording; + if (pScraper->Service("GetPosterBannerV2", &call)) { + if ((call.type == tSeries) && call.banner.path.size() > 0) { + mediaWidth = call.banner.width; + mediaHeight = call.banner.height; + mediaPath = call.banner.path; + isBanner = true; + bannerWidth = mediaWidth; + bannerHeight = mediaHeight; + bannerPath = mediaPath; + hasBanner = true; + ScraperGetPoster callPoster; + callPoster.event = event; + callPoster.recording = recording; + if (pScraper->Service("GetPoster", &callPoster)) { + posterWidth = callPoster.poster.width; + posterHeight = callPoster.poster.height; + posterPath = callPoster.poster.path; + hasPoster = true; + } + } else if (call.type == tMovie && call.poster.path.size() > 0 && call.poster.height > 0) { + mediaWidth = call.poster.width; + mediaHeight = call.poster.height; + mediaPath = call.poster.path; + posterWidth = call.poster.width; + posterHeight = call.poster.height; + posterPath = call.poster.path; + hasPoster = true; + } + } + tk->AddIntToken((int)eScraperPosterBannerIT::mediawidth, mediaWidth); + tk->AddIntToken((int)eScraperPosterBannerIT::mediaheight, mediaHeight); + tk->AddIntToken((int)eScraperPosterBannerIT::isbanner, isBanner); + tk->AddStringToken((int)eScraperPosterBannerST::mediapath, mediaPath.c_str()); + tk->AddIntToken((int)eScraperPosterBannerIT::posterwidth, posterWidth); + tk->AddIntToken((int)eScraperPosterBannerIT::posterheight, posterHeight); + tk->AddStringToken((int)eScraperPosterBannerST::posterpath, posterPath.c_str()); + tk->AddIntToken((int)eScraperPosterBannerIT::hasposter, hasPoster); + tk->AddIntToken((int)eScraperPosterBannerIT::bannerwidth, bannerWidth); + tk->AddIntToken((int)eScraperPosterBannerIT::bannerheight, bannerHeight); + tk->AddStringToken((int)eScraperPosterBannerST::bannerpath, bannerPath.c_str()); + tk->AddIntToken((int)eScraperPosterBannerIT::hasbanner, hasBanner); +} \ No newline at end of file diff --git a/extensions/scrapmanager.h b/extensions/scrapmanager.h new file mode 100644 index 0000000..0e026fc --- /dev/null +++ b/extensions/scrapmanager.h @@ -0,0 +1,28 @@ +#ifndef __SCRAPMANAGER_H +#define __SCRAPMANAGER_H + +#include "../services/scraper2vdr.h" +#include "../libskindesignerapi/tokencontainer.h" + +class cScrapManager { +private: + static cPlugin *pScraper; + cMovie *movie; + cSeries *series; + cPlugin *GetScraperPlugin(void); + void SetMovie(skindesignerapi::cTokenContainer *tk, int actorsIndex); + void SetSeries(skindesignerapi::cTokenContainer *tk, int actorsIndex); +protected: + bool LoadFullScrapInfo(const cEvent *event, const cRecording *recording); + void SetFullScrapInfo(skindesignerapi::cTokenContainer *tk, int actorsIndex); + int NumActors(void); + void SetHeaderScrapInfo(skindesignerapi::cTokenContainer *tk); + void SetScraperPosterBanner(skindesignerapi::cTokenContainer *tk); + void SetScraperRecordingPoster(skindesignerapi::cTokenContainer *tk, const cRecording *recording, bool isListElement); + void RecPoster(const cRecording *rec, int &posterWidth, int &posterHeight, string &path, bool &hasPoster); + void SetPosterBanner(skindesignerapi::cTokenContainer *tk, const cEvent *event, const cRecording *recording); +public: + cScrapManager(void); + virtual ~cScrapManager(void); +}; +#endif //__SCRAPMANAGER_H \ No newline at end of file diff --git a/libcore/skinrepo.c b/extensions/skinrepo.c similarity index 99% rename from libcore/skinrepo.c rename to extensions/skinrepo.c index e815421..16919e8 100644 --- a/libcore/skinrepo.c +++ b/extensions/skinrepo.c @@ -1,7 +1,7 @@ #include #include #include "skinrepo.h" -#include "../libcore/helpers.h" +#include "helpers.h" using namespace std; diff --git a/libcore/skinrepo.h b/extensions/skinrepo.h similarity index 91% rename from libcore/skinrepo.h rename to extensions/skinrepo.h index 7452ad4..2f10929 100644 --- a/libcore/skinrepo.h +++ b/extensions/skinrepo.h @@ -5,7 +5,7 @@ #include #include #include -#include "../libcore/libxmlwrapper.h" +#include "libxmlwrapper.h" #include using namespace std; @@ -61,9 +61,9 @@ public: string Author(void) { return author; }; string MinSDVersion(void) { return minSDVersion; }; string Url(void) { return url; }; - vector SpecialFonts(void) { return specialFonts; }; - vector SupportedPlugins(void) { return supportedPlugins; }; - vector< pair < string, string > > Screenshots(void) { return screenshots; }; + vector *SpecialFonts(void) { return &specialFonts; }; + vector *SupportedPlugins(void) { return &supportedPlugins; }; + vector< pair < string, string > > *Screenshots(void) { return &screenshots; }; void Install(string path, string themesPath); void Update(string path); bool InstallationFinished(void) { return !(Running()); }; diff --git a/libcore/skinsetup.c b/extensions/skinsetup.c similarity index 99% rename from libcore/skinsetup.c rename to extensions/skinsetup.c index 3a6b7cf..f622336 100644 --- a/libcore/skinsetup.c +++ b/extensions/skinsetup.c @@ -1,7 +1,7 @@ #include "skinsetup.h" #include "../config.h" -#include "../libtemplate/xmlparser.h" -#include "../libcore/helpers.h" +#include "../coreengine/xmlparser.h" +#include "helpers.h" // --- cSkinSetupParameter ----------------------------------------------------------- diff --git a/libcore/skinsetup.h b/extensions/skinsetup.h similarity index 98% rename from libcore/skinsetup.h rename to extensions/skinsetup.h index 0ae49cc..e3b9cc3 100644 --- a/libcore/skinsetup.h +++ b/extensions/skinsetup.h @@ -8,7 +8,7 @@ #include #include #include -#include "../libtemplate/globals.h" +#include "../coreengine/globals.h" using namespace std; @@ -99,4 +99,4 @@ public: void Debug(void); }; -#endif //__SKINSETUP_H \ No newline at end of file +#endif //__SKINSETUP_H diff --git a/libcore/timers.c b/extensions/timers.c similarity index 100% rename from libcore/timers.c rename to extensions/timers.c diff --git a/libcore/timers.h b/extensions/timers.h similarity index 100% rename from libcore/timers.h rename to extensions/timers.h diff --git a/libcore/pixmapcontainer.c b/libcore/pixmapcontainer.c deleted file mode 100644 index 5cbcf9e..0000000 --- a/libcore/pixmapcontainer.c +++ /dev/null @@ -1,835 +0,0 @@ -#define __STL_CONFIG_H -#include -#include "pixmapcontainer.h" -#include "../config.h" - -cMutex cPixmapContainer::mutex; -cOsd *cPixmapContainer::osd = NULL; -eFlushState cPixmapContainer::flushState = fsOpen; - -cPixmapContainer::cPixmapContainer(int numPixmaps) { - this->numPixmaps = numPixmaps; - pixContainerInit = true; - mutex.Lock(); - pixmaps = new cPixmap*[numPixmaps]; - pixmapsTransparency = new int[numPixmaps]; - for(int i=0; i < numPixmaps; i++) { - pixmaps[i] = NULL; - pixmapsTransparency[i] = 0; - } - pixmapsLayer = NULL; - mutex.Unlock(); - checkRunning = false; - fadeTime = 0; - shiftTime = 0; - shiftType = stNone; - shiftMode = smLinear; - deleteOsdOnExit = false; -} - -cPixmapContainer::~cPixmapContainer(void) { - for (int i=0; i < numPixmaps; i++) { - mutex.Lock(); - if (pixmaps[i] && osd) { - osd->DestroyPixmap(pixmaps[i]); - pixmaps[i] = NULL; - } - mutex.Unlock(); - } - delete[] pixmaps; - delete[] pixmapsTransparency; - if (pixmapsLayer) - delete[] pixmapsLayer; - - if (deleteOsdOnExit && osd) { - mutex.Lock(); - delete osd; - osd = NULL; - mutex.Unlock(); - } - flushState = fsOpen; -} - -bool cPixmapContainer::CreateOsd(int Left, int Top, int Width, int Height) { - if (osd) { - return false; - } - cOsd *newOsd = cOsdProvider::NewOsd(Left, Top); - if (newOsd) { - tArea Area = { 0, 0, Width - 1, Height - 1, 32 }; - if (newOsd->SetAreas(&Area, 1) == oeOk) { - osd = newOsd; - return true; - } - } - return false; -} - -void cPixmapContainer::LockFlush(void) { - flushState = fsLock; -} - -void cPixmapContainer::OpenFlush(void) { - flushState = fsOpen; -} - - -void cPixmapContainer::DoFlush(void) { - cMutexLock MutexLock(&mutex); - if (!osd || (checkRunning && !Running())) - return; - if (flushState == fsOpen) { - osd->Flush(); - } -} - -void cPixmapContainer::HidePixmaps(void) { - cMutexLock MutexLock(&mutex); - pixmapsLayer = new int[numPixmaps]; - for(int i=0; i < numPixmaps; i++) { - if (!pixmaps[i]) { - pixmapsLayer[i] = 0; - continue; - } - pixmapsLayer[i] = pixmaps[i]->Layer(); - pixmaps[i]->SetLayer(-1); - } -} - -void cPixmapContainer::ShowPixmaps(void) { - cMutexLock MutexLock(&mutex); - if (!pixmapsLayer) - return; - for(int i=0; i < numPixmaps; i++) { - if (!pixmaps[i]) - continue; - pixmaps[i]->SetLayer(pixmapsLayer[i]); - } -} - -/****************************************************************************************************** -* Protected Functions -******************************************************************************************************/ - -bool cPixmapContainer::PixmapExists(int num) { - cMutexLock MutexLock(&mutex); - if (pixmaps[num]) - return true; - return false; -} - -void cPixmapContainer::CreatePixmap(int num, int Layer, const cRect &ViewPort, const cRect &DrawPort) { - cMutexLock MutexLock(&mutex); - if (!osd || (checkRunning && !Running())) - return; - pixmaps[num] = osd->CreatePixmap(Layer, ViewPort, DrawPort); - if (!pixmaps[num]) - return; - pixmaps[num]->Fill(clrTransparent); - if (pixContainerInit && (fadeTime || shiftTime)) { - pixmaps[num]->SetAlpha(0); - } else if (pixmapsTransparency[num]) { - pixmaps[num]->SetAlpha(pixmapsTransparency[num]); - } -} - -bool cPixmapContainer::DestroyPixmap(int num) { - cMutexLock MutexLock(&mutex); - if (pixmaps[num] && osd) { - osd->DestroyPixmap(pixmaps[num]); - pixmaps[num] = NULL; - return true; - } - return false; -} - -void cPixmapContainer::DrawText(int num, const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, std::string fontName, int fontSize) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - fontManager->Lock(); - cFont *font = fontManager->Font(fontName, fontSize); - if (font) - pixmaps[num]->DrawText(Point, s, ColorFg, ColorBg, font); - fontManager->Unlock(); -} - - -void cPixmapContainer::DrawRectangle(int num, const cRect &Rect, tColor Color) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->DrawRectangle(Rect, Color); -} - -void cPixmapContainer::DrawEllipse(int num, const cRect &Rect, tColor Color, int Quadrants) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->DrawEllipse(Rect, Color, Quadrants); -} - -void cPixmapContainer::DrawSlope(int num, const cRect &Rect, tColor Color, int Type) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->DrawSlope(Rect, Color, Type); -} - -void cPixmapContainer::DrawImage(int num, const cPoint &Point, const cImage &Image) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->DrawImage(Point, Image); -} - -void cPixmapContainer::DrawBitmap(int num, const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg, tColor ColorBg, bool Overlay) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->DrawBitmap(Point, Bitmap, ColorFg, ColorBg, Overlay); -} - -void cPixmapContainer::Fill(int num, tColor Color) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->Fill(Color); -} - -void cPixmapContainer::SetAlpha(int num, int Alpha) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->SetAlpha(Alpha); -} - -void cPixmapContainer::SetTransparency(int num, int Transparency) { - if (Transparency < 0 && Transparency > 100) - return; - pixmapsTransparency[num] = (100 - Transparency)*255/100; -} - -void cPixmapContainer::SetLayer(int num, int Layer) { - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->SetLayer(Layer); -} - -void cPixmapContainer::SetViewPort(int num, const cRect &rect) { - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->SetViewPort(rect); -} - -int cPixmapContainer::Layer(int num) { - if (checkRunning && !Running()) - return 0; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return 0; - return pixmaps[num]->Layer(); -} - -void cPixmapContainer::Pos(int num, cPoint &pos) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pos.SetX(pixmaps[num]->ViewPort().X()); - pos.SetY(pixmaps[num]->ViewPort().Y()); -} - -cRect cPixmapContainer::ViewPort(int num) { - cRect vp; - if (checkRunning && !Running()) - return vp; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return vp; - return pixmaps[num]->ViewPort(); -} - -int cPixmapContainer::Width(int num) { - if (checkRunning && !Running()) - return 0; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return 0; - int width = pixmaps[num]->ViewPort().Width(); - return width; -} - -int cPixmapContainer::Height(int num) { - if (checkRunning && !Running()) - return 0; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return 0; - int height = pixmaps[num]->ViewPort().Height(); - return height; -} - -int cPixmapContainer::DrawportWidth(int num) { - if (checkRunning && !Running()) - return 0; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return 0; - int width = pixmaps[num]->DrawPort().Width(); - return width; -} - -int cPixmapContainer::DrawportHeight(int num) { - if (checkRunning && !Running()) - return 0; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return 0; - int height = pixmaps[num]->DrawPort().Height(); - return height; -} - -int cPixmapContainer::DrawportX(int num) { - if (checkRunning && !Running()) - return 0; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return 0; - int x = pixmaps[num]->DrawPort().X(); - return x; -} - -int cPixmapContainer::DrawportY(int num) { - if (checkRunning && !Running()) - return 0; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return 0; - int y = pixmaps[num]->DrawPort().Y(); - return y; -} - -void cPixmapContainer::SetDrawPortPoint(int num, const cPoint &Point) { - if (checkRunning && !Running()) - return; - cMutexLock MutexLock(&mutex); - if (!pixmaps[num]) - return; - pixmaps[num]->SetDrawPortPoint(Point); -} - -/*************************************************************************** -* HELPERS -- do not access the pixmaps array directly, use wrapper functions -* to ensure that a proper lock is set before accessing pixmaps -****************************************************************************/ - -int cPixmapContainer::AnimationDelay(void) { - int animTime = max(shiftTime, fadeTime); - return animTime + 100; -} - -void cPixmapContainer::FadeIn(void) { - if (!fadeTime) { - for (int i = 0; i < numPixmaps; i++) { - if (PixmapExists(i)) { - SetAlpha(i, pixmapsTransparency[i] ? pixmapsTransparency[i] : ALPHA_OPAQUE); - } - } - return; - } - int frames = fadeTime * config.framesPerSecond / 1000; - if (frames <= 0) frames = 1; - int frameTime = fadeTime / frames; - uint64_t Start = cTimeMs::Now(); - while (Running()) { - uint64_t Now = cTimeMs::Now(); - double t = min(double(Now - Start) / fadeTime, 1.0); - int Alpha = t * ALPHA_OPAQUE; - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - int alpha = (double)pixmapsTransparency[i] / 255.0 * Alpha; - SetAlpha(i, alpha); - } - DoFlush(); - int Delta = cTimeMs::Now() - Now; - if (Running() && (Delta < frameTime)) - cCondWait::SleepMs(frameTime - Delta); - if ((int)(Now - Start) > fadeTime) - break; - } -} - -void cPixmapContainer::FadeOut(void) { - if (!fadeTime || IsAnimated()) - return; - int frames = fadeTime * config.framesPerSecond / 1000; - if (frames <= 0) frames = 1; - int frameTime = fadeTime / frames; - uint64_t Start = cTimeMs::Now(); - while (true) { - uint64_t Now = cTimeMs::Now(); - double t = min(double(Now - Start) / fadeTime, 1.0); - int Alpha = (1 - t) * ALPHA_OPAQUE; - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - int alpha = (double)pixmapsTransparency[i] / 255.0 * Alpha; - SetAlpha(i, alpha); - } - DoFlush(); - int Delta = cTimeMs::Now() - Now; - if (Delta < frameTime) - cCondWait::SleepMs(frameTime - Delta); - if ((int)(Now - Start) > fadeTime) - break; - } -} - -void cPixmapContainer::ShiftIn(void) { - if (shiftTime < 1) - return; - - int frames = shiftTime * config.framesPerSecond / 1000; - if (frames <= 0) frames = 1; - int frameTime = shiftTime / frames; - - if (shiftType > stNone) { - ShiftInFromBorder(frames, frameTime); - } else { - ShiftInFromPoint(frames, frameTime); - } -} - -void cPixmapContainer::ShiftOut(void) { - if (shiftTime < 1) - return; - - int frames = shiftTime * config.framesPerSecond / 1000; - if (frames <= 0) frames = 1; - int frameTime = shiftTime / frames; - - if (shiftType > stNone) { - ShiftOutToBorder(frames, frameTime); - } else { - ShiftOutToPoint(frames, frameTime); - } -} - -void cPixmapContainer::ShiftInFromBorder(int frames, int frameTime) { - cRect unionArea = UnionPixmaps(); - //shifthing all pixmaps to dedicated start positions - cPoint startPositions[numPixmaps]; - int osdWidth = osd->Width(); - int osdHeight = osd->Height(); - int xStart = 0; - int yStart = 0; - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - cPoint pos; - Pos(i, pos); - switch (shiftType) { - case stLeft: - xStart = pos.X() - (unionArea.X() + unionArea.Width()); - pos.SetX(xStart); - break; - case stRight: - xStart = osdWidth + (pos.X() - unionArea.X()); - pos.SetX(xStart); - break; - case stTop: - yStart = pos.Y() - (unionArea.Y() + unionArea.Height()); - pos.SetY(yStart); - break; - case stBottom: - yStart = osdHeight + (pos.Y() - unionArea.Y()); - pos.SetY(yStart); - break; - default: - break; - } - startPositions[i] = pos; - cRect r = ViewPort(i); - r.SetPoint(pos.X(), pos.Y()); - SetViewPort(i, r); - SetAlpha(i, pixmapsTransparency[i] ? pixmapsTransparency[i] : ALPHA_OPAQUE); - } - DoFlush(); - //Calculating total shifting distance - int shiftTotal = 0; - switch (shiftType) { - case stLeft: - shiftTotal = unionArea.X() + unionArea.Width(); - break; - case stRight: - shiftTotal = unionArea.Width() + (osdWidth - (unionArea.X() + unionArea.Width())); - break; - case stTop: - shiftTotal = unionArea.Y() + unionArea.Height(); - break; - case stBottom: - shiftTotal = unionArea.Height() + (osdHeight - (unionArea.Y() + unionArea.Height())); - break; - default: - break; - } - //Moving In - uint64_t Start = cTimeMs::Now(); - while (Running()) { - uint64_t Now = cTimeMs::Now(); - double t = min(double(Now - Start) / shiftTime, 1.0); - if (shiftMode == smSlowedDown) { - //using f(x) = -(x-1)^2 + 1 as mapping function - t = (-1)*pow(t - 1, 2) + 1; - } - int xNew = 0; - int yNew = 0; - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - cRect r = ViewPort(i); - switch (shiftType) { - case stLeft: - xNew = startPositions[i].X() + t * shiftTotal; - r.SetPoint(xNew, r.Y()); - break; - case stRight: - xNew = startPositions[i].X() - t * shiftTotal; - r.SetPoint(xNew, r.Y()); - break; - case stTop: - yNew = startPositions[i].Y() + t * shiftTotal; - r.SetPoint(r.X(), yNew); - break; - case stBottom: - yNew = startPositions[i].Y() - t * shiftTotal; - r.SetPoint(r.X(), yNew); - break; - default: - break; - } - SetViewPort(i, r); - } - DoFlush(); - int Delta = cTimeMs::Now() - Now; - if (Running() && (Delta < frameTime)) { - cCondWait::SleepMs(frameTime - Delta); - } - if ((int)(Now - Start) > shiftTime) - break; - } -} - -void cPixmapContainer::ShiftOutToBorder(int frames, int frameTime) { - cRect unionArea = UnionPixmaps(); - //calculating end positions - cPoint startPositions[numPixmaps]; - int osdWidth = osd->Width(); - int osdHeight = osd->Height(); - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - cPoint pos; - Pos(i, pos); - startPositions[i] = pos; - } - //Calculating total shifting distance - int shiftTotal = 0; - switch (shiftType) { - case stLeft: - shiftTotal = unionArea.X() + unionArea.Width(); - break; - case stRight: - shiftTotal = unionArea.Width() + (osdWidth - (unionArea.X() + unionArea.Width())); - break; - case stTop: - shiftTotal = unionArea.Y() + unionArea.Height(); - break; - case stBottom: - shiftTotal = unionArea.Height() + (osdHeight - (unionArea.Y() + unionArea.Height())); - break; - default: - break; - } - //Moving Out - uint64_t Start = cTimeMs::Now(); - while (true) { - uint64_t Now = cTimeMs::Now(); - double t = min(double(Now - Start) / shiftTime, 1.0); - int xNew = 0; - int yNew = 0; - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - cRect r = ViewPort(i); - switch (shiftType) { - case stLeft: - xNew = startPositions[i].X() - t * shiftTotal; - r.SetPoint(xNew, r.Y()); - break; - case stRight: - xNew = startPositions[i].X() + t * shiftTotal; - r.SetPoint(xNew, r.Y()); - break; - case stTop: - yNew = startPositions[i].Y() - t * shiftTotal; - r.SetPoint(r.X(), yNew); - break; - case stBottom: - yNew = startPositions[i].Y() + t * shiftTotal; - r.SetPoint(r.X(), yNew); - break; - default: - break; - } - SetViewPort(i, r); - } - DoFlush(); - int Delta = cTimeMs::Now() - Now; - if ((Delta < frameTime)) { - cCondWait::SleepMs(frameTime - Delta); - } - if ((int)(Now - Start) > shiftTime) - break; - } -} - -void cPixmapContainer::ShiftInFromPoint(int frames, int frameTime) { - //store original positions of pixmaps and move to StartPosition - cPoint destPos[numPixmaps]; - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - cPoint pos; - Pos(i, pos); - destPos[i] = pos; - cRect r = ViewPort(i); - r.SetPoint(startPos); - SetViewPort(i, r); - SetAlpha(i, pixmapsTransparency[i] ? pixmapsTransparency[i] : ALPHA_OPAQUE); - } - DoFlush(); - //Move In - uint64_t Start = cTimeMs::Now(); - while (Running()) { - uint64_t Now = cTimeMs::Now(); - double t = min(double(Now - Start) / shiftTime, 1.0); - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - int x = startPos.X() + t * (destPos[i].X() - startPos.X()); - int y = startPos.Y() + t * (destPos[i].Y() - startPos.Y()); - cRect r = ViewPort(i); - r.SetPoint(x, y); - SetViewPort(i, r); - } - DoFlush(); - int Delta = cTimeMs::Now() - Now; - if (Running() && (Delta < frameTime)) - cCondWait::SleepMs(frameTime - Delta); - if ((int)(Now - Start) > shiftTime) - break; - } -} - -void cPixmapContainer::ShiftOutToPoint(int frames, int frameTime) { - //TODO -} - -cRect cPixmapContainer::UnionPixmaps(void) { - cRect unionArea; - bool isNew = true; - for (int i = 0; i < numPixmaps; i++) { - if (!PixmapExists(i)) - continue; - if (isNew) { - unionArea = ViewPort(i); - isNew = false; - } else { - unionArea.Combine(ViewPort(i)); - } - } - return unionArea; -} - -/***************************************** -* scrollSpeed: 1 slow -* 2 medium -* 3 fast -******************************************/ -void cPixmapContainer::ScrollHorizontal(int num, int scrollDelay, int scrollSpeed, int scrollMode) { - bool carriageReturn = (scrollMode == 1) ? true : false; - - int scrollDelta = 1; - int drawPortX; - - int FrameTime = 0; - if (scrollSpeed == 1) - FrameTime = 50; - else if (scrollSpeed == 2) - FrameTime = 30; - else - FrameTime = 15; - if (!Running()) - return; - int maxX = DrawportWidth(num) - Width(num); - bool doSleep = false; - while (Running()) { - if (doSleep) { - DoSleep(scrollDelay); - doSleep = false; - } - if (!Running()) - return; - uint64_t Now = cTimeMs::Now(); - drawPortX = DrawportX(num); - drawPortX -= scrollDelta; - - if (abs(drawPortX) > maxX) { - DoSleep(scrollDelay); - if (carriageReturn) - drawPortX = 0; - else { - scrollDelta *= -1; - drawPortX -= scrollDelta; - } - doSleep = true; - } - if (!carriageReturn && (drawPortX == 0)) { - scrollDelta *= -1; - doSleep = true; - } - SetDrawPortPoint(num, cPoint(drawPortX, 0)); - int Delta = cTimeMs::Now() - Now; - DoFlush(); - if (Running() && (Delta < FrameTime)) - cCondWait::SleepMs(FrameTime - Delta); - } -} - -/***************************************** -* scrollSpeed: 1 slow -* 2 medium -* 3 fast -******************************************/ -void cPixmapContainer::ScrollVertical(int num, int scrollDelay, int scrollSpeed) { - if (!scrollSpeed) - return; - DoSleep(scrollDelay); - int drawPortY; - int FrameTime = 0; - if (scrollSpeed == 1) - FrameTime = 50; - else if (scrollSpeed == 2) - FrameTime = 30; - else - FrameTime = 15; - int maxY = DrawportHeight(num) - Height(num); - bool doSleep = false; - while (Running()) { - if (doSleep) { - doSleep = false; - DoSleep(scrollDelay); - } - uint64_t Now = cTimeMs::Now(); - drawPortY = DrawportY(num); - drawPortY -= 1; - if (abs(drawPortY) > maxY) { - doSleep = true; - DoSleep(scrollDelay); - drawPortY = 0; - } - SetDrawPortPoint(num, cPoint(0, drawPortY)); - if (doSleep) { - DoSleep(scrollDelay); - } - int Delta = cTimeMs::Now() - Now; - DoFlush(); - if (Running() && (Delta < FrameTime)) - cCondWait::SleepMs(FrameTime - Delta); - } -} - -void cPixmapContainer::CancelSave(void) { - Cancel(-1); - while (Active()) - cCondWait::SleepMs(10); -} - -void cPixmapContainer::DoSleep(int duration) { - int sleepSlice = 10; - for (int i = 0; Running() && (i*sleepSlice < duration); i++) - cCondWait::SleepMs(sleepSlice); -} - -void cPixmapContainer::DrawBlendedBackground(int num, int xStart, int width, tColor color, tColor colorBlending, bool fromTop) { - int height = Height(num); - int numSteps = 16; - int alphaStep = 0x0F; - int alpha = 0x00; - int step, begin, end; - if (fromTop) { - step = 1; - begin = 0; - end = numSteps; - } else { - step = -1; - begin = height; - end = height - numSteps; - } - tColor clr; - bool cont = true; - for (int i = begin; cont; i = i + step) { - clr = AlphaBlend(color, colorBlending, alpha); - DrawRectangle(num, cRect(xStart,i,width,1), clr); - alpha += alphaStep; - if (i == end) - cont = false; - } -} - -void cPixmapContainer::DrawRoundedCorners(int num, int radius, int x, int y, int width, int height) { - if (radius > 2) { - DrawEllipse(num, cRect(x, y, radius, radius), clrTransparent, -2); - DrawEllipse(num, cRect(x + width - radius, y , radius, radius), clrTransparent, -1); - DrawEllipse(num, cRect(x, y + height - radius, radius, radius), clrTransparent, -3); - DrawEllipse(num, cRect(x + width - radius, y + height - radius, radius, radius), clrTransparent, -4); - } -} - -void cPixmapContainer::DrawRoundedCornersWithBorder(int num, tColor borderColor, int radius, int width, int height) { - if (radius < 3) - return; - DrawEllipse(num, cRect(0,0,radius,radius), borderColor, -2); - DrawEllipse(num, cRect(-1,-1,radius,radius), clrTransparent, -2); - - DrawEllipse(num, cRect(width-radius,0,radius,radius), borderColor, -1); - DrawEllipse(num, cRect(width-radius+1,-1,radius,radius), clrTransparent, -1); - - DrawEllipse(num, cRect(0,height-radius,radius,radius), borderColor, -3); - DrawEllipse(num, cRect(-1,height-radius+1,radius,radius), clrTransparent, -3); - - DrawEllipse(num, cRect(width-radius,height-radius,radius,radius), borderColor, -4); - DrawEllipse(num, cRect(width-radius+1,height-radius+1,radius,radius), clrTransparent, -4); -} diff --git a/libcore/pixmapcontainer.h b/libcore/pixmapcontainer.h deleted file mode 100644 index a116da0..0000000 --- a/libcore/pixmapcontainer.h +++ /dev/null @@ -1,98 +0,0 @@ -#ifndef __PIXMAP_CONTAINER_H -#define __PIXMAP_CONTAINER_H - -#include -#include -#include "fontmanager.h" - -enum eFlushState { - fsOpen, - fsLock, - fsCount, -}; - -class cPixmapContainer : public cThread { -private: - static cMutex mutex; - static cOsd *osd; - static eFlushState flushState; - bool pixContainerInit; - int numPixmaps; - cPixmap **pixmaps; - int *pixmapsTransparency; - int *pixmapsLayer; - bool checkRunning; - int fadeTime; - int shiftTime; - int shiftType; - int shiftMode; - cPoint startPos; - bool deleteOsdOnExit; - void ShiftInFromBorder(int frames, int frameTime); - void ShiftOutToBorder(int frames, int frameTime); - void ShiftInFromPoint(int frames, int frameTime); - void ShiftOutToPoint(int frames, int frameTime); - cRect UnionPixmaps(void); -protected: - void SetInitFinished(void) { pixContainerInit = false; }; - bool CreateOsd(int Left, int Top, int Width, int Height); - void DeleteOsdOnExit(bool doDelete = true) { deleteOsdOnExit = doDelete; }; - //Wrappers for access to pixmaps - bool PixmapExists(int num); - int NumPixmaps(void) { return numPixmaps; }; - void CreatePixmap(int num, int Layer, const cRect &ViewPort, const cRect &DrawPort = cRect::Null); - bool DestroyPixmap(int num); - void DrawText(int num, const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, std::string fontName, int fontSize); - void DrawRectangle(int num, const cRect &Rect, tColor Color); - void DrawEllipse(int num, const cRect &Rect, tColor Color, int Quadrants = 0); - void DrawSlope(int num, const cRect &Rect, tColor Color, int Type); - void DrawImage(int num, const cPoint &Point, const cImage &Image); - void DrawBitmap(int num, const cPoint &Point, const cBitmap &Bitmap, tColor ColorFg = 0, tColor ColorBg = 0, bool Overlay = false); - void Fill(int num, tColor Color); - void SetAlpha(int num, int Alpha); - void SetTransparency(int num, int Transparency); - void SetLayer(int num, int Layer); - void SetViewPort(int num, const cRect &rect); - int Layer(int num); - void Pos(int num, cPoint &pos); - cRect ViewPort(int num); - int Width(int num); - int Height(int num); - int DrawportWidth(int num); - int DrawportHeight(int num); - int DrawportX(int num); - int DrawportY(int num); - void SetDrawPortPoint(int num, const cPoint &Point); - void SetCheckRunning(void) { checkRunning = true; }; - void UnsetCheckRunning(void) { checkRunning = false; }; - //HELPERS -- do not access the pixmaps array directly, use wrapper functions - void SetFadeTime(int fade) { fadeTime = fade; }; - void SetShiftTime(int shift) { shiftTime = shift; }; - void SetShiftType(int type) { shiftType = type; }; - void SetShiftMode(int mode) { shiftMode = mode; }; - void SetStartPos(int posX, int posY) { startPos.SetX(posX); startPos.SetY(posY); }; - bool IsAnimated(void) { return (shiftTime > 0); }; - int AnimationDelay(void); - void FadeIn(void); - void FadeOut(void); - void ShiftIn(void); - void ShiftOut(void); - void ScrollVertical(int num, int scrollDelay, int scrollSpeed); - void ScrollHorizontal(int num, int scrollDelay, int scrollSpeed, int scrollMode); - void CancelSave(void); - void DoSleep(int duration); - void DrawBlendedBackground(int num, int xStart, int width, tColor color, tColor colorBlending, bool fromTop); - void DrawRoundedCorners(int num, int radius, int x, int y, int width, int height); - void DrawRoundedCornersWithBorder(int num, tColor borderColor, int radius, int width, int height); -public: - cPixmapContainer(int numPixmaps); - virtual ~cPixmapContainer(void); - void LockFlush(void); - void OpenFlush(void); - void DoFlush(void); - void HidePixmaps(void); - void ShowPixmaps(void); - virtual void Action(void) {}; -}; - -#endif //__PIXMAP_CONTAINER_H \ No newline at end of file diff --git a/libskindesignerapi/Makefile b/libskindesignerapi/Makefile index 7948799..edff97c 100644 --- a/libskindesignerapi/Makefile +++ b/libskindesignerapi/Makefile @@ -3,7 +3,7 @@ NAME = skindesignerapi LIBNAME = lib$(NAME) MAJOR = 0 -MINOR = 0.2 +MINOR = 1.0 VERSION = $(MAJOR).$(MINOR) SONAME = $(LIBNAME).so.$(MAJOR) diff --git a/libskindesignerapi/osdelements.c b/libskindesignerapi/osdelements.c index 105a409..ae688ea 100644 --- a/libskindesignerapi/osdelements.c +++ b/libskindesignerapi/osdelements.c @@ -3,37 +3,37 @@ /********************************************************************** * cOsdElement **********************************************************************/ -skindesignerapi::cOsdElement::cOsdElement(skindesignerapi::ISkinDisplayPlugin *view) { +skindesignerapi::cOsdElement::cOsdElement(skindesignerapi::ISkinDisplayPlugin *view, int viewId) { this->view = view; + this->viewId = viewId; + tk = NULL; } skindesignerapi::cOsdElement::~cOsdElement() { } void skindesignerapi::cOsdElement::ClearTokens(void) { - stringTokens.clear(); - intTokens.clear(); - loopTokens.clear(); + tk->Clear(); } -void skindesignerapi::cOsdElement::AddStringToken(string key, string value) { - stringTokens.insert(pair(key, value)); +int skindesignerapi::cOsdElement::GetLoopIndex(const char *loop) { + return tk->LoopIndex(loop); } -void skindesignerapi::cOsdElement::AddIntToken(string key, int value) { - intTokens.insert(pair(key, value)); +void skindesignerapi::cOsdElement::SetLoop(vector loopInfo) { + tk->CreateLoopTokenContainer(&loopInfo); } -void skindesignerapi::cOsdElement::AddLoopToken(string loopName, map &tokens) { - map > >::iterator hitLoop = loopTokens.find(loopName); - if (hitLoop == loopTokens.end()) { - vector > tokenVector; - tokenVector.push_back(tokens); - loopTokens.insert(pair > >(loopName, tokenVector)); - } else { - vector > *tokenVector = &hitLoop->second; - tokenVector->push_back(tokens); - } +void skindesignerapi::cOsdElement::AddStringToken(int index, const char *value) { + tk->AddStringToken(index, value); +} + +void skindesignerapi::cOsdElement::AddIntToken(int index, int value) { + tk->AddIntToken(index, value); +} + +void skindesignerapi::cOsdElement::AddLoopToken(int loopIndex, int row, int index, const char *value) { + tk->AddLoopToken(loopIndex, row, index, value); } bool skindesignerapi::cOsdElement::ChannelLogoExists(string channelId) { @@ -41,166 +41,162 @@ bool skindesignerapi::cOsdElement::ChannelLogoExists(string channelId) { } string skindesignerapi::cOsdElement::GetEpgImagePath(void) { - return view->GetEpgImagePath(); + return view->GetEpgImagePath(); } +void skindesignerapi::cOsdElement::DebugTokenContainer(void) { + tk->Debug(); +} /********************************************************************** * cViewElement **********************************************************************/ -skindesignerapi::cViewElement::cViewElement(skindesignerapi::ISkinDisplayPlugin *view, int viewElementID) : cOsdElement(view) { - this->viewElementID = viewElementID; +skindesignerapi::cViewElement::cViewElement(skindesignerapi::ISkinDisplayPlugin *view, int viewId, int viewElementId) : cOsdElement(view, viewId) { + this->viewElementId = viewElementId; } skindesignerapi::cViewElement::~cViewElement() { + view->ClearViewElement(viewElementId, viewId); } void skindesignerapi::cViewElement::Clear(void) { - if (!view) - return; - view->ClearViewElement(viewElementID); + view->ClearViewElement(viewElementId, viewId); } void skindesignerapi::cViewElement::Display(void) { - if (!view) - return; - view->SetViewElementIntTokens(&intTokens); - view->SetViewElementStringTokens(&stringTokens); - view->SetViewElementLoopTokens(&loopTokens); - view->DisplayViewElement(viewElementID); + view->SetViewElementTokens(viewElementId, viewId, tk); + view->DisplayViewElement(viewElementId, viewId); } /********************************************************************** * cViewGrid **********************************************************************/ -skindesignerapi::cViewGrid::cViewGrid(skindesignerapi::ISkinDisplayPlugin *view, int viewGridID) : cOsdElement(view) { - this->viewGridID = viewGridID; +skindesignerapi::cViewGrid::cViewGrid(skindesignerapi::ISkinDisplayPlugin *view, int viewId, int viewGridId) : cOsdElement(view, viewId) { + this->viewGridId = viewGridId; } skindesignerapi::cViewGrid::~cViewGrid() { - if (!view) - return; - view->ClearGrids(viewGridID); + view->ClearGrids(viewId, viewGridId); } -void skindesignerapi::cViewGrid::SetGrid(long gridID, double x, double y, double width, double height) { - if (!view) - return; - view->SetGrid(viewGridID, gridID, x, y, width, height, &intTokens, &stringTokens); +void skindesignerapi::cViewGrid::SetGrid(long gridId, double x, double y, double width, double height) { + view->SetGrid(gridId, viewId, viewGridId, x, y, width, height, tk); } -void skindesignerapi::cViewGrid::SetCurrent(long gridID, bool current) { - if (!view) - return; - view->SetGridCurrent(viewGridID, gridID, current); +void skindesignerapi::cViewGrid::SetCurrent(long gridId, bool current) { + view->SetGridCurrent(gridId, viewId, viewGridId, current); } -void skindesignerapi::cViewGrid::MoveGrid(long gridID, double x, double y, double width, double height) { - if (!view) - return; - view->SetGrid(viewGridID, gridID, x, y, width, height, NULL, NULL); +void skindesignerapi::cViewGrid::MoveGrid(long gridId, double x, double y, double width, double height) { + view->SetGrid(gridId, viewId, viewGridId, x, y, width, height, NULL); } -void skindesignerapi::cViewGrid::Delete(long gridID) { - if (!view) - return; - view->DeleteGrid(viewGridID, gridID); +void skindesignerapi::cViewGrid::Delete(long gridId) { + view->DeleteGrid(gridId, viewId, viewGridId); } void skindesignerapi::cViewGrid::Clear(void) { - if (!view) - return; - view->ClearGrids(viewGridID); + view->ClearGrids(viewId, viewGridId); } void skindesignerapi::cViewGrid::Display(void) { - if (!view) - return; - view->DisplayGrids(viewGridID); + view->DisplayGrids(viewId, viewGridId); } /********************************************************************** * cViewTab **********************************************************************/ -skindesignerapi::cViewTab::cViewTab(skindesignerapi::ISkinDisplayPlugin *view) : cOsdElement(view) { +skindesignerapi::cViewTab::cViewTab(skindesignerapi::ISkinDisplayPlugin *view, int viewId) : cOsdElement(view, viewId) { } skindesignerapi::cViewTab::~cViewTab() { + view->ClearTab(viewId); } void skindesignerapi::cViewTab::Init(void) { - view->SetTabIntTokens(&intTokens); - view->SetTabStringTokens(&stringTokens); - view->SetTabLoopTokens(&loopTokens); - view->SetTabs(); + view->SetTabTokens(viewId, tk); } void skindesignerapi::cViewTab::Left(void) { - view->TabLeft(); + view->TabLeft(viewId); } void skindesignerapi::cViewTab::Right(void) { - view->TabRight(); + view->TabRight(viewId); } void skindesignerapi::cViewTab::Up(void) { - view->TabUp(); + view->TabUp(viewId); } void skindesignerapi::cViewTab::Down(void) { - view->TabDown(); + view->TabDown(viewId); } void skindesignerapi::cViewTab::Display(void) { - if (!view) - return; - view->DisplayTabs(); + view->DisplayTabs(viewId); } /********************************************************************** * cOsdView **********************************************************************/ -skindesignerapi::cOsdView::cOsdView(skindesignerapi::ISkinDisplayPlugin *displayPlugin) { +skindesignerapi::cOsdView::cOsdView(skindesignerapi::cPluginStructure *plugStruct, skindesignerapi::ISkinDisplayPlugin *displayPlugin, int viewId) { + this->plugStruct = plugStruct; this->displayPlugin = displayPlugin; + this->viewId = viewId; } skindesignerapi::cOsdView::~cOsdView() { - delete displayPlugin; + if (displayPlugin && (viewId == 0)) + displayPlugin->CloseOsd(); } void skindesignerapi::cOsdView::Deactivate(bool hide) { if (!displayPlugin) return; - displayPlugin->Deactivate(hide); + displayPlugin->Deactivate(viewId, hide); } void skindesignerapi::cOsdView::Activate(void) { if (!displayPlugin) return; - displayPlugin->Activate(); + displayPlugin->Activate(viewId); } -skindesignerapi::cViewElement *skindesignerapi::cOsdView::GetViewElement(int viewElementID) { +skindesignerapi::cViewElement *skindesignerapi::cOsdView::GetViewElement(int viewElementId) { if (!displayPlugin) return NULL; - return new cViewElement(displayPlugin, viewElementID); + cTokenContainer *tk = plugStruct->GetTokenContainerVE(viewId, viewElementId); + if (!tk) + return NULL; + skindesignerapi::cViewElement *ve = new cViewElement(displayPlugin, viewId, viewElementId); + ve->SetTokenContainer(tk); + return ve; } -skindesignerapi::cViewGrid *skindesignerapi::cOsdView::GetViewGrid(int viewGridID) { +skindesignerapi::cViewGrid *skindesignerapi::cOsdView::GetViewGrid(int viewGridId) { if (!displayPlugin) return NULL; - displayPlugin->InitGrids(viewGridID); - return new cViewGrid(displayPlugin, viewGridID); + cTokenContainer *tk = plugStruct->GetTokenContainerGE(viewId, viewGridId); + if (!tk) + return NULL; + skindesignerapi::cViewGrid *ge = new cViewGrid(displayPlugin, viewId, viewGridId); + ge->SetTokenContainer(tk); + return ge; } skindesignerapi::cViewTab *skindesignerapi::cOsdView::GetViewTabs(void) { if (!displayPlugin) return NULL; - return new cViewTab(displayPlugin); + cTokenContainer *tk = plugStruct->GetTokenContainerTab(viewId); + if (!tk) + return NULL; + skindesignerapi::cViewTab *tab = new cViewTab(displayPlugin, viewId); + tab->SetTokenContainer(tk); + return tab; } void skindesignerapi::cOsdView::Display(void) { - if (!displayPlugin) - return; - displayPlugin->Flush(); + if (displayPlugin) + displayPlugin->Flush(); } diff --git a/libskindesignerapi/osdelements.h b/libskindesignerapi/osdelements.h index df6193f..816a219 100644 --- a/libskindesignerapi/osdelements.h +++ b/libskindesignerapi/osdelements.h @@ -12,19 +12,22 @@ namespace skindesignerapi { class cOsdElement { protected: + int viewId; ISkinDisplayPlugin *view; - map < string, string > stringTokens; - map < string, int > intTokens; - map < string, vector< map< string, string > > > loopTokens; + cTokenContainer *tk; public: - cOsdElement(ISkinDisplayPlugin *view); + cOsdElement(ISkinDisplayPlugin *view, int viewId); virtual ~cOsdElement(); - void AddLoopToken(string loopName, map &tokens); - void AddStringToken(string key, string value); - void AddIntToken(string key, int value); + void SetTokenContainer(cTokenContainer *tk) { this->tk = tk; }; + int GetLoopIndex(const char *loop); + void SetLoop(vector loopInfo); + void AddLoopToken(int loopIndex, int row, int index, const char *value); + void AddStringToken(int index, const char *value); + void AddIntToken(int index, int value); void ClearTokens(void); bool ChannelLogoExists(string channelId); string GetEpgImagePath(void); + void DebugTokenContainer(void); }; /********************************************************************** @@ -32,9 +35,9 @@ public: **********************************************************************/ class cViewElement : public cOsdElement { private: - int viewElementID; + int viewElementId; public: - cViewElement(ISkinDisplayPlugin *view, int viewElementID); + cViewElement(ISkinDisplayPlugin *view, int viewId, int viewElementId); virtual ~cViewElement(); void Clear(void); void Display(void); @@ -45,14 +48,14 @@ public: **********************************************************************/ class cViewGrid : public cOsdElement { private: - int viewGridID; + int viewGridId; public: - cViewGrid(ISkinDisplayPlugin *view, int viewGridID); + cViewGrid(ISkinDisplayPlugin *view, int viewId, int viewGridId); virtual ~cViewGrid(); - void SetGrid(long gridID, double x, double y, double width, double height); - void SetCurrent(long gridID, bool current); - void MoveGrid(long gridID, double x, double y, double width, double height); - void Delete(long gridID); + void SetGrid(long gridId, double x, double y, double width, double height); + void SetCurrent(long gridId, bool current); + void MoveGrid(long gridId, double x, double y, double width, double height); + void Delete(long gridId); void Clear(void); void Display(void); }; @@ -63,7 +66,7 @@ public: class cViewTab : public cOsdElement { private: public: - cViewTab(ISkinDisplayPlugin *view); + cViewTab(ISkinDisplayPlugin *view, int viewId); virtual ~cViewTab(); void Init(void); void Left(void); @@ -79,8 +82,10 @@ public: class cOsdView { private: ISkinDisplayPlugin *displayPlugin; + cPluginStructure *plugStruct; + int viewId; public: - cOsdView(ISkinDisplayPlugin *displayPlugin); + cOsdView(cPluginStructure *plugStruct, ISkinDisplayPlugin *displayPlugin, int viewId); virtual ~cOsdView(); void Deactivate(bool hide); void Activate(void); diff --git a/libskindesignerapi/pluginstructure.c b/libskindesignerapi/pluginstructure.c new file mode 100644 index 0000000..2d5d4f3 --- /dev/null +++ b/libskindesignerapi/pluginstructure.c @@ -0,0 +1,92 @@ +#include "pluginstructure.h" + +skindesignerapi::cPluginStructure::cPluginStructure(void) { + name = ""; + libskindesignerAPIVersion = "undefined"; + id = -1; + rootview = ""; +}; + +skindesignerapi::cPluginStructure::~cPluginStructure(void) { + for (map::iterator it = menus.begin(); it != menus.end(); it++) { + delete (it->second).tokenContainer; + } +}; + +void skindesignerapi::cPluginStructure::RegisterMenu(int key, int type, string tpl, skindesignerapi::cTokenContainer *tk) { + tk->CreateContainers(); + sPlugMenu s; + s.type = type; + s.tplname = tpl; + s.tokenContainer = tk; + menus.insert(pair(key, s)); +} + +skindesignerapi::cTokenContainer *skindesignerapi::cPluginStructure::GetMenuTokenContainer(int key) { + map::iterator hit = menus.find(key); + if (hit == menus.end()) + return NULL; + return hit->second.tokenContainer; +} + +void skindesignerapi::cPluginStructure::RegisterRootView(string templateName) { + rootview = templateName; +} + +void skindesignerapi::cPluginStructure::RegisterSubView(int subView, string templateName) { + subviews.insert(pair(subView, templateName)); +} + +void skindesignerapi::cPluginStructure::RegisterViewElement(int view, int viewElement, string name, skindesignerapi::cTokenContainer *tk) { + tk->CreateContainers(); + sPlugViewElement ve; + ve.id = viewElement; + ve.viewId = view; + ve.name = name; + ve.tokenContainer = tk; + viewelements.insert(pair(view, ve)); +} + +void skindesignerapi::cPluginStructure::RegisterViewGrid(int view, int viewGrid, string name, skindesignerapi::cTokenContainer *tk) { + tk->CreateContainers(); + sPlugViewGrid vg; + vg.id = viewGrid; + vg.viewId = view; + vg.name = name; + vg.tokenContainer = tk; + viewgrids.insert(pair(view, vg)); +} + +void skindesignerapi::cPluginStructure::RegisterViewTab(int view, skindesignerapi::cTokenContainer *tk) { + tk->CreateContainers(); + viewtabs.insert(pair(view, tk)); +} + +skindesignerapi::cTokenContainer *skindesignerapi::cPluginStructure::GetTokenContainerVE(int viewId, int veId) { + pair::iterator, multimap::iterator> range; + range = viewelements.equal_range(viewId); + for (multimap::iterator it=range.first; it!=range.second; ++it) { + sPlugViewElement *ve = &it->second; + if (ve->id == veId) + return ve->tokenContainer; + } + return NULL; +} + +skindesignerapi::cTokenContainer *skindesignerapi::cPluginStructure::GetTokenContainerGE(int viewId, int geId) { + pair::iterator, multimap::iterator> range; + range = viewgrids.equal_range(viewId); + for (multimap::iterator it=range.first; it!=range.second; ++it) { + sPlugViewGrid *ge = &it->second; + if (ge->id == geId) + return ge->tokenContainer; + } + return NULL; +} + +skindesignerapi::cTokenContainer *skindesignerapi::cPluginStructure::GetTokenContainerTab(int viewId) { + map::iterator hit = viewtabs.find(viewId); + if (hit == viewtabs.end()) + return NULL; + return hit->second; +} diff --git a/libskindesignerapi/pluginstructure.h b/libskindesignerapi/pluginstructure.h new file mode 100644 index 0000000..f4ba281 --- /dev/null +++ b/libskindesignerapi/pluginstructure.h @@ -0,0 +1,57 @@ +#ifndef __PLUGINSTRUCTURE_H +#define __PLUGINSTRUCTURE_H + +#include "tokencontainer.h" + +namespace skindesignerapi { + +struct sPlugMenu { + int type; + string tplname; + cTokenContainer *tokenContainer; +}; + +struct sPlugViewElement { + int id; + int viewId; + string name; + cTokenContainer *tokenContainer; +}; + +struct sPlugViewGrid { + int id; + int viewId; + string name; + cTokenContainer *tokenContainer; +}; + +class cPluginStructure { +public: + cPluginStructure(void); + ~cPluginStructure(void); + void RegisterMenu(int key, int type, string tpl, cTokenContainer *tk); + cTokenContainer *GetMenuTokenContainer(int key); + void RegisterRootView(string templateName); + void RegisterSubView(int subView, string templateName); + void RegisterViewElement(int view, int viewElement, string name, cTokenContainer *tk); + void RegisterViewGrid(int view, int viewGrid, string name, cTokenContainer *tk); + void RegisterViewTab(int view, cTokenContainer *tk); + cTokenContainer *GetTokenContainerVE(int viewId, int veId); + cTokenContainer *GetTokenContainerGE(int viewId, int geId); + cTokenContainer *GetTokenContainerTab(int viewId); + string name; //name of plugin + string libskindesignerAPIVersion; //skindesigner API Version plugin is using + int id; //id of plugin in skindesigner + //basic plugin interface + map< int, sPlugMenu > menus; //menus as key -> sPlugMenu struct hashmap + //advanced plugin interface + string rootview; //template name of root view + map< int, string > subviews; //subviews as subviewid -> template name map + multimap< int, sPlugViewElement > viewelements; //viewelements as viewid -> sPlugViewElement struct multimap + multimap< int, sPlugViewGrid > viewgrids; //viewgrids as viewid -> sPlugViewGrid struct hashmap + map< int, cTokenContainer* > viewtabs; //viewtabs as viewid -> tokencontainer hashmap +}; + + +} +#endif //__PLUGINSTRUCTURE_H \ No newline at end of file diff --git a/libskindesignerapi/skindesignerapi.c b/libskindesignerapi/skindesignerapi.c index 0cd024e..6308b3e 100644 --- a/libskindesignerapi/skindesignerapi.c +++ b/libskindesignerapi/skindesignerapi.c @@ -3,31 +3,37 @@ skindesignerapi::SkindesignerAPI *skindesignerapi::SkindesignerAPI::skindesigner = NULL; skindesignerapi::SkindesignerAPI::SkindesignerAPI(void) { - if (skindesigner != NULL) - esyslog("skindesigner should only be loaded once"); - else - skindesigner = this; + if (skindesigner != NULL) + esyslog("skindesigner should only be loaded once"); + else + skindesigner = this; } skindesignerapi::SkindesignerAPI::~SkindesignerAPI(void) { - if (skindesigner == this) - skindesigner = NULL; + if (skindesigner == this) + skindesigner = NULL; +} + +bool skindesignerapi::SkindesignerAPI::ServiceAvailable(void) { + if (skindesigner) + return true; + return false; } bool skindesignerapi::SkindesignerAPI::RegisterPlugin(cPluginStructure *plugStructure) { - if (skindesigner) - return skindesigner->ServiceRegisterPlugin(plugStructure); - return false; + if (skindesigner) + return skindesigner->ServiceRegisterPlugin(plugStructure); + return false; } skindesignerapi::ISDDisplayMenu *skindesignerapi::SkindesignerAPI::GetDisplayMenu() { - if (skindesigner) - return skindesigner->ServiceGetDisplayMenu(); - return NULL; + if (skindesigner) + return skindesigner->ServiceGetDisplayMenu(); + return NULL; } -skindesignerapi::ISkinDisplayPlugin *skindesignerapi::SkindesignerAPI::GetDisplayPlugin(string pluginName, int viewID, int subViewID) { - if (skindesigner) - return skindesigner->ServiceGetDisplayPlugin(pluginName, viewID, subViewID); - return NULL; -} \ No newline at end of file +skindesignerapi::ISkinDisplayPlugin *skindesignerapi::SkindesignerAPI::GetDisplayPlugin(int plugId) { + if (skindesigner) + return skindesigner->ServiceGetDisplayPlugin(plugId); + return NULL; +} diff --git a/libskindesignerapi/skindesignerapi.h b/libskindesignerapi/skindesignerapi.h index f38e191..64155ae 100644 --- a/libskindesignerapi/skindesignerapi.h +++ b/libskindesignerapi/skindesignerapi.h @@ -7,92 +7,51 @@ using namespace std; #include #include #include +#include "pluginstructure.h" +#include "tokencontainer.h" namespace skindesignerapi { +enum eMenuType { + mtList, + mtText +}; + class ISDDisplayMenu : public cSkinDisplayMenu { public: virtual void SetTitle(const char *Title) = 0; - virtual void SetPluginMenu(string name, int menu, int type, bool init) = 0; - virtual bool SetItemPlugin(map *stringTokens, map *intTokens, map > > *loopTokens, int Index, bool Current, bool Selectable) = 0; - virtual bool SetPluginText(map *stringTokens, map *intTokens, map > > *loopTokens) = 0; + virtual void SetPluginMenu(int plugId, int menuId, int type, bool init) = 0; + virtual bool SetItemPlugin(cTokenContainer *tk, int Index, bool Current, bool Selectable) = 0; + virtual bool SetPluginText(cTokenContainer *tk) = 0; }; class ISkinDisplayPlugin { public: virtual ~ISkinDisplayPlugin(void) {}; - virtual void Deactivate(bool hide) = 0; - virtual void Activate(void) = 0; - virtual void ClearViewElement(int id) = 0; - virtual void DisplayViewElement(int id) = 0; - virtual void SetViewElementIntTokens(map *intTokens) = 0; - virtual void SetViewElementStringTokens(map *stringTokens) = 0; - virtual void SetViewElementLoopTokens(map > > *loopTokens) = 0; - virtual void InitGrids(int viewGridID) = 0; - virtual void SetGrid(int viewGridID, long gridID, double x, double y, double width, double height, map *intTokens, map *stringTokens) = 0; - virtual void SetGridCurrent(int viewGridID, long gridID, bool current) = 0; - virtual void DeleteGrid(int viewGridID, long gridID) = 0; - virtual void DisplayGrids(int viewGridID) = 0; - virtual void ClearGrids(int viewGridID) = 0; - virtual void SetTabIntTokens(map *intTokens) = 0; - virtual void SetTabStringTokens(map *stringTokens) = 0; - virtual void SetTabLoopTokens(map > > *loopTokens) = 0; - virtual void SetTabs(void) = 0; - virtual void TabLeft(void) = 0; - virtual void TabRight(void) = 0; - virtual void TabUp(void) = 0; - virtual void TabDown(void) = 0; - virtual void DisplayTabs(void) = 0; + virtual bool InitOsd(void) = 0; + virtual void CloseOsd(void) = 0; + virtual void Deactivate(int viewId, bool hide) = 0; + virtual void Activate(int viewId) = 0; + virtual void SetViewElementTokens(int id, int viewId, skindesignerapi::cTokenContainer *tk) = 0; + virtual void ClearViewElement(int id, int viewId) = 0; + virtual void DisplayViewElement(int id, int viewId) = 0; + virtual void SetGrid(long id, int viewId, int viewGridId, double x, double y, double width, double height, skindesignerapi::cTokenContainer *tk) = 0; + virtual void SetGridCurrent(long id, int viewId, int viewGridId, bool current) = 0; + virtual void DeleteGrid(long id, int viewId, int viewGridId) = 0; + virtual void DisplayGrids(int viewId, int viewGridId) = 0; + virtual void ClearGrids(int viewId, int viewGridId) = 0; + virtual void SetTabTokens(int viewId, skindesignerapi::cTokenContainer *tk) = 0; + virtual void TabLeft(int viewId) = 0; + virtual void TabRight(int viewId) = 0; + virtual void TabUp(int viewId) = 0; + virtual void TabDown(int viewId) = 0; + virtual void DisplayTabs(int viewId) = 0; + virtual void ClearTab(int viewId) = 0; virtual void Flush(void) = 0; virtual bool ChannelLogoExists(string channelId) = 0; virtual string GetEpgImagePath(void) = 0; }; -class cPluginStructure { -public: - cPluginStructure(void) { - name = ""; - libskindesignerAPIVersion = "undefined"; - }; - void SetMenu(int key, string templateName) { - menus.insert(pair(key, templateName)); - } - void SetView(int key, string templateName) { - views.insert(pair(key, templateName)); - } - void SetSubView(int view, int subView, string templateName) { - pair sub = make_pair(subView, templateName); - subViews.insert(pair >(view, sub)); - } - void SetViewElement(int view, int viewElement, string name) { - map< int, map >::iterator hit = viewElements.find(view); - if (hit == viewElements.end()) { - map vE; - vE.insert(pair(viewElement, name)); - viewElements.insert(pair >(view, vE)); - } else { - (hit->second).insert(pair(viewElement, name)); - } - } - void SetViewGrid(int view, int viewGrid, string name) { - map< int, map >::iterator hit = viewGrids.find(view); - if (hit == viewGrids.end()) { - map vG; - vG.insert(pair(viewGrid, name)); - viewGrids.insert(pair >(view, vG)); - } else { - (hit->second).insert(pair(viewGrid, name)); - } - } - string name; //name of plugin - string libskindesignerAPIVersion; //skindesigner API Version plugin is using - map< int, string > menus; //menus as key -> templatename hashmap - map< int, string> views; //standalone views as key -> templatename hashmap - multimap< int, pair > subViews; //subviews of standalone views as view -> (subview, templatename) multimap - map< int, map > viewElements; //viewelements as key -> (viewelement, viewelementname) hashmap - map< int, map > viewGrids; //viewgrids as key -> (viewgrid, viewgridname) hashmap -}; - class SkindesignerAPI { private: static SkindesignerAPI* skindesigner; @@ -101,11 +60,12 @@ protected: virtual ~SkindesignerAPI(void); virtual bool ServiceRegisterPlugin(cPluginStructure *plugStructure) = 0; virtual ISDDisplayMenu *ServiceGetDisplayMenu(void) = 0; - virtual ISkinDisplayPlugin *ServiceGetDisplayPlugin(string pluginName, int viewID, int subViewID) = 0; + virtual ISkinDisplayPlugin *ServiceGetDisplayPlugin(int plugId) = 0; public: + static bool ServiceAvailable(void); static bool RegisterPlugin(cPluginStructure *plugStructure); static ISDDisplayMenu *GetDisplayMenu(void); - static ISkinDisplayPlugin *GetDisplayPlugin(string pluginName, int viewID, int subViewID); + static ISkinDisplayPlugin *GetDisplayPlugin(int plugId); }; } diff --git a/libskindesignerapi/skindesignerosdbase.c b/libskindesignerapi/skindesignerosdbase.c index f552664..ed3ee73 100644 --- a/libskindesignerapi/skindesignerosdbase.c +++ b/libskindesignerapi/skindesignerosdbase.c @@ -4,44 +4,61 @@ * cSkindesignerOsdObject **********************************************************************/ -skindesignerapi::cSkindesignerOsdObject::cSkindesignerOsdObject(void) { - pluginName = ""; +skindesignerapi::cSkindesignerOsdObject::cSkindesignerOsdObject(cPluginStructure *plugStruct) { + this->plugStruct = plugStruct; + init = true; } skindesignerapi::cSkindesignerOsdObject::~cSkindesignerOsdObject() { } -bool skindesignerapi::cSkindesignerOsdObject::InitSkindesignerInterface(string pluginName) { - this->pluginName = pluginName; - return true; -} - -skindesignerapi::cOsdView *skindesignerapi::cSkindesignerOsdObject::GetOsdView(int viewID, int subViewID) { - ISkinDisplayPlugin *displayPlugin = SkindesignerAPI::GetDisplayPlugin(pluginName, viewID, subViewID); +skindesignerapi::cOsdView *skindesignerapi::cSkindesignerOsdObject::GetOsdView(int subViewId) { + ISkinDisplayPlugin *displayPlugin = SkindesignerAPI::GetDisplayPlugin(plugStruct->id); if (!displayPlugin) return NULL; - cOsdView *view = new cOsdView(displayPlugin); + if (init) { + init = false; + if (!displayPlugin->InitOsd()) { + esyslog("skindesignerapi: error opening osd"); + return NULL; + } + } + cOsdView *view = NULL; + if (subViewId > -1) + view = new cOsdView(plugStruct, displayPlugin, subViewId); + else { + view = new cOsdView(plugStruct, displayPlugin, 0); + } return view; } +bool skindesignerapi::cSkindesignerOsdObject::SkindesignerAvailable(void) { + return SkindesignerAPI::ServiceAvailable(); +} + + /********************************************************************** * cSkindesignerOsdItem **********************************************************************/ -skindesignerapi::cSkindesignerOsdItem::cSkindesignerOsdItem(eOSState State) : cOsdItem(State) { +skindesignerapi::cSkindesignerOsdItem::cSkindesignerOsdItem(cTokenContainer *tk, eOSState State) : cOsdItem(State) { sdDisplayMenu = NULL; + tokenContainer = new skindesignerapi::cTokenContainer(*tk); + tokenContainer->CreateContainers(); } -skindesignerapi::cSkindesignerOsdItem::cSkindesignerOsdItem(const char *Text, eOSState State, bool Selectable) : cOsdItem(Text, State, Selectable) { +skindesignerapi::cSkindesignerOsdItem::cSkindesignerOsdItem(cTokenContainer *tk, const char *Text, eOSState State, bool Selectable) : cOsdItem(Text, State, Selectable) { sdDisplayMenu = NULL; + tokenContainer = new skindesignerapi::cTokenContainer(*tk); + tokenContainer->CreateContainers(); } skindesignerapi::cSkindesignerOsdItem::~cSkindesignerOsdItem() { - + delete tokenContainer; } void skindesignerapi::cSkindesignerOsdItem::SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable) { if (sdDisplayMenu) { - if (!sdDisplayMenu->SetItemPlugin(&stringTokens, &intTokens, &loopTokens, Index, Current, Selectable)) { + if (!sdDisplayMenu->SetItemPlugin(tokenContainer, Index, Current, Selectable)) { DisplayMenu->SetItem(Text(), Index, Current, Selectable); } } else { @@ -49,59 +66,61 @@ void skindesignerapi::cSkindesignerOsdItem::SetMenuItem(cSkinDisplayMenu *Displa } } -void skindesignerapi::cSkindesignerOsdItem::AddStringToken(string key, string value) { - stringTokens.insert(pair(key, value)); +int skindesignerapi::cSkindesignerOsdItem::GetLoopIndex(const char *loop) { + return tokenContainer->LoopIndex(loop); } -void skindesignerapi::cSkindesignerOsdItem::AddIntToken(string key, int value) { - intTokens.insert(pair(key, value)); +void skindesignerapi::cSkindesignerOsdItem::SetLoop(vector loopInfo) { + tokenContainer->CreateLoopTokenContainer(&loopInfo); } -void skindesignerapi::cSkindesignerOsdItem::AddLoopToken(string loopName, map &tokens) { - map > >::iterator hitLoop = loopTokens.find(loopName); - if (hitLoop == loopTokens.end()) { - vector > tokenVector; - tokenVector.push_back(tokens); - loopTokens.insert(pair > >(loopName, tokenVector)); - } else { - vector > *tokenVector = &hitLoop->second; - tokenVector->push_back(tokens); - } +void skindesignerapi::cSkindesignerOsdItem::AddStringToken(int index, const char *value) { + tokenContainer->AddStringToken(index, value); +} + +void skindesignerapi::cSkindesignerOsdItem::AddIntToken(int index, int value) { + tokenContainer->AddIntToken(index, value); +} + +void skindesignerapi::cSkindesignerOsdItem::AddLoopToken(int loopIndex, int row, int index, const char *value) { + tokenContainer->AddLoopToken(loopIndex, row, index, value); } /********************************************************************** * cSkindesignerOsdMenu **********************************************************************/ -skindesignerapi::cSkindesignerOsdMenu::cSkindesignerOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4) : cOsdMenu(Title, c0, c1, c2, c3, c4) { +skindesignerapi::cSkindesignerOsdMenu::cSkindesignerOsdMenu(skindesignerapi::cPluginStructure *plugStruct, const char *Title, int c0, int c1, int c2, int c3, int c4) : cOsdMenu(Title, c0, c1, c2, c3, c4) { + this->plugStruct = plugStruct; + tokenContainer = NULL; init = true; + activeMenu = 0; firstCallCleared = false; secondCall = false; firstMenu = -1; firstType = mtList; displayText = false; sdDisplayMenu = NULL; - pluginName = ""; SetMenuCategory(mcPlugin); SetSkinDesignerDisplayMenu(); } skindesignerapi::cSkindesignerOsdMenu::~cSkindesignerOsdMenu() { - } -void skindesignerapi::cSkindesignerOsdMenu::SetPluginMenu(int menu, eMenuType type) { +void skindesignerapi::cSkindesignerOsdMenu::SetPluginMenu(int menuId, eMenuType type) { + activeMenu = menuId; if (firstCallCleared) { - firstMenu = menu; + firstMenu = menuId; firstType = type; } if (type == mtList) displayText = false; else if (type == mtText) displayText = true; - if (sdDisplayMenu) { - sdDisplayMenu->SetPluginMenu(pluginName, menu, type, init); + int plugId = plugStruct->id; + sdDisplayMenu->SetPluginMenu(plugId, menuId, type, init); } init = false; } @@ -113,29 +132,32 @@ bool skindesignerapi::cSkindesignerOsdMenu::SetSkinDesignerDisplayMenu(void) { void skindesignerapi::cSkindesignerOsdMenu::ClearTokens(void) { text = ""; - stringTokens.clear(); - intTokens.clear(); - loopTokens.clear(); + if (tokenContainer) + tokenContainer->Clear(); } -void skindesignerapi::cSkindesignerOsdMenu::AddStringToken(string key, string value) { - stringTokens.insert(pair(key, value)); +int skindesignerapi::cSkindesignerOsdMenu::GetLoopIndex(const char *loop) { + return tokenContainer->LoopIndex(loop); } -void skindesignerapi::cSkindesignerOsdMenu::AddIntToken(string key, int value) { - intTokens.insert(pair(key, value)); +void skindesignerapi::cSkindesignerOsdMenu::SetLoop(vector loopInfo) { + tokenContainer->CreateLoopTokenContainer(&loopInfo); } -void skindesignerapi::cSkindesignerOsdMenu::AddLoopToken(string loopName, map &tokens) { - map > >::iterator hitLoop = loopTokens.find(loopName); - if (hitLoop == loopTokens.end()) { - vector > tokenVector; - tokenVector.push_back(tokens); - loopTokens.insert(pair > >(loopName, tokenVector)); - } else { - vector > *tokenVector = &hitLoop->second; - tokenVector->push_back(tokens); - } +void skindesignerapi::cSkindesignerOsdMenu::SetTokenContainer(cTokenContainer *tk) { + tokenContainer = tk; +} + +void skindesignerapi::cSkindesignerOsdMenu::AddStringToken(int index, const char *value) { + tokenContainer->AddStringToken(index, value); +} + +void skindesignerapi::cSkindesignerOsdMenu::AddIntToken(int index, int value) { + tokenContainer->AddIntToken(index, value); +} + +void skindesignerapi::cSkindesignerOsdMenu::AddLoopToken(int loopIndex, int row, int index, const char *value) { + tokenContainer->AddLoopToken(loopIndex, row, index, value); } void skindesignerapi::cSkindesignerOsdMenu::TextKeyLeft(void) { @@ -162,6 +184,12 @@ void skindesignerapi::cSkindesignerOsdMenu::TextKeyDown(void) { DisplayMenu()->Scroll(false, false); } +skindesignerapi::cTokenContainer *skindesignerapi::cSkindesignerOsdMenu::GetTokenContainer(int menuId) { + if (!plugStruct) + return NULL; + return plugStruct->GetMenuTokenContainer(menuId); +} + void skindesignerapi::cSkindesignerOsdMenu::Display(void) { if (firstCallCleared) { firstCallCleared = false; @@ -174,11 +202,13 @@ void skindesignerapi::cSkindesignerOsdMenu::Display(void) { } if (displayText) { if (sdDisplayMenu) { + sdDisplayMenu->SetMenuCategory(mcPlugin); sdDisplayMenu->SetTitle(Title()); - if (sdDisplayMenu->SetPluginText(&stringTokens, &intTokens, &loopTokens)) { + if (tokenContainer && sdDisplayMenu->SetPluginText(tokenContainer)) { sdDisplayMenu->Flush(); } else { DisplayMenu()->Clear(); + DisplayMenu()->SetMenuCategory(mcText); DisplayMenu()->SetTitle(Title()); DisplayMenu()->SetText(text.c_str(), false); DisplayMenu()->Flush(); @@ -192,6 +222,7 @@ void skindesignerapi::cSkindesignerOsdMenu::Display(void) { return; } if (sdDisplayMenu) { + //sdDisplayMenu->SetMenuCategory(mcPlugin); sdDisplayMenu->SetTitle(Title()); for (cOsdItem *item = First(); item; item = Next(item)) { cSkindesignerOsdItem *sdItem = dynamic_cast(item); diff --git a/libskindesignerapi/skindesignerosdbase.h b/libskindesignerapi/skindesignerosdbase.h index 1b41092..baa7999 100644 --- a/libskindesignerapi/skindesignerosdbase.h +++ b/libskindesignerapi/skindesignerosdbase.h @@ -13,11 +13,6 @@ namespace skindesignerapi { -enum eMenuType { - mtList, - mtText -}; - class cOsdView; /********************************************************************** @@ -25,11 +20,12 @@ class cOsdView; **********************************************************************/ class cSkindesignerOsdObject : public cOsdObject { protected: - string pluginName; - bool InitSkindesignerInterface(string pluginName); - cOsdView *GetOsdView(int viewID, int subViewID = -1); + bool init; + cPluginStructure *plugStruct; + cOsdView *GetOsdView(int subViewId = -1); + bool SkindesignerAvailable(void); public: - cSkindesignerOsdObject(void); + cSkindesignerOsdObject(cPluginStructure *plugStruct); virtual ~cSkindesignerOsdObject(); virtual void Show(void) {}; }; @@ -40,19 +36,19 @@ public: class cSkindesignerOsdItem : public cOsdItem { private: ISDDisplayMenu *sdDisplayMenu; - map < string, string > stringTokens; - map < string, int > intTokens; - map < string, vector< map< string, string > > > loopTokens; + cTokenContainer *tokenContainer; protected: public: - cSkindesignerOsdItem(eOSState State = osUnknown); - cSkindesignerOsdItem(const char *Text, eOSState State = osUnknown, bool Selectable = true); + cSkindesignerOsdItem(cTokenContainer *tk, eOSState State = osUnknown); + cSkindesignerOsdItem(cTokenContainer *tk, const char *Text, eOSState State = osUnknown, bool Selectable = true); virtual ~cSkindesignerOsdItem(); virtual void SetMenuItem(cSkinDisplayMenu *DisplayMenu, int Index, bool Current, bool Selectable); void SetDisplayMenu(ISDDisplayMenu *sdDisplayMenu) { this->sdDisplayMenu = sdDisplayMenu; }; - void AddStringToken(string key, string value); - void AddIntToken(string key, int value); - void AddLoopToken(string loopName, map &tokens); + int GetLoopIndex(const char *loop); + void SetLoop(vector loopInfo); + void AddStringToken(int index, const char *value); + void AddIntToken(int index, int value); + void AddLoopToken(int loopIndex, int row, int index, const char *value); }; /********************************************************************** @@ -60,34 +56,37 @@ public: **********************************************************************/ class cSkindesignerOsdMenu : public cOsdMenu { private: + cPluginStructure *plugStruct; + cTokenContainer *tokenContainer; + int activeMenu; bool init; bool firstCallCleared; bool secondCall; int firstMenu; eMenuType firstType; bool displayText; - string pluginName; ISDDisplayMenu *sdDisplayMenu; string text; - map < string, string > stringTokens; - map < string, int > intTokens; - map < string, vector< map< string, string > > > loopTokens; bool SetSkinDesignerDisplayMenu(void); protected: + void SetPluginName(const char *name); void FirstCallCleared(void) { firstCallCleared = true; }; void ClearTokens(void); - void SetPluginName(string name) {pluginName = name; }; - void SetPluginMenu(int menu, eMenuType type); + void SetTokenContainer(cTokenContainer *tk); + void SetPluginMenu(int menuId, eMenuType type); void SetText(string text) { this->text = text; }; - void AddStringToken(string key, string value); - void AddIntToken(string key, int value); - void AddLoopToken(string loopName, map &tokens); + int GetLoopIndex(const char *loop); + void SetLoop(vector loopInfo); + void AddStringToken(int index, const char *value); + void AddIntToken(int index, int value); + void AddLoopToken(int loopIndex, int row, int index, const char *value); void TextKeyLeft(void); void TextKeyRight(void); void TextKeyUp(void); void TextKeyDown(void); + cTokenContainer *GetTokenContainer(int menuId); public: - cSkindesignerOsdMenu(const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0); + cSkindesignerOsdMenu(skindesignerapi::cPluginStructure *plugStruct, const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0); virtual ~cSkindesignerOsdMenu(); virtual void Display(void); }; diff --git a/libskindesignerapi/tokencontainer.c b/libskindesignerapi/tokencontainer.c new file mode 100644 index 0000000..00df1f2 --- /dev/null +++ b/libskindesignerapi/tokencontainer.c @@ -0,0 +1,305 @@ +#include "tokencontainer.h" + +skindesignerapi::cTokenContainer::cTokenContainer(void) { + numIntTokens = 0; + numStringTokens = 0; + stringTokens = NULL; + intTokens = NULL; + stNames = NULL; + itNames = NULL; +} + +skindesignerapi::cTokenContainer::cTokenContainer(const cTokenContainer &other) { + numIntTokens = 0; + numStringTokens = 0; + stringTokens = NULL; + intTokens = NULL; + stNames = NULL; + itNames = NULL; + stringTokenNames = other.stringTokenNames; + intTokenNames = other.intTokenNames; + loopTokenNames = other.loopTokenNames; + loopNameMapping = other.loopNameMapping; +} + +skindesignerapi::cTokenContainer::~cTokenContainer(void) { + Clear(); + delete[] intTokens; + delete[] stringTokens; + delete[] stNames; + delete[] itNames; +} + +void skindesignerapi::cTokenContainer::CreateContainers(void) { + numIntTokens = intTokenNames.size(); + if (numIntTokens) { + intTokens = new int[numIntTokens]; + itNames = new string[numIntTokens]; + for (int i=0; i < numIntTokens; i++) { + intTokens[i] = -1; + itNames[i] = GetIntTokenName(i); + } + } + numStringTokens = stringTokenNames.size(); + if (numStringTokens) { + stringTokens = new char*[numStringTokens]; + stNames = new string[numStringTokens]; + for (int i=0; i < numStringTokens; i++) { + stringTokens[i] = NULL; + stNames[i] = GetStringTokenName(i); + } + } + + int numLoops = loopTokenNames.size(); + for (int i = 0; i < numLoops; ++i) { + vector loopToken; + int numLoopTokens = loopTokenNames[i].size(); + for (int j = 0; j < numLoopTokens; ++j) { + string tokenName = GetLoopTokenName(i, j); + loopToken.push_back(tokenName); + } + ltNames.push_back(loopToken); + } +} + +void skindesignerapi::cTokenContainer::CreateLoopTokenContainer(vector *loopInfo) { + int numLoops = loopInfo->size(); + for (int i = 0; i < numLoops; ++i) { + numLoopTokens.push_back(loopInfo->at(i)); + int rows = loopInfo->at(i); + char*** loopToks = new char**[rows]; + for (int j = 0; j < rows ; ++j) { + int numLoopTokens = loopTokenNames[i].size(); + loopToks[j] = new char*[numLoopTokens]; + for (int k = 0; k < numLoopTokens; ++k) { + loopToks[j][k] = NULL; + } + } + loopTokens.push_back(loopToks); + } +} + +void skindesignerapi::cTokenContainer::DeleteLoopTokenContainer(void) { + int i = 0; + for (vector::iterator it = loopTokens.begin(); it != loopTokens.end(); it++) { + char*** loopToks = *it; + for (int j = 0; j < numLoopTokens[i] ; j++) { + int numToks = loopTokenNames[i].size(); + for (int k = 0; k < numToks; ++k) { + free(loopToks[j][k]); + } + delete[] loopToks[j]; + } + delete[] loopToks; + ++i; + } + loopTokens.clear(); + numLoopTokens.clear(); +} + +void skindesignerapi::cTokenContainer::DefineStringToken(string name, int index) { + stringTokenNames.insert(pair(name, index)); +} + +void skindesignerapi::cTokenContainer::DefineIntToken(string name, int index) { + intTokenNames.insert(pair(name, index)); +} + +void skindesignerapi::cTokenContainer::DefineLoopToken(string name, int index) { + string loopName = LoopName(name); + int loopIndex = LoopIndex(loopName, true); + if ((int)loopTokenNames.size() < loopIndex+1) { + map newloop; + newloop.insert(pair(name, index)); + loopTokenNames.push_back(newloop); + return; + } + loopTokenNames[loopIndex].insert(pair(name, index)); +} + +int skindesignerapi::cTokenContainer::GetNumDefinedIntTokens(void) { + return intTokenNames.size(); +} + +int skindesignerapi::cTokenContainer::LoopIndex(string name, bool createNew) { + map::iterator hit = loopNameMapping.find(name); + if (hit != loopNameMapping.end()) + return hit->second; + if (!createNew) + return -1; + int index = loopNameMapping.size(); + loopNameMapping.insert(pair(name, index)); + return index; +} + +int skindesignerapi::cTokenContainer::StringTokenIndex(string name) { + map::iterator hit = stringTokenNames.find(name); + if (hit == stringTokenNames.end()) + return -1; + return hit->second; +} + +int skindesignerapi::cTokenContainer::IntTokenIndex(string name) { + map::iterator hit = intTokenNames.find(name); + if (hit == intTokenNames.end()) + return -1; + return hit->second; +} + +int skindesignerapi::cTokenContainer::LoopTokenIndex(string name) { + string loopName = LoopName(name); + int loopIndex = LoopIndex(loopName); + if (loopIndex > -1 && loopIndex < (int)loopTokenNames.size()) { + map::iterator hit = loopTokenNames[loopIndex].find(name); + if (hit == loopTokenNames[loopIndex].end()) + return -1; + return hit->second; + } + return -1; +} + +void skindesignerapi::cTokenContainer::AddIntToken(int index, int value) { + intTokens[index] = value; +} + +void skindesignerapi::cTokenContainer::AddStringToken(int index, const char *value) { + if (value) + stringTokens[index] = strdup(value); +} + +void skindesignerapi::cTokenContainer::AddLoopToken(int loopIndex, int row, int index, const char *value) { + if (value) { + loopTokens[loopIndex][row][index] = strdup(value); + } +} + +int skindesignerapi::cTokenContainer::NumLoops(int loopIndex) { + int numLT = numLoopTokens.size(); + if (loopIndex >= 0 && loopIndex < numLT) + return numLoopTokens[loopIndex]; + return 0; +} + +void skindesignerapi::cTokenContainer::SetTokens(cTokenContainer *other) { + //Set Int and String Tokens + if (numIntTokens) { + for (int i=0; i < numIntTokens; i++) { + AddIntToken(i, other->IntToken(i)); + } + } + if (numStringTokens) { + for (int i=0; i < numStringTokens; i++) { + AddStringToken(i, other->StringToken(i)); + } + } + //Set Looptoken Container + set loopIndices; + for (map::iterator it = loopNameMapping.begin(); it != loopNameMapping.end(); it++) { + loopIndices.insert(it->second); + } + vector loopInfo; + for (set::iterator it = loopIndices.begin(); it != loopIndices.end(); it++) { + loopInfo.push_back(other->NumLoops(*it)); + } + CreateLoopTokenContainer(&loopInfo); + //Set Loop Tokens + int i = 0; + for (vector::iterator it = loopInfo.begin(); it != loopInfo.end(); it++) { + int numRows = *it; + int numCols = loopTokenNames[i].size(); + for (int j = 0; j < numRows; j++) { + for (int k = 0; k < numCols; k++) { + AddLoopToken(i, j, k, other->LoopToken(i, j, k)); + } + } + i++; + } +} + +void skindesignerapi::cTokenContainer::Clear(void) { + if (numIntTokens) { + for (int i=0; i < numIntTokens; i++) { + intTokens[i] = -1; + } + } + if (numStringTokens) { + for (int i=0; i < numStringTokens; i++) { + free(stringTokens[i]); + stringTokens[i] = NULL; + } + } + DeleteLoopTokenContainer(); +} + +void skindesignerapi::cTokenContainer::Debug(void) { + /* + esyslog("skindesigner: TokenContainer defined string tokens"); + for (map::iterator it = stringTokenNames.begin(); it != stringTokenNames.end(); it++) { + esyslog("skindesigner: name %s id %d", (it->first).c_str(), it->second); + } + esyslog("skindesigner: TokenContainer defined int tokens"); + for (map::iterator it = intTokenNames.begin(); it != intTokenNames.end(); it++) { + esyslog("skindesigner: name %s id %d", (it->first).c_str(), it->second); + } + */ + esyslog("skindesigner: TokenContainer content"); + for (int i=0; i < numStringTokens; i++) { + if (stringTokens[i]) + esyslog("skindesigner: stringtoken %d. %s: \"%s\"", i, stNames[i].c_str(), stringTokens[i]); + else + esyslog("skindesigner: stringtoken %d. %s: empty", i, stNames[i].c_str()); + } + for (int i=0; i < numIntTokens; i++) { + if (intTokens[i] >= 0) + esyslog("skindesigner: inttoken %d. %s: %d", i, itNames[i].c_str(), intTokens[i]); + else + esyslog("skindesigner: inttoken %d. %s: empty", i, itNames[i].c_str()); + } + + for (size_t i=0; i < loopTokens.size(); i++) { + for (int j = 0; j < numLoopTokens[i]; j++) { + esyslog("skindesigner: row %d", j); + for (size_t k = 0; k < loopTokenNames[i].size(); k++) { + if (loopTokens[i][j][k]) + esyslog("skindesigner: looptoken %d. %s: \"%s\"", (int)k, ltNames[i][k].c_str(), loopTokens[i][j][k]); + else + esyslog("skindesigner: looptoken %d. %s: empty", (int)k, ltNames[i][k].c_str()); + } + } + } +} + + +string skindesignerapi::cTokenContainer::GetStringTokenName(int id) { + for (map::iterator it = stringTokenNames.begin(); it != stringTokenNames.end(); it++) { + if (it->second == id) + return it->first; + } + return ""; +} +string skindesignerapi::cTokenContainer::GetIntTokenName(int id) { + for (map::iterator it = intTokenNames.begin(); it != intTokenNames.end(); it++) { + if (it->second == id) + return it->first; + } + return ""; +} + +string skindesignerapi::cTokenContainer::GetLoopTokenName(int loop, int id) { + for (map::iterator it = loopTokenNames[loop].begin(); it != loopTokenNames[loop].end(); it++) { + if (it->second == id) + return it->first; + } + return ""; +} + +//Get name of loop from a loop token name +string skindesignerapi::cTokenContainer::LoopName(string &loopToken) { + size_t hit = loopToken.find('{'); + if (hit != 0) + return ""; + hit = loopToken.find('['); + if (hit == string::npos) + return ""; + return loopToken.substr(1, hit-1); +} diff --git a/libskindesignerapi/tokencontainer.h b/libskindesignerapi/tokencontainer.h new file mode 100644 index 0000000..86d8652 --- /dev/null +++ b/libskindesignerapi/tokencontainer.h @@ -0,0 +1,69 @@ +#ifndef __TOKENCONTAINER_H +#define __TOKENCONTAINER_H + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace skindesignerapi { + +class cTokenContainer { +private: + int numIntTokens; + int numStringTokens; + vector numLoopTokens; + //token containers + char **stringTokens; + int *intTokens; + vectorloopTokens; + //mapping id --> name + string *stNames; + string *itNames; + vector< vector > ltNames; + //mapping name --> id + map stringTokenNames; + map intTokenNames; + vector< map > loopTokenNames; + //get token name from id + string GetStringTokenName(int id); + string GetIntTokenName(int id); + string GetLoopTokenName(int loop, int id); + //looptoken management + string LoopName(string &loopToken); + map loopNameMapping; + void DeleteLoopTokenContainer(void); +public: + cTokenContainer(void); + cTokenContainer(const cTokenContainer &other); + ~cTokenContainer(void); + void CreateContainers(void); + void CreateLoopTokenContainer(vector *loopInfo); + void DefineStringToken (string name, int index); + void DefineIntToken (string name, int index); + void DefineLoopToken (string name, int index); + int GetNumDefinedIntTokens(void); + int LoopIndex (string name, bool createNew = false); + int StringTokenIndex (string name); + int IntTokenIndex (string name); + int LoopTokenIndex (string name); + void AddIntToken (int index, int value); + void AddStringToken (int index, const char *value); + void AddLoopToken (int loopIndex, int row, int index, const char *value); + char *StringToken (int index) { return stringTokens[index]; }; + int IntToken (int index) { return intTokens[index]; }; + char *LoopToken (int i, int j, int k) { return loopTokens[i][j][k]; }; + int NumLoops (int loopIndex); + void SetTokens (cTokenContainer *other); + void Clear(void); + void Debug(void); +}; + +} +#endif //__TOKENCONTAINER_H \ No newline at end of file diff --git a/libtemplate/parameter.c b/libtemplate/parameter.c deleted file mode 100644 index d76cb35..0000000 --- a/libtemplate/parameter.c +++ /dev/null @@ -1,493 +0,0 @@ -#include "../config.h" -#include "parameter.h" - -using namespace std; - -// --- cNumericParameter ------------------------------------------------------------- - -cNumericParameter::cNumericParameter(string value) { - this->value = value; - globals = NULL; - isValid = false; - width = 0; - height = 0; - columnWidth = -1; - rowHeight = -1; - hor = true; - defaultValue = 0; -} - -cNumericParameter::~cNumericParameter(void) { -} - -void cNumericParameter::SetAreaSize(int w, int h) { - width = w; - height = h; -} - -int cNumericParameter::Parse(string &parsedValue) { - int retVal = defaultValue; - - if (IsNumber(value)) { - isValid = true; - retVal = atoi(value.c_str()); - return retVal; - } - - //checking for percent value - bool isPercentValue = CheckPercentValue(retVal); - if (isPercentValue) { - isValid = true; - return retVal; - } - - //checking for expression - bool isValidExpression = CheckExpression(retVal, parsedValue); - if (isValidExpression) { - isValid = true; - return retVal; - } - - return retVal; -} - -bool cNumericParameter::IsNumber(const string& s) { - string::const_iterator it = s.begin(); - while (it != s.end() && isdigit(*it)) ++it; - return !s.empty() && it == s.end(); -} - -bool cNumericParameter::CheckPercentValue(int &val) { - bool ok = false; - size_t posPercent = value.find('%'); - if (posPercent != string::npos) { - string strPerc = value.substr(0, posPercent); - if (!IsNumber(strPerc)) { - return ok; - } - int perc = atoi(strPerc.c_str()); - if (hor) { - val = width * perc / 100; - } else { - val = height * perc / 100; - } - ok = true; - } - return ok; -} - -bool cNumericParameter::CheckExpression(int &val, string &parsedVal) { - bool ok = false; - string parsedValue = value; - //remove white spaces - parsedValue.erase( std::remove_if( parsedValue.begin(), parsedValue.end(), ::isspace ), parsedValue.end() ); - - //check and replace {areawidth} and {areaheight} tokens - string tokenWidth = "{areawidth}"; - string tokenHeight = "{areaheight}"; - - stringstream sw; - sw << width; - string strWidth = sw.str(); - stringstream sh; - sh << height; - string strHeight = sh.str(); - - bool foundToken = true; - while(foundToken) { - size_t foundTokenWidth = parsedValue.find(tokenWidth); - if (foundTokenWidth != string::npos) { - parsedValue = parsedValue.replace(foundTokenWidth, tokenWidth.size(), strWidth); - } else { - foundToken = false; - } - } - - foundToken = true; - while(foundToken) { - size_t foundTokenHeight = parsedValue.find(tokenHeight); - if (foundTokenHeight != string::npos) { - parsedValue = parsedValue.replace(foundTokenHeight, tokenHeight.size(), strHeight); - } else { - foundToken = false; - } - } - - //check and replace {columnwidth} and {rowheight} tokens for loop functions - if (columnWidth > 0 || rowHeight > 0) { - tokenWidth = "{columnwidth}"; - tokenHeight = "{rowheight}"; - stringstream cw; - cw << columnWidth; - strWidth = cw.str(); - stringstream rh; - rh << rowHeight; - strHeight = rh.str(); - - foundToken = true; - while(foundToken) { - size_t foundTokenWidth = parsedValue.find(tokenWidth); - if (foundTokenWidth != string::npos) { - parsedValue = parsedValue.replace(foundTokenWidth, tokenWidth.size(), strWidth); - } else { - foundToken = false; - } - } - - foundToken = true; - while(foundToken) { - size_t foundTokenHeight = parsedValue.find(tokenHeight); - if (foundTokenHeight != string::npos) { - parsedValue = parsedValue.replace(foundTokenHeight, tokenHeight.size(), strHeight); - } else { - foundToken = false; - } - } - } - - if (globals) { - globals->ReplaceIntVars(parsedValue); - globals->ReplaceDoubleVars(parsedValue); - } - - if (IsNumber(parsedValue)) { - ok = true; - val = atoi(parsedValue.c_str()); - return ok; - } - - if (!ValidNumericExpression(parsedValue)) { - parsedVal = parsedValue; - return ok; - } - ok = true; - char * expression = new char[parsedValue.size() + 1]; - std::copy(parsedValue.begin(), parsedValue.end(), expression); - expression[parsedValue.size()] = '\0'; - int expRes = EvaluateTheExpression(expression); - val = expRes; - delete[] expression; - return ok; -} - -bool cNumericParameter::ValidNumericExpression(string &parsedValue) { - string::const_iterator it = parsedValue.begin(); - while (it != parsedValue.end() && (isdigit(*it) || *it == '.' || *it == ',' || *it == '+' || *it == '-' || *it == '*' || *it == '/')) ++it; - return !parsedValue.empty() && it == parsedValue.end(); -} - -int cNumericParameter::EvaluateTheExpression(char* expr) { - return round(ParseSummands(expr)); -} - -double cNumericParameter::ParseAtom(char*& expr) { - // Read the number from string - char* end_ptr; - double res = strtod(expr, &end_ptr); - // Advance the pointer and return the result - expr = end_ptr; - return res; -} - -// Parse multiplication and division -double cNumericParameter::ParseFactors(char*& expr) { - double num1 = ParseAtom(expr); - for(;;) { - // Save the operation - char op = *expr; - if(op != '/' && op != '*') - return num1; - expr++; - double num2 = ParseAtom(expr); - // Perform the saved operation - if(op == '/') { - if (num2 != 0) { - num1 /= num2; - } - } else - num1 *= num2; - } -} - -// Parse addition and subtraction -double cNumericParameter::ParseSummands(char*& expr) { - double num1 = ParseFactors(expr); - for(;;) { - char op = *expr; - if(op != '-' && op != '+') - return num1; - expr++; - double num2 = ParseFactors(expr); - if(op == '-') - num1 -= num2; - else - num1 += num2; - } -} - -// --- cConditionalParameter ------------------------------------------------------------- - -cConditionalParameter::cConditionalParameter(cGlobals *globals, string value) { - this->globals = globals; - isTrue = false; - this->value = value; - type = cpNone; -} - -cConditionalParameter::~cConditionalParameter(void) { -} - -void cConditionalParameter::Tokenize(void) { - size_t posAnd = value.find("++"); - if (posAnd != string::npos) { - type = cpAnd; - TokenizeValue("++"); - } else { - size_t posOr = value.find("||"); - if (posOr != string::npos) { - type = cpOr; - TokenizeValue("||"); - } - } - if (type == cpNone) { - InsertCondition(value); - } -} - -void cConditionalParameter::Evaluate(map < string, int > *intTokens, map < string, string > *stringTokens) { - isTrue = false; - bool first = true; - for (vector::iterator cond = conditions.begin(); cond != conditions.end(); cond++) { - bool tokenTrue = false; - - if (cond->type == ctStringSet) { - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(cond->tokenName); - if (hit != stringTokens->end()) { - string value = hit->second; - if (value.size() > 0) - tokenTrue = true; - } - } - } else if (cond->type == ctStringEmpty) { - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(cond->tokenName); - if (hit != stringTokens->end()) { - string value = hit->second; - if (value.size() == 0) - tokenTrue = true; - } else { - tokenTrue = true; - } - } else { - tokenTrue = true; - } - } else if (cond->type == ctStringEquals) { - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(cond->tokenName); - if (hit != stringTokens->end()) { - string value = hit->second; - if (!value.compare(cond->strCompareValue)) - tokenTrue = true; - } - } - if (!tokenTrue) { - string value = ""; - if (globals->GetString(cond->tokenName, value)) { - if (!value.compare(cond->strCompareValue)) { - tokenTrue = true; - } - } - } - } else if (cond->type == ctStringNotEquals) { - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(cond->tokenName); - if (hit != stringTokens->end()) { - string value = hit->second; - if (value.compare(cond->strCompareValue)) - tokenTrue = true; - } else { - tokenTrue = true; - } - } else { - tokenTrue = true; - } - } else if (cond->type == ctStringContains) { - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(cond->tokenName); - if (hit != stringTokens->end()) { - string value = hit->second; - if (value.find(cond->strCompareValue) != string::npos) - tokenTrue = true; - } - } - if (!tokenTrue) { - string value = ""; - if (globals->GetString(cond->tokenName, value)) { - if (value.find(cond->strCompareValue) != string::npos) { - tokenTrue = true; - } - } - } - } else if (cond->type == ctStringNotContains) { - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(cond->tokenName); - if (hit != stringTokens->end()) { - string value = hit->second; - if (value.find(cond->strCompareValue) == string::npos) - tokenTrue = true; - } else { - tokenTrue = true; - } - } else { - tokenTrue = true; - } - } else { - int tokenValue = EvaluateParameter(cond->tokenName, intTokens, stringTokens); - if (cond->type == ctBool) { - tokenTrue = tokenValue; - } else if (cond->type == ctGreater) { - tokenTrue = (tokenValue > cond->compareValue) ? true : false; - } else if (cond->type == ctLower) { - tokenTrue = (tokenValue < cond->compareValue) ? true : false; - } else if (cond->type == ctEquals) { - tokenTrue = (tokenValue == cond->compareValue) ? true : false; - } - } - - if (cond->isNegated) - tokenTrue = !tokenTrue; - if (type == cpAnd) { - if (first) - isTrue = tokenTrue; - else - isTrue = isTrue && tokenTrue; - } else if (type == cpOr) { - isTrue = isTrue || tokenTrue; - } else { - isTrue = tokenTrue; - } - first = false; - } -} - -int cConditionalParameter::EvaluateParameter(string token, map < string, int > *intTokens, map < string, string > *stringTokens) { - //first check globals - int result = 0; - if (globals->GetInt(token, result)) - return result; - //then check custom tokens - if (globals->GetCustomInt(token, result)) - return result; - //then check tokens - if (intTokens) { - map < string, int >::iterator hit = intTokens->find(token); - if (hit != intTokens->end()) { - return hit->second; - } - } - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(token); - if (hit != stringTokens->end()) { - string value = hit->second; - return atoi(value.c_str()); - } - } - return 0; -} - -void cConditionalParameter::TokenizeValue(string sep) { - string buffer = value; - bool sepFound = true; - while (sepFound) { - size_t posSep = buffer.find(sep); - if (posSep == string::npos) { - InsertCondition(buffer); - sepFound = false; - } - string token = buffer.substr(0, posSep); - buffer = buffer.replace(0, posSep + sep.size(), ""); - InsertCondition(token); - } -} - -void cConditionalParameter::InsertCondition(string cond) { - cond = StripWhitespaces(cond); - if (cond.size() < 1) - return; - - size_t tokenStart = cond.find('{'); - size_t tokenEnd = cond.find('}'); - - if (tokenStart == string::npos || tokenEnd == string::npos || tokenStart > tokenEnd) - return; - - string tokenName = cond.substr(tokenStart + 1, tokenEnd - tokenStart - 1); - string rest = cond.replace(tokenStart, tokenEnd - tokenStart + 1, ""); - - sCondition sCond; - sCond.tokenName = tokenName; - sCond.type = ctBool; - sCond.compareValue = 0; - sCond.strCompareValue = ""; - sCond.isNegated = false; - if (!rest.compare("not")) { - sCond.isNegated = true; - } else if (!rest.compare("isset")) { - sCond.type = ctStringSet; - } else if (!rest.compare("empty")) { - sCond.type = ctStringEmpty; - } else if (startswith(rest.c_str(), "strequal(")) { - sCond.strCompareValue = rest.substr(10, rest.size() - 11); - sCond.type = ctStringEquals; - } else if (startswith(rest.c_str(), "strnotequal(")) { - sCond.strCompareValue = rest.substr(13, rest.size() - 14); - sCond.type = ctStringNotEquals; - } else if (startswith(rest.c_str(), "strcontains(")) { - sCond.strCompareValue = rest.substr(13, rest.size() - 14); - sCond.type = ctStringContains; - } else if (startswith(rest.c_str(), "strnotcontains(")) { - sCond.strCompareValue = rest.substr(16, rest.size() - 17); - sCond.type = ctStringNotContains; - } else if (startswith(rest.c_str(), "gt(")) { - string compVal = rest.substr(4, rest.size() - 5); - sCond.compareValue = atoi(compVal.c_str()); - sCond.type = ctGreater; - } else if (startswith(rest.c_str(), "lt(")) { - string compVal = rest.substr(4, rest.size() - 5); - sCond.compareValue = atoi(compVal.c_str()); - sCond.type = ctLower; - } else if (startswith(rest.c_str(), "eq(")) { - string compVal = rest.substr(4, rest.size() - 5); - sCond.compareValue = atoi(compVal.c_str()); - sCond.type = ctEquals; - } - - conditions.push_back(sCond); -} - -string cConditionalParameter::StripWhitespaces(string value) { - size_t startEqual = value.find("strequal("); - size_t startNotEqual = value.find("strnotequal("); - size_t startContains = value.find("strcontains("); - size_t startNotContains = value.find("strnotcontains("); - if (startEqual != string::npos || startContains != string::npos || startNotEqual != string::npos || startNotContains != string::npos) { - size_t startString = value.find_first_of('\''); - size_t stopString = value.find_last_of('\''); - string text = value.substr(startString + 1, stopString - startString - 1); - value.replace(startString, stopString - startString + 1, "xxxxxx"); - value.erase( std::remove_if( value.begin(), value.end(), ::isspace ), value.end() ); - size_t startPlaceholder = value.find("xxxxxx"); - value.replace(startPlaceholder, 6, text); - } else { - value.erase( std::remove_if( value.begin(), value.end(), ::isspace ), value.end() ); - } - return value; -} - -void cConditionalParameter::Debug(void) { - dsyslog("skindesigner: Condition %s, Type: %s, cond is %s", value.c_str(), (type == cpAnd)?"and combination":((type == cpOr)?"or combination":"single param") , isTrue?"true":"false"); - for (vector::iterator it = conditions.begin(); it != conditions.end(); it++) { - dsyslog("skindesigner: cond token %s, type: %d, compareValue %d, negated: %d, strCompareValue %s", it->tokenName.c_str(), it->type, it->compareValue, it->isNegated, it->strCompareValue.c_str()); - } -} \ No newline at end of file diff --git a/libtemplate/parameter.h b/libtemplate/parameter.h deleted file mode 100644 index 0a4ca23..0000000 --- a/libtemplate/parameter.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef __TEMPLATEPARAMETER_H -#define __TEMPLATEPARAMETER_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "globals.h" - -using namespace std; - -enum eAlign { - alLeft, - alCenter, - alRight, - alTop, - alBottom -}; - -enum eScrollMode { - smNone, - smCarriageReturn, - smForthAndBack -}; - -enum eScrollSpeed { - ssNone, - ssSlow, - ssMedium, - ssFast -}; - -enum eOrientation { - orNone, - orHorizontal, - orVertical, - orAbsolute -}; - -// --- cNumericParameter ------------------------------------------------------------- - -class cNumericParameter { -private: - cGlobals *globals; - string value; - bool isValid; - int width; - int height; - int columnWidth; - int rowHeight; - bool hor; - int defaultValue; - bool IsNumber(const string& s); - bool CheckPercentValue(int &val); - bool CheckExpression(int &val, string &parsedVal); - bool ValidNumericExpression(string &parsedValue); - int EvaluateTheExpression(char* expr); - double ParseAtom(char*& expr); - double ParseFactors(char*& expr); - double ParseSummands(char*& expr); -public: - cNumericParameter(string value); - virtual ~cNumericParameter(void); - void SetGlobals(cGlobals *globals) { this->globals = globals; }; - void SetAreaSize(int w, int h); - void SetLoopContainer(int columnWidth, int rowHeight) { this->columnWidth = columnWidth; this->rowHeight = rowHeight; }; - void SetDefault(int def) { defaultValue = def; }; - void SetHorizontal(void) { hor = true; }; - void SetVertical(void) { hor = false; }; - int Parse(string &parsedValue); - bool Valid(void) { return isValid; }; -}; - -// --- cTextToken ------------------------------------------------------------- - -enum eTextTokenType { - ttConstString, - ttToken, - ttConditionalToken, - ttPrintfToken -}; - -class cTextToken { -public: - eTextTokenType type; - string value; - vector parameters; - vector subTokens; -}; - -// --- cConditionalParameter ------------------------------------------------------------- - -enum eCondParameterType { - cpAnd, - cpOr, - cpNone -}; - -enum eCondType { - ctLower, - ctGreater, - ctEquals, - ctBool, - ctStringSet, - ctStringEmpty, - ctStringEquals, - ctStringNotEquals, - ctStringContains, - ctStringNotContains, - ctNone -}; - -struct sCondition { - string tokenName; - bool isNegated; - eCondType type; - int compareValue; - string strCompareValue; -}; - -class cConditionalParameter { -private: - cGlobals *globals; - bool isTrue; - string value; - eCondParameterType type; - vector conditions; - void TokenizeValue(string sep); - void InsertCondition(string cond); - string StripWhitespaces(string value); - int EvaluateParameter(string token, map < string, int > *intTokens, map < string, string > *stringTokens); -public: - cConditionalParameter(cGlobals *globals, string value); - virtual ~cConditionalParameter(void); - void Tokenize(void); - void Evaluate(map < string, int > *intTokens, map < string, string > *stringTokens); - bool IsTrue(void) { return isTrue; }; - void Debug(void); -}; -#endif //__TEMPLATEPARAMETER_H \ No newline at end of file diff --git a/libtemplate/template.c b/libtemplate/template.c deleted file mode 100644 index 43fd3da..0000000 --- a/libtemplate/template.c +++ /dev/null @@ -1,322 +0,0 @@ - #include "template.h" -#include "xmlparser.h" -#include "../config.h" - -// --- cTemplate ------------------------------------------------------------- - -cTemplate::cTemplate(eViewType viewType, string pluginName, int viewID) { - globals = NULL; - rootView = NULL; - this->viewType = viewType; - CreateView(pluginName, viewID); -} - -cTemplate::~cTemplate() { - if (rootView) - delete rootView; - -} - -/******************************************************************* -* Public Functions -*******************************************************************/ -bool cTemplate::ReadFromXML(string xmlfile) { - string xmlFile; - switch (viewType) { - case vtDisplayChannel: - xmlFile = "displaychannel.xml"; - break; - case vtDisplayMenu: - xmlFile = "displaymenu.xml"; - break; - case vtDisplayMessage: - xmlFile = "displaymessage.xml"; - break; - case vtDisplayReplay: - xmlFile = "displayreplay.xml"; - break; - case vtDisplayVolume: - xmlFile = "displayvolume.xml"; - break; - case vtDisplayAudioTracks: - xmlFile = "displayaudiotracks.xml"; - break; - case vtDisplayPlugin: - xmlFile = xmlfile; - break; - default: - return false; - } - - cXmlParser parser; - if (!parser.ReadView(rootView, xmlFile)) { - return false; - } - if (!parser.ParseView()) { - return false; - } - - //read additional plugin menu templates - bool ok = true; - if (viewType == vtDisplayMenu) { - config.InitPluginMenuIterator(); - map *plugTemplates = NULL; - string plugName; - while ( plugTemplates = config.GetPluginTemplates(plugName) ) { - for (map ::iterator it = plugTemplates->begin(); it != plugTemplates->end(); it++) { - int templateNumber = it->first; - stringstream templateName; - templateName << "plug-" << plugName << "-" << it->second.c_str(); - if (parser.ReadPluginView(plugName, templateNumber, templateName.str())) { - ok = parser.ParsePluginView(plugName, templateNumber); - } else { - dsyslog("skindesigner: template %s for plugin %s not available", templateName.str().c_str(), plugName.c_str()); - } - } - } - } - return ok; -} - -void cTemplate::SetGlobals(cGlobals *globals) { - this->globals = globals; - rootView->SetGlobals(globals); -} - -void cTemplate::Translate(void) { - rootView->Translate(); -} - - -void cTemplate::PreCache(void) { - rootView->PreCache(false); -} - -vector< pair > cTemplate::GetUsedFonts(void) { - vector< pair > usedFonts; - - GetUsedFonts(rootView, usedFonts); - - rootView->InitSubViewIterator(); - cTemplateView *subView = NULL; - while(subView = rootView->GetNextSubView()) { - GetUsedFonts(subView, usedFonts); - } - - return usedFonts; -} - - -void cTemplate::CacheImages(void) { - CacheImages(rootView); - rootView->InitSubViewIterator(); - cTemplateView *subView = NULL; - while(subView = rootView->GetNextSubView()) { - CacheImages(subView); - } -} - -bool cTemplate::SetSubViews(string plugName, int viewID) { - map subViews = config.GetPluginSubViews(plugName, viewID); - - if (subViews.size() == 0) { - return true; - } - - for (map::iterator it = subViews.begin(); it != subViews.end(); it ++) { - int subViewID = it->first; - stringstream templateName; - templateName << "plug-" << plugName << "-" << it->second; - string subViewTemplate = templateName.str(); - cTemplateView *plgTemplateView = new cTemplateViewPlugin(plugName, subViewID); - plgTemplateView->SetGlobals(globals); - cXmlParser parser; - if (!parser.ReadView(plgTemplateView, subViewTemplate)) { - esyslog("skindesigner: error reading plugin %s template", plugName.c_str()); - delete plgTemplateView; - return false; - } - if (!parser.ParseView()) { - esyslog("skindesigner: error reading plugin %s template", plugName.c_str()); - delete plgTemplateView; - return false; - } - stringstream svid; - svid << subViewID; - rootView->AddSubView(svid.str(), plgTemplateView); - } - return true; -} - - -void cTemplate::Debug(void) { - rootView->Debug(); -} - -/******************************************************************* -* Private Functions -*******************************************************************/ - -void cTemplate::CreateView(string pluginName, int viewID) { - switch (viewType) { - case vtDisplayChannel: - rootView = new cTemplateViewChannel(); - break; - case vtDisplayMenu: - rootView = new cTemplateViewMenu(); - break; - case vtDisplayReplay: - rootView = new cTemplateViewReplay(); - break; - case vtDisplayVolume: - rootView = new cTemplateViewVolume(); - break; - case vtDisplayAudioTracks: - rootView = new cTemplateViewAudioTracks(); - break; - case vtDisplayMessage: - rootView = new cTemplateViewMessage(); - break; - case vtDisplayPlugin: - rootView = new cTemplateViewPlugin(pluginName, viewID); - break; - default: - esyslog("skindesigner: unknown view %d", viewType); - } -} - -void cTemplate::GetUsedFonts(cTemplateView *view, vector< pair > &usedFonts) { - //used fonts in viewElements - view->InitViewElementIterator(); - cTemplateViewElement *viewElement = NULL; - while(viewElement = view->GetNextViewElement()) { - viewElement->InitPixmapIterator(); - cTemplatePixmap *pix = NULL; - while(pix = viewElement->GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText) { - usedFonts.push_back(pair(func->GetFontName(), func->GetNumericParameter(ptFontSize))); - } - } - } - } - //used fonts in viewLists pixmaps - view->InitViewListIterator(); - cTemplateViewList *viewList = NULL; - while(viewList = view->GetNextViewList()) { - viewList->InitPixmapIterator(); - cTemplatePixmap *pix = NULL; - while(pix = viewList->GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText) { - usedFonts.push_back(pair(func->GetFontName(), func->GetNumericParameter(ptFontSize))); - } - } - } - cTemplateViewElement *listElement = viewList->GetListElement(); - listElement->InitPixmapIterator(); - while(pix = listElement->GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText) { - usedFonts.push_back(pair(func->GetFontName(), func->GetNumericParameter(ptFontSize))); - } - } - } - } - //used fonts in viewTabs - view->InitViewTabIterator(); - cTemplateViewTab *viewTab = NULL; - while(viewTab = view->GetNextViewTab()) { - viewTab->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = viewTab->GetNextFunction()) { - if (func->GetType() == ftDrawText) { - usedFonts.push_back(pair(func->GetFontName(), func->GetNumericParameter(ptFontSize))); - } - } - } -} - -void cTemplate::CacheImages(cTemplateView *view) { - //used images in viewElements - view->InitViewElementIterator(); - cTemplateViewElement *viewElement = NULL; - while(viewElement = view->GetNextViewElement()) { - viewElement->InitPixmapIterator(); - cTemplatePixmap *pix = NULL; - while(pix = viewElement->GetNextPixmap()) { - CachePixmapImages(pix); - } - } - //used images in viewLists pixmaps - view->InitViewListIterator(); - cTemplateViewList *viewList = NULL; - while(viewList = view->GetNextViewList()) { - viewList->InitPixmapIterator(); - cTemplatePixmap *pix = NULL; - while(pix = viewList->GetNextPixmap()) { - CachePixmapImages(pix); - } - cTemplateViewElement *listElement = viewList->GetListElement(); - listElement->InitPixmapIterator(); - while(pix = listElement->GetNextPixmap()) { - CachePixmapImages(pix); - } - cTemplateViewElement *currentElement = viewList->GetListElementCurrent(); - if (!currentElement) { - continue; - } - currentElement->InitPixmapIterator(); - while(pix = currentElement->GetNextPixmap()) { - CachePixmapImages(pix); - } - } - //used images in viewTabs - view->InitViewTabIterator(); - cTemplateViewTab *viewTab = NULL; - while(viewTab = view->GetNextViewTab()) { - CachePixmapImages(viewTab); - } -} - -void cTemplate::CachePixmapImages(cTemplatePixmap *pix) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawImage) { - CacheImage(func); - } - } -} - -void cTemplate::CacheImage(cTemplateFunction *func) { - eImageType imgType = (eImageType)func->GetNumericParameter(ptImageType); - int width = func->GetNumericParameter(ptWidth); - int height = func->GetNumericParameter(ptHeight); - - switch (imgType) { - case itIcon: - case itMenuIcon: { - string path = func->GetParameter(ptPath); - imgCache->CacheIcon(imgType, path, width, height); - break; } - case itChannelLogo: { - string doCache = func->GetParameter(ptCache); - if (!doCache.compare("true")) { - imgCache->CacheLogo(width, height); - } - break; } - case itSkinPart: { - string path = func->GetParameter(ptPath); - imgCache->CacheSkinpart(path, width, height); - break; } - default: - break; - } -} diff --git a/libtemplate/template.h b/libtemplate/template.h deleted file mode 100644 index 75dce5c..0000000 --- a/libtemplate/template.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef __TEMPLATE_H -#define __TEMPLATE_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "globals.h" -#include "templateview.h" -#include "templateviewelement.h" -#include "templatepixmap.h" -#include "templatefunction.h" - -using namespace std; - -// --- cTemplate ------------------------------------------------------------- -enum eViewType { - vtDisplayChannel, - vtDisplayMenu, - vtDisplayReplay, - vtDisplayVolume, - vtDisplayAudioTracks, - vtDisplayMessage, - vtDisplayPlugin -}; - -class cTemplate { -private: - eViewType viewType; - void CachePixmapImages(cTemplatePixmap *pix); - void CacheImage(cTemplateFunction *func); -protected: - cGlobals *globals; - cTemplateView *rootView; - void CreateView(string pluginName, int viewID); - void GetUsedFonts(cTemplateView *view, vector< pair > &usedFonts); - void CacheImages(cTemplateView *view); -public: - cTemplate(eViewType viewType, string pluginName = "", int viewID = -1); - virtual ~cTemplate(void); - bool ReadFromXML(string xmlfile = ""); - void SetGlobals(cGlobals *globals); - cTemplateView *GetRootView(void) { return rootView; }; - void Translate(void); - void PreCache(void); - //get fonts for pre caching - vector< pair > GetUsedFonts(void); - void CacheImages(void); - //Set Plugin Subviews - bool SetSubViews(string plugName, int viewID); - //Debug - void Debug(void); -}; - -#endif //__TEMPLATE_H \ No newline at end of file diff --git a/libtemplate/templatefunction.c b/libtemplate/templatefunction.c deleted file mode 100644 index 0adc754..0000000 --- a/libtemplate/templatefunction.c +++ /dev/null @@ -1,1856 +0,0 @@ -#include "templatefunction.h" -#include "../config.h" -#include "../libcore/helpers.h" - -using namespace std; - -// --- cTemplateFunction ------------------------------------------------------------- - -cTemplateFunction::cTemplateFunction(eFuncType type) { - this->type = type; - debug = false; - containerX = 0; - containerY = 0; - containerWidth = 0; - containerHeight = 0; - columnWidth = -1; - rowHeight = -1; - globals = NULL; - condParam = NULL; - parsedCompletely = false; - updated = false; - alreadyCutted = false; - parsedTextWidth = 0; - fontName = ""; - imgPath = ""; - textboxHeight = 0; - stringTokens = NULL; - intTokens = NULL; - parsedText = ""; - cuttedText = ""; -} - -cTemplateFunction::~cTemplateFunction(void) { - if (condParam) - delete condParam; -} - -/******************************************************************* -* Public Functions -*******************************************************************/ - -void cTemplateFunction::SetParameters(vector > params) { - for (vector >::iterator it = params.begin(); it != params.end(); it++) { - string name = it->first; - pair< eParamType, string > p; - if (!name.compare("debug")) { - string value = it->second; - if (!value.compare("true")) { - debug = true; - } - continue; - } else if (!name.compare("debuggrid")) { - string value = it->second; - SetDebugGrid(value); - continue; - } else if (!name.compare("condition")) { - p.first = ptCond; - } else if (!name.compare("name")) { - p.first = ptName; - } else if (!name.compare("mode")) { - p.first = ptMode; - } else if (!name.compare("x")) { - p.first = ptX; - } else if (!name.compare("y")) { - p.first = ptY; - } else if (!name.compare("width")) { - p.first = ptWidth; - } else if (!name.compare("height")) { - p.first = ptHeight; - } else if (!name.compare("menuitemwidth")) { - p.first = ptMenuItemWidth; - } else if (!name.compare("detached")) { - p.first = ptDetached; - } else if (!name.compare("fadetime")) { - p.first = ptFadeTime; - } else if (!name.compare("shifttime")) { - p.first = ptShiftTime; - } else if (!name.compare("shifttype")) { - p.first = ptShiftType; - } else if (!name.compare("shiftmode")) { - p.first = ptShiftMode; - } else if (!name.compare("startx")) { - p.first = ptStartX; - } else if (!name.compare("starty")) { - p.first = ptStartY; - } else if (!name.compare("imagetype")) { - p.first = ptImageType; - } else if (!name.compare("path")) { - p.first = ptPath; - } else if (!name.compare("color")) { - p.first = ptColor; - } else if (!name.compare("font")) { - p.first = ptFont; - } else if (!name.compare("fontsize")) { - p.first = ptFontSize; - } else if (!name.compare("text")) { - p.first = ptText; - } else if (!name.compare("layer")) { - p.first = ptLayer; - } else if (!name.compare("transparency")) { - p.first = ptTransparency; - } else if (!name.compare("background")) { - p.first = ptBackground; - } else if (!name.compare("quadrant")) { - p.first = ptQuadrant; - } else if (!name.compare("type")) { - p.first = ptType; - } else if (!name.compare("align")) { - p.first = ptAlign; - } else if (!name.compare("valign")) { - p.first = ptValign; - } else if (!name.compare("delay")) { - p.first = ptDelay; - } else if (!name.compare("mode")) { - p.first = ptScrollMode; - } else if (!name.compare("scrollspeed")) { - p.first = ptScrollSpeed; - } else if (!name.compare("orientation")) { - p.first = ptOrientation; - } else if (!name.compare("numlistelements")) { - p.first = ptNumElements; - } else if (!name.compare("scrollelement")) { - p.first = ptScrollElement; - } else if (!name.compare("scrollheight")) { - p.first = ptScrollHeight; - } else if (!name.compare("float")) { - p.first = ptFloat; - } else if (!name.compare("floatwidth")) { - p.first = ptFloatWidth; - } else if (!name.compare("floatheight")) { - p.first = ptFloatHeight; - } else if (!name.compare("maxlines")) { - p.first = ptMaxLines; - } else if (!name.compare("columnwidth")) { - p.first = ptColumnWidth; - } else if (!name.compare("rowheight")) { - p.first = ptRowHeight; - } else if (!name.compare("overflow")) { - p.first = ptOverflow; - } else if (!name.compare("scaletvx")) { - p.first = ptScaleTvX; - } else if (!name.compare("scaletvy")) { - p.first = ptScaleTvY; - } else if (!name.compare("scaletvwidth")) { - p.first = ptScaleTvWidth; - } else if (!name.compare("scaletvheight")) { - p.first = ptScaleTvHeight; - } else if (!name.compare("hideroot")) { - p.first = ptHideRoot; - } else if (!name.compare("cache")) { - p.first = ptCache; - } else if (!name.compare("determinatefont")) { - p.first = ptDeterminateFont; - } else if (!name.compare("direction")) { - p.first = ptDirection; - } else if (!name.compare("animtype")) { - p.first = ptAnimType; - } else if (!name.compare("animfreq")) { - p.first = ptAnimFreq; - } else { - p.first = ptNone; - } - p.second = it->second; - nativeParameters.insert(p); - } -} - -void cTemplateFunction::SetParameter(eParamType type, string value) { - nativeParameters.erase(type); - nativeParameters.insert(pair(type, value)); -} - -void cTemplateFunction::SetContainer(int x, int y, int w, int h) { - containerX = x; - containerY = y; - containerWidth = w; - containerHeight = h; -} - -void cTemplateFunction::SetLoopContainer(int columnWidth, int rowHeight) { - this->columnWidth = columnWidth; - this->rowHeight = rowHeight; -} - -void cTemplateFunction::SetWidthManually(string width) { - nativeParameters.erase(ptWidth); - nativeParameters.insert(pair(ptWidth, width)); -} - -void cTemplateFunction::SetHeightManually(string height) { - nativeParameters.erase(ptHeight); - nativeParameters.insert(pair(ptHeight, height)); -} - -void cTemplateFunction::SetXManually(int newX) { - numericParameters.erase(ptX); - numericParameters.insert(pair(ptX, newX)); -} - -void cTemplateFunction::SetYManually(int newY) { - numericParameters.erase(ptY); - numericParameters.insert(pair(ptY, newY)); -} - -void cTemplateFunction::SetTextboxHeight(int boxHeight) { - numericParameters.erase(ptHeight); - numericParameters.insert(pair(ptHeight, boxHeight)); -} - -void cTemplateFunction::SetTranslatedText(string translation) { - if (type != ftDrawText && type != ftDrawTextBox && type != ftDrawTextVertical) - return; - if (translation.size() == 0) - return; - nativeParameters.erase(ptText); - nativeParameters.insert(pair(ptText, translation)); -} - -void cTemplateFunction::SetMaxTextWidth(int maxWidth) { - if (type != ftDrawText) - return; - numericParameters.erase(ptWidth); - numericParameters.insert(pair(ptWidth, maxWidth)); -} - -bool cTemplateFunction::CalculateParameters(void) { - bool paramValid = true; - bool paramsValid = true; - for (map< eParamType, string >::iterator param = nativeParameters.begin(); param != nativeParameters.end(); param++) { - paramValid = true; - eParamType type = param->first; - string value = param->second; - switch (type) { - case ptCond: - paramValid = SetCondition(value); - break; - case ptX: - case ptY: - case ptWidth: - case ptHeight: - case ptMenuItemWidth: - case ptFadeTime: - case ptShiftTime: - case ptDelay: - case ptStartX: - case ptStartY: - case ptFontSize: - case ptLayer: - case ptTransparency: - case ptQuadrant: - case ptType: - case ptNumElements: - case ptFloatWidth: - case ptFloatHeight: - case ptMaxLines: - case ptColumnWidth: - case ptRowHeight: - case ptScaleTvX: - case ptScaleTvY: - case ptScaleTvWidth: - case ptScaleTvHeight: - case ptAnimFreq: - SetNumericParameter(type, value); - break; - case ptAlign: - case ptValign: - paramValid = SetAlign(type, value); - break; - case ptImageType: - paramValid = SetImageType(type, value); - break; - case ptColor: - paramValid = SetColor(type, value); - break; - case ptFont: - paramValid = SetFont(type, value); - break; - case ptText: - paramValid = SetTextTokens(value); - break; - case ptScrollMode: - paramValid = SetScrollMode(value); - break; - case ptScrollSpeed: - paramValid = SetScrollSpeed(value); - break; - case ptOrientation: - paramValid = SetOrientation(value); - break; - case ptFloat: - paramValid = SetFloating(value); - break; - case ptOverflow: - paramValid = SetOverflow(value); - break; - case ptHideRoot: - paramValid = SetHideRoot(value); - break; - case ptDetached: - paramValid = SetDetached(value); - break; - case ptBackground: - paramValid = SetBackground(value); - break; - case ptDirection: - paramValid = SetDirection(value); - break; - case ptAnimType: - paramValid = SetAnimType(value); - break; - case ptShiftType: - paramValid = SetShiftType(value); - break; - case ptShiftMode: - paramValid = SetShiftMode(value); - break; - default: - paramValid = true; - break; - } - if (!paramValid) { - paramsValid = false; - esyslog("skindesigner: %s: invalid parameter %d, value %s", GetFuncName().c_str(), type, value.c_str()); - } - } - return paramsValid; -} - -bool cTemplateFunction::ReCalculateParameters(void) { - bool paramValid = true; - bool paramsValid = true; - for (map< eParamType, string >::iterator param = nativeParameters.begin(); param != nativeParameters.end(); param++) { - paramValid = true; - eParamType type = param->first; - string value = param->second; - switch (type) { - case ptX: - case ptY: - case ptWidth: - case ptHeight: - case ptMenuItemWidth: - case ptFontSize: - case ptFloatWidth: - case ptFloatHeight: - case ptMaxLines: - case ptColumnWidth: - case ptRowHeight: - SetNumericParameter(type, value); - break; - default: - break; - } - if (!paramValid) { - paramsValid = false; - esyslog("skindesigner: %s: invalid parameter %d, value %s", GetFuncName().c_str(), type, value.c_str()); - } - } - return paramsValid; -} - -void cTemplateFunction::CompleteParameters(void) { - switch (type) { - case ftDrawImage: { - CalculateAlign(GetNumericParameter(ptWidth), GetNumericParameter(ptHeight)); - if (imgPath.size() == 0) { - imgPath = GetParameter(ptPath); - } - break; } - case ftDrawRectangle: - CalculateAlign(GetNumericParameter(ptWidth), GetNumericParameter(ptHeight)); - break; - case ftDrawEllipse: - CalculateAlign(GetNumericParameter(ptWidth), GetNumericParameter(ptHeight)); - break; - case ftDrawSlope: - CalculateAlign(GetNumericParameter(ptWidth), GetNumericParameter(ptHeight)); - break; - case ftDrawText: - CalculateAlign(GetWidth(), GetHeight()); - break; - default: - break; - } -} - -void cTemplateFunction::ClearDynamicParameters(void) { - parsedText = ""; - cuttedText = ""; - alreadyCutted = false; - parsedTextWidth = 0; - textboxHeight = 0; - - //clear dynamically parsed int parameters - for (map::iterator it = numericDynamicParameters.begin(); it != numericDynamicParameters.end(); it++) { - numericParameters.erase(it->first); - } - //restoring dynamic numeric parameters only if x, y, width or height of other elements is needed dynamically - for (map::iterator it = nativeParameters.begin(); it != nativeParameters.end(); it++) { - eParamType paramType = it->first; - if (paramType == ptX || - paramType == ptY || - paramType == ptWidth || - paramType == ptHeight || - paramType == ptFloatWidth || - paramType == ptFloatHeight) - { - string value = it->second; - if (value.find("{width(") != string::npos || value.find("{height(") != string::npos || value.find("{posx(") != string::npos || value.find("{posy(") != string::npos) { - numericDynamicParameters.erase(paramType); - SetNumericParameter(paramType, value); - } - } - } - -} - -bool cTemplateFunction::ParseParameters(void) { - updated = false; - parsedCompletely = true; - - if (stringTokens) { - ParseStringParameters(); - } - - if (intTokens && numericDynamicParameters.size() > 0) { - ParseNumericalParameters(); - } - - if (condParam) { - condParam->Evaluate(intTokens, stringTokens); - } - - return parsedCompletely; -} - -string cTemplateFunction::GetParameter(eParamType type) { - map::iterator hit = nativeParameters.find(type); - if (hit == nativeParameters.end()) - return ""; - return hit->second; -} - -int cTemplateFunction::GetNumericParameter(eParamType type) { - map::iterator hit = numericParameters.find(type); - if (hit == numericParameters.end()) { - //Set Default Value for Integer Parameters - if (type == ptLayer) - return 1; - else if (type == ptTransparency) - return 0; - else if (type == ptDelay) - return 0; - else if (type == ptFadeTime) - return 0; - else if (type == ptShiftTime) - return 0; - else if (type == ptMenuItemWidth) - return 0; - else if (type == ptHideRoot) - return 0; - else if (type == ptDetached) - return 0; - else if (type == ptBackground) - return 0; - else if (type == ptDrawDebugGrid) - return 0; - else if (type == ptDirection) - return diBottomUp; - else if (type == ptStartX) - return 0; - else if (type == ptStartY) - return 0; - else if (type == ptShiftType) - return stNone; - else if (type == ptShiftMode) - return smLinear; - //default default ;) - return -1; - } - return hit->second; -} - -string cTemplateFunction::GetText(bool cut) { - if (!cut) { - return parsedText; - } - if (alreadyCutted && cuttedText.size() > 0) { - return cuttedText; - } - alreadyCutted = true; - int maxWidth = GetNumericParameter(ptWidth); - if (maxWidth > 0) { - parsedTextWidth = fontManager->Width(fontName, GetNumericParameter(ptFontSize), parsedText.c_str()); - if (parsedTextWidth > maxWidth) { - cuttedText = CutText(parsedText, maxWidth, fontName, GetNumericParameter(ptFontSize)); - return cuttedText; - } - } - return parsedText; -} - - -tColor cTemplateFunction::GetColorParameter(eParamType type) { - map::iterator hit = colorParameters.find(type); - if (hit == colorParameters.end()) - return 0x00000000; - return hit->second; -} - -int cTemplateFunction::GetWidth(bool cutted) { - int funcWidth = 0; - switch (type) { - case ftDrawText: { - if (cutted) { - if (!alreadyCutted) { - alreadyCutted = true; - int maxWidth = GetNumericParameter(ptWidth); - if (maxWidth > 0) { - parsedTextWidth = fontManager->Width(fontName, GetNumericParameter(ptFontSize), parsedText.c_str()); - if (parsedTextWidth > maxWidth) { - cuttedText = CutText(parsedText, maxWidth, fontName, GetNumericParameter(ptFontSize)); - } - } - } - if (cuttedText.size() > 0) - return fontManager->Width(fontName, GetNumericParameter(ptFontSize), cuttedText.c_str()); - } - if (parsedTextWidth > 0) - funcWidth = parsedTextWidth; - else - funcWidth = fontManager->Width(fontName, GetNumericParameter(ptFontSize), parsedText.c_str()); - break; } - case ftDrawTextVertical: - funcWidth = GetNumericParameter(ptFontSize)*1.2; - break; - case ftFill: - case ftDrawImage: - case ftDrawRectangle: - case ftDrawEllipse: - case ftDrawSlope: - case ftDrawTextBox: - funcWidth = GetNumericParameter(ptWidth); - break; - default: - esyslog("skindesigner: GetWidth not implemented for funcType %d", type); - break; - } - return funcWidth; -} - -int cTemplateFunction::GetHeight(map < string, vector< map< string, string > > > *loopTokens) { - int funcHeight = 0; - switch (type) { - case ftDrawText: - funcHeight = fontManager->Height(fontName, GetNumericParameter(ptFontSize)); - break; - case ftDrawTextVertical: - funcHeight = fontManager->Width(fontName, GetNumericParameter(ptFontSize), parsedText.c_str()); - break; - case ftFill: - case ftDrawImage: - case ftDrawRectangle: - case ftDrawEllipse: - case ftDrawSlope: - funcHeight = GetNumericParameter(ptHeight); - break; - case ftDrawTextBox: { - int maxLines = GetNumericParameter(ptMaxLines); - int fixedBoxHeight = GetNumericParameter(ptHeight); - if (maxLines > 0) { - funcHeight = maxLines * fontManager->Height(fontName, GetNumericParameter(ptFontSize)); - } else if (fixedBoxHeight > 0) { - funcHeight = fixedBoxHeight; - } else if (textboxHeight > 0) { - funcHeight = textboxHeight; - } else { - funcHeight = CalculateTextBoxHeight(); - textboxHeight = funcHeight; - } - break; } - case ftLoop: { - cTemplateLoopFunction *loopFunc = dynamic_cast(this); - if (loopFunc) { - funcHeight = loopFunc->CalculateHeight(loopTokens); - } - break; } - default: - esyslog("skindesigner: GetHeight not implemented for funcType %d", type); - break; - } - return funcHeight; -} - -void cTemplateFunction::GetNeededWidths(multimap *widths) { - for (map::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) { - string val = param->second; - size_t posStart = val.find("{width("); - while (posStart != string::npos) { - size_t posEnd = val.find(")", posStart+1); - if (posEnd != string::npos) { - string label = val.substr(posStart+7, posEnd - posStart - 7); - widths->insert(pair(param->first, label)); - val = val.replace(posStart, posEnd - posStart, ""); - } else { - break; - } - posStart = val.find("{width("); - } - } -} - -void cTemplateFunction::GetNeededHeights(multimap *heights) { - for (map::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) { - string val = param->second; - size_t posStart = val.find("{height("); - while (posStart != string::npos) { - size_t posEnd = val.find(")", posStart + 1); - if (posEnd != string::npos) { - string label = val.substr(posStart + 8, posEnd - posStart - 8); - heights->insert(pair(param->first, label)); - val = val.replace(posStart, posEnd - posStart, ""); - } else { - break; - } - posStart = val.find("{height("); - } - } -} - -void cTemplateFunction::GetNeededPosX(multimap *posXs) { - for (map::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) { - string val = param->second; - size_t posStart = val.find("{posx("); - while (posStart != string::npos) { - size_t posEnd = val.find(")", posStart+1); - if (posEnd != string::npos) { - string label = val.substr(posStart+6, posEnd - posStart - 6); - posXs->insert(pair(param->first, label)); - val = val.replace(posStart, posEnd - posStart, ""); - } else { - break; - } - posStart = val.find("{posx("); - } - } -} - -void cTemplateFunction::GetNeededPosY(multimap *posYs) { - for (map::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) { - string val = param->second; - size_t posStart = val.find("{posy("); - while (posStart != string::npos) { - size_t posEnd = val.find(")", posStart+1); - if (posEnd != string::npos) { - string label = val.substr(posStart+6, posEnd - posStart - 6); - posYs->insert(pair(param->first, label)); - val = val.replace(posStart, posEnd - posStart, ""); - } else { - break; - } - posStart = val.find("{posy("); - } - } -} - -void cTemplateFunction::SetWidth(eParamType type, string label, int funcWidth) { - updated = false; - map< eParamType, string >::iterator hit = numericDynamicParameters.find(type); - if (hit == numericDynamicParameters.end()) - return; - stringstream needle; - needle << "{width(" << label << ")}"; - size_t posFound = (hit->second).find(needle.str()); - if (posFound == string::npos) - return; - stringstream repl; - repl << funcWidth; - string parsedVal = (hit->second).replace(posFound, needle.str().size(), repl.str()); - - cNumericParameter param(parsedVal); - param.SetAreaSize(containerWidth, containerHeight); - param.SetGlobals(globals); - int val = param.Parse(parsedVal); - if (param.Valid()) { - updated = true; - numericParameters.insert(pair(type, val)); - } else { - numericDynamicParameters.erase(type); - numericDynamicParameters.insert(pair(type, parsedVal)); - } -} - -void cTemplateFunction::SetHeight(eParamType type, string label, int funcHeight) { - updated = false; - map< eParamType, string >::iterator hit = numericDynamicParameters.find(type); - if (hit == numericDynamicParameters.end()) - return; - stringstream needle; - needle << "{height(" << label << ")}"; - size_t posFound = (hit->second).find(needle.str()); - if (posFound == string::npos) - return; - stringstream repl; - repl << funcHeight; - string parsedVal = (hit->second).replace(posFound, needle.str().size(), repl.str()); - - cNumericParameter param(parsedVal); - param.SetAreaSize(containerWidth, containerHeight); - param.SetGlobals(globals); - int val = param.Parse(parsedVal); - if (param.Valid()) { - updated = true; - numericParameters.insert(pair(type, val)); - } else { - numericDynamicParameters.erase(type); - numericDynamicParameters.insert(pair(type, parsedVal)); - } -} - -void cTemplateFunction::SetX(eParamType type, string label, int funcX) { - updated = false; - map< eParamType, string >::iterator hit = numericDynamicParameters.find(type); - if (hit == numericDynamicParameters.end()) - return; - stringstream needle; - needle << "{posx(" << label << ")}"; - size_t posFound = (hit->second).find(needle.str()); - if (posFound == string::npos) - return; - stringstream repl; - repl << funcX; - string parsedVal = (hit->second).replace(posFound, needle.str().size(), repl.str()); - - cNumericParameter param(parsedVal); - param.SetAreaSize(containerWidth, containerHeight); - param.SetGlobals(globals); - int val = param.Parse(parsedVal); - if (param.Valid()) { - updated = true; - numericParameters.insert(pair(type, val)); - } else { - numericDynamicParameters.erase(type); - numericDynamicParameters.insert(pair(type, parsedVal)); - } -} - -void cTemplateFunction::SetY(eParamType type, string label, int funcY) { - updated = false; - map< eParamType, string >::iterator hit = numericDynamicParameters.find(type); - if (hit == numericDynamicParameters.end()) - return; - stringstream needle; - needle << "{posy(" << label << ")}"; - size_t posFound = (hit->second).find(needle.str()); - if (posFound == string::npos) - return; - stringstream repl; - repl << funcY; - string parsedVal = (hit->second).replace(posFound, needle.str().size(), repl.str()); - - cNumericParameter param(parsedVal); - param.SetAreaSize(containerWidth, containerHeight); - param.SetGlobals(globals); - int val = param.Parse(parsedVal); - if (param.Valid()) { - updated = true; - numericParameters.insert(pair(type, val)); - } else { - numericDynamicParameters.erase(type); - numericDynamicParameters.insert(pair(type, parsedVal)); - } -} - -bool cTemplateFunction::DoExecute(void) { - if (!condParam) - return true; - return condParam->IsTrue(); -} - -bool cTemplateFunction::IsAnimated(void) { - map< eParamType, int >::iterator hit = numericParameters.find(ptAnimType); - if (hit == numericParameters.end()) - return false; - eAnimType type = (eAnimType)hit->second; - if (type > atNone) - return true; - return false; -} - -/******************************************************************* -* Private Functions -*******************************************************************/ - -bool cTemplateFunction::SetCondition(string cond) { - if (condParam) - delete condParam; - condParam = new cConditionalParameter(globals, cond); - condParam->Tokenize(); - return true; -} - - -bool cTemplateFunction::SetNumericParameter(eParamType type, string value) { - if (config.replaceDecPoint) { - if (value.find_first_of('.') != string::npos) { - std::replace( value.begin(), value.end(), '.', config.decPoint); - } - } - - cNumericParameter param(value); - param.SetAreaSize(containerWidth, containerHeight); - param.SetLoopContainer(columnWidth, rowHeight); - param.SetGlobals(globals); - switch (type) { - case ptX: - case ptStartX: - case ptWidth: - case ptMenuItemWidth: - case ptScaleTvX: - case ptScaleTvWidth: - param.SetHorizontal(); - break; - case ptY: - case ptStartY: - case ptHeight: - case ptScaleTvY: - case ptScaleTvHeight: - param.SetVertical(); - break; - case ptFontSize: { - if (this->type == ftDrawTextVertical) - param.SetHorizontal(); - else - param.SetVertical(); - break; } - case ptLayer: - param.SetDefault(1); - break; - default: - break; - } - string parsedValue = ""; - int val = param.Parse(parsedValue); - if (param.Valid()) { - if (this->type < ftLoop && type == ptX) { - val += containerX; - } - if (this->type < ftLoop && type == ptY) { - val += containerY; - } - numericParameters.erase(type); - numericDynamicParameters.erase(type); - numericParameters.insert(pair(type, val)); - } else { - numericDynamicParameters.erase(type); - numericDynamicParameters.insert(pair(type, parsedValue)); - } - return param.Valid(); -} - -bool cTemplateFunction::SetAlign(eParamType type, string value) { - eAlign align = alLeft; - bool ok = true; - if (!value.compare("center")) { - align = alCenter; - } else if (!value.compare("right")) { - align = alRight; - } else if (!value.compare("top")) { - align = alTop; - } else if (!value.compare("bottom")) { - align = alBottom; - } else if (!value.compare("left")) { - align = alLeft; - } else { - ok = false; - } - numericParameters.insert(pair(type, align)); - return ok; -} - -bool cTemplateFunction::SetFont(eParamType type, string value) { - //check if token - if (IsToken(value)) { - if (!globals->GetFont(value, fontName)) { - if (!globals->GetFont("{vdrOsd}", fontName)) { - return false; - } - } - } else { - //if no token, directly use input - fontName = value; - } - return true; -} - -bool cTemplateFunction::SetImageType(eParamType type, string value) { - eImageType imgType = itImage; - bool ok = true; - if (!value.compare("channellogo")) { - imgType = itChannelLogo; - } else if (!value.compare("seplogo")) { - imgType = itSepLogo; - } else if (!value.compare("skinpart")) { - imgType = itSkinPart; - } else if (!value.compare("menuicon")) { - imgType = itMenuIcon; - } else if (!value.compare("icon")) { - imgType = itIcon; - } else if (!value.compare("image")) { - imgType = itImage; - } else { - ok = false; - } - numericParameters.insert(pair(ptImageType, imgType)); - return ok; -} - - -bool cTemplateFunction::SetColor(eParamType type, string value) { - if (globals) { - tColor colVal = 0x00000000; - if (globals->GetColor(value, colVal)) { - colorParameters.insert(pair(type, colVal)); - return true; - } - } - if (value.size() != 8) - return false; - std::stringstream str; - str << value; - tColor colVal; - str >> std::hex >> colVal; - colorParameters.insert(pair(type, colVal)); - return true; -} - -bool cTemplateFunction::SetTextTokens(string value) { - textTokens.clear(); - //first replace globals - globals->ReplaceStringVars(value); - //now tokenize - bool tokenFound = true; - while (tokenFound) { - //search for conditional token or normal token - size_t tokenStart = value.find_first_of('{'); - size_t conditionStart = value.find_first_of('|'); - size_t printfStart = value.find("{printf("); - if (tokenStart == string::npos && conditionStart == string::npos) { - //find constant strings - if (value.size() > 0) { - cTextToken token; - token.type = ttConstString; - token.value = value; - textTokens.push_back(token); - } - tokenFound = false; - continue; - } else if (tokenStart != string::npos && conditionStart == string::npos) { - size_t tokenEnd = value.find_first_of('}'); - if (printfStart != string::npos && printfStart <= tokenStart) { - //replace printf text token - ParsePrintfTextToken(value, printfStart, tokenEnd); - } else { - //replace normal text token - ParseTextToken(value, tokenStart, tokenEnd); - } - } else if (tokenStart != string::npos && conditionStart != string::npos) { - if (tokenStart < conditionStart) { - size_t tokenEnd = value.find_first_of('}'); - if (printfStart != string::npos && printfStart <= tokenStart) { - //replace printf text token - ParsePrintfTextToken(value, printfStart, tokenEnd); - } else { - //replace normal text token - ParseTextToken(value, tokenStart, tokenEnd); - } - } else { - //replace conditional text token - size_t conditionEnd = value.find_first_of('|', conditionStart+1); - ParseConditionalTextToken(value, conditionStart, conditionEnd); - } - } - } - return true; -} - -void cTemplateFunction::ParseTextToken(string &value, size_t start, size_t end) { - cTextToken token; - if (start > 0) { - string constString = value.substr(0, start); - value = value.replace(0, start, ""); - token.type = ttConstString; - token.value = constString; - } else { - string tokenName = value.substr(1, end - start - 1); - value = value.replace(0, end - start + 1, ""); - token.type = ttToken; - token.value = tokenName; - } - textTokens.push_back(token); -} - -void cTemplateFunction::ParseConditionalTextToken(string &value, size_t start, size_t end) { - cTextToken token; - if (start > 0) { - string constString = value.substr(0, start); - value = value.replace(0, start, ""); - token.type = ttConstString; - token.value = constString; - } else { - string condToken = value.substr(start + 1, end - start - 1); - value = value.replace(0, end - start + 1, ""); - size_t tokenStart = condToken.find_first_of('{'); - size_t tokenEnd = condToken.find_first_of('}'); - vector subTokens; - if (tokenStart > 0) { - cTextToken subToken; - string constString = condToken.substr(0, tokenStart); - condToken = condToken.replace(0, tokenStart, ""); - subToken.type = ttConstString; - subToken.value = constString; - subTokens.push_back(subToken); - } - string tokenName = condToken.substr(1, tokenEnd - tokenStart - 1); - condToken = condToken.replace(0, tokenEnd - tokenStart + 1, ""); - - cTextToken subToken2; - subToken2.type = ttToken; - subToken2.value = tokenName; - subTokens.push_back(subToken2); - - if (condToken.size() > 0) { - cTextToken subToken3; - subToken3.type = ttConstString; - subToken3.value = condToken; - subTokens.push_back(subToken3); - } - - token.type = ttConditionalToken; - token.value = tokenName; - token.subTokens = subTokens; - } - textTokens.push_back(token); -} - -void cTemplateFunction::ParsePrintfTextToken(string &value, size_t start, size_t end) { - cTextToken token; - if (start > 0) { - string constString = value.substr(0, start); - value = value.replace(0, start, ""); - token.type = ttConstString; - token.value = constString; - } else { - token.type = ttPrintfToken; - //fetch parameter list from printf - string printfParams = value.substr(start + 8, end - start - 9); - value = value.replace(0, end - start + 1, ""); - splitstring s(printfParams.c_str()); - vector flds = s.split(',', 1); - - int numParams = flds.size(); - if (numParams < 1) - return; - string formatString = trim(flds[0]); - token.value = formatString.substr(1, formatString.size() - 2); - for (int i=1; i < numParams; i++) { - token.parameters.push_back(trim(flds[i])); - } - } - textTokens.push_back(token); -} - -bool cTemplateFunction::SetScrollMode(string value) { - eScrollMode mode = smNone; - bool ok = true; - if (!value.compare("forthandback")) - mode = smForthAndBack; - else if (!value.compare("carriagereturn")) - mode = smCarriageReturn; - else - ok = false; - numericParameters.insert(pair(ptScrollMode, mode)); - return ok; -} - -bool cTemplateFunction::SetScrollSpeed(string value) { - eScrollSpeed speed = ssMedium; - bool ok = true; - if (!value.compare("slow")) - speed = ssSlow; - else if (!value.compare("fast")) - speed = ssFast; - else if (!value.compare("medium")) - speed = ssMedium; - else - ok = false; - numericParameters.insert(pair(ptScrollSpeed, speed)); - return ok; - -} - -bool cTemplateFunction::SetOrientation(string value) { - eOrientation orientation = orNone; - bool ok = true; - if (!value.compare("horizontal")) - orientation = orHorizontal; - else if (!value.compare("vertical")) - orientation = orVertical; - else if (!value.compare("absolute")) - orientation = orAbsolute; - else - ok = false; - numericParameters.insert(pair(ptOrientation, orientation)); - return ok; -} - -bool cTemplateFunction::SetFloating(string value) { - eFloatType floatType = flNone; - bool ok = true; - if (!value.compare("topleft")) - floatType = flTopLeft; - else if (!value.compare("topright")) - floatType = flTopRight; - else - ok = false; - numericParameters.insert(pair(ptFloat, floatType)); - return ok; -} - -bool cTemplateFunction::SetOverflow(string value) { - eOverflowType overflowType = otNone; - bool ok = true; - if (!value.compare("linewrap")) - overflowType = otWrap; - else if (!value.compare("cut")) - overflowType = otCut; - else - ok = false; - numericParameters.insert(pair(ptOverflow, overflowType)); - return ok; -} - -bool cTemplateFunction::SetHideRoot(string value) { - int hideRoot = 0; - if (!value.compare("true")) - hideRoot = 1; - numericParameters.insert(pair(ptHideRoot, hideRoot)); - return true; -} - -bool cTemplateFunction::SetDetached(string value) { - int detached = 0; - if (!value.compare("true")) - detached = 1; - numericParameters.insert(pair(ptDetached, detached)); - return true; -} - -bool cTemplateFunction::SetBackground(string value) { - int back = 0; - if (!value.compare("true")) - back = 1; - numericParameters.insert(pair(ptBackground, back)); - return true; -} - -bool cTemplateFunction::SetDirection(string value) { - int direction = diNone; - if (!value.compare("bottomup")) - direction = diBottomUp; - else if (!value.compare("topdown")) - direction = diTopDown; - numericParameters.insert(pair(ptDirection, direction)); - return true; -} - -bool cTemplateFunction::SetAnimType(string value) { - int animType = atNone; - if (!value.compare("blink")) - animType = atBlink; - else if (!value.compare("animated")) - animType = atAnimated; - numericParameters.insert(pair(ptAnimType, animType)); - return true; -} - -bool cTemplateFunction::SetShiftType(string value) { - int shiftType = stNone; - if (!value.compare("left")) - shiftType = stLeft; - else if (!value.compare("right")) - shiftType = stRight; - else if (!value.compare("top")) - shiftType = stTop; - else if (!value.compare("bottom")) - shiftType = stBottom; - numericParameters.insert(pair(ptShiftType, shiftType)); - return true; -} - -bool cTemplateFunction::SetShiftMode(string value) { - int shiftMode = smLinear; - if (!value.compare("slowed")) - shiftMode = smSlowedDown; - numericParameters.insert(pair(ptShiftMode, shiftMode)); - return true; -} - -void cTemplateFunction::SetDebugGrid(string value) { - int numGridsX = 0; - int numGridsY = 0; - size_t posSep = value.find("x"); - if (posSep != string::npos) { - string x = value.substr(0, posSep); - string y = value.substr(posSep+1); - numGridsX = atoi(x.c_str()); - numGridsY = atoi(y.c_str()); - } - if (numGridsX < 1) - numGridsX = 10; - if (numGridsY < 1) - numGridsY = 10; - numericParameters.insert(pair(ptDebugGridX, numGridsX)); - numericParameters.insert(pair(ptDebugGridY, numGridsY)); - numericParameters.insert(pair(ptDrawDebugGrid, 1)); -} - -void cTemplateFunction::ParseStringParameters(void) { - //first replace stringtokens in Text (drawText) - stringstream text; - for (vector::iterator it = textTokens.begin(); it !=textTokens.end(); it++) { - updated = true; - if ((*it).type == ttConstString) { - text << (*it).value; - } else if ((*it).type == ttToken) { - bool found = false; - string tokenName = (*it).value; - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(tokenName); - if (hit != stringTokens->end()) { - text << hit->second; - found = true; - } - } - if (!found && intTokens) { - map < string, int >::iterator hitInt = intTokens->find(tokenName); - if (hitInt != intTokens->end()) { - text << hitInt->second; - found = true; - } - } - if (!found) { - text << "{" << tokenName << "}"; - } - } else if ((*it).type == ttConditionalToken) { - bool found = false; - string tokenName = (*it).value; - if (stringTokens) { - map < string, string >::iterator hit = stringTokens->find(tokenName); - if (hit != stringTokens->end()) { - string replaceText = hit->second; - if (replaceText.size() > 0) { - for (vector::iterator it2 = (*it).subTokens.begin(); it2 != (*it).subTokens.end(); it2++) { - if ((*it2).type == ttConstString) { - text << (*it2).value; - } else { - text << replaceText; - } - } - } - found = true; - } - } - if (!found && intTokens) { - map < string, int >::iterator hitInt = intTokens->find(tokenName); - if (hitInt != intTokens->end()) { - int intVal = hitInt->second; - if (intVal > 0) { - for (vector::iterator it2 = (*it).subTokens.begin(); it2 != (*it).subTokens.end(); it2++) { - if ((*it2).type == ttConstString) { - text << (*it2).value; - } else { - text << intVal; - } - } - } - found = true; - } - } - } else if ((*it).type == ttPrintfToken) { - cTextToken token = *it; - int paramCount = token.parameters.size(); - string printfResult = ""; - switch (paramCount) { - case 1: { - int param1 = ReplaceIntToken(token.parameters[0]); - printfResult = *cString::sprintf(token.value.c_str(), param1); - break; } - case 2: { - int param1 = ReplaceIntToken(token.parameters[0]); - int param2 = ReplaceIntToken(token.parameters[1]); - printfResult = *cString::sprintf(token.value.c_str(), param1, param2); - break; } - case 3: { - int param1 = ReplaceIntToken(token.parameters[0]); - int param2 = ReplaceIntToken(token.parameters[1]); - int param3 = ReplaceIntToken(token.parameters[2]); - printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3); - break; } - case 4: { - int param1 = ReplaceIntToken(token.parameters[0]); - int param2 = ReplaceIntToken(token.parameters[1]); - int param3 = ReplaceIntToken(token.parameters[2]); - int param4 = ReplaceIntToken(token.parameters[3]); - printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3, param4); - break; } - case 5: { - int param1 = ReplaceIntToken(token.parameters[0]); - int param2 = ReplaceIntToken(token.parameters[1]); - int param3 = ReplaceIntToken(token.parameters[2]); - int param4 = ReplaceIntToken(token.parameters[3]); - int param5 = ReplaceIntToken(token.parameters[4]); - printfResult = *cString::sprintf(token.value.c_str(), param1, param2, param3, param4, param5); - break; } - default: - break; - } - text << printfResult; - } - } - parsedText = text.str(); - - string path = GetParameter(ptPath); - if (GetNumericParameter(ptImageType) == itImage && path.size() > 0) { - //no absolute pathes allowed - if (!startswith(path.c_str(), "{")) { - esyslog("skindesigner: no absolute pathes allowed for images - %s", path.c_str()); - } - if (startswith(path.c_str(), "{ressourcedir}")) { - imgPath = path.replace(0, 14, *config.GetSkinRessourcePath()); - } - } - //now check further possible string variables - if (stringTokens && path.size() > 0 && path.find("{") != string::npos) { - for (map < string, string >::iterator it = stringTokens->begin(); it != stringTokens->end(); it++) { - size_t found = path.find(it->first); - if (found != string::npos) { - size_t posEndBracket = found + (it->first).size(); - if (posEndBracket < path.size()) { - string endChar = path.substr(posEndBracket, 1); - if (endChar.compare("}")) - continue; - } - updated = true; - imgPath = path; - if (found > 0 && ((it->first).size() + 2 <= imgPath.size())) - imgPath.replace(found-1, (it->first).size() + 2, it->second); - break; - } - } - for (map < string, int >::iterator it = intTokens->begin(); it != intTokens->end(); it++) { - size_t found = path.find(it->first); - if (found != string::npos) { - size_t posEndBracket = found + (it->first).size(); - if (posEndBracket < path.size()) { - string endChar = path.substr(posEndBracket, 1); - if (endChar.compare("}")) - continue; - } - updated = true; - imgPath = path; - if (found > 0 && ((it->first).size() + 2 <= imgPath.size())) { - stringstream intVal; - intVal << it->second; - imgPath.replace(found-1, (it->first).size() + 2, intVal.str()); - } - break; - } - } - } -} - -void cTemplateFunction::ParseNumericalParameters(void) { - parsedCompletely = true; - for (map::iterator param = numericDynamicParameters.begin(); param !=numericDynamicParameters.end(); param++) { - string val = param->second; - for (map::iterator tok = intTokens->begin(); tok != intTokens->end(); tok++) { - stringstream sToken; - sToken << "{" << tok->first << "}"; - string token = sToken.str(); - size_t foundToken = val.find(token); - //replace token as often as it appears - while (foundToken != string::npos) { - stringstream sVal; - sVal << tok->second; - val = val.replace(foundToken, token.size(), sVal.str()); - foundToken = val.find(token); - } - } - cNumericParameter p(val); - string parsedVal = ""; - int newVal = p.Parse(parsedVal); - if (p.Valid()) { - updated = true; - numericParameters.insert(pair(param->first, newVal)); - } else { - parsedCompletely = false; - } - } -} - -void cTemplateFunction::CalculateAlign(int elementWidth, int elementHeight) { - int align = GetNumericParameter(ptAlign); - //if element is used in a loop, use loop box width - int boxWidth = (columnWidth > 0) ? columnWidth : containerWidth; - int boxHeight = (rowHeight > 0) ? rowHeight : containerHeight; - if (align == alCenter) { - int xNew = (boxWidth - elementWidth) / 2; - numericParameters.erase(ptX); - numericParameters.insert(pair(ptX, xNew)); - } else if (align == alRight) { - int xNew = boxWidth - elementWidth; - numericParameters.erase(ptX); - numericParameters.insert(pair(ptX, xNew)); - } - - int vAlign = GetNumericParameter(ptValign); - if (vAlign == alCenter) { - int yNew = (boxHeight - elementHeight) / 2; - numericParameters.erase(ptY); - numericParameters.insert(pair(ptY, yNew)); - } else if (vAlign == alBottom) { - int yNew = boxHeight - elementHeight; - numericParameters.erase(ptY); - numericParameters.insert(pair(ptY, yNew)); - } -} - -int cTemplateFunction::CalculateTextBoxHeight(void) { - int width = GetNumericParameter(ptWidth); - string fontName = GetFontName(); - int fontSize = GetNumericParameter(ptFontSize); - string text = GetText(false); - const cFont *font = fontManager->Font(fontName, fontSize); - if (!font) - return 0; - - int fontHeight = fontManager->Height(fontName, fontSize); - int floatType = GetNumericParameter(ptFloat); - - if (floatType == flNone) { - fontManager->Lock(); - cTextWrapper wrapper; - wrapper.Set(text.c_str(), font, width); - fontManager->Unlock(); - int lines = wrapper.Lines(); - return (lines * fontHeight); - } - - int floatWidth = GetNumericParameter(ptFloatWidth); - int floatHeight = GetNumericParameter(ptFloatHeight); - - cTextWrapper wTextTall; - cTextWrapper wTextFull; - - int linesNarrow = floatHeight / fontHeight; - int widthNarrow = width - floatWidth; - int linesDrawn = 0; - int curY = 0; - bool drawNarrow = true; - - splitstring s(text.c_str()); - vector flds = s.split('\n', 1); - - if (flds.size() < 1) - return 0; - - stringstream sstrTextTall; - stringstream sstrTextFull; - - for (int i=0; i < (int)flds.size(); i++) { - if (!flds[i].size()) { - //empty line - linesDrawn++; - curY += fontHeight; - if (drawNarrow) - sstrTextTall << "\n"; - else - sstrTextFull << "\n"; - } else { - cTextWrapper wrapper; - if (drawNarrow) { - fontManager->Lock(); - wrapper.Set((flds[i].c_str()), font, widthNarrow); - fontManager->Unlock(); - int newLines = wrapper.Lines(); - //check if wrapper fits completely into narrow area - if (linesDrawn + newLines < linesNarrow) { - for (int line = 0; line < wrapper.Lines(); line++) { - sstrTextTall << wrapper.GetLine(line) << " "; - } - sstrTextTall << "\n"; - linesDrawn += newLines; - } else { - //this wrapper has to be splitted - for (int line = 0; line < wrapper.Lines(); line++) { - if (line + linesDrawn < linesNarrow) { - sstrTextTall << wrapper.GetLine(line) << " "; - } else { - sstrTextFull << wrapper.GetLine(line) << " "; - } - } - sstrTextFull << "\n"; - drawNarrow = false; - } - } else { - fontManager->Lock(); - wrapper.Set((flds[i].c_str()), font, width); - fontManager->Unlock(); - for (int line = 0; line < wrapper.Lines(); line++) { - sstrTextFull << wrapper.GetLine(line) << " "; - } - sstrTextFull << "\n"; - } - } - } - fontManager->Lock(); - wTextTall.Set(sstrTextTall.str().c_str(), font, widthNarrow); - fontManager->Unlock(); - fontManager->Lock(); - wTextFull.Set(sstrTextFull.str().c_str(), font, width); - fontManager->Unlock(); - - int textLinesTall = wTextTall.Lines(); - int textLinesFull = wTextFull.Lines(); - - return ((textLinesTall+textLinesFull) * fontHeight); -} - -int cTemplateFunction::ReplaceIntToken(string intTok) { - if (intTokens) { - map::iterator hit = intTokens->find(intTok); - if (hit != intTokens->end()) - return hit->second; - } - if (stringTokens) { - map::iterator hit = stringTokens->find(intTok); - if (hit != stringTokens->end()) { - return atoi(hit->second.c_str()); - } - } - return 0; -} - -/******************************************************************* -* Helper Functions -*******************************************************************/ - -string cTemplateFunction::GetFuncName(void) { - string name; - switch (type) { - case ftOsd: - name = "OSD Parameters"; - break; - case ftView: - name = "View Parameters"; - break; - case ftViewElement: - name = "View Element Parameters"; - break; - case ftPixmapContainer: - name = "Pixmap Container Parameters"; - break; - case ftPixmap: - name = "Pixmap Parameters"; - break; - case ftPixmapScroll: - name = "ScrollPixmap Parameters"; - break; - case ftLoop: - name = "Looping Function"; - break; - case ftFill: - name = "Function Fill"; - break; - case ftDrawText: - name = "Function DrawText"; - break; - case ftDrawTextBox: - name = "Function DrawTextBox"; - break; - case ftDrawTextVertical: - name = "Function DrawTextVertical"; - break; - case ftDrawImage: - name = "Function DrawImage"; - break; - case ftDrawRectangle: - name = "Function DrawRectangle"; - break; - case ftDrawEllipse: - name = "Function DrawEllipse"; - break; - case ftDrawSlope: - name = "Function DrawSlope"; - break; - case ftNone: - name = "Undefined"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -string cTemplateFunction::GetParamName(eParamType pt) { - string name; - switch (pt) { - case ptCond: - name = "Condition"; - break; - case ptName: - name = "Name"; - break; - case ptMode: - name = "Mode"; - break; - case ptX: - name = "X"; - break; - case ptY: - name = "Y"; - break; - case ptWidth: - name = "Width"; - break; - case ptHeight: - name = "Height"; - break; - case ptMenuItemWidth: - name = "Menu Item Width"; - break; - case ptDetached: - name = "Detached"; - break; - case ptFadeTime: - name = "Fade Time"; - break; - case ptShiftTime: - name = "Shift Time"; - break; - case ptShiftType: - name = "Shift Type"; - break; - case ptShiftMode: - name = "Shift Mode"; - break; - case ptStartX: - name = "Startpos X"; - break; - case ptStartY: - name = "Startpos Y"; - break; - case ptDelay: - name = "Delay"; - break; - case ptImageType: - name = "Image Type"; - break; - case ptPath: - name = "Image Path"; - break; - case ptColor: - name = "Color"; - break; - case ptFont: - name = "Font"; - break; - case ptFontSize: - name = "FontSize"; - break; - case ptText: - name = "Text"; - break; - case ptLayer: - name = "Layer"; - break; - case ptTransparency: - name = "Transparency"; - break; - case ptQuadrant: - name = "Quadrant"; - break; - case ptType: - name = "Type"; - break; - case ptAlign: - name = "Align"; - break; - case ptValign: - name = "Vertical Align"; - break; - case ptScrollMode: - name = "Scroll Mode"; - break; - case ptScrollSpeed: - name = "Scroll Speed"; - break; - case ptOrientation: - name = "Orientation"; - break; - case ptNumElements: - name = "NumElements"; - break; - case ptScrollElement: - name = "Scroll Element"; - break; - case ptScrollHeight: - name = "Scroll Height"; - break; - case ptFloat: - name = "Floating Type"; - break; - case ptFloatWidth: - name = "Floating Width"; - break; - case ptFloatHeight: - name = "Floating Height"; - break; - case ptMaxLines: - name = "Max num of lines"; - break; - case ptColumnWidth: - name = "Column Width"; - break; - case ptRowHeight: - name = "Row Height"; - break; - case ptOverflow: - name = "Overflow Mode"; - break; - case ptScaleTvX: - name = "Scale TV Picture X"; - break; - case ptScaleTvY: - name = "Scale TV Picture Y"; - break; - case ptScaleTvWidth: - name = "Scale TV Picture Width"; - break; - case ptScaleTvHeight: - name = "Scale TV Picture Height"; - break; - case ptHideRoot: - name = "Hide Root View"; - break; - case ptCache: - name = "Cache Image"; - break; - case ptDeterminateFont: - name = "Determinate Font"; - break; - case ptDirection: - name = "Text Direction"; - break; - case ptAnimType: - name = "Animation Type"; - break; - case ptAnimFreq: - name = "Animation Frequency"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -void cTemplateFunction::Debug(void) { - esyslog("skindesigner: Debugging %s, Container: x = %d, y = %d, Size: %dx%d", GetFuncName().c_str(), containerX, containerY, containerWidth, containerHeight); - esyslog("skindesigner: --- Native Parameters:"); - - if (condParam) { - condParam->Debug(); - } - esyslog("skindesigner: --- Native Parameters:"); - for (map::iterator it = nativeParameters.begin(); it != nativeParameters.end(); it++) { - esyslog("skindesigner: \"%s\" = \"%s\"", GetParamName(it->first).c_str(), (it->second).c_str()); - } - if (numericParameters.size() > 0) { - esyslog("skindesigner: --- Integer Parameters: "); - for (map::iterator it = numericParameters.begin(); it != numericParameters.end(); it++) { - esyslog("skindesigner: %s = %d", GetParamName(it->first).c_str(), it->second); - } - } - if (numericDynamicParameters.size() > 0) { - esyslog("skindesigner: --- Dynamic Integer Parameters: "); - for (map::iterator it = numericDynamicParameters.begin(); it != numericDynamicParameters.end(); it++) { - esyslog("skindesigner: %s = %s", GetParamName(it->first).c_str(), (it->second).c_str()); - } - } - if (colorParameters.size() > 0) { - esyslog("skindesigner: --- Color Parameters:"); - for (map::iterator it = colorParameters.begin(); it != colorParameters.end(); it++) { - esyslog("skindesigner: %s = %x", GetParamName(it->first).c_str(), it->second); - } - } - if (textTokens.size() > 0) { - esyslog("skindesigner: --- Text Tokens:"); - int i=0; - for (vector::iterator it = textTokens.begin(); it != textTokens.end(); it++) { - eTextTokenType tokenType = (*it).type; - string tokType = ""; - if (tokenType == ttConstString) - tokType = "Const"; - else if (tokenType == ttToken) - tokType = "Token"; - else if (tokenType == ttConditionalToken) - tokType = "Conditional Token"; - else if (tokenType == ttPrintfToken) - tokType = "PrintF Token"; - esyslog("skindesigner: Token %d Type %s : \"%s\"", i++, tokType.c_str(), (*it).value.c_str()); - if (tokenType == ttConditionalToken) { - for (vector::iterator it2 = (*it).subTokens.begin(); it2 != (*it).subTokens.end(); it2++) { - eTextTokenType tokenTypeCond = (*it2).type; - string tokTypeCond = ""; - if (tokenTypeCond == ttConstString) - tokTypeCond = "Const: "; - else if (tokenTypeCond == ttToken) - tokTypeCond = "Token: "; - esyslog("skindesigner: %s \"%s\"", tokTypeCond.c_str(), (*it2).value.c_str()); - } - } - if (tokenType == ttPrintfToken) { - for (vector::iterator it2 = (*it).parameters.begin(); it2 != (*it).parameters.end(); it2++) { - esyslog("skindesigner: PrintF parameter: %s", (*it2).c_str()); - } - } - } - } - if (fontName.size() > 0) { - esyslog("skindesigner: --- Font Name: \"%s\"", fontName.c_str()); - } - if (parsedText.size() > 0) { - esyslog("skindesigner: --- Parsed Text: \"%s\"", parsedText.c_str()); - } - if (type == ftDrawText) { - esyslog("skindesigner: --- Cutted Text: \"%s\"", cuttedText.c_str()); - esyslog("skindesigner: --- Parsed Text Width: %d", parsedTextWidth); - esyslog("skindesigner: --- Already Cutted: %s", alreadyCutted ? "true" : "false"); - } - if (imgPath.size() > 0) { - esyslog("skindesigner: --- Image Path: \"%s\"", imgPath.c_str()); - } -} diff --git a/libtemplate/templatefunction.h b/libtemplate/templatefunction.h deleted file mode 100644 index d800c5f..0000000 --- a/libtemplate/templatefunction.h +++ /dev/null @@ -1,270 +0,0 @@ -#ifndef __TEMPLATEFUNCTION_H -#define __TEMPLATEFUNCTION_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "globals.h" -#include "parameter.h" - -using namespace std; - -// --- cTemplateFunction ------------------------------------------------------------- - -enum eFuncType { - ftOsd, - ftView, - ftViewElement, - ftViewList, - ftPixmapContainer, - ftPixmap, - ftPixmapScroll, - ftLoop, - ftFill, - ftDrawText, - ftDrawTextBox, - ftDrawTextVertical, - ftDrawImage, - ftDrawRectangle, - ftDrawEllipse, - ftDrawSlope, - ftNone -}; - -enum eParamType { - ptCond, - ptName, - ptMode, - ptDrawDebugGrid, - ptDebugGridX, - ptDebugGridY, - ptX, - ptY, - ptWidth, - ptHeight, - ptMenuItemWidth, - ptDetached, - ptFadeTime, - ptShiftTime, - ptShiftType, - ptShiftMode, - ptStartX, - ptStartY, - ptDelay, - ptImageType, - ptPath, - ptColor, - ptFont, - ptFontSize, - ptText, - ptLayer, - ptTransparency, - ptBackground, - ptQuadrant, - ptType, - ptAlign, - ptValign, - ptScrollMode, - ptScrollSpeed, - ptOrientation, - ptNumElements, - ptScrollElement, - ptScrollHeight, - ptFloat, - ptFloatWidth, - ptFloatHeight, - ptMaxLines, - ptColumnWidth, - ptRowHeight, - ptOverflow, - ptScaleTvX, - ptScaleTvY, - ptScaleTvWidth, - ptScaleTvHeight, - ptHideRoot, - ptCache, - ptDeterminateFont, - ptDirection, - ptAnimType, - ptAnimFreq, - ptNone -}; - -enum eImageType { - itChannelLogo, - itSepLogo, - itSkinPart, - itMenuIcon, - itIcon, - itImage -}; - -enum eShiftType { - stNone, - stLeft, - stRight, - stTop, - stBottom -}; - -enum eShiftMode { - smLinear, - smSlowedDown -}; - -enum eAnimType { - atNone, - atBlink, - atAnimated -}; - -enum eFloatType { - flNone, - flTopLeft, - flTopRight -}; - -enum eOverflowType { - otNone, - otWrap, - otCut -}; - -enum eDirection { - diNone, - diBottomUp, - diTopDown -}; - -class cTemplateFunction { -protected: - eFuncType type; - bool debug; - int containerX; //X of parent container - int containerY; //Y of parent container - int containerWidth; //width of parent container - int containerHeight; //height of parent container - int columnWidth; //if func is executed in a loop, width of loop column - int rowHeight; //if func is executed in a loop, height of loop row - cGlobals *globals; //globals - map< eParamType, string > nativeParameters; //native parameters directly from xml - map< eParamType, int > numericParameters; //sucessfully parsed numeric parameters - map< eParamType, string > numericDynamicParameters; //numeric parameters with dynamic tokens - bool parsedCompletely; - bool updated; - map< eParamType, tColor > colorParameters; - cConditionalParameter *condParam; - //drawimage parameters - string imgPath; - //drawtext parameters - string fontName; - vector textTokens; - string parsedText; - int parsedTextWidth; - string cuttedText; - bool alreadyCutted; - //drawtextbox parameters - int textboxHeight; - //dynamic tokens - map < string, string > *stringTokens; - map < string, int > *intTokens; - //private functions - bool SetCondition(string cond); - bool SetNumericParameter(eParamType type, string value); - bool SetAlign(eParamType type, string value); - bool SetFont(eParamType type, string value); - bool SetImageType(eParamType type, string value); - bool SetColor(eParamType type, string value); - bool SetTextTokens(string value); - void ParseTextToken(string &value, size_t start, size_t end); - void ParseConditionalTextToken(string &value, size_t start, size_t end); - void ParsePrintfTextToken(string &value, size_t start, size_t end); - bool SetScrollMode(string value); - bool SetScrollSpeed(string value); - bool SetOrientation(string value); - bool SetFloating(string value); - bool SetOverflow(string value); - bool SetHideRoot(string value); - bool SetDetached(string value); - bool SetBackground(string value); - bool SetDirection(string value); - bool SetAnimType(string value); - bool SetShiftType(string value); - bool SetShiftMode(string value); - void SetDebugGrid(string value); - void ParseStringParameters(void); - void ParseNumericalParameters(void); - void CalculateAlign(int elementWidth, int elementHeight); - int CalculateTextBoxHeight(void); - int ReplaceIntToken(string intTok); -public: - cTemplateFunction(eFuncType type); - virtual ~cTemplateFunction(void); - //Setter Functions - void SetParameters(vector > params); - void SetParameter(eParamType type, string value); - void SetContainer(int x, int y, int w, int h); - void SetLoopContainer(int columnWidth, int rowHeight); - void SetWidthManually(string width); - void SetHeightManually(string height); - void SetXManually(int newX); - void SetYManually(int newY); - void SetMaxTextWidth(int maxWidth); - void SetTextboxHeight(int boxHeight); - void SetGlobals(cGlobals *globals) { this->globals = globals; }; - void SetTranslatedText(string translation); - //PreCache Parameters - bool CalculateParameters(void); - //Complete Parameters - bool ReCalculateParameters(void); - void CompleteParameters(void); - //Set and Unset Dynamic Tokens from view - void SetStringTokens(map < string, string > *tok) { stringTokens = tok; }; - void SetIntTokens(map < string, int > *tok) { intTokens = tok; }; - void UnsetIntTokens(void) { intTokens = NULL; }; - void UnsetStringTokens(void) { stringTokens = NULL; }; - //Clear dynamically parameters - void ClearDynamicParameters(void); - //Parse parameters with dynamically set Tokens - bool ParseParameters(void); - //Getter Functions - eFuncType GetType(void) { return type; }; - bool DoDebug(void) { return debug; }; - string GetParameter(eParamType type); - int GetNumericParameter(eParamType type); - string GetText(bool cut = true); - string GetImagePath(void) { return imgPath; }; - tColor GetColorParameter(eParamType type); - string GetFontName(void) { return fontName; }; - string GetFuncName(void); - string GetParamName(eParamType pt); - //Dynamic width or height parameter - int GetWidth(bool cutted = true); - int GetHeight(map < string, vector< map< string, string > > > *loopTokens = NULL); - int GetContainerWidth(void) { return containerWidth; }; - int GetContainerHeight(void) { return containerHeight; }; - void GetNeededWidths(multimap *widths); - void GetNeededHeights(multimap *heights); - void GetNeededPosX(multimap *posXs); - void GetNeededPosY(multimap *posYs); - void SetWidth(eParamType type, string label, int funcWidth); - void SetHeight(eParamType type, string label, int funcHeight); - void SetX(eParamType type, string label, int funcX); - void SetY(eParamType type, string label, int funcY); - //Status Functions - bool ParsedCompletely(void) { return parsedCompletely; }; - bool DoExecute(void); - bool Updated(void) { return updated; }; - bool IsAnimated(void); - //Debug - void Debug(void); -}; - -#endif //__TEMPLATEFUNCTION_H \ No newline at end of file diff --git a/libtemplate/templateloopfunction.c b/libtemplate/templateloopfunction.c deleted file mode 100644 index 07219ac..0000000 --- a/libtemplate/templateloopfunction.c +++ /dev/null @@ -1,248 +0,0 @@ -#include "templateloopfunction.h" -#include "../libcore/helpers.h" - -using namespace std; - -// --- cTemplateFunction ------------------------------------------------------------- - -cTemplateLoopFunction::cTemplateLoopFunction(void) : cTemplateFunction(ftLoop) { -} - -cTemplateLoopFunction::~cTemplateLoopFunction(void) { -} - -void cTemplateLoopFunction::InitIterator(void) { - funcIt = functions.begin(); -} - -void cTemplateLoopFunction::AddFunction(string name, vector > ¶ms) { - eFuncType type = ftNone; - - if (!name.compare("drawtext")) { - type = ftDrawText; - } else if (!name.compare("drawtextbox")) { - type = ftDrawTextBox; - } else if (!name.compare("drawimage")) { - type = ftDrawImage; - } else if (!name.compare("drawrectangle")) { - type = ftDrawRectangle; - } else if (!name.compare("drawellipse")) { - type = ftDrawEllipse; - } - - if (type == ftNone) { - return; - } - - cTemplateFunction *f = new cTemplateFunction(type); - f->SetParameters(params); - functions.push_back(f); -} - -void cTemplateLoopFunction::CalculateLoopFuncParameters(void) { - int columnWidth = GetNumericParameter(ptColumnWidth); - int rowHeight = GetNumericParameter(ptRowHeight); - for (vector::iterator func = functions.begin(); func != functions.end(); func++) { - (*func)->SetGlobals(globals); - (*func)->SetContainer(0, 0, containerWidth, containerHeight); - (*func)->SetLoopContainer(columnWidth, rowHeight); - (*func)->CalculateParameters(); - (*func)->CompleteParameters(); - } -} - -cTemplateFunction *cTemplateLoopFunction::GetNextFunction(void) { - if (funcIt == functions.end()) - return NULL; - cTemplateFunction *func = *funcIt; - funcIt++; - return func; -} - -void cTemplateLoopFunction::ClearDynamicParameters(void) { - InitIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - func->ClearDynamicParameters(); - } -} - -void cTemplateLoopFunction::ParseDynamicParameters(map *tokens) { - if (!tokens) - return; - InitIterator(); - cTemplateFunction *func = NULL; - - map intTokens; - for (map ::iterator it = tokens->begin(); it != tokens->end(); it++) { - if (isNumber(it->second)) - intTokens.insert(pair(it->first, atoi((it->second).c_str()))); - } - - bool completelyParsed = true; - while(func = GetNextFunction()) { - func->SetStringTokens(tokens); - func->SetIntTokens(&intTokens); - bool funcCompletelyParsed = func->ParseParameters(); - if (!funcCompletelyParsed) - completelyParsed = false; - if (func->Updated()) - func->CompleteParameters(); - func->UnsetStringTokens(); - func->UnsetIntTokens(); - } - if (completelyParsed) { - return; - } - - bool replacedWidth = ReplaceWidthFunctions(); - bool replacedHeight = ReplaceHeightFunctions(); - - if (!replacedWidth && !replacedHeight) - return; - - InitIterator(); - func = NULL; - while(func = GetNextFunction()) { - if (func->ParsedCompletely()) - continue; - func->SetStringTokens(tokens); - func->SetIntTokens(&intTokens); - func->ParseParameters(); - if (func->Updated()) - func->CompleteParameters(); - func->UnsetIntTokens(); - func->UnsetStringTokens(); - } -} - -int cTemplateLoopFunction::GetLoopElementsWidth(void) { - int cW = GetNumericParameter(ptColumnWidth); - if (cW > 0) { - return cW; - } - InitIterator(); - cTemplateFunction *func = NULL; - int maxWidth = 1; - while(func = GetNextFunction()) { - int funcWidth = func->GetWidth(true); - if (funcWidth > maxWidth) - maxWidth = funcWidth; - } - return maxWidth; -} - -int cTemplateLoopFunction::GetLoopElementsHeight(void) { - int rH = GetNumericParameter(ptRowHeight); - if (rH > 0) - return rH; - InitIterator(); - cTemplateFunction *func = NULL; - int maxHeight = 1; - while(func = GetNextFunction()) { - int funcY = func->GetNumericParameter(ptY); - int funcHeight = func->GetHeight(); - int totalHeight = funcY + funcHeight; - if (totalHeight > maxHeight) - maxHeight = totalHeight; - } - return maxHeight; -} - -int cTemplateLoopFunction::CalculateHeight(map < string, vector< map< string, string > > > *loopTokens) { - if (!loopTokens) { - return 0; - } - int rowHeight = GetLoopElementsHeight(); - string loopName = GetParameter(ptName); - map < string, vector< map< string, string > > >::iterator hit = loopTokens->find(loopName); - if (hit == loopTokens->end()) - return 0; - vector< map< string, string > > toks = hit->second; - int numElements = toks.size(); - - return numElements * rowHeight; -} - -bool cTemplateLoopFunction::ReplaceWidthFunctions(void) { - bool replaced = false; - InitIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - if (func->ParsedCompletely()) { - continue; - } - multimap widths; - func->GetNeededWidths(&widths); - for (map::iterator names = widths.begin(); names !=widths.end(); names++) { - eParamType type = names->first; - string label = names->second; - int funcWidth = 0; - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - cTemplateFunction *myFunc = *it; - string myFuncName = myFunc->GetParameter(ptName); - if (!myFuncName.compare(label)) { - funcWidth = myFunc->GetWidth(); - func->SetWidth(type, label, funcWidth); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - } - } - } - } - return replaced; -} - -bool cTemplateLoopFunction::ReplaceHeightFunctions(void) { - bool replaced = false; - InitIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - if (func->ParsedCompletely()) { - continue; - } - multimap heights; - func->GetNeededHeights(&heights); - for (map::iterator names = heights.begin(); names !=heights.end(); names++) { - eParamType type = names->first; - string label = names->second; - int funcHeight = 0; - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - cTemplateFunction *myFunc = *it; - string myFuncName = myFunc->GetParameter(ptName); - if (!myFuncName.compare(label)) { - funcHeight = myFunc->GetHeight(); - func->SetHeight(type, label, funcHeight); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - } - } - } - } - return replaced; -} - -bool cTemplateLoopFunction::Ready(void) { - bool isReady = true; - map< eParamType, string >::iterator hit = numericDynamicParameters.find(ptColumnWidth); - if (hit != numericDynamicParameters.end()) - isReady = false; - hit = numericDynamicParameters.find(ptRowHeight); - if (hit != numericDynamicParameters.end()) - isReady = false; - return isReady; -} - -void cTemplateLoopFunction::Debug(void) { - cTemplateFunction::Debug(); - esyslog("skindesigner: functions to be looped:"); - for (vector::iterator func = functions.begin(); func != functions.end(); func++) { - (*func)->Debug(); - } -} \ No newline at end of file diff --git a/libtemplate/templateloopfunction.h b/libtemplate/templateloopfunction.h deleted file mode 100644 index 1a28c65..0000000 --- a/libtemplate/templateloopfunction.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef __TEMPLATELOOPFUNCTION_H -#define __TEMPLATELOOPFUNCTION_H - -#include "templatefunction.h" - -using namespace std; - -// --- cTemplateLoopFunction ------------------------------------------------------------- - -class cTemplateLoopFunction : public cTemplateFunction { -private: - vector functions; - vector::iterator funcIt; - bool ReplaceWidthFunctions(void); - bool ReplaceHeightFunctions(void); -public: - cTemplateLoopFunction(void); - virtual ~cTemplateLoopFunction(void); - void AddFunction(string name, vector > ¶ms); - void CalculateLoopFuncParameters(void); - void InitIterator(void); - cTemplateFunction *GetNextFunction(void); - void ClearDynamicParameters(void); - void ParseDynamicParameters(map *tokens); - int GetLoopElementsWidth(void); - int GetLoopElementsHeight(void); - int GetContainerWidth(void) { return containerWidth; }; - int GetContainerHeight(void) { return containerHeight; }; - int CalculateHeight(map < string, vector< map< string, string > > > *loopTokens); - bool Ready(void); - void Debug(void); -}; - -#endif //__TEMPLATELOOPFUNCTION_H diff --git a/libtemplate/templatepixmap.c b/libtemplate/templatepixmap.c deleted file mode 100644 index 117ab25..0000000 --- a/libtemplate/templatepixmap.c +++ /dev/null @@ -1,739 +0,0 @@ -#include "templatepixmap.h" - -using namespace std; -// --- cTemplatePixmapNode ------------------------------------------------------------- - -cTemplatePixmapNode::cTemplatePixmapNode(void) { - parameters = NULL; - globals = NULL; - containerX = 0; - containerY = 0; - containerWidth = 0; - containerHeight = 0; -} - -cTemplatePixmapNode::~cTemplatePixmapNode() { - if (parameters) - delete parameters; -} - -void cTemplatePixmapNode::SetParameters(vector ¶ms) { - parameters = new cTemplateFunction(isContainer?ftPixmapContainer:ftPixmap); - parameters->SetGlobals(globals); - parameters->SetParameters(params); -} - -void cTemplatePixmapNode::SetContainer(int x, int y, int w, int h) { - containerX = x; - containerY = y; - containerWidth = w; - containerHeight = h; -} - -// --- cTemplatePixmap ------------------------------------------------------------- - -cTemplatePixmap::cTemplatePixmap(void) { - pixContainer = NULL; - isContainer = false; - scrolling = false; - background = false; -} - -cTemplatePixmap::~cTemplatePixmap() { - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - delete (*it); - } -} - -void cTemplatePixmap::SetWidth(int width) { - cString pWidth = cString::sprintf("%d", width); - parameters->SetWidthManually(*pWidth); -} - -void cTemplatePixmap::SetHeight(int height) { - cString pHeight = cString::sprintf("%d", height); - parameters->SetHeightManually(*pHeight); -} - -void cTemplatePixmap::SetX(int x) { - parameters->SetXManually(x); -} - -void cTemplatePixmap::SetY(int y) { - parameters->SetYManually(y); -} - -void cTemplatePixmap::SetWidthPercent(double width) { - int absWidth = containerWidth * width; - cString pWidth = cString::sprintf("%d", absWidth); - parameters->SetWidthManually(*pWidth); -} - -void cTemplatePixmap::SetHeightPercent(double height) { - int absHeight = containerHeight * height; - cString pHeight = cString::sprintf("%d", absHeight); - parameters->SetHeightManually(*pHeight); -} - -void cTemplatePixmap::SetXPercent(double x) { - int absX = containerX + containerWidth * x; - parameters->SetXManually(absX); -} - -void cTemplatePixmap::SetYPercent(double y) { - int absY = containerY + containerHeight * y; - parameters->SetYManually(absY); -} - -void cTemplatePixmap::SetParameter(eParamType type, string value) { - parameters->SetParameter(type, value); -} - - -void cTemplatePixmap::ClearDynamicParameters(void) { - parameters->ClearDynamicParameters(); -} - -void cTemplatePixmap::ParseDynamicParameters(map *stringTokens, map *intTokens, bool initFuncs) { - parameters->ClearDynamicParameters(); - parameters->SetIntTokens(intTokens); - parameters->SetStringTokens(stringTokens); - parameters->ParseParameters(); - parameters->UnsetIntTokens(); - parameters->UnsetStringTokens(); - - if (!DoExecute()) { - parameters->ClearDynamicParameters(); - return; - } - - if (!initFuncs || !Ready()) - return; - - int x = parameters->GetNumericParameter(ptX); - int y = parameters->GetNumericParameter(ptY); - int width = parameters->GetNumericParameter(ptWidth); - int height = parameters->GetNumericParameter(ptHeight); - - for (vector::iterator func = functions.begin(); func != functions.end(); func++) { - (*func)->SetContainer(x, y, width, height); - (*func)->ReCalculateParameters(); - (*func)->CompleteParameters(); - if ((*func)->GetType() == ftLoop) { - cTemplateLoopFunction *loopFunc = dynamic_cast(*func); - if (!loopFunc->Ready()) { - loopFunc->CalculateParameters(); - loopFunc->SetIntTokens(intTokens); - loopFunc->ParseParameters(); - loopFunc->UnsetIntTokens(); - } - loopFunc->CalculateLoopFuncParameters(); - } - } -} - -void cTemplatePixmap::AddFunction(string name, vector > ¶ms) { - eFuncType type = ftNone; - - if (!name.compare("fill")) { - type = ftFill; - } else if (!name.compare("drawtext")) { - type = ftDrawText; - } else if (!name.compare("drawtextbox")) { - type = ftDrawTextBox; - } else if (!name.compare("drawtextvertical")) { - type = ftDrawTextVertical; - } else if (!name.compare("drawimage")) { - type = ftDrawImage; - } else if (!name.compare("drawrectangle")) { - type = ftDrawRectangle; - } else if (!name.compare("drawellipse")) { - type = ftDrawEllipse; - } else if (!name.compare("drawslope")) { - type = ftDrawSlope; - } - - if (type == ftNone) { - return; - } - - cTemplateFunction *f = new cTemplateFunction(type); - f->SetParameters(params); - functions.push_back(f); -} - -void cTemplatePixmap::AddLoopFunction(cTemplateLoopFunction *lf) { - functions.push_back(lf); -} - - -bool cTemplatePixmap::CalculateParameters(void) { - bool paramsValid = true; - //Calculate Pixmap Size - parameters->SetContainer(containerX, containerY, containerWidth, containerHeight); - parameters->SetGlobals(globals); - paramsValid = parameters->CalculateParameters(); - - int pixWidth = parameters->GetNumericParameter(ptWidth); - int pixHeight = parameters->GetNumericParameter(ptHeight); - - for (vector::iterator func = functions.begin(); func != functions.end(); func++) { - (*func)->SetGlobals(globals); - (*func)->SetContainer(0, 0, pixWidth, pixHeight); - paramsValid = (*func)->CalculateParameters(); - (*func)->CompleteParameters(); - if ((*func)->GetType() == ftLoop) { - cTemplateLoopFunction *loopFunc = dynamic_cast(*func); - loopFunc->CalculateLoopFuncParameters(); - } - } - - background = parameters->GetNumericParameter(ptBackground); - - return paramsValid; -} - -void cTemplatePixmap::ClearDynamicFunctionParameters(void) { - InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - func->ClearDynamicParameters(); - } -} - -void cTemplatePixmap::ParseDynamicFunctionParameters(map *stringTokens, map *intTokens, map < string, vector< map< string, string > > > *loopTokens) { - InitFunctionIterator(); - cTemplateFunction *func = NULL; - bool completelyParsed = true; - while(func = GetNextFunction()) { - func->SetStringTokens(stringTokens); - func->SetIntTokens(intTokens); - bool funcCompletelyParsed = func->ParseParameters(); - if (!funcCompletelyParsed) - completelyParsed = false; - if (func->Updated()) - func->CompleteParameters(); - func->UnsetIntTokens(); - func->UnsetStringTokens(); - } - - if (completelyParsed) { - return; - } - - bool replacedWidth = ReplaceWidthFunctions(); - bool replacedHeight = ReplaceHeightFunctions(loopTokens); - bool replacedPosX = ReplacePosXFunctions(); - bool replacedPosY = ReplacePosYFunctions(); - - if (!replacedWidth && !replacedHeight && !replacedPosX && !replacedPosY) - return; - - InitFunctionIterator(); - func = NULL; - while(func = GetNextFunction()) { - if (func->ParsedCompletely()) - continue; - func->SetStringTokens(stringTokens); - func->SetIntTokens(intTokens); - func->ParseParameters(); - if (func->Updated()) - func->CompleteParameters(); - func->UnsetIntTokens(); - func->UnsetStringTokens(); - } -} - -bool cTemplatePixmap::CalculateDrawPortSize(cSize &size, map < string, vector< map< string, string > > > *loopTokens) { - int pixWidth = parameters->GetNumericParameter(ptWidth); - int pixHeight = parameters->GetNumericParameter(ptHeight); - int orientation = parameters->GetNumericParameter(ptOrientation); - if (orientation < 0) - orientation = orVertical; - if (orientation == orHorizontal) { - //get function which determinates drawport width - cTemplateFunction *scrollFunc = GetScrollFunction(); - if (!scrollFunc) - return false; - int drawportWidth = scrollFunc->GetWidth(false) + scrollFunc->GetNumericParameter(ptX) + 10; - if (drawportWidth > pixWidth) { - size.SetWidth(drawportWidth); - size.SetHeight(pixHeight); - return true; - } - } else if (orientation == orVertical) { - //check "last" element height - InitFunctionIterator(); - cTemplateFunction *f = NULL; - int drawportHeight = 1; - while (f = GetNextFunction()) { - if (f->GetType() == ftLoop) { - cTemplateLoopFunction *loopFunc = dynamic_cast(f); - //get number of loop tokens - string loopTokenName = loopFunc->GetParameter(ptName); - int numLoopTokens = 0; - map < string, vector< map< string, string > > >::iterator hit = loopTokens->find(loopTokenName); - if (hit != loopTokens->end()) { - vector< map > loopToken = hit->second; - numLoopTokens = loopToken.size(); - //parse first loop token element to get correct height - vector< map >::iterator firstLoopToken = loopToken.begin(); - loopFunc->ClearDynamicParameters(); - loopFunc->ParseDynamicParameters(&(*firstLoopToken)); - } - int orientation = loopFunc->GetNumericParameter(ptOrientation); - int yFunc = loopFunc->GetNumericParameter(ptY); - int heightFunc = loopFunc->GetLoopElementsHeight(); - if (loopTokens && orientation == orVertical) { - //height is height of loop elements times num loop elements - heightFunc = heightFunc * numLoopTokens; - } else if (loopTokens && orientation == orHorizontal) { - int overflow = loopFunc->GetNumericParameter(ptOverflow); - if (overflow == otCut) { - //do nothing, height is only height of one line - } else if (overflow == otWrap) { - int widthFunc = loopFunc->GetLoopElementsWidth(); - if (widthFunc <= 0) - continue; - int loopWidth = loopFunc->GetNumericParameter(ptWidth); - if (loopWidth <= 0) - loopWidth = loopFunc->GetContainerWidth(); - int elementsPerRow = loopWidth / widthFunc; - int rest = loopWidth % widthFunc; - if (rest > 0) - elementsPerRow++; - if (elementsPerRow <= 0) - continue; - int lines = numLoopTokens / elementsPerRow; - rest = numLoopTokens % elementsPerRow; - if (rest > 0) - lines++; - heightFunc = heightFunc * lines; - } - } - int neededHeight = heightFunc + yFunc; - if (neededHeight > drawportHeight) - drawportHeight = neededHeight; - } else { - int yFunc = f->GetNumericParameter(ptY); - int heightFunc = f->GetHeight(); - int neededHeight = heightFunc + yFunc; - if (neededHeight > drawportHeight) - drawportHeight = neededHeight; - } - } - if (drawportHeight > pixHeight) { - size.SetWidth(pixWidth); - size.SetHeight(drawportHeight); - return true; - } - } - size.SetWidth(0); - size.SetHeight(0); - return false; -} - -void cTemplatePixmap::SetScrollingTextWidth(void) { - int orientation = parameters->GetNumericParameter(ptOrientation); - if (orientation != orHorizontal) - return; - int pixWidth = parameters->GetNumericParameter(ptWidth); - InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - if (func->GetType() == ftDrawText) { - int offset = func->GetNumericParameter(ptX); - func->SetMaxTextWidth(pixWidth - offset); - } - } -} - - -cTemplateFunction *cTemplatePixmap::GetScrollFunction(void) { - string scrollElement = parameters->GetParameter(ptScrollElement); - if (scrollElement.size() == 0) - return NULL; - InitFunctionIterator(); - cTemplateFunction *f = NULL; - while (f = GetNextFunction()) { - string funcName = f->GetParameter(ptName); - if (!funcName.compare(scrollElement)) { - return f; - } - } - return NULL; -} - -cRect cTemplatePixmap::GetPixmapSize(void) { - cRect size; - size.SetX(GetNumericParameter(ptX)); - size.SetY(GetNumericParameter(ptY)); - size.SetWidth(GetNumericParameter(ptWidth)); - size.SetHeight(GetNumericParameter(ptHeight)); - return size; -} - -int cTemplatePixmap::GetNumericParameter(eParamType type) { - if (!parameters) - return -1; - return parameters->GetNumericParameter(type); -} - -void cTemplatePixmap::InitFunctionIterator(void) { - funcIt = functions.begin(); -} - -cTemplateFunction *cTemplatePixmap::GetNextFunction(void) { - if (funcIt == functions.end()) - return NULL; - cTemplateFunction *func = *funcIt; - funcIt++; - return func; -} - -bool cTemplatePixmap::Ready(void) { - int myX = parameters->GetNumericParameter(ptX); - if (myX < 0) - return false; - int myY = parameters->GetNumericParameter(ptY); - if (myY < 0) - return false; - int myWidth = parameters->GetNumericParameter(ptWidth); - if (myWidth < 1) - return false; - int myHeight = parameters->GetNumericParameter(ptHeight); - if (myHeight < 1) - return false; - return true; -} - -bool cTemplatePixmap::ParameterSet(eParamType type) { - string value = parameters->GetParameter(type); - if (value.size() > 0) - return true; - return false; -} - -cTemplateFunction *cTemplatePixmap::GetFunction(string name) { - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - string funcName = (*it)->GetParameter(ptName); - if (!name.compare(funcName)) - return *it; - } - return NULL; -} - -bool cTemplatePixmap::ReplaceWidthFunctions(void) { - bool replaced = false; - bool found = false; - InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - if (func->ParsedCompletely()) { - continue; - } - multimap widths; - func->GetNeededWidths(&widths); - for (map::iterator names = widths.begin(); names !=widths.end(); names++) { - eParamType type = names->first; - string label = names->second; - int funcWidth = 0; - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - cTemplateFunction *myFunc = *it; - string myFuncName = myFunc->GetParameter(ptName); - if (!myFuncName.compare(label)) { - found = true; - funcWidth = myFunc->GetWidth(); - func->SetWidth(type, label, funcWidth); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - break; - } - } - if (!found && pixContainer) { - cTemplateFunction *myFunc = pixContainer->GetFunction(label); - if (myFunc) { - funcWidth = myFunc->GetWidth(); - func->SetWidth(type, label, funcWidth); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - break; - } - } - } - } - return replaced; -} - -bool cTemplatePixmap::ReplaceHeightFunctions(map < string, vector< map< string, string > > > *loopTokens) { - bool replaced = false; - bool found = false; - InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - if (func->ParsedCompletely()) { - continue; - } - multimap heights; - func->GetNeededHeights(&heights); - for (map::iterator names = heights.begin(); names !=heights.end(); names++) { - eParamType type = names->first; - string label = names->second; - int funcHeight = 0; - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - cTemplateFunction *myFunc = *it; - string myFuncName = myFunc->GetParameter(ptName); - if (!myFuncName.compare(label)) { - found = true; - funcHeight = myFunc->GetHeight(loopTokens); - func->SetHeight(type, label, funcHeight); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - break; - } - } - if (!found && pixContainer) { - cTemplateFunction *myFunc = pixContainer->GetFunction(label); - if (myFunc) { - funcHeight = myFunc->GetHeight(loopTokens); - func->SetHeight(type, label, funcHeight); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - break; - } - } - } - } - return replaced; -} - -bool cTemplatePixmap::ReplacePosXFunctions(void) { - bool replaced = false; - bool found = false; - InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - if (func->ParsedCompletely()) { - continue; - } - multimap posXs; - func->GetNeededPosX(&posXs); - for (map::iterator names = posXs.begin(); names !=posXs.end(); names++) { - eParamType type = names->first; - string label = names->second; - int funcX = 0; - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - cTemplateFunction *myFunc = *it; - string myFuncName = myFunc->GetParameter(ptName); - if (!myFuncName.compare(label)) { - found = true; - funcX = myFunc->GetNumericParameter(ptX); - if (funcX > -1) { - func->SetX(type, label, funcX); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - } - break; - } - } - if (!found && pixContainer) { - cTemplateFunction *myFunc = pixContainer->GetFunction(label); - if (myFunc) { - funcX = myFunc->GetNumericParameter(ptX); - if (funcX > -1) { - func->SetX(type, label, funcX); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - } - break; - } - } - } - } - return replaced; -} - -bool cTemplatePixmap::ReplacePosYFunctions(void) { - bool replaced = false; - bool found = false; - InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = GetNextFunction()) { - if (func->ParsedCompletely()) { - continue; - } - multimap posYs; - func->GetNeededPosY(&posYs); - for (map::iterator names = posYs.begin(); names !=posYs.end(); names++) { - eParamType type = names->first; - string label = names->second; - int funcY = 0; - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - cTemplateFunction *myFunc = *it; - string myFuncName = myFunc->GetParameter(ptName); - if (!myFuncName.compare(label)) { - found = true; - funcY = myFunc->GetNumericParameter(ptY); - if (funcY > -1) { - func->SetY(type, label, funcY); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - } - break; - } - } - if (!found && pixContainer) { - cTemplateFunction *myFunc = pixContainer->GetFunction(label); - if (myFunc) { - funcY = myFunc->GetNumericParameter(ptY); - if (funcY > -1) { - func->SetY(type, label, funcY); - if (func->Updated()) { - func->CompleteParameters(); - } else { - replaced = true; - } - } - break; - } - } - } - } - return replaced; -} - -void cTemplatePixmap::Debug(void) { - esyslog("skindesigner: pixmap container size x: %d, y: %d, width: %d, height %d", containerX, containerY, containerWidth, containerHeight); - parameters->Debug(); - for (vector::iterator it = functions.begin(); it != functions.end(); it++) { - (*it)->Debug(); - } -} - -// --- cTemplatePixmapContainer ------------------------------------------------------------- - -cTemplatePixmapContainer::cTemplatePixmapContainer(void) { - isContainer = true; -} - -cTemplatePixmapContainer::~cTemplatePixmapContainer() { - for (vector::iterator it = pixmaps.begin(); it != pixmaps.end(); it++) { - delete (*it); - } -} - -void cTemplatePixmapContainer::SetGlobals(cGlobals *globals) { - this->globals = globals; - for (vector::iterator it = pixmaps.begin(); it != pixmaps.end(); it++) { - (*it)->SetGlobals(globals); - } -} - -void cTemplatePixmapContainer::SetWidth(int width) { - for (vector::iterator it = pixmaps.begin(); it != pixmaps.end(); it++) { - (*it)->SetWidth(width); - } -} - -void cTemplatePixmapContainer::SetHeight(int height) { - for (vector::iterator it = pixmaps.begin(); it != pixmaps.end(); it++) { - (*it)->SetHeight(height); - } -} - -void cTemplatePixmapContainer::AddPixmap(cTemplatePixmap *pix) { - //setting default parameters of container if parameter is not set in area - string containerDefaultX = parameters->GetParameter(ptX); - string containerDefaultY = parameters->GetParameter(ptY); - string containerDefaultWidth = parameters->GetParameter(ptWidth); - string containerDefaultHeight = parameters->GetParameter(ptHeight); - if (containerDefaultX.size() > 0 && !pix->ParameterSet(ptX)) - pix->SetParameter(ptX, containerDefaultX); - if (containerDefaultY.size() > 0 && !pix->ParameterSet(ptY)) - pix->SetParameter(ptY, containerDefaultY); - if (containerDefaultWidth.size() > 0 && !pix->ParameterSet(ptWidth)) - pix->SetParameter(ptWidth, containerDefaultWidth); - if (containerDefaultHeight.size() > 0 && !pix->ParameterSet(ptHeight)) - pix->SetParameter(ptHeight, containerDefaultHeight); - - pix->SetPixmapContainer(this); - pixmaps.push_back(pix); -} - -bool cTemplatePixmapContainer::CalculateParameters(void) { - bool paramsValid = true; - //Calculate Pixmap Size - parameters->SetContainer(containerX, containerY, containerWidth, containerHeight); - parameters->SetGlobals(globals); - paramsValid = parameters->CalculateParameters(); - - for (vector::iterator it = pixmaps.begin(); it != pixmaps.end(); it++) { - (*it)->SetContainer(containerX, containerY, containerWidth, containerHeight); - (*it)->SetGlobals(globals); - paramsValid = (*it)->CalculateParameters() && paramsValid; - } - - return paramsValid; -} - -void cTemplatePixmapContainer::ParseDynamicParameters(map *stringTokens, map *intTokens) { - parameters->ClearDynamicParameters(); - parameters->SetIntTokens(intTokens); - parameters->SetStringTokens(stringTokens); - parameters->ParseParameters(); - parameters->UnsetIntTokens(); - parameters->UnsetStringTokens(); -} - -void cTemplatePixmapContainer::InitIterator(void) { - pixmapIterator = pixmaps.begin(); -} - -cTemplatePixmap *cTemplatePixmapContainer::GetNextPixmap(void) { - if (pixmapIterator == pixmaps.end()) - return NULL; - cTemplatePixmap *pix = *pixmapIterator; - pixmapIterator++; - return pix; -} - -cTemplateFunction *cTemplatePixmapContainer::GetFunction(string name) { - cTemplateFunction *hit = NULL; - for (vector::iterator it = pixmaps.begin(); it != pixmaps.end(); it++) { - hit = (*it)->GetFunction(name); - if (hit) - return hit; - } - return NULL; -} - - -void cTemplatePixmapContainer::Debug(void) { - esyslog("skindesigner: pixmapcontainer"); - parameters->Debug(); - for (vector::iterator it = pixmaps.begin(); it != pixmaps.end(); it++) { - (*it)->Debug(); - } -} - diff --git a/libtemplate/templatepixmap.h b/libtemplate/templatepixmap.h deleted file mode 100644 index f9c2f6f..0000000 --- a/libtemplate/templatepixmap.h +++ /dev/null @@ -1,132 +0,0 @@ -#ifndef __TEMPLATEPIXMAP_H -#define __TEMPLATEPIXMAP_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "globals.h" -#include "templateloopfunction.h" -#include "../views/viewhelpers.h" - -using namespace std; - -// --- cTemplatePixmapNode ------------------------------------------------------------- -class cTemplatePixmapNode { -protected: - bool isContainer; - cGlobals *globals; - cTemplateFunction *parameters; - int containerX; - int containerY; - int containerWidth; - int containerHeight; -public: - cTemplatePixmapNode(void); - virtual ~cTemplatePixmapNode(void); - void SetParameters(vector ¶ms); - void SetContainer(int x, int y, int w, int h); - bool IsContainer(void) { return isContainer; }; - bool DoExecute(void) { return parameters->DoExecute(); }; - bool DoDebug(void) { return parameters->DoDebug(); }; - virtual void SetGlobals(cGlobals *globals) { this->globals = globals; }; - virtual bool CalculateParameters(void) { return false; }; - virtual void SetWidth(int width) {}; - virtual void SetHeight(int height) {}; - virtual int NumPixmaps(void) { return 0; }; - virtual void Debug(void) {}; -}; - -// --- cTemplatePixmap ------------------------------------------------------------- -class cTemplatePixmapContainer; - -class cTemplatePixmap : public cTemplatePixmapNode { -protected: - cTemplatePixmapContainer *pixContainer; - bool scrolling; - bool background; - vector functions; - vector::iterator funcIt; - //functions replacing {width(label)} and {height(label)} tokens - bool ReplaceWidthFunctions(void); - bool ReplaceHeightFunctions(map < string, vector< map< string, string > > > *loopTokens); - //functions replacing {posx(label)} and {posy(label)} tokens - bool ReplacePosXFunctions(void); - bool ReplacePosYFunctions(void); - //Get Scrolling Function - cTemplateFunction *GetScrollFunction(void); -public: - cTemplatePixmap(void); - virtual ~cTemplatePixmap(void); - //Setter Functions - void SetPixmapContainer(cTemplatePixmapContainer *pixContainer) { this->pixContainer = pixContainer; }; - void SetScrolling(void) { scrolling = true; }; - void SetWidth(int width); - void SetHeight(int height); - void SetX(int x); - void SetY(int y); - void SetWidthPercent(double width); - void SetHeightPercent(double height); - void SetXPercent(double x); - void SetYPercent(double y); - void SetParameter(eParamType type, string value); - void AddFunction(string name, vector > ¶ms); - void AddLoopFunction(cTemplateLoopFunction *lf); - //PreCache Parameters - bool CalculateParameters(void); - //clear dynamically set function parameters - void ClearDynamicFunctionParameters(void); - //Clear dynamically set pixmap parameters - void ClearDynamicParameters(void); - //Parse pixmap parameters with dynamically set Tokens - void ParseDynamicParameters(map *stringTokens, map *intTokens, bool initFuncs); - //Parse all function parameters with dynamically set Tokens - void ParseDynamicFunctionParameters(map *stringTokens, map *intTokens, map < string, vector< map< string, string > > > *loopTokens); - //Calculate size of drawport in case area scrolls - bool CalculateDrawPortSize(cSize &size, map < string, vector< map< string, string > > > *loopTokens = NULL); - //Set max width for text in scrollarea - void SetScrollingTextWidth(void); - //Getter Functions - int NumPixmaps(void) { return 1; }; - cRect GetPixmapSize(void); - int GetNumericParameter(eParamType type); - bool Scrolling(void) { return scrolling; }; - bool Ready(void); - bool BackgroundArea(void) { return background; }; - bool ParameterSet(eParamType type); - cTemplateFunction *GetFunction(string name); - //Traverse Functions - void InitFunctionIterator(void); - cTemplateFunction *GetNextFunction(void); - //Debug - void Debug(void); -}; - -class cTemplatePixmapContainer : public cTemplatePixmapNode { -private: - vector pixmaps; - vector::iterator pixmapIterator; -public: - cTemplatePixmapContainer(void); - virtual ~cTemplatePixmapContainer(void); - void SetGlobals(cGlobals *globals); - void SetWidth(int width); - void SetHeight(int height); - void AddPixmap(cTemplatePixmap *pix); - //PreCache Parameters - bool CalculateParameters(void); - void ParseDynamicParameters(map *stringTokens, map *intTokens); - int NumPixmaps(void) { return pixmaps.size(); }; - void InitIterator(void); - cTemplatePixmap *GetNextPixmap(void); - cTemplateFunction *GetFunction(string name); - void Debug(void); -}; - -#endif //__TEMPLATEPIXMAP_H \ No newline at end of file diff --git a/libtemplate/templateview.c b/libtemplate/templateview.c deleted file mode 100644 index 78d6fdf..0000000 --- a/libtemplate/templateview.c +++ /dev/null @@ -1,2148 +0,0 @@ -#include "../config.h" -#include "templateview.h" - -// --- cTemplateView ------------------------------------------------------------- - -cTemplateView::cTemplateView(void) { - globals = NULL; - parameters = NULL; - containerX = 0; - containerY = 0; - containerWidth = 0; - containerHeight = 0; - SetFunctionDefinitions(); -} - -cTemplateView::~cTemplateView() { - for (multimap < eViewElement, cTemplateViewElement* >::iterator it = viewElements.begin(); it != viewElements.end(); it++) { - delete it->second; - } - - for (multimap < eViewList, cTemplateViewList* >::iterator it = viewLists.begin(); it != viewLists.end(); it++) { - delete it->second; - } - - for (map < int, cTemplateViewGrid* >::iterator it = viewGrids.begin(); it != viewGrids.end(); it++) { - delete it->second; - } - - for (vector < cTemplateViewTab* >::iterator it = viewTabs.begin(); it != viewTabs.end(); it++) { - delete *it; - } - - for (map < eSubView, cTemplateView* >::iterator it = subViews.begin(); it != subViews.end(); it++) { - delete it->second; - } - - for (map < string, map< int, cTemplateView*> >::iterator it = pluginViews.begin(); it != pluginViews.end(); it++) { - map< int, cTemplateView*> plugViews = it->second; - for (map< int, cTemplateView*>::iterator it2 = plugViews.begin(); it2 != plugViews.end(); it2++) { - delete it2->second; - } - } - - if (parameters) - delete parameters; - -} - -/******************************************************************* -* Public Functions -*******************************************************************/ - -void cTemplateView::SetParameters(vector > ¶ms) { - parameters = new cTemplateFunction(ftView); - parameters->SetGlobals(globals); - parameters->SetParameters(params); -} - -void cTemplateView::SetContainer(int x, int y, int width, int height) { - containerX = x; - containerY = y; - containerWidth = width; - containerHeight = height; -} - -cTemplateViewElement *cTemplateView::GetViewElement(eViewElement ve) { - pair::iterator, multimap< eViewElement, cTemplateViewElement* >::iterator> rangeViewElements; - rangeViewElements = viewElements.equal_range(ve); - for (multimap::iterator it = rangeViewElements.first; it!=rangeViewElements.second; ++it) { - cTemplateViewElement *viewElement = it->second; - if (viewElement->Execute()) { - return viewElement; - } - } - return NULL; -} - -void cTemplateView::InitViewElementIterator(void) { - veIt = viewElements.begin(); -} - -cTemplateViewElement *cTemplateView::GetNextViewElement(void) { - if (veIt == viewElements.end()) - return NULL; - cTemplateViewElement *viewElement = veIt->second; - veIt++; - return viewElement; -} - -cTemplateViewGrid *cTemplateView::GetViewGrid(int gridID) { - map < int, cTemplateViewGrid* >::iterator hit = viewGrids.find(gridID); - if (hit == viewGrids.end()) { - return NULL; - } - return hit->second; -} - -void cTemplateView::InitViewGridIterator(void) { - geIt = viewGrids.begin(); -} - -cTemplateViewGrid *cTemplateView::GetNextViewGrid(void) { - if (geIt == viewGrids.end()) - return NULL; - cTemplateViewGrid *viewGrid = geIt->second; - geIt++; - return viewGrid; -} - -cTemplateViewList *cTemplateView::GetViewList(eViewList vl) { - if (viewLists.size() == 1) { - multimap < eViewList, cTemplateViewList* >::iterator hit = viewLists.find(vl); - if (hit == viewLists.end()) - return NULL; - return hit->second; - } - pair::iterator, multimap< eViewList, cTemplateViewList* >::iterator> rangeViewLists; - rangeViewLists = viewLists.equal_range(vl); - for (multimap::iterator it = rangeViewLists.first; it!=rangeViewLists.second; ++it) { - cTemplateViewList *viewList = it->second; - if (viewList->Execute()) { - return viewList; - } - } - return NULL; -} - -void cTemplateView::InitViewListIterator(void) { - vlIt = viewLists.begin(); -} - -cTemplateViewList *cTemplateView::GetNextViewList(void) { - if (vlIt == viewLists.end()) - return NULL; - cTemplateViewList *viewList = vlIt->second; - vlIt++; - return viewList; -} - -cTemplateView *cTemplateView::GetSubView(eSubView sv) { - map < eSubView, cTemplateView* >::iterator hit = subViews.find(sv); - if (hit == subViews.end()) - return NULL; - return hit->second; -} - -cTemplateView *cTemplateView::GetPluginView(string pluginName, int pluginMenu) { - map < string, map< int, cTemplateView*> >::iterator hit = pluginViews.find(pluginName); - - if (hit == pluginViews.end()) - return NULL; - - map< int, cTemplateView*> plugViews = hit->second; - map< int, cTemplateView*>::iterator hit2 = plugViews.find(pluginMenu); - - if (hit2 == plugViews.end()) - return NULL; - - return hit2->second; -} - - -void cTemplateView::InitViewTabIterator(void) { - vtIt = viewTabs.begin(); -} - -cTemplateViewTab *cTemplateView::GetNextViewTab(void) { - if (vtIt == viewTabs.end()) { - return NULL; - } - cTemplateViewTab *tab = *vtIt; - vtIt++; - return tab; -} - -void cTemplateView::InitSubViewIterator(void) { - svIt = subViews.begin(); -} - -cTemplateView *cTemplateView::GetNextSubView(void) { - if (svIt == subViews.end()) - return NULL; - cTemplateView *subView = svIt->second; - svIt++; - return subView; -} - -int cTemplateView::GetNumericParameter(eParamType type) { - if (!parameters) - return 0; - return parameters->GetNumericParameter(type); -} - -cRect cTemplateView::GetOsdSize(void) { - cRect osdSize; - if (!parameters) { - return osdSize; - } - osdSize.SetX(parameters->GetNumericParameter(ptX)); - osdSize.SetY(parameters->GetNumericParameter(ptY)); - osdSize.SetWidth(parameters->GetNumericParameter(ptWidth)); - osdSize.SetHeight(parameters->GetNumericParameter(ptHeight)); - return osdSize; -} - -int cTemplateView::GetNumPixmaps(void) { - int numPixmaps = 0; - for (multimap < eViewElement, cTemplateViewElement* >::iterator it = viewElements.begin(); it != viewElements.end(); it++) { - cTemplateViewElement *viewElement = it->second; - numPixmaps += viewElement->GetNumPixmaps(); - } - return numPixmaps; -} - -int cTemplateView::GetNumPixmapsViewElement(eViewElement ve) { - cTemplateViewElement *viewElement = GetViewElement(ve); - if (!viewElement) - return 0; - return viewElement->GetNumPixmaps(); -} - -bool cTemplateView::HideView(void) { - if (!parameters) - return false; - return parameters->GetNumericParameter(ptHideRoot); -} - -bool cTemplateView::DrawGebugGrid(void) { - if (!parameters) - return false; - return parameters->GetNumericParameter(ptDrawDebugGrid); -} - -int cTemplateView::DebugGridX(void) { - if (!parameters) - return 0; - return parameters->GetNumericParameter(ptDebugGridX); -} - -int cTemplateView::DebugGridY(void) { - if (!parameters) - return 0; - return parameters->GetNumericParameter(ptDebugGridY); -} - -tColor cTemplateView::DebugGridColor(void) { - tColor col = 0xFFFF0000; - if (!globals) - return col; - string colName = "{clrDebugGrid}"; - globals->GetColor(colName, col); - return col; -} - -tColor cTemplateView::DebugGridFontColor(void) { - tColor col = 0xFFFF0000; - if (!globals) - return col; - string colName = "{clrFontDebugGrid}"; - globals->GetColor(colName, col); - return col; -} - -bool cTemplateView::ExecuteView(eViewElement ve) { - cTemplateViewElement *viewElement = GetViewElement(ve); - if (!viewElement) - return false; - return true; -} - -bool cTemplateView::DetachViewElement(eViewElement ve) { - multimap < eViewElement, cTemplateViewElement* >::iterator hit = viewElements.find(ve); - if (hit == viewElements.end()) - return false; - cTemplateViewElement *viewElement = hit->second; - return viewElement->Detach(); -} - -string cTemplateView::GetViewElementMode(eViewElement ve) { - cTemplateViewElement *viewElement = GetViewElement(ve); - if (!viewElement) - return ""; - return viewElement->GetMode(); -} - -int cTemplateView::GetNumListViewMenuItems(void) { - int numElements = 0; - cTemplateViewList *menuList = GetViewList(vlMenuItem); - if (!menuList) - return numElements; - return menuList->GetNumericParameter(ptNumElements); -} - -bool cTemplateView::GetScalingWindow(cRect &scalingWindow) { - if (!parameters) - return false; - bool doScale = false; - int scaleX = parameters->GetNumericParameter(ptScaleTvX) + cOsd::OsdLeft(); - int scaleY = parameters->GetNumericParameter(ptScaleTvY) + cOsd::OsdTop(); - int scaleWidth = parameters->GetNumericParameter(ptScaleTvWidth); - int scaleHeight = parameters->GetNumericParameter(ptScaleTvHeight); - if (scaleX > -1 && scaleY > -1 && scaleWidth > -1 && scaleHeight > -1) { - cRect suggestedScaleWindow(scaleX, scaleY, scaleWidth, scaleHeight); - scalingWindow = cDevice::PrimaryDevice()->CanScaleVideo(suggestedScaleWindow); - doScale = true; - } else { - scalingWindow = cDevice::PrimaryDevice()->CanScaleVideo(cRect::Null); - } - return doScale; -} - -bool cTemplateView::ValidViewElement(const char *viewElement) { - set::iterator hit = viewElementsAllowed.find(viewElement); - if (hit == viewElementsAllowed.end()) - return false; - return true; -} - -bool cTemplateView::ValidSubView(const char *subView) { - set::iterator hit = subViewsAllowed.find(subView); - if (hit == subViewsAllowed.end()) - return false; - return true; -} - -bool cTemplateView::ValidViewList(const char *viewList) { - set::iterator hit = viewListsAllowed.find(viewList); - if (hit == viewListsAllowed.end()) - return false; - return true; -} - -bool cTemplateView::ValidViewGrid(const char *viewGrid) { - set::iterator hit = viewGridsAllowed.find(viewGrid); - if (hit == viewGridsAllowed.end()) - return false; - return true; -} - -bool cTemplateView::ValidFunction(const char *func) { - map < string, set < string > >::iterator hit = funcsAllowed.find(func); - if (hit == funcsAllowed.end()) - return false; - return true; -} - -bool cTemplateView::ValidAttribute(const char *func, const char *att) { - map < string, set < string > >::iterator hit = funcsAllowed.find(func); - if (hit == funcsAllowed.end()) - return false; - - set::iterator hitAtt = (hit->second).find(att); - if (hitAtt == (hit->second).end()) - return false; - - return true; -} - -void cTemplateView::Translate(void) { - //Translate ViewElements - InitViewElementIterator(); - cTemplateViewElement *viewElement = NULL; - while(viewElement = GetNextViewElement()) { - viewElement->InitPixmapIterator(); - cTemplatePixmap *pix = NULL; - while(pix = viewElement->GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = func->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - func->SetTranslatedText(translation); - } - } - if (func->GetType() == ftLoop) { - cTemplateLoopFunction *funcsLoop = dynamic_cast(func); - funcsLoop->InitIterator(); - cTemplateFunction *loopFunc = NULL; - while(loopFunc = funcsLoop->GetNextFunction()) { - if (loopFunc->GetType() == ftDrawText || loopFunc->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = loopFunc->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - loopFunc->SetTranslatedText(translation); - } - } - } - } - } - } - } - //Translate viewLists - InitViewListIterator(); - cTemplateViewList *viewList = NULL; - while(viewList = GetNextViewList()) { - viewList->InitPixmapIterator(); - cTemplatePixmap *pix = NULL; - while(pix = viewList->GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = func->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - func->SetTranslatedText(translation); - } - } - } - } - cTemplateViewElement *listElement = viewList->GetListElement(); - listElement->InitPixmapIterator(); - while(pix = listElement->GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = func->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - func->SetTranslatedText(translation); - } - } - } - } - - cTemplateViewElement *listElementCurrent = viewList->GetListElementCurrent(); - if (listElementCurrent) { - listElementCurrent->InitPixmapIterator(); - while(pix = listElementCurrent->GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = func->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - func->SetTranslatedText(translation); - } - } - if (func->GetType() == ftLoop) { - cTemplateLoopFunction *funcsLoop = dynamic_cast(func); - funcsLoop->InitIterator(); - cTemplateFunction *loopFunc = NULL; - while(loopFunc = funcsLoop->GetNextFunction()) { - if (loopFunc->GetType() == ftDrawText || loopFunc->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = loopFunc->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - loopFunc->SetTranslatedText(translation); - } - } - } - } - } - } - } - } - - //Translate viewTabs - InitViewTabIterator(); - cTemplateViewTab *viewTab = NULL; - while(viewTab = GetNextViewTab()) { - string tabName = viewTab->GetName(); - string tabTrans; - bool translated = globals->Translate(tabName, tabTrans); - if (translated) { - viewTab->SetName(tabTrans); - } - viewTab->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = viewTab->GetNextFunction()) { - if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = func->GetParameter(ptText); - string translation; - translated = globals->Translate(text, translation); - if (translated) { - func->SetTranslatedText(translation); - } - } - if (func->GetType() == ftLoop) { - cTemplateLoopFunction *funcsLoop = dynamic_cast(func); - funcsLoop->InitIterator(); - cTemplateFunction *loopFunc = NULL; - while(loopFunc = funcsLoop->GetNextFunction()) { - if (loopFunc->GetType() == ftDrawText || loopFunc->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = loopFunc->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - loopFunc->SetTranslatedText(translation); - } - } - } - } - } - } - - //Translate ViewGrids - InitViewGridIterator(); - cTemplateViewGrid *viewGrid = NULL; - while(viewGrid = GetNextViewGrid()) { - viewGrid->InitPixmapIterator(); - cTemplatePixmap *pix = NULL; - while(pix = viewGrid->GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText || func->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = func->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - func->SetTranslatedText(translation); - } - } - if (func->GetType() == ftLoop) { - cTemplateLoopFunction *funcsLoop = dynamic_cast(func); - funcsLoop->InitIterator(); - cTemplateFunction *loopFunc = NULL; - while(loopFunc = funcsLoop->GetNextFunction()) { - if (loopFunc->GetType() == ftDrawText || loopFunc->GetType() == ftDrawTextBox || func->GetType() == ftDrawTextVertical) { - string text = loopFunc->GetParameter(ptText); - string translation; - bool translated = globals->Translate(text, translation); - if (translated) { - loopFunc->SetTranslatedText(translation); - } - } - } - } - } - } - } - - //Translate Plugin Views - for (map < string, map< int, cTemplateView*> >::iterator it = pluginViews.begin(); it != pluginViews.end(); it++) { - map< int, cTemplateView*> plugViews = it->second; - for (map< int, cTemplateView*>::iterator it2 = plugViews.begin(); it2 != plugViews.end(); it2++) { - cTemplateView *pluginView = it2->second; - pluginView->Translate(); - } - } - - //Translate Subviews - InitSubViewIterator(); - cTemplateView *subView = NULL; - while(subView = GetNextSubView()) { - subView->Translate(); - } -} - -void cTemplateView::PreCache(bool isSubview) { - - if (!isSubview) { - int osdW = cOsd::OsdWidth(); - int osdH = cOsd::OsdHeight(); - parameters->SetContainer(0, 0, osdW, osdH); - } else { - parameters->SetContainer(containerX, containerY, containerWidth, containerHeight); - } - //Calculate OSD Size - parameters->CalculateParameters(); - - int osdX = parameters->GetNumericParameter(ptX); - int osdY = parameters->GetNumericParameter(ptY); - int osdWidth = parameters->GetNumericParameter(ptWidth); - int osdHeight = parameters->GetNumericParameter(ptHeight); - int pixOffset = 0; - //Cache ViewElements - for (multimap < eViewElement, cTemplateViewElement* >::iterator it = viewElements.begin(); it != viewElements.end(); it++) { - cTemplateViewElement *viewElement = it->second; - viewElement->SetGlobals(globals); - if (!isSubview) - viewElement->SetContainer(0, 0, osdWidth, osdHeight); - else - viewElement->SetContainer(osdX, osdY, osdWidth, osdHeight); - viewElement->CalculateParameters(); - viewElement->CalculatePixmapParameters(); - viewElement->SetPixOffset(pixOffset); - pixOffset += viewElement->GetNumPixmaps(); - } - - //Cache ViewGrids - for (map < int, cTemplateViewGrid* >::iterator it = viewGrids.begin(); it != viewGrids.end(); it++) { - cTemplateViewGrid *viewGrid = it->second; - viewGrid->SetGlobals(globals); - viewGrid->SetContainer(0, 0, osdWidth, osdHeight); - viewGrid->CalculateParameters(); - viewGrid->CalculatePixmapParameters(); - } - - //Cache ViewLists - for (multimap < eViewList, cTemplateViewList* >::iterator it = viewLists.begin(); it != viewLists.end(); it++) { - cTemplateViewList *viewList = it->second; - viewList->SetGlobals(globals); - //viewlists in subviews need complete container information - if (isSubview) - viewList->SetContainer(osdX, osdY, osdWidth, osdHeight); - else - viewList->SetContainer(0, 0, osdWidth, osdHeight); - viewList->CalculateParameters(); - viewList->CalculateListParameters(); - } - - //Cache ViewTabs - for (vector::iterator tab = viewTabs.begin(); tab != viewTabs.end(); tab++) { - //viewtabs are only in subviews - (*tab)->SetContainer(osdX, osdY, osdWidth, osdHeight); - (*tab)->SetGlobals(globals); - (*tab)->CalculateParameters(); - } - - //Cache Subviews - for (map < eSubView, cTemplateView* >::iterator it = subViews.begin(); it != subViews.end(); it++) { - cTemplateView *subView = it->second; - subView->SetContainer(0, 0, osdWidth, osdHeight); - subView->PreCache(true); - } - - //Cache Plugin Subviews - for (map < string, map< int, cTemplateView*> >::iterator it = pluginViews.begin(); it != pluginViews.end(); it++) { - map< int, cTemplateView*> plugViews = it->second; - for (map< int, cTemplateView*>::iterator it2 = plugViews.begin(); it2 != plugViews.end(); it2++) { - cTemplateView *plugView = it2->second; - plugView->SetContainer(0, 0, osdWidth, osdHeight); - plugView->PreCache(true); - } - } -} - -void cTemplateView::Debug(void) { - - esyslog("skindesigner: TemplateView %s", viewName.c_str());; - - parameters->Debug(); - - for (multimap < eViewElement, cTemplateViewElement* >::iterator it = viewElements.begin(); it != viewElements.end(); it++) { - esyslog("skindesigner: ++++++++ ViewElement: %s", GetViewElementName(it->first).c_str()); - cTemplateViewElement *viewElement = it->second; - viewElement->Debug(); - } - - for (multimap < eViewList, cTemplateViewList* >::iterator it = viewLists.begin(); it != viewLists.end(); it++) { - esyslog("skindesigner: ++++++++ ViewList: %s", GetViewListName(it->first).c_str()); - cTemplateViewList *viewList = it->second; - viewList->Debug(); - } - - for (map < int, cTemplateViewGrid* >::iterator it = viewGrids.begin(); it != viewGrids.end(); it++) { - esyslog("skindesigner: ++++++++ ViewGrid %d:", it->first); - cTemplateViewGrid *viewGrid = it->second; - viewGrid->Debug(); - } - - for (vector::iterator tab = viewTabs.begin(); tab != viewTabs.end(); tab++) { - esyslog("skindesigner: ++++++++ ViewTab"); - (*tab)->Debug(); - } - - for (map < eSubView, cTemplateView* >::iterator it = subViews.begin(); it!= subViews.end(); it++) { - esyslog("skindesigner: ++++++++ SubView: %s", GetSubViewName(it->first).c_str()); - cTemplateView *subView = it->second; - subView->Debug(); - } - - for (map < string, map< int, cTemplateView*> >::iterator it = pluginViews.begin(); it!= pluginViews.end(); it++) { - esyslog("skindesigner: ++++++++ Plugin: %s", it->first.c_str()); - map< int, cTemplateView*> plugViews = it->second; - for (map< int, cTemplateView*>::iterator it2 = plugViews.begin(); it2 != plugViews.end(); it2++) { - esyslog("skindesigner: Tmpl %d", it2->first); - ((cTemplateView*)it2->second)->Debug(); - } - } - -} - - -void cTemplateView::SetFunctionDefinitions(void) { - - string name = "viewelement"; - set attributes; - attributes.insert("debug"); - attributes.insert("detached"); - attributes.insert("delay"); - attributes.insert("fadetime"); - attributes.insert("shifttime"); - attributes.insert("shifttype"); - attributes.insert("shiftmode"); - attributes.insert("startx"); - attributes.insert("starty"); - attributes.insert("name"); - attributes.insert("condition"); - attributes.insert("mode"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "listelement"; - attributes.clear(); - attributes.insert("debug"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "areacontainer"; - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("debug"); - attributes.insert("condition"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "area"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("layer"); - attributes.insert("transparency"); - attributes.insert("background"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "areascroll"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("orientation"); - attributes.insert("delay"); - attributes.insert("mode"); - attributes.insert("scrollspeed"); - attributes.insert("condition"); - attributes.insert("scrollelement"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("layer"); - attributes.insert("transparency"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "loop"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("name"); - attributes.insert("orientation"); - attributes.insert("condition"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("columnwidth"); - attributes.insert("rowheight"); - attributes.insert("overflow"); - attributes.insert("maxitems"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "fill"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("color"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "drawtext"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("name"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("align"); - attributes.insert("valign"); - attributes.insert("font"); - attributes.insert("fontsize"); - attributes.insert("color"); - attributes.insert("text"); - attributes.insert("animtype"); - attributes.insert("animfreq"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "drawtextbox"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("name"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("align"); - attributes.insert("valign"); - attributes.insert("maxlines"); - attributes.insert("font"); - attributes.insert("fontsize"); - attributes.insert("color"); - attributes.insert("text"); - attributes.insert("float"); - attributes.insert("floatwidth"); - attributes.insert("floatheight"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "drawtextvertical"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("name"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("height"); - attributes.insert("align"); - attributes.insert("valign"); - attributes.insert("direction"); - attributes.insert("font"); - attributes.insert("fontsize"); - attributes.insert("color"); - attributes.insert("text"); - attributes.insert("animtype"); - attributes.insert("animfreq"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "drawimage"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("name"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("align"); - attributes.insert("valign"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("imagetype"); - attributes.insert("path"); - attributes.insert("align"); - attributes.insert("valign"); - attributes.insert("cache"); - attributes.insert("animtype"); - attributes.insert("animfreq"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "drawrectangle"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("name"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("align"); - attributes.insert("valign"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("color"); - attributes.insert("animtype"); - attributes.insert("animfreq"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "drawellipse"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("name"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("align"); - attributes.insert("valign"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("color"); - attributes.insert("quadrant"); - attributes.insert("animtype"); - attributes.insert("animfreq"); - funcsAllowed.insert(pair< string, set >(name, attributes)); - - name = "drawslope"; - attributes.clear(); - attributes.insert("debug"); - attributes.insert("condition"); - attributes.insert("name"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("align"); - attributes.insert("valign"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("color"); - attributes.insert("type"); - attributes.insert("animtype"); - attributes.insert("animfreq"); - funcsAllowed.insert(pair< string, set >(name, attributes)); -} - -/************************************************************************************ -* cTemplateViewChannel -************************************************************************************/ - -cTemplateViewChannel::cTemplateViewChannel(void) { - - viewName = "displaychannel"; - //definition of allowed parameters for class itself - set attributes; - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("shifttime"); - attributes.insert("shifttype"); - attributes.insert("shiftmode"); - attributes.insert("startx"); - attributes.insert("starty"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(viewName, attributes)); - - SetViewElements(); -} - -cTemplateViewChannel::~cTemplateViewChannel() { -} - -void cTemplateViewChannel::SetViewElements(void) { - viewElementsAllowed.insert("background"); - viewElementsAllowed.insert("channelinfo"); - viewElementsAllowed.insert("channelgroup"); - viewElementsAllowed.insert("epginfo"); - viewElementsAllowed.insert("progressbar"); - viewElementsAllowed.insert("progressbarback"); - viewElementsAllowed.insert("statusinfo"); - viewElementsAllowed.insert("audioinfo"); - viewElementsAllowed.insert("ecminfo"); - viewElementsAllowed.insert("screenresolution"); - viewElementsAllowed.insert("signalquality"); - viewElementsAllowed.insert("signalqualityback"); - viewElementsAllowed.insert("devices"); - viewElementsAllowed.insert("currentweather"); - viewElementsAllowed.insert("scrapercontent"); - viewElementsAllowed.insert("datetime"); - viewElementsAllowed.insert("time"); - viewElementsAllowed.insert("message"); - viewElementsAllowed.insert("customtokens"); -} - -string cTemplateViewChannel::GetViewElementName(eViewElement ve) { - string name; - switch (ve) { - case veBackground: - name = "Background"; - break; - case veChannelInfo: - name = "ChannelInfo"; - break; - case veChannelGroup: - name = "ChannelGroup"; - break; - case veEpgInfo: - name = "EpgInfo"; - break; - case veProgressBar: - name = "ProgressBar"; - break; - case veProgressBarBack: - name = "ProgressBar Background"; - break; - case veStatusInfo: - name = "StatusInfo"; - break; - case veAudioInfo: - name = "AudioInfo"; - break; - case veScreenResolution: - name = "Screen Resolution"; - break; - case veEcmInfo: - name = "ECM Info"; - break; - case veSignalQuality: - name = "Signal Quality"; - break; - case veSignalQualityBack: - name = "Signal Quality Background"; - break; - case veDevices: - name = "Devices"; - break; - case veCurrentWeather: - name = "Current Weather"; - break; - case veScraperContent: - name = "Scraper Content"; - break; - case veDateTime: - name = "DateTime"; - break; - case veTime: - name = "Time"; - break; - case veMessage: - name = "Message"; - break; - case veCustomTokens: - name = "Custom Tokens"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -void cTemplateViewChannel::AddViewElement(string sViewElement, cTemplateViewElement *viewElement) { - eViewElement ve = veUndefined; - - if (!sViewElement.compare("background")) { - ve = veBackground; - } else if (!sViewElement.compare("channelinfo")) { - ve = veChannelInfo; - } else if (!sViewElement.compare("channelgroup")) { - ve = veChannelGroup; - } else if (!sViewElement.compare("epginfo")) { - ve = veEpgInfo; - } else if (!sViewElement.compare("progressbar")) { - ve = veProgressBar; - } else if (!sViewElement.compare("progressbarback")) { - ve = veProgressBarBack; - } else if (!sViewElement.compare("statusinfo")) { - ve = veStatusInfo; - } else if (!sViewElement.compare("audioinfo")) { - ve = veAudioInfo; - } else if (!sViewElement.compare("ecminfo")) { - ve = veEcmInfo; - } else if (!sViewElement.compare("screenresolution")) { - ve = veScreenResolution; - } else if (!sViewElement.compare("signalquality")) { - ve = veSignalQuality; - } else if (!sViewElement.compare("signalqualityback")) { - ve = veSignalQualityBack; - } else if (!sViewElement.compare("devices")) { - ve = veDevices; - } else if (!sViewElement.compare("currentweather")) { - ve = veCurrentWeather; - } else if (!sViewElement.compare("scrapercontent")) { - ve = veScraperContent; - } else if (!sViewElement.compare("datetime")) { - ve = veDateTime; - } else if (!sViewElement.compare("time")) { - ve = veTime; - } else if (!sViewElement.compare("message")) { - ve = veMessage; - } else if (!sViewElement.compare("customtokens")) { - ve = veCustomTokens; - } - if (ve == veUndefined) { - esyslog("skindesigner: unknown ViewElement in displaychannel: %s", sViewElement.c_str()); - return; - } - - viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement)); -} - -/************************************************************************************ -* cTemplateViewMenu -************************************************************************************/ - -cTemplateViewMenu::cTemplateViewMenu(void) { - - viewName = "displaymenu"; - //definition of allowed parameters for class itself - set attributes; - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(viewName, attributes)); - - string subViewName = "menudefault"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menumain"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menusetup"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menuschedules"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menuchannels"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menutimers"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menurecordings"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menudetailedepg"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menudetailedrecording"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - subViewName = "menudetailedtext"; - //definition of allowed parameters for subtemplate menumain - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(subViewName, attributes)); - - //definition of allowed parameters for menuitems viewlist - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("orientation"); - attributes.insert("align"); - attributes.insert("menuitemwidth"); - attributes.insert("determinatefont"); - attributes.insert("numlistelements"); - attributes.insert("condition"); - funcsAllowed.insert(pair< string, set >("menuitems", attributes)); - - //definition of allowed parameters for currentitems viewlist - attributes.clear(); - attributes.insert("debug"); - attributes.insert("delay"); - attributes.insert("fadetime"); - attributes.insert("condition"); - funcsAllowed.insert(pair< string, set >("currentelement", attributes)); - - //definition of allowed parameters for viewtab - attributes.clear(); - attributes.insert("debug"); - attributes.insert("name"); - attributes.insert("condition"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("layer"); - attributes.insert("transparency"); - attributes.insert("scrollheight"); - funcsAllowed.insert(pair< string, set >("tab", attributes)); - - //definition of allowed parameters for plugin menus - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >("menuplugin", attributes)); - - SetSubViews(); - SetViewElements(); - SetViewLists(); - -} - -cTemplateViewMenu::~cTemplateViewMenu() { -} - -void cTemplateViewMenu::SetSubViews(void) { - subViewsAllowed.insert("menudefault"); - subViewsAllowed.insert("menumain"); - subViewsAllowed.insert("menusetup"); - subViewsAllowed.insert("menuschedules"); - subViewsAllowed.insert("menutimers"); - subViewsAllowed.insert("menurecordings"); - subViewsAllowed.insert("menuchannels"); - subViewsAllowed.insert("menudetailedepg"); - subViewsAllowed.insert("menudetailedrecording"); - subViewsAllowed.insert("menudetailedtext"); -} - -void cTemplateViewMenu::SetViewElements(void) { - viewElementsAllowed.insert("background"); - viewElementsAllowed.insert("datetime"); - viewElementsAllowed.insert("time"); - viewElementsAllowed.insert("header"); - viewElementsAllowed.insert("colorbuttons"); - viewElementsAllowed.insert("message"); - viewElementsAllowed.insert("sortmode"); - viewElementsAllowed.insert("discusage"); - viewElementsAllowed.insert("systemload"); - viewElementsAllowed.insert("systemmemory"); - viewElementsAllowed.insert("vdrstatistics"); - viewElementsAllowed.insert("temperatures"); - viewElementsAllowed.insert("timers"); - viewElementsAllowed.insert("lastrecordings"); - viewElementsAllowed.insert("devices"); - viewElementsAllowed.insert("currentweather"); - viewElementsAllowed.insert("currentschedule"); - viewElementsAllowed.insert("customtokens"); - viewElementsAllowed.insert("scrollbar"); - viewElementsAllowed.insert("detailheader"); - viewElementsAllowed.insert("tablabels"); -} - -void cTemplateViewMenu::SetViewLists(void) { - viewListsAllowed.insert("menuitems"); -} - -string cTemplateViewMenu::GetSubViewName(eSubView sv) { - string name; - switch (sv) { - case svMenuDefault: - name = "Default Menu"; - break; - case svMenuMain: - name = "Main Menu"; - break; - case svMenuSetup: - name = "Setup Menu"; - break; - case svMenuSchedules: - name = "Schedules Menu"; - break; - case svMenuTimers: - name = "Timers Menu"; - break; - case svMenuRecordings: - name = "Recordings Menu"; - break; - case svMenuChannels: - name = "Channels Menu"; - break; - case svMenuDetailedEpg: - name = "Detailed EPG"; - break; - case svMenuDetailedRecording: - name = "Detailed Recording"; - break; - case svMenuDetailedText: - name = "Detailed Text"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - - -string cTemplateViewMenu::GetViewElementName(eViewElement ve) { - string name; - switch (ve) { - case veBackground: - name = "Background"; - break; - case veDateTime: - name = "DateTime"; - break; - case veTime: - name = "Time"; - break; - case veHeader: - name = "Header"; - break; - case veButtons: - name = "Color Buttons"; - break; - case veMessage: - name = "Message"; - break; - case veSortMode: - name = "Sort Mode"; - break; - case veDiscUsage: - name = "Disc Usage"; - break; - case veSystemLoad: - name = "System Load"; - break; - case veSystemMemory: - name = "System Memory"; - break; - case veVDRStats: - name = "VDR Statistics"; - break; - case veTemperatures: - name = "Temperatures"; - break; - case veTimers: - name = "Timers"; - break; - case veLastRecordings: - name = "Last Recordings"; - break; - case veCurrentSchedule: - name = "Current Schedule"; - break; - case veCurrentWeather: - name = "Current Weather"; - break; - case veCustomTokens: - name = "Custom Tokens"; - break; - case veDevices: - name = "Devices"; - break; - case veMenuItem: - name = "Menu Item"; - break; - case veMenuCurrentItemDetail: - name = "Menu Current Item Detail"; - break; - case veScrollbar: - name = "Scrollbar"; - break; - case veDetailHeader: - name = "Detail header"; - break; - case veTabLabels: - name = "tab labels"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -string cTemplateViewMenu::GetViewListName(eViewList vl) { - string name; - switch (vl) { - case vlMenuItem: - name = "Menu Item"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -void cTemplateViewMenu::AddSubView(string sSubView, cTemplateView *subView) { - eSubView sv = svUndefined; - - if (!sSubView.compare("menumain")) { - sv = svMenuMain; - } else if (!sSubView.compare("menudefault")) { - sv = svMenuDefault; - } else if (!sSubView.compare("menuschedules")) { - sv = svMenuSchedules; - } else if (!sSubView.compare("menusetup")) { - sv = svMenuSetup; - } else if (!sSubView.compare("menuschedules")) { - sv = svMenuSchedules; - } else if (!sSubView.compare("menutimers")) { - sv = svMenuTimers; - } else if (!sSubView.compare("menurecordings")) { - sv = svMenuRecordings; - } else if (!sSubView.compare("menuchannels")) { - sv = svMenuChannels; - } else if (!sSubView.compare("menudetailedepg")) { - sv = svMenuDetailedEpg; - } else if (!sSubView.compare("menudetailedrecording")) { - sv = svMenuDetailedRecording; - } else if (!sSubView.compare("menudetailedtext")) { - sv = svMenuDetailedText; - } - - if (sv == svUndefined) { - esyslog("skindesigner: unknown SubView in displayMenu: %s", sSubView.c_str()); - return; - } - subView->SetGlobals(globals); - subViews.insert(pair(sv, subView)); -} - -void cTemplateViewMenu::AddPluginView(string plugName, int templNo, cTemplateView *plugView) { - plugView->SetGlobals(globals); - - map < string, map< int, cTemplateView*> >::iterator hit = pluginViews.find(plugName); - - if (hit == pluginViews.end()) { - map< int, cTemplateView*> plugTemplates; - plugTemplates.insert(pair(templNo, plugView)); - pluginViews.insert(pair< string, map< int, cTemplateView*> >(plugName, plugTemplates)); - } else { - hit->second.insert(pair(templNo, plugView)); - } -} - -void cTemplateViewMenu::AddViewElement(string sViewElement, cTemplateViewElement *viewElement) { - eViewElement ve = veUndefined; - - if (!sViewElement.compare("background")) { - ve = veBackground; - } else if (!sViewElement.compare("datetime")) { - ve = veDateTime; - } else if (!sViewElement.compare("time")) { - ve = veTime; - } else if (!sViewElement.compare("header")) { - ve = veHeader; - } else if (!sViewElement.compare("colorbuttons")) { - ve = veButtons; - } else if (!sViewElement.compare("message")) { - ve = veMessage; - } else if (!sViewElement.compare("sortmode")) { - ve = veSortMode; - } else if (!sViewElement.compare("discusage")) { - ve = veDiscUsage; - } else if (!sViewElement.compare("systemload")) { - ve = veSystemLoad; - } else if (!sViewElement.compare("systemmemory")) { - ve = veSystemMemory; - } else if (!sViewElement.compare("vdrstatistics")) { - ve = veVDRStats; - } else if (!sViewElement.compare("temperatures")) { - ve = veTemperatures; - } else if (!sViewElement.compare("timers")) { - ve = veTimers; - } else if (!sViewElement.compare("lastrecordings")) { - ve = veLastRecordings; - } else if (!sViewElement.compare("currentschedule")) { - ve = veCurrentSchedule; - } else if (!sViewElement.compare("customtokens")) { - ve = veCustomTokens; - } else if (!sViewElement.compare("devices")) { - ve = veDevices; - } else if (!sViewElement.compare("currentweather")) { - ve = veCurrentWeather; - } else if (!sViewElement.compare("scrollbar")) { - ve = veScrollbar; - } else if (!sViewElement.compare("detailheader")) { - ve = veDetailHeader; - } else if (!sViewElement.compare("tablabels")) { - ve = veTabLabels; - } - - if (ve == veUndefined) { - esyslog("skindesigner: unknown ViewElement in displayMenu: %s", sViewElement.c_str()); - return; - } - - viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement)); -} - -void cTemplateViewMenu::AddViewList(string sViewList, cTemplateViewList *viewList) { - - eViewList vl = vlUndefined; - if (!sViewList.compare("menuitems")) { - vl = vlMenuItem; - } - - if (vl == vlUndefined) { - esyslog("skindesigner: unknown ViewList in displaymenu: %s", sViewList.c_str()); - return; - } - - viewList->SetGlobals(globals); - viewLists.insert(pair< eViewList, cTemplateViewList*>(vl, viewList)); -} - -void cTemplateViewMenu::AddViewTab(cTemplateViewTab *viewTab) { - viewTabs.push_back(viewTab); -} - -/************************************************************************************ -* cTemplateViewMessage -************************************************************************************/ - -cTemplateViewMessage::cTemplateViewMessage(void) { - - viewName = "displaymessage"; - //definition of allowed parameters for class itself - set attributes; - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("shifttime"); - attributes.insert("shifttype"); - attributes.insert("shiftmode"); - attributes.insert("startx"); - attributes.insert("starty"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(viewName, attributes)); - - SetViewElements(); -} - -cTemplateViewMessage::~cTemplateViewMessage() { -} - -void cTemplateViewMessage::SetViewElements(void) { - viewElementsAllowed.insert("background"); - viewElementsAllowed.insert("message"); -} - -string cTemplateViewMessage::GetViewElementName(eViewElement ve) { - string name; - switch (ve) { - case veBackground: - name = "Background"; - break; - case veMessage: - name = "Message"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -void cTemplateViewMessage::AddViewElement(string sViewElement, cTemplateViewElement *viewElement) { - eViewElement ve = veUndefined; - - if (!sViewElement.compare("background")) { - ve = veBackground; - } else if (!sViewElement.compare("message")) { - ve = veMessage; - } - - if (ve == veUndefined) { - esyslog("skindesigner: unknown ViewElement in displaymessage: %s", sViewElement.c_str()); - return; - } - - viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement)); -} - -/************************************************************************************ -* cTemplateViewReplay -************************************************************************************/ - -cTemplateViewReplay::cTemplateViewReplay(void) { - - viewName = "displayreplay"; - //definition of allowed parameters for class itself - set attributes; - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("shifttime"); - attributes.insert("shifttype"); - attributes.insert("shiftmode"); - attributes.insert("startx"); - attributes.insert("starty"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(viewName, attributes)); - - //definition of allowed parameters for onpause and onpausemodeonly viewelement - attributes.clear(); - attributes.insert("debug"); - attributes.insert("delay"); - attributes.insert("fadetime"); - funcsAllowed.insert(pair< string, set >("onpause", attributes)); - funcsAllowed.insert(pair< string, set >("onpausemodeonly", attributes)); - - SetViewElements(); -} - -cTemplateViewReplay::~cTemplateViewReplay() { -} - -void cTemplateViewReplay::SetViewElements(void) { - viewElementsAllowed.insert("background"); - viewElementsAllowed.insert("backgroundmodeonly"); - viewElementsAllowed.insert("datetime"); - viewElementsAllowed.insert("time"); - viewElementsAllowed.insert("rectitle"); - viewElementsAllowed.insert("recinfo"); - viewElementsAllowed.insert("scrapercontent"); - viewElementsAllowed.insert("currenttime"); - viewElementsAllowed.insert("totaltime"); - viewElementsAllowed.insert("endtime"); - viewElementsAllowed.insert("progressbar"); - viewElementsAllowed.insert("cutmarks"); - viewElementsAllowed.insert("controlicons"); - viewElementsAllowed.insert("controliconsmodeonly"); - viewElementsAllowed.insert("progressmodeonly"); - viewElementsAllowed.insert("jump"); - viewElementsAllowed.insert("message"); - viewElementsAllowed.insert("onpause"); - viewElementsAllowed.insert("onpausemodeonly"); - viewElementsAllowed.insert("customtokens"); -} - -string cTemplateViewReplay::GetViewElementName(eViewElement ve) { - string name; - switch (ve) { - case veBackground: - name = "Background"; - break; - case veDateTime: - name = "DateTime"; - break; - case veTime: - name = "DateTime"; - break; - case veRecTitle: - name = "Recording Title"; - break; - case veRecInfo: - name = "Recording Information"; - break; - case veRecCurrent: - name = "Recording current Time"; - break; - case veRecTotal: - name = "Recording total Time"; - break; - case veRecEnd: - name = "Recording end Time"; - break; - case veRecProgressBar: - name = "Rec Progress Bar"; - break; - case veCuttingMarks: - name = "Cutting Marks"; - break; - case veControlIcons: - name = "Control Icons"; - break; - case veControlIconsModeOnly: - name = "Control Icons Mode only"; - break; - case veProgressModeOnly: - name = "Progress Mode only"; - break; - case veBackgroundModeOnly: - name = "Background Mode only"; - break; - case veRecJump: - name = "Recording Jump"; - break; - case veScraperContent: - name = "Scraper Content"; - break; - case veOnPause: - name = "On Pause"; - break; - case veOnPauseModeOnly: - name = "On Pause Mode Only"; - break; - case veCustomTokens: - name = "Custom Tokens"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -void cTemplateViewReplay::AddViewElement(string sViewElement, cTemplateViewElement *viewElement) { - eViewElement ve = veUndefined; - - if (!sViewElement.compare("background")) { - ve = veBackground; - } else if (!sViewElement.compare("datetime")) { - ve = veDateTime; - } else if (!sViewElement.compare("time")) { - ve = veTime; - } else if (!sViewElement.compare("rectitle")) { - ve = veRecTitle; - } else if (!sViewElement.compare("recinfo")) { - ve = veRecInfo; - } else if (!sViewElement.compare("scrapercontent")) { - ve = veScraperContent; - } else if (!sViewElement.compare("currenttime")) { - ve = veRecCurrent; - } else if (!sViewElement.compare("totaltime")) { - ve = veRecTotal; - } else if (!sViewElement.compare("endtime")) { - ve = veRecEnd; - } else if (!sViewElement.compare("progressbar")) { - ve = veRecProgressBar; - } else if (!sViewElement.compare("cutmarks")) { - ve = veCuttingMarks; - } else if (!sViewElement.compare("controlicons")) { - ve = veControlIcons; - } else if (!sViewElement.compare("controliconsmodeonly")) { - ve = veControlIconsModeOnly; - } else if (!sViewElement.compare("progressmodeonly")) { - ve = veProgressModeOnly; - } else if (!sViewElement.compare("backgroundmodeonly")) { - ve = veBackgroundModeOnly; - } else if (!sViewElement.compare("jump")) { - ve = veRecJump; - } else if (!sViewElement.compare("message")) { - ve = veMessage; - } else if (!sViewElement.compare("onpause")) { - ve = veOnPause; - } else if (!sViewElement.compare("onpausemodeonly")) { - ve = veOnPauseModeOnly; - } else if (!sViewElement.compare("customtokens")) { - ve = veCustomTokens; - } - - if (ve == veUndefined) { - esyslog("skindesigner: unknown ViewElement in displayreplay: %s", sViewElement.c_str()); - return; - } - - viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement)); -} - - -/************************************************************************************ -* cTemplateViewVolume -************************************************************************************/ - -cTemplateViewVolume::cTemplateViewVolume(void) { - - viewName = "displayvolume"; - //definition of allowed parameters for class itself - set attributes; - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("shifttime"); - attributes.insert("shifttype"); - attributes.insert("shiftmode"); - attributes.insert("startx"); - attributes.insert("starty"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(viewName, attributes)); - - SetViewElements(); -} - -cTemplateViewVolume::~cTemplateViewVolume() { -} - -void cTemplateViewVolume::SetViewElements(void) { - viewElementsAllowed.insert("background"); - viewElementsAllowed.insert("volume"); -} - -string cTemplateViewVolume::GetViewElementName(eViewElement ve) { - string name; - switch (ve) { - case veBackground: - name = "Background"; - break; - case veVolume: - name = "Volume"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -void cTemplateViewVolume::AddViewElement(string sViewElement, cTemplateViewElement *viewElement) { - eViewElement ve = veUndefined; - - if (!sViewElement.compare("background")) { - ve = veBackground; - } else if (!sViewElement.compare("volume")) { - ve = veVolume; - } - - if (ve == veUndefined) { - esyslog("skindesigner: unknown ViewElement in displayvolume: %s", sViewElement.c_str()); - return; - } - - viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement)); -} - -/************************************************************************************ -* cTemplateViewAudioTracks -************************************************************************************/ - -cTemplateViewAudioTracks::cTemplateViewAudioTracks(void) { - - viewName = "displayaudiotracks"; - //definition of allowed parameters for class itself - set attributes; - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("shifttime"); - attributes.insert("shifttype"); - attributes.insert("shiftmode"); - attributes.insert("startx"); - attributes.insert("starty"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(viewName, attributes)); - - //definition of allowed parameters for menuitems viewlist - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("orientation"); - attributes.insert("align"); - attributes.insert("menuitemwidth"); - attributes.insert("numlistelements"); - funcsAllowed.insert(pair< string, set >("menuitems", attributes)); - - SetViewElements(); - SetViewLists(); -} - -cTemplateViewAudioTracks::~cTemplateViewAudioTracks() { -} - -void cTemplateViewAudioTracks::SetViewElements(void) { - viewElementsAllowed.insert("background"); - viewElementsAllowed.insert("header"); -} - -void cTemplateViewAudioTracks::SetViewLists(void) { - viewListsAllowed.insert("menuitems"); -} - -string cTemplateViewAudioTracks::GetViewElementName(eViewElement ve) { - string name; - switch (ve) { - case veBackground: - name = "Background"; - break; - case veHeader: - name = "Header"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -string cTemplateViewAudioTracks::GetViewListName(eViewList vl) { - string name; - switch (vl) { - case vlMenuItem: - name = "Menu Item"; - break; - default: - name = "Unknown"; - break; - }; - return name; -} - -void cTemplateViewAudioTracks::AddViewElement(string sViewElement, cTemplateViewElement *viewElement) { - eViewElement ve = veUndefined; - - if (!sViewElement.compare("background")) { - ve = veBackground; - } else if(!sViewElement.compare("header")) { - ve = veHeader; - } - - if (ve == veUndefined) { - esyslog("skindesigner: unknown ViewElement in displayaudiotracks: %s", sViewElement.c_str()); - return; - } - - viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement)); -} - -void cTemplateViewAudioTracks::AddViewList(string sViewList, cTemplateViewList *viewList) { - - eViewList vl = vlUndefined; - if (!sViewList.compare("menuitems")) { - vl = vlMenuItem; - } - - if (vl == vlUndefined) { - esyslog("skindesigner: unknown ViewList in displaymenu: %s", sViewList.c_str()); - return; - } - - viewList->SetGlobals(globals); - viewLists.insert(pair< eViewList, cTemplateViewList*>(vl, viewList)); -} - -/************************************************************************************ -* cTemplateViewPlugin -************************************************************************************/ - -cTemplateViewPlugin::cTemplateViewPlugin(string pluginName, int viewID) { - this->pluginName = pluginName; - this->viewID = viewID; - viewName = "displayplugin"; - //definition of allowed parameters for class itself - set attributes; - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("fadetime"); - attributes.insert("shifttime"); - attributes.insert("shifttype"); - attributes.insert("shiftmode"); - attributes.insert("startx"); - attributes.insert("starty"); - attributes.insert("scaletvx"); - attributes.insert("scaletvy"); - attributes.insert("scaletvwidth"); - attributes.insert("scaletvheight"); - attributes.insert("hideroot"); - attributes.insert("debuggrid"); - funcsAllowed.insert(pair< string, set >(viewName, attributes)); - - //definition of allowed parameters for viewtab - attributes.clear(); - attributes.insert("debug"); - attributes.insert("name"); - attributes.insert("condition"); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("layer"); - attributes.insert("transparency"); - attributes.insert("scrollheight"); - funcsAllowed.insert(pair< string, set >("tab", attributes)); - - attributes.clear(); - attributes.insert("x"); - attributes.insert("y"); - attributes.insert("width"); - attributes.insert("height"); - attributes.insert("name"); - funcsAllowed.insert(pair< string, set >("grid", attributes)); - - viewElementsAllowed.insert("viewelement"); - viewElementsAllowed.insert("scrollbar"); - viewElementsAllowed.insert("tablabels"); - viewGridsAllowed.insert("grid"); -} - -cTemplateViewPlugin::~cTemplateViewPlugin() { -} - -void cTemplateViewPlugin::AddSubView(string sSubView, cTemplateView *subView) { - int subViewId = atoi(sSubView.c_str()); - subViews.insert(pair< eSubView, cTemplateView* >((eSubView)subViewId, subView)); -} - -void cTemplateViewPlugin::AddViewElement(string sViewElement, cTemplateViewElement *viewElement) { - eViewElement ve = veUndefined; - string viewElementName = ""; - int viewElementID = -1; - - bool found = viewElement->GetName(viewElementName); - - if (found) { - viewElementID = config.GetPluginViewElementID(pluginName, viewElementName, viewID); - } else { - //check for internal view elements - ePluginInteralViewElements pve = pveUndefined; - if (!sViewElement.compare("scrollbar")) { - pve = pveScrollbar; - } else if (!sViewElement.compare("tablabels")) { - pve = pveTablabels; - } - if (pve == pveUndefined) { - esyslog("skindesigner: %s: unknown ViewElement in displayplugin: %s", pluginName.c_str(), viewElementName.c_str()); - return; - } - viewElementID = pve; - } - - ve = (eViewElement)viewElementID; - viewElements.insert(pair< eViewElement, cTemplateViewElement*>(ve, viewElement)); -} - -void cTemplateViewPlugin::AddGrid(cTemplateViewGrid *viewGrid) { - string gridName = ""; - bool found = viewGrid->GetName(gridName); - - if (!found) { - esyslog("skindesigner: no name defined for plugin %s grid", pluginName.c_str()); - } - int gridID = config.GetPluginViewGridID(pluginName, gridName, viewID); - - if (gridID == -1) { - esyslog("skindesigner: %s: unknown Grid in displayplugin: %s", pluginName.c_str(), gridName.c_str()); - return; - } - - viewGrids.insert(pair< int, cTemplateViewGrid*>(gridID, viewGrid)); -} - -void cTemplateViewPlugin::AddViewTab(cTemplateViewTab *viewTab) { - viewTabs.push_back(viewTab); -} diff --git a/libtemplate/templateview.h b/libtemplate/templateview.h deleted file mode 100644 index 1713cdc..0000000 --- a/libtemplate/templateview.h +++ /dev/null @@ -1,243 +0,0 @@ -#ifndef __TEMPLATEVIEW_H -#define __TEMPLATEVIEW_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "templateviewelement.h" -#include "templateviewlist.h" -#include "templateviewgrid.h" -#include "templatepixmap.h" -#include "templateviewtab.h" -#include "templatefunction.h" - -using namespace std; - -// --- cTemplateView ------------------------------------------------------------- - -enum eSubView { - svUndefined, - svMenuDefault, - svMenuMain, - svMenuSetup, - svMenuSchedules, - svMenuTimers, - svMenuRecordings, - svMenuChannels, - svMenuDetailedEpg, - svMenuDetailedRecording, - svMenuDetailedText, - svMenuPlugin, -}; - -class cTemplateView { -private: -protected: - cGlobals *globals; - //view parameters - string viewName; - cTemplateFunction *parameters; - int containerX; - int containerY; - int containerWidth; - int containerHeight; - //basic view data structures - multimap < eViewElement, cTemplateViewElement* > viewElements; - multimap < eViewList, cTemplateViewList* > viewLists; - map < int, cTemplateViewGrid* > viewGrids; - map < eSubView, cTemplateView* > subViews; - vector< cTemplateViewTab* > viewTabs; - map < string, map< int, cTemplateView*> > pluginViews; - //helpers to iterate data structures - map < eViewElement, cTemplateViewElement* >::iterator veIt; - map < eViewList, cTemplateViewList* >::iterator vlIt; - map < int, cTemplateViewGrid* >::iterator geIt; - map < eSubView, cTemplateView* >::iterator svIt; - vector< cTemplateViewTab* >::iterator vtIt; - //helpers to check valid xml templates - set subViewsAllowed; - set viewElementsAllowed; - set viewListsAllowed; - set viewGridsAllowed; - map < string, set < string > > funcsAllowed; - void SetFunctionDefinitions(void); -public: - cTemplateView(void); - virtual ~cTemplateView(void); - virtual string GetSubViewName(eSubView sv) { return ""; }; - virtual string GetViewElementName(eViewElement ve) { return ""; }; - virtual string GetViewListName(eViewList vl) { return ""; }; - virtual void AddSubView(string sSubView, cTemplateView *subView) {}; - virtual void AddPluginView(string plugName, int templNo, cTemplateView *plugView) {}; - virtual void AddViewElement(string sViewElement, cTemplateViewElement *viewElement) {}; - virtual void AddGrid(cTemplateViewGrid *viewGrid) {}; - virtual void AddViewList(string sViewList, cTemplateViewList *viewList) {}; - virtual void AddViewTab(cTemplateViewTab *viewTab) {}; - //Setter Functions - void SetGlobals(cGlobals *globals) { this->globals = globals; }; - void SetParameters(vector > ¶ms); - void SetContainer(int x, int y, int width, int height); - //access view elements - cTemplateViewElement *GetViewElement(eViewElement ve); - void InitViewElementIterator(void); - cTemplateViewElement *GetNextViewElement(void); - //access view grids - cTemplateViewGrid *GetViewGrid(int gridID); - void InitViewGridIterator(void); - cTemplateViewGrid *GetNextViewGrid(void); - //access list elements - cTemplateViewList *GetViewList(eViewList vl); - void InitViewListIterator(void); - cTemplateViewList *GetNextViewList(void); - bool IsListView(void) { return viewLists.size() > 0 ? true : false; }; - //access tabs - void InitViewTabIterator(void); - cTemplateViewTab *GetNextViewTab(void); - //access sub views - cTemplateView *GetSubView(eSubView sv); - void InitSubViewIterator(void); - cTemplateView *GetNextSubView(void); - //access plugin views - cTemplateView *GetPluginView(string pluginName, int pluginMenu); - //Getter Functions - const char *GetViewName(void) { return viewName.c_str(); }; - int GetNumericParameter(eParamType type); - cRect GetOsdSize(void); - int GetNumPixmaps(void); - int GetNumPixmapsViewElement(eViewElement ve); - bool DrawGebugGrid(void); - int DebugGridX(void); - int DebugGridY(void); - tColor DebugGridColor(void); - tColor DebugGridFontColor(void); - bool HideView(void); - bool ExecuteView(eViewElement ve); - bool DetachViewElement(eViewElement ve); - string GetViewElementMode(eViewElement ve); - int GetNumListViewMenuItems(void); - bool GetScalingWindow(cRect &scalingWindow); - map GetCustomStringTokens(void) { return globals->GetCustomStringTokens(); }; - map GetCustomIntTokens(void) { return globals->GetCustomIntTokens(); }; - bool CustomTokenChange(void) { return globals->CustomTokenChange(); }; - //Checks for parsing template XML files - bool ValidSubView(const char *subView); - bool ValidViewElement(const char *viewElement); - bool ValidViewList(const char *viewList); - bool ValidViewGrid(const char *viewGrid); - bool ValidFunction(const char *func); - bool ValidAttribute(const char *func, const char *att); - //Caching - void Translate(void); - void PreCache(bool isSubview); - //Debug - void Debug(void); -}; - -// --- cTemplateViewChannel ------------------------------------------------------------- - -class cTemplateViewChannel : public cTemplateView { -private: - void SetViewElements(void); - void SetViewLists(void); - eViewElement GetViewElementID(string sViewElement); -public: - cTemplateViewChannel(void); - virtual ~cTemplateViewChannel(void); - string GetViewElementName(eViewElement ve); - void AddViewElement(string sViewElement, cTemplateViewElement *viewElement); -}; - -// --- cTemplateViewMenu ------------------------------------------------------------- - -class cTemplateViewMenu : public cTemplateView { -private: - void SetSubViews(void); - void SetViewElements(void); - void SetViewLists(void); -public: - cTemplateViewMenu(void); - virtual ~cTemplateViewMenu(void); - string GetSubViewName(eSubView sv); - string GetViewElementName(eViewElement ve); - string GetViewListName(eViewList vl); - void AddSubView(string sSubView, cTemplateView *subView); - void AddPluginView(string plugName, int templNo, cTemplateView *plugView); - void AddViewElement(string sViewElement, cTemplateViewElement *viewElement); - void AddViewList(string sViewList, cTemplateViewList *viewList); - void AddViewTab(cTemplateViewTab *viewTab); -}; - -// --- cTemplateViewMessage ------------------------------------------------------------- - -class cTemplateViewMessage : public cTemplateView { -private: - void SetViewElements(void); -public: - cTemplateViewMessage(void); - virtual ~cTemplateViewMessage(void); - string GetViewElementName(eViewElement ve); - void AddViewElement(string sViewElement, cTemplateViewElement *viewElement); -}; - -// --- cTemplateViewReplay ------------------------------------------------------------- - -class cTemplateViewReplay : public cTemplateView { -private: - void SetViewElements(void); -public: - cTemplateViewReplay(void); - virtual ~cTemplateViewReplay(void); - string GetViewElementName(eViewElement ve); - void AddViewElement(string sViewElement, cTemplateViewElement *viewElement); -}; - -// --- cTemplateViewVolume ------------------------------------------------------------- - -class cTemplateViewVolume : public cTemplateView { -private: - void SetViewElements(void); -public: - cTemplateViewVolume(void); - virtual ~cTemplateViewVolume(void); - string GetViewElementName(eViewElement ve); - void AddViewElement(string sViewElement, cTemplateViewElement *viewElement); -}; - -// --- cTemplateViewAudioTracks ------------------------------------------------------------- - -class cTemplateViewAudioTracks : public cTemplateView { -private: - void SetViewElements(void); - void SetViewLists(void); -public: - cTemplateViewAudioTracks(void); - virtual ~cTemplateViewAudioTracks(void); - string GetViewElementName(eViewElement ve); - string GetViewListName(eViewList vl); - void AddViewElement(string sViewElement, cTemplateViewElement *viewElement); - void AddViewList(string sViewList, cTemplateViewList *viewList); -}; - -// --- cTemplateViewPlugin ------------------------------------------------------------- - -class cTemplateViewPlugin : public cTemplateView { -private: - string pluginName; - int viewID; -public: - cTemplateViewPlugin(string pluginName, int viewID); - virtual ~cTemplateViewPlugin(void); - void AddSubView(string sSubView, cTemplateView *subView); - void AddViewElement(string sViewElement, cTemplateViewElement *viewElement); - void AddGrid(cTemplateViewGrid *viewGrid); - void AddViewTab(cTemplateViewTab *viewTab); -}; - -#endif //__TEMPLATEVIEW_H diff --git a/libtemplate/templateviewelement.c b/libtemplate/templateviewelement.c deleted file mode 100644 index 56672b8..0000000 --- a/libtemplate/templateviewelement.c +++ /dev/null @@ -1,236 +0,0 @@ -#include "templateviewelement.h" -#include "../config.h" - -cTemplateViewElement::cTemplateViewElement(void) { - debugTokens = false; - parameters = NULL; - containerX = 0; - containerY = 0; - containerWidth = 0; - containerHeight = 0; - pixOffset = -1; - pixmapIterator = NULL; - currentNode = NULL; -} - -cTemplateViewElement::~cTemplateViewElement(void) { - if (parameters) - delete parameters; - for (vector::iterator it = viewPixmapNodes.begin(); it != viewPixmapNodes.end(); it++) { - delete (*it); - } -} - -void cTemplateViewElement::SetContainer(int x, int y, int width, int height) { - containerX = x; - containerY = y; - containerWidth = width; - containerHeight = height; -} - -void cTemplateViewElement::SetGlobals(cGlobals *globals) { - this->globals = globals; - for (vector::iterator pix = viewPixmapNodes.begin(); pix != viewPixmapNodes.end(); pix++) { - (*pix)->SetGlobals(globals); - } -} - -void cTemplateViewElement::SetParameters(vector > ¶ms) { - parameters = new cTemplateFunction(ftViewElement); - parameters->SetGlobals(globals); - parameters->SetParameters(params); -} - -bool cTemplateViewElement::CalculateParameters(void) { - if (!parameters) - return true; - bool paramsValid = true; - parameters->SetContainer(containerX, containerY, containerWidth, containerHeight); - parameters->SetGlobals(globals); - paramsValid = parameters->CalculateParameters(); - parameters->ParseParameters(); - return paramsValid; -} - -bool cTemplateViewElement::CalculatePixmapParameters(void) { - bool paramsValid = true; - for (vector::iterator pix = viewPixmapNodes.begin(); pix != viewPixmapNodes.end(); pix++) { - (*pix)->SetContainer(containerX, containerY, containerWidth, containerHeight); - (*pix)->SetGlobals(globals); - paramsValid = paramsValid && (*pix)->CalculateParameters(); - } - return paramsValid; -} - -bool cTemplateViewElement::CalculatePixmapParametersList(int orientation, int numElements) { - bool paramsValid = true; - for (vector::iterator pix = viewPixmapNodes.begin(); pix != viewPixmapNodes.end(); pix++) { - (*pix)->SetContainer(containerX, containerY, containerWidth, containerHeight); - (*pix)->SetGlobals(globals); - if (orientation == orHorizontal) { - if (numElements > 0) { - int width = containerWidth / numElements; - (*pix)->SetWidth(width); - } - } else if (orientation == orVertical) { - if (numElements > 0) { - int height = containerHeight / numElements; - (*pix)->SetHeight(height); - } - } - paramsValid = paramsValid && (*pix)->CalculateParameters(); - } - return paramsValid; -} - -int cTemplateViewElement::GetNumericParameter(eParamType type) { - if (!parameters) - return -1; - return parameters->GetNumericParameter(type); -} - -int cTemplateViewElement::GetNumPixmaps(void) { - int numPixmaps = 0; - for (vector::iterator pix = viewPixmapNodes.begin(); pix != viewPixmapNodes.end(); pix++) { - numPixmaps += (*pix)->NumPixmaps(); - } - return numPixmaps; -}; - -bool cTemplateViewElement::GetName(string &name) { - if (!parameters) - return false; - name = parameters->GetParameter(ptName); - if (name.size() > 0) - return true; - return false; -} - -void cTemplateViewElement::InitPixmapNodeIterator(void) { - pixmapNodeIterator = viewPixmapNodes.begin(); -} - -cTemplatePixmapNode *cTemplateViewElement::GetNextPixmapNode(void) { - if (pixmapNodeIterator == viewPixmapNodes.end()) - return NULL; - cTemplatePixmapNode *pix = *pixmapNodeIterator; - pixmapNodeIterator++; - return pix; -} - -void cTemplateViewElement::InitPixmapIterator(void) { - pixmapNodeIterator = viewPixmapNodes.begin(); - if (pixmapNodeIterator == viewPixmapNodes.end()) - return; - if (!(*pixmapNodeIterator)->IsContainer()) { - //first node is a pixmap, use this - pixmapIterator = dynamic_cast(*pixmapNodeIterator); - return; - } - //first node is a container, so fetch first pixmap of this container - currentNode = dynamic_cast(*pixmapNodeIterator); - currentNode->InitIterator(); - pixmapIterator = currentNode->GetNextPixmap(); -} - -cTemplatePixmap *cTemplateViewElement::GetNextPixmap(void) { - if (!pixmapIterator) - return NULL; - cTemplatePixmap *current = pixmapIterator; - //set next pixmap - if (!currentNode) { - //last node was a pixmap - pixmapNodeIterator++; - if (pixmapNodeIterator == viewPixmapNodes.end()) { - pixmapIterator = NULL; - return current; - } - if (!(*pixmapNodeIterator)->IsContainer()) { - //node is a pixmap, use this - pixmapIterator = dynamic_cast(*pixmapNodeIterator); - return current; - } - //node is a container, so fetch first pixmap of this container - currentNode = dynamic_cast(*pixmapNodeIterator); - currentNode->InitIterator(); - pixmapIterator = currentNode->GetNextPixmap(); - } else { - pixmapIterator = currentNode->GetNextPixmap(); - if (pixmapIterator) { - return current; - } - currentNode = NULL; - pixmapNodeIterator++; - if (pixmapNodeIterator == viewPixmapNodes.end()) { - pixmapIterator = NULL; - return current; - } - if (!(*pixmapNodeIterator)->IsContainer()) { - //node is a pixmap, use this - pixmapIterator = dynamic_cast(*pixmapNodeIterator); - return current; - } - //node is a container, so fetch first pixmap of this container - currentNode = dynamic_cast(*pixmapNodeIterator); - currentNode->InitIterator(); - pixmapIterator = currentNode->GetNextPixmap(); - } - return current; -} - -cTemplateFunction *cTemplateViewElement::GetFunction(string name) { - InitPixmapIterator(); - cTemplatePixmap *pix = NULL; - while (pix = GetNextPixmap()) { - pix->InitFunctionIterator(); - cTemplateFunction *func = NULL; - while(func = pix->GetNextFunction()) { - if (func->GetType() == ftDrawText) { - string funcName = func->GetParameter(ptName); - if (!funcName.compare(name)) - return func; - } else { - continue; - } - } - } - return NULL; -} - -bool cTemplateViewElement::Execute(void) { - if (!parameters) - return true; - return parameters->DoExecute(); -} - -bool cTemplateViewElement::Detach(void) { - if (!parameters) - return false; - int detached = parameters->GetNumericParameter(ptDetached); - if (detached == 1) - return true; - return false; -} - -string cTemplateViewElement::GetMode(void) { - if (!parameters) - return ""; - return parameters->GetParameter(ptMode); -} - -bool cTemplateViewElement::DebugTokens(void) { - if (!parameters) - return false; - return parameters->DoDebug(); -} - - -void cTemplateViewElement::Debug(void) { - esyslog("skindesigner: viewelement container size x: %d, y: %d, width: %d, height %d", containerX, containerY, containerWidth, containerHeight); - if (parameters) - parameters->Debug(); - return; - for (vector::iterator it = viewPixmapNodes.begin(); it != viewPixmapNodes.end(); it++) { - (*it)->Debug(); - } -} \ No newline at end of file diff --git a/libtemplate/templateviewelement.h b/libtemplate/templateviewelement.h deleted file mode 100644 index 189e9e5..0000000 --- a/libtemplate/templateviewelement.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef __TEMPLATEVIEWELEMENT_H -#define __TEMPLATEVIEWELEMENT_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "templatepixmap.h" -#include "templatefunction.h" - -using namespace std; - -// --- cTemplateViewElement ------------------------------------------------------------- - -enum eViewElement { - //Common ViewElements - veUndefined, - veBackground, - veDateTime, - veTime, - veMessage, - veSortMode, - veDevices, - veCurrentWeather, - veCustomTokens, - //DisplayChannel ViewElements - veChannelInfo, - veChannelGroup, - veEpgInfo, - veProgressBar, - veProgressBarBack, - veStatusInfo, - veAudioInfo, - veScreenResolution, - veSignalQuality, - veSignalQualityBack, - veScraperContent, - veEcmInfo, - //DisplayMenu ViewElements - veHeader, - veButtons, - veDiscUsage, - veSystemLoad, - veSystemMemory, - veVDRStats, - veTemperatures, - veTimers, - veLastRecordings, - veCurrentSchedule, - veMenuItem, - veMenuCurrentItemDetail, - veScrollbar, - veDetailHeader, - veTabLabels, - //DisplayReplay ViewElements - veRecTitle, - veRecInfo, - veRecCurrent, - veRecTotal, - veRecEnd, - veRecProgressBar, - veCuttingMarks, - veControlIcons, - veControlIconsModeOnly, - veProgressModeOnly, - veBackgroundModeOnly, - veRecJump, - veOnPause, - veOnPauseModeOnly, - //DisplayVolume ViewElements - veVolume -}; - -enum ePluginInteralViewElements { - pveScrollbar = -1, - pveTablabels = -2, - pveUndefined = 0 -}; - -class cTemplateViewElement { -protected: - bool debugTokens; - cGlobals *globals; - cTemplateFunction *parameters; - int containerX; - int containerY; - int containerWidth; - int containerHeight; - vector viewPixmapNodes; - vector::iterator pixmapNodeIterator; - cTemplatePixmap *pixmapIterator; - cTemplatePixmapContainer *currentNode; - int pixOffset; -public: - cTemplateViewElement(void); - virtual ~cTemplateViewElement(void); - void SetContainer(int x, int y, int width, int height); - virtual void SetGlobals(cGlobals *globals); - void SetParameters(vector > ¶ms); - bool CalculateParameters(void); - virtual bool CalculatePixmapParameters(void); - bool CalculatePixmapParametersList(int orientation, int numElements); - void AddPixmap(cTemplatePixmapNode *pix) { viewPixmapNodes.push_back(pix); }; - int GetNumericParameter(eParamType type); - void SetPixOffset(int offset) { pixOffset = offset; }; - int GetPixOffset(void) { return pixOffset; }; - virtual int GetNumPixmaps(void); - bool GetName(string &name); - void InitPixmapNodeIterator(void); - cTemplatePixmapNode *GetNextPixmapNode(void); - void InitPixmapIterator(void); - cTemplatePixmap *GetNextPixmap(void); - cTemplateFunction *GetFunction(string name); - bool Execute(void); - bool Detach(void); - string GetMode(void); - bool DebugTokens(void); - virtual void Debug(void); -}; - -#endif //__TEMPLATEVIEWELEMENT_H \ No newline at end of file diff --git a/libtemplate/templateviewgrid.c b/libtemplate/templateviewgrid.c deleted file mode 100644 index bd73d84..0000000 --- a/libtemplate/templateviewgrid.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "templateviewgrid.h" -#include "../config.h" -#include "../libcore/helpers.h" - -cTemplateViewGrid::cTemplateViewGrid(void) : cTemplateViewElement() { -} - -cTemplateViewGrid::~cTemplateViewGrid(void) { -} - -bool cTemplateViewGrid::CalculatePixmapParameters(void) { - bool paramsValid = true; - int gridX = parameters->GetNumericParameter(ptX); - int gridY = parameters->GetNumericParameter(ptY); - int gridWidth = parameters->GetNumericParameter(ptWidth); - int gridHeight = parameters->GetNumericParameter(ptHeight); - - for (vector::iterator pix = viewPixmapNodes.begin(); pix != viewPixmapNodes.end(); pix++) { - (*pix)->SetContainer(gridX, gridY, gridWidth, gridHeight); - (*pix)->SetGlobals(globals); - paramsValid = paramsValid && (*pix)->CalculateParameters(); - } - return paramsValid; -} - -void cTemplateViewGrid::Debug(void) { - esyslog("skindesigner: --- Grid: "); - cTemplateViewElement::Debug(); -} \ No newline at end of file diff --git a/libtemplate/templateviewgrid.h b/libtemplate/templateviewgrid.h deleted file mode 100644 index 6b5c34a..0000000 --- a/libtemplate/templateviewgrid.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __TEMPLATEVIEWGRID_H -#define __TEMPLATEVIEWGRID_H - -#include -#include -#include -#include -#include - -#include "templateviewelement.h" - -using namespace std; - -// --- cTemplateViewGrid ------------------------------------------------------------- - -class cTemplateViewGrid : public cTemplateViewElement { -private: -public: - cTemplateViewGrid(void); - ~cTemplateViewGrid(void); - bool CalculatePixmapParameters(void); - void Debug(void); -}; - -#endif //__TEMPLATEVIEWGRID_H \ No newline at end of file diff --git a/libtemplate/templateviewlist.c b/libtemplate/templateviewlist.c deleted file mode 100644 index a831d2d..0000000 --- a/libtemplate/templateviewlist.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "templateviewlist.h" -#include "../config.h" -#include "../libcore/helpers.h" - -cTemplateViewList::cTemplateViewList(void) : cTemplateViewElement() { - listElement = NULL; - currentElement = NULL; -} - -cTemplateViewList::~cTemplateViewList(void) { - if (listElement) - delete listElement; - if (currentElement) - delete currentElement; -} - -void cTemplateViewList::SetGlobals(cGlobals *globals) { - cTemplateViewElement::SetGlobals(globals); - if (listElement) - listElement->SetGlobals(globals); - if (currentElement) - currentElement->SetGlobals(globals); -} - -bool cTemplateViewList::CalculateListParameters(void) { - if (!parameters) - return false; - bool paramsValid = false; - if (!listElement) - return false; - listElement->SetContainer(parameters->GetNumericParameter(ptX), - parameters->GetNumericParameter(ptY), - parameters->GetNumericParameter(ptWidth), - parameters->GetNumericParameter(ptHeight)); - paramsValid = listElement->CalculateParameters(); - paramsValid = listElement->CalculatePixmapParametersList(parameters->GetNumericParameter(ptOrientation), - parameters->GetNumericParameter(ptNumElements)); - if (!currentElement) - return paramsValid; - currentElement->SetContainer(parameters->GetNumericParameter(ptX), - parameters->GetNumericParameter(ptY), - parameters->GetNumericParameter(ptWidth), - parameters->GetNumericParameter(ptHeight)); - paramsValid = currentElement->CalculateParameters(); - paramsValid = currentElement->CalculatePixmapParameters(); - currentElement->SetPixOffset(0); - return paramsValid; -} - -bool cTemplateViewList::CalculateListParameters(map < string, int > *intTokens) { - if (!parameters) - return false; - parameters->ClearDynamicParameters(); - parameters->SetIntTokens(intTokens); - parameters->ParseParameters(); - parameters->UnsetIntTokens(); - - listElement->SetContainer(parameters->GetNumericParameter(ptX), - parameters->GetNumericParameter(ptY), - parameters->GetNumericParameter(ptWidth), - parameters->GetNumericParameter(ptHeight)); - bool paramsValid = listElement->CalculateParameters(); - paramsValid = listElement->CalculatePixmapParametersList(parameters->GetNumericParameter(ptOrientation), - parameters->GetNumericParameter(ptNumElements)); - return paramsValid; -} - -eOrientation cTemplateViewList::GetOrientation(void) { - if (!parameters) - return orNone; - int orientation = parameters->GetNumericParameter(ptOrientation); - return (eOrientation)orientation; -} - -int cTemplateViewList::GetAverageFontWidth(void) { - int defaultAverageFontWidth = 20; - - if (!listElement) - return defaultAverageFontWidth; - - int numItems = GetNumericParameter(ptNumElements); - int listHeight = GetNumericParameter(ptHeight); - if (listHeight <= 0) - return defaultAverageFontWidth; - int itemHeight = (double)listHeight / (double)numItems; - string fontFuncName = parameters->GetParameter(ptDeterminateFont); - - cTemplateFunction *fontFunc = listElement->GetFunction(fontFuncName); - if (!fontFunc) - return defaultAverageFontWidth; - - string fontNameToken = fontFunc->GetParameter(ptFont); - string paramFontSize = fontFunc->GetParameter(ptFontSize); - - string fontName = ""; - if (IsToken(fontNameToken)) { - if (!globals->GetFont(fontNameToken, fontName)) { - if (!globals->GetFont("{vdrOsd}", fontName)) { - return defaultAverageFontWidth; - } - } - } else { - //if no token, directly use input - fontName = fontNameToken; - } - - cNumericParameter pFontSize(paramFontSize); - pFontSize.SetGlobals(globals); - pFontSize.SetAreaSize(1000, itemHeight); - pFontSize.SetVertical(); - int fontSize = pFontSize.Parse(paramFontSize); - if (!pFontSize.Valid()) - return defaultAverageFontWidth; - - int averageFontWidth = fontManager->Width(fontName, fontSize, "x") + 3; - return averageFontWidth; -} - -cFont *cTemplateViewList::GetTextAreaFont(void) { - if (!listElement) - return NULL; - - int numItems = GetNumericParameter(ptNumElements); - int listHeight = GetNumericParameter(ptHeight); - if (listHeight <= 0) - return NULL; - int itemHeight = (double)listHeight / (double)numItems; - string fontFuncName = parameters->GetParameter(ptDeterminateFont); - - cTemplateFunction *fontFunc = listElement->GetFunction(fontFuncName); - if (!fontFunc) - return NULL; - - string fontNameToken = fontFunc->GetParameter(ptFont); - string paramFontSize = fontFunc->GetParameter(ptFontSize); - - string fontName = ""; - if (IsToken(fontNameToken)) { - if (!globals->GetFont(fontNameToken, fontName)) { - if (!globals->GetFont("{vdrOsd}", fontName)) { - return NULL; - } - } - } else { - //if no token, directly use input - fontName = fontNameToken; - } - - cNumericParameter pFontSize(paramFontSize); - pFontSize.SetGlobals(globals); - pFontSize.SetAreaSize(1000, itemHeight); - pFontSize.SetVertical(); - int fontSize = pFontSize.Parse(paramFontSize); - if (!pFontSize.Valid()) - return NULL; - - return fontManager->FontUncached(fontName, fontSize); -} - - -int cTemplateViewList::GetMenuItemWidth(void) { - return GetNumericParameter(ptMenuItemWidth); -} - - -int cTemplateViewList::GetNumPixmaps(void) { - if (!listElement) - return 0; - return listElement->GetNumPixmaps(); -} - -void cTemplateViewList::Debug(void) { - if (parameters) - parameters->Debug(); - esyslog("skindesigner: --- listelement: "); - if (listElement) - listElement->Debug(); - esyslog("skindesigner: --- currentelement: "); - if (currentElement) - currentElement->Debug(); -} \ No newline at end of file diff --git a/libtemplate/templateviewlist.h b/libtemplate/templateviewlist.h deleted file mode 100644 index 4cc4ccb..0000000 --- a/libtemplate/templateviewlist.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef __TEMPLATEVIEWLIST_H -#define __TEMPLATEVIEWLIST_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "templateviewelement.h" - -using namespace std; - -// --- cTemplateViewList ------------------------------------------------------------- - -enum eViewList { - vlUndefined, - vlMenuItem -}; - -class cTemplateViewList : public cTemplateViewElement { -private: - cTemplateViewElement *listElement; - cTemplateViewElement *currentElement; -public: - cTemplateViewList(void); - ~cTemplateViewList(void); - void SetGlobals(cGlobals *globals); - void AddListElement(cTemplateViewElement *listElement) { this->listElement = listElement; }; - void AddCurrentElement(cTemplateViewElement *currentElement) { this->currentElement = currentElement; }; - bool CalculateListParameters(void); - bool CalculateListParameters(map < string, int > *intTokens); - cTemplateViewElement *GetListElement(void) { return listElement; }; - cTemplateViewElement *GetListElementCurrent(void) { return currentElement; }; - eOrientation GetOrientation(void); - int GetAverageFontWidth(void); - cFont *GetTextAreaFont(void); - int GetMenuItemWidth(void); - int GetNumPixmaps(void); - void Debug(void); -}; - -#endif //__TEMPLATEVIEWLIST_H \ No newline at end of file diff --git a/libtemplate/templateviewtab.c b/libtemplate/templateviewtab.c deleted file mode 100644 index 1e9f463..0000000 --- a/libtemplate/templateviewtab.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "templateviewtab.h" - -cTemplateViewTab::cTemplateViewTab(void) : cTemplatePixmap() { - scrollStep = -1; -} - -cTemplateViewTab::~cTemplateViewTab(void) { -} - -int cTemplateViewTab::GetScrollStep(void) { - if (scrollStep > 0) - return scrollStep; - int pixWidth = GetNumericParameter(ptWidth); - int pixHeight = GetNumericParameter(ptHeight); - string scrollHeight = parameters->GetParameter(ptScrollHeight); - - cNumericParameter p(scrollHeight); - p.SetAreaSize(pixWidth, pixHeight); - string parsedValue = ""; - scrollStep = p.Parse(parsedValue); - if (scrollStep < 1) - scrollStep = 50; - return scrollStep; -} - -string cTemplateViewTab::GetName(void) { - return parameters->GetParameter(ptName); -} - -void cTemplateViewTab::SetName(string trans) { - parameters->SetParameter(ptName, trans); -} - -void cTemplateViewTab::Debug(void) { - esyslog("skindesigner: cTemplateViewTab Debug %s", GetName().c_str()); - cTemplatePixmap::Debug(); - esyslog("skindesigner: -------------------------------------------------------"); -} diff --git a/libtemplate/templateviewtab.h b/libtemplate/templateviewtab.h deleted file mode 100644 index 8514cad..0000000 --- a/libtemplate/templateviewtab.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __TEMPLATEVIEWTAB_H -#define __TEMPLATEVIEWTAB_H - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "templatepixmap.h" - -using namespace std; - -// --- cTemplateViewTab ------------------------------------------------------------- - -class cTemplateViewTab : public cTemplatePixmap { -private: - int scrollStep; -public: - cTemplateViewTab(void); - ~cTemplateViewTab(void); - int GetScrollStep(void); - string GetName(void); - void SetName(string trans); - void Debug(void); -}; - -#endif //__TEMPLATEVIEWTAB_H \ No newline at end of file diff --git a/po/de_DE.po b/po/de_DE.po index a46d874..b5db7ab 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-skindesigner 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-08-14 17:20+0200\n" +"POT-Creation-Date: 2016-01-20 18:31+0100\n" "PO-Revision-Date: 2014-09-27 11:02+0200\n" "Last-Translator: Louis Braun \n" "Language-Team: \n" @@ -46,7 +46,7 @@ msgid "at one go" msgstr "alle auf einmal" msgid "Downloading Skin Screenshots..." -msgstr "Lade Screenshots herunter..." +msgstr "" msgid "Install Skin" msgstr "Installiere Skin" @@ -84,11 +84,8 @@ msgstr "Skin gelöscht" msgid "Plugin Setup" msgstr "" -msgid "Menu Item display method" -msgstr "Art der Ausgabe der Menüelemente" - -msgid "Frames per Second (fading and shifting)" -msgstr "Frames pro Sekunde (fading und shifting)" +msgid "Maximum number of custom tokens" +msgstr "Maximale Anzahl Custom Tokens" msgid "Reruns" msgstr "Wiederholungen" @@ -111,6 +108,9 @@ msgstr "Bilder" msgid "Debug Image Loading" msgstr "Debugausgabe für das Laden der Bilder" +msgid "Cache icons, skinparts and logos at start" +msgstr "Icons, Skinparts und Logos beim Start cachen" + msgid "Limit Channel Logo Cache" msgstr "Größe des Kanallogo Caches bechränken" @@ -132,8 +132,14 @@ msgstr "Icons" msgid "size" msgstr "Größe" -msgid "byte" -msgstr "Byte" +msgid "MB" +msgstr "" + +msgid "int. memory" +msgstr "int. Speicher" + +msgid "high level memory" +msgstr "High Level Speicher" msgid "logos" msgstr "Logos" @@ -163,7 +169,7 @@ msgid "Author" msgstr "Autor" msgid "Used Fonts" -msgstr "Benutze Schriften" +msgstr "Benutze Schriftarten" msgid "Supported Plugins" msgstr "Unterstützte Plugins" diff --git a/po/fi_FI.po b/po/fi_FI.po index 12b3ed7..fb5754b 100644 --- a/po/fi_FI.po +++ b/po/fi_FI.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-skindesigner 0.2.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-08-14 17:20+0200\n" +"POT-Creation-Date: 2016-01-20 18:31+0100\n" "PO-Revision-Date: 2015-01-25 01:25+0200\n" "Last-Translator: Rolf Ahrenberg\n" "Language-Team: Finnish\n" @@ -84,10 +84,7 @@ msgstr "" msgid "Plugin Setup" msgstr "Yleiset" -msgid "Menu Item display method" -msgstr "Valikkorivien esitystapa" - -msgid "Frames per Second (fading and shifting)" +msgid "Maximum number of custom tokens" msgstr "" msgid "Reruns" @@ -111,6 +108,9 @@ msgstr "Kuvat" msgid "Debug Image Loading" msgstr "Debuggaa kuvien latausta" +msgid "Cache icons, skinparts and logos at start" +msgstr "" + msgid "Limit Channel Logo Cache" msgstr "Rajoita kanavalogojen välimuistia" @@ -132,8 +132,14 @@ msgstr "ikoni(a)" msgid "size" msgstr "koko" -msgid "byte" -msgstr "tavu(a)" +msgid "MB" +msgstr "" + +msgid "int. memory" +msgstr "" + +msgid "high level memory" +msgstr "" msgid "logos" msgstr "logo(a)" @@ -167,3 +173,9 @@ msgstr "" msgid "Supported Plugins" msgstr "" + +#~ msgid "byte" +#~ msgstr "tavu(a)" + +#~ msgid "Menu Item display method" +#~ msgstr "Valikkorivien esitystapa" diff --git a/setup.c b/setup.c index 3b6c432..bc7318f 100644 --- a/setup.c +++ b/setup.c @@ -1,5 +1,5 @@ #include -#include "libcore/curlfuncs.h" +#include "extensions/curlfuncs.h" #include #include "setup.h" @@ -119,16 +119,17 @@ eOSState cInstallManager::ProcessInstallationStatus(void) { } // --- cSkinDesignerSetup ----------------------------------------------------------- -cSkinDesignerSetup::cSkinDesignerSetup() { +cSkinDesignerSetup::cSkinDesignerSetup(skindesignerapi::cPluginStructure *skinPreviewStruct) { + this->skinPreviewStruct = skinPreviewStruct; numLogosPerSizeInitial = config.numLogosPerSizeInitial; + cacheImagesInitial = config.cacheImagesInitial; limitLogoCache = config.limitLogoCache; numLogosMax = config.numLogosMax; debugImageLoading = config.debugImageLoading; rerunAmount = config.rerunAmount; rerunDistance = config.rerunDistance; rerunMaxChannel = config.rerunMaxChannel; - blockFlush = config.blockFlush; - framesPerSecond = config.framesPerSecond; + numCustomTokens = config.numCustomTokens; menuDisplayStyle[0] = tr("after one another"); menuDisplayStyle[1] = tr("at one go"); Setup(); @@ -179,7 +180,7 @@ eOSState cSkinDesignerSetup::ProcessKey(eKeys Key) { state = osContinue; } else if (type == itSkinRepo) { Skins.Message(mtStatus, tr("Downloading Skin Screenshots...")); - cSkindesignerSkinPreview *prev = new cSkindesignerSkinPreview(currentSkin); + cSkindesignerSkinPreview *prev = new cSkindesignerSkinPreview(currentSkin, skinPreviewStruct); Skins.Message(mtStatus, NULL); state = AddSubMenu(prev); } @@ -254,14 +255,14 @@ eOSState cSkinDesignerSetup::ProcessKey(eKeys Key) { void cSkinDesignerSetup::Store(void) { config.numLogosPerSizeInitial = numLogosPerSizeInitial; + config.cacheImagesInitial = cacheImagesInitial; config.limitLogoCache = limitLogoCache; config.numLogosMax = numLogosMax; config.debugImageLoading = debugImageLoading; config.rerunAmount = rerunAmount; config.rerunDistance = rerunDistance; config.rerunMaxChannel = rerunMaxChannel; - config.blockFlush = blockFlush; - config.framesPerSecond = framesPerSecond; + config.numCustomTokens = numCustomTokens; config.InitSetupIterator(); cSkinSetup *skinSetup = NULL; @@ -278,14 +279,14 @@ void cSkinDesignerSetup::Store(void) { config.UpdateGlobals(); SetupStore("DebugImageLoading", debugImageLoading); + SetupStore("CacheImagesInitial", cacheImagesInitial); SetupStore("LimitChannelLogoCache", limitLogoCache); SetupStore("NumberLogosInitially", numLogosPerSizeInitial); SetupStore("NumberLogosMax", numLogosMax); SetupStore("RerunAmount", rerunAmount); SetupStore("RerunDistance", rerunDistance); SetupStore("RerunMaxChannel", rerunMaxChannel); - SetupStore("BlockFlush", blockFlush); - SetupStore("FramesPerSecond", framesPerSecond); + SetupStore("NumCustomTokens", numCustomTokens); } cOsdItem *cSkinDesignerSetup::InfoItem(const char *label) { @@ -298,8 +299,7 @@ cOsdItem *cSkinDesignerSetup::InfoItem(const char *label) { void cSkinDesignerSetup::PluginSetup(void) { Add(InfoItem(tr("Plugin Setup"))); - Add(new cMenuEditStraItem(tr("Menu Item display method"), &blockFlush, 2, menuDisplayStyle)); - Add(new cMenuEditIntItem(tr("Frames per Second (fading and shifting)"), &framesPerSecond, 10, 100)); + Add(new cMenuEditIntItem(tr("Maximum number of custom tokens"), &numCustomTokens, 0, 100)); Add(InfoItem(tr("Reruns"))); Add(new cMenuEditIntItem(tr("Maximum number of reruns to display"), &rerunAmount, 1, 100)); @@ -308,6 +308,7 @@ void cSkinDesignerSetup::PluginSetup(void) { Add(InfoItem(tr("Image Loading"))); Add(new cMenuEditBoolItem(tr("Debug Image Loading"), &debugImageLoading)); + Add(new cMenuEditBoolItem(tr("Cache icons, skinparts and logos at start"), &cacheImagesInitial)); Add(new cMenuEditBoolItem(tr("Limit Channel Logo Cache"), &limitLogoCache)); Add(new cMenuEditIntItem(tr("Number to cache initially (per size)"), &numLogosPerSizeInitial, 0, 1000)); Add(new cMenuEditIntItem(tr("Number to cache in maximum"), &numLogosMax, 0, 1000)); @@ -319,24 +320,26 @@ void cSkinDesignerSetup::ImageCacheStatistics(void) { } Add(InfoItem(tr("Cache Statistics"))); - int sizeIconCache = 0; + float sizeIconCacheInt = 0; + float sizeIconCacheExt = 0; int numIcons = 0; - imgCache->GetIconCacheSize(numIcons, sizeIconCache); - cString iconCacheInfo = cString::sprintf("%s %d %s - %s %d %s", tr("cached"), numIcons, tr("icons"), tr("size"), sizeIconCache, tr("byte")); + imgCache->GetIconCacheSize(numIcons, sizeIconCacheInt, sizeIconCacheExt); + cString iconCacheInfo = cString::sprintf("%s %d %s - %s %.2f%s %s, %.2f%s %s", tr("cached"), numIcons, tr("icons"), tr("size"), sizeIconCacheInt, tr("MB"), tr("int. memory"), sizeIconCacheExt, tr("MB"), tr("high level memory")); Add(new cOsdItem(*iconCacheInfo)); cList::Last()->SetSelectable(false); - int sizeLogoCache = 0; + float sizeLogoCache = 0; int numLogos = 0; imgCache->GetLogoCacheSize(numLogos, sizeLogoCache); - cString logoCacheInfo = cString::sprintf("%s %d %s - %s %d %s", tr("cached"), numLogos, tr("logos"), tr("size"), sizeLogoCache, tr("byte")); + cString logoCacheInfo = cString::sprintf("%s %d %s - %s %.2f%s %s", tr("cached"), numLogos, tr("logos"), tr("size"), sizeLogoCache, tr("MB"), tr("int. memory")); Add(new cOsdItem(*logoCacheInfo)); cList::Last()->SetSelectable(false); - int sizeSkinpartCache = 0; + float sizeSkinpartCacheInt = 0; + float sizeSkinpartCacheExt = 0; int numSkinparts = 0; - imgCache->GetSkinpartsCacheSize(numSkinparts, sizeSkinpartCache); - cString skinpartCacheInfo = cString::sprintf("%s %d %s - %s %d %s", tr("cached"), numSkinparts, tr("skinparts"), tr("size"), sizeSkinpartCache, tr("byte")); + imgCache->GetSkinpartsCacheSize(numSkinparts, sizeSkinpartCacheInt, sizeSkinpartCacheExt); + cString skinpartCacheInfo = cString::sprintf("%s %d %s - %s %.2f%s %s, %.2f%s %s", tr("cached"), numSkinparts, tr("skinparts"), tr("MB"), sizeSkinpartCacheInt, tr("MB"), tr("int. memory"), sizeSkinpartCacheExt, tr("MB"), tr("high level memory")); Add(new cOsdItem(*skinpartCacheInfo)); cList::Last()->SetSelectable(false); } @@ -518,10 +521,9 @@ void cSkindesignerSkinSetup::ShowButtons(int current, bool force) { // --- cSkindesignerSkinPreview ----------------------------------------------------------- -cSkindesignerSkinPreview::cSkindesignerSkinPreview(string skinName) : -cSkindesignerOsdMenu(*cString::sprintf("%s: %s \"%s\"", trVDR("Preview"), tr("Skin"), skinName.c_str())) { - currentSkin = skinName; - SetPluginName("setup"); +cSkindesignerSkinPreview::cSkindesignerSkinPreview(string skin, skindesignerapi::cPluginStructure *plugStruct) : +cSkindesignerOsdMenu(plugStruct, *cString::sprintf("%s: %s \"%s\"", trVDR("Preview"), tr("Skin"), skin.c_str())) { + currentSkin = skin; FirstCallCleared(); Set(); } @@ -584,64 +586,89 @@ void cSkindesignerSkinPreview::Display(void) { void cSkindesignerSkinPreview::Set(void) { SetPluginMenu(0, skindesignerapi::mtText); - ClearTokens(); Clear(); + skindesignerapi::cTokenContainer *tk = GetTokenContainer(0); + SetTokenContainer(tk); + ClearTokens(); + cSkinRepo *skinRepo = config.GetSkinRepo(currentSkin); if (!skinRepo) { esyslog("skindesigner: no valid skin repository found for skin %s", currentSkin.c_str()); return; } - AddStringToken("menuheader", *cString::sprintf("%s: %s \"%s\"", trVDR("Preview"), tr("Skin"), currentSkin.c_str())); - AddStringToken("skinname", currentSkin); - AddStringToken("author", skinRepo->Author()); + + int fontsIndex = GetLoopIndex("fonts"); + int pluginIndex = GetLoopIndex("plugins"); + int screenshotIndex = GetLoopIndex("screenshots"); + + vector *specialFonts = skinRepo->SpecialFonts(); + vector *supportedPlugins = skinRepo->SupportedPlugins(); + vector< pair < string, string > > *screenshots = skinRepo->Screenshots(); + + vector loopInfo; + loopInfo.push_back((int)specialFonts->size()); + loopInfo.push_back((int)supportedPlugins->size()); + loopInfo.push_back((int)screenshots->size()); + SetLoop(loopInfo); + + AddStringToken((int)eDmSkinPreviewST::menuheader, *cString::sprintf("%s: %s \"%s\"", trVDR("Preview"), tr("Skin"), currentSkin.c_str())); + AddStringToken((int)eDmSkinPreviewST::skinname, currentSkin.c_str()); + AddStringToken((int)eDmSkinPreviewST::author, skinRepo->Author().c_str()); stringstream plainText; plainText << *cString::sprintf("%s: %s \"%s\"", trVDR("Preview"), tr("Skin"), currentSkin.c_str()) << "\n\n"; plainText << tr("Author") << ": " << skinRepo->Author() << "\n"; - plainText << tr("Used Fonts") << ": \n"; - vector specialFonts = skinRepo->SpecialFonts(); - for (vector::iterator it = specialFonts.begin(); it != specialFonts.end(); it++) { - map usedFonts; - usedFonts.insert(pair("fonts[name]", *it)); - usedFonts.insert(pair("fonts[installed]", CheckFontInstalled(*it))); - AddLoopToken("fonts", usedFonts); + + int i = 0; + for (vector::iterator it = specialFonts->begin(); it != specialFonts->end(); it++) { + AddLoopToken(fontsIndex, i, (int)eDmSkinPreviewFontsLT::name, (*it).c_str()); + AddLoopToken(fontsIndex, i, (int)eDmSkinPreviewFontsLT::installed, CheckFontInstalled(*it)); plainText << *it << "\n"; + i++; } plainText << tr("Supported Plugins") << ": \n"; - vector supportedPlugins = skinRepo->SupportedPlugins(); - for (vector::iterator it = supportedPlugins.begin(); it != supportedPlugins.end(); it++) { - map plugins; - plugins.insert(pair("plugins[name]", *it)); - AddLoopToken("plugins", plugins); + i = 0; + for (vector::iterator it = supportedPlugins->begin(); it != supportedPlugins->end(); it++) { + AddLoopToken(pluginIndex, i, (int)eDmSkinPreviewPluginsLT::name, (*it).c_str()); plainText << *it << "\n"; + i++; } SetText(plainText.str().c_str()); - vector< pair < string, string > > screenshots = skinRepo->Screenshots(); - int i = 0; - for (vector< pair < string, string > >::iterator it = screenshots.begin(); it != screenshots.end(); it++) { + i = 0; + for (vector< pair < string, string > >::iterator it = screenshots->begin(); it != screenshots->end(); it++) { string url = it->second; string imgType = ".jpg"; if (url.find(".png") != string::npos) imgType = ".png"; - stringstream tempName; - tempName << "/tmp/screenshot_" << currentSkin << "_" << i++ << imgType; - dsyslog("skindesigner: download screenshot name %s url %s", tempName.str().c_str(), url.c_str()); - CurlGetUrlFile(url.c_str(), tempName.str().c_str()); - map img; - img.insert(pair("screenshots[desc]", it->first)); - img.insert(pair("screenshots[path]", tempName.str())); - AddLoopToken("screenshots", img); + cString tempName = cString::sprintf("/tmp/screenshot_%s_%d%s", currentSkin.c_str(), i, imgType.c_str()); + dsyslog("skindesigner: download screenshot name %s url %s", *tempName, url.c_str()); + CurlGetUrlFile(url.c_str(), *tempName); + AddLoopToken(screenshotIndex, i, (int)eDmSkinPreviewScreenshotsLT::desc, (it->first).c_str()); + AddLoopToken(screenshotIndex, i, (int)eDmSkinPreviewScreenshotsLT::path, *tempName); + i++; } } -string cSkindesignerSkinPreview::CheckFontInstalled(string fontName) { +void cSkindesignerSkinPreview::DefineTokens(skindesignerapi::cTokenContainer *tk) { + tk->DefineStringToken("{menuheader}", (int)eDmSkinPreviewST::menuheader); + tk->DefineStringToken("{skinname}", (int)eDmSkinPreviewST::skinname); + tk->DefineStringToken("{author}", (int)eDmSkinPreviewST::author); + tk->DefineLoopToken("{fonts[name]}", (int)eDmSkinPreviewFontsLT::name); + tk->DefineLoopToken("{fonts[installed]}", (int)eDmSkinPreviewFontsLT::installed); + tk->DefineLoopToken("{plugins[name]}", (int)eDmSkinPreviewPluginsLT::name); + tk->DefineLoopToken("{screenshots[desc]}", (int)eDmSkinPreviewScreenshotsLT::desc); + tk->DefineLoopToken("{screenshots[path]}", (int)eDmSkinPreviewScreenshotsLT::path); +} + +const char *cSkindesignerSkinPreview::CheckFontInstalled(string fontName) { if (fontManager->FontInstalled(fontName)) return "1"; return "0"; } + diff --git a/setup.h b/setup.h index 5bf5c14..2147ad6 100644 --- a/setup.h +++ b/setup.h @@ -38,15 +38,16 @@ public: // --- cSkinDesignerSetup ----------------------------------------------------------- class cSkinDesignerSetup : public cMenuSetupPage, cInstallManager { private: + skindesignerapi::cPluginStructure *skinPreviewStruct; int numLogosPerSizeInitial; + int cacheImagesInitial; int limitLogoCache; int numLogosMax; int debugImageLoading; int rerunAmount; int rerunDistance; int rerunMaxChannel; - int blockFlush; - int framesPerSecond; + int numCustomTokens; const char *menuDisplayStyle[2]; void Setup(void); virtual void Store(void); @@ -57,7 +58,7 @@ private: void SkinSetup(void); void InstallSkins(void); public: - cSkinDesignerSetup(void); + cSkinDesignerSetup(skindesignerapi::cPluginStructure *skinPreviewStruct); virtual ~cSkinDesignerSetup(void); }; @@ -110,16 +111,15 @@ public: }; // --- cSkindesignerSkinPreview ----------------------------------------------------------- - class cSkindesignerSkinPreview : public skindesignerapi::cSkindesignerOsdMenu, cInstallManager { protected: virtual eOSState ProcessKey(eKeys Key); void Set(void); - string CheckFontInstalled(string fontName); + const char *CheckFontInstalled(string fontName); public: - cSkindesignerSkinPreview(string skin); + cSkindesignerSkinPreview(string skin, skindesignerapi::cPluginStructure *plugStruct); virtual ~cSkindesignerSkinPreview(); + static void DefineTokens(skindesignerapi::cTokenContainer *tk); void Display(void); }; - #endif //__SKINDESIGNER_SETUP_H \ No newline at end of file diff --git a/skindesigner.c b/skindesigner.c index de93231..c6049bb 100644 --- a/skindesigner.c +++ b/skindesigner.c @@ -7,28 +7,29 @@ */ #include #include -#include "libskindesignerapi/skindesignerapi.h" #define DEFINE_CONFIG 1 #include "config.h" #include "designer.h" #include "setup.h" +#include "libskindesignerapi/skindesignerapi.h" #if defined(APIVERSNUM) && APIVERSNUM < 20000 #error "VDR-2.0.0 API version or greater is required!" #endif -static const char *VERSION = "0.7.2"; +static const char *VERSION = "0.8.0"; static const char *DESCRIPTION = trNOOP("Skin Designer"); class cPluginSkinDesigner : public cPlugin, public skindesignerapi::SkindesignerAPI { private: string libskindesignerApiVersion; + skindesignerapi::cPluginStructure *skinPreviewStruct; protected: bool ServiceRegisterPlugin(skindesignerapi::cPluginStructure *plugStructure); skindesignerapi::ISDDisplayMenu *ServiceGetDisplayMenu(void); - skindesignerapi::ISkinDisplayPlugin *ServiceGetDisplayPlugin(string pluginName, int viewID, int subViewID); + skindesignerapi::ISkinDisplayPlugin *ServiceGetDisplayPlugin(int plugId); public: cPluginSkinDesigner(void); virtual ~cPluginSkinDesigner(); @@ -55,9 +56,11 @@ public: cPluginSkinDesigner::cPluginSkinDesigner(void) { libskindesignerApiVersion = "undefined"; config.SetVersion(VERSION); + skinPreviewStruct = NULL; } cPluginSkinDesigner::~cPluginSkinDesigner() { + delete skinPreviewStruct; } const char *cPluginSkinDesigner::CommandLineHelp(void) { @@ -115,15 +118,19 @@ bool cPluginSkinDesigner::Start(void) { } else dsyslog("skindesigner: TrueColor OSD found"); + plgManager = new cSDPluginManager(); libskindesignerApiVersion = LIBSKINDESIGNERAPIVERSION; dsyslog("skindesigner: using libskindesigner API Version %s", libskindesignerApiVersion.c_str()); - //register template for skin preview page - skindesignerapi::cPluginStructure plugStruct; - plugStruct.name = "setup"; - plugStruct.libskindesignerAPIVersion = LIBSKINDESIGNERAPIVERSION; - plugStruct.SetMenu(0, "skinpreview.xml"); - ServiceRegisterPlugin(&plugStruct); + skinPreviewStruct = new skindesignerapi::cPluginStructure(); + skinPreviewStruct->name = "setup"; + skinPreviewStruct->libskindesignerAPIVersion = LIBSKINDESIGNERAPIVERSION; + skindesignerapi::cTokenContainer *tkSkinPreview = new skindesignerapi::cTokenContainer(); + cSkindesignerSkinPreview::DefineTokens(tkSkinPreview); + skinPreviewStruct->RegisterMenu(0, skindesignerapi::mtText, "skinpreview.xml", tkSkinPreview); + if (RegisterPlugin(skinPreviewStruct)) { + dsyslog("skindesigner: skinsetup template successfully registered at skindesigner, id %d", skinPreviewStruct->id); + } config.SetOsdLanguage(); config.SetPathes(); @@ -153,6 +160,7 @@ bool cPluginSkinDesigner::Start(void) { void cPluginSkinDesigner::Stop(void) { delete imgCache; delete fontManager; + delete plgManager; cXmlParser::CleanupLibXML(); } @@ -175,7 +183,7 @@ cOsdObject *cPluginSkinDesigner::MainMenuAction(void) { } cMenuSetupPage *cPluginSkinDesigner::SetupMenu(void) { - return new cSkinDesignerSetup(); + return new cSkinDesignerSetup(skinPreviewStruct); } bool cPluginSkinDesigner::SetupParse(const char *Name, const char *Value) { @@ -190,8 +198,10 @@ const char **cPluginSkinDesigner::SVDRPHelpPages(void) { static const char *HelpPages[] = { "RELD\n" " force reload of templates and caches", - "SCTK\n" - " Set custom Token name = value", + "SCIT\n" + " Set custom Integer Token key = value", + "SCST\n" + " Set custom String Token key = value", "LCTK\n" " List custom Tokens", "LSTF\n" @@ -236,18 +246,31 @@ cString cPluginSkinDesigner::SVDRPCommand(const char *Command, const char *Optio activeSkin->ListAvailableFonts(); ReplyCode = 250; return "SKINDESIGNER available fonts listed in syslog."; - } else if (strcasecmp(Command, "SCTK") == 0) { + } else if (strcasecmp(Command, "SCIT") == 0) { if (!Option) { ReplyCode = 501; - return "SKINDESIGNER SCTK Error: no Token name = value set"; + return "SKINDESIGNER SCIK Error: no Token name = value set"; } - bool optionOk = activeSkin->SetCustomToken(Option); + bool optionOk = activeSkin->SetCustomIntToken(Option); if (optionOk) { ReplyCode = 250; - return cString::sprintf("SKINDESIGNER Set custom Token %s", Option); + return cString::sprintf("SKINDESIGNER Set custom Int Token %s", Option); } else { ReplyCode = 501; - return cString::sprintf("SKINDESIGNER Invalid custom Token %s", Option); + return cString::sprintf("SKINDESIGNER Invalid custom Int Token %s", Option); + } + } else if (strcasecmp(Command, "SCST") == 0) { + if (!Option) { + ReplyCode = 501; + return "SKINDESIGNER SCSK Error: no Token name = value set"; + } + bool optionOk = activeSkin->SetCustomStringToken(Option); + if (optionOk) { + ReplyCode = 250; + return cString::sprintf("SKINDESIGNER Set custom String Token %s", Option); + } else { + ReplyCode = 501; + return cString::sprintf("SKINDESIGNER Invalid custom String Token %s", Option); } } else if (strcasecmp(Command, "LCTK") == 0) { activeSkin->ListCustomTokens(); @@ -258,18 +281,18 @@ cString cPluginSkinDesigner::SVDRPCommand(const char *Command, const char *Optio return ""; } + bool cPluginSkinDesigner::ServiceRegisterPlugin(skindesignerapi::cPluginStructure *plugStructure) { - if (plugStructure->menus.size() < 1 && plugStructure->views.size() < 1) { + if (plugStructure->menus.size() < 1 && plugStructure->rootview.size() < 1) { esyslog("skindesigner: error - plugin without menus or views registered"); return false; } - dsyslog("skindesigner: plugin %s uses libskindesigner API Version %s", plugStructure->name.c_str(), plugStructure->libskindesignerAPIVersion.c_str()); - config.AddPluginMenus(plugStructure->name, plugStructure->menus); - config.AddPluginViews(plugStructure->name, plugStructure->views, plugStructure->subViews, plugStructure->viewElements, plugStructure->viewGrids); + //basic plugin interface if (plugStructure->menus.size() > 0) - dsyslog("skindesigner: plugin %s has registered %ld menus", plugStructure->name.c_str(), plugStructure->menus.size()); - if (plugStructure->views.size() > 0) - dsyslog("skindesigner: plugin %s has registered %ld views", plugStructure->name.c_str(), plugStructure->views.size()); + plgManager->RegisterBasicPlugin(plugStructure); + //advanced plugin interface + if (plugStructure->rootview.size() > 0) + plgManager->RegisterAdvancedPlugin(plugStructure); return true; } @@ -290,20 +313,13 @@ skindesignerapi::ISDDisplayMenu *cPluginSkinDesigner::ServiceGetDisplayMenu(void return NULL; } -skindesignerapi::ISkinDisplayPlugin *cPluginSkinDesigner::ServiceGetDisplayPlugin(string pluginName, int viewID, int subViewID) { - if (pluginName.size() == 0 || viewID < 0) - return NULL; +skindesignerapi::ISkinDisplayPlugin *cPluginSkinDesigner::ServiceGetDisplayPlugin(int plugId) { cSkin *current = Skins.Current(); cSkinDesigner *availableSkin = NULL; config.InitSkinRefsIterator(); while (availableSkin = config.GetNextSkinRef()) { if (availableSkin == current) { - cSkinDisplayPlugin *displayPlugin = availableSkin->DisplayPlugin(pluginName, viewID, subViewID); - if (displayPlugin) { - return displayPlugin; - } else { - return NULL; - } + return availableSkin->GetDisplayPlugin(plugId); } } return NULL; diff --git a/skins/metrixhd/xmlfiles/displaychannel.xml b/skins/metrixhd/xmlfiles/displaychannel.xml index 9817b9d..3a68bc9 100644 --- a/skins/metrixhd/xmlfiles/displaychannel.xml +++ b/skins/metrixhd/xmlfiles/displaychannel.xml @@ -4,7 +4,7 @@ - + @@ -61,8 +61,8 @@ - - + + @@ -100,10 +100,7 @@ - - - - + @@ -121,7 +118,7 @@ - + @@ -138,16 +135,16 @@ - + - + - + @@ -172,7 +169,4 @@ - - - diff --git a/skins/metrixhd/xmlfiles/displaymenu.xml b/skins/metrixhd/xmlfiles/displaymenu.xml index 53b70fb..da903ba 100644 --- a/skins/metrixhd/xmlfiles/displaymenu.xml +++ b/skins/metrixhd/xmlfiles/displaymenu.xml @@ -12,11 +12,11 @@ ]> - + - + @@ -64,7 +64,7 @@ - + @@ -74,7 +74,7 @@ - + @@ -84,7 +84,7 @@ - + @@ -94,7 +94,7 @@ - + @@ -105,6 +105,14 @@ + + + + + + + + &displaymenudefault; &displaymenumain; &displaymenusetup; diff --git a/skins/metrixhd/xmlfiles/displaymenuchannels.xml b/skins/metrixhd/xmlfiles/displaymenuchannels.xml index 5b3a184..21999fc 100644 --- a/skins/metrixhd/xmlfiles/displaymenuchannels.xml +++ b/skins/metrixhd/xmlfiles/displaymenuchannels.xml @@ -17,7 +17,7 @@ - + diff --git a/skins/metrixhd/xmlfiles/displaymenudetailtext.xml b/skins/metrixhd/xmlfiles/displaymenudetailtext.xml index 08c37b2..81600bd 100644 --- a/skins/metrixhd/xmlfiles/displaymenudetailtext.xml +++ b/skins/metrixhd/xmlfiles/displaymenudetailtext.xml @@ -4,6 +4,11 @@ +
+ + + +
diff --git a/skins/metrixhd/xmlfiles/displaymenumain.xml b/skins/metrixhd/xmlfiles/displaymenumain.xml index 7bd8e33..f9dd6c6 100644 --- a/skins/metrixhd/xmlfiles/displaymenumain.xml +++ b/skins/metrixhd/xmlfiles/displaymenumain.xml @@ -1,4 +1,4 @@ - + @@ -9,6 +9,19 @@ + + + + + + + + + + + + +
@@ -70,7 +83,7 @@ - + @@ -109,16 +122,15 @@ - + - + - @@ -128,11 +140,7 @@ - - - - - + @@ -145,7 +153,7 @@ - + @@ -163,19 +171,13 @@ - - - - + - - - - + @@ -185,7 +187,7 @@ - + @@ -195,7 +197,7 @@ - + @@ -209,7 +211,15 @@ - + + + + + + + + + @@ -217,11 +227,5 @@ - - - - - - - + diff --git a/skins/metrixhd/xmlfiles/displaymenurecordings.xml b/skins/metrixhd/xmlfiles/displaymenurecordings.xml index 9cef713..276c10f 100644 --- a/skins/metrixhd/xmlfiles/displaymenurecordings.xml +++ b/skins/metrixhd/xmlfiles/displaymenurecordings.xml @@ -1,6 +1,6 @@ - + - + @@ -13,7 +13,7 @@ -
+
@@ -22,7 +22,7 @@
- + @@ -33,7 +33,7 @@ - + @@ -43,13 +43,13 @@ - + + - @@ -65,7 +65,7 @@ - + @@ -80,27 +80,27 @@ - + + - - + - - - + + + - + @@ -119,15 +119,7 @@ - - - - - - - - - + @@ -135,7 +127,15 @@ - + + + + + + + + + diff --git a/skins/metrixhd/xmlfiles/displaymenuschedules.xml b/skins/metrixhd/xmlfiles/displaymenuschedules.xml index b32ea99..a592e76 100644 --- a/skins/metrixhd/xmlfiles/displaymenuschedules.xml +++ b/skins/metrixhd/xmlfiles/displaymenuschedules.xml @@ -21,7 +21,7 @@ - + @@ -88,8 +88,8 @@ - - + + @@ -103,7 +103,7 @@ - + @@ -132,11 +132,4 @@ - - - - - - - diff --git a/skins/metrixhd/xmlfiles/displaymenusetup.xml b/skins/metrixhd/xmlfiles/displaymenusetup.xml index 4e2ae0f..0bd8aa2 100644 --- a/skins/metrixhd/xmlfiles/displaymenusetup.xml +++ b/skins/metrixhd/xmlfiles/displaymenusetup.xml @@ -54,7 +54,7 @@ - + diff --git a/skins/metrixhd/xmlfiles/displaymenutimers.xml b/skins/metrixhd/xmlfiles/displaymenutimers.xml index b9be696..7d65f64 100644 --- a/skins/metrixhd/xmlfiles/displaymenutimers.xml +++ b/skins/metrixhd/xmlfiles/displaymenutimers.xml @@ -15,7 +15,7 @@ - + diff --git a/skins/metrixhd/xmlfiles/displaymessage.xml b/skins/metrixhd/xmlfiles/displaymessage.xml index 1ab2bd5..04be966 100644 --- a/skins/metrixhd/xmlfiles/displaymessage.xml +++ b/skins/metrixhd/xmlfiles/displaymessage.xml @@ -1,7 +1,7 @@ - + diff --git a/skins/metrixhd/xmlfiles/displayreplay.xml b/skins/metrixhd/xmlfiles/displayreplay.xml index d2fa71b..4842c39 100644 --- a/skins/metrixhd/xmlfiles/displayreplay.xml +++ b/skins/metrixhd/xmlfiles/displayreplay.xml @@ -1,17 +1,12 @@ - + - - - - - @@ -21,7 +16,11 @@ - + + + + + @@ -31,7 +30,7 @@ - + @@ -183,13 +182,13 @@ - + - + diff --git a/skins/metrixhd/xmlfiles/displayvolume.xml b/skins/metrixhd/xmlfiles/displayvolume.xml index db78bde..814bacd 100644 --- a/skins/metrixhd/xmlfiles/displayvolume.xml +++ b/skins/metrixhd/xmlfiles/displayvolume.xml @@ -1,7 +1,7 @@ - + diff --git a/skins/metrixhd/xmlfiles/plug-tvguideng-recmenu.xml b/skins/metrixhd/xmlfiles/plug-tvguideng-recmenu.xml index 058f1f5..21ae64c 100644 --- a/skins/metrixhd/xmlfiles/plug-tvguideng-recmenu.xml +++ b/skins/metrixhd/xmlfiles/plug-tvguideng-recmenu.xml @@ -60,17 +60,17 @@ - + - - + + - + @@ -80,16 +80,16 @@ - + - + - + @@ -176,7 +176,7 @@ - + @@ -191,7 +191,7 @@ - + @@ -208,13 +208,13 @@ - - + + - + @@ -241,30 +241,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + @@ -280,7 +280,7 @@ - + diff --git a/skins/metrixhd/xmlfiles/plug-tvguideng-root.xml b/skins/metrixhd/xmlfiles/plug-tvguideng-root.xml index 442c921..9914a80 100644 --- a/skins/metrixhd/xmlfiles/plug-tvguideng-root.xml +++ b/skins/metrixhd/xmlfiles/plug-tvguideng-root.xml @@ -30,8 +30,8 @@ - - + + @@ -282,7 +282,7 @@ - + diff --git a/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecast.xml b/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecast.xml index 08b85ab..078353c 100644 --- a/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecast.xml +++ b/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecast.xml @@ -1,8 +1,8 @@ - - + + @@ -10,7 +10,7 @@ - + @@ -42,7 +42,13 @@ - + + + + + + + @@ -53,7 +59,7 @@ - + @@ -88,7 +94,7 @@ - + @@ -99,7 +105,7 @@ - + diff --git a/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetailcurrent.xml b/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetailcurrent.xml index 365abf7..52746ca 100644 --- a/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetailcurrent.xml +++ b/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetailcurrent.xml @@ -8,7 +8,7 @@ -
+
diff --git a/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetaildaily.xml b/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetaildaily.xml index 802fa90..52f027d 100644 --- a/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetaildaily.xml +++ b/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetaildaily.xml @@ -48,8 +48,8 @@ - - + + diff --git a/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetailhourly.xml b/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetailhourly.xml index 86670fa..e54551c 100644 --- a/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetailhourly.xml +++ b/skins/metrixhd/xmlfiles/plug-weatherforecast-weatherforecastdetailhourly.xml @@ -48,8 +48,8 @@ - - + + diff --git a/skinskeleton/xmlfiles/displayaudiotracks.xml b/skinskeleton/xmlfiles/displayaudiotracks.xml index 1989bb9..2e3d994 100644 --- a/skinskeleton/xmlfiles/displayaudiotracks.xml +++ b/skinskeleton/xmlfiles/displayaudiotracks.xml @@ -15,7 +15,7 @@
- diff --git a/skinskeleton/xmlfiles/displaychannel.xml b/skinskeleton/xmlfiles/displaychannel.xml index 319ff20..c4519dd 100644 --- a/skinskeleton/xmlfiles/displaychannel.xml +++ b/skinskeleton/xmlfiles/displaychannel.xml @@ -98,7 +98,7 @@ - - - - + + + &displaymenudefault; &displaymenumain; &displaymenusetup; diff --git a/skinskeleton/xmlfiles/displaymenumain.xml b/skinskeleton/xmlfiles/displaymenumain.xml index 7ba9aee..6124c25 100644 --- a/skinskeleton/xmlfiles/displaymenumain.xml +++ b/skinskeleton/xmlfiles/displaymenumain.xml @@ -21,7 +21,7 @@ + +