From 2a7a011055a44516ec981e525776394a8c04dcfe Mon Sep 17 00:00:00 2001 From: louis Date: Tue, 9 Jul 2013 00:17:42 +0200 Subject: [PATCH] Version 0.0.6 --- HISTORY | 3 +- Makefile | 8 +- channelcolumn.c | 17 + channelcolumn.h | 6 +- config.c | 18 +- config.h | 6 + detailview.c | 53 +- detailview.h | 15 +- dummygrid.c | 1 + epggrid.c | 24 +- epggrid.h | 6 +- footer.c | 4 +- grid.h | 7 +- headergrid.c | 4 +- icons/arrow_left.png | Bin 0 -> 428 bytes icons/arrow_right.png | Bin 0 -> 438 bytes icons/delete_active.png | Bin 0 -> 58636 bytes icons/delete_inactive.png | Bin 0 -> 11721 bytes icons/edit_active.png | Bin 0 -> 16127 bytes icons/edit_inactive.png | Bin 0 -> 53216 bytes icons/icon_backspace.png | Bin 0 -> 2012 bytes icons/icon_del_ins.png | Bin 0 -> 1680 bytes icons/icon_shift.png | Bin 0 -> 1484 bytes icons/info_active.png | Bin 0 -> 11487 bytes icons/info_inactive.png | Bin 0 -> 9034 bytes icons/no.png | Bin 0 -> 52583 bytes icons/record_active.png | Bin 0 -> 7098 bytes icons/record_inactive.png | Bin 0 -> 5897 bytes icons/yes.png | Bin 0 -> 35529 bytes imageloader.c | 13 +- imageloader.h | 1 + osdmanager.c | 31 - po/de_DE.po | 344 ++++- recmanager.c | 598 ++++++++ recmanager.h | 53 + recmenu.c | 525 +++++++ recmenu.h | 61 + recmenuitem.c | 2016 ++++++++++++++++++++++++++ recmenuitem.h | 465 ++++++ recmenumanager.c | 521 +++++++ recmenumanager.h | 38 + services/epgsearch.h | 61 +- setup.c | 6 +- styledpixmap.c | 8 + styledpixmap.h | 37 +- switchtimer.c | 109 ++ switchtimer.h | 30 + themes/tvguide-darkblue.theme | 12 + themes/tvguide-default.theme | 12 + themes/tvguide-keepitsimple.theme | 14 +- themes/tvguide-nOpacity.theme | 12 + themes/tvguide-nOpacitydarkred.theme | 12 + themes/tvguide-nOpacitygreen.theme | 12 + themes/tvguide-nOpacityiceblue.theme | 15 + timeline.c | 10 +- timer.c | 46 + timer.h | 15 + tools.c | 370 +++++ tvguide.c | 12 +- tvguideosd.c | 132 +- tvguideosd.h | 2 + 61 files changed, 5564 insertions(+), 201 deletions(-) create mode 100644 icons/arrow_left.png create mode 100644 icons/arrow_right.png create mode 100644 icons/delete_active.png create mode 100644 icons/delete_inactive.png create mode 100644 icons/edit_active.png create mode 100644 icons/edit_inactive.png create mode 100644 icons/icon_backspace.png create mode 100644 icons/icon_del_ins.png create mode 100644 icons/icon_shift.png create mode 100644 icons/info_active.png create mode 100644 icons/info_inactive.png create mode 100644 icons/no.png create mode 100644 icons/record_active.png create mode 100644 icons/record_inactive.png create mode 100644 icons/yes.png create mode 100644 recmanager.c create mode 100644 recmanager.h create mode 100644 recmenu.c create mode 100644 recmenu.h create mode 100644 recmenuitem.c create mode 100644 recmenuitem.h create mode 100644 recmenumanager.c create mode 100644 recmenumanager.h create mode 100644 switchtimer.c create mode 100644 switchtimer.h create mode 100644 tools.c diff --git a/HISTORY b/HISTORY index 9950b38..4698d9f 100644 --- a/HISTORY +++ b/HISTORY @@ -43,7 +43,8 @@ VDR Plugin 'tvguide' Revision History - Added setup option to switch functionality of keys "Blue" and "OK" - Setup option to hide schedules time display in horizontal EPG grids -Version 0.0.6 +2013-07-08: Version 0.0.6 - added frame around scaled video picture - added theme "keep it simple" (thanks @saman) - display of additional EPG pictures in detailed epg view +- Introduction of "Search & Recording" Menu diff --git a/Makefile b/Makefile index df0ba33..b668830 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ LIBDIR = $(call PKGCFG,libdir) LOCDIR = $(call PKGCFG,locdir) PLGCFG = $(call PKGCFG,plgcfg) VDRCONFDIR= $(call PKGCFG,configdir) +PLGRESDIR = $(call PKGCFG,resdir)/plugins/$(PLUGIN) TMPDIR ?= /tmp ### The compiler options: @@ -100,6 +101,7 @@ i18n: $(I18Nmo) $(I18Npot) install-i18n: $(I18Nmsgs) ### Targets: + $(SOFILE): $(OBJS) $(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@ @@ -110,7 +112,11 @@ install-themes: @mkdir -p $(DESTDIR)$(VDRCONFDIR)/themes cp themes/* $(DESTDIR)$(VDRCONFDIR)/themes -install: install-lib install-i18n install-themes +install-icons: + mkdir -p $(DESTDIR)$(PLGRESDIR)/icons + cp -r icons/* $(DESTDIR)$(PLGRESDIR)/icons + +install: install-lib install-i18n install-themes install-icons dist: $(I18Npo) clean @-rm -rf $(TMPDIR)/$(ARCHIVE) diff --git a/channelcolumn.c b/channelcolumn.c index dae36a0..8ed34b0 100644 --- a/channelcolumn.c +++ b/channelcolumn.c @@ -5,6 +5,7 @@ cChannelColumn::cChannelColumn(int num, const cChannel *channel, cMyTime *myTime this->num = num; this->myTime = myTime; hasTimer = channel->HasTimer(); + hasSwitchTimer = SwitchTimers.ChannelInSwitchList(channel); schedulesLock = new cSchedulesLock(false, 100); header = NULL; } @@ -339,6 +340,22 @@ cGrid *cChannelColumn::addDummyGrid(time_t start, time_t end, cGrid *firstGrid, return dummy; } +void cChannelColumn::SetTimers() { + hasTimer = channel->HasTimer(); + hasSwitchTimer = SwitchTimers.ChannelInSwitchList(channel); + for (cGrid *grid = grids.First(); grid; grid = grids.Next(grid)) { + bool gridHadTimer = grid->HasTimer(); + grid->SetTimer(); + if (gridHadTimer != grid->HasTimer()) + grid->SetDirty(); + bool gridHadSwitchTimer = grid->HasSwitchTimer(); + grid->SetSwitchTimer(); + if (gridHadSwitchTimer != grid->HasSwitchTimer()) + grid->SetDirty(); + grid->Draw(); + } +} + void cChannelColumn::dumpGrids() { esyslog("tvguide: ------Channel %s: %d entires ---------", channel->Name(), grids.Count()); int i=1; diff --git a/channelcolumn.h b/channelcolumn.h index a84f9a6..1dbd174 100644 --- a/channelcolumn.h +++ b/channelcolumn.h @@ -16,6 +16,7 @@ private: cSchedulesLock *schedulesLock; const cSchedules *schedules; bool hasTimer; + bool hasSwitchTimer; cGrid *addEpgGrid(const cEvent *event, cGrid *firstGrid, bool color); cGrid *addDummyGrid(time_t start, time_t end, cGrid *firstGrid, bool color); public: @@ -42,8 +43,11 @@ public: void ClearOutdatedEnd(); int GetNum() {return num;}; void SetNum(int num) {this->num = num;}; - void setTimer() {hasTimer = true;}; + void setTimer() {hasTimer = channel->HasTimer();}; bool HasTimer() { return hasTimer; }; + void setSwitchTimer() {hasSwitchTimer = SwitchTimers.ChannelInSwitchList(channel);}; + bool HasSwitchTimer() { return hasSwitchTimer; }; + void SetTimers(); void clearGrids(); void dumpGrids(); }; diff --git a/config.c b/config.c index ac767fa..408374f 100644 --- a/config.c +++ b/config.c @@ -81,6 +81,8 @@ cTvguideConfig::cTvguideConfig() { FontGridHorizontalSmallDelta = 0; FontTimeLineDateHorizontalDelta = 0; FontTimeLineTimeHorizontalDelta = 0; + FontRecMenuItemDelta = 0; + FontRecMenuItemSmallDelta = 0; //Common Fonts FontButton = NULL; FontDetailView = NULL; @@ -102,7 +104,9 @@ cTvguideConfig::cTvguideConfig() { FontGridHorizontalSmall = NULL; FontTimeLineDateHorizontal = NULL; FontTimeLineTimeHorizontal = NULL; - + //Fonts for RecMenu + FontRecMenuItem = NULL; + FontRecMenuItemSmall = NULL; timeFormat = 1; themeIndex = 4; useBlending = 2; @@ -133,6 +137,8 @@ cTvguideConfig::~cTvguideConfig() { delete FontGridHorizontalSmall; delete FontTimeLineDateHorizontal; delete FontTimeLineTimeHorizontal; + delete FontRecMenuItem; + delete FontRecMenuItemSmall; } void cTvguideConfig::setDynamicValues(int width, int height) { @@ -207,7 +213,9 @@ void cTvguideConfig::SetFonts(void){ FontGridHorizontalSmall = cFont::CreateFont(*fontname, rowHeight/4 + FontGridHorizontalSmallDelta); FontTimeLineDateHorizontal = cFont::CreateFont(*fontname, timeLineHeight/2 + 5 + FontTimeLineDateHorizontalDelta); FontTimeLineTimeHorizontal = cFont::CreateFont(*fontname, timeLineHeight/2 + FontTimeLineTimeHorizontalDelta); - + //Fonts for RecMenu + FontRecMenuItem = cFont::CreateFont(*fontname, osdHeight/30 + FontRecMenuItemDelta); + FontRecMenuItemSmall = cFont::CreateFont(*fontname, osdHeight/40 + FontRecMenuItemSmallDelta); } void cTvguideConfig::SetBlending(void) { @@ -228,6 +236,10 @@ void cTvguideConfig::SetImagesPath(cString path) { epgImagePath = path; } +void cTvguideConfig::SetIconsPath(cString path) { + iconPath = path; +} + void cTvguideConfig::loadTheme() { cThemes themes; themes.Load(*cString("tvguide")); @@ -295,6 +307,8 @@ bool cTvguideConfig::SetupParse(const char *Name, const char *Value) { else if (strcmp(Name, "FontGridHorizontalSmallDelta") == 0) FontGridHorizontalSmallDelta = atoi(Value); else if (strcmp(Name, "FontTimeLineDateHorizontalDelta") == 0) FontTimeLineDateHorizontalDelta = atoi(Value); else if (strcmp(Name, "FontTimeLineTimeHorizontalDelta") == 0) FontTimeLineTimeHorizontalDelta = atoi(Value); + else if (strcmp(Name, "FontRecMenuItemDelta") == 0) FontRecMenuItemDelta = atoi(Value); + else if (strcmp(Name, "FontRecMenuItemSmallDelta") == 0) FontRecMenuItemSmallDelta = atoi(Value); else if (strcmp(Name, "displayRerunsDetailEPGView") == 0) displayRerunsDetailEPGView = atoi(Value); else if (strcmp(Name, "numReruns") == 0) numReruns = atoi(Value); else if (strcmp(Name, "useSubtitleRerun") == 0) useSubtitleRerun = atoi(Value); diff --git a/config.h b/config.h index 3269e50..3afd857 100644 --- a/config.h +++ b/config.h @@ -10,6 +10,7 @@ class cTvguideConfig { ~cTvguideConfig(); void SetLogoPath(cString path); void SetImagesPath(cString path); + void SetIconsPath(cString path); void SetBlending(void); int showMainMenuEntry; int osdWidth; @@ -61,6 +62,7 @@ class cTvguideConfig { int epgImageWidthLarge; int epgImageHeightLarge; cString epgImagePath; + cString iconPath; int fontIndex; const char *fontNameDefault; int FontButtonDelta; @@ -83,6 +85,8 @@ class cTvguideConfig { int FontGridHorizontalSmallDelta; int FontTimeLineDateHorizontalDelta; int FontTimeLineTimeHorizontalDelta; + int FontRecMenuItemDelta; + int FontRecMenuItemSmallDelta; const cFont *FontChannelHeader; const cFont *FontChannelHeaderHorizontal; const cFont *FontChannelGroups; @@ -103,6 +107,8 @@ class cTvguideConfig { const cFont *FontDetailHeader; const cFont *FontMessageBox; const cFont *FontMessageBoxLarge; + const cFont *FontRecMenuItem; + const cFont *FontRecMenuItemSmall; int timeFormat; int themeIndex; int useBlending; diff --git a/detailview.c b/detailview.c index f06229f..0ce16f0 100644 --- a/detailview.c +++ b/detailview.c @@ -2,12 +2,9 @@ #include #include "detailview.h" -cDetailView::cDetailView(cGrid *grid) { - this->grid = grid; - this->event = grid->GetEvent(); +cDetailView::cDetailView(const cEvent *event) { + this->event = event; imgScrollBar = NULL; - FrameTime = 40; // ms - FadeTime = 500; // ms borderWidth = 100; //px scrollBarWidth = 40; headerHeight = max (40 + 3 * tvguideConfig.FontDetailHeader->Height(), // border + 3 Lines @@ -48,24 +45,18 @@ bool cDetailView::setContentDrawportHeight() { void cDetailView::createPixmaps() { header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null)); - header->SetAlpha(0); headerLogo = osdManager.requestPixmap(6, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null); headerLogo->Fill(clrTransparent); - headerLogo->SetAlpha(0); headerBack = osdManager.requestPixmap(4, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null); - headerBack->SetAlpha(0); headerBack->Fill(clrBlack); header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); content = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight, tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth, tvguideConfig.osdHeight-2*borderWidth-headerHeight), cRect(0,0, tvguideConfig.osdWidth - 2*borderWidth - scrollBarWidth, max(heightContent, tvguideConfig.osdHeight-2*borderWidth-headerHeight))); - content->SetAlpha(0); header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending)); scrollBar = osdManager.requestPixmap(5, cRect(tvguideConfig.osdWidth-borderWidth-scrollBarWidth, borderWidth + headerHeight, scrollBarWidth, tvguideConfig.osdHeight-2*borderWidth-headerHeight)); - scrollBar->SetAlpha(0); footer = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight + content->ViewPort().Height(), tvguideConfig.osdWidth - 2*borderWidth, 3)); - footer->SetAlpha(0); footer->Fill(theme.Color(clrBorder)); } @@ -79,7 +70,8 @@ void cDetailView::drawHeader() { cImageLoader imgLoader; bool logoDrawn = false; if (!tvguideConfig.hideChannelLogos) { - if (imgLoader.LoadLogo(grid->column->getChannel()->Name(), logoWidth, logoHeight)) { + cString channelName = Channels.GetByChannelID(event->ChannelID())->Name(); + if (imgLoader.LoadLogo(*channelName, logoWidth, logoHeight)) { cImage logo = imgLoader.GetImage(); headerLogo->DrawImage(cPoint(10, (header->Height() - logoHeight)/2), logo); logoDrawn = true; @@ -293,28 +285,21 @@ void cDetailView::drawEPGPictures(int height) { } } -void cDetailView::Action(void) { - drawHeader(); - drawContent(); - drawScrollbar(); - uint64_t Start = cTimeMs::Now(); - while (true) { - uint64_t Now = cTimeMs::Now(); - cPixmap::Lock(); - double t = min(double(Now - Start) / FadeTime, 1.0); - int Alpha = t * ALPHA_OPAQUE; - header->SetAlpha(Alpha); - headerBack->SetAlpha(Alpha); - headerLogo->SetAlpha(Alpha); - content->SetAlpha(Alpha); - scrollBar->SetAlpha(Alpha); - footer->SetAlpha(Alpha); - osdManager.flush(); - cPixmap::Unlock(); - int Delta = cTimeMs::Now() - Now; - if (Delta < FrameTime) - cCondWait::SleepMs(FrameTime - Delta); - if ((Now - Start) > FadeTime) +eOSState cDetailView::ProcessKey(eKeys Key) { + eOSState state = osContinue; + switch (Key & ~k_Repeat) { + case kUp: + scrollUp(); + osdManager.flush(); + break; + case kDown: + scrollDown(); + osdManager.flush(); + break; + case kOk: + case kBack: + state = osEnd; break; } + return state; } \ No newline at end of file diff --git a/detailview.h b/detailview.h index 3d72795..6b59bbb 100644 --- a/detailview.h +++ b/detailview.h @@ -5,9 +5,8 @@ class cEpgGrid; -class cDetailView : public cThread { +class cDetailView { private: - cGrid *grid; cStyledPixmap *header; cPixmap *headerLogo; cPixmap *headerBack; @@ -16,8 +15,6 @@ private: cPixmap *footer; const cEvent *event; cImage *imgScrollBar; - int FrameTime; - int FadeTime; cTextWrapper description; cTextWrapper reruns; int borderWidth; @@ -29,19 +26,19 @@ private: int numEPGPics; bool contentScrollable; void loadReruns(void); - void drawHeader(); - void drawContent(); - void drawScrollbar(); int heightEPGPics(void); void drawEPGPictures(int height); cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend); - virtual void Action(void); public: - cDetailView(cGrid *grid); + cDetailView(const cEvent *event); virtual ~cDetailView(void); void createPixmaps(); + void drawHeader(); + void drawContent(); + void drawScrollbar(); void scrollUp(); void scrollDown(); + eOSState ProcessKey(eKeys Key); }; #endif //__TVGUIDE_DETAILVIEW_H \ No newline at end of file diff --git a/dummygrid.c b/dummygrid.c index 97a8d1a..42025e0 100644 --- a/dummygrid.c +++ b/dummygrid.c @@ -5,6 +5,7 @@ cDummyGrid::cDummyGrid(cChannelColumn *c, time_t start, time_t end) : cGrid(c) { this->end = end; strText = tr("No EPG Information available"); dummy = true; + hasTimer = false; } cDummyGrid::~cDummyGrid(void) { diff --git a/epggrid.c b/epggrid.c index 97a57f8..434a612 100644 --- a/epggrid.c +++ b/epggrid.c @@ -7,6 +7,9 @@ cEpgGrid::cEpgGrid(cChannelColumn *c, const cEvent *event) : cGrid(c) { hasTimer = false; if (column->HasTimer()) hasTimer = event->HasTimer(); + hasSwitchTimer = false; + if (column->HasSwitchTimer()) + hasSwitchTimer = SwitchTimers.EventInSwitchList(event); dummy = false; } @@ -89,8 +92,6 @@ void cEpgGrid::drawText() { pixmap->DrawText(cPoint(borderWidth, borderWidth + offset + i*textHeight), extText->GetLine(i), colorText, colorTextBack, tvguideConfig.FontGridSmall); } } - if (hasTimer) - drawRecIcon(); } else if (tvguideConfig.displayMode == eHorizontal) { if (Width()/tvguideConfig.minutePixel < 10) { int titleY = (tvguideConfig.rowHeight - tvguideConfig.FontGridHorizontal->Height())/2; @@ -107,14 +108,21 @@ void cEpgGrid::drawText() { } pixmap->DrawText(cPoint(borderWidth, titleY), *strTitle, colorText, colorTextBack, tvguideConfig.FontGridHorizontal); } + if (hasSwitchTimer) + drawIcon("Switch", theme.Color(clrButtonYellow)); + if (hasTimer) + drawIcon("REC", theme.Color(clrButtonRed)); } -void cEpgGrid::drawRecIcon() { - cString recIconText("REC"); - int width = tvguideConfig.FontGrid->Width(*recIconText)+2*borderWidth; - int height = tvguideConfig.FontGrid->Height()+10; - pixmap->DrawRectangle( cRect(Width() - width - borderWidth, Height() - height - borderWidth, width, height), theme.Color(clrButtonRed)); - pixmap->DrawText(cPoint(Width() - width, Height() - height - borderWidth/2), *recIconText, theme.Color(clrFont), theme.Color(clrButtonRed), tvguideConfig.FontGrid); +void cEpgGrid::drawIcon(cString iconText, tColor color) { + + const cFont *font = (tvguideConfig.displayMode == eVertical) + ?tvguideConfig.FontGrid + :tvguideConfig.FontGridHorizontalSmall; + int textWidth = font->Width(*iconText)+2*borderWidth; + int textHeight = font->Height()+10; + pixmap->DrawRectangle( cRect(Width() - textWidth - borderWidth, Height() - textHeight - borderWidth, textWidth, textHeight), color); + pixmap->DrawText(cPoint(Width() - textWidth, Height() - textHeight - borderWidth/2), *iconText, theme.Color(clrFont), color, font); } cString cEpgGrid::getTimeString(void) { diff --git a/epggrid.h b/epggrid.h index d7cae70..0465d06 100644 --- a/epggrid.h +++ b/epggrid.h @@ -8,9 +8,8 @@ private: const cEvent *event; cTextWrapper *extText; cString timeString; - bool hasTimer; void drawText(); - void drawRecIcon(); + void drawIcon(cString iconText, tColor color); time_t Duration(void) { return event->Duration(); }; public: cEpgGrid(cChannelColumn *c, const cEvent *event); @@ -21,7 +20,8 @@ public: const cEvent *GetEvent() {return event;}; time_t StartTime() { return event->StartTime(); }; time_t EndTime() { return event->EndTime(); }; - void setTimer() {hasTimer = true;}; + void SetTimer() {hasTimer = event->HasTimer();}; + void SetSwitchTimer() {hasSwitchTimer = SwitchTimers.EventInSwitchList(event);}; cString getTimeString(void); void debug(); }; diff --git a/footer.c b/footer.c index 4c26336..7a19053 100644 --- a/footer.c +++ b/footer.c @@ -38,7 +38,7 @@ void cFooter::DrawButton(const char *text, tColor color, tColor borderColor, int } void cFooter::drawRedButton() { - cString text(tr("Set Timer")); + cString text(tr("Search & Rec")); DrawButton(*text, theme.Color(clrButtonRed), theme.Color(clrButtonRedBorder), 0); } @@ -78,4 +78,4 @@ void cFooter::UpdateGroupButtons(const cChannel *channel) { drawGreenButton(channelGroups->GetPrev(group)); drawYellowButton(channelGroups->GetNext(group)); } -} \ No newline at end of file +} diff --git a/grid.h b/grid.h index 42ad41d..d51271b 100644 --- a/grid.h +++ b/grid.h @@ -12,6 +12,8 @@ protected: bool isColor1; bool active; bool dirty; + bool hasTimer; + bool hasSwitchTimer; bool intersects(cGrid *neighbor); virtual time_t Duration(void) {}; virtual void drawText(void) {}; @@ -37,10 +39,13 @@ public: virtual void SetStartTime(time_t start) {}; virtual void SetEndTime(time_t end) {}; int calcOverlap(cGrid *neighbor); - virtual void setTimer() {}; + virtual void SetTimer() {}; + virtual void SetSwitchTimer() {}; virtual cString getText(void) { return cString("");}; virtual cString getTimeString(void) { return cString("");}; bool Active(void) { return active; }; + bool HasTimer() {return hasTimer;}; + bool HasSwitchTimer() {return hasSwitchTimer;}; bool isDummy() { return dummy; }; virtual void debug() {}; }; diff --git a/headergrid.c b/headergrid.c index 280ea46..4bb25c8 100644 --- a/headergrid.c +++ b/headergrid.c @@ -24,8 +24,8 @@ void cHeaderGrid::createBackground(int num) { width = tvguideConfig.channelHeaderWidth; height = tvguideConfig.rowHeight; } - pixmap = osdManager.requestPixmap(2, cRect(x, y, width, height)); - pixmapLogo = osdManager.requestPixmap(3, cRect(x, y, width, height)); + pixmap = osdManager.requestPixmap(1, cRect(x, y, width, height)); + pixmapLogo = osdManager.requestPixmap(2, cRect(x, y, width, height)); if ((!pixmap) || (!pixmapLogo)){ return; } diff --git a/icons/arrow_left.png b/icons/arrow_left.png new file mode 100644 index 0000000000000000000000000000000000000000..a65e47d315c1e19873e6e51a319a858734c35ab4 GIT binary patch literal 428 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&NtU=qlmzFem6RtIr7}3CHAi!|1d2b{G1EZLyi(^Q|tv5FfrJ5XgSRb;uzN=5pUHUk6-`zADhR@<0 zvjeU_i{}(jaA;s)WMbh!W-t`b-29!XZ`D1{A77Il1OJ8uMA(anTtCmk`c2t!;$N45 zjC#w2d-E9^{&6^bQD<0U&tULZhT&^6!&QIA2z!=-zdQ`zlo@XNGi2B^Z20@UVe(sh z_Ak5zI`g>`91DauH9g7i;9A5ksCh!}=mLcr$-<^Dr9GUFm^oEX^ruWnD9}h{nVf8? zB*ClJl3+HAvFTw!mH3>~$3NE}{Jpi#@#1E?4U1j|&W{NCx}<;2%c=|MVpHdSUl^Ku tyf!QHujlVNePpk|J$In)KzIWq!_SU&uTI?dPzQz@gQu&X%Q~loCICSjrLF(~ literal 0 HcmV?d00001 diff --git a/icons/arrow_right.png b/icons/arrow_right.png new file mode 100644 index 0000000000000000000000000000000000000000..97fa1232485286bb7f36f8e64f8a0d0578383d28 GIT binary patch literal 438 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&NtU=qlmzFem6RtIr7}3C( zr2qf_b67Il0~K?Z1o;I6xlq91< zy=1yi(32JOj>NZF>eab5FfcN)a0n^_ZaVq9 zC!xzuX~r^t4nO8N;}s7~9(+t;eSV!mhog*9+v6N#h``*IB?`N_9ULp9i<(O04zPT5 zapC+lkw-|xSW!8nEyyLn_h`!k>C=pkKjT0AV>|ON{lMGh_5VMsGyD>5cwx@4B%WbL z9bdyQ!-iMO8P>=%?Wkj8_$}D*Mx9}cJj0EDl?->*Gv@C9%Tl^OrlofO?KX$~RvjI6 y#Ujdo9~mY6`dPY1{yNhJcNDL{J!i+n!;tzSef@)s_ZNV{#^CAd=d#Wzp$Py~iKvkP literal 0 HcmV?d00001 diff --git a/icons/delete_active.png b/icons/delete_active.png new file mode 100644 index 0000000000000000000000000000000000000000..b01dc5c5237e002e093e5dc29061a9b09dff811a GIT binary patch literal 58636 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[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 Ef^2R{(EtDd literal 0 HcmV?d00001 diff --git a/icons/delete_inactive.png b/icons/delete_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..b327f07d997af11343b5902c96179032f6e80693 GIT binary patch literal 11721 zcmX9^1yoes7QS?cbhm&=OGtNj35axeDo7690wV2@(j9_ymq`CeH%LiHBlV8!EoKI0 z7BhFBbNBx0PPC@F0uCkxCImq^N{X`D;5Y2w9UT=s_KKU2KoF*ey^M^erk$&otEZi- z8=aDj44s>YtBt*rH3a!Az;$eOb@oWau2#;aRia>@R9v-*(do3MV_`%|%xv@+_{vfA zdGo|t-B0A?kST|9qmVv)fW;AOv17+z&Y^A5=YI$-h>H1syY5%u__OWm*XYC7S@E5U zGkE(80ce^({`xU`!@A2p_%Pir({{5dpdm6cv5W(1q3k zA^1#Vp+jA2SzX*zk&k%$(iv|MU||SdUP&)i&|yT7r0)mmB1lpm0R~TJ)`4=7A+r%n zi%m$A12SU?`ZW!~;MW;`2$0bydSZm!B#4gCI!YF@6M-tmU&Y8l2HX&ljY^*oG{*sP zE9u)PLN!fL*BCxl9fXbzacf0|KZB6{AhRJxMjt3F10s??)ffHqyb6DZ4eV4#ooF+Y zkX*14I)^)&zCI@n>zEShb0PtAMDt8Z&Yt%fuKUCu&j^LNXQDSU~bg9CEZ{XFnaRouAt*+hwv7#fv>_XSay&sPy?iF&M zLNFVpkM0m;BFn_7`@LRb5FLVKbA#Dxq$tn3$=JJ4sk%{?y0Pxe1j3}5`g)}Cr7^8w zR32u}Dng`LBSvee+03~9lceVB(z1(4cEjcD(ffug=7#sz96h_6wJjI}S!xKK(42lD z3c(`Afbj!5X-4=peYYYqK`ay9a1@aigGv&=B9C^AE}fnt^{JQ#qEO@;`IaP+A&58R zE}~6==TmTS*PdbeI|QEt(n z8ezgMB;CJU>uj)Ue|JzO-^SnO+eWoc=atec$kbjg$km zGFx(Qvg&lzBJ$~2@xavxL2{gQqMm6kJ?bVR^ zqLo`~y4f~Bhh<4#@54^-h*KW%HkiMUxps8k{~cRv`aN}PtXNrTo{-E7KihalS;VK>%wzq=u`D$$)u3FlT&rB+pk1Kquozy{ zF4t;!8;mP8sLb+)MZq><3)q*6e3YKuVFJrm zbuC_b-@fygDuC-=_ulz$@r44m0ct%q6Y3)N7@254zq_j_HP_(cA1xWLdu zn>|C%qGF>}LPj{##5uDl2bPE0x0Jmu+>O_Lr!L@G^;tcKC5zQZ0!Q{okxMy0_;Q|Q z8@}+I=pB+-)7qYtz{*MCc3iCp)R55#w*9)p$Ysfuq+dB((^TkPc4dA{Dt;;Mk+Uhj zDJrB~G_*x_eIBg7n z%oxB8l$=zkggDu%1YDdtR__kaA~)b0Set&N>0Cp`ZtwHPdd|a(NlG~h*o9LiRio5j zemarDXDcCzdwNRf{qzIo`yT2ZTL!L4fyt;jnKx`S>ZgiqYQ7(TC$;gvXX<}Z$iCei z#!{Ntri!DwoF$x1lKGC#nO97>ohS5TQlh(b8NFI^qwT)!FPnEG71rT(5B)B&O6i4`b@9GH#LMZ3DMS!dbM>TIp`Z8}GzzYC?7XFnf3{89gXF;VdIan9o*K@Y+D z$Hu}46@3nBgJ10x4nlRJ?(Y{dH;GZ6N4!F<5d9X@$mTqwQGTeORu$OJ?5pM&Y|{Nb zr28v^;{lc)=5~0%!P4xZv4#Pc;p$iOzY%asapLHhDxyWwG~%E+)+L{9%1GDmof%7? z8cNIinytodrfl|pt#D);;ii_Q{Yt}i!I@uZz*&9OaCmVkx5$+?%DUJZ+9=ap&?)+@ z&ANDaY*a)-_lxei?q6Mjqp9Vu=Cju>lSh<(ZI^t%XBLgxuI|N$I~Mg2^wef-W~^_O zZtJfks-nyGu2XNFjVsli-46$mrjYK@7;zhCoBx}ko)Xj5PWbu!Kmm7OlP4@lP-WA5`6%CH?!n-)XigmPU+IQ5p)LahInWvfZSvr}wMixdb8b8D* zf9|jN-YG27;(g{5HGHppraNrEuop6&YxbW$L1s7_OE_6 zS9_G%f@90)?eG7PJpP=?77|--Kl63H>c6^JC0P#iV7VU~X`T0GIjU^aXfr*RJd~Q3 zS&p2MFnU;;J6;NM=`5q$VeE8z==4>ekm>_v?1Yfzjs$G zGj27`oK5!aOG?S;-n@oh4Ba`GcGQu^7QP$A3S$ z?ZwI96%02;Lr(}2H2!x-Acx6=KOi(OB{ey;WmH^z1S+c8y*3DBhX6t^Bn9(W$@z1TSy5Nlj7D%Y*QC@CI4>lknS zeAT89-EV;j>CL_!t*bzWv33YQ!12TgqASQHEq&Zh4Au1X^ky$O)uywL4-c28odoKk z3WcEa8g{Ih{5g|H5t^9%3BS#p$Jo`@(_MqASLHhg7k?jT`8Z1Xv(z{!;>91~$NoDP z4-XHgzkjncBt;!R9tp7ih8jI*(p_*;9!B z-7UB!BqV&a&a}~~XMdhOY?a-_Uhe<*+`gi+Qc7_}Nz2lg5v2SIcn`-pPj&2}0$Hd0yH zRFG3ewR=h*-dMtoi9N2x+AT|>$UkypgRg-MABMM^5G;Y zBFE%^($k}!Ad(9%D@!f1kCHFoRwD$jH^0Fx)y4ed^Eq(1TIhrUekkk!zZB}Z3~#H8 zq$ME^upvXu9AyRz&?=v)X=}rVz&mB3shIpNKIxm^1!ZMJR=h(yXNt_pQG=VhkdN8D zW)dl;=Pf&HSK#uzW$VZ#%A>R!vI_=13iWv@E#gmX(#U z#we3PlXgU)5KJji8U?l#Y2FN3h9p>#z4qZHBen_3z_?$6(Lt!)`&NoWhpUR*} z)K!G{9`z*u-sE!!x2j}1HvWI2*VYIb6Ymj>Wv>|W@N3`mQH1BSIx!3#A=O|@+I(2@ zhta9$lG5X=c{FUEgp;Gjuo@z_WgV}{UND$SS<%RL)jx*zC$4>G3i+)CnIrT-Te6o{ z|hGin;p*zag2*L7%Se zC-rqgibM?A!|0nu}S4)Z-yHEbb><@{%`rTi1H) zDQ02@rXf*RCiL^aCRv1vuoFZ&Or%9(XtKaQv&!j|=|zaSEaXJ=6lr{vD=|FeH~;%P z*=Tx7q#A*o8STKv3D=_W*fWJL4d&#bZI6=K0|R4YoTvOtA0)4p(1!^mMD+$OcuLA* zE-v1dTJC*1PqOc%#Hv|u~fq@6s^h}nwLlK|8TSOGU!2cYL5@fHDJdanG!ZXyT=SSI%M$6w$B7bv!*D2 zdw<59nwpw8zT<4UW3{>5BR$D@@a+t7f|tB63;L=4M;hO2O2LbB@~*pE>h3J(v2VWK zHfdzr%#ehcg@uQgH^ifvy;A#Vi?1dtAkALnQ5>PufPG^OE@JTdwKO}4Ou;0~K68Q( zCt9{gXNn~%_f*_OB@lK&U|E|!+Kg|FaIXppVML(csWQtDl8o9APESt*l#!8<(dDLX z!bj%de7a^^Z}>_1=~8D9t%`~YDEmL$gBJBsDYlf;QBjwjv$^P#|9sST&h7(sx=j4R z7$+(ha=&~TH9V~JS;QN6&x>Nx?$ZjLlJQErA8Aa!CcPWdQ>PbeB)H!{zU*sAQGV(V zkk!D%L|#0n2_aFvI7yZH&ssNFRNaz5 z_%45&e{fo@Hr?0LgQ%+~XKI?GW+zOKZQ=omO7^8*ou8XIJLAO5BW0+{Q)t)!_lBJ$ zNs-Cz=F~b1f5-;1CbZ$j&bWXqXkjU4bpp9?46>xrZ$z;i8CjBs@oDbi)5Qr(`Tu7}%_s{M>mbh7{%Zh}i+-+}NPYL?7?YuFt16YHMm> zRaKlC?w!euLl5d31r65_1FBn$E8OI)!IU$NM@%d}IvS(w#so%+LndMn8yowN(wGQ7 z{HdEg;Tf{Pe|5&M*8BIb@W zf4#aP{4a@N?ds}k6HLxGuf30-F59s`*h%8_*7Q%R-(1&dcZy#B@u32H1CC)Qkflr3 zj>!4f$kbH9+glKqRy;15MZ+R6Fxy5hlqtgCmDwIG#3!Jywwq_nX3hTyI{%yhjR)4X z3(}TcC_ywbc5m)TcGT#h6%7onv#E&`v~dS6rto+KC{vSlEk)m?`}Vj~V-z8yDvhH) z?cT=FFz44S9fg70j{9)2!0>|nF&S^dx|BcGz zyD-ySIP)A310Ky(9T%0Z>&xD&{XkYJ7k=c!erv(O@N(2<+D5(v!pEEB#{Q0+-|~Vh z5VW>|fkD^(?Ug;EENVw`k>7nBdiT=OXO1w;mWq*5zSzQhaB51*98}Qb-HMRBaG}D2F1qyI3 z@x6*?Wa}E*2DHPf4g_+S9-5u17Pzrx3$(nvy)7LaFeA*(dLwY`_$ac&=%RpJ2yqgK zji(gc_Jmq7YCU(4m>3NUn$$-lVq8iaMF z(iz@+EH{$rxt*P~kQ=}baDsl%*P}gu{=7zdx3;h1z^Eim=OKAZ4~F^iRk_h2-6Jk<(!Xnqr6pLxBNtdVO^ae25H z>F`xKoDO}$h5W0Ra6GB0|C3^koJ%I;wqFVH@$;#pO-L;@4|PS@<=b)7;p77CfIuwnwg^q@ek2HU|22KtRCU zH+M^{YpJg$Ha7W_tNW_-D*H7FWp%uv ze6>ic)*voqd|DhKXV$lvW~A=QN{L>dC9xWvAYk4;q+ew!>JA47r@M~*?#R1S27GdN zC|Ye}qm85PI!pa8oAPMt1|HX{{pKdf-x)f#evtOf)Gm|dnDYPfU_sq#kyDcA%1CISVy1bPyzqP+J>i+WQ z_1-J!S-x*EgB;hvx}IMD!~{?deOay@7{DjFu8LF8yvOLg6Se~^N)f*?ktYMhsWXBE zYkRCoa>KW(gO?s#=;HV1I{!ujoCqKU0ecDL^tyU$Hhtpy<33mS_B-T1mURs=;nCIe zn6w41AV-CTS%y z>SnEs%?c*Fk{A`-E`J;TE3m!2oyecJ@b~Q4?dV;txfvGHOSR{|h0-hDCsQX~vG|}M zKo*O3zm*!i&dxGnrmRF0c6=wx$AP3fWAI)e9wrwT7YX*8CAIah1> z&21g=-Qj{9zeLt(BkVX0-j?d~XQy^uEF*wOI5_MipiTQbVha6FSe;?LT- zUcG3A{}$1ZR{w~%)5b*)fqG!bv|}oUV$}7N3Rm9i%7q_N2APLwcgI1Gw*sSF zDau55bnb17LUlYl1tr8c(#r1lmaZ%zt19 zEKnGIzCO#yv0sF_=E7q)ULY)%l*)?%kUZCV+0Kt6YIV^c{4QUM_Trx!Lh@)I$7=E7sqByz?JURQ2JO5D+-bn3F@ zm6u~>s227Aj0pHv%bP&E$nl@PT;g>9QrmyruCJKzzhwWL3*abUdhI4wR`IZR-6+&y zA1X-veF8k!vuoKixqd1*1s)4wS9UM3uRnB9>D1}6&`t<3zR4k*<3Y97+aBb#2G}|} zI^blX0r53@9EtKR>H**{NJ$E{^VaGGB%Idnh1W&jS&2bP$Vpe>#8M0rbQNN5%e%`5 zQh~0(c>o&H1k4^UzxTa>8)1hwEiFxpmFVAjT0d-B9q8!^;r%KOREqRBmu|UMV`48@&=;;tjDZ3twAY3c`k=(?NDGrxPo$u$&O!%Ka?!cjBmfITk8P~MNWSb9P9qHg z`p`D}eZ=Jh@mnrGDrT6oCF5(T;=S?fEgRGxQAOS|T{d$kC+r*lY)+#06rkF%{e3oz zS~3CWg)m^L*}1sDg-%go`rI0(ANI;Tc9F`R@8a*>fioeaq%7dSxQl_S+xxME{Zql| znVCJ`zhf@rl}@X6-9k(V|9!;#6>QTT_?a2Tam#Ehq+Lq1Y&3{X&}Q> zYy|r95Aq5M?)QJ+R#a4cbHSU&AfdZrc|!`pg!TI{h@M6WtKEVWH&7H9B1cEZ?Cz`Q z$X0pG&pw@Ryg_Yush^hx8tUYP+hwIK`gP?`cY6HrfQo9C3j|qsFT5ozJf%jH2n9?? zZ*T7epIYWDUg&_5IslT5Vu|}_?~azDT?5au(sOdW-%wFR;A7+9nEU!tl$Vz`tXr~p zvbe~VWd4{>Rzr#8=^f-UWVl5DvH=kKtP-5Nt9r)4=l){$PeRZgQhj|r2s-ELZSf9u z8B|Ie&$5Qftfr*eUzKaoyDcL0Iij=1uA%p0&Z5*Lv*)AGwe67o#HO`xd##{hGz!C$LxxU^^m~;}T zwH(9+`+bcm5{fPbJonNP6>-SmIx@kuSr(3$LmEjVo@8KLkv*_YtZ5?+RPD)YJ03#d z9cve}fbB_R<%lp*ta!=6WYYu90f-ye)VYoT5r?mtEcECE9|f}1K3$HUf=rJkiIgX{zF zXQVmVT%+@%<&zNUJlM?*NF8xBMoU9v5qJsd-;hp3&r5pr0`y~KWCXhApApk(Jq&pS z*%g(b%Ti77c$)jOn2_vj8lW4nNI3y$i=O>>(NO8kQkNi$4#1Lxlyol;`LJPQ9R)U8 z_0eIQgpf{!{FI2`9IOar2xQdM{}|zwzP_y2^Wd zd&mAdGw0r;65!!M=;f}l9wAwkUQ;lL!UsD9;BP^xg1RvI>*F?x453nNl=Omqg0g@P z1vPcyhq+C}$9Tb&u1ce(8vAKxqFA}tOu3p`A{p4m&D`YzoCDb;7)p>d72@QJU<5KJOMycFY!3e8kmP%I$70sBuvf1-R7_ygqqzyzENONGO1T~D(NPrD3Vgp<)3u;VHSuI8s^AEtlkpS zQi1+El&eYoa=_k!`tZUcy3lbX}n;Kw`DX-1hXBnhH23lp@ zirUM~EiA0u{RBe;f9*y=PAgHBnMXn*!GK+UWF+J-q)pf*5-e2!ofaG~HHQMyh>MGx za9NhJowwSlTkE{PTqL>!amLo!`!Cb>M%vHg@>9T5Ae6ukg5CuGJy%rOYv4P!VhcEV zV}s#e?g}76mVth0ewhQ)4US8~L1)K;2i8^fra8pnYs}$d)AZ}mnlKnUj*+o(ziZH~ z(NeQ#WXSkbVEP%E>^BU;rIxo?AgJ*1NykKxNcx51Lw*h7Ll9!Ue7jEsycjAfDv;2- zBwtO=Aa!EXOgo(Bq2%)eWRP=$hJ4fPfdcSwuHDbuPFk|78ej-u=7d)7V+$vzA4NCt z*M%wr!M}HbL2w2O0a-K{QT@S*5l@mkkW=N)J6V{SVzayQfn`wUkVZ{pup%?h`f79qV%V{dzCE_o8 z_IN!gu>sPteE_>{;weZ|3|Ua@-c`cXgySiZ{K8 zXMu}O_~XY9Q29cK{FhRbE{TA@d|t+bCns)L*CxkmeQRx|W-kza$CsW>+Nxc6C`kQ-*WrFP;GQ|FC2FKDuU|A8tx3 ziJJxC)0;VN&sQ$p{k)4tWlJ75133-vzhtVEkWJZ^;6&r|OR4T1{zoMaQ^I%*M_ffb z#>NX=31-o2ko14LOa>Wg*71McpGcAOFxJr2FZ*jyr99X46wp5BP^qorEsz2O9*;j_aL zzSYtf<+QZ092}y*Q2xi7cRiAV^ydFs&uOKNJk@%#RI{#f@#Lf?@iK>GGz|fSBxad5 zvG`2M!;N;UBVw`sP+*W<76v{)!MiM67w;2dIVpg_h1%Wc=X}7g0}=xlHDj(;{O~}e zpSvb8nt2?FAulgq1JdUN@xM_aIV0PNBip;$U+EggHyM?;W9Qner&&7!-!MVu4)Axrt12u%|x7O8DCRj!dxii8Y_y$VblNRFM7EZ^L<=iD=|LlWkbd|Gs6<@ zA(Kg>d-*izOFY93SB)uli>IxK;6=mSt@@1^yiLN8IZ@wDjYy!TVZ@c?@n!29F%Gl0 zAy0%2%jr%L4CLM!Q!snbd}ii*sHWDK78_|CO}2KYzC}7w%NORSJ!!z(Pe$abaJSsi zk;Re;Q_EK*Q+$vuT~j|MUu!x#F(sZ*cd72Zh4Ssq_Pn@T7oNtYbZhjEk!#f3pLlkd znm?&L+#2bA%@)%37s-@bquQ+&YCXJSg5&s8!KFJ1zKm^ASW&_f9k>L(r18Q^D2A%9 zXl+tYp08{AH|<#RZ0#VvZV8Wl5SpimzpGd0kGb=<{4hA9xfqKl$!+yDXO(!M(V42% zn>&M&F6E1pgFsxx&*@Klx88hDku^F{swU9z10;VIDge5B!|p_zOZ{Rp8Zm{%x<2%Q z>k0Gkbb`Mu1~CJX+_0V;$xLFQdC#WNoOayL>{;8F%}#^vftrTJKb73t{tErRSa!Jl zEcx;N)srEU0k!j1x$;n>&ysRlL?7ulnnNX&W z2mR|_>MnLzQGQvOgW;>mx{60lqHPHTC&Wa=Txd5+pV%w%&*0&f5QZ;);kEk8Aob!(I&VUgW*(JTGRNBR5wD8|3P@PFo#pJg-A}|&>g5|9e#2S(Aoz>eqptZT S4t!@8f|TUcWviskLjDJ=sa-Yz literal 0 HcmV?d00001 diff --git a/icons/edit_active.png b/icons/edit_active.png new file mode 100644 index 0000000000000000000000000000000000000000..5b3b6672452a44e0ec05e30e003bf9e62ab230b7 GIT binary patch literal 16127 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 H+$8uv^$VAT literal 0 HcmV?d00001 diff --git a/icons/edit_inactive.png b/icons/edit_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..d4f59a13eb0a1aa21dc0b419b71b2d325ff084ce GIT binary patch literal 53216 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 literal 0 HcmV?d00001 diff --git a/icons/icon_backspace.png b/icons/icon_backspace.png new file mode 100644 index 0000000000000000000000000000000000000000..e20b7bd1f4c95fe9e727086d3536e7e1bf5b1a64 GIT binary patch literal 2012 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 literal 0 HcmV?d00001 diff --git a/icons/info_active.png b/icons/info_active.png new file mode 100644 index 0000000000000000000000000000000000000000..7f1ccf78a8b9f31a385ea9169112638c2339eef6 GIT binary patch literal 11487 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 CDT3et literal 0 HcmV?d00001 diff --git a/icons/no.png b/icons/no.png new file mode 100644 index 0000000000000000000000000000000000000000..3630d29b6dcb53866debd261d50a004f1ef2b4a8 GIT binary patch literal 52583 zcmV)dK&QWnP)sv)6@3dK}YgeeBo+yP^-V+Y4h;_etbEFSo#&&=$--aq!txko}^Y$R0B@@IVRJ-VDZ zGkex=t@T@F!y!2&hvbkPl0$Mx4#^=oB!}dX9FjwFNDj$CDj$KRAAvXS>+f+$_O1LC zEcu&5&%rZG{u+kwyx?VW*ZG&o|Ad$A>+f?&_Ko}%4Bz>}SIE!Kd5QeRGx#|$`}zw! zo$^0m_|&z>?wEc4^XXfA46`2DeCg4TKD_=WxNBd3w?p#u$^QpKryYIV#OU*1N@?jb z1|Hdb>5A=-uD|^m_#8ZA0N}$gdd$$s`0z<*Vag?_R46Z4NagKCf!N?p`L8If8`n?-zP41vSZC!e- zu;FXZkmo?}>o2f3cfF@4WE0j*#u z-0(5Dd|!X>L$YV(V=%f9#tl$DYAvM&izqB#L}|%figV@=%^5-W_2Fzvad0+=hw6s+ z!^`*e_kKDg*whlKcB+Fc@&l`hR6VlcybPAutI7r21jLZ zjODd$H(b+k{26>|Uth!Cl!MX(xE98asq}3LD?=nYC8_jbgAg}7M5PeH$N+^(nQ(Xz zJv4~!8z3k{Bv72y&r-$pA3x*?9Psi<7+s**uFEBq69mvf5mPP@4D=Hgi|9g;NNH5L zpP*DgD@`gwv40M$3gHdc9ONm&gAM?$hOsr3zOBK)5S?O)VpyRZ7Af}kp=#5(AcWMC z)a#_vRgywLxaCoVek6#%T8gsi4IB71QU}?JhFw#yfH$Aq*y_$rQAQjV$BVoI^+o)aPlb_S!5Uw ziy=w`2^5%sVrWS2+d$fA;_7u=J4Lk;C>05Y1}KltB`Oq&!iZEU5TP(In-zud#&;g1 zAaKwCz&l}Vb>F~NQyIdP`!Escpg>p%DTZY#!;2`4%|@CXQmu(vP0Vzaw3VQzCkXpT zQGI2~&SHyYVr$WZ11y2-Z#?7)958Y{j4U>cN5u$H1_1xQ#SQdphzWpEsfrA17-VS3cLbWv-7$Gk8p_LGt zBDzu{D$SxYcMj3qxfB*IMwd&d(4Yz-5=Dr1Xrqbd%%w0m8&@b2T8k|dDL9849$+cl z@b8B}V855oz{s+I@t_o8l}6!Eh);Iw5FJFgdW-atZ6vKWuGT_zQdANXj*bxa&B7Fm zXr&OXQ7Axg)-fnRR8#KCwF z1vnu)3?;!#ON6s#VFrf@M`oc4nrQY2!N>?& z2k3Hp&)%}(rzA-Lg->JTTezsctnqrkWV+O0HOE6@5{ zEhrawF2GshW}VS<&&14|4FaWQ3yG&{BojMGS}`h4&|!cHG#aoGPKEQPJYOff?`y$Pi?pfP;|L_n>%VZw6WDL$^NJCH?Sg-p9~Mx~qLk|SD@P~p z(A+W2vNybe@<~TQwF*;HC?^b^ay-@hHqzL!73nmvNsOov!pM68+EA@+1IU5`4+3w1 z%bxx#-m`K*0>JNk%fA(Tc$Y7Jb-GD0(3r{~2EhaYDk?!3;o2z!#~*_p7ytxkGzy58 zFF`DxH0&QBD)pg;M^Hh4GLTm5B!E(W@iV#MD~CLReJ)>6jH=A?=aK^LmPG-|2qccQ z*~E4%&-&2cGVr2vVSEC%Y)Ad-VPtxmV5q|CcfXC+)^S?38cC9%okj3#t`Q~^K|}XF z@#p%~>ke>E;D7^w*JjF}p>X#wz@va`w=jSz7I9&KQbIgkW%#le5-wSQBr#HNq3aE# z)keF7!3)kHEDxbliz=1~!;qj-Aq)+hjK4`*!0vp`>u);b3G6fZqGCj4mcRGV_~$^Q zNSq~Yw`eDp?hiZ5HYw8&J!z(dMmwT7bMCd{RQyT~8KUWkv4}ij38sLVn9`Xd9cDczb z|9HM00$7>(_YTl*w2*p2JB1TI@HfnU-K$|@3N}87q#Z~)IBRi9irumWwrruajcIJ! z!r@oGj>@_dpdBOCD$-~`9DABLb*SlST&<2IDGRQ(HnpY0SdE|4YK*dAJ9EM$!S3 z1%3fpD8P)zVd*{yH{5*46WHr=OBVCzYYsEkKUYeNHwrs|6R-Lc=DhuluzeivxgVw* z;G92{&+ofzC7p8E2Ofki4^vpPf>(UyRyx%>v&-OPbp|ffK-7vkQ`~Um;AeE|MTVN$idw`wy)%7#RxE-;@3L& z#2k=jXpjIgPzNr(@{Npr_|IW-64u|1vknw!rEyt?KoBs22NUN&94d}6OP0W*g|vVC zGydiU&t)_ISu@!=dcoiB{`bp2cYt&e?$-eD;!OENW|XZL02F><`m?_`KpS|+b$`eF zH@_BXHjph3BN}v6MvR8gKLA<;Qb8f4Ndjqt5r^&@gu~{71l)7%S~lH#FDamX=O|9R z#gXix>ji;qy2=&j%Ar=`Jt<#RjB424tNf5z`yS=*;FbU4D__sN4_*gTQ?P!$clnh< z0-Z61LFNT0QZgkF!8wPq7DUiXmZA=uPyB^Zp z>OmSE#972Sw6mCbb75o*Ivwsj`B`k*yqO69+@z{YA9O(=kE6ouRl()w9`XeCh}`1y z{NuUer#=6c_GD&SWXgZV?=$zW{>&@?&wc^z7?i>W0nRxnhNw=8&OVRGpsd4L@wr|B zu_;P~VEIzi(!=R|@8`Vx(({-FiV+yuL zJl68}dH{Jmo?C_wyzU(w{-O85#11-l-i5Q4uu_Dm2w~uhL&9+8MAmvYupQ%)*q43U z6oZ1p7Q&nnu!=j6Ue4z6shvQ;0;%<2kORQ3p1?VWJb|Yqw<<pzO-iQAjCUAiK2o~rD30Ps8*Ba8Vp9&ru3_X2X|uLB=?#T!`l zf%n3W?R4&c0I4={BLf%#6GTWULTeBmdZb4|8Y3dOcI-WgH1!pNCPY<==z$?vz6d&S z=W#38JU&STzCef>5D>L*uoFaz+talaG)eg|j(FS+71jD7Hf zFtr1I{BvBV>6Jf+VU)xVXV7~%@vtYi4Ex8rd%%E+r_0Nkj61?00*O&f2t3GrsOza@O z=YCwP;XhCWH){Zt#@G~N0tmvaa!5m`gA)f@`B0(RLK%Z9MM$khAi&Dyu<~$dIqp1e zC7UOvy&Gu2Des0l+w~qX%#1shNyH;y*#c%z`JqXI0(*m);-Z80Ca$%?entjQ9t4^7>c3kV*Wr zX?Uy`kh0sb;PP+phn&EE0|4tX%b(xW+=}iB0J(+j05#xmFMTbmKX@&SPmuiNM@YSe z8|*_&=${mE5EYR^0UzMugZIEY?#h8_)KDT|j1LpEMz!lGLbM5B)e1O#F<9ZwV^{Lf zbe#fVGZ3)Op9*#kPkKCo%g;W<2|OveMKPkYRG(vK%MXyqOpILvUUcb|%>9e^`-N9!;@@HJhcd$NM?XaBzHlQ|%J=eH z=b8T`LFpg^63OECO#Mw}`K^HDXWKk$w}fL{)n{Y-S?eD z1o{VN{PWxc$R)da(HfH`sCs>77=-pIBbAYdDhg0Xtb%2Sdt&gom29du2=O2wYG*zm z&tAYG5O^}OJLT`S{=I}>3wZuZU&-7*zYcax!cTsJH0q!;8%_TYd#mh?vMvhmZtN zs8-AWnZmRGfYQ1f5{L+)QaEEUr4Uvf2}>7&Gu(OX3O3amz9UhCRsM9jC$Jk*5CvD9 zeTWm-NwNyR?T@GYl3D&3Z~349qE|5Y&)yG{6Y!%SBdwNKa;3b|18G+ADdNdKQQqTw zN+S4Tq0~}1@<`P3WpwWN1uuK;%c(I_CjgJn3FJS=aQQv^0SN3f09XxU8ny<^xcRxo z%$fgOiNN2qDd1mT@G6e^^J`#y8=W8gn6%ykV=`u+#{$4Ezo=b2fc#gDLPFJ5S`mCm zAc8UmF$Qe{Ofi6!t6;?vNELS;zmiSWruR@X5O7(2aIf<3@_NV<$mG{q{$Ay80vEmb za^`;E128d;{O}HF)p156#(*dv>jUD%a{z!Op6Pc_^=Z$&NGE7(DIB#Ly>cb(JMQGg zue+=Z0=%{U5V)?aB*O8dU>LVyzGI|aiCRSsd<5gr6$%lebn z@=&e0lPB=&K;Tezz~}i@#`Zrc<$vMJnftzL{V+;HJ5IQ9eYf*ljIzyCvAvpHk=_uy5i)Ik_}7Fft;!xM{(C0_Bn%74*i%zghg zP@9JD{s3vTa5|g%o7eV>Lr{ohW5IL)N#cpXJuMjss5B)y`Y6ouWwd^L7Z<+ym0eGu z_quWbAiJjABgi;{%eL+#5O`VvV63OYFSqcT8J0g{XDivkyZtv_^h%EV(|5r3Nt*xl zeWY3S!yeV1|M~)Go!N?vGt^39f&f8bv_XmiDk!4MA!@}DuyQFhQtm!w4G-4aK7`Oc zJp*d@UO*lWJogzE4m=s)YSMwQIgJCnJ3JmgI_`pFw3m8*PvpMuR z;mMx8to*&Al=2qcxo)k12?8XHP?aJ|8FUz;Ra|Sc+td{^N}mHkF92A4s1y60sGhdx;OWq! zF<@(%88pl-elHJ@Tf_uk0RGkUF5`rEzXPfhw7&T*Y%62?b&uVA8bmqgi9u$v0vJQ6 zJ@c%JB~-!ZEzGe;!lJ{FmgTO~*YHr=XEa=fbT&&4=f-JQUO*khAdvU-=PrNm>+T4@ z3!nD_=KV>g{NMTxuG7G2pQx2=#~%ORdG{*+9GpY+KA3Zpc>+c$3a6cn9-T+)XLoVp zAHR+&Q0cj5@F15H+__iKrd#;*w1L3h)}%2qw?D!oVeaM^+1d36e*-3fubuTWPWY3n zU~-)1H@{8VXrS_#|7oTzeJGF@jtEL=R8~|HYTsC*N)?C4*1)o5NWH~fXCA}m zmcK>`GOOpGlWv9}_XP6#LoNc1NjH9RD6OcRvJN$GjMh)@_h1SK`1^= zs1(Ws7_AVD&kTeS7==FaC|I=usdu>htY`61+j%d?K%%@S;CiYCds2gW>hp^84iXT! zC2Q&JR`g}>=k<41W?bPWaQ+z=vEWbt6l#;WZ+-*UXd>DAi#S9ZKZZ@*3>YK|CvM*; z{;ra90$Ql7dk$*B7_B?*V$Hif2=p;CUaZ5;p+M)cpLQ90nG@Js_iR3}W!E=%^#XF% zKgQ2+`_5S}<>dFg4XRT#zV=O|KC}4y$LfMn%3B?!{Lhj0Eyu{U--Z>ZHymcLhWt6$7s^K{5G@a@xI!n&*93X{_`zWEJotu~YDdzuKpUoV1E*s`@EBRsL|3G>d_f`{r(nFi#8SAn*jT*F1qeedium`Ew~T!~W+k(05LKA*WsQ z7MQG2zx8%(s|F_McJ}RWlBWa(2$aHQ*@2LZ7z}l`vrs^A!tt)yv0sQ-3m31k(U6Sob^@UV9DHCb74F16Qko z(SCbx5%2P6F@K)xSIpG=@3$i22h1o<-*e7D&mW`ti+h=S?OUkfy_O@W2!NN8da1rJVdnZ-82r+AX(X+f8rzbru=#k1L$z^o{l; zltB=s&|3RqA++xzECgsBU`{z1mao7zJKS^O32bVJA1V^`Ot64A-Mda0|W%V z*u(b2E>@q6|DY%4KmA+|d+&Ro(Lip!jkH!n1p!VgoTzSyWS!?;EI9$Fy0!lMt>hUB zYcV+b&O8e}XN=~Z8yNkQx6=9zK57;)wHH8OPu;@Vz_xRXBZMX-6(NcuGUIgDY7-q3)UL)Z92o%~Fj0uoJ zfDR(`NhhLKtb|6w`sbg(=B5xR{CKg z=Jua<4u@U+9+<9SZ@nFwHLM8`rLjtRq7U7}_`9sLPtA<^Isin(fpr)W2F^YUHG7Qq z`g^Fn@9pf$Ui9NVgFy^Ks!S;iDVP9_VtwmT9@@j4z@E5=-tremFgnD9AyyntghEsV zflzs?7>grGE#Ig<$k)z$1|YUd2hft zL4^h#6j23(4noXHC&03mq>Y#jFFBRX4M&jq`xZY}AkAh<=aqwwok8G*`zZ)yTXb)S zofTj5d_6O%uO@KODQC0r-B&|(3j4LM;p$n1Ulvl$kbW8aZ+p{!`z+b_TS~?Wq!y*1 z|D3Ziv&X2f-@u#?T*WXjhcdH^echoY`K$k*?^cbJ=I+)uHtj(Wc&c}CKCtDS;s}8b zQDJ~}jxa0|DR2J+tx!h$Ic}-t<{kI)^%q^qNw0quRHtcv<#t-NX`fFw2CVbLIrno9 zpjSj`41&V>Isv6nSwDgI1hgMC8XC;;C&Jp*q^%BjU9^rZu@L1TpnZDKisuIM%E8_{ z;oyoF?`Oo|7k0z;=ezaf%AeQ6d*wfq!`|^8Xx4GJ-HNN#aLOQ|!77DL9aiViG9^eFi+xs~NZ1t8u@Z*<_rVvDg%3y+kS$zXUL5L0loWRX@eUs0<_MIGc<;!r} zr)Yiao5bT2h*oHupyPyC6go-#6Q3qLevkitDp__wlhq3-)g3WroS-5@pfqSOC$B@T zK7yo?@XME+#TJ30&Uy#5SANMn0h@XN$VtLX!7hLCJ`M*y2P0ZD?%d94zT6Y&9g*Dx zUU1^6EPCfPP@l%#atp3rCow)J)NSg~I`e#lB%kV&{eDnL-Wg_7lqmY2`&@#t*-YHM zk&{34ZbFJwOo7lCv{rt2sm|(9onW-WC`}-Wd)nLB{1idpx6!UKVC(6@5S6Gvg2eLpZJY(NDk6-@WCnEPL_!Fu9%9H@-(axgDbvNh?MqMRgK% zCn1SrKaVfzWP$Jj1OP(U^;b$`vU%YOW@UDS001BWNklef*JxmkujHEYe$(4J25dcv68&MB*jd6LB-8;#6A=|6h6YENGd#-B zoKY%6!`yr4FZtuQy^gVU$HR1k*0;Wg+xjRXDQVn6HQLy?jdWs6oFH10#Ib+c(`292 z|34)WA=G}uN##5Upro_Dr+nzV^z;#^ znH`CINi3IN@-)wuyAeiAPo6(NU?$!dX7c>cKjvhXy!*YL<^SSMxR!VO1%+skG|TUc z;85MdC<}-?u=t=SD@J@;6X(mCOJ|-%ao!jc_ddv}AHF67frv<(?&XX4v@-%q2?|Z1 zH21{Y+45V0z!TlsuJ@J67_jveDwM-A!vllN>K|soym=J+`{~r`gyj-8O&DFcfH{j6 zv1P*su6)C5=sV^Js7(?7^e%X03vnYxPfugx7Pi$!*XtyyMa2m!Nr*db&>G$8%=ncD zkO*M3Mp=jQt3_xuq9mI!;0aGHf)T--dK&7eHFTz${OHv$Wed=!{mxa|WLbc0?*S*! z&N+h2L(oqn2zL;(sP-RGKFyr=LaLkD;zv^93tz*A>6Sh&ssi2$T zu-c%V%fg$Pl$W>s4z<4)f;|QCbs|}Nxj?>ek+v2whSJ$*Q&=#MiC=Bzk3Rlc2K#2w zUoJCiWQ5Uqqx6+4=t4lJ(PnzbB#%D4g-x3uAZ;f6WZS*0CwVpSZ@s5v_eq8BKkn|m z{C$V-+3CD)-m_S=WCbqNjLw_Qyd{ennm?C;(ILvS2C=CheVAI~|m3gY|Q1ZE~rD{l;35K=hzc@*c(W%8ki`TKAGn8hnrFg$0NzTsJv`zq*26E{25 z$0wP1WGjzs+Ddinb_U83fB*GQ@gSTB+``WKy;~62m1XFnMFb`UQlG)uar*of7cO13 zn#!yJhUU$te{3#8bA}k0Ge%{&9}x(P5hjWloHLsRM=XO-X?IYaHqvfF z5+kiPwiQFtK~jh7w0+Fy1dHFVJs--s%P zL<6c+auTG8+&$rzc)I| zJKLJT`9~ec^0&SV>NV0Yex7uC8W)CsJ)v94mp288wOHpXB7GWA?fbRc!w3GVP#N!` zy!NAPHnF%10x9l+2MA6$f%3=z!|gh)`HL7B9b#}~7Jaj4(KkFwP!7?e5fxAjL&}wY z*8lS7+&a1Wo4~aIA*cY9-Fc~YlHCD-!V}Q}P%J_rfbV{1$3vZkZJvAB;Y%nD^ihZk zM3smjG-w@=#tEHPj7vL6oG@8!Fgo1tp-u_1eFxI%pc*Y)+=1yPlElz#KqrPcfiy;S zV((2jzX5|GMT9RoJn9&hzvVs9m?r(= z7qHc7BnZ07kASn*Z=T{3a5l^NJ8&slWS_6so;;K|jJS-n6Hg2~n-PF13hme4IRb0Z zX-ag`i3B5~)UEK@J2o&dJW9DzASy;gl@d`{#9B+-X=B?7DzSX$_FMVLegE}!;H+6* zXNx_PmvZa>7!cSU01$x|-;z@*KqZ1%gRtQn6Ps=L@c1bOi71sqTmmk!*hYiNhaY9z z{hQhL;3k^Y25~!OdfNnJW3zo~OcZQ>1lMRF^(Hi%NUMp&2@=PCaH$N1k5{OE@((U+BB)Iq2~xor5< zE@c{zRrp;*hdxskm0+L<{UP-A6AcZ9mBQW0gGlT>R+t$~}GAgxYAGbU*_QLPp#O-bW6 ziSiu4zMcfMrzD49<7{`|!3YI`Mx_>IG+KEVQ9Fm~v?;DT3w7ktG;7m*?_FB7R>TD$Xmro@pOfqGqz{56lWGW22S+S%Xo3ddK$rE{Ndr z`NbiMIs`POa)~G`PzXaR#WHhd&!^m9p;#_6Fj(Pt-tcNvC4&1NpmWF1ag7G9QA1T5 zwCi=GRzs&L&ZfkfCm=3)oXF+C7SRDl#P>?z$pWSQ81gPL*hx@vhvM01qmFzQ&1#+R zzxxer0|xZWtQ5%sKp@FMAOnIy1=GUiul^0Q1OEp`Mqqrn0QYsWnTG8A4|9R5t6s}mvVqZv9#(|)HqgdALV%5&ua35^q(|vxe1)UY}WDm4+DCN*j z(47v2Q%)yZbp*{?i?gr0jvX}Ur$9jmSy{Ot)^*#1G>XkM*amlBcGz*()!X%OM`N;H zjobCfwDD*Q*J#5;2imC*u!R|iu`6bm?+c(pUxyMFpctWx5n*X4EDiRT2Kom3`YIU)k3n-A z@5hvjM2nX&cG}rY-hLC40-eF=o^FK(dQ$FVRG%gk&>WDaOnq9ARIB|$gpZ0sd z*Vi_4`vni?D&uw#=WE&|L5W4gVr+`;v?!i(2GQzOY}@z{&;FYaFhQGQwo_(|#bSxY z5;Jpbq>aG6?>gh<|1)t(zk?`taVn{}j!hd5m!{AXaH)3?cb(7j7y#%3L6&+p1tevU|U_x>0bDj0%;Em~K1{hpwD@qwo^vkM+rG?{cupW6nxwKBVv=zKL!qx4EO?IT;tOEI zuLFU9fss)d?<)s>3>S(ZbxigAO+Lw|30$yZEh}IDR#dA_^6&qFt4)vwI_q0-eg;5B z_&M>#K516`BG#|%zFvzxedt`p#G$Px0sUM9K|70a9wGf%gbAUS4S*I4GsrLWe%M_x&$>%SSqCr@tMybebft*^b+tG>)6LT}zQT zMq1Wa(%2pzU?L%wkuk>}b^Jqi$7Fqdee0T8 zggBIUca%aoAx%C)id45kV)u0#Gcz z7(@;}F91AAq?N{5p91pTKEC)R+s`sf7z=LWf1^qz3WqIb^z?I?zWpX9#CM0~)zVIT z+?cCC3Z|=cWgoy_avt3Kg~tJb-11k-0o{^Q1v*gdNd0q@yZsH|g5|4N`Nls&x9Y^7 z`y945finRj*=Cr|6I~94bq?z+BK~2Pu2np^4wW4_L#vJMR{a@K+0N7gX^L)jD4u#2 zg|(|0-?)Vn|JR2J(DYFxRN7aJ_8!@3Hq&GX?){73zxJP|8?{oa-PWykGik-GcB9pr z?!=vXBaLeo*KQ-NB#R6))ADNpKmq8CY*s!LK!YymFe-#5475>!2}6)ji3`@OIP$@G z+f;phH3D#9t>wUUUh2zSmQiJ&!%Zy)DtTYko;KK%(^bM}R(!xx~UGIrzrNT&m0 zQEB3>hRe!mGj~~KC2;;8?)$~wQ-^a7Ez%8j6hM+@#$UYFWe<{UycY@;ii;0pblo{r zZ~qEYE(-&)FxxojADV^LAZg};3zSNRN+K7Z0rz|n*7q*@Kf~wuvU;iH`p71;EEDA@iVdB0`%>S3aBm~AN5o(i_i)WUf{AYNWCVjBs zeOJEwqZ89pU1OSG#a)w-Nvl`IsOiefSY1Nzk1p)(P7AB!&ZDEP-V4t;J>Ip$?YAr^x(u z<{^{V)YtjDocO_$K=KII*gH1&tl^1H#40@3}{$b0V!5M9I3L9Izk13DNtIv zf?2ikOHQ{lp1}Ww(S@4r#eyNr#*>fQRDdXrP95W!@}GbBN>;t$ZRkdg&SyVETA#vd z-@=&KjHr@4y{E9wqO2nk!Pzvs=7Vefz-H+^Z>WT<{97rX;c?bm|0KqA+7#BEO>xaC zChy(M$p8CmEZ(bnganb80SrM;6A%KANCOQU-hSSzJ~}?Wy;Pmrp(dv%I@Q{AYq~Z) zHQi`bCmZ!0jkq~oBdMm)jy(Zrv*Jk5l|Y9Z;jQ;j~v5jjJ0TMG1gLe z&bgT5k7IhW%8##mCtLA_`g0b|!KM})C$v%MxPy&5h$&E*zl^@Ix$L;(o7~q-F9L2^ zYDkK+=MmR-V4Wg$*-SE(mxT&0vD|6l`HPma=1o_jn{_&$z7gB3VwJ%eot5|c^>N~| zEw1vP{d~WJR(-fT~6xThM;!$gvymvFhAOG9O{m3C;HkuJ# zVUw%Th7G@e?DPJyDQRD7Q<6AIJ4sxR<=QvPA5RA$PsS0Rc z0jM+ONBfORbz%w9gy_ukF~>cNsi_7(`LlOofWE~;fQB@HG{vTE+D@>}5Y3)PX?Q-B zrOVm&rH^4_Vb%#}GX1N2NXH+6z@W6oS%|F%Zn2hH3P&zl!rIrr9bK!_`Oh1$wHh`I zNVA#-r}AP(Ay&S8IYs%rlN@L>{GOcTWwS;rKguo}+>vuKxfftuif*?koc=sYtJkvQ zfh~-F;_sgHc}8Hv3+Es8k8PV&V(XOPIvwYliR(;t;-t|`I@?=GQlFwV)kc~zv=U!d zXVb^Y|L3y%i32^MK=xls_NoLcPEwOtD>k)3Y@JG6YSOe5wmYrDoXV_??RKNF16lKA zE^Zw7#BE>ZEhnFiS~!HLTskvxV3#CmUFKZpVM%;7@-1e{oO zx0cgqRm+SUs3VL47iyf2(21a;kV5|uL1lpQ zqQe+E=OSjUeHKa-Zre6mtr|8gA!&kAio`nN)Y7!DX33#Sez{*Rk*K>z-XBBxm>W-l@xe?g;}-R;i`p4yMzgxb7TEtJW~F zaTBAT{QD=V`Y;R|o;z#tKTfr4ebr7&b<%dy=ro(Hw9{5^p-`EX;zrL<<%Y-?IVjEVdi(gDA<^Q0udsA|SrBG+&s5;c#M6;&75; zvTH{Y$jV6b*i^6Lp%jKle$J={jNzY37mnao@hI zSDY{PbvE@)PcGf(_i}F>N|D9&KF|ro4}(Q{;#wm<>P|WYaZGvLb1AJpl8Fa5Gjjb$ zo{UNWFdH_kE6@ArWYVhC($uumG;Y{9Zly`RnRe=R+nQ`hTyJ8h6KHmz75l`xjr~Xb zTG#8>`DNV-#?X_^#y}K8Iq=7D2>k&JgqV>4GZ3J{f{vn+Hm!%#sdXFS;wO8-OMv@6 z^pBW%qqv7QQT^m6uxW=hO+6nV4(WX0htS^dh_QtUKoefE>2^*SyxxNNtMv>W65s>aj`Rvb3(emn@J zx0m0ya{E-NPw_dFDDV2)lpswgpL#CEqmE|BgPR%s)IUAx^NhlVW5S`2Hk>WDT}&d9 zSfpWb%@n&ML24a8iMiQj zO~)l>P!}H1k~XSO(i4~hK6TrddHu;}VHVCOTC|8{{dz=YUVu~N{b=IIg3kOZ<)8uq zZ|JitN_{?EOWt5YM$-8r0Evp&2k#{a%M_O`VdTW;F#g?d`83|(046G6%EN^7<}+}{ zX+)!QDGUu^`uZT$7^P|6b04l)bQl#X1>_6N5x`^Jwx z>2nRkh83#xk5$($H(jFI*p9`vn%JoXH{FEo9hi)v+J;5~%@kraqx?@=6`nKz09eoM zI5SgsqB9pk6c~pD3L!-W4l#+iupj-P#?|Xj00IU4W{Cyh5#Y18eVNyud?w+-1w@M% zliqnZ+F8iv=4)|Cn)tTZtll8!2M(r!As^cK@@*dm`CKz1S#~$Oc4JVf!~W`CRR0jg zC5KZv?o=j!{v)(eg#G;lgZ&hjuB3eQu|#7-=+Pl`r2tA}<2Id*57OSTjpo!iOP8-@ z?Q368VY*7|Qy(K~HL+U!STdJwV&WW1tk29ihjW%xvaxiMwS{Yt#8Xx}M(E&Ff{P;9XrR&B1q4ETqe-FX ziwxq&&V1pvn|SppXA#byOR#t`$@)8yY-bhQ9gvsjVf{5b@#V++`hnR~hZ4aPg5J8| zd?Sq!0R)Fb1)(n^7K;uF==(Pi4h&IRy^{Xp*D-m=9R!5}!K_h=t5y*naRhp>gdqU@ z+`^>VqP6i?O#k;US+MdrR=(;=g6SH~f4_lrYCCCQa84m&u~`U)NVcD$FJQ8QZ*UQ^ z?|twbI^XPttfyamXdQIdD7*h@iiw+)PCbv(F-NogSDRVzng8u4A2Va*G97x1RA9qG z_~;a_)WEq8635W6FlnKdz_t!dr7&&%`%Up|e?Ai8H&TB1%>kgx2{^h9BDrI(^vn*| zp?^ftDTFBmAv_pBqYY~U{QhToTV#+O#q3q%vjaEX_GMmi(wRi_$A}L9|Ji%d1-aGHSlUR~t zc^5_744uVxBrl5X*hy?h)%{2F1xXnp|j!`Tx6w8EdRL=$J$1oJ2iJ1k{B zf8~mDiKM^juK? zeVp5~Pb*A@bs-(u1!B110_2=+*19l%UhsW5hq1XId*QqTD(~uoN;jof_hJ_>rEAqn z`ZjN6^5wmx%a&2T;z~;0B}huR++b%WnRwx4y2r=4>L2W)IzG(wAN?VX6DM%S4+v^l z3-u{-oS(eNI5La3`AtG*1L0l-ZFJ7s+R+?{=EHohxzdwyU~(7QJSWK;q_r8UxBV#9 z!Hpb0c$BsO{r8!{YqTZR*UPjJEBm@&&sFfi2=vw!tt9wDvrave=*c z^yfio2x%N)NfU0a3m5~w{_t1%@Xha|Yspf|tJaV`{~TCHp68Hw0Wbx*uDp_|*IvcU8-S!t zZU37jukB&p%{!@#k5d2gm$9$!$2rJqGuW&~?!0?BZ`8fS4_TNEXK}etg1O*ra*j6> zdZV}T(`Ir{;(WY6armX)8V!=^8G3HHlkQF1IDYsj8~^GLnv%a;^=-oU5-rsBz@7>` zFclFZpOW#1O0oQ52tbO3;292{NY9I8VH4+Znh@ql zfV2b$t1#h$V^HiO7wQV55a|m0PXJ$g=qr5WmiN%LWEttom1HkG-^{|oc}JNaQRl}G zSZi=$pu9WfwlD4CXT>T$001BWNklk}!PNSW99YE^*D(d=i^^@YgfCZ@q)=%{MZ1_y}A7`VXlC z^J(>E0X^Zj!}slO*z4edQRtrW0N8q z&@HV=V~zF0*P-Pc+}9106&RE`=LGb+bBT#C27K+|ukxX7x6!@)N=nyWPvg1o;%pt4 zB$Q0Z!*YItjl?!Ep`Bcql=6Zbm*;S^)WbDX32c#80wguxSvZP+78=%JQqJ)N15^@@M4x_F<#^nBQnFCq z`5t;U-N^AnuXF2Hzf2vk_Ln0-h$)MJ0QMyCz%=wUykD%Ac#r;MDa83hH=h7z!j|zv zdiy(-b4>tFeL7m}MA}N21S<{ulQ7G*gNlQFRUg_IlnM-lQE{~S2YT@o`HjcE#*c5k zjh-u)Qo4Q}_Qmh`vDhXdO-o_yxxW?X90?W-xUdA(h3<6cX7i0>!}BDm!RCIw0rEPS zB&-VIDb?hT{Dl`W^X60T?Iru8|AIYo09%`&F*Svo@e8%uMvZ#C7H0Cve2Q7_$7M7V zk>=25jKk!AUB zfC}s}-sbPFdC6Z(VBEo&^}s(?f|1;J@d<*rpC2O5f4Xw6380xLp!T_NAww_$N`B4D zQkdPkocO874pd<>37UWiE+GN&2{^nqFa|vQt#9zb4Lj+*>I%|TgXAwhi_PkQ^NVi+ zgfvZylgWizH#J9!vwqCE%NjmRXj0#@nIDXkBnhsO;cOjKpN5xTCVTNEc=Hf>qfTRb z8ds}PpP3?W%us7Ie0;xAr*18cEG*wXcN#odDGvZ>6$n2gi@R z&Yj=*Qzr3he-%#vf>KfWr5|^B@ZUcJyfcOye+^THUWmJ2MSa z6XY{9-qG<^b3Jj#!(*+SnH zODL~dPyM-PaG77yBEe6u@$~9a*$g|)2)-#XK;-= zIew{##`H8%>Av@EmjFLEwy(yv6bgciCa1TB+#2r2Y#-brQi z4u*~#;qN^B->Kszf2y{Us-M=rJteq*%7dTW1AEfJND|b3=VSb%sV4#P_FJ``w{kuS zK(v4aaKZK$Ez*^}L(r8&nrXw#?MqiOaLv`2 z)f=$8pTOh|OzN|@e0HF1b^J+uhYo%^ zZ)!74XEidL`%FLQ-O_#rg1ON)Qbd4g;0wrgVwwn^63{bvBjt_T7&>~C4?XgiOykpg z#pXAv?nLbqn}5cq_ojHsUr$1u-}se#hEs3)PFXMcCC;y{iSt&@Cjm%tav|fLf7Y}# zf<~Bq*cw0AKvMRLjYgg`lRL2C*ig^ZMesc5 zx@}^z7r&B;KE-Y?1J(6gscgKF6K}rGPdxh9)PMn6<5omRmp&?es0;Su!QbtC2)v&A zyifFD>iNqpwuzU~km z5a}-(0knfw23Gvl{_pc6NiPf5uOk`UjNSb>E^qj#pi4X$!Z|vlLdRM1OLUWamuwMe zb?WAtfgww)oLfJ8gvUOOaQ-A-JZW;g(9d-)+ecDzbfNxX4)-^FsL$f(=AQ;eQa_;Qn1hqflfi`Z{(yRT6*hmHzz=UD z0p$K-Ca6ayT-+HS5pZcRnIuuj_}Pd{PDKZ#E@>Tk3F03}@tyxG`(NgE)6K#SgP6f> zZxXzxG9Gl!_0a0(%@h(C}7*$)J{d@Qd0%?qJyYeE*rm z5BkZ$4`r*rjo_F2ep^aV?Tz-hrd|^eA3^H;uwfI_u@c@a=rXXc>>F%Qq`izGkjx|5 zm*PA9-yC?E_tV3|)vIw^c91>!nD^{*sua-D&Z+ym)HiuHolPRZF5&ghDOwpPbLrV* zkn7*E{V)54AQrA%M`_azP9A@qk3If1W@ruU5mjFUN5~)vx&4zq!_S0N_^AY@Oc>X1 zywo4FFqOhg4q5JB2{T~J{=B!Xyln&^Ae{zR^^#u*AU9wW$Ww0~WXAgkL{k?cI8cF! zG=vDD#p?1xf|k+r#{TtzmwB%(vv|!q(oNf`?fzEtB}*xi6begv4FKQe+NX(uxk0 zj87oyN?>2fH)=CFpdUoE3!OytKM%dadtAbzb?ZqsZYO{Gal(wLP1|1vRcqkH;F$|s zgZ9ol8TQrH{<*YC(V9&Wz~sLxuD+Jirkgo2bd*m%`EWD0zl)ZWP})v@q(2p9g@=v=k$kKux1J@1aLM)X2wh{o)1m6s}UjNl8r(m9X4ImHf z>Y%mGf(c^>jMrM5(E)MF=oc+a?|{EK^cwHZ%Piio9=CA^?EY3$+RF~;R}?nm0xey8e?^Q5no1NcLz z&$tlhCwTacAJ{W$LV9l=;{49{d3z$fnhODbxBvtoWf7PmPXb9;gU}_kR=G|**j?)L z0}`N|hK#`k_VY)&b0HtW3lvr)N z*h_r>@;hF%?NWO#De?0)(|2ik>Gk)DIxYdOTCozd>1Kvcyum-){YW#;pK_|Smwq7* zzmgx=)0@$Zy4Fog+K&Ol!4#NsFl|Ge-+?`T>aD-+<$@8wboiVEH?MUwc?vechYB4u zN?rrVjh{mR<4GWOAx}V)fH1X=<$`}%4dAPXU*$GeVe#O4%%&Yp5@-%rq$Tw!_|)Wb zDV5kU<_KP=X#b^JVuzmwy>xI*0wVPjVEKxbB%5yLu=in zslKcQd-Ng!KU^dP0G1Z4}2FKfs!ngq&{u9oWQsk{KV1t)@ zj~sf1?Y7L~LGKuJyT3()mIeUrnt)aHTr_X)ozg5C{95vBNiQTI`>tBC5;on;$cZ=j zKLYrBX-(!KnvxVn278ha=g)k|u4coiKIfBq#;gzbO(rm7y~8gLn>}!mb)k!f09JVL zo9M;a0DKoDzatQ|LU`}7N?=dwz5Trn|5qmV zJ)Qu@oL{DE48L#2LKeW!YhYLSDA+|)E*b&|8UU|?TkM^HLI62n%OOe^UZxF>LDCks z50<tXhVd+mBOSVMr8m8bD%4MeO+o4p_Dl6 z(^MmXClBsnbJEM=je{__opkqO%}}K#eJ zI2S;QQ~$qH-rgdSn<4_x<^Z%bz~u`3|L>EJ(4gh*7qbs_t`L73)cz^xwZ8i4+}r%a zi3k2MyyI`gctU6!&;LT`HWwrK;UXjeDI3AO0B)Hd8R)``b*X1yR|*4%(vU5PpH?gd zy3*hnbRlgxp~dphuHH$UEZd&A^eFgG9Lp?HqXKx-Pzw_Xq4Bq}R=RYl=EA(wAWsL0lRz(xW(Z&dg2W}9n}6_+UM%;Q2!nS z57a`O-}vmkX}qO63LHzqG~TWi=dTmu{Fegw;UXpgDcit&2i#R&6R=6pyi38im$XcP zQUH2$>;QfRq6rrqgE89+U=v#T-n;ic&-$LlEZn#jvw90W{dk)u0Ieh%Xn)J^m;>jp z==WzhRq|^;k9=OeVkK_#t&E&_onKUvKaLW_=AD4Q?#J^R7rgxho1Y;0@sfYag@rm@ z=o-&lLS5maCxAD@=j-6E#seM?`aBFKvL^Thf{!3^!9>7k4eqZ5O+ZWQI5Z?uqy#*( z_j%UzEn(5RH6&{`SOe@0SGiUm``T{aUq8qJ6P1;HniXv72vYZ0IPT zQ%OFeHR!Oen2F)DDfum!;Lw{gA-CU!3_rZ&pLAh~?y%XXE+O#4B|rdDc7S;b+%>K6 zA4zEJkSruK4wsG3CpaZfzyuP|jzMits(N{P&-1M5Tg0L@Ybf0?2;Y68Ictvg18Bd3 ze1FFrIJZTs_$7+feeDBS9wh(x&{2LVNd6vmoX+r!-rt_Y&*amawc`Au-jCt8QRg** zDHrBVl_VbrEC=)Yd2EYwT`m~{kVZY^Nx+4d?eL=qUC;vZ@V#jw5Cla62a}K|pgqNM zkT`yHM%nJYFR;3IAq&^8p>+Kq?%5}sLuW{CI7Dl@K5`k{Eve>N~@n+P04cYD zc^uqzcmi-OGB6SnEc?Dw3ONL6&(Iy+58uF9>mS4RR8^HhhFtDe}scL^bxW|M=I~vfJ zdz-&OSd&jO`%Ej&KN%!{T_pcwmoV2~as+S~c(?cZo8S<1AxtRC;3dH^ST?O=%1JQs zO~?~SqAAC;2knJU6JhNSm? z6YP7y96CSEao)=%M*skafE$1Z!Cp`Eh34SbAPnY!Gc>0gON}Q6T+jqcQJ#Qw5}n+m z(}rJo#zmi6J6nFuYTV|V z7#@0^FFpAP34SIY8PXm5VuT1%*ptEid6>Xc#rb84?&Em-e~i|8ef8k%vtOShukVs2 z09{@KR{JP`O#{iRsDMj+Vo)jkE+r~Dpz{Pu_|CI1Y(0r#UbRA3wMwv`h3bhwr6QOqarL?5DXjC#(S8V#_*RH{C z+R5n9QU3VJN9e(i>gzMG(7*!YiMtQ)3rO*)dP$J{4d`(#Z+}~yAD`hj6_R{vd6;L^ zf&JcO1cHP&2~=!YntUk?E=@wLID`^P#^4-S49?}0 zOo=2-dF!R`(6ev_^VYAXx_&F!laB#D)Z}P&wlXc>K$({0hxYK(<>nXAo_HOq5fxv@ z>*IL8_yVrHZasF>4kk{%!Iz)-X46lQm?*|?{QK-q{5td#KDS@u{MLp!{7e+*cU}va zB#i0{1Yo~1hrkbWhyZ>J%vZpz3w=reA3hWD0T}NPG=T_2dp}TviC)KGYScUc4sZ_R za=&aemaeWIl4_M>-+7#c%U3aP{aPwpcH$m?2=EokQqj_xyYUI+q7}&OywdnOvv95# zd2W&Xq6vtzu8WqM-$ly-C?sluWve!jZ`{H7@Nxd+Z@)n|K|3(*J{)M788ruQh6z0D zVPKDGt)DVQ6z6w-U(E%{pNDE+Ie$%aLCTyVfLFuk%bov!_Pe9KzkOm?s zmEhnwjQ8S6z~FmG;zWJ7q^3lpM^MoaORDf7VwWdHL5Sz{8=CX`f8O>|e}bex7p# zum||C2fJ)S0w#0{?Hnu{NJ@SvaXE!j7wn&e$!?_yG^JI^kXpz5a*0x3AHChZbS+uI zmV=w@AmwalP|Nj0Klta!WPbqbxvTXlVuUVit3)NE?ddQ#Ak7- z%X8Oln81@TjhBn!{5Du-{}t>$X(&{PGROOpq)APZ8+ zmLRQoA}}RLyWn6QCdw*VsFFg-TB;R`D|OM=+fTWF0X+*B(S7CB)ZREq*YazqthyHS zu3Io~4w2UDm`XQEeHs!&o@GtRR|}sq+*mY%xhiV3`Y*s2@XJU{8L1~raaF^X{DY6< zw(n%-#1Iev+3(U@PDqjxY2q+>$owKWZ=GlT+`$O!?f2mC#;g5xr8Ncp82|wd-0{ei;-g0HITJ52` zyN|ANH}e)>P4BgX%)fpuJ*(Ezw{|@}%a_r0^-8jtQOXM!)3tOl$)+v1lf#&kBbeS^ zlBo$YmqTuw2`tmJC#HxtFc(b$?d=yQpSJmh1Vr-7f634MbCT`bsGS_<>EHiV`sXjA zT&dF4*GF3FCM{KPSw?QX{*;Dv%yHP$1NU1W>a%!$owmWlZ{S$wNnk?4eT1pI9oRpa zyIkB><}3l|@*=Rw3kn;|0viY+v3}@qnuPfTBs!3KU%`QCn~x9l_iq?ja3y_9u3+J{ zH!yGYD*CUzmi`sjP`zp~m8-6zvUDlsWmk|*)iLFi($Yn+c@y^NG0c&JG|E+y@exk~ z!Lu|I?oVK*R?QZG8ruNT?Wl3z0ZWYk^-NdC#c!foG9W8@?+|Iu&LyY^;!man9L z#SQc>yOx1vSJSg#F+KAaQ5l#|C8>~SIm21wdsV{&K(7muKTO>{>B1a-IgEr9-x(Li z^AjZhA73Wmhs%Tj0A2vMg*L}vp7?=8vNAEH5G@Ek0TU$g_a>&N)2pw!eofDkWt6YD zlD?~!(Y@?yx|S@W+}}@W-T>ul52n9L+Fgb5Y0|5%B<=0SjZKieeiUqmsW+fe!{vF? z4z`4F1g%+!=b{E6Q4w)^%6D<_3Fw<4)Svs8xSO_N$Hv(IKmRNJJKjz2(j`={SVnch z0xApVQ=UIS+PjcSwTDuv3zOG)<*nBb_8NXUNPZFz>~RNUnFs!{97Y;m3z)DlZNeI{ z4(uOZM&O55e#M+GcZ2y7xPKIe3pUnXvPpkVv02RCzAS3of`jgB*8hrq&O@#@qU1=+7#2r z6C4hc7?$jP>Dm#;oh5jb7Ozg)ApOHU{*(B3UrWNG9R}=|=GH4XqjEWE0Q_`o6k#(m z5PSkA^{T%MHfnBsN4aKMPxTl2mRwIhIf9#+qTJn$!I2n4ni&$~usH1a43&{lD(lyP zv6LR$jeGJ5+{6U-#7VO0NwU#lvOFWpa%S+}r<_)3P;vt z*z4G7OJma}`ZjE3{F~pPbmi5!YB$C?Fo}P02 zm0_w3<2kHYWcZzGcMr9xG2F}y)8i*F$KIkoK21JT$K`dHoS`v1LUnqa?k!ufwFb%K zPv9PZoP2s3cVdLb&|BD}2eFN58dK9`v{KKYHHWlz0$yk$I2&*m9VQ{Uc5`!6@}!`w7CPh0+XFuw)v zpLyq>OQ2kWa+i+)Gz{#V58sp_sRrmO8&V79?jE|j`|0oLqkriYR2K~}Z`}qKd}tSG zxkCBDZ{oiD9bDER&oVgl8nxWgIQj~D?d4l~XEz@fWz= zPm*_4!8OQ8a0mAI%#z75a_1L5Ie`~HQ?%57Ap^;R6WduA+1F`GYhB`VrJOG9*wM;O zh>z31JG2o77XSbt07*naR7w5#IQgy@-YC(Y^RF}ix@e7`=nMNwx7nCxw8D6{Z z7s$(1X6iL+jRvmKpw^fo%dKCB%Yd=1!5=5QzW-1DE&R^Ef>LN}2iVVFrl8m59Rg70 z=VAE(9F;*Q&2&;iY`WyvAnU7?DLGiW^A48Y{WGK`L-M6RfbV<@x_hvB9h;P~W5>zT zGWpb$A99ADGp>#YzYE_JTB@>?BCu&;#7%%i05BI zf_jaHZhTHaPx!C0?cLNr{1HqoXU}i_YwDxZG*WNKXQA#|!F?q76u%kx>0f{^%Dw!{ z5as!m%bWz>A%IZ+4J?}nZ&W$8N0f}8L8P|=U14z073*(d`Op4SN?9HAyZ2*X`Y!bJ zkmWhX<>ZZw%=q!9Io{qE$?xz4Aen!T<~a4XnTe8ud!b;Teu=Y@!Vg;F>valM#$cBu zrtmQK)IO_(O!{xGa0(L5&g~blu5^1a_o~VS}@{+^`frYELu;Qow5w1}q{f*Dj*uTen z^Rou^ET@rM8ibi6@!$^~kc_Z?RJgWGIi@GNl+CGq`aeA>hMv$gKL31ea<4@DrNr|h z3aC?cY(o1mXn9`wUlT_|jvsoH>e1J6n{Q;{#+{73_!QI{ZT<$ijzkxvO?v(HKJqTu z^N7z4d#CUY0q|K^Zf?P zCCEI3uXqyQ*&DPx-Ovh!$qYgo=rLg8jp*}CK|9-argceMoee=i`)s^&oD>--q^C=h zQIhgr43G~Wqx+55aa(t=aOZuF@(u04BfKI`_7|5ND=>*!-m9y0ZI^72p6GTi5sAFRXr=jH>mD~Xv{?AVyqjL0h z*mNU{w%)?nvrl0f4U*81LIg4e*a`f5k?Q~-xdZk*{EjAY`4YfqVUd9$-2l>2#TnI& z@063k%GH}#{!>4LnVF>g>;HzanMo#S#k9w0m-I8V9D9~l3|!B3FPcECx_45sV<4Z6 z_v%bZ;0N)Dohdm;{YA&>|Frr}^q*(~ZumGoM-Jg`yoJR#-onW9Phx6~=91C5^|N}8 zcep3uuG`-sfylY5W-4V^sy@%^5T7~(0skQ8pzdTY=sJFw zqMd6+*D1OmJ?oFIBQ7y1Nc~#nFVc8qrDnosK0HLvk;B;Sx3XyKyO?gKc*Bf#YK`g zXl3+?{V!wv^?;wE8Gp3O9|Qe#pe`~S&eo1U8+$*#rY;&-F*(GoI=#UpY9C zHm+LF6?gw*+}J4T7e2#~wao?N8hG%Fy{`wfNKU_wM@#7h_D(?8;65EdwIl6(5J2p~ zKOIRFm6#ahUW-UU-jj~y>-*4A0t49LA-azo#%;ZcMLTXM-~Aw?dFy|fX@bRza*SUXAqUYYJwIJdZ7pZr^v@gNbdVIL#`D@5-BgE_Y(D8lK`}L_}RdI zI-t)6Y#r+Abj;b5*}&cDzE4LIojm_>8zs>(+DVG~E^VSsEd$t*A-azo!fxBiqMP0i zfds_q3a#&&FqIQ>*PXEEaw35_PXM0_4nHjkB=t1KOZ|##CI75nwVtJSe+oM`LVE9~ zo7sDkyd$AIkvy_b$FOAyu-WYNBCr<$y$ING(ff)>K${gs@qaCqBv6N|RL z7xVPP4BHmy_3`@t)bCv%fISah1|%?N3EDd3C1r$HV|?jp&o>o^l%L6H`~Y0inmesF5Kua?{~ zImE=!i4@}d(7&|`UnKeUu?dikoS=I2FlOsbEZFg0(q|rKByT5LoqwR)FObSzcf#Je zP6Bh106qtcl91%1rKhOo6%$7HIsbcb^#&Gy^pn_$QIh*UQ>gZ9kQ-Vlym6?n2=Mwp zR2@2oU*sdu0N4L%N8;H4IVK#=@|@Ugh_5LnCWlx{fp${p1bY2FiH;XjD+aN?S35jJ z&(Xu=H|}Kqj`xu~{Sae$Yw%J0TslQN5W$?+1m+w8{0b~KA<0K4_(%urHa@Rk)}mXt zdIL*7`bpf_2;BE+PI4;v#d9oKeL@Br{6$i;2=K8(5ZXJu)&MlXeEkmRv?eg8 z2;i3^n_oa~XbmkboAxB1CHH(1J34~9@6(JpAHNryUu=D+eoF_D|6-M2N+-Z;$sXJE zrwgMM0lO3VoU4t3`cIdksQ1OhP;~5>5JC~aV>6;tC@~)%qI%>ocH2!X+WCIm(+@F` zhwB=@LF@hMNI|%tT|WYQzCH&@V9pT0FZ&_AZ8pEbgRh%bqK_o`Y*@X4#rOOyjE&*G z@EL|(D~Df_d$igwcE6s*S4(kdk93uM@qTC}4&}o`bR9Z`+jbL+Zn+cl^f#EyJop{>6=EsQrx2gO z2Vw6w<`@ag2?F?~VDoF+E}^y9q)b62D&OGhjV!wRXK`a=xO+d%sB?bV7>cLr7U>V| zVIycscmX}k4*0kffn9?m22c_mtIeCDs6Z0!JKfgl9K8?PiLJ=~j)~!Pq)n4j#mAyNUU?d=Q@bI-`x&>cZBv>eD8k_6d9t_RJ*`xa0}o z*P}SU24e}Y@^=NbA7K63%`E!p&)~+#;NDL&?i|y!a{5K;OL#9{$TN@X*PTx~vUX0z zr6^iZBndSE=w}ijo~b{8vp7!Q-|6bprb|o`QjZ4f=|~~2U)L4?r=LIe!-(|OB+!;L zGLF8BoI3JF}&1n}!>G7kZYbRNm@ z6HmVb*00{cqM!O-o8TXIt~qgsNPbcOq2=_`15|W2q0S`h1o}>Z*G1Q%f!+z^u}yxu z?QEQaXH&0!zPOG!QbEBvF)6s{IQia*B(>UKq!q;4n*6q-C+I$S0K4Tz=G}ZJ`7_^O zEDLMJhdPaE*8t@F@LuMOPvDXzfL~LSdBm~jGG6MJBJeN0`;*wQF}U~V+iZRrwktM% zLc7`zr)Hpa0)4E~#~pVzu*c1Dq*9kga3*D?fiVBc%7X&Vb}z7zMI2N`R4UqExCJ?BH;vw^#Q6!v`W5+{L6 zk^p`!Nd8#5h^;S!dZbgYU$u^<_k0RFHcE1@_x4L}zl8drUGmEd*X#9(+TRKEMUJr; z@Mi<|BD*;Ta?vp1A}3uZlO*cYrx3?%zJk~v&?zxzwr4t1Lg=I&Xdgh)91HR;Q(6+e zsR@h?)3xt4@(o*RUF$UvJM8mPK0^XPop8WSV*ytWs+Wd{Q{-AVH7 zLrgTh34j6PTErstDpLUKHG#dCDhXUt1aNQg_DjbRTR+9yZ{o8iC+gHi+x;=k?~YA} zBDKEAEa>E8n9V_`+n^I6#H1HzT}oX=ZB4XKq62b{zK`k2ar$3<8N2x==G}ZJHjqGS zyas?dB`+X$4DPyAHGxZp06rgb`!(>J-gx7keX_K)!-Ie6JwJyVpMcN*JY&JzFByLE zEIyhD^csEo7_DB)eQ40@G8^De2lg0L`noZw&jhq_eWES(aB9?p=-AVl1)4bIcvn!5 zewLybe-R@d=pop;&XPJl;nZi8_gI^npzpQ4*sV9QV5ipvMuIt@E0*i%k%Zyi z?)u;*s0myW1n_y~?H8~~Cn_7C+AG6*9k6EAAXnV;DeU+d$>)Ebks$eHJio;F1@xK> z;uU&3+4N=39Q2y3W&?XCke?3NMI;adO{A41MD^gOJs0VyrJK%ah|L4(^hM9CuNxCX zCsLS=5YB`Q9PPG$d<_{PsEfWgA-@D@Opeq4+H2%nw=;0louuDw`2&Id5-&{f@aM2UM=R<~{07+ha3GeCeGOd++46ycwbu78(=dk0Wq@VvZ!_a2)%L~_w zQfMM5vN@sM;nqpL*Q#`!93-U^xoFcN26>U1uZd!|qU%fXT2c?bE&FJNI1}2J>(*Xx z4ZzsRRzwi-bz@S{?a+x3&Xf#va*`Y`b!exb{FeWu-Z*ceJ~>MNzJ26dwllEvPLl6> za{!~>No-@ZKl`p9gS}t9L`dMGCV<~iGx=y|lYqa9*8obPYcb``8b-urR>dx0m#h(rIous_f7Xx1EljF1&5KB=h@qa~;fcTz8>Wi7w6E^MB z(CV@dt3o@_iq!r1-t;j=q@Ya*-9|-{KK31S(zH5h1^RcV*gmSB#>5D{fdu9$5=e~K z0!+Ax_`N8zVAqeqo=brQE?NTkjgaA23BRQ?luc_azpU14fg5gE&yxS;6Xe4qnEQXR zIiy#n>DB{#MC$4EUTD2gE$wxQJDomGccLPdem21C<8;ygb($wDJipn)7q;#g}q9VrxP2tOzp=;Pvyz#(|c>-lc0y2oGh`=q}bt#a*MM(f(2;diqBsO=K@y@=ofocM2SQ&QJ_3K&klb;|T z9)$;fiD6n3ck1+BozdnXVE?AXOI6o6H?Ioi%bTo|4bZ$F%f8DBib+hL7N7;KO{hH zVuYUk`*GWL(7*Eol)n2QBaN2u!GvctEn?9cAt6uTVkUu$jsSjB&Ex~^;4eAoPW^YR z2l3ifgDn1sA16OCO!Du4rMU>FIQz837du}%yzJA!kG;_`ITYFSMQVNg-{}B7<@_B86CrLpz|)h795yfY?0H02krX zTx3LDBT>Ke@e%qD?#JGE3j;gvp!A(@FwzKFrill?wcb3y6h<`e`jLy+CvZ^_z(Z(nrgq;`l8C}X}X=-53RWYq|7GmV>|V9 zpg&Wk7mkL#55bEagV zORNUcQfgGd#1iC$HW5Wy_*hju)2faJ*p!CdxjAS14WfQakxrTaSii~#s*hLy0 zxM&FAKDB6vbha{n`mVBp-qf?MvyeMjw|bCyyY9grKSA=Jew|~q(t2a?Lp$i9z0=1X zrN{?Rq~hz2SOoewa!>^LBCvOI@)g~4e1Fh#Tnfm$Xa~QL0k^&nbL3##ASxXp5$#Bv zq`K()kL~lA7|xUsI(hVGBZF8YK>Zh=6W@=%jDP?D{*f_bV3}30xEea9@b?YpEtfdAki%Q%Ecr>l=La>Oto3 z`j`j*@BRkIXt7`@3ideQ)^W&c6@uy#v;5hVOj4O^b+}SD~K%?8fc%ZMz-!>^B+9)%`{$f!1uoeO+`UaKQ;c zgJ0~{G)Vm(1LYLb0RGIussMiX)^U>G`#f*aTA?SN$U{5+bjO(u_*%`^(w>6-x^on1 z3`Ht?C%{8{CyqO^29*Fk2AH1pD7N_}{+|N8|L?$Uw?R)87A%0lt?-?1lUUc(1~Q6g z$kFp5=zEfT(CrrkI@T2AxK0{^{x4SDH5s@L`*i!orbZF)rD#n|JBbZ2JvBk!_ns#o z+)DpVw_~4ul=0m6SMZ;S@v9R%b1GrsNnp>#LIM|*05tfugslY0Ur9nox6p8~dewRs zeE1&R@gdyreV*f-3Vu=Jw7oCtzwXGw^0NUyE!d}>Y;j^x5$I9J$3BBjoizq}k>(I* zqKVDlMZ2e8oPDzX0YAPAZht=<+|S|XpJv|jt6=GJ*l;5}^(ZEg0JKOTcCHDj%Kd60 z(2*PMLx`VK6GGe;vynk3AVWKtwRxbg8>{-U&mc|=lK-qaXSy~`@5|3)2XAEFO}As7 zf7DMZV!Zki~wTr3y^enU&VmSyhne{4Qp8V;g6FaJ5KVS z@8tyTHot&he~(|BywKTzuK`*l?S-g{)JP5b*y&efR_Nn2*o%O!>yN{PDJ{t_o2dJe z1CRiG_-?rMT`+c%V>1(!Hf&^SXo%hfSaKz--3YrM^D%B(w!bDh{aF;M)Ptzxo;4}x z=kKH;=yreEVUwVw;y7vPl z2~B69XiZYDBCd;q1TF{x2>7)sTO!Qh6V(4Mz=b&fx*OIo|0ACuf9n{@m+m{o;im`j zNF!U?B^BYA3Y~!;OY%+~nP|UO?~8l|QYXv~c%8kbfnMY{kWH)o;^-^m!7q~E0POll zaNE0Z;}e{yjZ;~*iPFOPB$Wzd-`h)X#lTf7yieeX$4;@gV|7`ys+h2fG#pI|0&=Z( z$9|33$RIX1wDu7LxDyfRccCS|?9=xl*U^1O-qTdQPX8+}kPmKSV8g%q&_%vz!!l>->Zp^*OQ)Vn_r}URVujaQ_x@?A$ln+8fp|@57(K9zRa<#TNMMw7)C?xyQ`xeW^3~U1=5=Gz zD&#pXt7C^p82{7%K>u~?VMWjcp88fBA;u0=t!>4cfNskoRbRK6o~%Ov+KCL#R4XWQ z8WR0q zg(88sjR3w7EzvD@cw4A1=#>swwQ?2nf8rC^<3pG)exXhB>kKt%L{b0cJG9&R+T&m3 z+=EkrAFKIAegdfnP7nGs9S@+vUZgtfP+v;RyDzD}P4MsfINWqIynck&|NM7xNlIzu z8j>rnz$6tg4p*DPjZToAI6?N((~Lj&I0M&igln$$K7pqmZxU#cS3V{L-5#9?p(vg& zMLRb;k-=afIdfSesR*!RK3o;SDq&y+|I!E+u@~084Dzk8V~*) znj;D2n(EniT?ljFZ6N^3?H83_oK__Pe-hZz`UYKf!x|R+#3!&PP6fZ7rd!+k&?1Id z!f4xEe#bU`5%6{A*0z07#NbRoUvzCvE=1?W2}IB`Wh%5lFPVL(fd7_T;lO?l{mK0} z3ogqjExd-bw~Vup%+#rmPhwA;fWrrw*}sRR0V6Lx&b*bI;F@b;-KHi97}fT=%oag0 z(J?W}#qoKqtrd}h)D;6(7ZV*@WE#ZMyvQtwkI~N~|7o(Bs@3R!^+oax+nKlhb`l{0 z6U^OU21q4w9S-h#yYmFjI|1AqE!vUbJ8BYC{w`W9nOnHw`nAme$S1HvL-3!!z%g1G zeR_gU7j4?pA4}JB0en;)(B9F{2J~kGcoXfDu?V8}3km34e*kuU3~qTB?0=1ee{>&7 zqd|fpo0`Ox%24iw`V{%Z7;fk|`CBJx9NI_Y$YD$gk{rgLeVl>oH+gg5hV}5wx7(zp zeqPb4Vqoev?G*pl??UhILqLIR_PVVl^8#7UzZ6l&OjrF>#twS;=4Xh{?>8$ zq6fdI^zjtk($V4+Rry~74o>ZCTAIhemt%{7FQ$u@_C=omPN44ucMM zG7ztS%jW+?ko@~N{N>*UQk*f=TuxeRkmnh6bwl0are|;`N61bdqkd>Vc4Qcnf(c6~ zjX(D|1J`ect5?8vYcSt^vTgPt4HRi(<>797e!XA77Mo{rTXZ4=4dzZ7h9;y=L=b!a zi~IvIK(&S$`#yw_rfM_Hd*vmvP1~7&(;Xx)Ji=Jr_wzJ7bmC~6VJI@8?s~gO;JgvQ zZv^nma$L<$E0RBeKQ)l&uquGR{^oIv0>3!?pe5h$|oFHodp#vQG!!LkKeVf?^uAY-OAg4ho ztzaG4tbv=DBs=j2+3N?ewMO$sOzQ7v?AdR55?FCHT(buA>{FD~dk~OFk!RN7Hr-xD zgrMJ7Y!bvayFNd5s!E$lDIx-WkGd{7zLQy?iKHldFg|9wHp9Rx-y`3&oq4x>kmR|C z8LLC7r23m808L1tuD68*&IVMoB^h=7Rh}H;V(va(QQu8|{3(W?4xn?ZkbtwXjj`NGAA^H8{{RiM9AM@Zp zc#xxi`~@&2uV&_TT$W=)<;GZCTE-*^#z8(gN;W)#tBr#Y06|&>aW($J;|yH45w2MQ zSFgf6zq^fK<#}bF&K`_Sg82DjGSKzJVAT8c`_xjo6A{ED71uAni_8N3oU$)=Ji6#u z1Jq`w>3`*WbqR0Na{;RiAg~Nf3`4Ttmd17 z$kvl*TGfSlRW?QDQ1eafwY$f zwN|I4T~Oa+v!|0Puhnlkw-d4Jdn=OIomBt$KmCq7nGO1R^fhZUQw+TNeez8^7})s% z%FjK-@QgPFlEj0*qNge@-jwt~sn1C?}rvYz}K~SjYTb zA0vP3E%?%XP02q)>m_SRQbYuuq<*aKYc*d>Xep-yz7(VWk4Z#d<8+|!v z_;D!$eJnL}{o*VYsV~kyN&aa{{-3x9-u-Ska)j4^^OqO`dMcrP>KS?NaMEML#azQ; zC+mCq-*?CFbX~LZ&FNQPnzW64Ffl2vHr*l&)o@8_8LRmfm9nS*0MB8)3zD zaOG7bFFo6AOD*X&5$bku(SK)326=Q|tQEl76G4%GK)~He8_<0uzJ`3)Z6W6g3D`|L z7`WwwB+ov?Xbp_@+JLqGoJIIF?tv5*lno0jC6-mI^wb->cAkgDN6hIDIeqy)5~8%pKrnP>m@7KhtKBgZyq zrm&_Zzu5+4#`|n+27MVU`_%slix$DYSK+_>elt>|$7tw%+Ha$uSKpqzZ!KZzaE$&P zFKQBJ+UaX)v$4}LvF}2bPmA}<^XU8*OM9QvW?ThWxNr&fWB(L`;f;U)X-J?vun<$J zkoPUc*6Y;jQ`Bc>$g-T7dJRWT3d~GQvmfsM7x2fNqw+&*0Dl0B=5<$w=SAP zbzj1HXDacFYP=z0T2PEGgEe<%L(gX5TtGY3r;{60k0i0AMm0b6!nNjh9w+ zU~2ah46NG%*If@+tt5HzndUR;Hj5>&ey=gPo{45qq!md0u?7(T)-xb$DPDAr>=z-S z->r5Y#u`MdeZ)ecK0QU>-WRE_-$MV^_b_w(7^V+ePHp}SiTTb5x zK0r1)Mtc7*GKvShsQu#j(+n*VUpxDt{l&z#e(dCn!+zS+Y-kY*1?Qg)@MB*_s8pbv1Nz&cBKOY~RusMTi2mvMuOoWD)*>2>s4%DB1g1*7caP4()%_@@T zcQ*&lNF+c26B9uZ@Xv${v{s-Ug0m5UoEJw8W-|-od(;F`1af_Ey1!`?RnDK9nP%S0 z&ylU$LeGj-OuY6IE^pvUkfi=jtpk%-3v}q=;|udSI_R+d5)GL`+*7I^RQ@n zch?YIJ(QD_?(Q<(y$k4FvV`8HS5jGW1zqzOV7hxT*3muh3VLq89XB>b`QLqxsVpN5 znrdnQDJ^xY2>ja4684S3JDb!mvhzE=EDe15FLvr_FrUs*IGa|WCBObm)pr2?-cQ2& z-Uo+{@WyX_j)_oVbCu(eN{xe(^za-eGWN{tEB`x(?Qy(`8gVcTj{@M4P*OXhOCZD zN~9%2nxq&~9M<2DGvpzhQ!16{ZDhM{J_nk>4@3a>!r~Q%p=x&zU1^DODWN*Bh`z;F zQoZ_GdTzL$>hfh&<}W0zCRDo@({tN2#TDAaqM6ES4ka9biO{`6@1r3q3h5j5NiSe6Ip|SJq+sN*^<%iS+&YA%3g+(h2L%jp@aR$o9(A7Oa@1mu2 z->`;xgM)Ohy_T*O*HW4{K=sP&sNT90H#39z5C0Ah?`tmFp=0_rS{*|>`(h8Q+;mZR zPpf(Q94(D!Q}^{0;aY{%^~F-$75t9X`=Wi&Zug6mNDuLCzMQ}R(Nn;mrXGyeK^8)H zdMWF!45oAT^i_GlLJtmubD2rZjDZ=F^0Y~*C5{HxT5I#fxc{HMH;J+O&qt#%h{Pv;)-xL7+CY-hbjy78j z#8xyLEoM$x$K=cm(`R46^wvw6xbzZQ8!x7D#_43|ZzS9N1{gTxv!8{(|4S^;3lAU5 zcMli|KFR0bjLH9EwEoG={nSKFCm+c%C*uOrNl^zIVP(LGK-5Zp(@g$G5)gpf-wU_C z5%wM6;Ew;30se%Q_#&xRM+GQ{lUTsQ?CJ^bb;=|bLFfZL)Gd&)D4AKn%CgC_t`j#< z=Md{uU18K|*2vgxEFCLsHTd&8=QX}Es&$tOtx}{K3mBwf3ZN25{Gfz(sR~9f#mx-2v9p`y`|Q}N+1yLp{Pn$?|G8ysvB5+ z!4~>^pGL%jG=0Zb4p&sD8~9v}ssdM`&XQ+2GuGX4{kLcdtaRTiw*MQ}y#bD{KI1HA z&N_$53$`$I-r2O)ok?@uI-2WGr?vhJ@-xWW&{H12A-+lM1mnM12K}^A;PVCf$IGuni`FAUY{p$CTUO#nBNPZVv zH1*@Tq7@ML?;Eyve*m^`hdui^c=xZ-GoayNOZ6`+zQe4HuHR5*S2x({V8;0ytx(zs zT?`AFn@-l6?$c;gnQ1f}u0>_nsw<|n*IlFPnqo0hQTBzKd+@HIW)7Vm3t%=g&j&OG zbl?Hu%%A(;;EXfisi)zS9|K0=z_?dqT>-=hPdYaB@LUw4x**oWe)SrV@wn9ONb?G+ z2?{P5xic5vaSIkxz=B#X1ga&c1;1&L6`R1@n(T;1_LG1-2-W<|NFl z!n7vI)~=;mT%dDcAN^xT7#urDXK|igaOW?=XZR-Ci?RTI1J-X@x9-p>7hlHejhk7u z`BG-KY+>?(H!yL@23qHzOY5vN$j&)~#+p@#7-aQo1cN-io9qjZV3(J$&+SKxf;PU> z`{4$9oS5YYC-?X3pU0L8|BKQ3ruKPyo|9?(^!wE3PqjVCXLXAr3Vi%L`uTB5Z#=)e z`-5=Zb+B(g2k-th28Lm%uhgLZ1+?<6KoU)uU2WLuglQBJ$3UPf%7Q2hz%fA=5t+}j zMq9=7fdbT_)>4%Qr*Z$w9N3G;>#ai}QgGqH)p=0Jjkg4_(0%wmrZ2n3XAEAj8NT?? zmt9?&$+)DhwO4h*1A_XUN3F^E+U6I7!#`{X=UYrNn z@&e7HN0IHc{n<1&T)@nxOPIW96Vsb7V(Q#;Xr6I4Q|r&7ams1r6Vo&& zr&(Kc@3?$W?D_BT6@a@y-VXBraq_kz0Q~hO+vG=1IZgiP_z`{|%vr5`>HIg}PGikF zCeA&Z>GRezb>^8g&Oe*Rnd`|XCXqF($XYGT#002d@(gDLd1^Ou=n!__KFUMSVtYMG zywD2_$-vlA_0-Y2mVQ2yKV7DqS_SDONkLvX^Su~ zLOW|nSF=VTCaXXzR0TT#Yco*9l38e2Xc^e0&=J@wcn$zSTzEbWAS58h-&gms`C(p;umpHO5z?>2=3UuGlG2@Y4=T1#2bYkMHYX zAhqw)_tEsKXA+Veo7aAuo;NKq7Vj^0Me5g%=Z)uzdHm4@sE7H6!hhYhuzL>&@A@^* zkAwp%=i~g*@0Tcu{#>(7xVLi5RFIV!rG>&l*FwiBZ7VE`qm9zR(nGZi+6B5m2e0Yd z;nh(e>C@7$;QqWg{v15bZif<@ticJAMfc9)e3QhM)akh7+#7c}X+* zJSBqD{!IJ0J`Oo2j!QhgP6DQ5Ey?*-nlGs}xsoebFY=n+U;I6cTemBftxv(r-uY9M zr=5cC-_O#MUt#KsYmw;*WO@qIXp*g(#+W>Cm(P z@IS+U+u<#^ScXvU8lUdNHf90*_e-|PZF5iP`%gPlK+KP0+%Tvjeb#D+|;q#wpJAF+Iy*?deqi?XS>XvqJ)K5N4c9 zUMXtUHF$l1(t%vb?_Q<2)E>=pd2c4ph*2>~lX~>lVSu!hS1R3+Y&{WDV5E@MQP7lBSRIvVPw5*@O|`#d+KM!4II9 zUxwSekE8ehCDU)c9eeC3RlkFXA;aKog?0y&oi^3cCEUV1)%-lg;ln)j7k}_~3vk=N z@PIu5!J z#hb_{CNL8XvOEK4nLPU(CN^v!Uw@W&1)RfDAd3Uaea~Qj@=gliI357HjH>rWGq7a5 z40Bz`>L_lK-##B;M8U56W-9^B^L>~8|AY=?1SoYal4`l3&zJm0?)*t__V3xlb07Ov zy6R1BYeHRwVDf7gO#jd_n01bw7^d-7`M~&$;CY}ea2T)ImlS$UrPs(P&4gH5Gb(vY zKr)jtiv&74O8KNB=~x94MqB%P{@EPV}XM4&%U)CZnxH z5XR5lNzS>_xl*ep&X1Vh-2~R(_D69H9I^{uKv9hjbVf`CMs`b=!@?g$uaf8uA7GG?^Y80 z)WodcYrL;|_^7V=qp5nL<`2TZZ!gb%?BC+7m$Jy5N0YnWKLWD~_gcrKHGW7w<5RPjC<}7hyLtd z^2=_(4SEc^U2IWMRTb71h-P3dB|h#elHs&u;n8 z%DaM2cmV(a_`55v^T8&SChAt9x>}GKF`S7pYos~p+F!o!UzP>$oy4=hE{BP{L2K12 zCMRZSPOm}Mt|HG2S{Yn#nW;Cvjn=v6VxK#N{jFbSZ_;70W1?WDH&z$$C`fhTuWRS{ zc?ukGasglIT4|)9er!C~$(Z8E?#5TTvTw}i|KXp4?bpDb{T$r!D^wL!#uI)8UhwVM zkPX|c@jm~g8k~btJh!@l$JWEn(N@EvIC=)U80>^n&+_$)Bo7cY;lKzL?TfHdIDp9>)H%rod+zlM~f zs*VMtoRF9(7FQRhR^1B$LEQpKh5d!Bf%Nl7Lp@@-8OqP@7EwX$f{9Tjf%{6&za%%OKYxlWB z`#QZrahYV0IdBN#6ju%?dtGdIiE3#;xpW*I^cZ~YF*x;XCeJz(HeJosV-K*%NJ~dS zOW)VEbQGqQ{QbJgT{rnt@F4k~6@Hh-ZR4QTJ1RBh;ypy6Puc!B&?^f6oj(cNuZ4XF zIK1Oma2067tJeyz`NR0vC;Y5|ofaSJLny^7(JnrHe@S6cg^oa1g#kh(U~_Pr9QyQ3 zCO^MwMt))SYI(zekJZ;rSrx4nx0#L&DY;bT1fW#8xF$QBc?#;3X#y z;5c{g+kW7#s_0Eq+T0ELg{z7ZYugG%34Q1JVymEkRnz{k0s#EP#)|~WM6x`~8jWV2 z=Z!4Sn|a=t%$v=rtkGzAP>q^SXdIZ+dv!rR>K`G2_ zeD8<2x)`dS6#FYkvSIieSzm)#$Rviu>&>VG9Gm~nFX*C5X5#ea5$MYaIz=@tPB$I zv-thQKy!l1Iox1?wT{Ypliv!%vSG2hlY_a9 zKl-yf?ZU!D)mxIHy zfCb?A+&7q+YBGJvR+`t{%G5)jqg@;D^akT+^%yOT4_x{%sSCjhzj;2bU!Np(izAx) z@%wlW5fD3;or~UyM7sGLGzJ{j{d$&vSM-pW0*C{y-t}1GWCL8h!_4vyznpM zLw#L^o`zyP0$k&8j~nE7PXYlS>-KqibyILwLK2Z$d`3vPjZ~%@!4=3gaDE2%h@q|O zGX{ZSC1N8907wuXh2F#WGqd?}*l-?l*){O!=RF880)bQ@Qy|Dz_&ya@R``1|Yv9GW z1S^3+{LM-rkXUSE_qOS(8<=?GZB)mOa_|p#a>&3^3Ef_wW>KJ-4imgm>qB%1q;ng7 z=mR_L()?7pv|wDXS5@8RPStJq%5HnnmHm!&ELPADzJK&4Re?cl@#+P~%CzQiHbCa9tU_aLkF}UaL$hi1U0|N4(ZQE^t_2 zK>`Sf7ydywrMuR7nLC;A$9C7i@=*g96}XQ^?JeFL5&x>f3r6!Zc2NsuS7zv#uz)CT zg{3+)4m}uzlcCUk_H0o)v!=zL&t@`o-tSlf*0c!)HU^saS2i@ zqyAkA0vg6WwGg7|zvb#1nRwG}xMN2-`01S-Hl7=CVZi1cELAY!d`OkV3baA^&%Ei) zJB#^4lf~k328#>*VtKw>EFNDN^p+Q0zkS@5EOb4l^h-ZaY#;!2rHnwS{htTF>m6yI zWr*acW>nQQz3wSm^=7nRoaU->HMUwSh6yywq|vnH?kC=4OKzXa{evtp3Vmh5a5t13 z{~loTEjO|D#6Q2+d7kpNcsop54qLVB%~<&W>1 zwe!h)eiClj4*L&qc;_z-cR;op((Ul-x*qN`FzaBaQ>Jwkh3czM?rG!W{KxUGKwmvD zlop%?cir=t{V&wMCWsY`^RgJX9-IVL1FL}3#qaw#h2Qc)f>m-W;-dp;8w#3u6DD)e zR6o9FfA|;S4Hv@UL+IVV4n=QRhamP095tZX2>1upxD}WIr{Wh|sY2nHn|#B? zJJc4_wyK<#wkU16td(sK2FpjKv`dBMSQol|ANH-P5Je8pqxBFVtUv;Oa?g`|aO1@c z`%%^Z$hpi^g|TIYE&9e41zL7<*Y6q~bTij&H?yhfJ=*EE_dB*0j1zeg&0_Bv@j`Wc z-+m?!KgHCQH;`X-Gt-aUH(VJQ5k7)Is<~GZ{)pmr;TKNi3*!6d)B5rIIyVq|F>3ng z6sIY!z-YsVJ3r)w|CwhwyyM^a5eXNGEBY#ekC!|{=9m?@xAMYe@IHMXFXT%GmYmo8 z?eKY@ghRac+Yo+$oxsodNPv@(;scN0nvWYr5&s&-u*di$q^;=QHv@rDLNW|d-3UnLXVTK~C7MU}FnRS2G_SsesfRwt660aM z^oCC+{HdVUh4^Hl!`LEVq=Q>u*$3kjEoJz}ig<`ecO1x%{ETP&_wVQM&VMsxGS!6` zjRv;g1Pf_&OS2-}Tlx)@or6K<=fe{Ibr@L4V9|MD>yfbiSACdGUqb)@AOJ~3K~$T< zAKS+j{b@gbQPJ5T{7y#-GL8C)Dow-_gCxXY?8{;Q2MJU0{n2^!^Q_)*v3CcyUIAZv z%ui#ZCxAdIoT-4PZeGkWS&1Zs@pA+g&$4=01!anf{P{IiMR?^_R)T&T6Tr1QtTji)1u`^#t_|pMOC&CMv{3`)Q z`u{i>QSieU4j1-B;WzkyG|WEv(Vz8k{=NG+y5pC8ZHF+E20CKJVWj=>*O-+M>I-at zjPoyv7pf&Z@z)XPI_SyB0(MuvM8Xg7gh8%w=+DSFUYb$&#IA3I$2Ss_0ezl8M}sAh zj-3(&Uq`$^rO^J;!>l>y4X`1Cz@x;NVg!Mev~`+I8Xx|Jtbr65>I5N-K<4>Eg;8@Jx6j+k|QBCFU*H{PK$SyBM7u$Ze5d|m30%=sZq-S zOJ6NZ&av#2g%a95XuClAX|gU0PR#tPx03<@3@rfxMXM556>7^;DY~Lng%$&&RjEcC zSZ&~FsA9y?$})C0ly(u9kcM-nU|=L@J>wsI>F{xyhxajg^>$1G0;w=RpYYd-!qgN? zk0m+o#cKWf`C8$9tk^5Yt3{vjqF(r~z7qEA<;YGS>WdFh+MuSxNTt?^gbY8+7~9`t zB=}1*V*b10Lp?Fn$CVEEWrN)N5<$Sn6~1hSDgQ%7XvSUol;4H0G{6{I#<9l;Z4)fQ zx;ZW~$`v4hK<6uuvgYjb;k*rj7z`i~6vxRxpsuB(07p|DMp`x%Vv=Ly`;*1~<27M4 zkK=jMIkNH1-$#DyccBLl4}~8S>Nz-X(phD=z>DlY5@zgXdo?*h;k=pvA!HVBpl2R&C`}T_tFx zie`=sgNntdlC@x$^Mu6K*kQvN5<6G|L5Noyi${(#d1Nn>S6+{~>Sksh_94PLYNvyn z4%kWp|9mEY9OQaE!1^^}XGP)9NQ!o5LHNZ$;gI)#1g^RQcJ1Q1dw&%z!8HIIV*L^I zb$sFxl6*=p{NNAoi04zI*}oWG%XrN{2o|KfBC!20mGH-Qufop=1WN$C1>o>6E2E6s zxahcapqV>~bn3|Vr{}hyR zm^&4ASY<*%the&Ig)m<#3j;V>c%FSxz2Dz=0as#|z8K+$7XbhOpWOQtA3S%XXf;qR zE73s@wUtu!MV#Us&L|m<+$hEg4V1hTvK;mXGj&TGpgN;I+#xmdH?(l%IMauA)4F0i ztt+o*)g$+_z=Cky+*^MgPNT&cEC>l0jX+YgZ4bPLsi104F~$2chX z)l=$U8vZ&RKVQ6d4s(;<{hRXZw5c3)Dy3T)7E5Khg2ey|akXCzBq_j0UZn8H=Xg== zlh5qo$Io0ZT9vAUK3Z8vRXA`~!DiMk33o!}AS(r}6jKTf^@HDau%&*%jM3mnw;;=4 z{>VI2hj!Dt@_OySJ<5x2IwRViDeIBc}#8BTPege`G)EF=g zC@bW>KjnpgZjJ-L`&+0BF@71T%2fChw`LB{_D|x!F2oCZ8#r!+!$w$e-u#aRJO<&E z?(*RCf2V{$ws`(~75(rCQEk9An+uf@su1%}^8`fv`@I?C?f@iadcaZC_j?6&zWTTa zf%DHFxdYBZ7KGTHIM(TT>jYt(Co8!G@jH_9)guJye2aWg6#k8Gy&Z168F}Uz4u0ad zISfch^0GlaN3%b*ERy@0Gs@0Nm@L6n${<+Kiw+hF<%omDp!s{&rw>G{OBML=HzEA- z`CoMV{X@_3W2;XUEeERBf-M|QoodV(@e`rcNZWvl-~Cu&cSGqJVN2S9!w!}aAtZQL zx_xw>#__#OUVa_fw(YFm^-nDIdcy%vO~877fY!c$u_k{?97Z5Wm-V*dg&PJn;zzh& zAV2&exNIvtIm>}h-0kDmhGC(MnBkY+I{=PZ6?RrIrT%cgs?V{2ut1A-$9n~fR=4F|ijBsx$Bf|x6!G7`G>R~}={xfjBD z=OLF~31569ltda?0;xqA$3GqO^gDQQEsS`5ngI*)k&8{T?5*>%^W&pyMUPy9AV z@CQU@*5VJWFF|H>jyZ)LR+w_&P_N;wVW|?1R?57EdF$sv2cPp1M9s_EPk)obA8zrR zYoA&;#`~tG#qUN@2&yQkQN*bq3m>@gO}rUs6dDM72=U=KFk{4C82DkTtw8VaJlWCx zOm5pwe#LdH`r4OS9Q22=_Bs!+5|Y;^!b&E81f;ZMqR^+Mt1zHV0}_tt7s$Im0Nb|0 z>_4&Z4?gbqH_RBO&uO?hIdOPqMMB+ve+vV=fVV|h6ra^MkLLmUb+-SN68_je?m=K! z4#3E`6)up847)WZ_W88o00Qyg6bOc(9+8DW44!|H4-sB^l@Ad*3##6{(D9gj8X`=2 zqvvx8(w6?e9*K(cDT2fKZ@nG4?s{bZeh&Tq-F~O*@YFFAM`4&uG3=nxwdN|1sS^TX zMw)+Flx3?N$D8|Y>o?i%OE4;eF~Ntv1>uKp0RR9#-RFF$M-Y2^(xF2*RuAXo?x-x9~0mgN)C!G zEfNCbL|@7sMC~8_{vp}dG~TIG@xp({`(W!f_{J0L`{Pe|$&|#mGvS_A5dO@k_f7#4 zIIy%n-#nuQKHUHSRR93CIouNl`S>dc0Z;fMBr(fZ&B*j00s!MnDRR7Aw+!sU(Lww? zfD^T=zQrB)@;1QuN~ML(uUQ6=x`;WFb)Lq|EU?Df`y@`wuDodt6--DB@j&djtgns))#V#WM7Anpl zg&)2}008*(px}KOf~p1!z@b>H!@P!4p>kn0S%?qkc#?2e4xKE-hvQ8QT>(ODDfE&E z^p6}zo_v_e%WojN<|fvB7b`V{X)7jiyyWcJ5pBYg1N5dQdl-*Wr3Ro>S?)I0e?@ckn% z6ZVnILdQ1*a`o0gBlGLX+j+W#G`xZ)8Ky?&0X+uo68+l!OkH&g*|j&Z`k$U)IdB50 z37@(a(ch1qzmo7n@a-81{$%*f1T@fzNrpbkpg`{UQMmXLc=BuP`|PLb#SYEJuM=BL zej={tS7w6JD#V-ioy?>CvSG;l_Xs|JH2JnU^dAkf^A#5U*gmfCkHHd106?Mu%& zOpWINM10Ob=0c%SV@B>k+9D^A)vmM>PpTnQp!C}A#WT@O|?xsMLXnlY=3p-sPe(~NyPlc`u^Xk`n zbmEJ^_A}xT`SEX4_~SEwTkX>pe#9Wb1;8=fq}GZIQ$?#FI$7e6H4URGvuUhd8L{Pg zAkyOMuznx-#(hj&^(I~$HDlQE^|Eop#V~d2~ zr4Idw?^I1JcWc6$bnp-gL)XE>tFlLgwwO`1;j{@O(*g1Re*3X6uxj(RkSugHJo0(( zY%?1FbWX(2pD$Dh;}L>5Kce7AP}%U-cfz$dAp7@nIQ-Bu68^ZTtDbli+FS`c zoKN$%I;xR--1tH+M|I=^cGPEq4&(d^{Mbt%{PB6e?e<3w-Y*D#DYL{*Rzb~38^jG{ zOn5beeDBS?iMu8Btu*|=IfmO&VZ7=nd!S$c91~Z)iR|i|So4i9v)u0k;{zW}`qULj z(HzFPha8w8X#J)^8wQ$FV1inY!oTTKulfI9FZ@}YoH`Qrn&2Zan_2F4St#S>O}PRu z=y5%NB>ZA}Z(Q`|w%V6wz`s-N;|kx%kgXQ|h#8guP#A7skWxL-C~Jr#6QL!B-KL_g z#&1X}HHjIzRmp$5k37K4*310@qDvD?fN|okZVAAN;XSDx6aSxbOA4I#J@16=H^71Y z9Q@Qh9K&mVi=X&5D6Uiyq;7=5ToHW!V6YU7%DFA5p9c&0bsqzKjK6?kT@~K{5($62 zx0j@STH$@Z4`S77r!uMt6_+SPyFfSd8Gcq?1HvEMJv#iWKRaT* ztQm1(j$IOkks>o$1o;S)fh z-l8z4V3LABR1$TU@w~TuFWh)D96HF+Pu|5mPzFlK)qMWC<`33GYW6$4V8@c}^MrD4 z8c4sO`6GX#4tU>7DE#q0U$XXT;LZ^Ms>+ZMk2x^Tgh?ITdQ6a2f!)TNyj#Y6`G6S4 zd3H5({zOK=b{ysG=a{(Sjbzu{$eP)&ve@gLkS+`(K#0Om@_7SK!IA^h6KK}-nm(`k6H7jF43ICzL-zxVGsYVZ|SBO`|&uyoNx4Fu*K>`*_| z9HVH@G4&dMKAQbHBK(Hcd;s425(_`P!~g*BC%}7xY{X=a_%_Hb!5YZJ`$m`u4ToPx zZjun8)6sz`BunruiZ0k-3CJ}!v1azGv;zpl!B3Ne(ue{0l-{X$&_vS<|HKr-rE0x4 za{G__B%j@T*!xGn>(6Tl`TyhOW18k{@MXNLVG19vj_diC7=`%e#fN?R;)UN5KyveI zRQO}NN8ux8YzH$4#vJ2@o(BM-fg?ADJ=As}0)`Qyc%}^eI5_A&dOtH;u7GpSK{joJ zFFp)*yxMSj6DzeS{An}@VEtRZ7jAwd96H4D-~CPIgZWr$Qo@Z<-a>kf00MK)msgkw zUk`M&72CXqnvUw{#2^ZPRHOj!`3?wwyuX*ceTHBO$jE||k>b{%9phe-S@^sqAy0r1 z9Z)p05U2bsC@7P$5%R?R&@x9h9jri5TRum*33O%lGCo<>_UFf|=~ zeg{PtdDjQL@ISSSXZ~o1KW8JLnU2n#UMpyl*^D6k{&p)F(-T(k`KMXcm z+}AVYp4Tu0d?O3df$@)>8PDBHx!N2dLqefZOGnL#^#tM@r@<`@Slxa!6dFD6JY@6b z9t3nm4A#wh7>@?T<4BHOf7|!NEpI{(9%BA?euIS!To$S~F(Uoq@zJD7?sv|4o-`(V zRT|>_#{2mTc;W8`P#CTkix$ZbeTRe}zC!>29t7SaL)JI4!Zr^Y&iL^wb4CSl#V;c@ zgmh8G6GG{Y4o$Q$l35;vuIK1K^$^pS--29wBQwnjdb^(*`ub7TfS+yCgwS6OIyLS6 z{plHRS2~4$*B9{Iv#ZHHUGW8K_>`*p`+D&BIGroumV^TGUUWC3B8ErX{XVdnCiVB>{MH>c_Do;@LsJ51}%K-Zq?wf?G88Ln~b zb&&UbzzhF@XE^e^{|?PT8jPD1!RM=KmRW(FrSWlo@jibK=!mc+GA!oNCamg{uu4?C z@at@b?0Ag}e{AY!;l@UsgM`ZvbqAqGjBVL=Bq`$h4 zKj4YMbI(P#Tn>*v0$TZWY&Sk$>70rHvRXB#bGe_S) zbv1`!M#G#{c3PMW&+Fs-p6s5tqm`ZQK=u_biSsM)ofiIh&)?DZ89WF?_brm9fd{bS z`?XT<8bmO_K+`I_a=*LHm2u+H}S{IC7q`qW#)p*kP9zlYVBzhb6*2SG5(?O zpK?0nIjlMb8V#StQwW|Yrd@jDP1*qXBSky(t^Km-9* z=stEoGn>NZBU`WVAYjWO2t;0>P7FKX^tZeNuDcPQeU9Uw{Fsl&<~|T_b+pY_6!v&O ziBB_Ul^wuj0QN!9{KpAdes};_*3teAV{!i5Uk2famjM7^1Oj+r2Zrk+G+OXMe)Hf8 z4D$p8_8O%dR}n(Owg>YemY5#Zsj4XU?`87L^O3Dvm^kBH(C7s!Kzho z)&_3@6uy$0-1&akyb1R1;pp%El20(3^!BI*$6toj%!rE+H(b~=%?R-eyrz$F{wVkz z!k`m0|0S<+!tcej*$mli(T|#B2xZJ7kMl9zRV@>5wCxh;)IlKi=_42*-ZJbwd_Oar zw)yD5rB}h19`XB=WdU8(Uofuj6JX8TZinqR!u|ss{p>vqHk?JV)E)|cEZ%BYxPG|w zT;&PBsc?xxJgL`ZMEEU)zmf2>cqO0!KcFw)TzFXk0DN@dPC>Gf>?%Ho!Vz-ZCHRLi zdgSGb28LZ(2oa{8J;o%7PXx;ZTBojssWo(;{3_F@o{d~_Ir-(+!egIDFTM<}x)C;< z59`l`)+As+6uIMv;KEB_?;hs=^QX|FM?*@SG(jC2lbp+N10xkMi;ULuJFnHd;(fbg z0!Jj|`7>JZQxFFJ;(rFh4|FFEg-5EFCeUdIHh> z_Wp!_FX4mi^tJRK{|BZvZXK;6{PJTS1o8}WK?03$fW{r~hwH9|z56-#7dt7>*?>p` z78dAgn6Qk@mk2_!8JKg*PGC~~Ap;qaeaG>de^Govj}w;kI^g?XM&XB-5dgr0z>kbL z0q_<<{J#m|z!)+d*5Ay892e3>lLbUWl@Ul6BBGyi3Qip44f@aQV)}xM;F{~;9Y5f4 z_VR7M2K{O4e46i|gzx*8$i{PE|9%$#)2Fd{hD=VOOG|!x9ODqbJ<2FJ<8fow;g|FV zZ=g~i!iohw=JA?83Vz%P+X7r{M+*o4xwI!UavnXc?a;kb|tAMq3l~AOCx%Hf(`&&+$7Def5j}tXad)y2>Iy@e6R}m9S?Y$NubY zinA`l*%Ij$XwjxqjcYE$2_P`1j-4)J%Bm-R@%+w`dH`6)D}Wv$>O-x7=l8wL!VfPq z008_k@V;?QKuIzM%}5If;4<-1KM@)d%)p%SC8WwIV{j^iY@!LyA*O|_nxt5qXY!J5 zaP5_F>y3VPoPIi-vfAtGH{FVybq4Hzj>Z4_r`WPW#E{7Zx_ksj0V;@fsPmRaa06xq z?sb+)^}yB(re5^<=kch%$9ElKy!QTSoR3EZ7n0(jt0qXVg{ZNm4t^I3ztGxZ_D zItav*HCmvii4lWqP0@ekZ@ndO&e_Q2SHV}l>O+K8f&9Y1_QLOle-W z1zCRd1+4YEq}gDwN-W*&n6_rP zQD@hU;{3}pO7@99f7JXA;O7Ln`xP1XS4T@N0T>E!YT3uX!{~rOriO-u%|~>FLZcaw z&rBk!IOo6^v^hcd;lE{i!)DJ3Ty_O~^~=bI{}o(u4eWWEr9ZiwV*N&3QKG$N?4Sz7 zVMg9B86*yW5=ofD`~0z-TO}dRFTvlJ+NwT6`an1ZZ+nG=AI6K|ysYi5ivEqS6%Yx* zB77A!B{O!qIeaUx?V(|3X6V5#s z$^ywVc;+Cz1ACCw6PVs4cF^%R=0KV=l$wz_7x!mFGG=k?RL6AiI|nX=cYtp0bGn!D zMI4sJgF@75?xO0ShtK~)Epi_hRoJKUF)pu7;M)iVFM~-9KEg6#eaQI15DC5`x`P#7 z`{NYFB4W`(QOR&Kr*QDIJ2~r)55dKokzfBUXfW3S3no)2C3`AqzB1$xf}9af+0l#OWF9ef-AA=ZhwPAAiQzh5sb& zsT>LY;utA_zCthaS)uLB_iI~6)|5J*TKk~DpDW%9Y$%vk6A9(QoOOsTadv$UBlp8F5&sXg)X)MR1Wcyf?i6Iw z_<_eS6c8&|?PGgw+`=My=n(D==c7wava*7rqFPu&yM5fCjrI#H6=;dt5-BQh1>~(b z=(Cb>uUKZBlBv))UPE=se7MhrHQbC3yaTwXLX*kASPoyLLv zRH{_sOIv~B!m>71g)C>46tO)0oVsDCFDkBq_*nn4j?DkKUtAqVkU4V$2o^VP*H5r$F`R#4<3NsyJ?A8bWgS!7TmMsdQdIPL|{@>-!Ee7i1wMb|Q( z@ar-f{9&l?!fI&lzA6U()z&Vm(5G{_F#ILtWHK_B3%uYD#K+d-8iR)O8G{cPz?iTr zvB|(y81==8)m6S^SW)4MlGbhSWd6{zN4mTIF>21L*!5HqC9H@+3G1|W-XxDmr; zfx4h)d_fD}l%mgEF6^){oq38VuIF!y&+T8tyDUrATP-Cc&9Ct45`K6U0RX_86un=D zA>EV{054dEQC07T_zx!3(415r=nrr$UA~f4OjZB@4CYBhK~%%ctj3`}H`@t1XyX=P z@a#S&I}32=IO?2dh!>Z@THG`HsOFD=b-2>u23<07R7=Na)#dkMt7#ELmCDL+QAgw` zQeQ6u*U;>LnY!D`Q~ zISqyXO|LTHhgTT@0NkqR1LKxJG^1e@8!iG$6auRRW(1mfgZtb7j9I$FPOrhBh_hG& z*`SXsEnzDGXR&R?xC$zVG+R^$4??exszu8ZgHp`T&t}c$y~1EJBy5yGFZZdO9rcxb z+7fnZp~m)ad|mjzrIxr$c27Rcy-cG66%3KUTLX@1GFlFrw78!Vl-|3fHQ|?xRz8y_ zTXPy_?OM!fYmhb5;0z)PlhbIw#Mu(cid-Dl7{peTOXZwtu>;GLDAouAt3J6WgQIq| ze?!~>c?*X0vaQER^8hr_<2r7n_nKlpF z0e`0LMNmb>Kw;5x;IsP#j4jEs3R#u=rG%M4V}h#Fp&ASjTT(6_ot25Holcmdbb?SB zOWzs4V@m}~ZgelH<{xVR-FZD~^m_Yd+EY1_fM}ct(dX_GGVF|_gP|Kjg^JQL6ZwNw z{J9(Wke)GuI>^?akE~sdtUd*qoIzS4#b9~{=L)nc5a)?Nbrt1Of6h!9PxvXugs2bR z)Q=!gCw+(U0|C9|RVw`ODzpG%yIIkPjnC;}WC_H~sVbQNeK8bS-1$LiDW;iE=l9u8 zK`G03G^f{~CPQ82{k*b-N_@1yG*K}~>2UoH*gmQair(UEHnnc2+QGC|C8`XtEIC8l zSUM^k2}vjmtf2WXcwO_qBrUp67gX2;Onopmyf;v&&(JII1R)9&IG4+G>p|%b)b;y! zm}c-CRsE{ZM&@fj_6lFuQ5DxO(XvEU5hvKC{#-WG+@Y?DasIye-2QIx`D3 zj>hzOtCFalPVQK3Thq z9$Uh#K8~qMC@gldP1WsywWxK7D=3z`bJ^PIomvhi4NgK${sE)0uX8_9_=j=+SG(}T zs~i9TZgl7)W~>H;_pKZacl>slm_e+iIDDMO zkxJnPGNl8*xjlT=;@ zftR+$eoa1dc!7%m&<=l9p{arxCC6%xxCygn&F6J~5lY_WdQ0fBqu9v?bb8<{?$~iS zatvGck+Pubb?0Qwnw{8c3g;9@g)%_ss-^ABu$)_ulf?ONcnt_YyaoUOV7o&f9f1IV z!|x_js!%3{2m5}RQDX{pl~c{lDQiFH<`FzDfPHp!t- z#{j?Nyif(GK(v82T4w!O54b}I=|A=l@5;_N2V)esssow99zKj)m`5v1wbYqwoVR|b z?X)M=S;cAJDLqvd#Ia-zM^*hoA3ZV7uK?G*MuZ<;p~XPoO8Y&956Q58Ab`sZE_2un zlnl)Ti!q3ZN|qZ0QL?OY+Nry>yWFE(-eT6S!!%lu=jgF{+*7j*9{QWv=5=q{se|qm zMPKN*2UJB*ty=&VRXL2~xGHTGpYp587TvG2{Vz}Zm>d251v6SaBr(ax=kHjBO8iDO znP7x0&m?PP*;!}qwu_6MYTxdy*;(g#lDOZ+J$smH|5Mll`{wdXHt%52o6@rHTv-mp zx@C1N8Ou>8%$K2(j|(;Yf?GOV(!2dNB>eCyjRKskT|4SrA6r!{P$FSlZJ`4aEADns z?Hiocs%+*Px86@#{aG>hb#!?dJ$ejxU?085?wg(b7e9Ef+TJv_6mhOnr3=zVX`?KK zzda0nO)9wXy70eZEwQv>ea=3H9!eJ%+%;txacy9Ls;V=s)>St?sIL6;;{LzJ9bd#P zw6XI?D4u*`u6e^7cVg|77EYYH!l>(MaQ&=d$%b8M?u3x7U%;t^bLK=1Q^^W^j$KXxyrn?#KR z=_4$o%;Tzgl*6hV7004A!-XhAvgdW-e`VXoYAApuzNltb@B*urqbNrx+;MER=&b9Y zT4-e(lefJ6e%tT-$Kp#5AZ0=CvHPEzc=Pw)Lsd>-twmgqs$5p*=GAdT97j>+9V}Y) zAfTf}A7D&5y{6i0#sx^*?%`I2% zDQCY_mEZW{^vt_I^f8Lwr0aAlLP1zw7yeg8 z+Y|Bxe!+~YOgYf7m!yc0sX-;n8Yat;%ov%RZb&0JRh)y`Dv%=I3yI1z_*63u z_jG-AcK-R7-XIFWENn-f&cYj2Q{Q-(!s@0@ z17gmz`o8nwu(u)aEl;hSmMC|;emnEWHuFE9+#Q$88kX^z5>yH>j~(ttHJYZjNj>IO zRg?1$NjCMN?l9QUb>V%hJnt3d#wVcn;`uP&7zF^Iu0Z^-f&u{Wj-wyyXRHK_oQOFj zGi9^U2i3!@h%>6H@ti}`II6q8)}echcYDU^K+q}}WQ?&~Gi@{f^Ua;{@nt1|8+{T^ zV4Cx6X!N#2^E{esN_}?`5i*Y)-Bn9J9=z`#SACzXMEtOl0s!#N zh<>~0+j%Nz1@h;?fihj7ZY5$jUbU3}7-pXF@3Gr{72FpsI zID{MHlHQax`)pjJ*!3~xQD^megk&Ds^3dja=;XRe&LJBeVv4e*kgFW{eY_&^!-@(3 zz}ua4`SPuwfGq*hl^DS~Q^@-fOSTJ(nmoA;?v{sEIXZ%2d1CBK0@x=06Xm!a030I| zOJsfa+F}gbNt(`vqyP_>j|Z}k=5#K`xbv!S`SH=p#1BuIoUVgM4=&7#iMyFFrK+i` z`ktDq0i82PO?ZV*B9Ga!_t_aN$R;MYP5f)&vMw*cE0F|Es<`JylM?4x+DRe66^wG` z5WO37sGRmM5n%dYrRhzpEC2vMJ$T8=WiTeIt2$MUjG9mbR4^sRL7KBtFnTbfVh865 z-+KB_pX0&cqnf1R4U{CBR8a@)q6CB~ivMT!;`TI!ZUTTM;Qf_~A68rd0DgLK-%0^! zELD~aRX7zfSIXJ&A>@#}3_fM%=izdYw5^6d~N}>v=NjIG$667c`WqB^6 z9=_t4|H!Hf0Km_$ykurTYRX5T$-=W$o-J~g9FdW%IJi9AM87)jToE1%fkiQwP0NX~ zd~xszmE<=Ay}NSp!wJ3x_^-V2crP$s|Lt)Q3Lp}4%yKx66DH!#TxS2v&BkkW-0c{A zSjIWb2|@PqbCm*cOlp21#Q#F^%WJRLudhCMrnrAe*rQGOF9er0_HRZ0`x^VM+P;I0 kjg5_sjg5_sjg8gvH-H_;61q>!{r~^~07*qoM6N<$g7Cr05C8xG literal 0 HcmV?d00001 diff --git a/icons/record_active.png b/icons/record_active.png new file mode 100644 index 0000000000000000000000000000000000000000..8c421569a12617c773a822b32c035fd15d3eeba5 GIT binary patch literal 7098 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 Rf0`UXLFR*WwWLYVe*pb>lP3TG literal 0 HcmV?d00001 diff --git a/icons/record_inactive.png b/icons/record_inactive.png new file mode 100644 index 0000000000000000000000000000000000000000..6720a6f6ff810390aa92449540e03de52813ddc0 GIT binary patch literal 5897 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�XwSdu|X96&zD!t{C&|+SpZDm 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 literal 0 HcmV?d00001 diff --git a/imageloader.c b/imageloader.c index 31e0d0c..292d183 100644 --- a/imageloader.c +++ b/imageloader.c @@ -59,8 +59,19 @@ bool cImageLoader::LoadAdditionalEPGImage(cString name) { return true; } +bool cImageLoader::LoadIcon(const char *cIcon, int size) { + if (size==0) + return false; + bool success = false; + success = LoadImage(cString(cIcon), tvguideConfig.iconPath, "png"); + if (!success) + return false; + buffer.sample(Geometry(size, size)); + return true; +} + bool cImageLoader::DrawBackground(tColor back, tColor blend, int width, int height) { - if ((width < 1) || (height < 1)) + if ((width < 1) || (height < 1) || (width > 1920) || (height > 1080)) return false; Color Back = Argb2Color(back); Color Blend = Argb2Color(blend); diff --git a/imageloader.h b/imageloader.h index a38a5a0..bc2b7dd 100644 --- a/imageloader.h +++ b/imageloader.h @@ -17,6 +17,7 @@ public: bool LoadLogo(const char *logo, int width, int height); bool LoadEPGImage(int eventID); bool LoadAdditionalEPGImage(cString name); + bool LoadIcon(const char *cIcon, int size); bool DrawBackground(tColor back, tColor blend, int width, int height); private: Image buffer; diff --git a/osdmanager.c b/osdmanager.c index 8fdd7f6..c74162d 100644 --- a/osdmanager.c +++ b/osdmanager.c @@ -1,6 +1,3 @@ -#include -#include - #ifndef __TVGUIDE_OSDMANAGER_H #define __TVGUIDE_OSDMANAGER_H @@ -55,32 +52,4 @@ void cOsdManager::releasePixmap(cPixmap *pixmap) { if (!pixmap) return; osd->DestroyPixmap(pixmap); -} - -static std::string CutText(std::string text, int width, const cFont *font) { - if (width <= font->Size()) - return text.c_str(); - if (font->Width(text.c_str()) < width) - return text.c_str(); - cTextWrapper twText; - twText.Set(text.c_str(), font, width); - std::string cuttedTextNative = twText.GetLine(0); - std::stringstream sstrText; - sstrText << cuttedTextNative << "..."; - std::string cuttedText = sstrText.str(); - int actWidth = font->Width(cuttedText.c_str()); - if (actWidth > width) { - int overlap = actWidth - width; - int charWidth = font->Width("."); - if (charWidth == 0) - charWidth = 1; - int cutChars = overlap / charWidth; - if (cutChars > 0) { - cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars); - std::stringstream sstrText2; - sstrText2 << cuttedTextNative << "..."; - cuttedText = sstrText2.str(); - } - } - return cuttedText; } \ No newline at end of file diff --git a/po/de_DE.po b/po/de_DE.po index e075e74..d1a58c6 100755 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-tvguide 0.0.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-06-03 09:00+0200\n" +"POT-Creation-Date: 2013-07-07 13:43+0200\n" "PO-Revision-Date: 2012-08-25 17:49+0200\n" "Last-Translator: Horst\n" "Language-Team: \n" @@ -21,8 +21,8 @@ msgstr "Wiederholungen dieser Sendung" msgid "No EPG Information available" msgstr "Keine EPG Daten verfügbar" -msgid "Set Timer" -msgstr "Aufnehmen" +msgid "Search & Rec" +msgstr "Search & Rec" msgid "Channels back" msgstr "Kanäle zurück" @@ -36,6 +36,336 @@ msgstr "Umschalten" msgid "Detailed EPG" msgstr "Detailiertes EPG" +msgid "Transp." +msgstr "Transp." + +msgid "Timer Conflict" +msgstr "Timer Konflikt" + +msgid "all Channels" +msgstr "alle Kanäle" + +msgid "unknown channel" +msgstr "unbekannter Kanal" + +msgid "Duration" +msgstr "Dauer" + +msgid "min" +msgstr "min" + +msgid "recorded at" +msgstr "aufgenommen am" + +msgid "from" +msgstr "von" + +msgid "Instant Record" +msgstr "Sofortaufnahme" + +msgid "Delete Timer" +msgstr "Timer löschen" + +msgid "Edit Timer" +msgstr "Timer bearbeiten" + +msgid "Create Series Timer" +msgstr "Serientimer anlegen" + +msgid "Create Search Timer" +msgstr "Suchtimer anlegen" + +msgid "Create Switch Timer" +msgstr "Umschalttimer anlegen" + +msgid "Delete Switch Timer" +msgstr "Umschalttimer löschen" + +msgid "Search" +msgstr "Suchen" + +msgid "Search in Recordings" +msgstr "In Aufnahmen suchen" + +msgid "Check for Timer Conflicts" +msgstr "Auf Timerkoflikte prüfen" + +msgid "Timer created" +msgstr "Timer angelegt" + +msgid "Timer NOT created" +msgstr "Timer NICHT angelegt" + +msgid "OK" +msgstr "OK" + +msgid "Timer deleted" +msgstr "Timer gelöscht" + +msgid "Timer" +msgstr "Timer" + +msgid "still recording - really delete?" +msgstr "Aufzeichnung läuft - wirklich löschen?" + +msgid "Yes" +msgstr "Ja" + +msgid "No" +msgstr "Nein" + +msgid "One" +msgstr "Ein" + +msgid "detected" +msgstr "gefunden" + +msgid "Timer Conflicts" +msgstr "Timerkonflikte" + +msgid "Show conflict" +msgstr "Konflikt zeigen" + +msgid "timers involved" +msgstr "Timer beteiligt" + +msgid "Ignore Conflicts" +msgstr "Konflikte ignorieren" + +msgid "Ignore Conflict" +msgstr "Konflikt ignorieren" + +msgid "No Timer Conflicts found" +msgstr "Keine Timerkonflikte gefunden" + +msgid "Close" +msgstr "Schließen" + +msgid "Timer Active" +msgstr "Timer aktiv" + +msgid "Priority" +msgstr "Priorität" + +msgid "Lifetime" +msgstr "Lebensdauer" + +msgid "Day" +msgstr "Tag" + +msgid "Timer start time" +msgstr "Timer Start Zeit" + +msgid "Timer stop time" +msgstr "Timer Stop Zeit" + +msgid "Save" +msgstr "Speichern" + +msgid "Cancel" +msgstr "Abbrechen" + +msgid "Create Series Timer based on" +msgstr "Serientimer anlegen basierend auf" + +msgid "Channel" +msgstr "Kanal" + +msgid "Series Timer start time" +msgstr "Serientimer Start Zeit" + +msgid "Series Timer stop time" +msgstr "Serientimer Stop Zeit" + +msgid "Days to record" +msgstr "Tage" + +msgid "Day to start" +msgstr "Beginnen am" + +msgid "Create Timer" +msgstr "Timer anlegen" + +msgid "Series Timer created" +msgstr "Serientimer angelegt" + +msgid "Start" +msgstr "Start" + +msgid "Stop" +msgstr "Stop" + +msgid "Configure Search Timer based on" +msgstr "Suchtimer konfigurieren basierend auf" + +msgid "Search Expression:" +msgstr "Suchausdruck:" + +msgid "Continue" +msgstr "Weiter" + +msgid "Configure Search Timer for Search String" +msgstr "Suchtimer konfigurieren für Suchbegriff" + +msgid "Manually configure Options" +msgstr "Optionen manuell konfigurieren" + +msgid "Use Template" +msgstr "Template benutzen" + +msgid "Creating Search Timer" +msgstr "Suchtimer anlegen" + +msgid "Search Term" +msgstr "Suchbegriff" + +msgid "Using Template" +msgstr "Template" + +msgid "Display Results for Search Timer" +msgstr "Ergebnisse für Suchtimer anzeigen" + +msgid "Use other Template" +msgstr "Anderes Template benutzen" + +msgid "Configure Search Timer Options for Search String" +msgstr "Suchtimer Optionen konfigurieren für Suchbegriff" + +msgid "whole term must appear" +msgstr "vollständiger Ausdruck" + +msgid "all terms must exist" +msgstr "alle Worte" + +msgid "one term must exist" +msgstr "ein Wort" + +msgid "exact match" +msgstr "exakt" + +msgid "regular expression" +msgstr "Regulärer Ausdruck" + +msgid "Search Mode" +msgstr "Suchmodus" + +msgid "Use Title" +msgstr "Titel benutzen" + +msgid "Use Subtitle" +msgstr "Untertitel benutzen" + +msgid "Use Description" +msgstr "Beschreibung benutzen" + +msgid "Limit Channels" +msgstr "Kanäle einschränken" + +msgid "Start Channel" +msgstr "Startkanal" + +msgid "Stop Channel" +msgstr "Stopkanal" + +msgid "Use Time" +msgstr "Zeit benutzen" + +msgid "Start after" +msgstr "Beginn nach" + +msgid "Start before" +msgstr "Beginn vor" + +msgid "search results for Search Timer" +msgstr "Treffer für Suchtimer" + +msgid "search result for Search Timer" +msgstr "Treffer für Suchtimer" + +msgid "Nothing found for Search String" +msgstr "Keine Treffer für Suchbegriff" + +msgid "Search Timer sucessfully created." +msgstr "Suchtimer erfolgreich angelegt" + +msgid "Search Timer update initialised" +msgstr "Suchtimer update initialisiert" + +msgid "Search Timer NOT sucessfully created" +msgstr "Suchtimer NICHT erfolgreich angelegt" + +msgid "Configure Options for Switchtimer" +msgstr "Optionen für Umschalttimer konfigurieren" + +msgid "Minutes before switching" +msgstr "Minuten vor umschalten" + +msgid "switch" +msgstr "umschalten" + +msgid "announce only" +msgstr "nur ankündigen" + +msgid "ask for switch" +msgstr "vor umschalten fragen" + +msgid "Switch Mode" +msgstr "Umschaltmodus" + +msgid "Create" +msgstr "Anlegen" + +msgid "Switch Timer sucessfully created" +msgstr "Umschalttimer erfolgreich angelegt" + +msgid "Switch Timer NOT sucessfully created" +msgstr "Umschalttimer NICHT erfolgreich angelegt" + +msgid "Switch Timer deleted" +msgstr "Umschalttimer gelöscht" + +msgid "Show Search Options" +msgstr "Suchoptionen anzeigen" + +msgid "Perform Search" +msgstr "Suche ausführen" + +msgid "Channel to Search" +msgstr "Suche auf Kanal" + +msgid "Search in title" +msgstr "In Titel suchen" + +msgid "Search in Subtitle" +msgstr "In Untertitel suchen" + +msgid "Search in Description" +msgstr "In Beschreibung suchen" + +msgid "search results for" +msgstr "Suchergebnisse für" + +msgid "search result for" +msgstr "Suchergebnis für" + +msgid "Adapt Search" +msgstr "Suche anpassen" + +msgid "Found" +msgstr " " + +msgid "recording" +msgstr "Aufnahme gefunden" + +msgid "recordings" +msgstr "Aufnahmen gefunden" + +msgid "for" +msgstr "für" + +msgid "No recordings found for" +msgstr "Keine Aufnahmen gefunden für" + msgid "General Settings" msgstr "Allgemeine Einstellungen" @@ -234,8 +564,8 @@ msgstr "Zeitleiste Datum Schriftgröße" msgid "Timeline Time Font Size" msgstr "Zeitleiste Zeit Schriftgröße" -msgid "Timer not set! There is already a timer for this item." -msgstr "Timer wurde nicht gesetzt! Es existiert bereits ein Timer für diese Sendung" +msgid "Search & Recording Menu Font Size" +msgstr "Suchen & Aufnehmen Menu Schriftgröße" -msgid "Timer set" -msgstr "Timer gesetzt" +msgid "Search & Recording Menu Small Font Size" +msgstr "Suchen & Aufnehmen Menu kleine Schriftgröße" diff --git a/recmanager.c b/recmanager.c new file mode 100644 index 0000000..df65cc3 --- /dev/null +++ b/recmanager.c @@ -0,0 +1,598 @@ +#include +#include +#include "recmanager.h" + +static int CompareRecording(const void *p1, const void *p2) { + return (int)((*(cRecording **)p1)->Start() - (*(cRecording **)p2)->Start()); +} + +bool TVGuideTimerConflict::timerInvolved(int involvedID) { + int numConflicts = timerIDs.size(); + for (int i=0; iToDescr()); + return timer; +} + +void cRecManager::DeleteTimer(const cEvent *event) { + cTimer *t = Timers.GetMatch(event); + if (!t) + return; + DeleteTimer(t); +} + +void cRecManager::DeleteTimer(int timerID) { + cTimer *t = Timers.Get(timerID); + if (!t) + return; + DeleteTimer(t); +} + +void cRecManager::DeleteTimer(cTimer *timer) { + if (timer->Recording()) { + timer->Skip(); + cRecordControls::Process(time(NULL)); + } + isyslog("timer %s deleted", *timer->ToDescr()); + Timers.Del(timer, true); + Timers.SetModified(); +} + +void cRecManager::SaveTimer(cTimer *timer, cRecMenu *menu) { + if (!timer) + return; + + bool active = menu->GetBoolValue(1); + int prio = menu->GetIntValue(2); + int lifetime = menu->GetIntValue(3); + time_t day = menu->GetTimeValue(4); + int start = menu->GetIntValue(5); + int stop = menu->GetIntValue(6); + + timer->SetDay(day); + timer->SetStart(start); + timer->SetStop(stop); + timer->SetPriority(prio); + timer->SetLifetime(lifetime); + + if (timer->HasFlags(tfActive) && !active) + timer->ClrFlags(tfActive); + else if (!timer->HasFlags(tfActive) && active) + timer->SetFlags(tfActive); + + timer->SetEventFromSchedule(); + Timers.SetModified(); +} + +bool cRecManager::IsRecorded(const cEvent *event) { + cTimer *timer = Timers.GetMatch(event); + if (!timer) + return false; + return timer->Recording(); +} + +std::vector cRecManager::CheckTimerConflict(void) { + /* TIMERCONFLICT FORMAT: + The result list looks like this for example when we have 2 timer conflicts at one time: + 1190232780:152|30|50#152#45:45|10|50#152#45 + '1190232780' is the time of the conflict in seconds since 1970-01-01. + It's followed by list of timers that have a conflict at this time: + '152|30|50#1 int editTimer(cTimer *timer, bool active, int prio, int start, int stop); + 52#45' is the description of the first conflicting timer. Here: + '152' is VDR's timer id of this timer as returned from VDR's LSTT command + '30' is the percentage of recording that would be done (0...100) + '50#152#45' is the list of concurrent timers at this conflict + '45|10|50#152#45' describes the next conflict + */ + std::vector results; + if (!epgSearchAvailable) + return results; + Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1; + if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) { + std::list conflicts = epgSearch->handler->TimerConflictList(); + int numConflicts = conflicts.size(); + if (numConflicts > 0) { + for (std::list::iterator it=conflicts.begin(); it != conflicts.end(); ++it) { + TVGuideTimerConflict sConflict; + splitstring s(it->c_str()); + std::vector flds = s.split(':'); + if (flds.size() < 2) + continue; + sConflict.time = atoi(flds[0].c_str()); + splitstring s2(flds[1].c_str()); + std::vector flds2 = s2.split('|'); + if (flds2.size() < 3) + continue; + sConflict.timerID = atoi(flds2[0].c_str()); + sConflict.percentPossible = atoi(flds2[1].c_str()); + splitstring s3(flds2[2].c_str()); + std::vector flds3 = s3.split('#'); + std::vector timerIDs; + for (int k = 0; k < flds3.size(); k++) { + timerIDs.push_back(atoi(flds3[k].c_str()) - 1); + } + sConflict.timerIDs = timerIDs; + results.push_back(sConflict); + } + } + } + delete epgSearch; + + int numConflicts = results.size(); + time_t startTime = 0; + time_t endTime = 0; + for (int i=0; i < numConflicts; i++) { + cTimeInterval *unionSet = NULL; + int numTimers = results[i].timerIDs.size(); + for (int j=0; j < numTimers; j++) { + const cTimer *timer = Timers.Get(results[i].timerIDs[j]); + if (timer) { + if (!unionSet) { + unionSet = new cTimeInterval(timer->StartTime(), timer->StopTime()); + } else { + cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime()); + cTimeInterval *newUnion = unionSet->Union(timerInterval); + delete unionSet; + delete timerInterval; + unionSet = newUnion; + } + } + } + results[i].timeStart = unionSet->Start(); + results[i].timeStop = unionSet->Stop(); + delete unionSet; + + cTimeInterval *intersect = NULL; + for (int j=0; j < numTimers; j++) { + const cTimer *timer = Timers.Get(results[i].timerIDs[j]); + if (timer) { + if (!intersect) { + intersect = new cTimeInterval(timer->StartTime(), timer->StopTime()); + } else { + cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime()); + cTimeInterval *newIntersect = intersect->Intersect(timerInterval); + if (newIntersect) { + delete intersect; + intersect = newIntersect; + } + delete timerInterval; + } + } + } + results[i].overlapStart = intersect->Start(); + results[i].overlapStop = intersect->Stop(); + delete intersect; + } + + return results; +} + +cTimer *cRecManager::CreateSeriesTimer(cRecMenu *menu) { + bool active = menu->GetBoolValue(1); + int channelNumber = menu->GetIntValue(2); + int start = menu->GetIntValue(3); + int stop = menu->GetIntValue(4); + int weekdays = menu->GetIntValue(5); + time_t tday = menu->GetTimeValue(6); + int prio = menu->GetIntValue(7); + int lifetime = menu->GetIntValue(8); + + cChannel *channel = Channels.GetByNumber(channelNumber); + cTimer *seriesTimer = new cTimer(false, false, channel); + + seriesTimer->SetDay(tday); + seriesTimer->SetStart(start); + seriesTimer->SetStop(stop); + seriesTimer->SetPriority(prio); + seriesTimer->SetLifetime(lifetime); + seriesTimer->SetWeekDays(weekdays); + seriesTimer->SetFile("TITLE EPISODE"); + if (active) + seriesTimer->SetFlags(tfActive); + else + seriesTimer->SetFlags(tfNone); + seriesTimer->SetEventFromSchedule(); + Timers.Add(seriesTimer); + Timers.SetModified(); + return seriesTimer; +} + +std::vector cRecManager::ReadEPGSearchTemplates(void) { + cString ConfigDir = cPlugin::ConfigDirectory("epgsearch"); + cString epgsearchConf = "epgsearchtemplates.conf"; + cString fileName = AddDirectory(*ConfigDir, *epgsearchConf); + std::vector epgTemplates; + if (access(fileName, F_OK) == 0) { + FILE *f = fopen(fileName, "r"); + if (f) { + char *s; + cReadLine ReadLine; + while ((s = ReadLine.Read(f)) != NULL) { + char *p = strchr(s, '#'); + if (p) + *p = 0; + stripspace(s); + try { + if (!isempty(s)) { + std::string templ = s; + int posID = templ.find_first_of(":"); + int posName = templ.find_first_of(":", posID+1); + std::string name = templ.substr(posID+1, posName - posID - 1); + std::string templValue = templ.substr(posName); + TVGuideEPGSearchTemplate tmp; + tmp.name = name; + tmp.templValue = templValue; + epgTemplates.push_back(tmp); + } + } catch (...){} + } + } + } + return epgTemplates; +} + +std::string cRecManager::BuildEPGSearchString(cString searchString, std::string templValue) { + std::stringstream searchTimerString; + searchTimerString << "0:"; + searchTimerString << *searchString; + searchTimerString << templValue; + return searchTimerString.str(); +} + +std::string cRecManager::BuildEPGSearchString(cString searchString, cRecMenu *menu) { + int searchMode = menu->GetIntValue(0); + bool useTitle = menu->GetBoolValue(1); + bool useSubTitle = menu->GetBoolValue(2); + bool useDescription = menu->GetBoolValue(3); + bool limitChannels = menu->GetBoolValue(4); + int startChannel = -1; + int stopChannel = -1; + if (limitChannels) { + startChannel = menu->GetIntValue(5); + stopChannel = menu->GetIntValue(6); + } + int after = 0; + int before = 0; + bool limitTime = (limitChannels)?menu->GetBoolValue(7):menu->GetBoolValue(5); + if (limitTime) { + after = (limitChannels)?menu->GetIntValue(8):menu->GetIntValue(6); + before = (limitChannels)?menu->GetIntValue(9):menu->GetIntValue(7); + } + + std::stringstream searchTimerString; + //1 - unique search timer id + searchTimerString << "0:"; + //2 - the search term + searchTimerString << *searchString; + //3 - use time? 0/1 + //4 - start time in HHMM + //5 - stop time in HHMM + if (limitTime) { + searchTimerString << ":1:" << after << ":" << before << ":"; + } else { + searchTimerString << ":0:::"; + } + //6 - use channel? 0 = no, 1 = Interval, 2 = Channel group, 3 = FTA only + //7 - if 'use channel' = 1 then channel id[|channel id] in VDR format, + // one entry or min/max entry separated with |, if 'use channel' = 2 + // then the channel group name + if (limitChannels) { + searchTimerString << "1:"; + cChannel *startChan = Channels.GetByNumber(startChannel); + cChannel *stopChan = Channels.GetByNumber(stopChannel); + searchTimerString << *(startChan->GetChannelID().ToString()); + searchTimerString << "|"; + searchTimerString << *(stopChan->GetChannelID().ToString()) << ":"; + } else { + searchTimerString << "0::"; + } + //8 - match case? 0/1 + searchTimerString << ":0"; + /*9 - search mode: + 0 - the whole term must appear as substring + 1 - all single terms (delimiters are blank,',', ';', '|' or '~') + must exist as substrings. + 2 - at least one term (delimiters are blank, ',', ';', '|' or '~') + must exist as substring. + 3 - matches exactly + 4 - regular expression */ + searchTimerString << searchMode << ":"; + //10 - use title? 0/1 + if (useTitle) + searchTimerString << "1:"; + else + searchTimerString << "0:"; + //11 - use subtitle? 0/1 + if (useSubTitle) + searchTimerString << "1:"; + else + searchTimerString << "0:"; + // 12 - use description? 0/1 + if (useDescription) + searchTimerString << "1:"; + else + searchTimerString << "0:"; + //13 - use duration? 0/1 + //14 - min duration in hhmm + //15 - max duration in hhmm + searchTimerString << "0:::"; + //16 - use as search timer? 0/1 + searchTimerString << "1:"; + //17 - use day of week? 0/1 + //18 - day of week (0 = Sunday, 1 = Monday...; + // -1 Sunday, -2 Monday, -4 Tuesday, ...; -7 Sun, Mon, Tue) + searchTimerString << "0::"; + //19 - use series recording? 0/1 + searchTimerString << "1:"; + //20 - directory for recording + searchTimerString << ":"; + //21 - priority of recording + //22 - lifetime of recording + searchTimerString << "99:99:"; + //23 - time margin for start in minutes + //24 - time margin for stop in minutes + searchTimerString << "5:5:"; + //25 - use VPS? 0/1 + searchTimerString << "0:"; + /*26 - action: + 0 = create a timer + 1 = announce only via OSD (no timer) + 2 = switch only (no timer) + 3 = announce via OSD and switch (no timer) + 4 = announce via mail*/ + searchTimerString << "0:"; + /*27 - use extended EPG info? 0/1 + 28 - extended EPG info values. This entry has the following format + (delimiter is '|' for each category, '#' separates id and value): + 1 - the id of the extended EPG info category as specified in + epgsearchcats.conf + 2 - the value of the extended EPG info category + (a ':' will be translated to "!^colon^!", e.g. in "16:9") */ + searchTimerString << "0::"; + /*29 - avoid repeats? 0/1 + 30 - allowed repeats + 31 - compare title when testing for a repeat? 0/1 + 32 - compare subtitle when testing for a repeat? 0/1/2 + 0 - no + 1 - yes + 2 - yes, if present + 33 - compare description when testing for a repeat? 0/1 + 34 - compare extended EPG info when testing for a repeat? + This entry is a bit field of the category IDs. + 35 - accepts repeats only within x days */ + searchTimerString << "1:1:1:2:1:::"; + /*36 - delete a recording automatically after x days + 37 - but keep this number of recordings anyway + 38 - minutes before switch (if action = 2) + 39 - pause if x recordings already exist + 40 - blacklist usage mode (0 none, 1 selection, 2 all) + 41 - selected blacklist IDs separated with '|' + 42 - fuzzy tolerance value for fuzzy searching + 43 - use this search in favorites menu (0 no, 1 yes) + 44 - id of a menu search template + 45 - auto deletion mode (0 don't delete search timer, 1 delete after given + count of recordings, 2 delete after given days after first recording) + 46 - count of recordings after which to delete the search timer + 47 - count of days after the first recording after which to delete the search + timer + 48 - first day where the search timer is active (see parameter 16) + 49 - last day where the search timer is active (see parameter 16) + 50 - ignore missing EPG categories? 0/1 + 51 - unmute sound if off when used as switch timer + 52 - percentage of match when comparing the summary of two events (with 'avoid repeats') + 53 - HEX representation of the content descriptors, each descriptor ID is represented with 2 chars + 54 - compare date when testing for a repeat? (0=no, 1=same day, 2=same week, 3=same month) */ + searchTimerString << "0::::0:::0::0:::::::::0"; + + //esyslog("tvguide: epgsearch String: %s", searchTimerString.str().c_str()); + + return searchTimerString.str(); +} + +const cEvent **cRecManager::PerformSearchTimerSearch(std::string epgSearchString, int &numResults) { + if (!epgSearchAvailable) + return NULL; + const cEvent **searchResults = NULL; + Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1; + if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) { + std::list results = epgSearch->handler->QuerySearch(epgSearchString); + numResults = results.size(); + if (numResults > 0) { + searchResults = new const cEvent *[numResults]; + cSchedulesLock *schedulesLock; + const cSchedules *schedules; + schedules = cSchedules::Schedules(*schedulesLock); + const cEvent *event = NULL; + int index=0; + for (std::list::iterator it=results.begin(); it != results.end(); ++it) { + try { + splitstring s(it->c_str()); + std::vector flds = s.split(':', 1); + int eventID = atoi(flds[1].c_str()); + std::string channelID = flds[7]; + tChannelID chanID = tChannelID::FromString(channelID.c_str()); + cChannel *channel = Channels.GetByChannelID(chanID); + if (channel) { + const cSchedule *Schedule = NULL; + Schedule = schedules->GetSchedule(channel); + event = Schedule->GetEvent(eventID); + if (event) { + searchResults[index] = event; + } else + return NULL; + } else + return NULL; + index++; + } catch (...){} + } + } + } + return searchResults; +} + +const cEvent **cRecManager::PerformSearch(cRecMenu *menu, bool withOptions, int &numResults) { + if (epgSearchAvailable) { + cString searchString = menu->GetStringValue(1); + Epgsearch_searchresults_v1_0 data; + data.query = (char *)*searchString; + int mode = 0; + int channelNr = 0; + bool useTitle = true; + bool useSubTitle = true; + bool useDescription = false; + if (withOptions) { + mode = menu->GetIntValue(2); + channelNr = menu->GetIntValue(3); + useTitle = menu->GetBoolValue(4); + useSubTitle = menu->GetBoolValue(5); + useDescription = menu->GetBoolValue(6); + } + data.mode = mode; + data.channelNr = channelNr; + data.useTitle = useTitle; + data.useSubTitle = useSubTitle; + data.useDescription = useDescription; + + if (epgSearchPlugin->Service("Epgsearch-searchresults-v1.0", &data)) { + cList *list = data.pResultList; + int numElements = list->Count(); + const cEvent **searchResults = NULL; + if (numElements > 0) { + searchResults = new const cEvent *[numElements]; + numResults = numElements; + int index = 0; + for (Epgsearch_searchresults_v1_0::cServiceSearchResult *r = list->First(); r ; r = list->Next(r)) { + searchResults[index] = r->event; + index++; + } + } + delete list; + return searchResults; + } + } + return NULL; +} + +int cRecManager::CreateSearchTimer(std::string epgSearchString) { + int timerID = -1; + if (!epgSearchAvailable) + return timerID; + Epgsearch_services_v1_1 *epgSearch = new Epgsearch_services_v1_1; + if (epgSearchPlugin->Service("Epgsearch-services-v1.1", epgSearch)) { + timerID = epgSearch->handler->AddSearchTimer(epgSearchString); + } + return timerID; +} + +void cRecManager::UpdateSearchTimers(void) { + if (epgSearchAvailable) { + Epgsearch_updatesearchtimers_v1_0 data; + data.showMessage = false; + epgSearchPlugin->Service("Epgsearch-updatesearchtimers-v1.0", &data); + } +} + +// announceOnly: 0 = switch, 1 = announce only, 2 = ask for switch +bool cRecManager::CreateSwitchTimer(const cEvent *event, cRecMenu *menu) { + int switchMinsBefore = menu->GetIntValue(1); + int announceOnly = menu->GetIntValue(2); + if (epgSearchAvailable) { + Epgsearch_switchtimer_v1_0 data; + data.event = event; + data.mode = 1; + data.switchMinsBefore = switchMinsBefore; + data.announceOnly = announceOnly; + data.success = false; + epgSearchPlugin->Service("Epgsearch-switchtimer-v1.0", &data); + cSwitchTimer *t = new cSwitchTimer(event); + SwitchTimers.Add(t); + return data.success; + } + return false; +} + +void cRecManager::DeleteSwitchTimer(const cEvent *event) { + SwitchTimers.DeleteSwitchTimer(event); + if (epgSearchAvailable) { + Epgsearch_switchtimer_v1_0 data; + data.event = event; + data.mode = 2; + data.switchMinsBefore = 0; + data.announceOnly = 0; + data.success = false; + epgSearchPlugin->Service("Epgsearch-switchtimer-v1.0", &data); + } +} + +cRecording **cRecManager::SearchForRecordings(cString searchString, int &numResults) { + + cRecording **matchingRecordings = NULL; + int num = 0; + numResults = 0; + + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { + std::string s1 = recording->Name(); + std::string s2 = *searchString; + if (s1.empty() || s2.empty()) continue; + + // tolerance for fuzzy searching: 90% of the shorter text length, but at least 1 + int tolerance = std::max(1, (int)std::min(s1.size(), s2.size()) / 10); + + bool match = FindIgnoreCase(s1, s2) >= 0 || FindIgnoreCase(s2, s1) >= 0; + + if (!match) { + AFUZZY af = { NULL, NULL, NULL, NULL, NULL, NULL, { 0 }, { 0 }, 0, 0, 0, 0, 0, 0 }; + if (s1.size() > 32) s1 = s1.substr(0, 32); + afuzzy_init(s1.c_str(), tolerance, 0, &af); + /* Checking substring */ + int res = afuzzy_checkSUB(s2.c_str(), &af); + afuzzy_free(&af); + match = (res > 0); + } + + if (!match) { + AFUZZY af = { NULL, NULL, NULL, NULL, NULL, NULL, { 0 }, { 0 }, 0, 0, 0, 0, 0, 0 }; + if (s2.size() > 32) s2 = s2.substr(0, 32); + afuzzy_init(s2.c_str(), tolerance, 0, &af); + /* Checking substring */ + int res = afuzzy_checkSUB(s1.c_str(), &af); + afuzzy_free(&af); + match = (res > 0); + } + + if (match) { + matchingRecordings = (cRecording **)realloc(matchingRecordings, (num + 1) * sizeof(cRecording *)); + matchingRecordings[num++] = recording; + } + } + if (num > 0) { + qsort(matchingRecordings, num, sizeof(cRecording *), CompareRecording); + numResults = num; + return matchingRecordings; + } + return NULL; +} \ No newline at end of file diff --git a/recmanager.h b/recmanager.h new file mode 100644 index 0000000..0b010c4 --- /dev/null +++ b/recmanager.h @@ -0,0 +1,53 @@ +#ifndef __TVGUIDE_RECMMANAGER_H +#define __TVGUIDE_RECMMANAGER_H + +class TVGuideTimerConflict { +public: + time_t time; + time_t timeStart; + time_t timeStop; + time_t overlapStart; + time_t overlapStop; + int percentPossible; + int timerID; + std::vector timerIDs; + bool timerInvolved(int involvedID); +}; + +struct TVGuideEPGSearchTemplate { +public: + std::string name; + std::string templValue; +}; + +// --- cRecManager ------------------------------------------------------------- +class cRecManager { +private: + cPlugin *epgSearchPlugin; + bool epgSearchAvailable; + void DeleteTimer(cTimer *timer); +public: + cRecManager (void); + void SetEPGSearchPlugin(void); + bool EpgSearchAvailable(void) {return epgSearchAvailable;}; + cTimer *createTimer(const cEvent *event); + void DeleteTimer(const cEvent *event); + void DeleteTimer(int timerID); + void SaveTimer(cTimer *timer, cRecMenu *menu); + bool IsRecorded(const cEvent *event); + std::vector CheckTimerConflict(void); + cTimer *CreateSeriesTimer(cRecMenu *menu); + std::string BuildEPGSearchString(cString searchString, cRecMenu *menu); + std::string BuildEPGSearchString(cString searchString, std::string templValue); + const cEvent **PerformSearchTimerSearch(std::string epgSearchString, int &numResults); + const cEvent **PerformSearch(cRecMenu *menu, bool withOptions, int &numResults); + std::vector ReadEPGSearchTemplates(void); + int CreateSearchTimer(std::string epgSearchString); + void UpdateSearchTimers(void); + bool CreateSwitchTimer(const cEvent *event, cRecMenu *menu); + void DeleteSwitchTimer(const cEvent *event); + cRecording **SearchForRecordings(cString searchString, int &numResults); + virtual ~cRecManager (void); +}; + +#endif //__TVGUIDE_RECMMANAGER_H \ No newline at end of file diff --git a/recmenu.c b/recmenu.c new file mode 100644 index 0000000..66a5a84 --- /dev/null +++ b/recmenu.c @@ -0,0 +1,525 @@ +#include "recmenu.h" + +// --- cRecMenu ------------------------------------------------------------- + +cRecMenu::cRecMenu(void) { + border = 10; + height = 2*border; + headerHeight = 0; + footerHeight = 0; + scrollHeight = 0; + scrollItemHeight = 0; + scrollable = false; + scrollbarWidth = 3 * border; + pixmapScrollBar = NULL; + imgScrollBar = NULL; + startIndex = 0; + stopIndex = 0; + numItems = 0; + header = NULL; + footer = NULL; +} + +cRecMenu::~cRecMenu(void) { + if (header) + delete header; + menuItems.Clear(); + if (footer) + delete footer; + if (pixmapScrollBar) + osdManager.releasePixmap(pixmapScrollBar); + if (imgScrollBar) + delete imgScrollBar; +} + +void cRecMenu::SetWidthPercent(int percentOSDWidth) { + width = tvguideConfig.osdWidth * percentOSDWidth / 100; + x = (tvguideConfig.osdWidth - width) / 2; +} + +void cRecMenu::SetWidthPixel(int pixel) { + width = pixel; + x = (tvguideConfig.osdWidth - width) / 2; +} + +int cRecMenu::CalculateOptimalWidth(void) { + int optWidth = 0; + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + int itemWidth = item->GetWidth(); + if (itemWidth > optWidth) + optWidth = itemWidth; + } + return optWidth; +} + + +void cRecMenu::AddMenuItem(cRecMenuItem *item, cRecMenuItem *before) { + if (!before) + menuItems.Add(item); + else + menuItems.Ins(item, before); +} + +void cRecMenu::AddMenuItemScroll(cRecMenuItem *item) { + scrollHeight += item->GetHeight(); + stopIndex++; + numItems++; + if (scrollItemHeight == 0) + scrollItemHeight = item->GetHeight(); + menuItems.Add(item); +} + +bool cRecMenu::CheckHeight(void) { + int nextHeight = headerHeight + footerHeight + scrollHeight + 2*border + 150; + if (nextHeight > tvguideConfig.osdHeight) { + scrollable = true; + return false; + } + return true; +} + +void cRecMenu::CalculateHeight(void) { + height = 2*border; + if (header) + height += headerHeight; + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + height += item->GetHeight(); + } + if (footer) + height += footerHeight; + y = (tvguideConfig.osdHeight - height) / 2; + + if (scrollable) { + width += scrollbarWidth + border; + } +} + +void cRecMenu::CreatePixmap(void) { + pixmap = osdManager.requestPixmap(3, cRect(x, y, width, height)); + if (scrollable) { + int scrollBarX = x + width - scrollbarWidth - border; + int scrollBarY = y + border + headerHeight; + int scrollBarHeight = height - headerHeight - footerHeight - 2 * border; + pixmapScrollBar = osdManager.requestPixmap(4, cRect(scrollBarX, scrollBarY, scrollbarWidth, scrollBarHeight)); + } +} + +void cRecMenu::SetFooter(cRecMenuItem *footer) { + this->footer = footer; + footerHeight = footer->GetHeight(); + height += footerHeight; +} + +void cRecMenu::SetHeader(cRecMenuItem *header) { + this->header = header; + headerHeight = header->GetHeight(); + height += headerHeight; +} + +cRecMenuItem *cRecMenu::GetActiveMenuItem(void) { + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + if (item->isActive()) + return item; + } + if (footer && footer->isActive()) + return footer; + return NULL; +} + +int cRecMenu::GetActive(bool withOffset) { + int numActive = withOffset?startIndex:0; + int i = 0; + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + if (item->isActive()) { + numActive += i; + break; + } + i++; + } + return numActive; +} + +bool cRecMenu::ActivatePrev(void) { + cRecMenuItem *activeItem = GetActiveMenuItem(); + if (!scrollable && footer && footer->isActive()) { + Activate(footer, menuItems.Last()); + return true; + } else if (activeItem) { + cRecMenuItem *prev = NULL; + for (cRecMenuItem *item = menuItems.Prev(activeItem); item; item = menuItems.Prev(item)) { + if (item->isSelectable()) { + prev = item; + break; + } + } + if (prev) { + Activate(activeItem , prev); + return true; + } + } + return false; +} + +bool cRecMenu::ActivateNext(void) { + cRecMenuItem *activeItem = GetActiveMenuItem(); + if (activeItem) { + cRecMenuItem *next = NULL; + for (cRecMenuItem *item = menuItems.Next(activeItem); item; item = menuItems.Next(item)) { + if (item->isSelectable()) { + next = item; + break; + } + } + if (next) { + Activate(activeItem , next); + return true; + } else if (!scrollable && footer && footer->isSelectable()) { + Activate(activeItem , footer); + return true; + } + } + return false; +} + +void cRecMenu::Activate(cRecMenuItem *itemOld, cRecMenuItem *item) { + itemOld->setInactive(); + itemOld->setBackground(); + itemOld->Draw(); + item->setActive(); + item->setBackground(); + item->Draw(); +} + +void cRecMenu::ScrollUp(void) { + if (footer && footer->isActive()) { + Activate(footer, menuItems.Last()); + } else { + //get perv x items + int numNewItems = numItems / 2; + int numAdded = 0; + cRecMenuItem *newItem = NULL; + while (newItem = GetMenuItem(startIndex-1)) { + AddMenuItem(newItem, menuItems.First()); + menuItems.Del(menuItems.Last(), true); + stopIndex--; + startIndex--; + numAdded++; + if (numAdded >= numNewItems) + break; + } + if (numAdded != 0) { + Arrange(true); + Display(true); + ActivatePrev(); + } + } +} + +void cRecMenu::ScrollDown(void) { + //get next x items + int numNewItems = numItems / 2; + int numAdded = 0; + cRecMenuItem *newItem = NULL; + while (newItem = GetMenuItem(stopIndex)) { + menuItems.Add(newItem); + menuItems.Del(menuItems.First(), true); + stopIndex++; + startIndex++; + numAdded++; + if (numAdded >= numNewItems) + break; + } + if (numAdded != 0) { + Arrange(true); + Display(true); + ActivateNext(); + } else { + //last item reached, activate footer + if (footer) { + cRecMenuItem *activeItem = GetActiveMenuItem(); + Activate(activeItem , footer); + } + } +} + +void cRecMenu::JumpBegin(void) { + cRecMenuItem *activeItem = GetActiveMenuItem(); + if (!scrollable) { + cRecMenuItem *firstSelectable= NULL; + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + if (item->isSelectable()) { + firstSelectable = item; + break; + } + } + if (activeItem && firstSelectable) { + Activate(activeItem , firstSelectable); + } + } else { + activeItem->setInactive(); + activeItem->setBackground(); + if (footer) + footer->Draw(); + menuItems.Clear(); + int currentItem = 0; + cRecMenuItem *newItem = NULL; + while (newItem = GetMenuItem(currentItem)) { + AddMenuItem(newItem); + currentItem++; + if (currentItem >= numItems) + break; + } + Arrange(true); + startIndex = 0; + stopIndex = numItems-1; + menuItems.First()->setActive(); + menuItems.First()->setBackground(); + menuItems.First()->Draw(); + Display(true); + } +} + +void cRecMenu::JumpEnd(void) { + cRecMenuItem *activeItem = GetActiveMenuItem(); + if (!activeItem) + return; + if (!scrollable) { + cRecMenuItem *lastSelectable= NULL; + if (footer && footer->isSelectable()) { + lastSelectable = footer; + } else { + for (cRecMenuItem *item = menuItems.Last(); item; item = menuItems.Prev(item)) { + if (item->isSelectable()) { + lastSelectable = item; + break; + } + } + } + if (lastSelectable) { + Activate(activeItem , lastSelectable); + } + } else { + activeItem->setInactive(); + activeItem->setBackground(); + menuItems.Clear(); + int totalNumItems = GetTotalNumMenuItems(); + int currentItem = totalNumItems-1; + int itemsAdded = 0; + cRecMenuItem *newItem = NULL; + while (newItem = GetMenuItem(currentItem)) { + AddMenuItem(newItem, menuItems.First()); + currentItem--; + itemsAdded++; + if (itemsAdded >= numItems) + break; + } + Arrange(true); + stopIndex = totalNumItems; + startIndex = stopIndex - numItems; + if (footer) { + footer->setActive(); + footer->setBackground(); + footer->Draw(); + } else { + menuItems.Last()->setActive(); + menuItems.Last()->setBackground(); + menuItems.Last()->Draw(); + } + Display(true); + } +} + +void cRecMenu::Arrange(bool scroll) { + int xElement = x + border; + int yElement = y + border; + int widthElement = width - 2 * border; + if (scrollable) + widthElement -= scrollbarWidth + border; + + if (header) { + if (!scroll) { + header->SetGeometry(xElement, yElement, widthElement); + header->SetPixmaps(); + } + yElement += header->GetHeight(); + } + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + item->SetGeometry(xElement, yElement, widthElement); + item->SetPixmaps(); + yElement += item->GetHeight(); + } + if (footer && !scroll) { + footer->SetGeometry(xElement, yElement, widthElement); + footer->SetPixmaps(); + } +} + +void cRecMenu::Display(bool scroll) { + pixmap->Fill(theme.Color(clrBackground)); + drawBorder(); + if (header && !scroll) { + header->setBackground(); + header->Draw(); + } + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + item->setBackground(); + item->Draw(); + } + if (footer && !scroll) { + footer->setBackground(); + footer->Draw(); + } + if (scrollable) + DrawScrollBar(); +} + +void cRecMenu::Hide(void) { + pixmap->SetLayer(-1); + if (pixmapScrollBar) + pixmapScrollBar->SetLayer(-1); + if (header) + header->Hide(); + if (footer) + footer->Hide(); + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + item->Hide(); + } +} + +void cRecMenu::Show(void) { + pixmap->SetLayer(3); + if (pixmapScrollBar) + pixmapScrollBar->SetLayer(3); + if (header) + header->Show(); + if (footer) + footer->Show(); + for (cRecMenuItem *item = menuItems.First(); item; item = menuItems.Next(item)) { + item->Show(); + } +} + +void cRecMenu::DrawScrollBar(void) { + pixmapScrollBar->Fill(theme.Color(clrBorder)); + pixmapScrollBar->DrawRectangle(cRect(2,2,pixmapScrollBar->ViewPort().Width()-4, pixmapScrollBar->ViewPort().Height() - 4), theme.Color(clrBackground)); + + int totalNumItems = GetTotalNumMenuItems(); + if (imgScrollBar == NULL) { + int scrollBarImgHeight = (pixmapScrollBar->ViewPort().Height() - 8) * numItems / totalNumItems; + imgScrollBar = createScrollbar(pixmapScrollBar->ViewPort().Width()-8, scrollBarImgHeight, theme.Color(clrHighlight), theme.Color(clrHighlightBlending)); + } + int offset = (pixmapScrollBar->ViewPort().Height() - 8) * startIndex / totalNumItems; + pixmapScrollBar->DrawImage(cPoint(4, 2 + offset), *imgScrollBar); +} + +int cRecMenu::GetIntValue(int itemNumber) { + cRecMenuItem *item = NULL; + item = menuItems.Get(itemNumber); + if (item) { + return item->GetIntValue(); + } + return -1; +} + +time_t cRecMenu::GetTimeValue(int itemNumber) { + cRecMenuItem *item = NULL; + item = menuItems.Get(itemNumber); + if (item) { + return item->GetTimeValue(); + } + return 0; +} + +bool cRecMenu::GetBoolValue(int itemNumber) { + cRecMenuItem *item = NULL; + item = menuItems.Get(itemNumber); + if (item) { + return item->GetBoolValue(); + } + return false; +} + +cString cRecMenu::GetStringValue(int itemNumber) { + cRecMenuItem *item = NULL; + item = menuItems.Get(itemNumber); + if (item) { + return item->GetStringValue(); + } + return cString(""); +} + +const cEvent *cRecMenu::GetEventValue(int itemNumber) { + cRecMenuItem *item = NULL; + item = menuItems.Get(itemNumber); + if (item) { + return item->GetEventValue(); + } + return NULL; +} + +eRecMenuState cRecMenu::ProcessKey(eKeys Key) { + cRecMenuItem *activeItem = GetActiveMenuItem(); + eRecMenuState state = rmsContinue; + if (!activeItem) + return state; + + state = activeItem->ProcessKey(Key); + if (state == rmsRefresh) { + CreateMenuItems(); + Display(); + } else if (state == rmsNotConsumed) { + switch (Key & ~k_Repeat) { + case kUp: + if (!ActivatePrev() && scrollable) + ScrollUp(); + state = rmsConsumed; + break; + case kDown: + if (!ActivateNext() && scrollable) + ScrollDown(); + state = rmsConsumed; + break; + case kLeft: + JumpBegin(); + state = rmsConsumed; + break; + case kRight: + JumpEnd(); + state = rmsConsumed; + break; + default: + break; + } + } + return state; +} + +cImage *cRecMenu::createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend) { + cImage *image = new cImage(cSize(width, height)); + image->Fill(clrBgr); + if (tvguideConfig.useBlending) { + int numSteps = 64; + int alphaStep = 0x03; + if (height < 30) + return image; + else if (height < 100) { + numSteps = 32; + alphaStep = 0x06; + } + int stepY = 0.5*height / numSteps; + if (stepY == 0) + stepY = 1; + int alpha = 0x40; + tColor clr; + for (int i = 0; iSetPixel(cPoint(x,y), clr); + } + } + alpha += alphaStep; + } + } + return image; +} diff --git a/recmenu.h b/recmenu.h new file mode 100644 index 0000000..87d3ef5 --- /dev/null +++ b/recmenu.h @@ -0,0 +1,61 @@ +#ifndef __TVGUIDE_RECMENU_H +#define __TVGUIDE_RECMENU_H + +// --- cRecMenu ------------------------------------------------------------- + +class cRecMenu : public cStyledPixmap { +protected: + int x, y; + int width, height; + int headerHeight, footerHeight; + int scrollHeight; + int scrollItemHeight; + int scrollbarWidth; + cPixmap *pixmapScrollBar; + cImage *imgScrollBar; + int border; + bool scrollable; + int numItems; + int startIndex, stopIndex; + cRecMenuItem *header; + cRecMenuItem *footer; + cList menuItems; + void SetWidthPercent(int percentOSDWidth); + void SetWidthPixel(int pixel); + int CalculateOptimalWidth(void); + bool CheckHeight(void); + void CalculateHeight(void); + void CreatePixmap(void); + void SetHeader(cRecMenuItem *header); + void SetFooter(cRecMenuItem *footer); + void AddMenuItemScroll(cRecMenuItem *item); + void AddMenuItem(cRecMenuItem *item, cRecMenuItem *before = NULL); + cRecMenuItem *GetActiveMenuItem(void); + bool ActivateNext(void); + bool ActivatePrev(void); + void Activate(cRecMenuItem *itemOld, cRecMenuItem *item); + void ScrollUp(void); + void ScrollDown(void); + void JumpBegin(void); + void JumpEnd(void); + void DrawScrollBar(void); + cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend); + void Arrange(bool scroll = false); + virtual cRecMenuItem *GetMenuItem(int number) { return NULL; }; + virtual int GetTotalNumMenuItems(void) { return 0; }; + virtual void CreateMenuItems(void) {}; +public: + cRecMenu(void); + virtual ~cRecMenu(void); + void Display(bool scroll = false); + void Hide(void); + void Show(void); + int GetActive(bool withOffset); + int GetIntValue(int itemNumber); + time_t GetTimeValue(int itemNumber); + bool GetBoolValue(int itemNumber); + cString GetStringValue(int itemNumber); + const cEvent *GetEventValue(int itemNumber); + eRecMenuState ProcessKey(eKeys Key); +}; +#endif //__TVGUIDE_RECMENU_H \ No newline at end of file diff --git a/recmenuitem.c b/recmenuitem.c new file mode 100644 index 0000000..eb931e9 --- /dev/null +++ b/recmenuitem.c @@ -0,0 +1,2016 @@ +#include +#include +#include "recmenuitem.h" + +// --- cRecMenuItem ------------------------------------------------------------- + +cRecMenuItem::cRecMenuItem(void) { + height = 0; + action = rmsNotConsumed; + drawn = false; + font = tvguideConfig.FontRecMenuItem; + fontSmall = tvguideConfig.FontRecMenuItemSmall; +} + +cRecMenuItem::~cRecMenuItem(void) { +} + +void cRecMenuItem::SetGeometry(int x, int y, int width) { + this->x = x; + this->y = y; + this->width = width; + +} + +void cRecMenuItem::SetPixmaps(void) { + if (!pixmap) + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + else + pixmap->SetViewPort(cRect(x, y, width, height)); +} + +void cRecMenuItem::setBackground(void) { + if (active) { + color = theme.Color(clrHighlight); + colorBlending = theme.Color(clrHighlightBlending); + colorText = theme.Color(clrFontActive); + } else { + color = theme.Color(clrGrid1); + colorBlending = theme.Color(clrGrid1Blending); + colorText = theme.Color(clrFont); + } + colorTextBack = (tvguideConfig.useBlending==0)?color:clrTransparent; + drawBackground(); + drawBorder(); +} + +// --- cRecMenuItemButton ------------------------------------------------------- + +cRecMenuItemButton::cRecMenuItemButton(const char *text, eRecMenuState action, bool active, bool halfWidth) { + selectable = true; + this->text = text; + this->action = action; + this->active = active; + height = 3 * font->Height() / 2; + this->halfWidth = halfWidth; +} + +cRecMenuItemButton::~cRecMenuItemButton(void) { +} + +int cRecMenuItemButton::GetWidth(void) { + return font->Width(*text); +} + +void cRecMenuItemButton::SetPixmaps(void) { + if (halfWidth) { + x += width / 4; + width = width / 2; + } + if (!pixmap) + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + else + pixmap->SetViewPort(cRect(x, y, width, height)); +} + +void cRecMenuItemButton::Draw(void) { + int y = (height - font->Height()) / 2; + int x = (width - font->Width(*text)) / 2;; + pixmap->DrawText(cPoint(x, y), *text, colorText, colorTextBack, font); +} + +eRecMenuState cRecMenuItemButton::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kOk: + return action; + break; + default: + break; + } + return rmsNotConsumed; +} + + +// --- cRecMenuItemButtonYesNo ------------------------------------------------------- +cRecMenuItemButtonYesNo::cRecMenuItemButtonYesNo(cString textYes, + cString textNo, + eRecMenuState actionYes, + eRecMenuState actionNo, + bool active) { + selectable = true; + this->textYes = textYes; + this->textNo = textNo; + this->action = actionYes; + this->actionNo = actionNo; + this->active = active; + yesActive = true; + height = 3 * font->Height() / 2; + pixmapNo = NULL; +} + +cRecMenuItemButtonYesNo::~cRecMenuItemButtonYesNo(void) { + if (pixmapNo) + delete pixmapNo; +} + +void cRecMenuItemButtonYesNo::SetPixmaps(void) { + int buttonWidth = 44 * width / 100; + int yesX = x + width / 25; + int noX = x + 52 * width / 100; + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(yesX, y, buttonWidth, height)); + pixmapNo = new cStyledPixmap(osdManager.requestPixmap(4, cRect(noX, y, buttonWidth, height))); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapNo->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemButtonYesNo::Hide(void) { + pixmap->SetLayer(-1); + pixmapNo->SetLayer(-1); +} + +void cRecMenuItemButtonYesNo::Show(void) { + pixmap->SetLayer(4); + pixmapNo->SetLayer(4); +} + +void cRecMenuItemButtonYesNo::setBackground() { + if (active) { + if (yesActive) { + color = theme.Color(clrHighlight); + colorBlending = theme.Color(clrHighlightBlending); + colorText = theme.Color(clrFontActive); + pixmapNo->setColor( theme.Color(clrGrid1), + theme.Color(clrGrid1Blending)); + colorTextNo = theme.Color(clrFont); + } else { + color = theme.Color(clrGrid1); + colorBlending = theme.Color(clrGrid1Blending); + colorText = theme.Color(clrFont); + pixmapNo->setColor( theme.Color(clrHighlight), + theme.Color(clrHighlightBlending)); + colorTextNo = theme.Color(clrFontActive); + } + } else { + color = theme.Color(clrGrid1); + colorBlending = theme.Color(clrGrid1Blending); + colorText = theme.Color(clrFont); + pixmapNo->setColor( theme.Color(clrGrid1), + theme.Color(clrGrid1Blending)); + colorTextNo = theme.Color(clrFont); + } + colorTextBack = (tvguideConfig.useBlending==0)?color:clrTransparent; + drawBackground(); + drawBorder(); + pixmapNo->drawBackground(); + pixmapNo->drawBorder(); +} + +void cRecMenuItemButtonYesNo::Draw(void) { + int textYesX = (pixmap->ViewPort().Width() - font->Width(*textYes)) / 2; + int textNoX = (pixmapNo->Width() - font->Width(*textNo)) / 2; + int textY = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(textYesX, textY), *textYes, colorText, clrTransparent, font); + pixmapNo->DrawText(cPoint(textNoX, textY), *textNo, colorTextNo, clrTransparent, font); +} + +eRecMenuState cRecMenuItemButtonYesNo::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + if (!yesActive) { + yesActive = true; + setBackground(); + Draw(); + return rmsConsumed; + } else + return rmsNotConsumed; + break; + case kRight: + if (yesActive) { + yesActive = false; + setBackground(); + Draw(); + return rmsConsumed; + } else + return rmsNotConsumed; + break; + case kOk: + if (yesActive) + return action; + return actionNo; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemInfo ------------------------------------------------------- +cRecMenuItemInfo::cRecMenuItemInfo(const char *text) { + selectable = false; + active = false; + this->text = text; + border = 10; +} + +cRecMenuItemInfo::~cRecMenuItemInfo(void) { +} + +void cRecMenuItemInfo::CalculateHeight(int textWidth) { + wrapper.Set(*text, font, textWidth); + height = font->Height() * wrapper.Lines() + 2*border; +} + +void cRecMenuItemInfo::setBackground(void) { + pixmap->Fill(clrTransparent); +} + +void cRecMenuItemInfo::Draw(void) { + int lines = wrapper.Lines(); + int lineHeight = font->Height(); + int x = 0; + int y = border; + for (int i = 0; i < lines; i++) { + x = (width - font->Width(wrapper.GetLine(i))) / 2; + pixmap->DrawText(cPoint(x,y), wrapper.GetLine(i), theme.Color(clrFont), clrTransparent, font); + y += lineHeight; + } +} + +// --- cRecMenuItemInt ------------------------------------------------------- +cRecMenuItemInt::cRecMenuItemInt(cString text, + int initialVal, + int minVal, + int maxVal, + bool active) { + selectable = true; + this->text = text; + this->currentVal = initialVal; + this->minVal = minVal; + this->maxVal = maxVal; + this->active = active; + height = 3 * font->Height() / 2; + pixmapVal = NULL; + fresh = true; +} + +cRecMenuItemInt::~cRecMenuItemInt(void) { + if (pixmapVal) + osdManager.releasePixmap(pixmapVal); +} + +void cRecMenuItemInt::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapVal = osdManager.requestPixmap(5, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapVal->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemInt::Hide(void) { + pixmap->SetLayer(-1); + pixmapVal->SetLayer(-1); +} + +void cRecMenuItemInt::Show(void) { + pixmap->SetLayer(4); + pixmapVal->SetLayer(5); +} + +void cRecMenuItemInt::setBackground() { + cRecMenuItem::setBackground(); + fresh = true; +} + +void cRecMenuItemInt::Draw(void) { + int textY = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(10, textY), *text, colorText, colorTextBack, font); + DrawValue(); +} + +void cRecMenuItemInt::DrawValue(void) { + pixmapVal->Fill(clrTransparent); + cString textVal = cString::sprintf("%d", currentVal); + int textX = width - font->Width(*textVal) - 10; + int textY = (height - font->Height()) / 2; + pixmapVal->DrawText(cPoint(textX, textY), *textVal, colorText, clrTransparent, font); +} + +eRecMenuState cRecMenuItemInt::ProcessKey(eKeys Key) { + int oldValue = currentVal; + switch (Key & ~k_Repeat) { + case kLeft: + fresh = true; + if (currentVal > minVal) { + currentVal--; + DrawValue(); + } + return rmsConsumed; + break; + case kRight: + fresh = true; + if (currentVal < maxVal) { + currentVal++; + DrawValue(); + } + return rmsConsumed; + break; + case k0 ... k9: + if (fresh) { + currentVal = 0; + fresh = false; + } + currentVal = currentVal * 10 + (Key - k0); + if (!((currentVal >= minVal) && (currentVal <= maxVal))) + currentVal = oldValue; + DrawValue(); + return rmsConsumed; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemBool ------------------------------------------------------- +cRecMenuItemBool::cRecMenuItemBool(cString text, + bool initialVal, + bool refresh, + bool active) { + selectable = true; + this->text = text; + this->yes = initialVal; + this->refresh = refresh; + this->active = active; + height = 3 * font->Height() / 2; + pixmapVal = NULL; +} + +cRecMenuItemBool::~cRecMenuItemBool(void) { + if (pixmapVal) + osdManager.releasePixmap(pixmapVal); +} + +void cRecMenuItemBool::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapVal = osdManager.requestPixmap(5, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapVal->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemBool::Hide(void) { + pixmap->SetLayer(-1); + pixmapVal->SetLayer(-1); +} + +void cRecMenuItemBool::Show(void) { + pixmap->SetLayer(4); + pixmapVal->SetLayer(5); +} + +void cRecMenuItemBool::Draw(void) { + int textY = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(10, textY), *text, colorText, colorTextBack, font); + DrawValue(); +} + +void cRecMenuItemBool::DrawValue(void) { + pixmapVal->Fill(clrTransparent); + cString strIcon = yes?"yes":"no"; + int iconSize = height - 8; + int iconX = width - iconSize - 10; + int iconY = (height - iconSize) / 2; + cImageLoader imgLoader; + if (imgLoader.LoadIcon(strIcon, iconSize)) { + cImage icon = imgLoader.GetImage(); + pixmapVal->DrawImage(cPoint(iconX, iconY), icon); + } +} + +eRecMenuState cRecMenuItemBool::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + case kRight: + yes = !yes; + DrawValue(); + if (refresh) + return rmsRefresh; + else + return rmsConsumed; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemSelect ------------------------------------------------------- +cRecMenuItemSelect::cRecMenuItemSelect(cString text, + const char * const *Strings, + int initialVal, + int numValues, + bool active) { + selectable = true; + this->text = text; + strings = Strings; + this->numValues = numValues; + if ((initialVal < 0) || (initialVal > numValues-1)) + this->currentVal = 0; + else + this->currentVal = initialVal; + this->active = active; + height = 3 * font->Height() / 2; + pixmapVal = NULL; +} + +cRecMenuItemSelect::~cRecMenuItemSelect(void) { + if (pixmapVal) + osdManager.releasePixmap(pixmapVal); +} + +void cRecMenuItemSelect::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapVal = osdManager.requestPixmap(5, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapVal->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemSelect::Hide(void) { + pixmap->SetLayer(-1); + pixmapVal->SetLayer(-1); +} + +void cRecMenuItemSelect::Show(void) { + pixmap->SetLayer(4); + pixmapVal->SetLayer(5); +} + +void cRecMenuItemSelect::Draw(void) { + int textY = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(10, textY), *text, colorText, colorTextBack, font); + DrawValue(); +} + +void cRecMenuItemSelect::DrawValue(void) { + pixmapVal->Fill(clrTransparent); + const char *textVal = strings[currentVal]; + int iconSize = min(128, height); + int textX = width - font->Width(textVal) - iconSize; + int textY = (height - font->Height()) / 2; + pixmapVal->DrawText(cPoint(textX, textY), textVal, colorText, clrTransparent, font); + int iconLeftX = textX - iconSize; + int iconRightX = width - iconSize; + int iconY = (height - iconSize) / 2; + cImageLoader imgLoader; + if (imgLoader.LoadIcon("arrow_left", iconSize)) { + cImage icon = imgLoader.GetImage(); + pixmapVal->DrawImage(cPoint(iconLeftX, iconY), icon); + } + if (imgLoader.LoadIcon("arrow_right", iconSize)) { + cImage icon = imgLoader.GetImage(); + pixmapVal->DrawImage(cPoint(iconRightX, iconY), icon); + } +} + +eRecMenuState cRecMenuItemSelect::ProcessKey(eKeys Key) { + int oldValue = currentVal; + switch (Key & ~k_Repeat) { + case kLeft: + currentVal--; + if (currentVal<0) + currentVal = numValues - 1; + DrawValue(); + return rmsConsumed; + break; + case kRight: + currentVal = (currentVal+1)%numValues; + DrawValue(); + return rmsConsumed; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemText ------------------------------------------------------- +cRecMenuItemText::cRecMenuItemText(cString title, + char *initialVal, + int length, + bool active) { + selectable = true; + this->title = title; + value = initialVal; + this->active = active; + height = 3 * font->Height(); + pixmapVal = NULL; + pixmapKeyboard = NULL; + pixmapKeyboardHighlight = NULL; + pixmapKeyboardIcons = NULL; + keyboardWidth = 50; + gridHeight = 3 * fontSmall->Height(); + keyboardHeight = 5 * gridHeight; + + this->length = length; + allowed = trVDR(FileNameChars); + pos = -1; + offset = 0; + insert = uppercase = false; + newchar = true; + lengthUtf8 = 0; + valueUtf8 = NULL; + allowedUtf8 = NULL; + charMapUtf8 = NULL; + currentCharUtf8 = NULL; + lastKey = kNone; + keyboardDrawn = false; +} + +cRecMenuItemText::~cRecMenuItemText(void) { + if (pixmapVal) + osdManager.releasePixmap(pixmapVal); + if (pixmapKeyboard) + delete pixmapKeyboard; + if (pixmapKeyboardHighlight) + osdManager.releasePixmap(pixmapKeyboardHighlight); + if (pixmapKeyboardIcons) + osdManager.releasePixmap(pixmapKeyboardIcons); + delete[] valueUtf8; + delete[] allowedUtf8; + delete[] charMapUtf8; +} + +void cRecMenuItemText::SetPixmaps(void) { + int xPixmapVal = x + 20; + int yPixmapVal = y + height / 2 + 10; + int widthPixmapVal = width - 40; + int heightPixmapVal = height / 2 - 20; + int keyboardX = x + (100 - keyboardWidth)*width / 100; + int keyboardY = y + height; + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapVal = osdManager.requestPixmap(5, cRect(xPixmapVal, yPixmapVal, widthPixmapVal, heightPixmapVal)); + pixmapKeyboard = new cStyledPixmap(osdManager.requestPixmap(-1, cRect(keyboardX, keyboardY, keyboardWidth*width/100, keyboardHeight))); + pixmapKeyboardHighlight = osdManager.requestPixmap(-1, cRect(keyboardX, keyboardY, keyboardWidth*width/100, keyboardHeight)); + pixmapKeyboardIcons = osdManager.requestPixmap(-1, cRect(keyboardX, keyboardY, keyboardWidth*width/100, keyboardHeight)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapVal->SetViewPort(cRect(xPixmapVal, yPixmapVal, widthPixmapVal, heightPixmapVal)); + pixmapKeyboard->SetViewPort(cRect(keyboardX, keyboardY, keyboardWidth*width/100, keyboardHeight)); + pixmapKeyboardHighlight->SetViewPort(cRect(keyboardX, keyboardY, keyboardWidth*width/100, keyboardHeight)); + pixmapKeyboardIcons->SetViewPort(cRect(keyboardX, keyboardY, keyboardWidth*width/100, keyboardHeight)); + } + pixmapKeyboardIcons->Fill(clrTransparent); +} + +void cRecMenuItemText::Hide(void) { + pixmap->SetLayer(-1); + pixmapVal->SetLayer(-1); + pixmapKeyboard->SetLayer(-1); + pixmapKeyboardHighlight->SetLayer(-1); + pixmapKeyboardIcons->SetLayer(-1); +} + +void cRecMenuItemText::Show(void) { + pixmap->SetLayer(4); + pixmapVal->SetLayer(5); +} + +void cRecMenuItemText::setBackground() { + if (!active) { + DeactivateKeyboard(); + } + cRecMenuItem::setBackground(); +} + +void cRecMenuItemText::Draw(void) { + int textY = (height/2 - font->Height()) / 2; + pixmap->DrawText(cPoint(10, textY), *title, colorText, colorTextBack, font); + DrawValue(value); +} + +void cRecMenuItemText::DrawValue(char *newValue) { + tColor clrBack = InEditMode()?theme.Color(clrRecMenuTextActiveBack):theme.Color(clrRecMenuTextBack); + pixmapVal->Fill(clrBack); + int textX = pixmapVal->DrawPort().Width() - font->Width(newValue) - 10; + int textY = (pixmapVal->DrawPort().Height() - font->Height()) / 2; + pixmapVal->DrawText(cPoint(textX, textY), newValue, colorText, clrTransparent, font); +} + +void cRecMenuItemText::ActivateKeyboard(void) { + pixmapKeyboard->SetLayer(6); + pixmapKeyboardHighlight->SetLayer(6); + pixmapKeyboardIcons->SetLayer(6); + pixmapKeyboardHighlight->Fill(clrTransparent); + + if (keyboardDrawn) + return; + + pixmapKeyboard->setColor(theme.Color(clrRecMenuKeyboardBack), theme.Color(clrRecMenuKeyboardBack)); + pixmapKeyboard->drawBackground(); + + int widthKeyBoard = pixmapKeyboard->Width(); + gridWidth = widthKeyBoard / 3; + + pixmapKeyboard->DrawRectangle(cRect(0, 0, widthKeyBoard, keyboardHeight), theme.Color(clrRecMenuKeyboardBorder)); + int num = 1; + for (int row = 0; row < 5; row++) { + for (int col = 0; col < 3; col++) { + int X = col*gridWidth; + int Y = row*gridHeight; + tColor clrBack = theme.Color(clrRecMenuKeyboardBack); + if (num==13) + clrBack = theme.Color(clrButtonRedKeyboard); + else if (num==14) + clrBack = theme.Color(clrButtonGreenKeyboard); + else if (num==15) + clrBack = theme.Color(clrButtonYellowKeyboard); + pixmapKeyboard->DrawRectangle(cRect(X+2, Y+2, gridWidth-4, gridHeight-4), clrBack); + pixmapKeyboard->DrawEllipse(cRect(X, Y, 20, 20), theme.Color(clrRecMenuKeyboardBorder),-2); + pixmapKeyboard->DrawEllipse(cRect(X, Y+gridHeight-20, 20, 20), theme.Color(clrRecMenuKeyboardBorder),-3); + pixmapKeyboard->DrawEllipse(cRect(X+gridWidth-20, Y+gridHeight-20, 20, 20), theme.Color(clrRecMenuKeyboardBorder),-4); + pixmapKeyboard->DrawEllipse(cRect(X+gridWidth-20, Y, 20, 20), theme.Color(clrRecMenuKeyboardBorder),-1); + bool draw = false; + bool drawIcon = false; + cString strNum; + cString strIcon; + cImageLoader imgLoader; + if (num<10) { + strNum = *cString::sprintf("%d", num); + draw = true; + } else if (num == 11) { + strNum = *cString::sprintf("%d", 0); + draw = true; + } else if (num==13) { + strIcon = "icon_shift"; + drawIcon = true; + } else if (num==14) { + strIcon = "icon_del_ins"; + drawIcon = true; + } else if (num==15) { + strIcon = "icon_backspace"; + drawIcon = true; + } + if (draw) { + int numX = X + (gridWidth - font->Width(*strNum))/2; + int numY = Y + font->Height() / 4; + pixmapKeyboard->DrawText(cPoint(numX, numY), *strNum, colorText, colorTextBack, font); + char *smsKeys = GetSMSKeys(num); + int smsKeysX = X + (gridWidth - fontSmall->Width(smsKeys))/2; + int smsKeysY = Y + gridHeight - fontSmall->Height() - 10; + pixmapKeyboard->DrawText(cPoint(smsKeysX, smsKeysY), smsKeys, theme.Color(clrRecMenuKeyboardBorder), colorTextBack, fontSmall); + delete[] smsKeys; + } + if (drawIcon) { + int iconSize = gridHeight - 10; + if (imgLoader.LoadIcon(strIcon, iconSize)) { + cImage icon = imgLoader.GetImage(); + int iconX = X + (gridWidth - iconSize) / 2; + pixmapKeyboardIcons->DrawImage(cPoint(iconX, Y + 5), icon); + } + } + num++; + } + } + keyboardDrawn = true; +} + +void cRecMenuItemText::DeactivateKeyboard(void) { + pixmapKeyboard->SetLayer(-1); + pixmapKeyboardHighlight->SetLayer(-1); + pixmapKeyboardIcons->SetLayer(-1); +} + +void cRecMenuItemText::HighlightSMSKey(int num) { + int x = 0; + int y = 0; + if (num == 0) { + x = gridWidth; + y = 3 * gridHeight; + } else { + x = (num-1)%3 * gridWidth; + y = (num-1)/3 * gridHeight; + } + pixmapKeyboardHighlight->DrawRectangle(cRect(x, y, gridWidth, gridHeight), theme.Color(clrRecMenuKeyboardHigh)); +} + +void cRecMenuItemText::ClearSMSKey(void) { + pixmapKeyboardHighlight->Fill(clrTransparent); +} + + +char *cRecMenuItemText::GetSMSKeys(int num) { + if (num == 11) + num = 0; + if (num > 9) + return NULL; + + currentCharUtf8 = charMapUtf8; + int pos = num; + while (pos > 0 && *currentCharUtf8) { + if (*currentCharUtf8++ == '\t') + pos--; + } + while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8)) { + currentCharUtf8++; + } + uint *startCharUtf8 = currentCharUtf8; + int numChars = 0; + bool specialChar = false; + while(*currentCharUtf8 && *currentCharUtf8 != '\t' && IsAllowed(*currentCharUtf8)) { + currentCharUtf8++; + if (Utf8CharSet(*currentCharUtf8) > 1) + specialChar = true; + numChars++; + } + char buf[100]; + char *p = buf; + int addition = 0; + if (specialChar) + addition = 1; + Utf8FromArray(startCharUtf8, p, numChars+addition); + int maxChars = min(numChars+1+addition, 8); + char *smskey = new char[maxChars]; + Utf8Strn0Cpy(smskey, p, maxChars); + return smskey; +} + +void cRecMenuItemText::EnterEditMode(void) { + if (!valueUtf8) { + valueUtf8 = new uint[length]; + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + int l = strlen(allowed) + 1; + allowedUtf8 = new uint[l]; + Utf8ToArray(allowed, allowedUtf8, l); + const char *charMap = trVDR("CharMap$ 0\t-.,1#~\\^$[]|()*+?{}/:%@&\tabc2\tdef3\tghi4\tjkl5\tmno6\tpqrs7\ttuv8\twxyz9"); + l = strlen(charMap) + 1; + charMapUtf8 = new uint[l]; + Utf8ToArray(charMap, charMapUtf8, l); + currentCharUtf8 = charMapUtf8; + AdvancePos(); + } +} + +void cRecMenuItemText::LeaveEditMode(bool SaveValue) { + if (valueUtf8) { + if (SaveValue) { + Utf8FromArray(valueUtf8, value, length); + stripspace(value); + } + lengthUtf8 = 0; + delete[] valueUtf8; + valueUtf8 = NULL; + delete[] allowedUtf8; + allowedUtf8 = NULL; + delete[] charMapUtf8; + charMapUtf8 = NULL; + pos = -1; + offset = 0; + newchar = true; + } +} + +void cRecMenuItemText::AdvancePos(void) { + if (pos < length - 2 && pos < lengthUtf8) { + if (++pos >= lengthUtf8) { + if (pos >= 2 && valueUtf8[pos - 1] == ' ' && valueUtf8[pos - 2] == ' ') + pos--; // allow only two blanks at the end + else { + valueUtf8[pos] = ' '; + valueUtf8[pos + 1] = 0; + lengthUtf8++; + } + } + } + newchar = true; + if (!insert && Utf8is(alpha, valueUtf8[pos])) + uppercase = Utf8is(upper, valueUtf8[pos]); +} + +uint cRecMenuItemText::Inc(uint c, bool Up) { + uint *p = IsAllowed(c); + if (!p) + p = allowedUtf8; + if (Up) { + if (!*++p) + p = allowedUtf8; + } else if (--p < allowedUtf8) { + p = allowedUtf8; + while (*p && *(p + 1)) + p++; + } + return *p; +} + +void cRecMenuItemText::Type(uint c) { + if (insert && lengthUtf8 < length - 1) + Insert(); + valueUtf8[pos] = c; + if (pos < length - 2) + pos++; + if (pos >= lengthUtf8) { + valueUtf8[pos] = ' '; + valueUtf8[pos + 1] = 0; + lengthUtf8 = pos + 1; + } +} + +void cRecMenuItemText::Insert(void) { + memmove(valueUtf8 + pos + 1, valueUtf8 + pos, (lengthUtf8 - pos + 1) * sizeof(*valueUtf8)); + lengthUtf8++; + valueUtf8[pos] = ' '; +} + +void cRecMenuItemText::Delete(void) { + memmove(valueUtf8 + pos, valueUtf8 + pos + 1, (lengthUtf8 - pos) * sizeof(*valueUtf8)); + lengthUtf8--; +} + +uint *cRecMenuItemText::IsAllowed(uint c) { + if (allowedUtf8) { + for (uint *a = allowedUtf8; *a; a++) { + if (c == *a) + return a; + } + } + return NULL; +} + +void cRecMenuItemText::SetText(void) { + if (InEditMode()) { + int textAreaWidth = width - 20; + textAreaWidth -= font->Width("[]"); + textAreaWidth -= font->Width("<>"); // reserving this anyway make the whole thing simpler + if (pos < offset) + offset = pos; + int WidthFromOffset = 0; + int EndPos = lengthUtf8; + for (int i = offset; i < lengthUtf8; i++) { + WidthFromOffset += font->Width(valueUtf8[i]); + if (WidthFromOffset > textAreaWidth) { + if (pos >= i) { + do { + WidthFromOffset -= font->Width(valueUtf8[offset]); + offset++; + } while (WidthFromOffset > textAreaWidth && offset < pos); + EndPos = pos + 1; + } else { + EndPos = i; + break; + } + } + } + char buf[1000]; + char *p = buf; + if (offset) + *p++ = '<'; + p += Utf8FromArray(valueUtf8 + offset, p, sizeof(buf) - (p - buf), pos - offset); + *p++ = '['; + if (insert && newchar) + *p++ = ']'; + p += Utf8FromArray(&valueUtf8[pos], p, sizeof(buf) - (p - buf), 1); + if (!(insert && newchar)) + *p++ = ']'; + p += Utf8FromArray(&valueUtf8[pos + 1], p, sizeof(buf) - (p - buf), EndPos - pos - 1); + if (EndPos != lengthUtf8) + *p++ = '>'; + *p = 0; + DrawValue(buf); + } else { + DrawValue(value); + } +} + +eRecMenuState cRecMenuItemText::ProcessKey(eKeys Key) { + bool consumed = false; + bool SameKey = NORMALKEY(Key) == lastKey; + ClearSMSKey(); + if (Key != kNone) { + lastKey = NORMALKEY(Key); + } else if (!newchar && k0 <= lastKey && lastKey <= k9 && autoAdvanceTimeout.TimedOut()) { + AdvancePos(); + newchar = true; + currentCharUtf8 = NULL; + SetText(); + return rmsConsumed; + } + + switch ((int)Key) { + case kRed: // Switch between upper- and lowercase characters + if (InEditMode()) { + if (!insert || !newchar) { + uppercase = !uppercase; + valueUtf8[pos] = uppercase ? Utf8to(upper, valueUtf8[pos]) : Utf8to(lower, valueUtf8[pos]); + } + consumed = true; + } + break; + case kGreen: // Toggle insert/overwrite modes + if (InEditMode()) { + insert = !insert; + newchar = true; + consumed = true; + } + break; + case kYellow|k_Repeat: + case kYellow: // Remove the character at the current position; in insert mode it is the character to the right of the cursor + if (InEditMode()) { + if (lengthUtf8 > 1) { + if (!insert || pos < lengthUtf8 - 1) + Delete(); + else if (insert && pos == lengthUtf8 - 1) + valueUtf8[pos] = ' '; // in insert mode, deleting the last character replaces it with a blank to keep the cursor position + // reduce position, if we removed the last character + if (pos == lengthUtf8) + pos--; + } else if (lengthUtf8 == 1) + valueUtf8[0] = ' '; // This is the last character in the string, replace it with a blank + if (Utf8is(alpha, valueUtf8[pos])) + uppercase = Utf8is(upper, valueUtf8[pos]); + newchar = true; + consumed = true; + } + break; + case kLeft|k_Repeat: + case kLeft: + + if (pos > 0) { + if (!insert || newchar) + pos--; + newchar = true; + if (!insert && Utf8is(alpha, valueUtf8[pos])) + uppercase = Utf8is(upper, valueUtf8[pos]); + } + consumed = true; + break; + case kRight|k_Repeat: + case kRight: + if (InEditMode()) { + AdvancePos(); + } else { + EnterEditMode(); + ActivateKeyboard(); + } + consumed = true; + break; + case kUp|k_Repeat: + case kUp: + case kDown|k_Repeat: + case kDown: + if (InEditMode()) { + if (insert && newchar) { + // create a new character in insert mode + if (lengthUtf8 < length - 1) + Insert(); + } + if (uppercase) + valueUtf8[pos] = Utf8to(upper, Inc(Utf8to(lower, valueUtf8[pos]), NORMALKEY(Key) == kUp)); + else + valueUtf8[pos] = Inc( valueUtf8[pos], NORMALKEY(Key) == kUp); + newchar = false; + consumed = true; + } + break; + case k0|k_Repeat ... k9|k_Repeat: + case k0 ... k9: { + if (InEditMode()) { + if (Setup.NumberKeysForChars) { + HighlightSMSKey(NORMALKEY(Key) - k0); + if (!SameKey) { + if (!newchar) + AdvancePos(); + currentCharUtf8 = NULL; + } + if (!currentCharUtf8 || !*currentCharUtf8 || *currentCharUtf8 == '\t') { + // find the beginning of the character map entry for Key + int n = NORMALKEY(Key) - k0; + currentCharUtf8 = charMapUtf8; + while (n > 0 && *currentCharUtf8) { + if (*currentCharUtf8++ == '\t') + n--; + } + // find first allowed character + while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8)) + currentCharUtf8++; + } + if (*currentCharUtf8 && *currentCharUtf8 != '\t') { + if (insert && newchar) { + // create a new character in insert mode + if (lengthUtf8 < length - 1) + Insert(); + } + valueUtf8[pos] = *currentCharUtf8; + if (uppercase) + valueUtf8[pos] = Utf8to(upper, valueUtf8[pos]); + // find next allowed character + do { + currentCharUtf8++; + } while (*currentCharUtf8 && *currentCharUtf8 != '\t' && !IsAllowed(*currentCharUtf8)); + newchar = false; + autoAdvanceTimeout.Set(AUTO_ADVANCE_TIMEOUT); + } + } else { + Type('0' + NORMALKEY(Key) - k0); + } + consumed = true; + } + break; } + case kBack: + case kOk: + if (InEditMode()) { + LeaveEditMode(Key == kOk); + DeactivateKeyboard(); + } else { + EnterEditMode(); + ActivateKeyboard(); + } + consumed = true; + break; + default: + if (InEditMode() && BASICKEY(Key) == kKbd) { + int c = KEYKBD(Key); + if (c <= 0xFF) { + if (IsAllowed(Utf8to(lower, c))) + Type(c); + else { + switch (c) { + case 0x7F: // backspace + if (pos > 0) { + pos--; + ProcessKey(kYellow); + } + break; + default: ; + } + } + } else { + switch (c) { + case kfHome: pos = 0; break; + case kfEnd: pos = lengthUtf8 - 1; break; + case kfIns: ProcessKey(kGreen); + case kfDel: ProcessKey(kYellow); + default: ; + } + } + consumed = true; + } + break; + } + SetText(); + if (consumed) + return rmsConsumed; + return rmsNotConsumed; +} + +// --- cRecMenuItemTime ------------------------------------------------------- +cRecMenuItemTime::cRecMenuItemTime(cString text, + int initialVal, + bool active) { + selectable = true; + this->text = text; + this->value = initialVal; + hh = value / 100; + mm = value % 100; + pos = 0; + fresh = true; + this->active = active; + height = 3 * font->Height() / 2; + pixmapVal = NULL; +} + +cRecMenuItemTime::~cRecMenuItemTime(void) { + if (pixmapVal) + osdManager.releasePixmap(pixmapVal); +} + +void cRecMenuItemTime::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapVal = osdManager.requestPixmap(5, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapVal->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemTime::Hide(void) { + pixmap->SetLayer(-1); + pixmapVal->SetLayer(-1); +} + +void cRecMenuItemTime::Show(void) { + pixmap->SetLayer(4); + pixmapVal->SetLayer(5); +} + +void cRecMenuItemTime::Draw(void) { + int textY = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(10, textY), *text, colorText, colorTextBack, font); + DrawValue(); +} + +void cRecMenuItemTime::DrawValue(void) { + pixmapVal->Fill(clrTransparent); + char buf[10]; + switch (pos) { + case 1: snprintf(buf, sizeof(buf), "%01d-:--", hh / 10); break; + case 2: snprintf(buf, sizeof(buf), "%02d:--", hh); break; + case 3: snprintf(buf, sizeof(buf), "%02d:%01d-", hh, mm / 10); break; + default: snprintf(buf, sizeof(buf), "%02d:%02d", hh, mm); + } + int textX = width - font->Width(buf) - 10; + int textY = (height - font->Height()) / 2; + pixmapVal->DrawText(cPoint(textX, textY), buf, colorText, clrTransparent, font); +} + +eRecMenuState cRecMenuItemTime::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft|k_Repeat: + case kLeft: { + if (--mm < 0) { + mm = 59; + if (--hh < 0) + hh = 23; + } + fresh = true; + value = hh * 100 + mm; + DrawValue(); + return rmsConsumed; + break; } + case kRight|k_Repeat: + case kRight: { + if (++mm > 59) { + mm = 0; + if (++hh > 23) + hh = 0; + } + fresh = true; + value = hh * 100 + mm; + DrawValue(); + return rmsConsumed; + break; } + case k0|k_Repeat ... k9|k_Repeat: + case k0 ... k9: { + if (fresh || pos > 3) { + pos = 0; + fresh = false; + } + int n = Key - k0; + switch (pos) { + case 0: + if (n <= 2) { + hh = n * 10; + mm = 0; + pos++; + } + break; + case 1: + if (hh + n <= 23) { + hh += n; + pos++; + } + break; + case 2: + if (n <= 5) { + mm += n * 10; + pos++; + } + break; + case 3: + if (mm + n <= 59) { + mm += n; + pos++; + } + break; + default: ; + } + value = hh * 100 + mm; + DrawValue(); + return rmsConsumed; + break; } + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemDay ------------------------------------------------------- +cRecMenuItemDay::cRecMenuItemDay(cString text, + time_t initialVal, + bool active) { + selectable = true; + this->text = text; + this->currentVal = cTimer::SetTime(initialVal, 0); + this->active = active; + height = 3 * font->Height() / 2; + pixmapVal = NULL; +} + +cRecMenuItemDay::~cRecMenuItemDay(void) { + if (pixmapVal) + osdManager.releasePixmap(pixmapVal); +} + +void cRecMenuItemDay::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapVal = osdManager.requestPixmap(5, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapVal->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemDay::Hide(void) { + pixmap->SetLayer(-1); + pixmapVal->SetLayer(-1); +} + +void cRecMenuItemDay::Show(void) { + pixmap->SetLayer(4); + pixmapVal->SetLayer(5); +} + +void cRecMenuItemDay::Draw(void) { + int textY = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(10, textY), *text, colorText, colorTextBack, font); + DrawValue(); +} + +void cRecMenuItemDay::DrawValue(void) { + pixmapVal->Fill(clrTransparent); + cString textVal = DateString(currentVal); + int textX = width - font->Width(*textVal) - 10; + int textY = (height - font->Height()) / 2; + pixmapVal->DrawText(cPoint(textX, textY), *textVal, colorText, clrTransparent, font); +} + +eRecMenuState cRecMenuItemDay::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + currentVal -= 60*60*24; + DrawValue(); + return rmsConsumed; + break; + case kRight: + currentVal += 60*60*24; + DrawValue(); + return rmsConsumed; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemTimer ------------------------------------------------------- +cRecMenuItemTimer::cRecMenuItemTimer(const cTimer *timer, + eRecMenuState action1, + eRecMenuState action2, + eRecMenuState action3, + time_t conflictStart, + time_t conflictStop, + time_t overlapStart, + time_t overlapStop, + bool active) { + selectable = true; + this->timer = timer; + this->action = action1; + this->action2 = action2; + this->action3 = action3; + iconActive = 0; + this->conflictStart = conflictStart; + this->conflictStop = conflictStop; + this->overlapStart = overlapStart; + this->overlapStop = overlapStop; + this->active = active; + height = 3 * font->Height(); + pixmapIcons = NULL; +} + +cRecMenuItemTimer::~cRecMenuItemTimer(void) { + if (pixmapIcons) + osdManager.releasePixmap(pixmapIcons); + if (pixmapStatus) + osdManager.releasePixmap(pixmapStatus); +} + +void cRecMenuItemTimer::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapStatus = osdManager.requestPixmap(5, cRect(x, y, width, height)); + pixmapIcons = osdManager.requestPixmap(6, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapStatus->SetViewPort(cRect(x, y, width, height)); + pixmapIcons->SetViewPort(cRect(x, y, width, height)); + } + pixmapStatus->Fill(clrTransparent); + pixmapIcons->Fill(clrTransparent); +} + +void cRecMenuItemTimer::Hide(void) { + pixmap->SetLayer(-1); + pixmapStatus->SetLayer(-1); + pixmapIcons->SetLayer(-1); +} + +void cRecMenuItemTimer::Show(void) { + pixmap->SetLayer(4); + pixmapStatus->SetLayer(5); + pixmapIcons->SetLayer(6); +} + +void cRecMenuItemTimer::Draw(void) { + const cChannel *channel = timer->Channel(); + cString channelName(""); + int channelTransponder = 0; + if (channel) { + channelName = channel->Name(); + channelTransponder = channel->Transponder(); + } + int logoX = DrawIcons(); + int logoWidth = height * tvguideConfig.logoWidthRatio / tvguideConfig.logoHeightRatio; + cImageLoader imgLoader; + if (!tvguideConfig.hideChannelLogos) { + if (imgLoader.LoadLogo(*channelName, logoWidth, height)) { + cImage logo = imgLoader.GetImage(); + pixmapIcons->DrawImage(cPoint(logoX, 0), logo); + logoX += logoWidth + 5; + } + } + int textX = logoX; + int textHeightLine1 = (height/2 - font->Height()) / 2; + int textHeightLine2 = height/2 - 5 + (height/4 - fontSmall->Height()) / 2; + int textHeightLine3 = 3*height/4 - 5 + (height/4 - fontSmall->Height()) / 2; + const cEvent *event = timer->Event(); + cString timerTitle(""); + if (event) + timerTitle = event->Title(); + cString timeStart = DayDateTime(timer->StartTime()); + cString timeEnd = TimeString(timer->StopTime()); + cString timerTime = cString::sprintf("%s - %s", *timeStart, *timeEnd); + cString channelInfo = cString::sprintf("%s, %s %d", *channelName, tr("Transp."), channelTransponder); + pixmap->DrawText(cPoint(textX, textHeightLine1), *timerTitle, theme.Color(clrFont), clrTransparent, font); + pixmap->DrawText(cPoint(textX, textHeightLine2), *timerTime, theme.Color(clrFont), clrTransparent, fontSmall); + pixmap->DrawText(cPoint(textX, textHeightLine3), *channelInfo, theme.Color(clrFont), clrTransparent, fontSmall); + + DrawTimerConflict(); +} + +int cRecMenuItemTimer::DrawIcons(void) { + int iconsX = 10; + int iconSize = 64; + int iconY = (height - iconSize) / 2; + cString iconInfo, iconDelete, iconEdit; + if (active) { + iconInfo = (iconActive==0)?"info_active":"info_inactive"; + iconDelete = (iconActive==1)?"delete_active":"delete_inactive"; + iconEdit = (iconActive==2)?"edit_active":"edit_inactive"; + } else { + iconInfo = "info_inactive"; + iconDelete = "delete_inactive"; + iconEdit = "edit_inactive"; + } + cImageLoader imgLoader; + if (imgLoader.LoadIcon(iconInfo, iconSize)) { + cImage icon = imgLoader.GetImage(); + pixmapIcons->DrawImage(cPoint(iconsX, iconY), icon); + iconsX += iconSize + 5; + } + if (imgLoader.LoadIcon(iconDelete, iconSize)) { + cImage icon = imgLoader.GetImage(); + pixmapIcons->DrawImage(cPoint(iconsX, iconY), icon); + iconsX += iconSize + 5; + } + if (imgLoader.LoadIcon(iconEdit, iconSize)) { + cImage icon = imgLoader.GetImage(); + pixmapIcons->DrawImage(cPoint(iconsX, iconY), icon); + iconsX += iconSize + 5; + } + return iconsX; +} + +void cRecMenuItemTimer::DrawTimerConflict(void) { + int widthConfl = 30 * width / 100; + int xConfl = width - widthConfl; + int heightConflBar = height / 4; + int yConflBar = (height - heightConflBar) / 2; + pixmapStatus->DrawRectangle(cRect(xConfl, 0, widthConfl, height), theme.Color(clrRecMenuTimerConflictBackground)); + + int completeWidthSecs = conflictStop - conflictStart; + int xConfBar = xConfl + (timer->StartTime() - conflictStart) * widthConfl / completeWidthSecs; + int widthConfBar = (timer->StopTime() - timer->StartTime()) * widthConfl / completeWidthSecs; + pixmapStatus->DrawRectangle(cRect(xConfBar, yConflBar, widthConfBar, heightConflBar), theme.Color(clrRecMenuTimerConflictBar)); + + int xOverlap = xConfl + (overlapStart - conflictStart) * widthConfl / completeWidthSecs; + int widthOverlap = (overlapStop - overlapStart) * widthConfl / completeWidthSecs; + + pixmapIcons->DrawRectangle(cRect(xOverlap, 0, widthOverlap, height), theme.Color(clrRecMenuTimerConflictOverlap)); + + pixmapStatus->DrawRectangle(cRect(xConfl-3,2,1,height-4), theme.Color(clrBorder)); + pixmapStatus->DrawRectangle(cRect(xConfl-2,0,2,height), theme.Color(clrBackground)); +} + +eRecMenuState cRecMenuItemTimer::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: + if (iconActive > 0) { + iconActive--; + DrawIcons(); + return rmsConsumed; + } else + return rmsNotConsumed; + break; + case kRight: + if (iconActive < 2) { + iconActive++; + DrawIcons(); + return rmsConsumed; + } else + return rmsNotConsumed; + break; + case kOk: + if (iconActive == 0) + return action; + else if (iconActive == 1) + return action2; + else if (iconActive == 2) + return action3; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemTimerConflictHeader ------------------------------------------------------- + +cRecMenuItemTimerConflictHeader::cRecMenuItemTimerConflictHeader(time_t conflictStart, + time_t conflictStop, + time_t overlapStart, + time_t overlapStop) { + selectable = false; + active = false; + this->conflictStart = conflictStart; + this->conflictStop = conflictStop; + this->overlapStart = overlapStart; + this->overlapStop = overlapStop; + height = 3*font->Height()/2; + pixmapStatus = NULL; +} + +cRecMenuItemTimerConflictHeader::~cRecMenuItemTimerConflictHeader(void) { + if (pixmapStatus) + osdManager.releasePixmap(pixmapStatus); +} + +void cRecMenuItemTimerConflictHeader::SetPixmaps(void) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapStatus = osdManager.requestPixmap(5, cRect(x, y, width, height)); + pixmapStatus->Fill(clrTransparent); +} + +void cRecMenuItemTimerConflictHeader::Hide(void) { + pixmap->SetLayer(-1); + pixmapStatus->SetLayer(-1); +} + +void cRecMenuItemTimerConflictHeader::Show(void) { + pixmap->SetLayer(4); + pixmapStatus->SetLayer(5); +} + +void cRecMenuItemTimerConflictHeader::setBackground(void) { + pixmap->Fill(clrTransparent); +} + +void cRecMenuItemTimerConflictHeader::Draw(void) { + int widthConfl = 30 * width / 100; + int xConfl = width - widthConfl; + cString headerText = tr("Timer Conflict"); + int xHeader = (xConfl - font->Width(*headerText)) / 2; + int yHeader = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(xHeader, yHeader), *headerText, theme.Color(clrFont), clrTransparent, font); + + pixmap->DrawRectangle(cRect(xConfl, 0, widthConfl, height), theme.Color(clrRecMenuTimerConflictBackground)); + + int completeWidthSecs = conflictStop - conflictStart; + int xOverlap = xConfl + (overlapStart - conflictStart) * widthConfl / completeWidthSecs; + int yOverlap = height - fontSmall->Height(); + int widthOverlap = (overlapStop - overlapStart) * widthConfl / completeWidthSecs; + + pixmapStatus->DrawRectangle(cRect(xOverlap, yOverlap, widthOverlap, height), theme.Color(clrRecMenuTimerConflictOverlap)); + + cString strConflStart = TimeString(conflictStart); + cString strConflStop = TimeString(conflictStop); + cString strOverlapStart = TimeString(overlapStart); + cString strOverlapStop = TimeString(overlapStop); + int y1 = 5; + int y2 = yOverlap; + int xConflStart = xConfl + 2; + int xConflStop = width - fontSmall->Width(*strConflStop) - 2; + int xOverlapStart = xOverlap - fontSmall->Width(*strOverlapStart) - 2; + int xOverlapStop = xOverlap + widthOverlap + 2; + pixmap->DrawText(cPoint(xConflStart, y1), *strConflStart, theme.Color(clrRecMenuTimerConflictBar), clrTransparent, fontSmall); + pixmap->DrawText(cPoint(xConflStop, y1), *strConflStop, theme.Color(clrRecMenuTimerConflictBar), clrTransparent, fontSmall); + pixmap->DrawText(cPoint(xOverlapStart, y2), *strOverlapStart, theme.Color(clrRecMenuTimerConflictOverlap), clrTransparent, fontSmall); + pixmap->DrawText(cPoint(xOverlapStop, y2), *strOverlapStop, theme.Color(clrRecMenuTimerConflictOverlap), clrTransparent, fontSmall); +} + +// --- cRecMenuItemEvent ------------------------------------------------------- +cRecMenuItemEvent::cRecMenuItemEvent(const cEvent *event, + eRecMenuState action1, + eRecMenuState action2, + bool active) { + selectable = true; + this->event = event; + this->action = action1; + this->action2 = action2; + iconActive = 0; + this->active = active; + height = font->Height() + 2*fontSmall->Height() + 10; + pixmapText = NULL; + pixmapIcons = NULL; +} + +cRecMenuItemEvent::~cRecMenuItemEvent(void) { + if (pixmapIcons) + osdManager.releasePixmap(pixmapIcons); + if (pixmapText) + osdManager.releasePixmap(pixmapText); +} + +void cRecMenuItemEvent::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapText = osdManager.requestPixmap(5, cRect(x, y, width, height)); + pixmapText->Fill(clrTransparent); + pixmapIcons = osdManager.requestPixmap(6, cRect(x, y, width, height)); + pixmapIcons->Fill(clrTransparent); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapText->SetViewPort(cRect(x, y, width, height)); + pixmapIcons->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemEvent::Draw(void) { + if (!event) + return; + int logoX = DrawIcons(); + const cChannel *channel = Channels.GetByChannelID(event->ChannelID()); + cString channelName(""); + if (channel) { + channelName = channel->Name(); + } + int logoWidth = height * tvguideConfig.logoWidthRatio / tvguideConfig.logoHeightRatio; + cImageLoader imgLoader; + if (!tvguideConfig.hideChannelLogos) { + if (imgLoader.LoadLogo(*channelName, logoWidth, height)) { + cImage logo = imgLoader.GetImage(); + pixmapText->DrawImage(cPoint(logoX, 0), logo); + logoX += logoWidth + 5; + } + } + + int textX = logoX; + int textHeightLine1 = 5; + int textHeightLine2 = 5 + fontSmall->Height(); + int textHeightLine3 = height - fontSmall->Height() - 5; + + cString title = event->Title(); + cString desc = event->ShortText(); + cString start = DayDateTime(event->StartTime()); + cString end = event->GetEndTimeString(); + + colorText = active?theme.Color(clrFontActive):theme.Color(clrFont); + cString info = cString::sprintf("%s - %s, %s", *start, *end, *channelName); + pixmapText->DrawText(cPoint(textX, textHeightLine1), *info, colorText, clrTransparent, fontSmall); + pixmapText->DrawText(cPoint(textX, textHeightLine2), *title, colorText, clrTransparent, font); + pixmapText->DrawText(cPoint(textX, textHeightLine3), *desc, colorText, clrTransparent, fontSmall); +} + +int cRecMenuItemEvent::DrawIcons(void) { + pixmapIcons->Fill(clrTransparent); + int iconsX = 10; + int iconSize = 64; + int iconY = (height - iconSize) / 2; + cString iconInfo, iconRecord; + if (active) { + iconInfo = (iconActive==0)?"info_active":"info_inactive"; + if (action2 != rmsDisabled) + iconRecord = (iconActive==1)?"record_active":"record_inactive"; + } else { + iconInfo = "info_inactive"; + if (action2 != rmsDisabled) + iconRecord = "record_inactive"; + } + cImageLoader imgLoader; + if (imgLoader.LoadIcon(iconInfo, iconSize)) { + cImage icon = imgLoader.GetImage(); + pixmapIcons->DrawImage(cPoint(iconsX, iconY), icon); + iconsX += iconSize + 5; + } + if ((action2 != rmsDisabled) && imgLoader.LoadIcon(iconRecord, iconSize)) { + cImage icon = imgLoader.GetImage(); + pixmapIcons->DrawImage(cPoint(iconsX, iconY), icon); + iconsX += iconSize + 5; + } + return iconsX; +} + +void cRecMenuItemEvent::Hide(void) { + pixmap->SetLayer(-1); + pixmapText->SetLayer(-1); + pixmapIcons->SetLayer(-1); +} + +void cRecMenuItemEvent::Show(void) { + pixmap->SetLayer(4); + pixmapText->SetLayer(5); + pixmapIcons->SetLayer(6); +} + +eRecMenuState cRecMenuItemEvent::ProcessKey(eKeys Key) { + bool consumed = false; + switch (Key & ~k_Repeat) { + case kLeft: + if (action2 == rmsDisabled) + return rmsNotConsumed; + if (iconActive == 1) { + iconActive = 0; + consumed = true; + } + DrawIcons(); + if (consumed) + return rmsConsumed; + else + return rmsNotConsumed; + break; + case kRight: { + if (action2 == rmsDisabled) + return rmsNotConsumed; + if (iconActive == 0) { + iconActive = 1; + consumed = true; + } + DrawIcons(); + if (consumed) + return rmsConsumed; + else + return rmsNotConsumed; + break; } + case kOk: + if (iconActive == 0) + return action; + else if (iconActive == 1) + return action2; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemChannelChooser ------------------------------------------------------- +cRecMenuItemChannelChooser::cRecMenuItemChannelChooser(cString text, + cChannel *initialChannel, + bool active) { + selectable = true; + this->text = text; + this->channel = initialChannel; + if (initialChannel) + initialChannelSet = true; + else + initialChannelSet = false; + channelNumber = 0; + fresh = true; + this->active = active; + height = 2 * font->Height(); + pixmapChannel = NULL; +} + +cRecMenuItemChannelChooser::~cRecMenuItemChannelChooser(void) { + if (pixmapChannel) + osdManager.releasePixmap(pixmapChannel); +} + +void cRecMenuItemChannelChooser::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapChannel = osdManager.requestPixmap(5, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapChannel->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemChannelChooser::Hide(void) { + pixmap->SetLayer(-1); + pixmapChannel->SetLayer(-1); +} + +void cRecMenuItemChannelChooser::Show(void) { + pixmap->SetLayer(4); + pixmapChannel->SetLayer(5); +} + +void cRecMenuItemChannelChooser::Draw(void) { + int textY = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(10, textY), *text, colorText, colorTextBack, font); + DrawValue(); +} + +void cRecMenuItemChannelChooser::DrawValue(void) { + pixmapChannel->Fill(clrTransparent); + int textY = (height - font->Height()) / 2; + if (channel) { + cString textVal = cString::sprintf("%d - %s", channel->Number(), channel->Name()); + int textX = width - font->Width(*textVal) - 10; + pixmapChannel->DrawText(cPoint(textX, textY), *textVal, colorText, clrTransparent, font); + int logoWidth = height * tvguideConfig.logoWidthRatio / tvguideConfig.logoHeightRatio; + int logoX = textX - logoWidth - 10; + cImageLoader imgLoader; + if (imgLoader.LoadLogo(channel->Name(), logoWidth, height)) { + cImage logo = imgLoader.GetImage(); + pixmapChannel->DrawImage(cPoint(logoX, 0), logo); + } + } else { + cString textVal = tr("all Channels"); + int textX = width - font->Width(*textVal) - 10; + pixmapChannel->DrawText(cPoint(textX, textY), *textVal, colorText, clrTransparent, font); + } +} + +int cRecMenuItemChannelChooser::GetIntValue(void) { + if (channel) + return channel->Number(); + return 0; +} + + +eRecMenuState cRecMenuItemChannelChooser::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: { + fresh = true; + if (!channel) + return rmsConsumed; + cChannel *prev = channel; + cChannel *firstChannel = Channels.First(); + if(firstChannel->GroupSep()) + firstChannel = Channels.Next(firstChannel); + if (prev == firstChannel) { + if (!initialChannelSet) + channel = NULL; + } else { + while (prev = Channels.Prev(prev)) { + if(!prev->GroupSep()) { + channel = prev; + break; + } + } + } + DrawValue(); + return rmsConsumed; + break; } + case kRight: { + fresh = true; + if (!channel) { + channel = Channels.First(); + if(channel->GroupSep()) + channel = Channels.Next(channel); + } else { + cChannel *next = channel; + while (next = Channels.Next(next)) { + if(!next->GroupSep()) { + channel = next; + break; + } + } + } + DrawValue(); + return rmsConsumed; + break; } + case k0 ... k9: { + if (fresh) { + channelNumber = 0; + fresh = false; + } + channelNumber = channelNumber * 10 + (Key - k0); + cChannel *chanNew = Channels.GetByNumber(channelNumber); + if (chanNew) { + channel = chanNew; + DrawValue(); + } + return rmsConsumed; + break; } + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemDayChooser ------------------------------------------------------- +cRecMenuItemDayChooser::cRecMenuItemDayChooser(cString text, + int weekdays, + bool active) { + selectable = true; + this->text = text; + this->weekdays = weekdays; + this->active = active; + height = 2 * font->Height(); + selectedDay = 0; + pixmapWeekdays = NULL; + pixmapWeekdaysSelect = NULL; +} + +cRecMenuItemDayChooser::~cRecMenuItemDayChooser(void) { + if (pixmapWeekdays) + osdManager.releasePixmap(pixmapWeekdays); + if (pixmapWeekdaysSelect) + osdManager.releasePixmap(pixmapWeekdaysSelect); +} + +void cRecMenuItemDayChooser::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapWeekdays = osdManager.requestPixmap(5, cRect(x, y, width, height)); + pixmapWeekdaysSelect = osdManager.requestPixmap(6, cRect(x, y, width, height)); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapWeekdays->SetViewPort(cRect(x, y, width, height)); + pixmapWeekdaysSelect->SetViewPort(cRect(x, y, width, height)); + } + SetSizes(); +} + +void cRecMenuItemDayChooser::Hide(void) { + pixmap->SetLayer(-1); + pixmapWeekdays->SetLayer(-1); + pixmapWeekdaysSelect->SetLayer(-1); +} + +void cRecMenuItemDayChooser::Show(void) { + pixmap->SetLayer(4); + pixmapWeekdays->SetLayer(5); + pixmapWeekdaysSelect->SetLayer(6); +} + +void cRecMenuItemDayChooser::SetSizes(void) { + days = trVDR("MTWTFSS"); + int maxWidth = 0; + for (unsigned i=0; iWidth(days.at(i)); + if (charWidth > maxWidth) + maxWidth = charWidth; + } + daysSize = min(maxWidth + 15, height-4); + daysX = width - 10 - 7*daysSize; + daysY = (height - daysSize) / 2; +} + +void cRecMenuItemDayChooser::setBackground() { + cRecMenuItem::setBackground(); + if (active) { + DrawHighlight(selectedDay); + } else { + DrawHighlight(-1); + } +} + +void cRecMenuItemDayChooser::Draw(void) { + int textY = (height - font->Height()) / 2; + pixmap->DrawText(cPoint(10, textY), *text, colorText, colorTextBack, font); + DrawDays(); +} + +void cRecMenuItemDayChooser::DrawDays(void) { + pixmapWeekdays->Fill(clrTransparent); + int textY = (height - font->Height()) / 2; + pixmapWeekdays->DrawRectangle(cRect(daysX, daysY, 7*daysSize, daysSize), theme.Color(clrBorder)); + int currentX = daysX; + for (unsigned day=0; dayDrawRectangle(cRect(currentX+2, daysY+2, daysSize-4, daysSize-4), theme.Color(clrBackground)); + tColor colorDay = WeekDaySet(day)?theme.Color(clrRecMenuDayActive) + :theme.Color(clrRecMenuDayInactive); + int textX = currentX + (daysSize - font->Width(*strDay)) / 2; + pixmapWeekdays->DrawText(cPoint(textX, textY), *strDay, colorDay, clrTransparent, font); + currentX += daysSize; + } +} + +void cRecMenuItemDayChooser::DrawHighlight(int day) { + pixmapWeekdaysSelect->Fill(clrTransparent); + if (day > -1) { + int currentX = daysX + day*daysSize; + pixmapWeekdaysSelect->DrawRectangle(cRect(currentX, daysY, daysSize, daysSize), theme.Color(clrRecMenuDayHighlight)); + } +} + +bool cRecMenuItemDayChooser::WeekDaySet(unsigned day) { + return weekdays & (1 << day); +} + +void cRecMenuItemDayChooser::ToggleDay(void) { + bool dayActive = WeekDaySet(selectedDay); + int dayBit = pow(2, selectedDay); + if (dayActive) { + weekdays -= dayBit; + } else { + weekdays += dayBit; + } +} + +eRecMenuState cRecMenuItemDayChooser::ProcessKey(eKeys Key) { + switch (Key & ~k_Repeat) { + case kLeft: { + selectedDay--; + if (selectedDay<0) + selectedDay += 7; + DrawHighlight(selectedDay); + return rmsConsumed; + break; } + case kRight: { + selectedDay = (selectedDay+1)%7; + DrawHighlight(selectedDay); + return rmsConsumed; + break; } + case kOk: + ToggleDay(); + DrawDays(); + return rmsConsumed; + break; + default: + break; + } + return rmsNotConsumed; +} + +// --- cRecMenuItemRecording ------------------------------------------------------- +cRecMenuItemRecording::cRecMenuItemRecording(cRecording *recording, bool active) { + selectable = true; + this->recording = recording; + this->active = active; + height = font->Height() + 2*fontSmall->Height() + 10; + pixmapText = NULL; +} + +cRecMenuItemRecording::~cRecMenuItemRecording(void) { + if (pixmapText) + osdManager.releasePixmap(pixmapText); +} + +void cRecMenuItemRecording::SetPixmaps(void) { + if (!pixmap) { + pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height)); + pixmapText = osdManager.requestPixmap(5, cRect(x, y, width, height)); + pixmapText->Fill(clrTransparent); + } else { + pixmap->SetViewPort(cRect(x, y, width, height)); + pixmapText->SetViewPort(cRect(x, y, width, height)); + } +} + +void cRecMenuItemRecording::Draw(void) { + if (!recording) + return; + const cRecordingInfo *recInfo = recording->Info(); + cChannel *channel = Channels.GetByChannelID(recInfo->ChannelID()); + cString channelName = tr("unknown channel"); + if (channel) + channelName = channel->Name(); + cString name = recording->Name(); + cString dateTime = cString::sprintf("%s, %s", *DateString(recording->Start()), *TimeString(recording->Start())); + + int recDuration = recording->LengthInSeconds() / 60; + + cString recDetails = cString::sprintf("%s: %d %s, %s %s %s \"%s\"", tr("Duration"), recDuration, tr("min"), tr("recorded at"), *dateTime, tr("from"), *channelName); + recDetails = CutText(*recDetails, width - 40, fontSmall).c_str(); + int text1Y = (height/2 - font->Height()) / 2 + 5; + int text2Y = height/2 + (height/2 - fontSmall->Height())/2 - 5; + colorText = active?theme.Color(clrFontActive):theme.Color(clrFont); + pixmapText->DrawText(cPoint(10, text1Y), *name, colorText, clrTransparent, font); + pixmapText->DrawText(cPoint(10, text2Y), *recDetails, colorText, clrTransparent, fontSmall); +} + +void cRecMenuItemRecording::Hide(void) { + pixmap->SetLayer(-1); + pixmapText->SetLayer(-1); +} + +void cRecMenuItemRecording::Show(void) { + pixmap->SetLayer(4); + pixmapText->SetLayer(5); +} diff --git a/recmenuitem.h b/recmenuitem.h new file mode 100644 index 0000000..780eac9 --- /dev/null +++ b/recmenuitem.h @@ -0,0 +1,465 @@ +#ifndef __TVGUIDE_RECMENUITEM_H +#define __TVGUIDE_RECMENUITEM_H + +#define AUTO_ADVANCE_TIMEOUT 1500 + +enum eRecMenuState { + rmsConsumed, + rmsNotConsumed, + rmsRefresh, + rmsContinue, + rmsClose, + rmsInstantRecord, + rmsIgnoreTimerConflict, + rmsDeleteTimerConflictMenu, + rmsEditTimerConflictMenu, + rmsSaveTimerConflictMenu, + rmsTimerConflictShowInfo, + rmsDeleteTimer, + rmsDeleteTimerConfirmation, + rmsEditTimer, + rmsSaveTimer, + rmsSearch, + rmsSearchWithOptions, + rmsSearchPerform, + rmsSearchShowInfo, + rmsSearchRecord, + rmsSearchRecordConfirm, + rmsSearchNothingFoundConfirm, + rmsSeriesTimer, + rmsSeriesTimerCreate, + rmsSearchTimer, + rmsSearchTimerOptions, + rmsSearchTimerOptionsReload, + rmsSearchTimerUseTemplate, + rmsSearchTimerOptionsManually, + rmsSearchTimerTestManually, + rmsSearchTimerTestTemplate, + rmsSearchTimerNothingFoundConfirm, + rmsSearchTimerCreateManually, + rmsSearchTimerCreateTemplate, + rmsSwitchTimer, + rmsSwitchTimerCreate, + rmsSwitchTimerDelete, + rmsRecordingSearch, + rmsRecordingSearchResult, + rmsTimerConflict, + rmsTimerConflicts, + rmsDisabled, +}; + +enum eDependend { + eGreater, + eLower, +}; +// --- cRecMenuItem ------------------------------------------------------------- +class cRecMenuItem : public cListObject, public cStyledPixmap { +protected: + int x, y; + int width, height; + bool selectable; + bool active; + bool drawn; + eRecMenuState action; + tColor colorText; + tColor colorTextBack; + const cFont *font; + const cFont *fontSmall; +public: + cRecMenuItem(void); + virtual ~cRecMenuItem(void); + void SetGeometry(int x, int y, int width); + virtual void SetPixmaps(void); + virtual int GetHeight(void) { return height; }; + virtual int GetWidth(void) { return 0; }; + virtual void CalculateHeight(int textWidth) {}; + void setActive(void) { this->active = true; } + void setInactive(void) { this->active = false; } + bool isSelectable(void) { return selectable; } + bool isActive(void) { return active; } + virtual void setBackground(void); + virtual void Draw(void) {}; + virtual void Hide(void) { pixmap->SetLayer(-1);}; + virtual void Show(void) { pixmap->SetLayer(4);}; + virtual int GetIntValue(void) { return -1; }; + virtual time_t GetTimeValue(void) { return 0; }; + virtual bool GetBoolValue(void) { return false; }; + virtual cString GetStringValue(void) { return cString(""); }; + virtual const cEvent *GetEventValue(void) { return NULL; }; + virtual eRecMenuState ProcessKey(eKeys Key) { return rmsNotConsumed; }; + +}; + +// --- cRecMenuItemButton ------------------------------------------------------- +class cRecMenuItemButton : public cRecMenuItem { +private: + cString text; + bool halfWidth; +public: + cRecMenuItemButton(const char *text, eRecMenuState action, bool active, bool halfWidth = false); + virtual ~cRecMenuItemButton(void); + int GetWidth(void); + void SetPixmaps(void); + void Draw(void); + eRecMenuState ProcessKey(eKeys Key); +}; + +// --- cRecMenuItemButtonYesNo ------------------------------------------------------- +class cRecMenuItemButtonYesNo : public cRecMenuItem { +private: + cString textYes; + cString textNo; + eRecMenuState actionNo; + bool yesActive; + cStyledPixmap *pixmapNo; + tColor colorTextNo; +public: + cRecMenuItemButtonYesNo(cString textYes, + cString textNo, + eRecMenuState actionYes, + eRecMenuState actionNo, + bool active); + virtual ~cRecMenuItemButtonYesNo(void); + void SetPixmaps(void); + void setBackground(void); + void Hide(void); + void Show(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); +}; + +// --- cRecMenuItemInfo ------------------------------------------------------- +class cRecMenuItemInfo : public cRecMenuItem { +private: + cString text; + cTextWrapper wrapper; + int border; +public: + cRecMenuItemInfo(const char *text); + virtual ~cRecMenuItemInfo(void); + void setBackground(void); + void CalculateHeight(int textWidth); + void Draw(void); +}; + +// --- cRecMenuItemInt ------------------------------------------------------- +class cRecMenuItemInt : public cRecMenuItem { +private: + cString text; + int currentVal; + int minVal; + int maxVal; + cPixmap *pixmapVal; + bool fresh; + void DrawValue(void); +public: + cRecMenuItemInt(cString text, + int initialVal, + int minVal, + int maxVal, + bool active); + virtual ~cRecMenuItemInt(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + void setBackground(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); + int GetIntValue(void) { return currentVal; }; +}; + +// --- cRecMenuItemBool ------------------------------------------------------- +class cRecMenuItemBool : public cRecMenuItem { +private: + cString text; + bool yes; + cPixmap *pixmapVal; + bool refresh; + void DrawValue(void); +public: + cRecMenuItemBool(cString text, + bool initialVal, + bool refresh, + bool active); + virtual ~cRecMenuItemBool(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); + bool GetBoolValue(void) { return yes; }; +}; + +// --- cRecMenuItemSelect ------------------------------------------------------- +class cRecMenuItemSelect : public cRecMenuItem { +private: + cString text; + int currentVal; + const char * const *strings; + int numValues; + cPixmap *pixmapVal; + void DrawValue(void); +public: + cRecMenuItemSelect(cString text, + const char * const *Strings, + int initialVal, + int numValues, + bool active); + virtual ~cRecMenuItemSelect(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); + int GetIntValue(void) { return currentVal; }; + cString GetStringValue(void) { return strings[currentVal]; }; +}; + +// --- cRecMenuItemText ------------------------------------------------------- +class cRecMenuItemText : public cRecMenuItem { +private: + cString title; + char *value; + int length; + const char *allowed; + int pos, offset; + bool insert, newchar, uppercase; + int lengthUtf8; + uint *valueUtf8; + uint *allowedUtf8; + uint *charMapUtf8; + uint *currentCharUtf8; + eKeys lastKey; + cTimeMs autoAdvanceTimeout; + cPixmap *pixmapVal; + cStyledPixmap *pixmapKeyboard; + cPixmap *pixmapKeyboardHighlight; + cPixmap *pixmapKeyboardIcons; + int keyboardWidth; + int gridWidth; + int gridHeight; + int keyboardHeight; + bool keyboardDrawn; + uint *IsAllowed(uint c); + void AdvancePos(void); + uint Inc(uint c, bool Up); + void Type(uint c); + void Insert(void); + void Delete(void); + void EnterEditMode(void); + void LeaveEditMode(bool SaveValue = false); + bool InEditMode(void) { return valueUtf8 != NULL; }; + void SetText(void); + void ActivateKeyboard(void); + void DeactivateKeyboard(void); + void HighlightSMSKey(int num); + void ClearSMSKey(void); + char *GetSMSKeys(int num); + void DrawValue(char *newValue); +public: + cRecMenuItemText(cString title, + char *initialVal, + int length, + bool active); + virtual ~cRecMenuItemText(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + void setBackground(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); + cString GetStringValue(void) { return value; }; +}; + + +// --- cRecMenuItemTime ------------------------------------------------------- +class cRecMenuItemTime : public cRecMenuItem { +private: + cString text; + int value; + int mm; + int hh; + int pos; + bool fresh; + cPixmap *pixmapVal; + void DrawValue(void); +public: + cRecMenuItemTime(cString text, + int initialVal, + bool active); + virtual ~cRecMenuItemTime(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); + int GetIntValue(void) { return value; }; +}; + +// --- cRecMenuItemDay ------------------------------------------------------- +class cRecMenuItemDay : public cRecMenuItem { +private: + cString text; + time_t currentVal; + cPixmap *pixmapVal; + void DrawValue(void); +public: + cRecMenuItemDay(cString text, + time_t initialVal, + bool active); + virtual ~cRecMenuItemDay(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); + time_t GetTimeValue(void) { return currentVal; }; +}; + +// --- cRecMenuItemTimer ------------------------------------------------------- +class cRecMenuItemTimer : public cRecMenuItem { +private: + const cTimer *timer; + eRecMenuState action2; + eRecMenuState action3; + int iconActive; + cPixmap *pixmapIcons; + cPixmap *pixmapStatus; + time_t conflictStart; + time_t conflictStop; + time_t overlapStart; + time_t overlapStop; + int DrawIcons(void); + void DrawTimerConflict(void); +public: + cRecMenuItemTimer(const cTimer *timer, + eRecMenuState action1, + eRecMenuState action2, + eRecMenuState action3, + time_t conflictStart, + time_t conflictStop, + time_t overlapStart, + time_t overlapStop, + bool active); + virtual ~cRecMenuItemTimer(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); +}; + +// --- cRecMenuItemTimerConflictHeader ------------------------------------------------------- + +class cRecMenuItemTimerConflictHeader: public cRecMenuItem { +private: + cPixmap *pixmapStatus; + time_t conflictStart; + time_t conflictStop; + time_t overlapStart; + time_t overlapStop; +public: + cRecMenuItemTimerConflictHeader(time_t conflictStart, + time_t conflictStop, + time_t overlapStart, + time_t overlapStop); + virtual ~cRecMenuItemTimerConflictHeader(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + void setBackground(void); + void Draw(void); +}; + +// --- cRecMenuItemEvent ------------------------------------------------------- +class cRecMenuItemEvent : public cRecMenuItem { +private: + const cEvent *event; + eRecMenuState action2; + int iconActive; + cPixmap *pixmapText; + cPixmap *pixmapIcons; + int DrawIcons(void); +public: + cRecMenuItemEvent(const cEvent *event, + eRecMenuState action1, + eRecMenuState action2, + bool active); + virtual ~cRecMenuItemEvent(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + const cEvent *GetEventValue(void) { return event; }; + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); +}; + +// --- cRecMenuItemChannelChooser ------------------------------------------------------- +class cRecMenuItemChannelChooser : public cRecMenuItem { +private: + cString text; + cChannel *channel; + int channelNumber; + bool initialChannelSet; + bool fresh; + cPixmap *pixmapChannel; + void DrawValue(void); +public: + cRecMenuItemChannelChooser (cString text, + cChannel *initialChannel, + bool active); + virtual ~cRecMenuItemChannelChooser(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); + int GetIntValue(void); +}; + +// --- cRecMenuItemDayChooser ------------------------------------------------------- +class cRecMenuItemDayChooser : public cRecMenuItem { +private: + cString text; + int weekdays; + std::string days; + int daysX; + int daysY; + int daysSize; + int selectedDay; + cPixmap *pixmapWeekdays; + cPixmap *pixmapWeekdaysSelect; + void SetSizes(void); + void DrawDays(void); + void DrawHighlight(int day); + void ToggleDay(void); + bool WeekDaySet(unsigned day); +public: + cRecMenuItemDayChooser (cString text, + int weekdays, + bool active); + virtual ~cRecMenuItemDayChooser(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + void setBackground(void); + eRecMenuState ProcessKey(eKeys Key); + void Draw(void); + int GetIntValue(void) { return weekdays;} ; +}; + +// --- cRecMenuItemRecording ------------------------------------------------------- +class cRecMenuItemRecording : public cRecMenuItem { +private: + cRecording *recording; + cPixmap *pixmapText; +public: + cRecMenuItemRecording(cRecording *recording, bool active); + virtual ~cRecMenuItemRecording(void); + void SetPixmaps(void); + void Hide(void); + void Show(void); + void Draw(void); +}; + +#endif //__TVGUIDE_RECMENUITEM_H \ No newline at end of file diff --git a/recmenumanager.c b/recmenumanager.c new file mode 100644 index 0000000..cd34c12 --- /dev/null +++ b/recmenumanager.c @@ -0,0 +1,521 @@ +#include "recmenumanager.h" + +cRecMenuManager::cRecMenuManager(void) { + active = false; + activeMenu = NULL; + activeMenuBuffer = NULL; + recManager = new cRecManager(); + recManager->SetEPGSearchPlugin(); + instantRecord = false; + currentConflict = -1; + templateID = -1; + timer = NULL; + searchWithOptions = false; + detailViewActive = false; +} + +cRecMenuManager::~cRecMenuManager(void) { + if (activeMenu) { + active = false; + delete activeMenu; + activeMenu = NULL; + } + delete recManager; +} + +void cRecMenuManager::Start(const cEvent *event) { + active = true; + activeMenuBuffer = NULL; + instantRecord = false; + currentConflict = -1; + templateID = -1; + timer = NULL; + searchWithOptions = false; + detailViewActive = false; + SetBackground(); + this->event = event; + activeMenu = new cRecMenuMain(recManager->EpgSearchAvailable(), event->HasTimer(), SwitchTimers.EventInSwitchList(event)); + activeMenu->Display(); + osdManager.flush(); +} + +void cRecMenuManager::Close(void) { + event = NULL; + active = false; + if (activeMenu) { + delete activeMenu; + activeMenu = NULL; + } + DeleteBackground(); +} + +void cRecMenuManager::SetBackground(void) { + int backgroundWidth = tvguideConfig.osdWidth; + int backgroundHeight = tvguideConfig.osdHeight; + pixmapBackground = osdManager.requestPixmap(3, cRect(0, 0, backgroundWidth, backgroundHeight)); + pixmapBackground->Fill(theme.Color(clrRecMenuBackground)); + if (tvguideConfig.scaleVideo) { + int tvHeight = tvguideConfig.statusHeaderHeight; + int tvWidth = tvHeight * 16 / 9; + int tvX = tvguideConfig.osdWidth - tvWidth; + pixmapBackground->DrawRectangle(cRect(tvX, 0, tvWidth, tvHeight), clrTransparent); + } +} + +void cRecMenuManager::DeleteBackground(void) { + osdManager.releasePixmap(pixmapBackground); +} + +eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) { + eOSState state = osContinue; + switch (nextState) { + /* + * --------- INSTANT RECORDING --------------------------- + */ + case rmsInstantRecord: { + //Creating timer for active Event + //if no conflict, confirm and exit + instantRecord = true; + delete activeMenu; + cTimer *timer = recManager->createTimer(event); + if (!displayTimerConflict(timer)) { + activeMenu = new cRecMenuConfirmTimer(event); + activeMenu->Display(); + } + break; } + case rmsIgnoreTimerConflict: + //Confirming created Timer + if (instantRecord) { + delete activeMenu; + activeMenu = new cRecMenuConfirmTimer(event); + activeMenu->Display(); + } else { + state = osEnd; + Close(); + } + break; + case rmsTimerConflictShowInfo: { + int timerIndex = activeMenu->GetActive(true); + int timerID = conflictList[currentConflict].timerIDs[timerIndex]; + cTimer *t = Timers.Get(timerID); + if (t) { + const cEvent *ev = t->Event(); + if (ev) { + activeMenu->Hide(); + detailView = new cDetailView(ev); + detailView->drawHeader(); + detailView->drawContent(); + detailView->drawScrollbar(); + detailViewActive = true; + } + } + break;} + case rmsDeleteTimerConflictMenu: { + //delete timer out of current timer conflict + //active menu: cRecMenuTimerConflict + int timerIndex = activeMenu->GetActive(true); + int timerID = conflictList[currentConflict].timerIDs[timerIndex]; + recManager->DeleteTimer(timerID); + delete activeMenu; + if (!displayTimerConflict(timerID)) { + activeMenu = new cRecMenuConfirmTimer(event); + activeMenu->Display(); + } + break; } + case rmsEditTimerConflictMenu: { + //edit timer out of current timer conflict + //active menu: cRecMenuTimerConflict + int activeItem = activeMenu->GetActive(true); + int timerID = conflictList[currentConflict].timerIDs[activeItem]; + timer = Timers.Get(timerID); + if (timer) { + delete activeMenu; + activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimerConflictMenu); + activeMenu->Display(); + } + break; } + case rmsSaveTimerConflictMenu: { + //save timer from current timer conflict + recManager->SaveTimer(timer, activeMenu); + delete activeMenu; + if (!displayTimerConflict(timer)) { + activeMenu = new cRecMenuConfirmTimer(event); + activeMenu->Display(); + } + break; } + case rmsDeleteTimer: + //delete timer for active event + delete activeMenu; + if (recManager->IsRecorded(event)) { + activeMenu = new cRecMenuAskDeleteTimer(event); + } else { + recManager->DeleteTimer(event); + activeMenu = new cRecMenuConfirmDeleteTimer(event); + } + activeMenu->Display(); + break; + case rmsDeleteTimerConfirmation: + //delete running timer for active event + recManager->DeleteTimer(event); + delete activeMenu; + activeMenu = new cRecMenuConfirmDeleteTimer(event); + activeMenu->Display(); + break; + case rmsEditTimer: { + //edit timer for active event + timer = Timers.GetMatch(event); + if (timer) { + delete activeMenu; + activeMenu = new cRecMenuEditTimer(timer, rmsSaveTimer); + activeMenu->Display(); + } + break; } + case rmsSaveTimer: { + //save timer for active event + recManager->SaveTimer(timer, activeMenu); + state = osEnd; + Close(); + break; } + /* + * --------- SERIES TIMER --------------------------------- + */ + case rmsSeriesTimer: { + delete activeMenu; + cChannel *channel = Channels.GetByChannelID(event->ChannelID()); + activeMenu = new cRecMenuSeriesTimer(channel, event); + activeMenu->Display(); + break; } + case rmsSeriesTimerCreate: { + cTimer *seriesTimer = recManager->CreateSeriesTimer(activeMenu); + delete activeMenu; + activeMenu = new cRecMenuConfirmSeriesTimer(seriesTimer); + activeMenu->Display(); + break; } + /* + * --------- SEARCH TIMER --------------------------------- + */ + case rmsSearchTimer: + delete activeMenu; + activeMenu = new cRecMenuSearchTimer(event); + activeMenu->Display(); + break; + case rmsSearchTimerOptions: { + searchString = *activeMenu->GetStringValue(1); + delete activeMenu; + if (isempty(*searchString)) { + activeMenu = new cRecMenuSearchTimer(event); + } else { + epgSearchTemplates = recManager->ReadEPGSearchTemplates(); + int numTemplates = epgSearchTemplates.size(); + if (numTemplates > 0) { + activeMenu = new cRecMenuSearchTimerTemplates(searchString, epgSearchTemplates); + } else { + activeMenu = new cRecMenuSearchTimerOptions(searchString); + } + } + activeMenu->Display(); + break; } + case rmsSearchTimerOptionsReload: { + int numTemplates = epgSearchTemplates.size(); + delete activeMenu; + activeMenu = new cRecMenuSearchTimerTemplates(searchString, epgSearchTemplates); + activeMenu->Display(); + break; } + case rmsSearchTimerUseTemplate: { + templateID = activeMenu->GetActive(true) - 1; + delete activeMenu; + activeMenu = new cRecMenuSearchTimerTemplatesCreate(searchString, epgSearchTemplates[templateID].name.c_str()); + activeMenu->Display(); + break; } + case rmsSearchTimerOptionsManually: + delete activeMenu; + activeMenu = new cRecMenuSearchTimerOptions(searchString); + activeMenu->Display(); + break; + case rmsSearchTimerTestTemplate: { + std::string epgSearchString = recManager->BuildEPGSearchString(searchString, epgSearchTemplates[templateID].templValue); + int numSearchResults = 0; + const cEvent **searchResult = recManager->PerformSearchTimerSearch(epgSearchString, numSearchResults); + if (searchResult) { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerResults(searchString, searchResult, numSearchResults, epgSearchTemplates[templateID].name); + activeMenu->Display(); + } else { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerNothingFound(searchString, epgSearchTemplates[templateID].name); + activeMenu->Display(); + } + break; } + case rmsSearchTimerTestManually: { + std::string epgSearchString = recManager->BuildEPGSearchString(searchString, activeMenu); + int numSearchResults = 0; + const cEvent **searchResult = recManager->PerformSearchTimerSearch(epgSearchString, numSearchResults); + if (searchResult) { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerResults(searchString, searchResult, numSearchResults, ""); + activeMenu->Display(); + } else { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchTimerNothingFound(searchString, ""); + activeMenu->Display(); + } + break; } + case rmsSearchTimerNothingFoundConfirm: + delete activeMenu; + activeMenu = activeMenuBuffer; + activeMenuBuffer = NULL; + activeMenu->Show(); + break; + case rmsSearchTimerCreateManually: + case rmsSearchTimerCreateTemplate: { + std::string epgSearchString; + if (nextState == rmsSearchTimerCreateManually) { + epgSearchString = recManager->BuildEPGSearchString(searchString, activeMenu); + } else if (nextState = rmsSearchTimerCreateTemplate) { + epgSearchString = recManager->BuildEPGSearchString(searchString, epgSearchTemplates[templateID].templValue); + } + bool success = createSearchTimer(epgSearchString); + delete activeMenu; + activeMenu = new cRecMenuSearchTimerCreateConfirm(success); + activeMenu->Display(); + break; } + /* + * --------- SWITCH TIMER --------------------------------- + */ + case rmsSwitchTimer: + delete activeMenu; + activeMenu = new cRecMenuSwitchTimer(); + activeMenu->Display(); + break; + case rmsSwitchTimerCreate: { + bool success = recManager->CreateSwitchTimer(event, activeMenu); + delete activeMenu; + activeMenu = new cRecMenuSwitchTimerConfirm(success); + activeMenu->Display(); + break; } + case rmsSwitchTimerDelete: + recManager->DeleteSwitchTimer(event); + delete activeMenu; + activeMenu = new cRecMenuSwitchTimerDelete(); + activeMenu->Display(); + break; + /* + * --------- RECORDINGS SEARCH --------------------------------- + */ + case rmsRecordingSearch: + delete activeMenu; + activeMenu = new cRecMenuRecordingSearch(event); + activeMenu->Display(); + break; + case rmsRecordingSearchResult: { + searchString = activeMenu->GetStringValue(1); + delete activeMenu; + if (isempty(*searchString)) { + activeMenu = new cRecMenuRecordingSearch(event); + } else { + int numSearchResults = 0; + cRecording **searchResult = recManager->SearchForRecordings(searchString, numSearchResults); + if (numSearchResults == 0) { + activeMenu = new cRecMenuRecordingSearchNotFound(searchString); + } else { + activeMenu = new cRecMenuRecordingSearchResults(searchString, searchResult, numSearchResults); + } + } + activeMenu->Display(); + break; } + /* + * --------- SEARCH --------------------------------- + */ + case rmsSearch: + delete activeMenu; + activeMenu = new cRecMenuSearch(event); + activeMenu->Display(); + searchWithOptions = false; + break; + case rmsSearchWithOptions: { + cString searchString = activeMenu->GetStringValue(1); + delete activeMenu; + if (isempty(*searchString)) { + activeMenu = new cRecMenuSearch(event); + } else { + activeMenu = new cRecMenuSearch(event, *searchString); + searchWithOptions = true; + } + activeMenu->Display(); + break; } + case rmsSearchPerform: { + cString searchString = activeMenu->GetStringValue(1); + if (isempty(*searchString)) { + delete activeMenu; + activeMenu = new cRecMenuSearch(event); + } else { + int numSearchResults = 0; + const cEvent **searchResult = recManager->PerformSearch(activeMenu, searchWithOptions, numSearchResults); + if (searchResult) { + delete activeMenu; + activeMenu = new cRecMenuSearchResults(searchString, searchResult, numSearchResults); + } else { + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchNothingFound(searchString); + } + } + activeMenu->Display(); + break; } + case rmsSearchNothingFoundConfirm: + delete activeMenu; + activeMenu = activeMenuBuffer; + activeMenuBuffer = NULL; + activeMenu->Show(); + break; + case rmsSearchShowInfo: { + const cEvent *ev = activeMenu->GetEventValue(activeMenu->GetActive(false)); + if (ev) { + activeMenu->Hide(); + detailView = new cDetailView(ev); + detailView->drawHeader(); + detailView->drawContent(); + detailView->drawScrollbar(); + detailViewActive = true; + } + break;} + case rmsSearchRecord: { + const cEvent *ev = activeMenu->GetEventValue(activeMenu->GetActive(false)); + cTimer *timer = recManager->createTimer(ev); + activeMenuBuffer = activeMenu; + activeMenuBuffer->Hide(); + activeMenu = new cRecMenuSearchConfirmTimer(ev); + activeMenu->Display(); + break;} + case rmsSearchRecordConfirm: + delete activeMenu; + activeMenu = activeMenuBuffer; + activeMenuBuffer = NULL; + activeMenu->Show(); + break; + /* + * --------- CHECK FOR TIMER CONFLICTS --------------------------------- + */ + case rmsTimerConflicts: { + //Show timer conflict + //active menu: cRecMenuTimerConflicts + conflictList = recManager->CheckTimerConflict(); + delete activeMenu; + int numConflicts = conflictList.size(); + if (numConflicts > 0) { + activeMenu = new cRecMenuTimerConflicts(conflictList); + } else { + activeMenu = new cRecMenuNoTimerConflict(); + } + activeMenu->Display(); + break; } + case rmsTimerConflict: + //Show timer conflict + //active menu: cRecMenuTimerConflicts + currentConflict = activeMenu->GetActive(true); + delete activeMenu; + activeMenu = new cRecMenuTimerConflict(conflictList[currentConflict]); + activeMenu->Display(); + break; + + /* + * --------- COMMON --------------------------------- + */ + case rmsClose: { + if (activeMenuBuffer == NULL) { + state = osEnd; + Close(); + } else { + delete activeMenu; + activeMenu = activeMenuBuffer; + activeMenuBuffer = NULL; + activeMenu->Show(); + state = osContinue; + } + break; } + default: + break; + } + return state; +} + +bool cRecMenuManager::displayTimerConflict(cTimer *timer) { + int timerID = 0; + for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) { + if (t == timer) + return displayTimerConflict(timerID); + timerID++; + } + return false; +} + +bool cRecMenuManager::displayTimerConflict(int timerID) { + conflictList = recManager->CheckTimerConflict(); + int numConflicts = conflictList.size(); + int showTimerConflict = -1; + if (numConflicts > 0) { + for (int i=0; i -1) { + currentConflict = showTimerConflict; + activeMenu = new cRecMenuTimerConflict(conflictList[currentConflict]); + activeMenu->Display(); + return true; + } + return false; +} + +bool cRecMenuManager::createSearchTimer(std::string epgSearchString) { + int newTimerID = recManager->CreateSearchTimer(epgSearchString); + bool success = false; + if (newTimerID > -1) { + recManager->UpdateSearchTimers(); + success = true; + } + return success; +} + +eOSState cRecMenuManager::ProcessKey(eKeys Key) { + eOSState state = osContinue; + eRecMenuState nextState = rmsContinue; + if (!activeMenu) + return state; + if (detailViewActive) { + state = detailView->ProcessKey(Key); + if (state == osEnd) { + delete detailView; + detailView = NULL; + detailViewActive = false; + activeMenu->Show(); + state = osContinue; + } + } else { + nextState = activeMenu->ProcessKey(Key); + if ((nextState == rmsClose) || ((nextState == rmsNotConsumed)&&(Key == kBack))){ + if (activeMenuBuffer == NULL) { + state = osEnd; + Close(); + } else { + delete activeMenu; + activeMenu = activeMenuBuffer; + activeMenuBuffer = NULL; + activeMenu->Show(); + state = osContinue; + osdManager.flush(); + } + return state; + } + state = StateMachine(nextState); + } + osdManager.flush(); + return state; +} \ No newline at end of file diff --git a/recmenumanager.h b/recmenumanager.h new file mode 100644 index 0000000..cc9ac2c --- /dev/null +++ b/recmenumanager.h @@ -0,0 +1,38 @@ +#ifndef __TVGUIDE_RECMENUMANAGER_H +#define __TVGUIDE_RECMENUMANAGER_H + +// --- cRecMenuManager ------------------------------------------------------------- +class cRecMenuManager { +private: + bool active; + cRecMenu *activeMenu; + cRecMenu *activeMenuBuffer; + const cEvent *event; + cRecManager *recManager; + std::vector conflictList; + std::vector epgSearchTemplates; + bool instantRecord; + int currentConflict; + int templateID; + bool searchWithOptions; + cTimer *timer; + cString searchString; + cDetailView *detailView; + cPixmap *pixmapBackground; + bool detailViewActive; + void SetBackground(void); + void DeleteBackground(void); + bool displayTimerConflict(cTimer *timer); + bool displayTimerConflict(int timerID); + bool createSearchTimer(std::string epgSearchString); +public: + cRecMenuManager(void); + virtual ~cRecMenuManager(void); + bool isActive(void) { return active; }; + void Start(const cEvent *event); + void Close(void); + eOSState StateMachine(eRecMenuState nextState); + eOSState ProcessKey(eKeys Key); +}; + +#endif //__TVGUIDE_RECMENUMANAGER_H \ No newline at end of file diff --git a/services/epgsearch.h b/services/epgsearch.h index de29299..2669da4 100644 --- a/services/epgsearch.h +++ b/services/epgsearch.h @@ -1,5 +1,5 @@ -/* -Copyright (C) 2004-2007 Christian Wieninger +/* -*- c++ -*- +Copyright (C) 2004-2013 Christian Wieninger This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -24,10 +24,6 @@ The project's page is at http://winni.vdr-developer.org/epgsearch #ifndef EPGSEARCHSERVICES_INC #define EPGSEARCHSERVICES_INC -// Added by Andreas Mair (mail _AT_ andreas _DOT_ vdr-developer _DOT_ org) -#define EPGSEARCH_SEARCHRESULTS_SERVICE_STRING_ID "Epgsearch-searchresults-v1.0" -#define EPGSEARCH_LASTCONFLICTINFO_SERVICE_STRING_ID "Epgsearch-lastconflictinfo-v1.0" - #include #include #include @@ -59,6 +55,13 @@ struct Epgsearch_exttimeredit_v1_0 cOsdMenu* pTimerMenu; // pointer to the menu of results }; +// Data structure for service "Epgsearch-enablesearchtimers-v1.0" +struct Epgsearch_enablesearchtimers_v1_0 +{ +// in + bool enable; // enable search timer thread? +}; + // Data structure for service "Epgsearch-updatesearchtimers-v1.0" struct Epgsearch_updatesearchtimers_v1_0 { @@ -104,7 +107,7 @@ struct Epgsearch_searchresults_v1_0 bool useDescription; // search in description // out - class cServiceSearchResult : public cListObject + class cServiceSearchResult : public cListObject { public: const cEvent* event; @@ -119,11 +122,11 @@ struct Epgsearch_switchtimer_v1_0 { // in const cEvent* event; - int mode; // mode (0=query existance, 1=add/modify, 2=delete) + int mode; // mode (0=query existence, 1=add/modify, 2=delete) // in/out int switchMinsBefore; int announceOnly; -// out +// out bool success; // result }; @@ -132,7 +135,7 @@ class cServiceHandler { public: virtual std::list SearchTimerList() = 0; - // returns a list of search timer entries in the same format as used in epgsearch.conf + // returns a list of search timer entries in the same format as used in epgsearch.conf virtual int AddSearchTimer(const std::string&) = 0; // adds a new search timer and returns its ID (-1 on error) virtual bool ModSearchTimer(const std::string&) = 0; @@ -140,11 +143,11 @@ class cServiceHandler virtual bool DelSearchTimer(int) = 0; // deletes search timer with given ID and returns success virtual std::list QuerySearchTimer(int) = 0; - // returns the search result of the searchtimer with given ID in the same format as used in SVDRP command 'QRYS' (->MANUAL) + // returns the search result of the searchtimer with given ID in the same format as used in SVDRP command 'QRYS' (->MANUAL) virtual std::list QuerySearch(std::string) = 0; - // returns the search result of the searchtimer with given settings in the same format as used in SVDRP command 'QRYS' (->MANUAL) + // returns the search result of the searchtimer with given settings in the same format as used in SVDRP command 'QRYS' (->MANUAL) virtual std::list ExtEPGInfoList() = 0; - // returns a list of extended EPG categories in the same format as used in epgsearchcats.conf + // returns a list of extended EPG categories in the same format as used in epgsearchcats.conf virtual std::list ChanGrpList() = 0; // returns a list of channel groups maintained by epgsearch virtual std::list BlackList() = 0; @@ -164,4 +167,36 @@ struct Epgsearch_services_v1_0 std::auto_ptr handler; }; +// Data structures for service "Epgsearch-services-v1.1" +class cServiceHandler_v1_1 : public cServiceHandler +{ + public: + // Get timer conflicts + virtual std::list TimerConflictList(bool relOnly=false) = 0; + // Check if a conflict check is advised + virtual bool IsConflictCheckAdvised() = 0; +}; + +struct Epgsearch_services_v1_1 +{ +// in/out + std::auto_ptr handler; +}; + +// Data structures for service "Epgsearch-services-v1.2" +class cServiceHandler_v1_2 : public cServiceHandler_v1_1 +{ + public: + // List of all recording directories used in recordings, timers (and optionally search timers or in epgsearchdirs.conf) + virtual std::set ShortDirectoryList() = 0; + // Evaluate an expression against an event + virtual std::string Evaluate(const std::string& expr, const cEvent* event) = 0; +}; + +struct Epgsearch_services_v1_2 +{ +// in/out + std::auto_ptr handler; +}; + #endif diff --git a/setup.c b/setup.c index a49106e..7368bb7 100644 --- a/setup.c +++ b/setup.c @@ -102,6 +102,8 @@ void cTvguideSetup::Store(void) { SetupStore("FontGridHorizontalSmallDelta", tvguideConfig.FontGridHorizontalSmallDelta); SetupStore("FontTimeLineDateHorizontalDelta", tvguideConfig.FontTimeLineDateHorizontalDelta); SetupStore("FontTimeLineTimeHorizontalDelta", tvguideConfig.FontTimeLineTimeHorizontalDelta); + SetupStore("FontRecMenuItemDelta", tvguideConfig.FontRecMenuItemDelta); + SetupStore("FontRecMenuItemSmallDelta", tvguideConfig.FontRecMenuItemSmallDelta); SetupStore("displayRerunsDetailEPGView", tvguideConfig.displayRerunsDetailEPGView); SetupStore("numReruns", tvguideConfig.numReruns); SetupStore("useSubtitleRerun", tvguideConfig.useSubtitleRerun); @@ -301,7 +303,9 @@ void cMenuSetupFont::Set(void) { Add(new cMenuEditIntItem(tr("Timeline Date Font Size"), &tmpTvguideConfig->FontTimeLineDateHorizontalDelta, -30, 30)); Add(new cMenuEditIntItem(tr("Timeline Time Font Size"), &tmpTvguideConfig->FontTimeLineTimeHorizontalDelta, -30, 30)); } - + + Add(new cMenuEditIntItem(tr("Search & Recording Menu Font Size"), &tmpTvguideConfig->FontRecMenuItemDelta, -30, 30)); + Add(new cMenuEditIntItem(tr("Search & Recording Menu Small Font Size"), &tmpTvguideConfig->FontRecMenuItemSmallDelta, -30, 30)); SetCurrent(Get(currentItem)); Display(); diff --git a/styledpixmap.c b/styledpixmap.c index 77e6450..d57ee54 100644 --- a/styledpixmap.c +++ b/styledpixmap.c @@ -132,3 +132,11 @@ void cStyledPixmap::DrawImage(const cPoint &Point, const cImage &Image) { void cStyledPixmap::DrawRectangle(const cRect &Rect, tColor Color) { pixmap->DrawRectangle(Rect,Color); } + +void cStyledPixmap::DrawEllipse(const cRect &Rect, tColor Color, int Quadrant) { + pixmap->DrawEllipse(Rect,Color,Quadrant); +} + +void cStyledPixmap::SetViewPort(const cRect &Rect) { + pixmap->SetViewPort(Rect); +} \ No newline at end of file diff --git a/styledpixmap.h b/styledpixmap.h index ac974be..af09994 100644 --- a/styledpixmap.h +++ b/styledpixmap.h @@ -13,23 +13,26 @@ protected: tColor colorBlending; void setPixmap(cPixmap *pixmap); public: - cStyledPixmap(void); - cStyledPixmap(cPixmap *pixmap); - virtual ~cStyledPixmap(void); - void drawBackground(); - void drawBlendedBackground(); - void drawSparsedBackground(); - void drawBorder(); - void drawBoldBorder(); - void drawDefaultBorder(int width, int height); - void drawRoundedCorners(int width, int height, int radius); - void setColor(tColor color, tColor colorBlending) {this->color = color; this->colorBlending = colorBlending;}; - void SetAlpha(int alpha) {pixmap->SetAlpha(alpha);}; - void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font); - void DrawImage(const cPoint &Point, const cImage &Image); - void DrawRectangle(const cRect &Rect, tColor Color); - int Width() {return pixmap->ViewPort().Width();}; - int Height() {return pixmap->ViewPort().Height();}; + cStyledPixmap(void); + cStyledPixmap(cPixmap *pixmap); + virtual ~cStyledPixmap(void); + void drawBackground(); + void drawBlendedBackground(); + void drawSparsedBackground(); + void drawBorder(); + void drawBoldBorder(); + void drawDefaultBorder(int width, int height); + void drawRoundedCorners(int width, int height, int radius); + void setColor(tColor color, tColor colorBlending) {this->color = color; this->colorBlending = colorBlending;}; + void SetAlpha(int alpha) {pixmap->SetAlpha(alpha);}; + void SetLayer(int layer) {pixmap->SetLayer(layer);}; + void DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font); + void DrawImage(const cPoint &Point, const cImage &Image); + void DrawRectangle(const cRect &Rect, tColor Color); + void DrawEllipse(const cRect &Rect, tColor Color, int Quadrant); + void SetViewPort(const cRect &Rect); + int Width() {return pixmap->ViewPort().Width();}; + int Height() {return pixmap->ViewPort().Height();}; }; #endif //__TVGUIDE_STYLEDPIXMAP_H \ No newline at end of file diff --git a/switchtimer.c b/switchtimer.c new file mode 100644 index 0000000..4ba7b45 --- /dev/null +++ b/switchtimer.c @@ -0,0 +1,109 @@ +#include "switchtimer.h" + +cSwitchTimers SwitchTimers; + +// -- cSwitchTimer ----------------------------------------------------------------- +cSwitchTimer::cSwitchTimer(void) { +} + +cSwitchTimer::cSwitchTimer(const cEvent* Event) { + eventID = 0; + startTime = 0; + if (Event) { + eventID = Event->EventID(); + channelID = Event->ChannelID(); + startTime = Event->StartTime(); + } +} + +bool cSwitchTimer::Parse(const char *s) { + char *line; + char *pos; + char *pos_next; + int parameter = 1; + int valuelen; +#define MAXVALUELEN (10 * MaxFileName) + + char value[MAXVALUELEN]; + startTime=0; + + pos = line = strdup(s); + pos_next = pos + strlen(pos); + if (*pos_next == '\n') *pos_next = 0; + while (*pos) { + while (*pos == ' ') + pos++; + if (*pos) { + if (*pos != ':') { + pos_next = strchr(pos, ':'); + if (!pos_next) + pos_next = pos + strlen(pos); + valuelen = pos_next - pos + 1; + if (valuelen > MAXVALUELEN) + valuelen = MAXVALUELEN; + strn0cpy(value, pos, valuelen); + pos = pos_next; + switch (parameter) { + case 1: + channelID = tChannelID::FromString(value); + break; + case 2: + eventID = atoi(value); + break; + case 3: + startTime = atol(value); + break; + default: + break; + } + } + parameter++; + } + if (*pos) + pos++; + } + free(line); + return (parameter >= 3) ? true : false; +} + +bool cSwitchTimers::EventInSwitchList(const cEvent* event) { + if (!event) return false; + cMutexLock SwitchTimersLock(this); + cSwitchTimer* switchTimer = SwitchTimers.First(); + while (switchTimer) { + if (switchTimer->eventID == event->EventID()) + return true; + switchTimer = SwitchTimers.Next(switchTimer); + } + return false; +} + +bool cSwitchTimers::ChannelInSwitchList(const cChannel* channel) { + if (!channel) return false; + cMutexLock SwitchTimersLock(this); + cSwitchTimer* switchTimer = SwitchTimers.First(); + while (switchTimer) { + if (switchTimer->channelID == channel->GetChannelID()) + return true; + switchTimer = SwitchTimers.Next(switchTimer); + } + return false; +} + +void cSwitchTimers::DeleteSwitchTimer(const cEvent *event) { + if (!event) return; + cMutexLock SwitchTimersLock(this); + cSwitchTimer* switchTimer = SwitchTimers.First(); + cSwitchTimer* delTimer = NULL; + + while (switchTimer) { + if (switchTimer->eventID == event->EventID()) { + delTimer = switchTimer; + break; + } + switchTimer = SwitchTimers.Next(switchTimer); + } + if (delTimer) { + SwitchTimers.Del(delTimer, true); + } +} diff --git a/switchtimer.h b/switchtimer.h new file mode 100644 index 0000000..8958b44 --- /dev/null +++ b/switchtimer.h @@ -0,0 +1,30 @@ +#ifndef __TVGUIDE_SWITCHTIMER_H +#define __TVGUIDE_SWITCHTIMER_H + +#include + +class cSwitchTimer : public cListObject +{ +public: + tEventID eventID; + time_t startTime; + tChannelID channelID; + + cSwitchTimer(void); + cSwitchTimer(const cEvent* Event); + bool Parse(const char *s); +}; + +class cSwitchTimers : public cConfig, public cMutex +{ +public: + cSwitchTimers(void) {} + ~cSwitchTimers(void) {} + bool EventInSwitchList(const cEvent* event); + bool ChannelInSwitchList(const cChannel* channel); + void DeleteSwitchTimer(const cEvent *event); +}; + +extern cSwitchTimers SwitchTimers; + +#endif //__TVGUIDE_SWITCHTIMER_H diff --git a/themes/tvguide-darkblue.theme b/themes/tvguide-darkblue.theme index 90285ce..ec0a1b1 100644 --- a/themes/tvguide-darkblue.theme +++ b/themes/tvguide-darkblue.theme @@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00 clrButtonBlue = 990000BB clrButtonBlueBorder = FF0000BB clrButtonBlend = DD000000 +clrRecMenuBackground = AA000000 +clrRecMenuTimerConflictBackground = FFCCCCCC +clrRecMenuTimerConflictBar = FF222222 +clrRecMenuTimerConflictOverlap = AAFF0000 +clrRecMenuDayActive = FF00FF00 +clrRecMenuDayInactive = FFFF0000 +clrRecMenuDayHighlight = 44FFFFFF +clrRecMenuTextBack = FF000000 +clrRecMenuTextActiveBack = FF404749 +clrRecMenuKeyboardBack = FF000000 +clrRecMenuKeyboardBorder = FFFFFFFF +clrRecMenuKeyboardHigh = 40BB0000 \ No newline at end of file diff --git a/themes/tvguide-default.theme b/themes/tvguide-default.theme index 9704e65..05b2e47 100644 --- a/themes/tvguide-default.theme +++ b/themes/tvguide-default.theme @@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00 clrButtonBlue = 990000BB clrButtonBlueBorder = FF0000BB clrButtonBlend = DD000000 +clrRecMenuBackground = AA000000 +clrRecMenuTimerConflictBackground = FFCCCCCC +clrRecMenuTimerConflictBar = FF222222 +clrRecMenuTimerConflictOverlap = AAFF0000 +clrRecMenuDayActive = FF00FF00 +clrRecMenuDayInactive = FFFF0000 +clrRecMenuDayHighlight = 44FFFFFF +clrRecMenuTextBack = FF000000 +clrRecMenuTextActiveBack = FF404749 +clrRecMenuKeyboardBack = FF000000 +clrRecMenuKeyboardBorder = FFFFFFFF +clrRecMenuKeyboardHigh = 40BB0000 \ No newline at end of file diff --git a/themes/tvguide-keepitsimple.theme b/themes/tvguide-keepitsimple.theme index f88aa92..852d7c3 100644 --- a/themes/tvguide-keepitsimple.theme +++ b/themes/tvguide-keepitsimple.theme @@ -25,4 +25,16 @@ clrButtonYellow = 99BBBB00 clrButtonYellowBorder = FFBBBB00 clrButtonBlue = 990000BB clrButtonBlueBorder = FF0000BB -clrButtonBlend = DD000000 \ No newline at end of file +clrButtonBlend = DD000000 +clrRecMenuBackground = AA000000 +clrRecMenuTimerConflictBackground = FFCCCCCC +clrRecMenuTimerConflictBar = FF222222 +clrRecMenuTimerConflictOverlap = AAFF0000 +clrRecMenuDayActive = FF00FF00 +clrRecMenuDayInactive = FFFF0000 +clrRecMenuDayHighlight = 44FFFFFF +clrRecMenuTextBack = FF000000 +clrRecMenuTextActiveBack = FF404749 +clrRecMenuKeyboardBack = FF000000 +clrRecMenuKeyboardBorder = BB555555 +clrRecMenuKeyboardHigh = 40BB0000 \ No newline at end of file diff --git a/themes/tvguide-nOpacity.theme b/themes/tvguide-nOpacity.theme index f492c2d..345d13a 100644 --- a/themes/tvguide-nOpacity.theme +++ b/themes/tvguide-nOpacity.theme @@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00 clrButtonBlue = 990000BB clrButtonBlueBorder = FF0000BB clrButtonBlend = DD000000 +clrRecMenuBackground = AA000000 +clrRecMenuTimerConflictBackground = FFCCCCCC +clrRecMenuTimerConflictBar = FF222222 +clrRecMenuTimerConflictOverlap = AAFF0000 +clrRecMenuDayActive = FF00FF00 +clrRecMenuDayInactive = FFFF0000 +clrRecMenuDayHighlight = 44FFFFFF +clrRecMenuTextBack = FF000000 +clrRecMenuTextActiveBack = FF404749 +clrRecMenuKeyboardBack = FF000000 +clrRecMenuKeyboardBorder = FF003DF5 +clrRecMenuKeyboardHigh = 40BB0000 \ No newline at end of file diff --git a/themes/tvguide-nOpacitydarkred.theme b/themes/tvguide-nOpacitydarkred.theme index d0c73a0..b14f6ac 100644 --- a/themes/tvguide-nOpacitydarkred.theme +++ b/themes/tvguide-nOpacitydarkred.theme @@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00 clrButtonBlue = 990000BB clrButtonBlueBorder = FF0000BB clrButtonBlend = DD000000 +clrRecMenuBackground = AA000000 +clrRecMenuTimerConflictBackground = FFCCCCCC +clrRecMenuTimerConflictBar = FF222222 +clrRecMenuTimerConflictOverlap = AAFF0000 +clrRecMenuDayActive = FF00FF00 +clrRecMenuDayInactive = FFFF0000 +clrRecMenuDayHighlight = 44FFFFFF +clrRecMenuTextBack = FF000000 +clrRecMenuTextActiveBack = FF404749 +clrRecMenuKeyboardBack = FF000000 +clrRecMenuKeyboardBorder = FF660000 +clrRecMenuKeyboardHigh = 40BB0000 \ No newline at end of file diff --git a/themes/tvguide-nOpacitygreen.theme b/themes/tvguide-nOpacitygreen.theme index e787d15..3042a84 100644 --- a/themes/tvguide-nOpacitygreen.theme +++ b/themes/tvguide-nOpacitygreen.theme @@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00 clrButtonBlue = 990000BB clrButtonBlueBorder = FF0000BB clrButtonBlend = DD000000 +clrRecMenuBackground = AA000000 +clrRecMenuTimerConflictBackground = FFCCCCCC +clrRecMenuTimerConflictBar = FF222222 +clrRecMenuTimerConflictOverlap = AAFF0000 +clrRecMenuDayActive = FF00FF00 +clrRecMenuDayInactive = FFFF0000 +clrRecMenuDayHighlight = 44FFFFFF +clrRecMenuTextBack = FF000000 +clrRecMenuTextActiveBack = FF404749 +clrRecMenuKeyboardBack = FF000000 +clrRecMenuKeyboardBorder = EE006600 +clrRecMenuKeyboardHigh = 40BB0000 \ No newline at end of file diff --git a/themes/tvguide-nOpacityiceblue.theme b/themes/tvguide-nOpacityiceblue.theme index 2112974..ce5cb2c 100644 --- a/themes/tvguide-nOpacityiceblue.theme +++ b/themes/tvguide-nOpacityiceblue.theme @@ -25,3 +25,18 @@ clrButtonYellow = FFBBBB00 clrButtonYellowBorder = FFBBBB00 clrButtonBlue = FF0000BB clrButtonBlueBorder = FF0000BB +clrRecMenuBackground = AA000000 +clrRecMenuTimerConflictBackground = FFCCCCCC +clrRecMenuTimerConflictBar = FF222222 +clrRecMenuTimerConflictOverlap = AAFF0000 +clrRecMenuDayActive = FF00FF00 +clrRecMenuDayInactive = FFFF0000 +clrRecMenuDayHighlight = 77000000 +clrRecMenuTextBack = FF3C3C3C +clrRecMenuTextActiveBack = FF404749 +clrRecMenuKeyboardBack = FF000044 +clrRecMenuKeyboardBorder = FF3C3C3C +clrRecMenuKeyboardHigh = 55FFFFFF +clrButtonRedKeyboard = FFBB0000 +clrButtonGreenKeyboard = FF00BB00 +clrButtonYellowKeyboard = FFBBBB00 diff --git a/timeline.c b/timeline.c index 454aa9c..4355352 100644 --- a/timeline.c +++ b/timeline.c @@ -3,11 +3,11 @@ cTimeLine::cTimeLine(cMyTime *myTime) { this->myTime = myTime; if (tvguideConfig.displayMode == eVertical) { - dateViewer = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, + dateViewer = new cStyledPixmap(osdManager.requestPixmap(1, cRect(0, tvguideConfig.statusHeaderHeight, tvguideConfig.timeLineWidth, tvguideConfig.channelHeaderHeight + tvguideConfig.channelGroupsHeight))); - timeline = osdManager.requestPixmap(2, cRect(0, + timeline = osdManager.requestPixmap(1, cRect(0, tvguideConfig.statusHeaderHeight + tvguideConfig.channelHeaderHeight + tvguideConfig.channelGroupsHeight, tvguideConfig.timeLineWidth, tvguideConfig.osdHeight - tvguideConfig.statusHeaderHeight - tvguideConfig.channelHeaderHeight - tvguideConfig.channelGroupsHeight - tvguideConfig.footerHeight) @@ -16,11 +16,11 @@ cTimeLine::cTimeLine(cMyTime *myTime) { tvguideConfig.timeLineWidth, 1440*tvguideConfig.minutePixel)); } else if (tvguideConfig.displayMode == eHorizontal) { - dateViewer = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, + dateViewer = new cStyledPixmap(osdManager.requestPixmap(1, cRect(0, tvguideConfig.statusHeaderHeight, tvguideConfig.channelHeaderWidth + tvguideConfig.channelGroupsWidth, tvguideConfig.timeLineHeight))); - timeline = osdManager.requestPixmap(2, cRect(tvguideConfig.channelHeaderWidth + tvguideConfig.channelGroupsWidth, + timeline = osdManager.requestPixmap(1, cRect(tvguideConfig.channelHeaderWidth + tvguideConfig.channelGroupsWidth, tvguideConfig.statusHeaderHeight, tvguideConfig.osdWidth - tvguideConfig.channelHeaderWidth - tvguideConfig.channelGroupsWidth, tvguideConfig.timeLineHeight) @@ -29,7 +29,7 @@ cTimeLine::cTimeLine(cMyTime *myTime) { 1440*tvguideConfig.minutePixel, tvguideConfig.timeLineWidth)); } - clock = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0, + clock = new cStyledPixmap(osdManager.requestPixmap(1, cRect(0, tvguideConfig.osdHeight- tvguideConfig.footerHeight, tvguideConfig.timeLineWidth, tvguideConfig.footerHeight-9))); diff --git a/timer.c b/timer.c index 8e60c0e..f6d9925 100644 --- a/timer.c +++ b/timer.c @@ -120,3 +120,49 @@ time_t cMyTime::GetRounded() { void cMyTime::debug() { esyslog("t: %s, tStart: %s, tEnd: %s", *TimeString(t), *TimeString(tStart), *TimeString(tEnd)); } + +// --- cTimeInterval ------------------------------------------------------------- + +cTimeInterval::cTimeInterval(time_t start, time_t stop) { + this->start = start; + this->stop = stop; +} + +cTimeInterval::~cTimeInterval(void) { +} + +cTimeInterval *cTimeInterval::Intersect(cTimeInterval *interval) { + time_t startIntersect, stopIntersect; + + if ((stop <= interval->Start()) || (interval->Stop() <= start)) { + return NULL; + } + + if (start <= interval->Start()) { + startIntersect = interval->Start(); + } else { + startIntersect = start; + } + if (stop <= interval->Stop()) { + stopIntersect = stop; + } else { + stopIntersect = interval->Stop(); + } + return new cTimeInterval(startIntersect, stopIntersect); +} + +cTimeInterval *cTimeInterval::Union(cTimeInterval *interval) { + time_t startUnion, stopUnion; + + if (start <= interval->Start()) { + startUnion = start; + } else { + startUnion = interval->Start(); + } + if (stop <= interval->Stop()) { + stopUnion = interval->Stop(); + } else { + stopUnion = stop; + } + return new cTimeInterval(startUnion, stopUnion); +} \ No newline at end of file diff --git a/timer.h b/timer.h index e84f74c..2ab5045 100644 --- a/timer.h +++ b/timer.h @@ -30,4 +30,19 @@ class cMyTime { void debug(); }; +// --- cTimeInterval ------------------------------------------------------------- + +class cTimeInterval { + private: + time_t start; + time_t stop; + public: + cTimeInterval(time_t start, time_t stop); + virtual ~cTimeInterval(void); + time_t Start(void) { return start; }; + time_t Stop(void) { return stop; }; + cTimeInterval *Intersect(cTimeInterval *interval); + cTimeInterval *Union(cTimeInterval *interval); +}; + #endif //__TVGUIDE_TIMER_H \ No newline at end of file diff --git a/tools.c b/tools.c new file mode 100644 index 0000000..2a3815e --- /dev/null +++ b/tools.c @@ -0,0 +1,370 @@ +#include +#include +#include + +/**************************************************************************************** +* CUTTEXT +****************************************************************************************/ +static std::string CutText(std::string text, int width, const cFont *font) { + if (width <= font->Size()) + return text.c_str(); + if (font->Width(text.c_str()) < width) + return text.c_str(); + cTextWrapper twText; + twText.Set(text.c_str(), font, width); + std::string cuttedTextNative = twText.GetLine(0); + std::stringstream sstrText; + sstrText << cuttedTextNative << "..."; + std::string cuttedText = sstrText.str(); + int actWidth = font->Width(cuttedText.c_str()); + if (actWidth > width) { + int overlap = actWidth - width; + int charWidth = font->Width("."); + if (charWidth == 0) + charWidth = 1; + int cutChars = overlap / charWidth; + if (cutChars > 0) { + cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars); + std::stringstream sstrText2; + sstrText2 << cuttedTextNative << "..."; + cuttedText = sstrText2.str(); + } + } + return cuttedText; +} +/**************************************************************************************** +* SPLTSTRING +****************************************************************************************/ +class splitstring : public std::string { + std::vector flds; +public: + splitstring(const char *s) : std::string(s) { }; + std::vector& split(char delim, int rep=0); +}; + +// split: receives a char delimiter; returns a vector of strings +// By default ignores repeated delimiters, unless argument rep == 1. +std::vector& splitstring::split(char delim, int rep) { + if (!flds.empty()) flds.clear(); // empty vector if necessary + std::string work = data(); + std::string buf = ""; + int i = 0; + while (i < work.length()) { + if (work[i] != delim) + buf += work[i]; + else if (rep == 1) { + flds.push_back(buf); + buf = ""; + } else if (buf.length() > 0) { + flds.push_back(buf); + buf = ""; + } + i++; + } + if (!buf.empty()) + flds.push_back(buf); + return flds; +} + +/**************************************************************************************** +* FINDIGNORECASE +****************************************************************************************/ +int FindIgnoreCase(const std::string& expr, const std::string& query) +{ + const char *p = expr.c_str(); + const char *r = strcasestr(p, query.c_str()); + + if (!r) + return -1; + return r - p; +} + +/**************************************************************************************** +* FUZZYSEARCH +****************************************************************************************/ +#include +#include +#include +#include + +#ifndef _AFUZZY_H +#define _AFUZZY_H + +// source from: +/* + Leonid Boitsov 2002. (itman@narod.ru) + C version of Stas Namin. + This code is a GPL software and is distributed under GNU + public licence without any warranty. +*/ + +typedef unsigned int Uint; + +#define MaxPatSize (sizeof(Uint) * 8) + +typedef struct +{ + Uint *R, + *R1, + *RP, + *S, + *RI; + Uint *FilterS; + + int Map[256]; + int FilterMap[256]; + int k; + Uint mask_ok; + Uint filter_ok; + Uint filter_shift; + int r_size; + int FilterSet; +} AFUZZY; + +void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy); +void afuzzy_free(AFUZZY *fuzzy); +int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy); + +#endif + + +static int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy); + +/****************************************************************************** +FUNCTION afuzzy_init() + Initialization of the fuzzy search routine. This applies to the consequent + calls of the afuzzy_CheckRTR (whole string matching) and afuzzy_CheckSUB + (substring match) routines. afuzzy_init() should be called for each + new pattern or error length. The search is case sensitive + +ARGUMENTS: + p Pattern + kerr Number of possible errors. Shouldn't exceed pattern length + UseFilter Use agrep filter algorithm that speeds up search. + fuzzy pointer to the structure that will be later passes to Check* + (the first 6 elements should be NULLs for the first call) + +RETURN VALUE: + none + +ALGORITHM + see. the article on agrep algorithms. + The only change is accounting transpositions as one edit operation . +******************************************************************************/ +void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy) +{ + int cnt, p_len, i, j, l, d, m, dd; + char PatFilter[sizeof(Uint)*8 + 1]; + + fuzzy->k = kerr; + m = strlen(p); + fuzzy->FilterSet = 0; + memset(fuzzy->Map, 0 , sizeof(fuzzy->Map) ); + + if (fuzzy->S) + free(fuzzy->S); + if (fuzzy->R) + free(fuzzy->R); + if (fuzzy->R1) + free(fuzzy->R1); + if (fuzzy->RP) + free(fuzzy->RP); + if (fuzzy->RI) + free(fuzzy->RI); + if (fuzzy->FilterS) + free(fuzzy->FilterS); + + fuzzy->FilterS = NULL; + fuzzy->S = (Uint *)calloc(m + 1, sizeof(Uint)); + fuzzy->R = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); + fuzzy->R1 = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); + fuzzy->RI = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); + fuzzy->RP = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint)); + + for (i = 0, cnt = 0; i < m; i++) + { + l = fuzzy->Map[(unsigned char)p[i]]; + if (!l) + { + l = fuzzy->Map[(unsigned char)p[i]] = ++cnt; + fuzzy->S[l] = 0; + } + fuzzy->S[l] |= 1 << i; + } + + + for (d = 0; d <= fuzzy->k; d++) + fuzzy->RI[d] = (1 << d) - 1; + + fuzzy->mask_ok = (1 << (m - 1)); + fuzzy->r_size = sizeof(Uint) * (fuzzy->k + 1); + p_len = m; + + if (p_len > (int) sizeof(Uint)*8) + p_len = (int) sizeof(Uint)*8; + + /* If k is zero then no filter is needed! */ + if (fuzzy->k && (p_len >= 2*(fuzzy->k + 1)) ) + { + if (UseFilter) + { + fuzzy->FilterSet = 1; + memset(fuzzy->FilterMap, 0 , sizeof(fuzzy->FilterMap) ); + fuzzy->FilterS = (Uint *)calloc(m + 1, sizeof(Uint)); + + /* Not let's fill the interleaved pattern */ + dd = p_len / (fuzzy->k + 1); + p_len = dd * (fuzzy->k + 1); + + for (i = 0, cnt = 0; i < dd; i++) + for (j = 0; j < fuzzy->k + 1; j++, cnt++) + PatFilter[cnt] = (unsigned char)p[j*dd + i]; + PatFilter[p_len] = 0; + + for (i = 0, cnt = 0; i < p_len; i++) + { + l = fuzzy->FilterMap[(unsigned char)PatFilter[i]]; + if (!l) + { + l = fuzzy->FilterMap[(unsigned char)PatFilter[i]] = ++cnt; + fuzzy->FilterS[l] = 0; + } + fuzzy->FilterS[l] |= 1 << i; + } + fuzzy->filter_ok = 0; + for (i = p_len - fuzzy->k - 1; i <= p_len - 1; i++) /* k+1 times */ + fuzzy->filter_ok |= 1 << i; + + /* k+1 first bits set to 1 */ + fuzzy->filter_shift = (1 << (fuzzy->k + 2)) - 1; + } + } +} + +/****************************************************************************** +FUNCTION afuzzy_free() + Cleaning up after previous afuzzy_init() call. + +ARGUMENTS: + fuzzy pointer to the afuzzy parameters structure + +RETURN VALUE: + none +******************************************************************************/ +void afuzzy_free(AFUZZY *fuzzy) +{ + if (fuzzy->S) + { + free(fuzzy->S); + fuzzy->S = NULL; + } + if (fuzzy->R) + { + free(fuzzy->R); + fuzzy->R = NULL; + } + if (fuzzy->R1) + { + free(fuzzy->R1); + fuzzy->R1 = NULL; + } + if (fuzzy->RP) + { + free(fuzzy->RP); + fuzzy->RP = NULL; + } + if (fuzzy->RI) + { + free(fuzzy->RI); + fuzzy->RI = NULL; + } + if (fuzzy->FilterS) + { + free(fuzzy->FilterS); + fuzzy->FilterS = NULL; + } +} + + +/****************************************************************************** +FUNCTION afuzzy_CheckSUB() + Perform a fuzzy pattern substring matching. afuzzy_init() should be + called previously to initialize the pattern and error length. + Positive result means that some part of the string given matches the + pattern with no more than afuzzy->k errors (1 error = 1 letter + replacement or transposition) + +ARGUMENTS: + t the string to test + fuzzy pointer to the afuzzy parameters structure + +RETURN VALUE: + 0 - no match + > 0 - strings match + +ALGORITHM + ???????????????? +******************************************************************************/ +int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy) +{ + register char c; + register int j, d; + + /* For eficciency this case should be little bit optimized */ + if (!fuzzy->k) + { + Uint R = 0, R1; + + for (j = 0; (c = t[j]) != '\0'; j++) + { + R1 = ( ((R<<1) | 1) & fuzzy->S[fuzzy->Map[(unsigned char)c]]); + R = R1; + + if (R1 & fuzzy->mask_ok) + return 1; + } /* end for (register int j = 0 ... */ + return 0; + } + + if (fuzzy->FilterSet && !afuzzy_checkFLT(t, fuzzy)) + return 0; + + memcpy(fuzzy->R, fuzzy->RI, fuzzy->r_size); /* R = RI */ + + for (j = 0; (c = t[j]); j++) + { + for (d = 0; d <= fuzzy->k; d++) + { + fuzzy->R1[d] = (((fuzzy->R[d]<<1) | 1) & + fuzzy->S[fuzzy->Map[(unsigned char)c]]); + if (d > 0) + fuzzy->R1[d] |= ((fuzzy->R[d-1] | fuzzy->R1[d-1])<<1) | 1 | + fuzzy->R[d-1]; + } + if (fuzzy->R1[fuzzy->k] & fuzzy->mask_ok) + return j; + + memcpy(fuzzy->R, fuzzy->R1, fuzzy->r_size); + + } /* end for (register int j = 0 ... */ + + return 0; +} + +static int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy) +{ + register Uint FilterR = 0; + register Uint FilterR1; + register int j; + + for (j = 0; t[j] != '\0'; j++) + { + FilterR1 = ( ((FilterR<<(fuzzy->k+1)) | fuzzy->filter_shift) & + fuzzy->FilterS[fuzzy->FilterMap[(unsigned char)t[j]]]); + if (FilterR1 & fuzzy->filter_ok) + return 1; + FilterR = FilterR1; + } /* end for (register int j = 0 ... */ + + return 0; +} diff --git a/tvguide.c b/tvguide.c index 806868b..f33c1e9 100644 --- a/tvguide.c +++ b/tvguide.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "tvguideosd.c" @@ -20,7 +21,7 @@ -static const char *VERSION = "0.0.5"; +static const char *VERSION = "0.0.6"; static const char *DESCRIPTION = "A fancy 2d EPG Viewer"; static const char *MAINMENUENTRY = "Tvguide"; @@ -28,6 +29,7 @@ class cPluginTvguide : public cPlugin { private: bool logoPathSet; bool imagesPathSet; + bool iconsPathSet; public: cPluginTvguide(void); virtual ~cPluginTvguide(); @@ -58,6 +60,7 @@ cPluginTvguide::cPluginTvguide(void) // VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT! logoPathSet = false; imagesPathSet = false; + iconsPathSet = false; } cPluginTvguide::~cPluginTvguide() @@ -124,6 +127,13 @@ bool cPluginTvguide::Start(void) tvguideConfig.SetImagesPath(path); logoPathSet = true; } + + if (!iconsPathSet) { + cString path = cString::sprintf("%s/icons/", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N)); + tvguideConfig.SetIconsPath(path); + iconsPathSet = true; + } + return true; } diff --git a/tvguideosd.c b/tvguideosd.c index 5aaa128..01fcbe6 100644 --- a/tvguideosd.c +++ b/tvguideosd.c @@ -37,6 +37,21 @@ THEME_CLR(theme, clrButtonYellowBorder, 0xFFBBBB00); THEME_CLR(theme, clrButtonBlue, 0x990000BB); THEME_CLR(theme, clrButtonBlueBorder, 0xFF0000BB); THEME_CLR(theme, clrButtonBlend, 0xDD000000); +THEME_CLR(theme, clrRecMenuBackground, 0xB0000000); +THEME_CLR(theme, clrRecMenuTimerConflictBackground, 0xFFCCCCCC); +THEME_CLR(theme, clrRecMenuTimerConflictBar, 0xFF222222); +THEME_CLR(theme, clrRecMenuTimerConflictOverlap, 0xAAFF0000); +THEME_CLR(theme, clrRecMenuDayActive, 0xFF00FF00); +THEME_CLR(theme, clrRecMenuDayInactive, 0xFFFF0000); +THEME_CLR(theme, clrRecMenuDayHighlight, 0x44FFFFFF); +THEME_CLR(theme, clrRecMenuTextBack, 0xFF000000); +THEME_CLR(theme, clrRecMenuTextActiveBack, 0xFF404749); +THEME_CLR(theme, clrRecMenuKeyboardBack, 0xFF000000); +THEME_CLR(theme, clrRecMenuKeyboardBorder, clrWhite); +THEME_CLR(theme, clrRecMenuKeyboardHigh, 0x55FFFFFF); +THEME_CLR(theme, clrButtonRedKeyboard, 0xFFBB0000); +THEME_CLR(theme, clrButtonGreenKeyboard, 0xFF00BB00); +THEME_CLR(theme, clrButtonYellowKeyboard, 0xFFBBBB00); #include "config.c" cTvguideConfig tvguideConfig; @@ -44,11 +59,12 @@ cTvguideConfig tvguideConfig; #include "osdmanager.c" cOsdManager osdManager; +#include "tools.c" +#include "switchtimer.c" #include "setup.c" #include "imageloader.c" #include "styledpixmap.c" #include "timer.c" -#include "messagebox.c" #include "timeline.c" #include "grid.c" #include "headergrid.c" @@ -60,6 +76,11 @@ cOsdManager osdManager; #include "channelgroup.c" #include "channelgroups.c" #include "footer.c" +#include "recmenuitem.c" +#include "recmenu.c" +#include "recmanager.c" +#include "recmenus.c" +#include "recmenumanager.c" #include "tvguideosd.h" #include @@ -69,6 +90,7 @@ cTvGuideOsd::cTvGuideOsd(void) { detailViewActive = false; activeGrid = NULL; timeLine = NULL; + recMenuManager = NULL; } cTvGuideOsd::~cTvGuideOsd() { @@ -82,7 +104,7 @@ cTvGuideOsd::~cTvGuideOsd() { delete timeLine; delete channelGroups; delete footer; - cMessageBox::Destroy(); + delete recMenuManager; osdManager.deleteOsd(); } @@ -97,6 +119,12 @@ void cTvGuideOsd::Show(void) { osdManager.setBackground(); myTime = new cMyTime(); myTime->Now(); + SwitchTimers.Load(AddDirectory(cPlugin::ConfigDirectory("epgsearch"), "epgsearchswitchtimers.conf")); + cSwitchTimer *st = NULL; + for (st = SwitchTimers.First(); st; st = SwitchTimers.Next(st)) { + esyslog("tvguide: switchtimer eventID %d time %ld", st->eventID, st->startTime); + } + recMenuManager = new cRecMenuManager(); drawOsd(); } esyslog("tvguide: Rendering took %d ms", int(cTimeMs::Now()-start)); @@ -392,15 +420,10 @@ void cTvGuideOsd::processKeyUp() { if (!activeGrid) { return; } - if (detailViewActive) { - detailView->scrollUp(); - osdManager.flush(); - } else { - if (tvguideConfig.displayMode == eVertical) { - timeBack(); - } else if (tvguideConfig.displayMode == eHorizontal) { - channelBack(); - } + if (tvguideConfig.displayMode == eVertical) { + timeBack(); + } else if (tvguideConfig.displayMode == eHorizontal) { + channelBack(); } } @@ -408,21 +431,14 @@ void cTvGuideOsd::processKeyDown() { if (!activeGrid) { return; } - if (detailViewActive) { - detailView->scrollDown(); - osdManager.flush(); - } else { - if (tvguideConfig.displayMode == eVertical) { - timeForward(); - } else if (tvguideConfig.displayMode == eHorizontal) { - channelForward(); - } + if (tvguideConfig.displayMode == eVertical) { + timeForward(); + } else if (tvguideConfig.displayMode == eHorizontal) { + channelForward(); } } void cTvGuideOsd::processKeyLeft() { - if (detailViewActive) - return; if (activeGrid == NULL) return; if (tvguideConfig.displayMode == eVertical) { @@ -433,8 +449,6 @@ void cTvGuideOsd::processKeyLeft() { } void cTvGuideOsd::processKeyRight() { - if (detailViewActive) - return; if (activeGrid == NULL) return; if (tvguideConfig.displayMode == eVertical) { @@ -447,26 +461,7 @@ void cTvGuideOsd::processKeyRight() { void cTvGuideOsd::processKeyRed() { if ((activeGrid == NULL) || activeGrid->isDummy()) return; - cTimer *timer = new cTimer(activeGrid->GetEvent()); - cTimer *t = Timers.GetTimer(timer); - cString msg; - if (t) { - isyslog("timer %s already exists", *timer->ToDescr()); - delete timer; - msg = cString::sprintf(tr("Timer not set! There is already a timer for this item.")); - } else { - Timers.Add(timer); - Timers.SetModified(); - msg = cString::sprintf("%s:\n%s (%s) %s - %s", tr("Timer set"), activeGrid->GetEvent()->Title(), timer->Channel()->Name(), *DayDateTime(timer->StartTime()), *TimeString(timer->StopTime())); - timer->SetEvent(activeGrid->GetEvent()); - activeGrid->setTimer(); - activeGrid->column->setTimer(); - activeGrid->SetDirty(); - activeGrid->Draw(); - osdManager.flush(); - isyslog("timer %s added (active)", *timer->ToDescr()); - } - cMessageBox::Start(4000, msg); + recMenuManager->Start(activeGrid->GetEvent()); } void cTvGuideOsd::processKeyGreen() { @@ -547,7 +542,7 @@ eOSState cTvGuideOsd::processKeyBlue() { } eOSState cTvGuideOsd::processKeyOk() { - if ((tvguideConfig.blueKeyMode == 0) || detailViewActive ) { + if (tvguideConfig.blueKeyMode == 0) { DetailedEPG(); } else if (tvguideConfig.blueKeyMode == 1) { return ChannelSwitch(); @@ -567,17 +562,13 @@ eOSState cTvGuideOsd::ChannelSwitch() { } void cTvGuideOsd::DetailedEPG() { - if (detailViewActive) { - delete detailView; - detailView = NULL; - detailViewActive = false; + if (!activeGrid->isDummy()) { + detailViewActive = true; + detailView = new cDetailView(activeGrid->GetEvent()); + detailView->drawHeader(); + detailView->drawContent(); + detailView->drawScrollbar(); osdManager.flush(); - } else { - if (!activeGrid->isDummy()) { - detailViewActive = true; - detailView = new cDetailView(activeGrid); - detailView->Start(); - } } } @@ -646,11 +637,32 @@ void cTvGuideOsd::processKey9() { osdManager.flush(); } +void cTvGuideOsd::SetTimers() { + for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) { + column->SetTimers(); + } +} + eOSState cTvGuideOsd::ProcessKey(eKeys Key) { - eOSState state = cOsdObject::ProcessKey(Key); - if (state == osUnknown) { - cPixmap::Lock(); + eOSState state = osContinue; + cPixmap::Lock(); + if (recMenuManager->isActive()) { + state = recMenuManager->ProcessKey(Key); + if (state == osEnd) { + SetTimers(); + osdManager.flush(); + } state = osContinue; + } else if (detailViewActive) { + state = detailView->ProcessKey(Key); + if (state == osEnd) { + delete detailView; + detailView = NULL; + detailViewActive = false; + osdManager.flush(); + state = osContinue; + } + } else { switch (Key & ~k_Repeat) { case kUp: processKeyUp(); break; case kDown: processKeyDown(); break; @@ -661,7 +673,7 @@ eOSState cTvGuideOsd::ProcessKey(eKeys Key) { case kYellow: processKeyYellow(); break; case kBlue: state = processKeyBlue(); break; case kOk: state = processKeyOk(); break; - case kBack: state=osEnd; break; + case kBack: state=osEnd; break; case k1: processKey1(); break; case k3: processKey3(); break; case k4: processKey4(); break; @@ -670,8 +682,8 @@ eOSState cTvGuideOsd::ProcessKey(eKeys Key) { case k9: processKey9(); break; default: break; } - cPixmap::Unlock(); } + cPixmap::Unlock(); return state; } diff --git a/tvguideosd.h b/tvguideosd.h index bc46728..717ce10 100644 --- a/tvguideosd.h +++ b/tvguideosd.h @@ -13,6 +13,7 @@ private: cTimeLine *timeLine; cChannelGroups *channelGroups; cFooter *footer; + cRecMenuManager *recMenuManager; bool detailViewActive; void drawOsd(); void readChannels(const cChannel *channelStart); @@ -42,6 +43,7 @@ private: void ScrollBack(); eOSState ChannelSwitch(); void DetailedEPG(); + void SetTimers(); void dump(); public: cTvGuideOsd(void);