Version 0.0.6
3
HISTORY
@ -43,7 +43,8 @@ VDR Plugin 'tvguide' Revision History
|
|||||||
- Added setup option to switch functionality of keys "Blue" and "OK"
|
- Added setup option to switch functionality of keys "Blue" and "OK"
|
||||||
- Setup option to hide schedules time display in horizontal EPG grids
|
- 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 frame around scaled video picture
|
||||||
- added theme "keep it simple" (thanks @saman)
|
- added theme "keep it simple" (thanks @saman)
|
||||||
- display of additional EPG pictures in detailed epg view
|
- display of additional EPG pictures in detailed epg view
|
||||||
|
- Introduction of "Search & Recording" Menu
|
||||||
|
8
Makefile
@ -21,6 +21,7 @@ LIBDIR = $(call PKGCFG,libdir)
|
|||||||
LOCDIR = $(call PKGCFG,locdir)
|
LOCDIR = $(call PKGCFG,locdir)
|
||||||
PLGCFG = $(call PKGCFG,plgcfg)
|
PLGCFG = $(call PKGCFG,plgcfg)
|
||||||
VDRCONFDIR= $(call PKGCFG,configdir)
|
VDRCONFDIR= $(call PKGCFG,configdir)
|
||||||
|
PLGRESDIR = $(call PKGCFG,resdir)/plugins/$(PLUGIN)
|
||||||
TMPDIR ?= /tmp
|
TMPDIR ?= /tmp
|
||||||
|
|
||||||
### The compiler options:
|
### The compiler options:
|
||||||
@ -100,6 +101,7 @@ i18n: $(I18Nmo) $(I18Npot)
|
|||||||
install-i18n: $(I18Nmsgs)
|
install-i18n: $(I18Nmsgs)
|
||||||
|
|
||||||
### Targets:
|
### Targets:
|
||||||
|
|
||||||
$(SOFILE): $(OBJS)
|
$(SOFILE): $(OBJS)
|
||||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
$(CXX) $(CXXFLAGS) $(LDFLAGS) -shared $(OBJS) $(LIBS) -o $@
|
||||||
|
|
||||||
@ -110,7 +112,11 @@ install-themes:
|
|||||||
@mkdir -p $(DESTDIR)$(VDRCONFDIR)/themes
|
@mkdir -p $(DESTDIR)$(VDRCONFDIR)/themes
|
||||||
cp themes/* $(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
|
dist: $(I18Npo) clean
|
||||||
@-rm -rf $(TMPDIR)/$(ARCHIVE)
|
@-rm -rf $(TMPDIR)/$(ARCHIVE)
|
||||||
|
@ -5,6 +5,7 @@ cChannelColumn::cChannelColumn(int num, const cChannel *channel, cMyTime *myTime
|
|||||||
this->num = num;
|
this->num = num;
|
||||||
this->myTime = myTime;
|
this->myTime = myTime;
|
||||||
hasTimer = channel->HasTimer();
|
hasTimer = channel->HasTimer();
|
||||||
|
hasSwitchTimer = SwitchTimers.ChannelInSwitchList(channel);
|
||||||
schedulesLock = new cSchedulesLock(false, 100);
|
schedulesLock = new cSchedulesLock(false, 100);
|
||||||
header = NULL;
|
header = NULL;
|
||||||
}
|
}
|
||||||
@ -339,6 +340,22 @@ cGrid *cChannelColumn::addDummyGrid(time_t start, time_t end, cGrid *firstGrid,
|
|||||||
return dummy;
|
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() {
|
void cChannelColumn::dumpGrids() {
|
||||||
esyslog("tvguide: ------Channel %s: %d entires ---------", channel->Name(), grids.Count());
|
esyslog("tvguide: ------Channel %s: %d entires ---------", channel->Name(), grids.Count());
|
||||||
int i=1;
|
int i=1;
|
||||||
|
@ -16,6 +16,7 @@ private:
|
|||||||
cSchedulesLock *schedulesLock;
|
cSchedulesLock *schedulesLock;
|
||||||
const cSchedules *schedules;
|
const cSchedules *schedules;
|
||||||
bool hasTimer;
|
bool hasTimer;
|
||||||
|
bool hasSwitchTimer;
|
||||||
cGrid *addEpgGrid(const cEvent *event, cGrid *firstGrid, bool color);
|
cGrid *addEpgGrid(const cEvent *event, cGrid *firstGrid, bool color);
|
||||||
cGrid *addDummyGrid(time_t start, time_t end, cGrid *firstGrid, bool color);
|
cGrid *addDummyGrid(time_t start, time_t end, cGrid *firstGrid, bool color);
|
||||||
public:
|
public:
|
||||||
@ -42,8 +43,11 @@ public:
|
|||||||
void ClearOutdatedEnd();
|
void ClearOutdatedEnd();
|
||||||
int GetNum() {return num;};
|
int GetNum() {return num;};
|
||||||
void SetNum(int num) {this->num = num;};
|
void SetNum(int num) {this->num = num;};
|
||||||
void setTimer() {hasTimer = true;};
|
void setTimer() {hasTimer = channel->HasTimer();};
|
||||||
bool HasTimer() { return hasTimer; };
|
bool HasTimer() { return hasTimer; };
|
||||||
|
void setSwitchTimer() {hasSwitchTimer = SwitchTimers.ChannelInSwitchList(channel);};
|
||||||
|
bool HasSwitchTimer() { return hasSwitchTimer; };
|
||||||
|
void SetTimers();
|
||||||
void clearGrids();
|
void clearGrids();
|
||||||
void dumpGrids();
|
void dumpGrids();
|
||||||
};
|
};
|
||||||
|
18
config.c
@ -81,6 +81,8 @@ cTvguideConfig::cTvguideConfig() {
|
|||||||
FontGridHorizontalSmallDelta = 0;
|
FontGridHorizontalSmallDelta = 0;
|
||||||
FontTimeLineDateHorizontalDelta = 0;
|
FontTimeLineDateHorizontalDelta = 0;
|
||||||
FontTimeLineTimeHorizontalDelta = 0;
|
FontTimeLineTimeHorizontalDelta = 0;
|
||||||
|
FontRecMenuItemDelta = 0;
|
||||||
|
FontRecMenuItemSmallDelta = 0;
|
||||||
//Common Fonts
|
//Common Fonts
|
||||||
FontButton = NULL;
|
FontButton = NULL;
|
||||||
FontDetailView = NULL;
|
FontDetailView = NULL;
|
||||||
@ -102,7 +104,9 @@ cTvguideConfig::cTvguideConfig() {
|
|||||||
FontGridHorizontalSmall = NULL;
|
FontGridHorizontalSmall = NULL;
|
||||||
FontTimeLineDateHorizontal = NULL;
|
FontTimeLineDateHorizontal = NULL;
|
||||||
FontTimeLineTimeHorizontal = NULL;
|
FontTimeLineTimeHorizontal = NULL;
|
||||||
|
//Fonts for RecMenu
|
||||||
|
FontRecMenuItem = NULL;
|
||||||
|
FontRecMenuItemSmall = NULL;
|
||||||
timeFormat = 1;
|
timeFormat = 1;
|
||||||
themeIndex = 4;
|
themeIndex = 4;
|
||||||
useBlending = 2;
|
useBlending = 2;
|
||||||
@ -133,6 +137,8 @@ cTvguideConfig::~cTvguideConfig() {
|
|||||||
delete FontGridHorizontalSmall;
|
delete FontGridHorizontalSmall;
|
||||||
delete FontTimeLineDateHorizontal;
|
delete FontTimeLineDateHorizontal;
|
||||||
delete FontTimeLineTimeHorizontal;
|
delete FontTimeLineTimeHorizontal;
|
||||||
|
delete FontRecMenuItem;
|
||||||
|
delete FontRecMenuItemSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cTvguideConfig::setDynamicValues(int width, int height) {
|
void cTvguideConfig::setDynamicValues(int width, int height) {
|
||||||
@ -207,7 +213,9 @@ void cTvguideConfig::SetFonts(void){
|
|||||||
FontGridHorizontalSmall = cFont::CreateFont(*fontname, rowHeight/4 + FontGridHorizontalSmallDelta);
|
FontGridHorizontalSmall = cFont::CreateFont(*fontname, rowHeight/4 + FontGridHorizontalSmallDelta);
|
||||||
FontTimeLineDateHorizontal = cFont::CreateFont(*fontname, timeLineHeight/2 + 5 + FontTimeLineDateHorizontalDelta);
|
FontTimeLineDateHorizontal = cFont::CreateFont(*fontname, timeLineHeight/2 + 5 + FontTimeLineDateHorizontalDelta);
|
||||||
FontTimeLineTimeHorizontal = cFont::CreateFont(*fontname, timeLineHeight/2 + FontTimeLineTimeHorizontalDelta);
|
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) {
|
void cTvguideConfig::SetBlending(void) {
|
||||||
@ -228,6 +236,10 @@ void cTvguideConfig::SetImagesPath(cString path) {
|
|||||||
epgImagePath = path;
|
epgImagePath = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cTvguideConfig::SetIconsPath(cString path) {
|
||||||
|
iconPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
void cTvguideConfig::loadTheme() {
|
void cTvguideConfig::loadTheme() {
|
||||||
cThemes themes;
|
cThemes themes;
|
||||||
themes.Load(*cString("tvguide"));
|
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, "FontGridHorizontalSmallDelta") == 0) FontGridHorizontalSmallDelta = atoi(Value);
|
||||||
else if (strcmp(Name, "FontTimeLineDateHorizontalDelta") == 0) FontTimeLineDateHorizontalDelta = atoi(Value);
|
else if (strcmp(Name, "FontTimeLineDateHorizontalDelta") == 0) FontTimeLineDateHorizontalDelta = atoi(Value);
|
||||||
else if (strcmp(Name, "FontTimeLineTimeHorizontalDelta") == 0) FontTimeLineTimeHorizontalDelta = 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, "displayRerunsDetailEPGView") == 0) displayRerunsDetailEPGView = atoi(Value);
|
||||||
else if (strcmp(Name, "numReruns") == 0) numReruns = atoi(Value);
|
else if (strcmp(Name, "numReruns") == 0) numReruns = atoi(Value);
|
||||||
else if (strcmp(Name, "useSubtitleRerun") == 0) useSubtitleRerun = atoi(Value);
|
else if (strcmp(Name, "useSubtitleRerun") == 0) useSubtitleRerun = atoi(Value);
|
||||||
|
6
config.h
@ -10,6 +10,7 @@ class cTvguideConfig {
|
|||||||
~cTvguideConfig();
|
~cTvguideConfig();
|
||||||
void SetLogoPath(cString path);
|
void SetLogoPath(cString path);
|
||||||
void SetImagesPath(cString path);
|
void SetImagesPath(cString path);
|
||||||
|
void SetIconsPath(cString path);
|
||||||
void SetBlending(void);
|
void SetBlending(void);
|
||||||
int showMainMenuEntry;
|
int showMainMenuEntry;
|
||||||
int osdWidth;
|
int osdWidth;
|
||||||
@ -61,6 +62,7 @@ class cTvguideConfig {
|
|||||||
int epgImageWidthLarge;
|
int epgImageWidthLarge;
|
||||||
int epgImageHeightLarge;
|
int epgImageHeightLarge;
|
||||||
cString epgImagePath;
|
cString epgImagePath;
|
||||||
|
cString iconPath;
|
||||||
int fontIndex;
|
int fontIndex;
|
||||||
const char *fontNameDefault;
|
const char *fontNameDefault;
|
||||||
int FontButtonDelta;
|
int FontButtonDelta;
|
||||||
@ -83,6 +85,8 @@ class cTvguideConfig {
|
|||||||
int FontGridHorizontalSmallDelta;
|
int FontGridHorizontalSmallDelta;
|
||||||
int FontTimeLineDateHorizontalDelta;
|
int FontTimeLineDateHorizontalDelta;
|
||||||
int FontTimeLineTimeHorizontalDelta;
|
int FontTimeLineTimeHorizontalDelta;
|
||||||
|
int FontRecMenuItemDelta;
|
||||||
|
int FontRecMenuItemSmallDelta;
|
||||||
const cFont *FontChannelHeader;
|
const cFont *FontChannelHeader;
|
||||||
const cFont *FontChannelHeaderHorizontal;
|
const cFont *FontChannelHeaderHorizontal;
|
||||||
const cFont *FontChannelGroups;
|
const cFont *FontChannelGroups;
|
||||||
@ -103,6 +107,8 @@ class cTvguideConfig {
|
|||||||
const cFont *FontDetailHeader;
|
const cFont *FontDetailHeader;
|
||||||
const cFont *FontMessageBox;
|
const cFont *FontMessageBox;
|
||||||
const cFont *FontMessageBoxLarge;
|
const cFont *FontMessageBoxLarge;
|
||||||
|
const cFont *FontRecMenuItem;
|
||||||
|
const cFont *FontRecMenuItemSmall;
|
||||||
int timeFormat;
|
int timeFormat;
|
||||||
int themeIndex;
|
int themeIndex;
|
||||||
int useBlending;
|
int useBlending;
|
||||||
|
51
detailview.c
@ -2,12 +2,9 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "detailview.h"
|
#include "detailview.h"
|
||||||
|
|
||||||
cDetailView::cDetailView(cGrid *grid) {
|
cDetailView::cDetailView(const cEvent *event) {
|
||||||
this->grid = grid;
|
this->event = event;
|
||||||
this->event = grid->GetEvent();
|
|
||||||
imgScrollBar = NULL;
|
imgScrollBar = NULL;
|
||||||
FrameTime = 40; // ms
|
|
||||||
FadeTime = 500; // ms
|
|
||||||
borderWidth = 100; //px
|
borderWidth = 100; //px
|
||||||
scrollBarWidth = 40;
|
scrollBarWidth = 40;
|
||||||
headerHeight = max (40 + 3 * tvguideConfig.FontDetailHeader->Height(), // border + 3 Lines
|
headerHeight = max (40 + 3 * tvguideConfig.FontDetailHeader->Height(), // border + 3 Lines
|
||||||
@ -48,24 +45,18 @@ bool cDetailView::setContentDrawportHeight() {
|
|||||||
|
|
||||||
void cDetailView::createPixmaps() {
|
void cDetailView::createPixmaps() {
|
||||||
header = new cStyledPixmap(osdManager.requestPixmap(5, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null));
|
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 = osdManager.requestPixmap(6, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null);
|
||||||
headerLogo->Fill(clrTransparent);
|
headerLogo->Fill(clrTransparent);
|
||||||
headerLogo->SetAlpha(0);
|
|
||||||
headerBack = osdManager.requestPixmap(4, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null);
|
headerBack = osdManager.requestPixmap(4, cRect(borderWidth, borderWidth, tvguideConfig.osdWidth - 2*borderWidth, headerHeight), cRect::Null);
|
||||||
headerBack->SetAlpha(0);
|
|
||||||
headerBack->Fill(clrBlack);
|
headerBack->Fill(clrBlack);
|
||||||
header->setColor(theme.Color(clrHeader), theme.Color(clrHeaderBlending));
|
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),
|
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)));
|
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));
|
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 = 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 = osdManager.requestPixmap(5, cRect(borderWidth, borderWidth + headerHeight + content->ViewPort().Height(), tvguideConfig.osdWidth - 2*borderWidth, 3));
|
||||||
footer->SetAlpha(0);
|
|
||||||
footer->Fill(theme.Color(clrBorder));
|
footer->Fill(theme.Color(clrBorder));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +70,8 @@ void cDetailView::drawHeader() {
|
|||||||
cImageLoader imgLoader;
|
cImageLoader imgLoader;
|
||||||
bool logoDrawn = false;
|
bool logoDrawn = false;
|
||||||
if (!tvguideConfig.hideChannelLogos) {
|
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();
|
cImage logo = imgLoader.GetImage();
|
||||||
headerLogo->DrawImage(cPoint(10, (header->Height() - logoHeight)/2), logo);
|
headerLogo->DrawImage(cPoint(10, (header->Height() - logoHeight)/2), logo);
|
||||||
logoDrawn = true;
|
logoDrawn = true;
|
||||||
@ -293,28 +285,21 @@ void cDetailView::drawEPGPictures(int height) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cDetailView::Action(void) {
|
eOSState cDetailView::ProcessKey(eKeys Key) {
|
||||||
drawHeader();
|
eOSState state = osContinue;
|
||||||
drawContent();
|
switch (Key & ~k_Repeat) {
|
||||||
drawScrollbar();
|
case kUp:
|
||||||
uint64_t Start = cTimeMs::Now();
|
scrollUp();
|
||||||
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();
|
osdManager.flush();
|
||||||
cPixmap::Unlock();
|
break;
|
||||||
int Delta = cTimeMs::Now() - Now;
|
case kDown:
|
||||||
if (Delta < FrameTime)
|
scrollDown();
|
||||||
cCondWait::SleepMs(FrameTime - Delta);
|
osdManager.flush();
|
||||||
if ((Now - Start) > FadeTime)
|
break;
|
||||||
|
case kOk:
|
||||||
|
case kBack:
|
||||||
|
state = osEnd;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
return state;
|
||||||
}
|
}
|
15
detailview.h
@ -5,9 +5,8 @@
|
|||||||
|
|
||||||
class cEpgGrid;
|
class cEpgGrid;
|
||||||
|
|
||||||
class cDetailView : public cThread {
|
class cDetailView {
|
||||||
private:
|
private:
|
||||||
cGrid *grid;
|
|
||||||
cStyledPixmap *header;
|
cStyledPixmap *header;
|
||||||
cPixmap *headerLogo;
|
cPixmap *headerLogo;
|
||||||
cPixmap *headerBack;
|
cPixmap *headerBack;
|
||||||
@ -16,8 +15,6 @@ private:
|
|||||||
cPixmap *footer;
|
cPixmap *footer;
|
||||||
const cEvent *event;
|
const cEvent *event;
|
||||||
cImage *imgScrollBar;
|
cImage *imgScrollBar;
|
||||||
int FrameTime;
|
|
||||||
int FadeTime;
|
|
||||||
cTextWrapper description;
|
cTextWrapper description;
|
||||||
cTextWrapper reruns;
|
cTextWrapper reruns;
|
||||||
int borderWidth;
|
int borderWidth;
|
||||||
@ -29,19 +26,19 @@ private:
|
|||||||
int numEPGPics;
|
int numEPGPics;
|
||||||
bool contentScrollable;
|
bool contentScrollable;
|
||||||
void loadReruns(void);
|
void loadReruns(void);
|
||||||
void drawHeader();
|
|
||||||
void drawContent();
|
|
||||||
void drawScrollbar();
|
|
||||||
int heightEPGPics(void);
|
int heightEPGPics(void);
|
||||||
void drawEPGPictures(int height);
|
void drawEPGPictures(int height);
|
||||||
cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend);
|
cImage *createScrollbar(int width, int height, tColor clrBgr, tColor clrBlend);
|
||||||
virtual void Action(void);
|
|
||||||
public:
|
public:
|
||||||
cDetailView(cGrid *grid);
|
cDetailView(const cEvent *event);
|
||||||
virtual ~cDetailView(void);
|
virtual ~cDetailView(void);
|
||||||
void createPixmaps();
|
void createPixmaps();
|
||||||
|
void drawHeader();
|
||||||
|
void drawContent();
|
||||||
|
void drawScrollbar();
|
||||||
void scrollUp();
|
void scrollUp();
|
||||||
void scrollDown();
|
void scrollDown();
|
||||||
|
eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__TVGUIDE_DETAILVIEW_H
|
#endif //__TVGUIDE_DETAILVIEW_H
|
@ -5,6 +5,7 @@ cDummyGrid::cDummyGrid(cChannelColumn *c, time_t start, time_t end) : cGrid(c) {
|
|||||||
this->end = end;
|
this->end = end;
|
||||||
strText = tr("No EPG Information available");
|
strText = tr("No EPG Information available");
|
||||||
dummy = true;
|
dummy = true;
|
||||||
|
hasTimer = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cDummyGrid::~cDummyGrid(void) {
|
cDummyGrid::~cDummyGrid(void) {
|
||||||
|
24
epggrid.c
@ -7,6 +7,9 @@ cEpgGrid::cEpgGrid(cChannelColumn *c, const cEvent *event) : cGrid(c) {
|
|||||||
hasTimer = false;
|
hasTimer = false;
|
||||||
if (column->HasTimer())
|
if (column->HasTimer())
|
||||||
hasTimer = event->HasTimer();
|
hasTimer = event->HasTimer();
|
||||||
|
hasSwitchTimer = false;
|
||||||
|
if (column->HasSwitchTimer())
|
||||||
|
hasSwitchTimer = SwitchTimers.EventInSwitchList(event);
|
||||||
dummy = false;
|
dummy = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,8 +92,6 @@ void cEpgGrid::drawText() {
|
|||||||
pixmap->DrawText(cPoint(borderWidth, borderWidth + offset + i*textHeight), extText->GetLine(i), colorText, colorTextBack, tvguideConfig.FontGridSmall);
|
pixmap->DrawText(cPoint(borderWidth, borderWidth + offset + i*textHeight), extText->GetLine(i), colorText, colorTextBack, tvguideConfig.FontGridSmall);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hasTimer)
|
|
||||||
drawRecIcon();
|
|
||||||
} else if (tvguideConfig.displayMode == eHorizontal) {
|
} else if (tvguideConfig.displayMode == eHorizontal) {
|
||||||
if (Width()/tvguideConfig.minutePixel < 10) {
|
if (Width()/tvguideConfig.minutePixel < 10) {
|
||||||
int titleY = (tvguideConfig.rowHeight - tvguideConfig.FontGridHorizontal->Height())/2;
|
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);
|
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() {
|
void cEpgGrid::drawIcon(cString iconText, tColor color) {
|
||||||
cString recIconText("REC");
|
|
||||||
int width = tvguideConfig.FontGrid->Width(*recIconText)+2*borderWidth;
|
const cFont *font = (tvguideConfig.displayMode == eVertical)
|
||||||
int height = tvguideConfig.FontGrid->Height()+10;
|
?tvguideConfig.FontGrid
|
||||||
pixmap->DrawRectangle( cRect(Width() - width - borderWidth, Height() - height - borderWidth, width, height), theme.Color(clrButtonRed));
|
:tvguideConfig.FontGridHorizontalSmall;
|
||||||
pixmap->DrawText(cPoint(Width() - width, Height() - height - borderWidth/2), *recIconText, theme.Color(clrFont), theme.Color(clrButtonRed), tvguideConfig.FontGrid);
|
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) {
|
cString cEpgGrid::getTimeString(void) {
|
||||||
|
@ -8,9 +8,8 @@ private:
|
|||||||
const cEvent *event;
|
const cEvent *event;
|
||||||
cTextWrapper *extText;
|
cTextWrapper *extText;
|
||||||
cString timeString;
|
cString timeString;
|
||||||
bool hasTimer;
|
|
||||||
void drawText();
|
void drawText();
|
||||||
void drawRecIcon();
|
void drawIcon(cString iconText, tColor color);
|
||||||
time_t Duration(void) { return event->Duration(); };
|
time_t Duration(void) { return event->Duration(); };
|
||||||
public:
|
public:
|
||||||
cEpgGrid(cChannelColumn *c, const cEvent *event);
|
cEpgGrid(cChannelColumn *c, const cEvent *event);
|
||||||
@ -21,7 +20,8 @@ public:
|
|||||||
const cEvent *GetEvent() {return event;};
|
const cEvent *GetEvent() {return event;};
|
||||||
time_t StartTime() { return event->StartTime(); };
|
time_t StartTime() { return event->StartTime(); };
|
||||||
time_t EndTime() { return event->EndTime(); };
|
time_t EndTime() { return event->EndTime(); };
|
||||||
void setTimer() {hasTimer = true;};
|
void SetTimer() {hasTimer = event->HasTimer();};
|
||||||
|
void SetSwitchTimer() {hasSwitchTimer = SwitchTimers.EventInSwitchList(event);};
|
||||||
cString getTimeString(void);
|
cString getTimeString(void);
|
||||||
void debug();
|
void debug();
|
||||||
};
|
};
|
||||||
|
2
footer.c
@ -38,7 +38,7 @@ void cFooter::DrawButton(const char *text, tColor color, tColor borderColor, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cFooter::drawRedButton() {
|
void cFooter::drawRedButton() {
|
||||||
cString text(tr("Set Timer"));
|
cString text(tr("Search & Rec"));
|
||||||
DrawButton(*text, theme.Color(clrButtonRed), theme.Color(clrButtonRedBorder), 0);
|
DrawButton(*text, theme.Color(clrButtonRed), theme.Color(clrButtonRedBorder), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
7
grid.h
@ -12,6 +12,8 @@ protected:
|
|||||||
bool isColor1;
|
bool isColor1;
|
||||||
bool active;
|
bool active;
|
||||||
bool dirty;
|
bool dirty;
|
||||||
|
bool hasTimer;
|
||||||
|
bool hasSwitchTimer;
|
||||||
bool intersects(cGrid *neighbor);
|
bool intersects(cGrid *neighbor);
|
||||||
virtual time_t Duration(void) {};
|
virtual time_t Duration(void) {};
|
||||||
virtual void drawText(void) {};
|
virtual void drawText(void) {};
|
||||||
@ -37,10 +39,13 @@ public:
|
|||||||
virtual void SetStartTime(time_t start) {};
|
virtual void SetStartTime(time_t start) {};
|
||||||
virtual void SetEndTime(time_t end) {};
|
virtual void SetEndTime(time_t end) {};
|
||||||
int calcOverlap(cGrid *neighbor);
|
int calcOverlap(cGrid *neighbor);
|
||||||
virtual void setTimer() {};
|
virtual void SetTimer() {};
|
||||||
|
virtual void SetSwitchTimer() {};
|
||||||
virtual cString getText(void) { return cString("");};
|
virtual cString getText(void) { return cString("");};
|
||||||
virtual cString getTimeString(void) { return cString("");};
|
virtual cString getTimeString(void) { return cString("");};
|
||||||
bool Active(void) { return active; };
|
bool Active(void) { return active; };
|
||||||
|
bool HasTimer() {return hasTimer;};
|
||||||
|
bool HasSwitchTimer() {return hasSwitchTimer;};
|
||||||
bool isDummy() { return dummy; };
|
bool isDummy() { return dummy; };
|
||||||
virtual void debug() {};
|
virtual void debug() {};
|
||||||
};
|
};
|
||||||
|
@ -24,8 +24,8 @@ void cHeaderGrid::createBackground(int num) {
|
|||||||
width = tvguideConfig.channelHeaderWidth;
|
width = tvguideConfig.channelHeaderWidth;
|
||||||
height = tvguideConfig.rowHeight;
|
height = tvguideConfig.rowHeight;
|
||||||
}
|
}
|
||||||
pixmap = osdManager.requestPixmap(2, cRect(x, y, width, height));
|
pixmap = osdManager.requestPixmap(1, cRect(x, y, width, height));
|
||||||
pixmapLogo = osdManager.requestPixmap(3, cRect(x, y, width, height));
|
pixmapLogo = osdManager.requestPixmap(2, cRect(x, y, width, height));
|
||||||
if ((!pixmap) || (!pixmapLogo)){
|
if ((!pixmap) || (!pixmapLogo)){
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
BIN
icons/arrow_left.png
Normal file
After Width: | Height: | Size: 428 B |
BIN
icons/arrow_right.png
Normal file
After Width: | Height: | Size: 438 B |
BIN
icons/delete_active.png
Normal file
After Width: | Height: | Size: 57 KiB |
BIN
icons/delete_inactive.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
icons/edit_active.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
icons/edit_inactive.png
Normal file
After Width: | Height: | Size: 52 KiB |
BIN
icons/icon_backspace.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
icons/icon_del_ins.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
icons/icon_shift.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
icons/info_active.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
icons/info_inactive.png
Normal file
After Width: | Height: | Size: 8.8 KiB |
BIN
icons/no.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
icons/record_active.png
Normal file
After Width: | Height: | Size: 6.9 KiB |
BIN
icons/record_inactive.png
Normal file
After Width: | Height: | Size: 5.8 KiB |
BIN
icons/yes.png
Normal file
After Width: | Height: | Size: 35 KiB |
@ -59,8 +59,19 @@ bool cImageLoader::LoadAdditionalEPGImage(cString name) {
|
|||||||
return true;
|
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) {
|
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;
|
return false;
|
||||||
Color Back = Argb2Color(back);
|
Color Back = Argb2Color(back);
|
||||||
Color Blend = Argb2Color(blend);
|
Color Blend = Argb2Color(blend);
|
||||||
|
@ -17,6 +17,7 @@ public:
|
|||||||
bool LoadLogo(const char *logo, int width, int height);
|
bool LoadLogo(const char *logo, int width, int height);
|
||||||
bool LoadEPGImage(int eventID);
|
bool LoadEPGImage(int eventID);
|
||||||
bool LoadAdditionalEPGImage(cString name);
|
bool LoadAdditionalEPGImage(cString name);
|
||||||
|
bool LoadIcon(const char *cIcon, int size);
|
||||||
bool DrawBackground(tColor back, tColor blend, int width, int height);
|
bool DrawBackground(tColor back, tColor blend, int width, int height);
|
||||||
private:
|
private:
|
||||||
Image buffer;
|
Image buffer;
|
||||||
|
31
osdmanager.c
@ -1,6 +1,3 @@
|
|||||||
#include <string>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
#ifndef __TVGUIDE_OSDMANAGER_H
|
#ifndef __TVGUIDE_OSDMANAGER_H
|
||||||
#define __TVGUIDE_OSDMANAGER_H
|
#define __TVGUIDE_OSDMANAGER_H
|
||||||
|
|
||||||
@ -56,31 +53,3 @@ void cOsdManager::releasePixmap(cPixmap *pixmap) {
|
|||||||
return;
|
return;
|
||||||
osd->DestroyPixmap(pixmap);
|
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;
|
|
||||||
}
|
|
344
po/de_DE.po
@ -3,7 +3,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: vdr-tvguide 0.0.1\n"
|
"Project-Id-Version: vdr-tvguide 0.0.1\n"
|
||||||
"Report-Msgid-Bugs-To: <see README>\n"
|
"Report-Msgid-Bugs-To: <see README>\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"
|
"PO-Revision-Date: 2012-08-25 17:49+0200\n"
|
||||||
"Last-Translator: Horst\n"
|
"Last-Translator: Horst\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
@ -21,8 +21,8 @@ msgstr "Wiederholungen dieser Sendung"
|
|||||||
msgid "No EPG Information available"
|
msgid "No EPG Information available"
|
||||||
msgstr "Keine EPG Daten verfügbar"
|
msgstr "Keine EPG Daten verfügbar"
|
||||||
|
|
||||||
msgid "Set Timer"
|
msgid "Search & Rec"
|
||||||
msgstr "Aufnehmen"
|
msgstr "Search & Rec"
|
||||||
|
|
||||||
msgid "Channels back"
|
msgid "Channels back"
|
||||||
msgstr "Kanäle zurück"
|
msgstr "Kanäle zurück"
|
||||||
@ -36,6 +36,336 @@ msgstr "Umschalten"
|
|||||||
msgid "Detailed EPG"
|
msgid "Detailed EPG"
|
||||||
msgstr "Detailiertes 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"
|
msgid "General Settings"
|
||||||
msgstr "Allgemeine Einstellungen"
|
msgstr "Allgemeine Einstellungen"
|
||||||
|
|
||||||
@ -234,8 +564,8 @@ msgstr "Zeitleiste Datum Schriftgröße"
|
|||||||
msgid "Timeline Time Font Size"
|
msgid "Timeline Time Font Size"
|
||||||
msgstr "Zeitleiste Zeit Schriftgröße"
|
msgstr "Zeitleiste Zeit Schriftgröße"
|
||||||
|
|
||||||
msgid "Timer not set! There is already a timer for this item."
|
msgid "Search & Recording Menu Font Size"
|
||||||
msgstr "Timer wurde nicht gesetzt! Es existiert bereits ein Timer für diese Sendung"
|
msgstr "Suchen & Aufnehmen Menu Schriftgröße"
|
||||||
|
|
||||||
msgid "Timer set"
|
msgid "Search & Recording Menu Small Font Size"
|
||||||
msgstr "Timer gesetzt"
|
msgstr "Suchen & Aufnehmen Menu kleine Schriftgröße"
|
||||||
|
598
recmanager.c
Normal file
@ -0,0 +1,598 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#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; i<numConflicts; i++) {
|
||||||
|
if (timerIDs[i] == involvedID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cRecManager::cRecManager(void) {
|
||||||
|
epgSearchPlugin = NULL;
|
||||||
|
epgSearchAvailable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cRecManager::~cRecManager(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void cRecManager::SetEPGSearchPlugin(void) {
|
||||||
|
epgSearchPlugin = cPluginManager::GetPlugin("epgsearch");
|
||||||
|
if (epgSearchPlugin) {
|
||||||
|
epgSearchAvailable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cTimer *cRecManager::createTimer(const cEvent *event) {
|
||||||
|
cTimer *timer = new cTimer(event);
|
||||||
|
Timers.Add(timer);
|
||||||
|
Timers.SetModified();
|
||||||
|
isyslog("timer %s added (active)", *timer->ToDescr());
|
||||||
|
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<TVGuideTimerConflict> 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<TVGuideTimerConflict> 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<std::string> conflicts = epgSearch->handler->TimerConflictList();
|
||||||
|
int numConflicts = conflicts.size();
|
||||||
|
if (numConflicts > 0) {
|
||||||
|
for (std::list<std::string>::iterator it=conflicts.begin(); it != conflicts.end(); ++it) {
|
||||||
|
TVGuideTimerConflict sConflict;
|
||||||
|
splitstring s(it->c_str());
|
||||||
|
std::vector<std::string> flds = s.split(':');
|
||||||
|
if (flds.size() < 2)
|
||||||
|
continue;
|
||||||
|
sConflict.time = atoi(flds[0].c_str());
|
||||||
|
splitstring s2(flds[1].c_str());
|
||||||
|
std::vector<std::string> 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<std::string> flds3 = s3.split('#');
|
||||||
|
std::vector<int> 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<TVGuideEPGSearchTemplate> cRecManager::ReadEPGSearchTemplates(void) {
|
||||||
|
cString ConfigDir = cPlugin::ConfigDirectory("epgsearch");
|
||||||
|
cString epgsearchConf = "epgsearchtemplates.conf";
|
||||||
|
cString fileName = AddDirectory(*ConfigDir, *epgsearchConf);
|
||||||
|
std::vector<TVGuideEPGSearchTemplate> 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<std::string> 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<std::string>::iterator it=results.begin(); it != results.end(); ++it) {
|
||||||
|
try {
|
||||||
|
splitstring s(it->c_str());
|
||||||
|
std::vector<std::string> 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<Epgsearch_searchresults_v1_0::cServiceSearchResult> *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;
|
||||||
|
}
|
53
recmanager.h
Normal file
@ -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<int> 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<TVGuideTimerConflict> 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<TVGuideEPGSearchTemplate> 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
|
525
recmenu.c
Normal file
@ -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; i<numSteps; i++) {
|
||||||
|
clr = AlphaBlend(clrBgr, clrBlend, alpha);
|
||||||
|
for (int y = i*stepY; y < (i+1)*stepY; y++) {
|
||||||
|
for (int x=0; x<width; x++) {
|
||||||
|
image->SetPixel(cPoint(x,y), clr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alpha += alphaStep;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return image;
|
||||||
|
}
|
61
recmenu.h
Normal file
@ -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<cRecMenuItem> 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
|
2016
recmenuitem.c
Normal file
465
recmenuitem.h
Normal file
@ -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
|
521
recmenumanager.c
Normal file
@ -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<numConflicts; i++) {
|
||||||
|
if (conflictList[i].timerInvolved(timerID)) {
|
||||||
|
showTimerConflict = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (showTimerConflict > -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;
|
||||||
|
}
|
38
recmenumanager.h
Normal file
@ -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<TVGuideTimerConflict> conflictList;
|
||||||
|
std::vector<TVGuideEPGSearchTemplate> 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
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/* -*- c++ -*-
|
||||||
Copyright (C) 2004-2007 Christian Wieninger
|
Copyright (C) 2004-2013 Christian Wieninger
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
modify it under the terms of the GNU General Public License
|
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
|
#ifndef EPGSEARCHSERVICES_INC
|
||||||
#define 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 <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -59,6 +55,13 @@ struct Epgsearch_exttimeredit_v1_0
|
|||||||
cOsdMenu* pTimerMenu; // pointer to the menu of results
|
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"
|
// Data structure for service "Epgsearch-updatesearchtimers-v1.0"
|
||||||
struct Epgsearch_updatesearchtimers_v1_0
|
struct Epgsearch_updatesearchtimers_v1_0
|
||||||
{
|
{
|
||||||
@ -119,7 +122,7 @@ struct Epgsearch_switchtimer_v1_0
|
|||||||
{
|
{
|
||||||
// in
|
// in
|
||||||
const cEvent* event;
|
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
|
// in/out
|
||||||
int switchMinsBefore;
|
int switchMinsBefore;
|
||||||
int announceOnly;
|
int announceOnly;
|
||||||
@ -164,4 +167,36 @@ struct Epgsearch_services_v1_0
|
|||||||
std::auto_ptr<cServiceHandler> handler;
|
std::auto_ptr<cServiceHandler> handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Data structures for service "Epgsearch-services-v1.1"
|
||||||
|
class cServiceHandler_v1_1 : public cServiceHandler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Get timer conflicts
|
||||||
|
virtual std::list<std::string> 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<cServiceHandler_v1_1> 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<std::string> 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<cServiceHandler_v1_2> handler;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
4
setup.c
@ -102,6 +102,8 @@ void cTvguideSetup::Store(void) {
|
|||||||
SetupStore("FontGridHorizontalSmallDelta", tvguideConfig.FontGridHorizontalSmallDelta);
|
SetupStore("FontGridHorizontalSmallDelta", tvguideConfig.FontGridHorizontalSmallDelta);
|
||||||
SetupStore("FontTimeLineDateHorizontalDelta", tvguideConfig.FontTimeLineDateHorizontalDelta);
|
SetupStore("FontTimeLineDateHorizontalDelta", tvguideConfig.FontTimeLineDateHorizontalDelta);
|
||||||
SetupStore("FontTimeLineTimeHorizontalDelta", tvguideConfig.FontTimeLineTimeHorizontalDelta);
|
SetupStore("FontTimeLineTimeHorizontalDelta", tvguideConfig.FontTimeLineTimeHorizontalDelta);
|
||||||
|
SetupStore("FontRecMenuItemDelta", tvguideConfig.FontRecMenuItemDelta);
|
||||||
|
SetupStore("FontRecMenuItemSmallDelta", tvguideConfig.FontRecMenuItemSmallDelta);
|
||||||
SetupStore("displayRerunsDetailEPGView", tvguideConfig.displayRerunsDetailEPGView);
|
SetupStore("displayRerunsDetailEPGView", tvguideConfig.displayRerunsDetailEPGView);
|
||||||
SetupStore("numReruns", tvguideConfig.numReruns);
|
SetupStore("numReruns", tvguideConfig.numReruns);
|
||||||
SetupStore("useSubtitleRerun", tvguideConfig.useSubtitleRerun);
|
SetupStore("useSubtitleRerun", tvguideConfig.useSubtitleRerun);
|
||||||
@ -302,6 +304,8 @@ void cMenuSetupFont::Set(void) {
|
|||||||
Add(new cMenuEditIntItem(tr("Timeline Time Font Size"), &tmpTvguideConfig->FontTimeLineTimeHorizontalDelta, -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));
|
SetCurrent(Get(currentItem));
|
||||||
Display();
|
Display();
|
||||||
|
@ -132,3 +132,11 @@ void cStyledPixmap::DrawImage(const cPoint &Point, const cImage &Image) {
|
|||||||
void cStyledPixmap::DrawRectangle(const cRect &Rect, tColor Color) {
|
void cStyledPixmap::DrawRectangle(const cRect &Rect, tColor Color) {
|
||||||
pixmap->DrawRectangle(Rect,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);
|
||||||
|
}
|
@ -25,9 +25,12 @@ public:
|
|||||||
void drawRoundedCorners(int width, int height, int radius);
|
void drawRoundedCorners(int width, int height, int radius);
|
||||||
void setColor(tColor color, tColor colorBlending) {this->color = color; this->colorBlending = colorBlending;};
|
void setColor(tColor color, tColor colorBlending) {this->color = color; this->colorBlending = colorBlending;};
|
||||||
void SetAlpha(int alpha) {pixmap->SetAlpha(alpha);};
|
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 DrawText(const cPoint &Point, const char *s, tColor ColorFg, tColor ColorBg, const cFont *Font);
|
||||||
void DrawImage(const cPoint &Point, const cImage &Image);
|
void DrawImage(const cPoint &Point, const cImage &Image);
|
||||||
void DrawRectangle(const cRect &Rect, tColor Color);
|
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 Width() {return pixmap->ViewPort().Width();};
|
||||||
int Height() {return pixmap->ViewPort().Height();};
|
int Height() {return pixmap->ViewPort().Height();};
|
||||||
};
|
};
|
||||||
|
109
switchtimer.c
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
30
switchtimer.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef __TVGUIDE_SWITCHTIMER_H
|
||||||
|
#define __TVGUIDE_SWITCHTIMER_H
|
||||||
|
|
||||||
|
#include <vdr/plugin.h>
|
||||||
|
|
||||||
|
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<cSwitchTimer>, 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
|
@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00
|
|||||||
clrButtonBlue = 990000BB
|
clrButtonBlue = 990000BB
|
||||||
clrButtonBlueBorder = FF0000BB
|
clrButtonBlueBorder = FF0000BB
|
||||||
clrButtonBlend = DD000000
|
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
|
@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00
|
|||||||
clrButtonBlue = 990000BB
|
clrButtonBlue = 990000BB
|
||||||
clrButtonBlueBorder = FF0000BB
|
clrButtonBlueBorder = FF0000BB
|
||||||
clrButtonBlend = DD000000
|
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
|
@ -26,3 +26,15 @@ clrButtonYellowBorder = FFBBBB00
|
|||||||
clrButtonBlue = 990000BB
|
clrButtonBlue = 990000BB
|
||||||
clrButtonBlueBorder = FF0000BB
|
clrButtonBlueBorder = FF0000BB
|
||||||
clrButtonBlend = DD000000
|
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
|
@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00
|
|||||||
clrButtonBlue = 990000BB
|
clrButtonBlue = 990000BB
|
||||||
clrButtonBlueBorder = FF0000BB
|
clrButtonBlueBorder = FF0000BB
|
||||||
clrButtonBlend = DD000000
|
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
|
@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00
|
|||||||
clrButtonBlue = 990000BB
|
clrButtonBlue = 990000BB
|
||||||
clrButtonBlueBorder = FF0000BB
|
clrButtonBlueBorder = FF0000BB
|
||||||
clrButtonBlend = DD000000
|
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
|
@ -30,3 +30,15 @@ clrButtonYellowBorder = FFBBBB00
|
|||||||
clrButtonBlue = 990000BB
|
clrButtonBlue = 990000BB
|
||||||
clrButtonBlueBorder = FF0000BB
|
clrButtonBlueBorder = FF0000BB
|
||||||
clrButtonBlend = DD000000
|
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
|
@ -25,3 +25,18 @@ clrButtonYellow = FFBBBB00
|
|||||||
clrButtonYellowBorder = FFBBBB00
|
clrButtonYellowBorder = FFBBBB00
|
||||||
clrButtonBlue = FF0000BB
|
clrButtonBlue = FF0000BB
|
||||||
clrButtonBlueBorder = 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
|
||||||
|
10
timeline.c
@ -3,11 +3,11 @@
|
|||||||
cTimeLine::cTimeLine(cMyTime *myTime) {
|
cTimeLine::cTimeLine(cMyTime *myTime) {
|
||||||
this->myTime = myTime;
|
this->myTime = myTime;
|
||||||
if (tvguideConfig.displayMode == eVertical) {
|
if (tvguideConfig.displayMode == eVertical) {
|
||||||
dateViewer = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0,
|
dateViewer = new cStyledPixmap(osdManager.requestPixmap(1, cRect(0,
|
||||||
tvguideConfig.statusHeaderHeight,
|
tvguideConfig.statusHeaderHeight,
|
||||||
tvguideConfig.timeLineWidth,
|
tvguideConfig.timeLineWidth,
|
||||||
tvguideConfig.channelHeaderHeight + tvguideConfig.channelGroupsHeight)));
|
tvguideConfig.channelHeaderHeight + tvguideConfig.channelGroupsHeight)));
|
||||||
timeline = osdManager.requestPixmap(2, cRect(0,
|
timeline = osdManager.requestPixmap(1, cRect(0,
|
||||||
tvguideConfig.statusHeaderHeight + tvguideConfig.channelHeaderHeight + tvguideConfig.channelGroupsHeight,
|
tvguideConfig.statusHeaderHeight + tvguideConfig.channelHeaderHeight + tvguideConfig.channelGroupsHeight,
|
||||||
tvguideConfig.timeLineWidth,
|
tvguideConfig.timeLineWidth,
|
||||||
tvguideConfig.osdHeight - tvguideConfig.statusHeaderHeight - tvguideConfig.channelHeaderHeight - tvguideConfig.channelGroupsHeight - tvguideConfig.footerHeight)
|
tvguideConfig.osdHeight - tvguideConfig.statusHeaderHeight - tvguideConfig.channelHeaderHeight - tvguideConfig.channelGroupsHeight - tvguideConfig.footerHeight)
|
||||||
@ -16,11 +16,11 @@ cTimeLine::cTimeLine(cMyTime *myTime) {
|
|||||||
tvguideConfig.timeLineWidth,
|
tvguideConfig.timeLineWidth,
|
||||||
1440*tvguideConfig.minutePixel));
|
1440*tvguideConfig.minutePixel));
|
||||||
} else if (tvguideConfig.displayMode == eHorizontal) {
|
} else if (tvguideConfig.displayMode == eHorizontal) {
|
||||||
dateViewer = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0,
|
dateViewer = new cStyledPixmap(osdManager.requestPixmap(1, cRect(0,
|
||||||
tvguideConfig.statusHeaderHeight,
|
tvguideConfig.statusHeaderHeight,
|
||||||
tvguideConfig.channelHeaderWidth + tvguideConfig.channelGroupsWidth,
|
tvguideConfig.channelHeaderWidth + tvguideConfig.channelGroupsWidth,
|
||||||
tvguideConfig.timeLineHeight)));
|
tvguideConfig.timeLineHeight)));
|
||||||
timeline = osdManager.requestPixmap(2, cRect(tvguideConfig.channelHeaderWidth + tvguideConfig.channelGroupsWidth,
|
timeline = osdManager.requestPixmap(1, cRect(tvguideConfig.channelHeaderWidth + tvguideConfig.channelGroupsWidth,
|
||||||
tvguideConfig.statusHeaderHeight,
|
tvguideConfig.statusHeaderHeight,
|
||||||
tvguideConfig.osdWidth - tvguideConfig.channelHeaderWidth - tvguideConfig.channelGroupsWidth,
|
tvguideConfig.osdWidth - tvguideConfig.channelHeaderWidth - tvguideConfig.channelGroupsWidth,
|
||||||
tvguideConfig.timeLineHeight)
|
tvguideConfig.timeLineHeight)
|
||||||
@ -29,7 +29,7 @@ cTimeLine::cTimeLine(cMyTime *myTime) {
|
|||||||
1440*tvguideConfig.minutePixel,
|
1440*tvguideConfig.minutePixel,
|
||||||
tvguideConfig.timeLineWidth));
|
tvguideConfig.timeLineWidth));
|
||||||
}
|
}
|
||||||
clock = new cStyledPixmap(osdManager.requestPixmap(3, cRect(0,
|
clock = new cStyledPixmap(osdManager.requestPixmap(1, cRect(0,
|
||||||
tvguideConfig.osdHeight- tvguideConfig.footerHeight,
|
tvguideConfig.osdHeight- tvguideConfig.footerHeight,
|
||||||
tvguideConfig.timeLineWidth,
|
tvguideConfig.timeLineWidth,
|
||||||
tvguideConfig.footerHeight-9)));
|
tvguideConfig.footerHeight-9)));
|
||||||
|
46
timer.c
@ -120,3 +120,49 @@ time_t cMyTime::GetRounded() {
|
|||||||
void cMyTime::debug() {
|
void cMyTime::debug() {
|
||||||
esyslog("t: %s, tStart: %s, tEnd: %s", *TimeString(t), *TimeString(tStart), *TimeString(tEnd));
|
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);
|
||||||
|
}
|
15
timer.h
@ -30,4 +30,19 @@ class cMyTime {
|
|||||||
void debug();
|
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
|
#endif //__TVGUIDE_TIMER_H
|
370
tools.c
Normal file
@ -0,0 +1,370 @@
|
|||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
/****************************************************************************************
|
||||||
|
* 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<std::string> flds;
|
||||||
|
public:
|
||||||
|
splitstring(const char *s) : std::string(s) { };
|
||||||
|
std::vector<std::string>& 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<std::string>& 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 <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
12
tvguide.c
@ -11,6 +11,7 @@
|
|||||||
#include <vdr/osd.h>
|
#include <vdr/osd.h>
|
||||||
#include <vdr/plugin.h>
|
#include <vdr/plugin.h>
|
||||||
#include <vdr/device.h>
|
#include <vdr/device.h>
|
||||||
|
#include <vdr/menu.h>
|
||||||
|
|
||||||
#include "tvguideosd.c"
|
#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 *DESCRIPTION = "A fancy 2d EPG Viewer";
|
||||||
static const char *MAINMENUENTRY = "Tvguide";
|
static const char *MAINMENUENTRY = "Tvguide";
|
||||||
|
|
||||||
@ -28,6 +29,7 @@ class cPluginTvguide : public cPlugin {
|
|||||||
private:
|
private:
|
||||||
bool logoPathSet;
|
bool logoPathSet;
|
||||||
bool imagesPathSet;
|
bool imagesPathSet;
|
||||||
|
bool iconsPathSet;
|
||||||
public:
|
public:
|
||||||
cPluginTvguide(void);
|
cPluginTvguide(void);
|
||||||
virtual ~cPluginTvguide();
|
virtual ~cPluginTvguide();
|
||||||
@ -58,6 +60,7 @@ cPluginTvguide::cPluginTvguide(void)
|
|||||||
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
|
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
|
||||||
logoPathSet = false;
|
logoPathSet = false;
|
||||||
imagesPathSet = false;
|
imagesPathSet = false;
|
||||||
|
iconsPathSet = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
cPluginTvguide::~cPluginTvguide()
|
cPluginTvguide::~cPluginTvguide()
|
||||||
@ -124,6 +127,13 @@ bool cPluginTvguide::Start(void)
|
|||||||
tvguideConfig.SetImagesPath(path);
|
tvguideConfig.SetImagesPath(path);
|
||||||
logoPathSet = true;
|
logoPathSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!iconsPathSet) {
|
||||||
|
cString path = cString::sprintf("%s/icons/", cPlugin::ConfigDirectory(PLUGIN_NAME_I18N));
|
||||||
|
tvguideConfig.SetIconsPath(path);
|
||||||
|
iconsPathSet = true;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
110
tvguideosd.c
@ -37,6 +37,21 @@ THEME_CLR(theme, clrButtonYellowBorder, 0xFFBBBB00);
|
|||||||
THEME_CLR(theme, clrButtonBlue, 0x990000BB);
|
THEME_CLR(theme, clrButtonBlue, 0x990000BB);
|
||||||
THEME_CLR(theme, clrButtonBlueBorder, 0xFF0000BB);
|
THEME_CLR(theme, clrButtonBlueBorder, 0xFF0000BB);
|
||||||
THEME_CLR(theme, clrButtonBlend, 0xDD000000);
|
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"
|
#include "config.c"
|
||||||
cTvguideConfig tvguideConfig;
|
cTvguideConfig tvguideConfig;
|
||||||
@ -44,11 +59,12 @@ cTvguideConfig tvguideConfig;
|
|||||||
#include "osdmanager.c"
|
#include "osdmanager.c"
|
||||||
cOsdManager osdManager;
|
cOsdManager osdManager;
|
||||||
|
|
||||||
|
#include "tools.c"
|
||||||
|
#include "switchtimer.c"
|
||||||
#include "setup.c"
|
#include "setup.c"
|
||||||
#include "imageloader.c"
|
#include "imageloader.c"
|
||||||
#include "styledpixmap.c"
|
#include "styledpixmap.c"
|
||||||
#include "timer.c"
|
#include "timer.c"
|
||||||
#include "messagebox.c"
|
|
||||||
#include "timeline.c"
|
#include "timeline.c"
|
||||||
#include "grid.c"
|
#include "grid.c"
|
||||||
#include "headergrid.c"
|
#include "headergrid.c"
|
||||||
@ -60,6 +76,11 @@ cOsdManager osdManager;
|
|||||||
#include "channelgroup.c"
|
#include "channelgroup.c"
|
||||||
#include "channelgroups.c"
|
#include "channelgroups.c"
|
||||||
#include "footer.c"
|
#include "footer.c"
|
||||||
|
#include "recmenuitem.c"
|
||||||
|
#include "recmenu.c"
|
||||||
|
#include "recmanager.c"
|
||||||
|
#include "recmenus.c"
|
||||||
|
#include "recmenumanager.c"
|
||||||
|
|
||||||
#include "tvguideosd.h"
|
#include "tvguideosd.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -69,6 +90,7 @@ cTvGuideOsd::cTvGuideOsd(void) {
|
|||||||
detailViewActive = false;
|
detailViewActive = false;
|
||||||
activeGrid = NULL;
|
activeGrid = NULL;
|
||||||
timeLine = NULL;
|
timeLine = NULL;
|
||||||
|
recMenuManager = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cTvGuideOsd::~cTvGuideOsd() {
|
cTvGuideOsd::~cTvGuideOsd() {
|
||||||
@ -82,7 +104,7 @@ cTvGuideOsd::~cTvGuideOsd() {
|
|||||||
delete timeLine;
|
delete timeLine;
|
||||||
delete channelGroups;
|
delete channelGroups;
|
||||||
delete footer;
|
delete footer;
|
||||||
cMessageBox::Destroy();
|
delete recMenuManager;
|
||||||
osdManager.deleteOsd();
|
osdManager.deleteOsd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,6 +119,12 @@ void cTvGuideOsd::Show(void) {
|
|||||||
osdManager.setBackground();
|
osdManager.setBackground();
|
||||||
myTime = new cMyTime();
|
myTime = new cMyTime();
|
||||||
myTime->Now();
|
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();
|
drawOsd();
|
||||||
}
|
}
|
||||||
esyslog("tvguide: Rendering took %d ms", int(cTimeMs::Now()-start));
|
esyslog("tvguide: Rendering took %d ms", int(cTimeMs::Now()-start));
|
||||||
@ -392,37 +420,25 @@ void cTvGuideOsd::processKeyUp() {
|
|||||||
if (!activeGrid) {
|
if (!activeGrid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (detailViewActive) {
|
|
||||||
detailView->scrollUp();
|
|
||||||
osdManager.flush();
|
|
||||||
} else {
|
|
||||||
if (tvguideConfig.displayMode == eVertical) {
|
if (tvguideConfig.displayMode == eVertical) {
|
||||||
timeBack();
|
timeBack();
|
||||||
} else if (tvguideConfig.displayMode == eHorizontal) {
|
} else if (tvguideConfig.displayMode == eHorizontal) {
|
||||||
channelBack();
|
channelBack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void cTvGuideOsd::processKeyDown() {
|
void cTvGuideOsd::processKeyDown() {
|
||||||
if (!activeGrid) {
|
if (!activeGrid) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (detailViewActive) {
|
|
||||||
detailView->scrollDown();
|
|
||||||
osdManager.flush();
|
|
||||||
} else {
|
|
||||||
if (tvguideConfig.displayMode == eVertical) {
|
if (tvguideConfig.displayMode == eVertical) {
|
||||||
timeForward();
|
timeForward();
|
||||||
} else if (tvguideConfig.displayMode == eHorizontal) {
|
} else if (tvguideConfig.displayMode == eHorizontal) {
|
||||||
channelForward();
|
channelForward();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void cTvGuideOsd::processKeyLeft() {
|
void cTvGuideOsd::processKeyLeft() {
|
||||||
if (detailViewActive)
|
|
||||||
return;
|
|
||||||
if (activeGrid == NULL)
|
if (activeGrid == NULL)
|
||||||
return;
|
return;
|
||||||
if (tvguideConfig.displayMode == eVertical) {
|
if (tvguideConfig.displayMode == eVertical) {
|
||||||
@ -433,8 +449,6 @@ void cTvGuideOsd::processKeyLeft() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cTvGuideOsd::processKeyRight() {
|
void cTvGuideOsd::processKeyRight() {
|
||||||
if (detailViewActive)
|
|
||||||
return;
|
|
||||||
if (activeGrid == NULL)
|
if (activeGrid == NULL)
|
||||||
return;
|
return;
|
||||||
if (tvguideConfig.displayMode == eVertical) {
|
if (tvguideConfig.displayMode == eVertical) {
|
||||||
@ -447,26 +461,7 @@ void cTvGuideOsd::processKeyRight() {
|
|||||||
void cTvGuideOsd::processKeyRed() {
|
void cTvGuideOsd::processKeyRed() {
|
||||||
if ((activeGrid == NULL) || activeGrid->isDummy())
|
if ((activeGrid == NULL) || activeGrid->isDummy())
|
||||||
return;
|
return;
|
||||||
cTimer *timer = new cTimer(activeGrid->GetEvent());
|
recMenuManager->Start(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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cTvGuideOsd::processKeyGreen() {
|
void cTvGuideOsd::processKeyGreen() {
|
||||||
@ -547,7 +542,7 @@ eOSState cTvGuideOsd::processKeyBlue() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
eOSState cTvGuideOsd::processKeyOk() {
|
eOSState cTvGuideOsd::processKeyOk() {
|
||||||
if ((tvguideConfig.blueKeyMode == 0) || detailViewActive ) {
|
if (tvguideConfig.blueKeyMode == 0) {
|
||||||
DetailedEPG();
|
DetailedEPG();
|
||||||
} else if (tvguideConfig.blueKeyMode == 1) {
|
} else if (tvguideConfig.blueKeyMode == 1) {
|
||||||
return ChannelSwitch();
|
return ChannelSwitch();
|
||||||
@ -567,17 +562,13 @@ eOSState cTvGuideOsd::ChannelSwitch() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void cTvGuideOsd::DetailedEPG() {
|
void cTvGuideOsd::DetailedEPG() {
|
||||||
if (detailViewActive) {
|
|
||||||
delete detailView;
|
|
||||||
detailView = NULL;
|
|
||||||
detailViewActive = false;
|
|
||||||
osdManager.flush();
|
|
||||||
} else {
|
|
||||||
if (!activeGrid->isDummy()) {
|
if (!activeGrid->isDummy()) {
|
||||||
detailViewActive = true;
|
detailViewActive = true;
|
||||||
detailView = new cDetailView(activeGrid);
|
detailView = new cDetailView(activeGrid->GetEvent());
|
||||||
detailView->Start();
|
detailView->drawHeader();
|
||||||
}
|
detailView->drawContent();
|
||||||
|
detailView->drawScrollbar();
|
||||||
|
osdManager.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,11 +637,32 @@ void cTvGuideOsd::processKey9() {
|
|||||||
osdManager.flush();
|
osdManager.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cTvGuideOsd::SetTimers() {
|
||||||
|
for (cChannelColumn *column = columns.First(); column; column = columns.Next(column)) {
|
||||||
|
column->SetTimers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
eOSState cTvGuideOsd::ProcessKey(eKeys Key) {
|
eOSState cTvGuideOsd::ProcessKey(eKeys Key) {
|
||||||
eOSState state = cOsdObject::ProcessKey(Key);
|
eOSState state = osContinue;
|
||||||
if (state == osUnknown) {
|
|
||||||
cPixmap::Lock();
|
cPixmap::Lock();
|
||||||
|
if (recMenuManager->isActive()) {
|
||||||
|
state = recMenuManager->ProcessKey(Key);
|
||||||
|
if (state == osEnd) {
|
||||||
|
SetTimers();
|
||||||
|
osdManager.flush();
|
||||||
|
}
|
||||||
state = osContinue;
|
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) {
|
switch (Key & ~k_Repeat) {
|
||||||
case kUp: processKeyUp(); break;
|
case kUp: processKeyUp(); break;
|
||||||
case kDown: processKeyDown(); break;
|
case kDown: processKeyDown(); break;
|
||||||
@ -670,8 +682,8 @@ eOSState cTvGuideOsd::ProcessKey(eKeys Key) {
|
|||||||
case k9: processKey9(); break;
|
case k9: processKey9(); break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
cPixmap::Unlock();
|
|
||||||
}
|
}
|
||||||
|
cPixmap::Unlock();
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ private:
|
|||||||
cTimeLine *timeLine;
|
cTimeLine *timeLine;
|
||||||
cChannelGroups *channelGroups;
|
cChannelGroups *channelGroups;
|
||||||
cFooter *footer;
|
cFooter *footer;
|
||||||
|
cRecMenuManager *recMenuManager;
|
||||||
bool detailViewActive;
|
bool detailViewActive;
|
||||||
void drawOsd();
|
void drawOsd();
|
||||||
void readChannels(const cChannel *channelStart);
|
void readChannels(const cChannel *channelStart);
|
||||||
@ -42,6 +43,7 @@ private:
|
|||||||
void ScrollBack();
|
void ScrollBack();
|
||||||
eOSState ChannelSwitch();
|
eOSState ChannelSwitch();
|
||||||
void DetailedEPG();
|
void DetailedEPG();
|
||||||
|
void SetTimers();
|
||||||
void dump();
|
void dump();
|
||||||
public:
|
public:
|
||||||
cTvGuideOsd(void);
|
cTvGuideOsd(void);
|
||||||
|