Added timer Timeline view in red button recording menu

This commit is contained in:
louis 2014-01-02 11:25:58 +01:00
parent eede61ade5
commit e6335e9c44
24 changed files with 761 additions and 48 deletions

View File

@ -97,3 +97,4 @@ Version 1.1.0
- Fixed some issues with text backgrounds in flat themes (closes
Tickets 1480 and 1486)
- Added possibility to search for reruns in case of a timer conflict
- Added timer Timeline view in red button recording menu

View File

@ -206,5 +206,9 @@ THEME_CLR(theme, clrRecMenuKeyboardHigh, 0x40BB0000);
THEME_CLR(theme, clrButtonRedKeyboard, 0xFFBB0000);
THEME_CLR(theme, clrButtonGreenKeyboard, 0xFF00BB00);
THEME_CLR(theme, clrButtonYellowKeyboard, 0xFFBBBB00);
THEME_CLR(theme, clrRecMenuTimelineTimer, 0xB012273f);
THEME_CLR(theme, clrRecMenuTimelineBack, 0xFF828282);
THEME_CLR(theme, clrRecMenuTimelineActive, 0xFF3F3F3F);
THEME_CLR(theme, clrRecMenuTimelineConflict, 0x30FF0000);
THEME_CLR(theme, clrRecMenuTimelineConflictOverlap, 0x90FF0000);
#endif //__TVGUIDE_CONFIG_H

View File

@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-tvguide 0.0.1\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2013-12-29 17:53+0100\n"
"POT-Creation-Date: 2013-12-31 14:31+0100\n"
"PO-Revision-Date: 2013-09-21 17:49+0200\n"
"Last-Translator: My friend <Sampep> Thanks David <Gabychan> <gbonich@gmail.com>\n"
"Language-Team: \n"
@ -72,6 +72,15 @@ msgstr "enregistrat a"
msgid "from"
msgstr "des de"
msgid "Timers for"
msgstr ""
msgid "Rec"
msgstr ""
msgid "No Timers active"
msgstr ""
msgid "Instant Record"
msgstr "Enregistra a l'instant"
@ -96,12 +105,15 @@ msgstr "Esborra canvis de temporitzadors"
msgid "Search"
msgstr "Cerca"
msgid "Search in Recordings"
msgstr "Cerca a les gravacions"
msgid "Timer Timeline"
msgstr ""
msgid "Check for Timer Conflicts"
msgstr "Comprova conflictes de temporitzadors"
msgid "Search in Recordings"
msgstr "Cerca a les gravacions"
msgid "Set Folder for"
msgstr "Programa carpeta per"

View File

@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-tvguide 0.0.1\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2013-12-29 17:53+0100\n"
"POT-Creation-Date: 2013-12-31 14:31+0100\n"
"PO-Revision-Date: 2012-08-25 17:49+0200\n"
"Last-Translator: Horst\n"
"Language-Team: \n"
@ -69,6 +69,15 @@ msgstr "aufgenommen am"
msgid "from"
msgstr "von"
msgid "Timers for"
msgstr "Timer für"
msgid "Rec"
msgstr "Aufn"
msgid "No Timers active"
msgstr "Keine Timer aktiv"
msgid "Instant Record"
msgstr "Sofortaufnahme"
@ -93,12 +102,15 @@ msgstr "Umschalttimer löschen"
msgid "Search"
msgstr "Suchen"
msgid "Search in Recordings"
msgstr "In Aufnahmen suchen"
msgid "Timer Timeline"
msgstr "Timer Zeitleiste"
msgid "Check for Timer Conflicts"
msgstr "Auf Timerkoflikte prüfen"
msgid "Search in Recordings"
msgstr "In Aufnahmen suchen"
msgid "Set Folder for"
msgstr "Verzeichnis festlegen für"
@ -157,25 +169,25 @@ msgid "Close"
msgstr "Schließen"
msgid "reruns for"
msgstr ""
msgstr "Wiederholungen für"
msgid "rerun for"
msgstr ""
msgstr "Wiederholung für"
msgid "found"
msgstr ""
msgstr "gefunden"
msgid "Ignore reruns"
msgstr ""
msgstr "Wiederholungen ignorieren"
msgid "No reruns found for Event"
msgstr ""
msgstr "Keine Wiederholungen gefunden für"
msgid "Timer for"
msgstr ""
msgstr "Timer für"
msgid "replaced by rerun"
msgstr ""
msgstr "ersetzt durch Wiederholung"
msgid "Timer Active"
msgstr "Timer aktiv"
@ -664,4 +676,4 @@ msgid "Channel Groups Cache"
msgstr "Kanalgruppen Cache"
msgid "Recording Menus Icon Cache"
msgstr ""
msgstr "Recording Menüs Icon Cache"

View File

@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-tvguide 1.0.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2013-12-29 17:53+0100\n"
"POT-Creation-Date: 2013-12-31 14:31+0100\n"
"PO-Revision-Date: 2013-09-25 17:49+0400\n"
"Last-Translator: AmiD, ilya\n"
"Language-Team: Russia-Cherepovets(wm.amid@gmail.com)\n"
@ -69,6 +69,15 @@ msgstr "записано"
msgid "from"
msgstr "от"
msgid "Timers for"
msgstr ""
msgid "Rec"
msgstr ""
msgid "No Timers active"
msgstr ""
msgid "Instant Record"
msgstr "Записать"
@ -93,12 +102,15 @@ msgstr "Удалить таймер переключения"
msgid "Search"
msgstr "Поиск"
msgid "Search in Recordings"
msgstr "Искать в записях"
msgid "Timer Timeline"
msgstr ""
msgid "Check for Timer Conflicts"
msgstr "Поиск таймер-конфликтов"
msgid "Search in Recordings"
msgstr "Искать в записях"
msgid "Set Folder for"
msgstr "Укажите каталог для"

View File

@ -3,7 +3,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-tvguide 1.1.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2013-12-29 17:53+0100\n"
"POT-Creation-Date: 2013-12-31 14:31+0100\n"
"PO-Revision-Date: 2013-09-15 00:12+0100\n"
"Last-Translator: Milan Hrala <hrala.milan@gmail.com>\n"
"Language-Team: \n"
@ -69,6 +69,15 @@ msgstr "Zaznamenan
msgid "from"
msgstr "z"
msgid "Timers for"
msgstr ""
msgid "Rec"
msgstr ""
msgid "No Timers active"
msgstr ""
msgid "Instant Record"
msgstr "Okam¾ite nahra»"
@ -93,12 +102,15 @@ msgstr "Vymaza
msgid "Search"
msgstr "Hµada»"
msgid "Search in Recordings"
msgstr "Vyhµada» v nahrávkach"
msgid "Timer Timeline"
msgstr ""
msgid "Check for Timer Conflicts"
msgstr "Skontrolova» konflikty plánu"
msgid "Search in Recordings"
msgstr "Vyhµada» v nahrávkach"
msgid "Set Folder for"
msgstr "Nastavi» adresár pre"

View File

@ -705,4 +705,4 @@ const cEvent **cRecManager::LoadReruns(const cEvent *event, int &numResults) {
}
}
return NULL;
}
}

View File

@ -528,4 +528,4 @@ cImage *cRecMenu::createScrollbar(int width, int height, tColor clrBgr, tColor c
}
}
return image;
}
}

View File

@ -58,6 +58,6 @@ public:
bool GetBoolValue(int itemNumber);
cString GetStringValue(int itemNumber);
const cEvent *GetEventValue(int itemNumber);
eRecMenuState ProcessKey(eKeys Key);
virtual eRecMenuState ProcessKey(eKeys Key);
};
#endif //__TVGUIDE_RECMENU_H

View File

@ -10,6 +10,7 @@
cRecMenuItem::cRecMenuItem(void) {
height = 0;
action = rmsNotConsumed;
defaultBackground = true;
drawn = false;
font = fontManager.FontRecMenuItem;
fontSmall = fontManager.FontRecMenuItemSmall;
@ -34,7 +35,9 @@ void cRecMenuItem::SetPixmaps(void) {
void cRecMenuItem::setBackground(void) {
if (tvguideConfig.style == eStyleGraphical) {
drawBackgroundGraphical(bgButton, active);
if (defaultBackground) {
drawBackgroundGraphical(bgButton, active);
}
colorTextBack = clrTransparent;
colorText = (active)?theme.Color(clrFontActive):theme.Color(clrFont);
} else {
@ -48,8 +51,10 @@ void cRecMenuItem::setBackground(void) {
colorText = theme.Color(clrFont);
}
colorTextBack = (tvguideConfig.style == eStyleFlat)?color:clrTransparent;
drawBackground();
drawBorder();
if (defaultBackground) {
drawBackground();
drawBorder();
}
}
}
@ -2057,3 +2062,355 @@ void cRecMenuItemRecording::Show(void) {
pixmap->SetLayer(4);
pixmapText->SetLayer(5);
}
// --- cRecMenuItemTimelineHeader -------------------------------------------------------
cRecMenuItemTimelineHeader::cRecMenuItemTimelineHeader(time_t day, std::vector<cTVGuideTimerConflict*> conflictsToday) {
conflicts = conflictsToday;
pixmapTimeline = NULL;
pixmapTimerInfo = NULL;
pixmapTimerConflicts = NULL;
timer = NULL;
this->day = day;
selectable = false;
active = false;
height = 5 * font->Height();
timelineDrawn = false;
}
cRecMenuItemTimelineHeader::~cRecMenuItemTimelineHeader(void) {
if (pixmapTimeline)
osdManager.releasePixmap(pixmapTimeline);
if (pixmapTimerInfo)
osdManager.releasePixmap(pixmapTimerInfo);
if (pixmapTimerConflicts)
osdManager.releasePixmap(pixmapTimerConflicts);
}
void cRecMenuItemTimelineHeader::SetPixmaps(void) {
if (!pixmap) {
pixmap = osdManager.requestPixmap(4, cRect(x, y, width, height));
pixmapTimeline = osdManager.requestPixmap(5, cRect(x, y, width, height));
pixmapTimerInfo = osdManager.requestPixmap(6, cRect(x, y + 3 * font->Height() / 2, width, 2 * font->Height()));
if (conflicts.size() > 0) {
pixmapTimerConflicts = osdManager.requestPixmap(6, cRect(x, y, width, height));
}
} else {
pixmap->SetViewPort(cRect(x, y, width, height));
pixmapTimeline->SetViewPort(cRect(x, y, width, height));
pixmapTimerInfo->SetViewPort(cRect(x, y + 3 * font->Height() / 2, width, 2 * font->Height()));
if (pixmapTimerConflicts)
pixmapTimerConflicts->SetViewPort(cRect(x, y, width, height));
}
}
void cRecMenuItemTimelineHeader::RefreshTimerDisplay(void) {
if (!pixmapTimerInfo)
return;
if (timer)
DrawCurrentTimer();
else
pixmapTimerInfo->Fill(clrTransparent);
}
void cRecMenuItemTimelineHeader::Draw(void) {
if (!timelineDrawn) {
DrawTimeline();
timelineDrawn = true;
}
DrawTimerConflicts();
pixmap->Fill(clrTransparent);
cString headerText = tr("Timers for");
cString dateText = DateString(day);
cString header = cString::sprintf("%s: %s", *headerText, *dateText);
int xText = (width - font->Width(*header)) / 2;
int yText = (height/4 - font->Height())/2;
pixmap->DrawText(cPoint(xText, yText), *header, colorText, clrTransparent, font);
if (timer) {
DrawCurrentTimer();
}
}
void cRecMenuItemTimelineHeader::DrawCurrentTimer(void) {
int infoHeight = pixmapTimerInfo->ViewPort().Height();
pixmapTimerInfo->Fill(clrTransparent);
const cEvent *event = timer->Event();
const cChannel *channel = timer->Channel();
int x = 0;
if (channel) {
int logoWidth = infoHeight * tvguideConfig.logoWidthRatio / tvguideConfig.logoHeightRatio;
bool logoDrawn = false;
cImageLoader imgLoader;
if (!tvguideConfig.hideChannelLogos) {
if (imgLoader.LoadLogo(channel, logoWidth, infoHeight)) {
cImage logo = imgLoader.GetImage();
pixmapTimerInfo->DrawImage(cPoint(0, 0), logo);
x += logoWidth + 10;
logoDrawn = true;
}
}
if (tvguideConfig.hideChannelLogos || !logoDrawn) {
int channelNameWidth = fontSmall->Width(channel->Name());
pixmapTimerInfo->DrawText(cPoint(10, (infoHeight - fontSmall->Height())/2), channel->Name(), colorText, clrTransparent, fontSmall);
x += channelNameWidth + 20;
}
}
cString timerStartTime = TimeString(timer->StartTime());
cString timerStopTime = TimeString(timer->StopTime());
cString channelInfo = cString::sprintf("%s %d", tr("Transp."), timer->Channel()->Transponder());
if (event) {
cString title;
if (event->ShortText()) {
title = cString::sprintf("%s - %s", event->Title(), event->ShortText());
} else {
title = event->Title();
}
std::string titleCut = CutText(*title, width - x, font);
cString infoString = cString::sprintf("%s: %s - %s (%s. %s - %s), %s", *event->GetDateString(), *event->GetTimeString(), *event->GetEndTimeString(), tr("Rec"), *timerStartTime, *timerStopTime, *channelInfo);
pixmapTimerInfo->DrawText(cPoint(x, 0), *infoString, colorText, clrTransparent, font);
pixmapTimerInfo->DrawText(cPoint(x, font->Height()), titleCut.c_str(), colorText, clrTransparent, font);
} else {
cString infoString = cString::sprintf("%s. %s - %s, %s", tr("Rec"), *timerStartTime, *timerStopTime, *channelInfo);
pixmapTimerInfo->DrawText(cPoint(x, 0), *infoString, colorText, clrTransparent, font);
}
}
void cRecMenuItemTimelineHeader::DrawTimeline(void) {
pixmapTimeline->Fill(clrTransparent);
width5Mins = (float)width * 5.0 / 24.0 / 60.0;
int widthHour = 12 * width5Mins;
x0 = (width - 24*widthHour)/2;
int barHeight = fontSmall->Height();
int y = height - barHeight;
tColor col1 = theme.Color(clrTimeline1);
tColor col2 = theme.Color(clrTimeline2);
tColor colCurText = col1;
tColor colCurBack = col2;
int x = x0;
for (int hour = 0; hour < 24; hour++) {
pixmapTimeline->DrawRectangle(cRect(x, y, widthHour, barHeight), colCurBack);
cString hourText = cString::sprintf("%d", hour);
int xDelta = (widthHour - fontSmall->Width(*hourText)) / 2;
pixmapTimeline->DrawText(cPoint(x + xDelta, y), *hourText, colCurText, colCurBack, fontSmall);
x += widthHour;
colCurText = (colCurText==col1)?col2:col1;
colCurBack = (colCurBack==col1)?col2:col1;
}
pixmapTimeline->DrawRectangle(cRect(x0, height-2, width - 2*x0, 2), col2);
}
void cRecMenuItemTimelineHeader::DrawTimerConflicts(void) {
if (!pixmapTimerConflicts)
return;
pixmapTimerConflicts->Fill(clrTransparent);
int numConflicts = conflicts.size();
int barHeight = fontSmall->Height();
int y = height - barHeight;
for (int conflict = 0; conflict < numConflicts; conflict++) {
int confStart = conflicts[conflict]->timeStart - day;
int confStop = conflicts[conflict]->timeStop - day;
int overlapStart = conflicts[conflict]->overlapStart - day;
int overlapStop = conflicts[conflict]->overlapStop - day;
if (confStart < 0)
confStart = 0;
if (confStop > 24*60*60)
confStop = 24 * 60 * 60;
if (overlapStart < 0)
overlapStart = 0;
if (overlapStop > 24*60*60)
overlapStop = 24 * 60 * 60;
confStart = confStart / 60;
confStop = confStop / 60;
overlapStart = overlapStart / 60;
overlapStop = overlapStop / 60;
int xStartConflict = x0 + confStart * width5Mins / 5;
int xStopConflict = x0 + confStop * width5Mins / 5;
int xStartOverlap = x0 + overlapStart * width5Mins / 5;
int xStopOverlap = x0 + overlapStop * width5Mins / 5;
pixmapTimerConflicts->DrawRectangle(cRect(xStartConflict, y, xStopConflict - xStartConflict, barHeight), theme.Color(clrRecMenuTimelineConflict));
pixmapTimerConflicts->DrawRectangle(cRect(xStartOverlap, y, xStopOverlap - xStartOverlap, barHeight), theme.Color(clrRecMenuTimelineConflictOverlap));
}
}
void cRecMenuItemTimelineHeader::Hide(void) {
pixmap->SetLayer(-1);
pixmapTimeline->SetLayer(-1);
pixmapTimerInfo->SetLayer(-1);
if (pixmapTimerConflicts)
pixmapTimerConflicts->SetLayer(-1);
}
void cRecMenuItemTimelineHeader::Show(void) {
pixmap->SetLayer(4);
pixmapTimeline->SetLayer(5);
pixmapTimerInfo->SetLayer(6);
if (pixmapTimerConflicts)
pixmapTimerConflicts->SetLayer(6);
}
// --- cRecMenuItemTimelineTimer -------------------------------------------------------
cRecMenuItemTimelineTimer::cRecMenuItemTimelineTimer(cTimer *timer, time_t start, time_t stop, std::vector<cTVGuideTimerConflict*> conflictsToday, cRecMenuItemTimelineHeader *header, bool active) {
conflicts = conflictsToday;
defaultBackground = false;
pixmapBack = NULL;
pixmapTimerConflicts = NULL;
this->timer = timer;
this->start = start;
this->stop = stop;
this->header = header;
selectable = true;
this->active = active;
height = geoManager.osdHeight / 16;
}
cRecMenuItemTimelineTimer::~cRecMenuItemTimelineTimer(void) {
if (pixmapBack)
osdManager.releasePixmap(pixmapBack);
if (pixmapTimerConflicts)
osdManager.releasePixmap(pixmapTimerConflicts);
}
void cRecMenuItemTimelineTimer::SetPixmaps(void) {
if (!pixmap) {
pixmapBack = osdManager.requestPixmap(4, cRect(x, y, width, height));
pixmap = osdManager.requestPixmap(5, cRect(x, y, width, height));
if (conflicts.size() > 0) {
pixmapTimerConflicts = osdManager.requestPixmap(6, cRect(x, y, width, height));
}
} else {
pixmapBack->SetViewPort(cRect(x, y, width, height));
pixmap->SetViewPort(cRect(x, y, width, height));
if (pixmapTimerConflicts)
pixmapTimerConflicts->SetViewPort(cRect(x, y, width, height));
}
width5Mins = (float)width * 5.0 / 24.0 / 60.0;
x0 = (width - 24*12*width5Mins)/2;
}
void cRecMenuItemTimelineTimer::Draw(void) {
DrawBackground();
if (!timer) {
DrawNoTimerInfo();
return;
}
if (!drawn) {
pixmap->Fill(clrTransparent);
DrawTimeScale();
DrawTimerBar();
DrawTimerConflicts();
drawn = true;
}
}
void cRecMenuItemTimelineTimer::DrawBackground(void) {
tColor backgroundColor = (active)?theme.Color(clrRecMenuTimelineActive):theme.Color(clrRecMenuTimelineBack);
pixmapBack->Fill(clrTransparent);
pixmapBack->DrawRectangle(cRect(x0, 0, width - 2 * x0, height), backgroundColor);
}
void cRecMenuItemTimelineTimer::DrawTimeScale(void) {
int x = x0;
for (int hour = 0; hour < 25; hour++) {
int xModified = (hour%2) ? x - 1 : x ;
pixmap->DrawRectangle(cRect(xModified,0,1,height), theme.Color(clrTimeline2));
x += width5Mins*12;
}
}
void cRecMenuItemTimelineTimer::DrawTimerBar(void) {
time_t timerStart = timer->StartTime() - start;
time_t timerStop = timer->StopTime() - start;
if (timerStart < 0)
timerStart = 0;
if (timerStop > 24*60*60)
timerStop = 24 * 60 * 60;
timerStart = timerStart / 60;
timerStop = timerStop / 60;
int xStart = x0 + timerStart * width5Mins / 5;
int xStop = x0 + timerStop * width5Mins / 5;
pixmap->DrawRectangle(cRect(xStart, height / 4, xStop - xStart, height / 2), theme.Color(clrRecMenuTimelineTimer));
}
void cRecMenuItemTimelineTimer::DrawTimerConflicts(void) {
if (!pixmapTimerConflicts)
return;
pixmapTimerConflicts->Fill(clrTransparent);
int numConflicts = conflicts.size();
for (int conflict = 0; conflict < numConflicts; conflict++) {
int confStart = conflicts[conflict]->timeStart - start;
int confStop = conflicts[conflict]->timeStop - start;
int overlapStart = conflicts[conflict]->overlapStart - start;
int overlapStop = conflicts[conflict]->overlapStop - start;
if (confStart < 0)
confStart = 0;
if (confStop > 24*60*60)
confStop = 24 * 60 * 60;
if (overlapStart < 0)
overlapStart = 0;
if (overlapStop > 24*60*60)
overlapStop = 24 * 60 * 60;
confStart = confStart / 60;
confStop = confStop / 60;
overlapStart = overlapStart / 60;
overlapStop = overlapStop / 60;
int xStartConflict = x0 + confStart * width5Mins / 5;
int xStopConflict = x0 + confStop * width5Mins / 5;
int xStartOverlap = x0 + overlapStart * width5Mins / 5;
int xStopOverlap = x0 + overlapStop * width5Mins / 5;
pixmapTimerConflicts->DrawRectangle(cRect(xStartConflict, 0, xStopConflict - xStartConflict, height), theme.Color(clrRecMenuTimelineConflict));
pixmapTimerConflicts->DrawRectangle(cRect(xStartOverlap, 0, xStopOverlap - xStartOverlap, height), theme.Color(clrRecMenuTimelineConflictOverlap));
}
}
void cRecMenuItemTimelineTimer::DrawNoTimerInfo(void) {
pixmap->Fill(clrTransparent);
cString noTimersText = tr("No Timers active");
int widthText = font->Width(*noTimersText);
int x = (width - widthText) / 2;
int y = (height - font->Height()) / 2;
pixmap->DrawText(cPoint(x, y), *noTimersText, colorText, clrTransparent, font);
}
void cRecMenuItemTimelineTimer::setActive(void) {
active = true;
header->SetCurrentTimer(timer);
header->RefreshTimerDisplay();
}
void cRecMenuItemTimelineTimer::setInactive(void) {
active = false;
header->UnsetCurrentTimer();
header->RefreshTimerDisplay();
}
void cRecMenuItemTimelineTimer::Hide(void) {
pixmap->SetLayer(-1);
pixmapBack->SetLayer(-1);
if (pixmapTimerConflicts)
pixmapTimerConflicts->SetLayer(-1);
}
void cRecMenuItemTimelineTimer::Show(void) {
pixmap->SetLayer(5);
pixmapBack->SetLayer(4);
if (pixmapTimerConflicts)
pixmapTimerConflicts->SetLayer(6);
}
const cEvent *cRecMenuItemTimelineTimer::GetEventValue(void) {
return timer->Event();
}
eRecMenuState cRecMenuItemTimelineTimer::ProcessKey(eKeys Key) {
switch (Key & ~k_Repeat) {
case kOk:
return rmsTimelineInfo;
default:
break;
}
return rmsNotConsumed;
}

View File

@ -6,6 +6,7 @@
#include <string>
#include <vdr/tools.h>
#include "styledpixmap.h"
#include "timerconflict.h"
enum eRecMenuState {
rmsConsumed,
@ -54,6 +55,8 @@ enum eRecMenuState {
rmsTimerConflicts,
rmsTimerConflictIgnoreReruns,
rmsTimerConflictRecordRerun,
rmsTimeline,
rmsTimelineInfo,
rmsDisabled,
};
@ -68,6 +71,7 @@ protected:
int width, height;
bool selectable;
bool active;
bool defaultBackground;
bool drawn;
eRecMenuState action;
tColor colorText;
@ -82,8 +86,8 @@ public:
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; }
virtual void setActive(void) { this->active = true; }
virtual void setInactive(void) { this->active = false; }
bool isSelectable(void) { return selectable; }
bool isActive(void) { return active; }
virtual void setBackground(void);
@ -476,4 +480,62 @@ public:
void Draw(void);
};
// --- cRecMenuItemTimelineHeader -------------------------------------------------------
class cRecMenuItemTimelineHeader : public cRecMenuItem {
private:
time_t day;
cTimer *timer;
std::vector<cTVGuideTimerConflict*> conflicts;
cPixmap *pixmapTimeline;
cPixmap *pixmapTimerInfo;
cPixmap *pixmapTimerConflicts;
int width5Mins;
int x0;
bool timelineDrawn;
void DrawTimeline(void);
void DrawTimerConflicts(void);
void DrawCurrentTimer(void);
public:
cRecMenuItemTimelineHeader(time_t day, std::vector<cTVGuideTimerConflict*> conflictsToday);
virtual ~cRecMenuItemTimelineHeader(void);
void SetDay(time_t day) { this->day = day; };
void SetPixmaps(void);
void SetCurrentTimer(cTimer *timer) { this->timer = timer; };
void UnsetCurrentTimer(void) { timer = NULL; };
void RefreshTimerDisplay(void);
void Hide(void);
void Show(void);
void Draw(void);
};
// --- cRecMenuItemTimelineTimer -------------------------------------------------------
class cRecMenuItemTimelineTimer : public cRecMenuItem {
private:
cTimer *timer;
std::vector<cTVGuideTimerConflict*> conflicts;
cPixmap *pixmapBack;
cPixmap *pixmapTimerConflicts;
cRecMenuItemTimelineHeader *header;
int x0;
int width5Mins;
time_t start;
time_t stop;
void DrawBackground(void);
void DrawTimerBar(void);
void DrawTimeScale(void);
void DrawTimerConflicts(void);
void DrawNoTimerInfo(void);
public:
cRecMenuItemTimelineTimer(cTimer *timer, time_t start, time_t stop, std::vector<cTVGuideTimerConflict*> conflictsToday, cRecMenuItemTimelineHeader *header, bool active);
virtual ~cRecMenuItemTimelineTimer(void);
void setActive(void);
void setInactive(void);
void SetPixmaps(void);
void Hide(void);
void Show(void);
void Draw(void);
const cEvent *GetEventValue(void);
eRecMenuState ProcessKey(eKeys Key);
};
#endif //__TVGUIDE_RECMENUITEM_H

View File

@ -138,6 +138,7 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) {
detailView->drawHeader();
detailView->drawContent();
detailView->drawScrollbar();
detailView->Start();
detailViewActive = true;
}
}
@ -426,6 +427,7 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) {
detailView->drawHeader();
detailView->drawContent();
detailView->drawScrollbar();
detailView->Start();
detailViewActive = true;
}
break;}
@ -522,6 +524,32 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) {
activeMenu->Display();
}
break; }
/*
* --------- TIMELINE ---------------------------------
*/
case rmsTimeline: {
if (timerConflicts) {
delete timerConflicts;
}
timerConflicts = recManager->CheckTimerConflict();
delete activeMenu;
activeMenu = new cRecMenuTimeline(timerConflicts);
activeMenu->Display();
break; }
case rmsTimelineInfo: {
const cEvent *ev = activeMenu->GetEventValue(activeMenu->GetActive(true));
if (ev) {
activeMenu->Hide();
detailView = new cDetailView(ev);
detailView->setContent();
detailView->drawHeader();
detailView->drawContent();
detailView->drawScrollbar();
detailView->Start();
detailViewActive = true;
}
break;}
/*
* --------- COMMON ---------------------------------
*/

View File

@ -28,10 +28,12 @@ cRecMenuMain::cRecMenuMain(bool epgSearchAvailable, bool timerActive, bool switc
if (epgSearchAvailable) {
AddMenuItem(new cRecMenuItemButton(tr("Search"), rmsSearch, false));
}
AddMenuItem(new cRecMenuItemButton(tr("Search in Recordings"), rmsRecordingSearch, false));
AddMenuItem(new cRecMenuItemButton(tr("Timer Timeline"), rmsTimeline, false));
if (epgSearchAvailable) {
AddMenuItem(new cRecMenuItemButton(tr("Check for Timer Conflicts"), rmsTimerConflicts, false));
}
AddMenuItem(new cRecMenuItemButton(tr("Search in Recordings"), rmsRecordingSearch, false));
int menuWidth = CalculateOptimalWidth() + 4 * border;
SetWidthPixel(menuWidth);
@ -935,4 +937,140 @@ cRecMenuRecordingSearchNotFound::cRecMenuRecordingSearchNotFound(cString searchS
CalculateHeight();
CreatePixmap();
Arrange();
}
// --- cRecMenuTimeline ---------------------------------------------------------
cRecMenuTimeline::cRecMenuTimeline(cTVGuideTimerConflicts *timerConflicts) {
this->timerConflicts = timerConflicts;
SetStartStop();
conflictsToday = timerConflicts->GetConflictsBetween(timeStart, timeStop);
GetTimersForDay();
SetWidthPercent(95);
header = new cRecMenuItemTimelineHeader(timeStart, conflictsToday);
SetHeader(header);
cRecMenuItem *footer = new cRecMenuItemButton(tr("Close"), rmsClose, false, true);
SetFooter(footer);
SetTimers();
}
void cRecMenuTimeline::SetStartStop(void) {
time_t now = time(0);
tm *timeStruct = localtime(&now);
timeStart = now - timeStruct->tm_hour * 3600 - timeStruct->tm_min * 60 - timeStruct->tm_sec;
today = timeStart;
timeStop = timeStart + 24*3600 - 1;
}
void cRecMenuTimeline::GetTimersForDay(void) {
timersToday.clear();
for (cTimer *t = Timers.First(); t; t = Timers.Next(t)) {
if (((t->StartTime() > timeStart) && (t->StartTime() <= timeStop)) || ((t->StopTime() > timeStart) && (t->StopTime() <= timeStop))) {
timersToday.push_back(t);
}
}
numTimersToday = timersToday.size();
}
void cRecMenuTimeline::SetTimers(void) {
ClearMenuItems();
if (numTimersToday == 0) {
AddMenuItem(new cRecMenuItemTimelineTimer(NULL, 0, 0, conflictsToday, header, false));
header->UnsetCurrentTimer();
footer->setActive();
} else {
for (int i=0; i<numTimersToday; i++) {
cRecMenuItemTimelineTimer *item = new cRecMenuItemTimelineTimer(timersToday[i], timeStart, timeStop, conflictsToday, header, false);
if (i==0)
item->setActive();
AddMenuItemScroll(item);
if (!CheckHeight())
break;
}
footer->setInactive();
}
CalculateHeight();
CreatePixmap();
Arrange();
}
void cRecMenuTimeline::PrevDay(void) {
if ((timeStart - 3600*24) < today)
return;
timeStart -= 3600*24;
timeStop -= 3600*24;
conflictsToday = timerConflicts->GetConflictsBetween(timeStart, timeStop);
SetWidthPercent(95);
header->SetDay(timeStart);
header->UnsetCurrentTimer();
header->RefreshTimerDisplay();
GetTimersForDay();
SetTimers();
Display();
}
void cRecMenuTimeline::NextDay(void) {
timeStart += 3600*24;
timeStop += 3600*24;
conflictsToday = timerConflicts->GetConflictsBetween(timeStart, timeStop);
SetWidthPercent(95);
header->SetDay(timeStart);
header->UnsetCurrentTimer();
header->RefreshTimerDisplay();
GetTimersForDay();
SetTimers();
Display();
}
cRecMenuItem *cRecMenuTimeline::GetMenuItem(int number) {
if (number < 0)
return NULL;
if (number >= numTimersToday)
return NULL;
return new cRecMenuItemTimelineTimer(timersToday[number], timeStart, timeStop, conflictsToday, header, false);
}
int cRecMenuTimeline::GetTotalNumMenuItems(void) {
return numTimersToday;
}
void cRecMenuTimeline::ClearMenuItems(void) {
if (pixmap)
osdManager.releasePixmap(pixmap);
pixmap = NULL;
menuItems.Clear();
if (pixmapScrollBar)
osdManager.releasePixmap(pixmapScrollBar);
if (imgScrollBar)
delete imgScrollBar;
header->UnsetCurrentTimer();
height = 2*border + headerHeight + footerHeight;
scrollHeight = 0;
scrollItemHeight = 0;
scrollable = false;
pixmapScrollBar = NULL;
imgScrollBar = NULL;
startIndex = 0;
stopIndex = 0;
numItems = 0;
}
eRecMenuState cRecMenuTimeline::ProcessKey(eKeys Key) {
eRecMenuState state = rmsContinue;
switch (Key & ~k_Repeat) {
case kLeft:
PrevDay();
state = rmsConsumed;
break;
case kRight:
NextDay();
state = rmsConsumed;
break;
default:
break;
}
if (state != rmsConsumed) {
state = cRecMenu::ProcessKey(Key);
}
return state;
}

View File

@ -267,7 +267,6 @@ public:
};
// --- cRecMenuRecordingSearchResults ---------------------------------------------------------
class cRecMenuRecordingSearchResults: public cRecMenu {
private:
cRecording **searchResults;
@ -288,5 +287,30 @@ public:
virtual ~cRecMenuRecordingSearchNotFound(void) {};
};
// --- cRecMenuTimeline ---------------------------------------------------------
class cRecMenuTimeline: public cRecMenu {
private:
std::vector<cTimer*> timersToday;
int numTimersToday;
time_t today;
time_t timeStart;
time_t timeStop;
cTVGuideTimerConflicts *timerConflicts;
std::vector<cTVGuideTimerConflict*> conflictsToday;
cRecMenuItemTimelineHeader *header;
void SetStartStop(void);
void GetTimersForDay(void);
void SetTimers(void);
void PrevDay(void);
void NextDay(void);
void ClearMenuItems(void);
public:
cRecMenuTimeline(cTVGuideTimerConflicts *timerConflicts);
cRecMenuItem *GetMenuItem(int number);
int GetTotalNumMenuItems(void);
virtual ~cRecMenuTimeline(void) {
};
eRecMenuState ProcessKey(eKeys Key);
};
#endif //__TVGUIDE_RECMENUS_H

View File

@ -42,3 +42,8 @@ clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = FF003DF5
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B012273f
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

@ -42,3 +42,8 @@ clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = FFFFFFFF
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B012273f
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

@ -42,3 +42,8 @@ clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = FF660000
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B0660000
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

@ -33,7 +33,7 @@ clrButtonBlend = DD000000
clrRecMenuBackground = AA000000
clrRecMenuTimerConflictBackground = FFCCCCCC
clrRecMenuTimerConflictBar = FF222222
clrRecMenuTimerConflictOverlap = AAFF0000
clrRecMenuTimerConflictOverlap = 90FF0000
clrRecMenuDayActive = FF00FF00
clrRecMenuDayInactive = FFFF0000
clrRecMenuDayHighlight = 44FFFFFF
@ -42,3 +42,8 @@ clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = FF660000
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B0660000
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

@ -33,7 +33,7 @@ clrButtonBlend = DD000000
clrRecMenuBackground = AA000000
clrRecMenuTimerConflictBackground = FFCCCCCC
clrRecMenuTimerConflictBar = FF222222
clrRecMenuTimerConflictOverlap = AAFF0000
clrRecMenuTimerConflictOverlap = A0FF0000
clrRecMenuDayActive = FF00FF00
clrRecMenuDayInactive = FFFF0000
clrRecMenuDayHighlight = 44FFFFFF
@ -41,4 +41,9 @@ clrRecMenuTextBack = FF000000
clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = FFFFFFFF
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B012273f
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

@ -42,3 +42,8 @@ clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = EE006600
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B0003D00
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

@ -40,3 +40,8 @@ clrRecMenuKeyboardHigh = 55FFFFFF
clrButtonRedKeyboard = FFBB0000
clrButtonGreenKeyboard = FF00BB00
clrButtonYellowKeyboard = FFBBBB00
clrRecMenuTimelineTimer = B012273f
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

@ -37,4 +37,9 @@ clrRecMenuTextBack = FF000000
clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = BB555555
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B012273f
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

@ -165,3 +165,13 @@ cTVGuideTimerConflict *cTVGuideTimerConflicts::GetConflict(int conflictIndex) {
return NULL;
return conflicts[conflictIndex];
}
std::vector<cTVGuideTimerConflict*> cTVGuideTimerConflicts::GetConflictsBetween(time_t start, time_t stop) {
std::vector<cTVGuideTimerConflict*> conflictsFound;
for (int i=0; i < numConflicts; i++) {
if ((conflicts[i]->timeStart > start) && (conflicts[i]->timeStart < stop)||
(conflicts[i]->timeStop > start) && (conflicts[i]->timeStop < stop))
conflictsFound.push_back(conflicts[i]);
}
return conflictsFound;
}

View File

@ -3,8 +3,8 @@
class cTVGuideTimerConflict {
public:
cTVGuideTimerConflict(void);
virtual ~cTVGuideTimerConflict(void);
cTVGuideTimerConflict(void);
virtual ~cTVGuideTimerConflict(void);
time_t time;
time_t timeStart;
time_t timeStop;
@ -18,20 +18,21 @@ public:
class cTVGuideTimerConflicts {
private:
std::vector<cTVGuideTimerConflict*> conflicts;
int numConflicts;
int currentConflict;
std::vector<cTVGuideTimerConflict*> conflicts;
int numConflicts;
int currentConflict;
public:
cTVGuideTimerConflicts(void);
virtual ~cTVGuideTimerConflicts(void);
void AddConflict(std::string epgSearchConflictLine);
void CalculateConflicts(void);
int NumConflicts(void) {return numConflicts; };
void SetCurrentConflict(int current) { currentConflict = current; };
cTVGuideTimerConflict *GetCurrentConflict(void);
int GetCurrentConflictTimerID(int timerIndex);
cTVGuideTimerConflicts(void);
virtual ~cTVGuideTimerConflicts(void);
void AddConflict(std::string epgSearchConflictLine);
void CalculateConflicts(void);
int NumConflicts(void) {return numConflicts; };
void SetCurrentConflict(int current) { currentConflict = current; };
cTVGuideTimerConflict *GetCurrentConflict(void);
int GetCurrentConflictTimerID(int timerIndex);
int GetCorrespondingConflict(int timerID);
cTVGuideTimerConflict *GetConflict(int conflictIndex);
std::vector<cTVGuideTimerConflict*> GetConflictsBetween(time_t start, time_t stop);
};
#endif //__TVGUIDE_RECMMANAGER_H