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 - Fixed some issues with text backgrounds in flat themes (closes
Tickets 1480 and 1486) Tickets 1480 and 1486)
- Added possibility to search for reruns in case of a timer conflict - 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, clrButtonRedKeyboard, 0xFFBB0000);
THEME_CLR(theme, clrButtonGreenKeyboard, 0xFF00BB00); THEME_CLR(theme, clrButtonGreenKeyboard, 0xFF00BB00);
THEME_CLR(theme, clrButtonYellowKeyboard, 0xFFBBBB00); 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 #endif //__TVGUIDE_CONFIG_H

View File

@ -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-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" "PO-Revision-Date: 2013-09-21 17:49+0200\n"
"Last-Translator: My friend <Sampep> Thanks David <Gabychan> <gbonich@gmail.com>\n" "Last-Translator: My friend <Sampep> Thanks David <Gabychan> <gbonich@gmail.com>\n"
"Language-Team: \n" "Language-Team: \n"
@ -72,6 +72,15 @@ msgstr "enregistrat a"
msgid "from" msgid "from"
msgstr "des de" msgstr "des de"
msgid "Timers for"
msgstr ""
msgid "Rec"
msgstr ""
msgid "No Timers active"
msgstr ""
msgid "Instant Record" msgid "Instant Record"
msgstr "Enregistra a l'instant" msgstr "Enregistra a l'instant"
@ -96,12 +105,15 @@ msgstr "Esborra canvis de temporitzadors"
msgid "Search" msgid "Search"
msgstr "Cerca" msgstr "Cerca"
msgid "Search in Recordings" msgid "Timer Timeline"
msgstr "Cerca a les gravacions" msgstr ""
msgid "Check for Timer Conflicts" msgid "Check for Timer Conflicts"
msgstr "Comprova conflictes de temporitzadors" msgstr "Comprova conflictes de temporitzadors"
msgid "Search in Recordings"
msgstr "Cerca a les gravacions"
msgid "Set Folder for" msgid "Set Folder for"
msgstr "Programa carpeta per" msgstr "Programa carpeta per"

View File

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

View File

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

View File

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

View File

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

View File

@ -10,6 +10,7 @@
cRecMenuItem::cRecMenuItem(void) { cRecMenuItem::cRecMenuItem(void) {
height = 0; height = 0;
action = rmsNotConsumed; action = rmsNotConsumed;
defaultBackground = true;
drawn = false; drawn = false;
font = fontManager.FontRecMenuItem; font = fontManager.FontRecMenuItem;
fontSmall = fontManager.FontRecMenuItemSmall; fontSmall = fontManager.FontRecMenuItemSmall;
@ -34,7 +35,9 @@ void cRecMenuItem::SetPixmaps(void) {
void cRecMenuItem::setBackground(void) { void cRecMenuItem::setBackground(void) {
if (tvguideConfig.style == eStyleGraphical) { if (tvguideConfig.style == eStyleGraphical) {
if (defaultBackground) {
drawBackgroundGraphical(bgButton, active); drawBackgroundGraphical(bgButton, active);
}
colorTextBack = clrTransparent; colorTextBack = clrTransparent;
colorText = (active)?theme.Color(clrFontActive):theme.Color(clrFont); colorText = (active)?theme.Color(clrFontActive):theme.Color(clrFont);
} else { } else {
@ -48,9 +51,11 @@ void cRecMenuItem::setBackground(void) {
colorText = theme.Color(clrFont); colorText = theme.Color(clrFont);
} }
colorTextBack = (tvguideConfig.style == eStyleFlat)?color:clrTransparent; colorTextBack = (tvguideConfig.style == eStyleFlat)?color:clrTransparent;
if (defaultBackground) {
drawBackground(); drawBackground();
drawBorder(); drawBorder();
} }
}
} }
// --- cRecMenuItemButton ------------------------------------------------------- // --- cRecMenuItemButton -------------------------------------------------------
@ -2057,3 +2062,355 @@ void cRecMenuItemRecording::Show(void) {
pixmap->SetLayer(4); pixmap->SetLayer(4);
pixmapText->SetLayer(5); 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 <string>
#include <vdr/tools.h> #include <vdr/tools.h>
#include "styledpixmap.h" #include "styledpixmap.h"
#include "timerconflict.h"
enum eRecMenuState { enum eRecMenuState {
rmsConsumed, rmsConsumed,
@ -54,6 +55,8 @@ enum eRecMenuState {
rmsTimerConflicts, rmsTimerConflicts,
rmsTimerConflictIgnoreReruns, rmsTimerConflictIgnoreReruns,
rmsTimerConflictRecordRerun, rmsTimerConflictRecordRerun,
rmsTimeline,
rmsTimelineInfo,
rmsDisabled, rmsDisabled,
}; };
@ -68,6 +71,7 @@ protected:
int width, height; int width, height;
bool selectable; bool selectable;
bool active; bool active;
bool defaultBackground;
bool drawn; bool drawn;
eRecMenuState action; eRecMenuState action;
tColor colorText; tColor colorText;
@ -82,8 +86,8 @@ public:
virtual int GetHeight(void) { return height; }; virtual int GetHeight(void) { return height; };
virtual int GetWidth(void) { return 0; }; virtual int GetWidth(void) { return 0; };
virtual void CalculateHeight(int textWidth) {}; virtual void CalculateHeight(int textWidth) {};
void setActive(void) { this->active = true; } virtual void setActive(void) { this->active = true; }
void setInactive(void) { this->active = false; } virtual void setInactive(void) { this->active = false; }
bool isSelectable(void) { return selectable; } bool isSelectable(void) { return selectable; }
bool isActive(void) { return active; } bool isActive(void) { return active; }
virtual void setBackground(void); virtual void setBackground(void);
@ -476,4 +480,62 @@ public:
void Draw(void); 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 #endif //__TVGUIDE_RECMENUITEM_H

View File

@ -138,6 +138,7 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) {
detailView->drawHeader(); detailView->drawHeader();
detailView->drawContent(); detailView->drawContent();
detailView->drawScrollbar(); detailView->drawScrollbar();
detailView->Start();
detailViewActive = true; detailViewActive = true;
} }
} }
@ -426,6 +427,7 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) {
detailView->drawHeader(); detailView->drawHeader();
detailView->drawContent(); detailView->drawContent();
detailView->drawScrollbar(); detailView->drawScrollbar();
detailView->Start();
detailViewActive = true; detailViewActive = true;
} }
break;} break;}
@ -522,6 +524,32 @@ eOSState cRecMenuManager::StateMachine(eRecMenuState nextState) {
activeMenu->Display(); activeMenu->Display();
} }
break; } 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 --------------------------------- * --------- COMMON ---------------------------------
*/ */

View File

@ -28,10 +28,12 @@ cRecMenuMain::cRecMenuMain(bool epgSearchAvailable, bool timerActive, bool switc
if (epgSearchAvailable) { if (epgSearchAvailable) {
AddMenuItem(new cRecMenuItemButton(tr("Search"), rmsSearch, false)); 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) { if (epgSearchAvailable) {
AddMenuItem(new cRecMenuItemButton(tr("Check for Timer Conflicts"), rmsTimerConflicts, false)); AddMenuItem(new cRecMenuItemButton(tr("Check for Timer Conflicts"), rmsTimerConflicts, false));
} }
AddMenuItem(new cRecMenuItemButton(tr("Search in Recordings"), rmsRecordingSearch, false));
int menuWidth = CalculateOptimalWidth() + 4 * border; int menuWidth = CalculateOptimalWidth() + 4 * border;
SetWidthPixel(menuWidth); SetWidthPixel(menuWidth);
@ -936,3 +938,139 @@ cRecMenuRecordingSearchNotFound::cRecMenuRecordingSearchNotFound(cString searchS
CreatePixmap(); CreatePixmap();
Arrange(); 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 --------------------------------------------------------- // --- cRecMenuRecordingSearchResults ---------------------------------------------------------
class cRecMenuRecordingSearchResults: public cRecMenu { class cRecMenuRecordingSearchResults: public cRecMenu {
private: private:
cRecording **searchResults; cRecording **searchResults;
@ -288,5 +287,30 @@ public:
virtual ~cRecMenuRecordingSearchNotFound(void) {}; 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 #endif //__TVGUIDE_RECMENUS_H

View File

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

View File

@ -42,3 +42,8 @@ clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000 clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = FFFFFFFF 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 clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = FF660000 clrRecMenuKeyboardBorder = FF660000
clrRecMenuKeyboardHigh = 40BB0000 clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B0660000
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

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

View File

@ -33,7 +33,7 @@ clrButtonBlend = DD000000
clrRecMenuBackground = AA000000 clrRecMenuBackground = AA000000
clrRecMenuTimerConflictBackground = FFCCCCCC clrRecMenuTimerConflictBackground = FFCCCCCC
clrRecMenuTimerConflictBar = FF222222 clrRecMenuTimerConflictBar = FF222222
clrRecMenuTimerConflictOverlap = AAFF0000 clrRecMenuTimerConflictOverlap = A0FF0000
clrRecMenuDayActive = FF00FF00 clrRecMenuDayActive = FF00FF00
clrRecMenuDayInactive = FFFF0000 clrRecMenuDayInactive = FFFF0000
clrRecMenuDayHighlight = 44FFFFFF clrRecMenuDayHighlight = 44FFFFFF
@ -42,3 +42,8 @@ clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000 clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = FFFFFFFF 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 clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = EE006600 clrRecMenuKeyboardBorder = EE006600
clrRecMenuKeyboardHigh = 40BB0000 clrRecMenuKeyboardHigh = 40BB0000
clrRecMenuTimelineTimer = B0003D00
clrRecMenuTimelineBack = FF828282
clrRecMenuTimelineActive = FF3F3F3F
clrRecMenuTimelineConflict = 30FF0000
clrRecMenuTimelineConflictOverlap = 90FF0000

View File

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

View File

@ -38,3 +38,8 @@ clrRecMenuTextActiveBack = FF404749
clrRecMenuKeyboardBack = FF000000 clrRecMenuKeyboardBack = FF000000
clrRecMenuKeyboardBorder = BB555555 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 NULL;
return conflicts[conflictIndex]; 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

@ -32,6 +32,7 @@ public:
int GetCurrentConflictTimerID(int timerIndex); int GetCurrentConflictTimerID(int timerIndex);
int GetCorrespondingConflict(int timerID); int GetCorrespondingConflict(int timerID);
cTVGuideTimerConflict *GetConflict(int conflictIndex); cTVGuideTimerConflict *GetConflict(int conflictIndex);
std::vector<cTVGuideTimerConflict*> GetConflictsBetween(time_t start, time_t stop);
}; };
#endif //__TVGUIDE_RECMMANAGER_H #endif //__TVGUIDE_RECMMANAGER_H