mirror of
https://github.com/tuxbox-neutrino/neutrino.git
synced 2025-08-27 07:23:09 +02:00
* if epg title needs 2 lines, expand header downwards to make sure that we don't draw outside of the framebuffer * if USE_SPACE_EFFICIENTLY is defined, do not resize the EPG window if the font size is switched but always paint the "big" window git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@227 e54a6e83-5905-42d5-8d5c-058d10e6a962
1074 lines
34 KiB
C++
1074 lines
34 KiB
C++
/*
|
|
Neutrino-GUI - DBoxII-Project
|
|
|
|
Copyright (C) 2001 Steffen Hehn 'McClean'
|
|
Homepage: http://dbox.cyberphoria.org/
|
|
|
|
Kommentar:
|
|
|
|
Diese GUI wurde von Grund auf neu programmiert und sollte nun vom
|
|
Aufbau und auch den Ausbaumoeglichkeiten gut aussehen. Neutrino basiert
|
|
auf der Client-Server Idee, diese GUI ist also von der direkten DBox-
|
|
Steuerung getrennt. Diese wird dann von Daemons uebernommen.
|
|
|
|
|
|
License: GPL
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <algorithm>
|
|
#include <gui/epgview.h>
|
|
|
|
#include <gui/widget/hintbox.h>
|
|
#include <gui/widget/icons.h>
|
|
#include <gui/widget/messagebox.h>
|
|
#include <gui/widget/mountchooser.h>
|
|
#include <gui/widget/progressbar.h>
|
|
#include <gui/timerlist.h>
|
|
|
|
#include <global.h>
|
|
#include <neutrino.h>
|
|
|
|
#include <driver/encoding.h>
|
|
#include <driver/screen_max.h>
|
|
#include <gui/filebrowser.h>
|
|
#include <gui/customcolor.h>
|
|
#include <gui/pictureviewer.h>
|
|
|
|
extern CPictureViewer * g_PicViewer;
|
|
#define PIC_W 52
|
|
#define PIC_H 39
|
|
|
|
#define ICON_LARGE_WIDTH 26
|
|
#define ROUND_RADIUS 9
|
|
|
|
int findItem(std::string strItem, std::vector<std::string> & vecItems) {
|
|
for (std::vector<std::string>::size_type nCnt = 0; nCnt < vecItems.size(); nCnt++) {
|
|
std::string strThisItem = vecItems[nCnt];
|
|
if (strItem == strThisItem) {
|
|
return nCnt;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
// 21.07.2005 - rainerk
|
|
// Merge multiple extended event strings into one description and localize the label
|
|
// Examples:
|
|
// Actor1-ActorX -> Darsteller 1, 2, 3
|
|
// Year of production -> Produktionsjahr
|
|
// Director -> Regisseur
|
|
// Guests -> Gäste
|
|
void reformatExtendedEvents(std::string strItem, std::string strLabel, bool bUseRange, CEPGData & epgdata) {
|
|
std::vector<std::string> & vecDescriptions = epgdata.itemDescriptions;
|
|
std::vector<std::string> & vecItems = epgdata.items;
|
|
// Merge multiple events into 1 (Actor1-)
|
|
if (bUseRange) {
|
|
bool bHasItems = false;
|
|
char index[3];
|
|
// Maximum of 10 items should suffice
|
|
for (int nItem = 1; nItem < 11; nItem++) {
|
|
sprintf(index, "%d", nItem);
|
|
// Look for matching items
|
|
int nPos = findItem(std::string(strItem) + std::string(index), vecDescriptions);
|
|
if (-1 != nPos) {
|
|
std::string item = std::string(vecItems[nPos]);
|
|
vecDescriptions.erase(vecDescriptions.begin() + nPos);
|
|
vecItems.erase(vecItems.begin() + nPos);
|
|
if (false == bHasItems) {
|
|
// First item added, so create new label item
|
|
vecDescriptions.push_back(strLabel);
|
|
vecItems.push_back(item + ", ");
|
|
bHasItems = true;
|
|
} else {
|
|
vecItems.back().append(item).append(", ");
|
|
}
|
|
}
|
|
}
|
|
// Remove superfluous ", "
|
|
if (bHasItems) {
|
|
vecItems.back().resize(vecItems.back().length() - 2);
|
|
}
|
|
} else { // Single string event (e.g. Director)
|
|
// Look for matching items
|
|
int nPos = findItem(strItem, vecDescriptions);
|
|
if (-1 != nPos) {
|
|
vecDescriptions[nPos] = strLabel;
|
|
}
|
|
}
|
|
}
|
|
|
|
CEpgData::CEpgData()
|
|
{
|
|
bigFonts = false;
|
|
frameBuffer = CFrameBuffer::getInstance();
|
|
}
|
|
|
|
#define MAX_W 540
|
|
#define MAX_H 320
|
|
|
|
void CEpgData::start()
|
|
{
|
|
/* if you want usably sized epg windows, compile with "-DUSE_SPACE_EFFICIENTLY" */
|
|
#ifndef USE_SPACE_EFFICIENTLY
|
|
#define EPGWIN_SCALE_FACTOR BIG_FONT_FAKTOR
|
|
#else
|
|
#define EPGWIN_SCALE_FACTOR 1
|
|
#endif
|
|
/* This defines the size of the EPG window. We use 90% of the screen width and
|
|
* 90% of the screen height. It adjusts itself to the "visible screen" settings
|
|
*/
|
|
ox = (frameBuffer->getScreenWidth() / 20 * 18) / (bigFonts ? 1 : EPGWIN_SCALE_FACTOR);
|
|
oy = (frameBuffer->getScreenHeight() / 20 * 18) / (bigFonts ? 1 : EPGWIN_SCALE_FACTOR);
|
|
sx = getScreenStartX(ox);
|
|
sy = getScreenStartY(oy);
|
|
|
|
topheight = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_TITLE]->getHeight();
|
|
topboxheight = topheight + 6;
|
|
botboxheight = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->getHeight() + 6;
|
|
buttonheight = g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->getHeight() + 6;
|
|
if (buttonheight < 30)
|
|
buttonheight = 30; // the buttons and icons need space
|
|
/* this is the text box height - and the height of the scroll bar */
|
|
sb = oy - topboxheight - botboxheight - buttonheight;
|
|
/* button box is handled separately (why?) */
|
|
oy -= buttonheight;
|
|
medlineheight = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getHeight();
|
|
medlinecount = sb / medlineheight;
|
|
toph = topboxheight;
|
|
}
|
|
|
|
void CEpgData::addTextToArray(const std::string & text) // UTF-8
|
|
{
|
|
//printf("line: >%s<\n", text.c_str() );
|
|
if (text==" ")
|
|
{
|
|
emptyLineCount ++;
|
|
if (emptyLineCount<2)
|
|
{
|
|
epgText.push_back(text);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
emptyLineCount = 0;
|
|
epgText.push_back(text);
|
|
}
|
|
}
|
|
|
|
void CEpgData::processTextToArray(std::string text) // UTF-8
|
|
{
|
|
std::string aktLine = "";
|
|
std::string aktWord = "";
|
|
int aktWidth = 0;
|
|
text += ' ';
|
|
char* text_= (char*) text.c_str();
|
|
|
|
while (*text_!=0)
|
|
{
|
|
if ( (*text_==' ') || (*text_=='\n') || (*text_=='-') || (*text_=='.') )
|
|
{
|
|
// Houdini: if there is a newline (especially in the Premiere Portal EPGs) do not forget to add aktWord to aktLine
|
|
// after width check, if width check failes do newline, add aktWord to next line
|
|
// and "reinsert" i.e. reloop for the \n
|
|
if (*text_!='\n')
|
|
aktWord += *text_;
|
|
|
|
// check the wordwidth - add to this line if size ok
|
|
int aktWordWidth = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getRenderWidth(aktWord, true);
|
|
if ((aktWordWidth+aktWidth)<(ox- 20- 15))
|
|
{//space ok, add
|
|
aktWidth += aktWordWidth;
|
|
aktLine += aktWord;
|
|
|
|
if (*text_=='\n')
|
|
{ //enter-handler
|
|
addTextToArray( aktLine );
|
|
aktLine = "";
|
|
aktWidth= 0;
|
|
}
|
|
aktWord = "";
|
|
}
|
|
else
|
|
{//new line needed
|
|
addTextToArray( aktLine );
|
|
aktLine = aktWord;
|
|
aktWidth = aktWordWidth;
|
|
aktWord = "";
|
|
// Houdini: in this case where we skipped \n and space is too low, exec newline and rescan \n
|
|
// otherwise next word comes direct after aktLine
|
|
if (*text_=='\n')
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
aktWord += *text_;
|
|
}
|
|
text_++;
|
|
}
|
|
//add the rest
|
|
addTextToArray( aktLine + aktWord );
|
|
}
|
|
|
|
void CEpgData::showText( int startPos, int ypos )
|
|
{
|
|
// recalculate
|
|
medlineheight = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getHeight();
|
|
medlinecount = sb / medlineheight;
|
|
|
|
int textSize = epgText.size();
|
|
int y=ypos;
|
|
|
|
frameBuffer->paintBoxRel(sx, y, ox- 15, sb, COL_MENUCONTENT_PLUS_0); // background of the text box
|
|
|
|
for (int i = startPos; i < textSize && i < startPos + medlinecount; i++, y += medlineheight)
|
|
{
|
|
if ( i< info1_lines )
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->RenderString(sx+10, y+medlineheight, ox- 15- 15, epgText[i], COL_MENUCONTENT, 0, true); // UTF-8
|
|
else
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->RenderString(sx+10, y+medlineheight, ox- 15- 15, epgText[i], COL_MENUCONTENT, 0, true); // UTF-8
|
|
}
|
|
|
|
int sbc = ((textSize - 1)/ medlinecount) + 1;
|
|
int sbs= (startPos+ 1)/ medlinecount;
|
|
frameBuffer->paintBoxRel(sx+ ox- 15, ypos, 15, sb, COL_MENUCONTENT_PLUS_1); // scrollbar bg
|
|
frameBuffer->paintBoxRel(sx+ ox- 13, ypos+ 2+ sbs*(sb-4)/sbc , 11, (sb-4)/sbc, COL_MENUCONTENT_PLUS_3); // scrollbar
|
|
}
|
|
|
|
#define GENRE_MOVIE_COUNT 9
|
|
const neutrino_locale_t genre_movie[GENRE_MOVIE_COUNT] =
|
|
{
|
|
LOCALE_GENRE_MOVIE_0,
|
|
LOCALE_GENRE_MOVIE_1,
|
|
LOCALE_GENRE_MOVIE_2,
|
|
LOCALE_GENRE_MOVIE_3,
|
|
LOCALE_GENRE_MOVIE_4,
|
|
LOCALE_GENRE_MOVIE_5,
|
|
LOCALE_GENRE_MOVIE_6,
|
|
LOCALE_GENRE_MOVIE_7,
|
|
LOCALE_GENRE_MOVIE_8
|
|
};
|
|
#define GENRE_NEWS_COUNT 5
|
|
const neutrino_locale_t genre_news[GENRE_NEWS_COUNT] =
|
|
{
|
|
LOCALE_GENRE_NEWS_0,
|
|
LOCALE_GENRE_NEWS_1,
|
|
LOCALE_GENRE_NEWS_2,
|
|
LOCALE_GENRE_NEWS_3,
|
|
LOCALE_GENRE_NEWS_4
|
|
};
|
|
#define GENRE_SHOW_COUNT 4
|
|
const neutrino_locale_t genre_show[GENRE_SHOW_COUNT] =
|
|
{
|
|
LOCALE_GENRE_SHOW_0,
|
|
LOCALE_GENRE_SHOW_1,
|
|
LOCALE_GENRE_SHOW_2,
|
|
LOCALE_GENRE_SHOW_3
|
|
};
|
|
#define GENRE_SPORTS_COUNT 12
|
|
const neutrino_locale_t genre_sports[GENRE_SPORTS_COUNT] =
|
|
{
|
|
LOCALE_GENRE_SPORTS_0,
|
|
LOCALE_GENRE_SPORTS_1,
|
|
LOCALE_GENRE_SPORTS_2,
|
|
LOCALE_GENRE_SPORTS_3,
|
|
LOCALE_GENRE_SPORTS_4,
|
|
LOCALE_GENRE_SPORTS_5,
|
|
LOCALE_GENRE_SPORTS_6,
|
|
LOCALE_GENRE_SPORTS_7,
|
|
LOCALE_GENRE_SPORTS_8,
|
|
LOCALE_GENRE_SPORTS_9,
|
|
LOCALE_GENRE_SPORTS_10,
|
|
LOCALE_GENRE_SPORTS_11
|
|
};
|
|
#define GENRE_CHILDRENS_PROGRAMMES_COUNT 6
|
|
const neutrino_locale_t genre_childrens_programmes[GENRE_CHILDRENS_PROGRAMMES_COUNT] =
|
|
{
|
|
LOCALE_GENRE_CHILDRENS_PROGRAMMES_0,
|
|
LOCALE_GENRE_CHILDRENS_PROGRAMMES_1,
|
|
LOCALE_GENRE_CHILDRENS_PROGRAMMES_2,
|
|
LOCALE_GENRE_CHILDRENS_PROGRAMMES_3,
|
|
LOCALE_GENRE_CHILDRENS_PROGRAMMES_4,
|
|
LOCALE_GENRE_CHILDRENS_PROGRAMMES_5
|
|
};
|
|
#define GENRE_MUSIC_DANCE_COUNT 7
|
|
const neutrino_locale_t genre_music_dance[GENRE_MUSIC_DANCE_COUNT] =
|
|
{
|
|
LOCALE_GENRE_MUSIC_DANCE_0,
|
|
LOCALE_GENRE_MUSIC_DANCE_1,
|
|
LOCALE_GENRE_MUSIC_DANCE_2,
|
|
LOCALE_GENRE_MUSIC_DANCE_3,
|
|
LOCALE_GENRE_MUSIC_DANCE_4,
|
|
LOCALE_GENRE_MUSIC_DANCE_5,
|
|
LOCALE_GENRE_MUSIC_DANCE_6
|
|
};
|
|
#define GENRE_ARTS_COUNT 12
|
|
const neutrino_locale_t genre_arts_dance[GENRE_ARTS_COUNT] =
|
|
{
|
|
LOCALE_GENRE_ARTS_0,
|
|
LOCALE_GENRE_ARTS_1,
|
|
LOCALE_GENRE_ARTS_2,
|
|
LOCALE_GENRE_ARTS_3,
|
|
LOCALE_GENRE_ARTS_4,
|
|
LOCALE_GENRE_ARTS_5,
|
|
LOCALE_GENRE_ARTS_6,
|
|
LOCALE_GENRE_ARTS_7,
|
|
LOCALE_GENRE_ARTS_8,
|
|
LOCALE_GENRE_ARTS_9,
|
|
LOCALE_GENRE_ARTS_10,
|
|
LOCALE_GENRE_ARTS_11
|
|
};
|
|
#define GENRE_SOCIAL_POLITICAL_COUNT 4
|
|
const neutrino_locale_t genre_social_political[GENRE_SOCIAL_POLITICAL_COUNT] =
|
|
{
|
|
LOCALE_GENRE_SOCIAL_POLITICAL_0,
|
|
LOCALE_GENRE_SOCIAL_POLITICAL_1,
|
|
LOCALE_GENRE_SOCIAL_POLITICAL_2,
|
|
LOCALE_GENRE_SOCIAL_POLITICAL_3
|
|
};
|
|
#define GENRE_DOCUS_MAGAZINES_COUNT 8
|
|
const neutrino_locale_t genre_docus_magazines[GENRE_DOCUS_MAGAZINES_COUNT] =
|
|
{
|
|
LOCALE_GENRE_DOCUS_MAGAZINES_0,
|
|
LOCALE_GENRE_DOCUS_MAGAZINES_1,
|
|
LOCALE_GENRE_DOCUS_MAGAZINES_2,
|
|
LOCALE_GENRE_DOCUS_MAGAZINES_3,
|
|
LOCALE_GENRE_DOCUS_MAGAZINES_4,
|
|
LOCALE_GENRE_DOCUS_MAGAZINES_5,
|
|
LOCALE_GENRE_DOCUS_MAGAZINES_6,
|
|
LOCALE_GENRE_DOCUS_MAGAZINES_7
|
|
};
|
|
#define GENRE_TRAVEL_HOBBIES_COUNT 8
|
|
const neutrino_locale_t genre_travel_hobbies[GENRE_TRAVEL_HOBBIES_COUNT] =
|
|
{
|
|
LOCALE_GENRE_TRAVEL_HOBBIES_0,
|
|
LOCALE_GENRE_TRAVEL_HOBBIES_1,
|
|
LOCALE_GENRE_TRAVEL_HOBBIES_2,
|
|
LOCALE_GENRE_TRAVEL_HOBBIES_3,
|
|
LOCALE_GENRE_TRAVEL_HOBBIES_4,
|
|
LOCALE_GENRE_TRAVEL_HOBBIES_5,
|
|
LOCALE_GENRE_TRAVEL_HOBBIES_6,
|
|
LOCALE_GENRE_TRAVEL_HOBBIES_7
|
|
};
|
|
const unsigned char genre_sub_classes[10] =
|
|
{
|
|
GENRE_MOVIE_COUNT,
|
|
GENRE_NEWS_COUNT,
|
|
GENRE_SHOW_COUNT,
|
|
GENRE_SPORTS_COUNT,
|
|
GENRE_CHILDRENS_PROGRAMMES_COUNT,
|
|
GENRE_MUSIC_DANCE_COUNT,
|
|
GENRE_ARTS_COUNT,
|
|
GENRE_SOCIAL_POLITICAL_COUNT,
|
|
GENRE_DOCUS_MAGAZINES_COUNT,
|
|
GENRE_TRAVEL_HOBBIES_COUNT
|
|
};
|
|
const neutrino_locale_t * genre_sub_classes_list[10] =
|
|
{
|
|
genre_movie,
|
|
genre_news,
|
|
genre_show,
|
|
genre_sports,
|
|
genre_childrens_programmes,
|
|
genre_music_dance,
|
|
genre_arts_dance,
|
|
genre_social_political,
|
|
genre_docus_magazines,
|
|
genre_travel_hobbies
|
|
};
|
|
|
|
bool CEpgData::hasFollowScreenings(const t_channel_id /*channel_id*/, const std::string & title) {
|
|
time_t curtime = time(NULL);
|
|
|
|
for (CChannelEventList::iterator e = evtlist.begin(); e != evtlist.end(); ++e )
|
|
{
|
|
if (e->startTime > curtime && e->eventID && e->description == title)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
const char * GetGenre(const unsigned char contentClassification) // UTF-8
|
|
{
|
|
neutrino_locale_t res;
|
|
|
|
//unsigned char i = (contentClassification & 0x0F0);
|
|
int i = (contentClassification & 0xF0);
|
|
//printf("GetGenre: contentClassification %X i %X bool %s\n", contentClassification, i, i < 176 ? "yes" : "no"); fflush(stdout);
|
|
if ((i >= 0x010) && (i < 0x0B0))
|
|
{
|
|
i >>= 4;
|
|
i--;
|
|
//printf("GetGenre: i %d content %d\n", i, contentClassification & 0x0F); fflush(stdout);
|
|
res = genre_sub_classes_list[i][((contentClassification & 0x0F) < genre_sub_classes[i]) ? (contentClassification & 0x0F) : 0];
|
|
}
|
|
else
|
|
res = LOCALE_GENRE_UNKNOWN;
|
|
return g_Locale->getText(res);
|
|
}
|
|
|
|
static bool sortByDateTime (const CChannelEvent& a, const CChannelEvent& b)
|
|
{
|
|
return a.startTime< b.startTime;
|
|
}
|
|
|
|
extern char recDir[255];
|
|
void sectionsd_getEventsServiceKey(t_channel_id serviceUniqueKey, CChannelEventList &eList, char search = 0, std::string search_text = "");
|
|
bool sectionsd_getComponentTagsUniqueKey(const event_id_t uniqueKey, CSectionsdClient::ComponentTagList& tags);
|
|
|
|
int CEpgData::show(const t_channel_id channel_id, unsigned long long a_id, time_t* a_startzeit, bool doLoop )
|
|
{
|
|
int res = menu_return::RETURN_REPAINT;
|
|
static unsigned long long id;
|
|
static time_t startzeit;
|
|
|
|
if (a_startzeit)
|
|
startzeit=*a_startzeit;
|
|
id=a_id;
|
|
|
|
int height;
|
|
height = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->getHeight();
|
|
|
|
GetEPGData(channel_id, id, &startzeit );
|
|
if (doLoop)
|
|
{
|
|
if (!bigFonts && g_settings.bigFonts) {
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getSize() * BIG_FONT_FAKTOR));
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getSize() * BIG_FONT_FAKTOR));
|
|
}
|
|
bigFonts = g_settings.bigFonts;
|
|
start();
|
|
//evtlist = g_Sectionsd->getEventsServiceKey(channel_id&0xFFFFFFFFFFFFULL);
|
|
evtlist.clear();
|
|
sectionsd_getEventsServiceKey(channel_id&0xFFFFFFFFFFFFULL, evtlist);
|
|
// Houdini added for Private Premiere EPG start sorted by start date/time 2005-08-15
|
|
sort(evtlist.begin(),evtlist.end(),sortByDateTime);
|
|
}
|
|
|
|
if (epgData.title.empty()) /* no epg info found */
|
|
{
|
|
ShowHintUTF(LOCALE_MESSAGEBOX_INFO, g_Locale->getText(LOCALE_EPGVIEWER_NOTFOUND)); // UTF-8
|
|
hide();
|
|
return res;
|
|
}
|
|
|
|
int pos;
|
|
std::string text1 = epgData.title;
|
|
std::string text2 = "";
|
|
if (g_Font[SNeutrinoSettings::FONT_TYPE_EPG_TITLE]->getRenderWidth(text1) > ox - 15) // 15 for the scroll bar...
|
|
{
|
|
do
|
|
{
|
|
pos = text1.find_last_of("[ .]+");
|
|
if (pos != -1)
|
|
text1 = text1.substr(0, pos);
|
|
} while ((pos != -1) && (g_Font[SNeutrinoSettings::FONT_TYPE_EPG_TITLE]->getRenderWidth(text1) > ox - 15));
|
|
if (epgData.title.length() > text1.length()) // shold never be false in this place
|
|
text2 = epgData.title.substr(text1.length()+ 1, uint(-1) );
|
|
}
|
|
|
|
if (text2 != "")
|
|
toph = 2 * topboxheight;
|
|
else
|
|
toph = topboxheight;
|
|
if (toph < PIC_H)
|
|
toph = PIC_H;
|
|
|
|
sb = oy - toph - botboxheight;
|
|
|
|
// 21.07.2005 - rainerk
|
|
// Only show info1 if it's not included in info2!
|
|
std::string strEpisode = ""; // Episode title in case info1 gets stripped
|
|
if (!epgData.info1.empty()) {
|
|
bool bHide = false;
|
|
if (false == epgData.info2.empty()) {
|
|
// Look for the first . in info1, usually this is the title of an episode.
|
|
std::string::size_type nPosDot = epgData.info1.find('.');
|
|
if (std::string::npos != nPosDot) {
|
|
nPosDot += 2; // Skip dot and first blank
|
|
/* Houdini: changed for safty reason (crashes with some events at WDR regional)
|
|
if (nPosDot < epgData.info2.length()) { // Make sure we don't overrun the buffer
|
|
*/
|
|
if (nPosDot < epgData.info2.length() && nPosDot < epgData.info1.length()) { // Make sure we don't overrun the buffer
|
|
|
|
// Check if the stuff after the dot equals the beginning of info2
|
|
if (0 == epgData.info2.find(epgData.info1.substr(nPosDot, epgData.info1.length() - nPosDot))) {
|
|
strEpisode = epgData.info1.substr(0, nPosDot) + "\n";
|
|
bHide = true;
|
|
}
|
|
}
|
|
}
|
|
// Compare strings normally if not positively found to be equal before
|
|
if (false == bHide && false == (std::string::npos == epgData.info2.find(epgData.info1))) {
|
|
bHide = true;
|
|
}
|
|
}
|
|
if (false == bHide) {
|
|
processTextToArray(epgData.info1);
|
|
}
|
|
}
|
|
|
|
info1_lines = epgText.size();
|
|
|
|
//scan epg-data - sort to list
|
|
if ((epgData.info2.empty()) && (info1_lines == 0))
|
|
processTextToArray(g_Locale->getText(LOCALE_EPGVIEWER_NODETAILED)); // UTF-8
|
|
else
|
|
processTextToArray(strEpisode + epgData.info2);
|
|
|
|
// 21.07.2005 - rainerk
|
|
// Show extended information
|
|
if (0 != epgData.itemDescriptions.size() && 0 != epgData.items.size()) {
|
|
char line[256];
|
|
std::vector<std::string>::iterator description;
|
|
std::vector<std::string>::iterator item;
|
|
processTextToArray(""); // Add a blank line
|
|
for (description = epgData.itemDescriptions.begin(), item = epgData.items.begin(); description != epgData.itemDescriptions.end(), item != epgData.items.end(); ++description, ++item) {
|
|
sprintf(line, "%s: %s", (*(description)).c_str(), (*(item)).c_str());
|
|
processTextToArray(line);
|
|
}
|
|
}
|
|
|
|
if (epgData.fsk > 0)
|
|
{
|
|
char _tfsk[11];
|
|
sprintf (_tfsk, "FSK: ab %d", epgData.fsk );
|
|
processTextToArray( _tfsk ); // UTF-8
|
|
}
|
|
|
|
if (epgData.contentClassification.length()> 0)
|
|
processTextToArray(GetGenre(epgData.contentClassification[0])); // UTF-8
|
|
// processTextToArray( epgData.userClassification.c_str() );
|
|
|
|
|
|
// -- display more screenings on the same channel
|
|
// -- 2002-05-03 rasc
|
|
if (hasFollowScreenings(channel_id, epgData.title)) {
|
|
processTextToArray(""); // UTF-8
|
|
processTextToArray(std::string(g_Locale->getText(LOCALE_EPGVIEWER_MORE_SCREENINGS)) + ':'); // UTF-8
|
|
FollowScreenings(channel_id, epgData.title);
|
|
}
|
|
|
|
//show the epg
|
|
frameBuffer->paintBoxRel(sx, sy, ox, toph, COL_MENUHEAD_PLUS_0, ROUND_RADIUS, CORNER_TOP);
|
|
|
|
int pic_offx = 0;
|
|
if (g_PicViewer->DisplayLogo(channel_id, sx+10, sy + (toph-PIC_H)/2/*5*/, PIC_W, PIC_H))
|
|
pic_offx = PIC_W + 10;
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_TITLE]->RenderString(sx+15 + pic_offx, sy + topheight+ 3, ox-15- pic_offx, text1, COL_MENUHEAD, 0, true);
|
|
if (!(text2.empty()))
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_TITLE]->RenderString(sx+15+ pic_offx, sy+ 2* topheight+ 3, ox-15 - pic_offx, text2, COL_MENUHEAD, 0, true);
|
|
|
|
//show date-time....
|
|
frameBuffer->paintBoxRel(sx, sy+oy-botboxheight, ox, botboxheight, COL_MENUHEAD_PLUS_0);
|
|
std::string fromto;
|
|
int widthl,widthr;
|
|
fromto = epg_start;
|
|
fromto += " - ";
|
|
fromto += epg_end;
|
|
|
|
widthl = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->getRenderWidth(fromto);
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+40, sy+oy-3, widthl, fromto, COL_MENUHEAD);
|
|
widthr = g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->getRenderWidth(epg_date);
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ox-40-widthr, sy+oy-3, widthr, epg_date, COL_MENUHEAD);
|
|
|
|
int showPos = 0;
|
|
textCount = epgText.size();
|
|
showText(showPos, sy + toph);
|
|
|
|
// show Timer Event Buttons
|
|
showTimerEventBar (true);
|
|
|
|
//show Content&Component for Dolby & 16:9
|
|
CSectionsdClient::ComponentTagList tags;
|
|
if ( sectionsd_getComponentTagsUniqueKey( epgData.eventID, tags ) )
|
|
{
|
|
for (unsigned int i=0; i< tags.size(); i++)
|
|
{
|
|
if ( tags[i].streamContent == 1 && (tags[i].componentType == 2 || tags[i].componentType == 3) )
|
|
{
|
|
frameBuffer->paintIcon(NEUTRINO_ICON_16_9 ,ox+sx-(ICON_LARGE_WIDTH+2)-(ICON_LARGE_WIDTH+2),sy + oy+5 );
|
|
}
|
|
else if ( tags[i].streamContent == 2 && tags[i].componentType == 5 )
|
|
{
|
|
frameBuffer->paintIcon(NEUTRINO_ICON_DD, ox+sx-(ICON_LARGE_WIDTH+2), sy + oy+5);
|
|
}
|
|
}
|
|
}
|
|
|
|
//show progressbar
|
|
if ( epg_done!= -1 )
|
|
{
|
|
int pbx = sx + 10 + widthl + 10 + ((ox-104-widthr-widthl-10-10-20)>>1);
|
|
CProgressBar pb(g_settings.progressbar_color, -1, -1, 30, 100, 70, true);
|
|
pb.paintProgressBarDefault(pbx, sy+oy-height, 104, height-6, epg_done, 104);
|
|
}
|
|
|
|
GetPrevNextEPGData( epgData.eventID, &epgData.epg_times.startzeit );
|
|
if (prev_id != 0)
|
|
{
|
|
frameBuffer->paintBoxRel(sx+ 5, sy+ oy- botboxheight+ 4, botboxheight- 8, botboxheight- 8, COL_MENUCONTENT_PLUS_3);
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ 10, sy+ oy- 3, widthr, "<", COL_MENUCONTENT + 3);
|
|
}
|
|
|
|
if (next_id != 0)
|
|
{
|
|
frameBuffer->paintBoxRel(sx+ ox- botboxheight+ 8- 5, sy+ oy- botboxheight+ 4, botboxheight- 8, botboxheight- 8, COL_MENUCONTENT_PLUS_3);
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ ox- botboxheight+ 8, sy+ oy- 3, widthr, ">", COL_MENUCONTENT + 3);
|
|
}
|
|
|
|
if ( doLoop )
|
|
{
|
|
neutrino_msg_t msg;
|
|
neutrino_msg_data_t data;
|
|
|
|
int scrollCount;
|
|
|
|
bool loop = true;
|
|
|
|
unsigned long long timeoutEnd = CRCInput::calcTimeoutEnd(g_settings.timing[SNeutrinoSettings::TIMING_EPG]);
|
|
|
|
while (loop)
|
|
{
|
|
g_RCInput->getMsgAbsoluteTimeout( &msg, &data, &timeoutEnd );
|
|
|
|
scrollCount = medlinecount;
|
|
|
|
switch ( msg )
|
|
{
|
|
case NeutrinoMessages::EVT_TIMER:
|
|
if (data == g_InfoViewer->lcdUpdateTimer) {
|
|
GetEPGData(channel_id, id, &startzeit, false);
|
|
if ( epg_done!= -1 ) {
|
|
CProgressBar pb(g_settings.progressbar_color, -1, -1, 30, 100, 70, true);
|
|
int pbx = sx + 10 + widthl + 10 + ((ox-104-widthr-widthl-10-10-20)>>1);
|
|
pb.paintProgressBarDefault(pbx, sy+oy-height, 104, height-6, epg_done, 104);
|
|
}
|
|
}
|
|
CNeutrinoApp::getInstance()->handleMsg(msg, data);
|
|
break;
|
|
case NeutrinoMessages::EVT_CURRENTNEXT_EPG:
|
|
if (/*!id && */ ((*(t_channel_id *) data) == (channel_id & 0xFFFFFFFFFFFFULL))) {
|
|
show(channel_id,0,NULL,false);
|
|
showPos=0;
|
|
}
|
|
CNeutrinoApp::getInstance()->handleMsg(msg, data);
|
|
break;
|
|
case CRCInput::RC_left:
|
|
if (prev_id != 0)
|
|
{
|
|
frameBuffer->paintBoxRel(sx+ 5, sy+ oy- botboxheight+ 4, botboxheight- 8, botboxheight- 8, COL_MENUCONTENT_PLUS_1);
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ 10, sy+ oy- 3, widthr, "<", COL_MENUCONTENT + 1);
|
|
|
|
show(channel_id, prev_id, &prev_zeit, false);
|
|
showPos=0;
|
|
}
|
|
break;
|
|
|
|
case CRCInput::RC_right:
|
|
if (next_id != 0)
|
|
{
|
|
frameBuffer->paintBoxRel(sx+ ox- botboxheight+ 8- 5, sy+ oy- botboxheight+ 4, botboxheight- 8, botboxheight- 8, COL_MENUCONTENT_PLUS_1);
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_DATE]->RenderString(sx+ ox- botboxheight+ 8, sy+ oy- 3, widthr, ">", COL_MENUCONTENT + 1);
|
|
|
|
show(channel_id, next_id, &next_zeit, false);
|
|
showPos=0;
|
|
}
|
|
break;
|
|
|
|
case CRCInput::RC_down:
|
|
if (showPos+scrollCount<textCount)
|
|
{
|
|
showPos += scrollCount;
|
|
showText(showPos, sy + toph);
|
|
}
|
|
break;
|
|
|
|
case CRCInput::RC_up:
|
|
showPos -= scrollCount;
|
|
if (showPos<0)
|
|
showPos = 0;
|
|
else
|
|
showText(showPos, sy + toph);
|
|
break;
|
|
|
|
// 31.05.2002 dirch record timer
|
|
case CRCInput::RC_red:
|
|
if (!g_settings.minimode && (g_settings.recording_type != CNeutrinoApp::RECORDING_OFF))
|
|
{
|
|
//CTimerdClient timerdclient;
|
|
if (g_Timerd->isTimerdAvailable())
|
|
{
|
|
bool doRecord = true;
|
|
//char *recDir = g_settings.network_nfs_recordingdir;
|
|
strcpy(recDir, g_settings.network_nfs_recordingdir);
|
|
if (g_settings.recording_choose_direct_rec_dir == 2) {
|
|
CFileBrowser b;
|
|
b.Dir_Mode=true;
|
|
hide();
|
|
if (b.exec(g_settings.network_nfs_recordingdir)) {
|
|
strcpy(recDir, b.getSelectedFile()->Name.c_str());
|
|
} else
|
|
doRecord = false;
|
|
show(channel_id,epgData.eventID,&epgData.epg_times.startzeit,false);
|
|
}
|
|
else if (g_settings.recording_choose_direct_rec_dir == 1)
|
|
{
|
|
int lid = -1;
|
|
CMountChooser recDirs(LOCALE_TIMERLIST_RECORDING_DIR,NEUTRINO_ICON_SETTINGS,&lid,NULL,g_settings.network_nfs_recordingdir);
|
|
if (recDirs.hasItem())
|
|
{
|
|
hide();
|
|
recDirs.exec(NULL,"");
|
|
show(channel_id,epgData.eventID,&epgData.epg_times.startzeit,false);
|
|
} else
|
|
{
|
|
printf("no network devices available\n");
|
|
}
|
|
if (lid != -1)
|
|
strcpy(recDir, g_settings.network_nfs_local_dir[lid]);
|
|
//recDir = g_settings.network_nfs_local_dir[id];
|
|
//else
|
|
//recDir = NULL;
|
|
}
|
|
//if (recDir != NULL)
|
|
if (doRecord)
|
|
{
|
|
if (g_Timerd->addRecordTimerEvent(channel_id,
|
|
epgData.epg_times.startzeit,
|
|
epgData.epg_times.startzeit + epgData.epg_times.dauer,
|
|
epgData.eventID, epgData.epg_times.startzeit,
|
|
epgData.epg_times.startzeit - (ANNOUNCETIME + 120 ),
|
|
TIMERD_APIDS_CONF, true, recDir,false) == -1)
|
|
{
|
|
if (askUserOnTimerConflict(epgData.epg_times.startzeit - (ANNOUNCETIME + 120),
|
|
epgData.epg_times.startzeit + epgData.epg_times.dauer))
|
|
{
|
|
g_Timerd->addRecordTimerEvent(channel_id,
|
|
epgData.epg_times.startzeit,
|
|
epgData.epg_times.startzeit + epgData.epg_times.dauer,
|
|
epgData.eventID, epgData.epg_times.startzeit,
|
|
epgData.epg_times.startzeit - (ANNOUNCETIME + 120 ),
|
|
TIMERD_APIDS_CONF, true, recDir,true);
|
|
ShowLocalizedMessage(LOCALE_TIMER_EVENTRECORD_TITLE, LOCALE_TIMER_EVENTRECORD_MSG, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO);
|
|
}
|
|
} else {
|
|
ShowLocalizedMessage(LOCALE_TIMER_EVENTRECORD_TITLE, LOCALE_TIMER_EVENTRECORD_MSG, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
printf("timerd not available\n");
|
|
}
|
|
break;
|
|
|
|
// 31.05.2002 dirch zapto timer
|
|
case CRCInput::RC_yellow:
|
|
{
|
|
//CTimerdClient timerdclient;
|
|
if (g_Timerd->isTimerdAvailable())
|
|
{
|
|
g_Timerd->addZaptoTimerEvent(channel_id,
|
|
epgData.epg_times.startzeit,
|
|
epgData.epg_times.startzeit - ANNOUNCETIME, 0,
|
|
epgData.eventID, epgData.epg_times.startzeit, 0);
|
|
ShowLocalizedMessage(LOCALE_TIMER_EVENTTIMED_TITLE, LOCALE_TIMER_EVENTTIMED_MSG, CMessageBox::mbrBack, CMessageBox::mbBack, NEUTRINO_ICON_INFO);
|
|
}
|
|
else
|
|
printf("timerd not available\n");
|
|
break;
|
|
}
|
|
|
|
case CRCInput::RC_info:
|
|
case CRCInput::RC_help:
|
|
bigFonts = bigFonts ? false : true;
|
|
frameBuffer->paintBackgroundBox (sx, sy- toph, sx+ ox, sy+ oy);
|
|
showTimerEventBar (false);
|
|
start();
|
|
// textypos = sy;
|
|
//printf("bigFonts %d\n", bigFonts);
|
|
if (bigFonts)
|
|
{
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getSize() * BIG_FONT_FAKTOR));
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getSize() * BIG_FONT_FAKTOR));
|
|
} else
|
|
{
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getSize() / BIG_FONT_FAKTOR));
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getSize() / BIG_FONT_FAKTOR));
|
|
}
|
|
g_settings.bigFonts = bigFonts;
|
|
show(channel_id, id, &startzeit, false);
|
|
showPos=0;
|
|
break;
|
|
|
|
case CRCInput::RC_ok:
|
|
case CRCInput::RC_timeout:
|
|
loop = false;
|
|
break;
|
|
case CRCInput::RC_favorites:
|
|
case CRCInput::RC_sat:
|
|
g_RCInput->postMsg (msg, 0);
|
|
loop = false;
|
|
break;
|
|
|
|
default:
|
|
// konfigurierbare Keys handlen...
|
|
if (msg == (neutrino_msg_t)g_settings.key_channelList_cancel)
|
|
loop = false;
|
|
else
|
|
{
|
|
if ( CNeutrinoApp::getInstance()->handleMsg( msg, data ) & messages_return::cancel_all )
|
|
{
|
|
loop = false;
|
|
res = menu_return::RETURN_EXIT_ALL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
hide();
|
|
}
|
|
return res;
|
|
}
|
|
|
|
void CEpgData::hide()
|
|
{
|
|
// 2004-09-10 rasc (bugfix, scale large font settings back to normal)
|
|
if (bigFonts) {
|
|
bigFonts = false;
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO1]->getSize() / BIG_FONT_FAKTOR));
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->setSize((int)(g_Font[SNeutrinoSettings::FONT_TYPE_EPG_INFO2]->getSize() / BIG_FONT_FAKTOR));
|
|
}
|
|
|
|
frameBuffer->paintBackgroundBoxRel(sx, sy, ox, oy);
|
|
showTimerEventBar (false);
|
|
}
|
|
|
|
bool sectionsd_getEPGid(const event_id_t epgID, const time_t startzeit, CEPGData * epgdata);
|
|
bool sectionsd_getActualEPGServiceKey(const t_channel_id uniqueServiceKey, CEPGData * epgdata);
|
|
|
|
void CEpgData::GetEPGData(const t_channel_id channel_id, unsigned long long id, time_t* startzeit, bool clear )
|
|
{
|
|
if(clear)
|
|
epgText.clear();
|
|
emptyLineCount = 0;
|
|
epgData.title.clear();
|
|
|
|
bool res;
|
|
if ( id!= 0 )
|
|
//res = g_Sectionsd->getEPGid( id, *startzeit, &epgData );
|
|
res = sectionsd_getEPGid(id, *startzeit, &epgData);
|
|
else
|
|
//res = g_Sectionsd->getActualEPGServiceKey(channel_id&0xFFFFFFFFFFFFULL, &epgData );
|
|
res = sectionsd_getActualEPGServiceKey(channel_id&0xFFFFFFFFFFFFULL, &epgData );
|
|
|
|
if ( res )
|
|
{
|
|
// If we have items, merge and localize them (e.g. actor1, actor2, ... -> Actors)
|
|
if (false == epgData.itemDescriptions.empty()) {
|
|
reformatExtendedEvents("Year of production", g_Locale->getText(LOCALE_EPGEXTENDED_YEAR_OF_PRODUCTION), false, epgData);
|
|
reformatExtendedEvents("Original title", g_Locale->getText(LOCALE_EPGEXTENDED_ORIGINAL_TITLE), false, epgData);
|
|
reformatExtendedEvents("Director", g_Locale->getText(LOCALE_EPGEXTENDED_DIRECTOR), false, epgData);
|
|
reformatExtendedEvents("Actor", g_Locale->getText(LOCALE_EPGEXTENDED_ACTORS), true, epgData);
|
|
reformatExtendedEvents("Guests", g_Locale->getText(LOCALE_EPGEXTENDED_GUESTS), false, epgData);
|
|
reformatExtendedEvents("Presenter", g_Locale->getText(LOCALE_EPGEXTENDED_PRESENTER), false, epgData);
|
|
}
|
|
|
|
struct tm *pStartZeit = localtime(&(epgData.epg_times).startzeit);
|
|
tmp_curent_zeit = (epgData.epg_times).startzeit;
|
|
char temp[20]={0};
|
|
strftime( temp, sizeof(temp),"%d.%m.%Y", pStartZeit);
|
|
epg_date = g_Locale->getText(CLocaleManager::getWeekday(pStartZeit));
|
|
epg_date += ".";
|
|
epg_date += temp;
|
|
strftime( temp, sizeof(temp), "%H:%M", pStartZeit);
|
|
epg_start= temp;
|
|
|
|
long int uiEndTime((epgData.epg_times).startzeit+ (epgData.epg_times).dauer);
|
|
struct tm *pEndeZeit = localtime((time_t*)&uiEndTime);
|
|
strftime( temp, sizeof(temp), "%H:%M", pEndeZeit);
|
|
epg_end= temp;
|
|
|
|
epg_done= -1;
|
|
if (( time(NULL)- (epgData.epg_times).startzeit )>= 0 )
|
|
{
|
|
unsigned nProcentagePassed = ((time(NULL) - (epgData.epg_times).startzeit) * 100 / (epgData.epg_times).dauer);
|
|
if (nProcentagePassed<= 100)
|
|
epg_done= nProcentagePassed;
|
|
}
|
|
}
|
|
//printf("GetEPGData:: items %d descriptions %d\n", epgData.items.size(), epgData.itemDescriptions.size());
|
|
}
|
|
|
|
void CEpgData::GetPrevNextEPGData( unsigned long long id, time_t* startzeit )
|
|
{
|
|
prev_id= 0;
|
|
next_id= 0;
|
|
unsigned int i;
|
|
|
|
for ( i= 0; i< evtlist.size(); i++ )
|
|
{
|
|
//printf("%d %llx/%llx - %x %x\n", i, evtlist[i].eventID, id, evtlist[i].startTime, *startzeit);
|
|
if ( ( evtlist[i].eventID == id ) && ( evtlist[i].startTime == *startzeit ) )
|
|
{
|
|
if ( i > 0 )
|
|
{
|
|
prev_id= evtlist[i- 1].eventID;
|
|
prev_zeit= evtlist[i- 1].startTime;
|
|
}
|
|
if ( i < ( evtlist.size()- 1 ) )
|
|
{
|
|
next_id= evtlist[i+ 1].eventID;
|
|
next_zeit= evtlist[i+ 1].startTime;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
/* Houdini: dirty RTL double event workaround, if prev/next event has same starttime as actual event skip it */
|
|
if ((prev_zeit == *startzeit) && ((i-1) > 0))
|
|
{
|
|
prev_id = evtlist[i- 2].eventID;
|
|
prev_zeit = evtlist[i- 2].startTime;
|
|
}
|
|
if ((next_zeit == *startzeit) && ((i+1) < (evtlist.size()- 1)))
|
|
{
|
|
next_id = evtlist[i+ 2].eventID;
|
|
next_zeit = evtlist[i+ 2].startTime;
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// -- get following screenings of this program title
|
|
// -- yek! a better class design would be more helpfull
|
|
// -- BAD THING: Cross channel screenings will not be shown
|
|
// -- $$$TODO
|
|
// -- 2002-05-03 rasc
|
|
//
|
|
|
|
int CEpgData::FollowScreenings (const t_channel_id /*channel_id*/, const std::string & title)
|
|
|
|
{
|
|
CChannelEventList::iterator e;
|
|
struct tm *tmStartZeit;
|
|
std::string screening_dates,screening_nodual;
|
|
int count;
|
|
char tmpstr[256]={0};
|
|
|
|
|
|
count = 0;
|
|
screening_dates = screening_nodual = "";
|
|
// alredy read: evtlist = g_Sectionsd->getEventsServiceKey( channel_id&0xFFFFFFFFFFFFULL );
|
|
|
|
for ( e= evtlist.begin(); e != evtlist.end(); ++e )
|
|
{
|
|
if (e->startTime <= tmp_curent_zeit) continue;
|
|
if (! e->eventID) continue;
|
|
if (e->description == title) {
|
|
count++;
|
|
tmStartZeit = localtime(&(e->startTime));
|
|
|
|
screening_dates = " ";
|
|
|
|
screening_dates += g_Locale->getText(CLocaleManager::getWeekday(tmStartZeit));
|
|
screening_dates += '.';
|
|
|
|
strftime(tmpstr, sizeof(tmpstr), " %d.", tmStartZeit );
|
|
screening_dates += tmpstr;
|
|
|
|
screening_dates += g_Locale->getText(CLocaleManager::getMonth(tmStartZeit));
|
|
|
|
strftime(tmpstr, sizeof(tmpstr), ". %H:%M ", tmStartZeit );
|
|
screening_dates += tmpstr;
|
|
if (screening_dates != screening_nodual) {
|
|
screening_nodual=screening_dates;
|
|
processTextToArray(screening_dates ); // UTF-8
|
|
}
|
|
}
|
|
}
|
|
if (count == 0)
|
|
processTextToArray("---\n"); // UTF-8
|
|
return count;
|
|
}
|
|
|
|
|
|
//
|
|
// -- Just display or hide TimerEventbar
|
|
// -- 2002-05-13 rasc
|
|
//
|
|
|
|
void CEpgData::showTimerEventBar (bool pshow)
|
|
|
|
{
|
|
int x,y,w,h;
|
|
int cellwidth; // 4 cells
|
|
int h_offset, pos;
|
|
|
|
w = ox;
|
|
h = 30;
|
|
x = sx;
|
|
y = sy + oy;
|
|
h_offset = 5;
|
|
cellwidth = w / 4;
|
|
|
|
|
|
frameBuffer->paintBackgroundBoxRel(x,y,w,h);
|
|
// hide only?
|
|
if (! pshow) return;
|
|
|
|
frameBuffer->paintBoxRel(x,y,w,h, COL_MENUHEAD_PLUS_0, ROUND_RADIUS, CORNER_BOTTOM);//round
|
|
|
|
// Button: Timer Record & Channelswitch
|
|
if (g_settings.recording_type != CNeutrinoApp::RECORDING_OFF)
|
|
{
|
|
pos = 0;
|
|
frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_RED, x+8+cellwidth*pos, y+h_offset );
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->RenderString(x+29+cellwidth*pos, y+h-h_offset, w-30, g_Locale->getText(LOCALE_TIMERBAR_RECORDEVENT), COL_INFOBAR, 0, true); // UTF-8
|
|
}
|
|
// Button: Timer Channelswitch
|
|
pos = 2;
|
|
frameBuffer->paintIcon(NEUTRINO_ICON_BUTTON_YELLOW, x+8+cellwidth*pos, y+h_offset );
|
|
g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->RenderString(x+29+cellwidth*pos, y+h-h_offset, w-30, g_Locale->getText(LOCALE_TIMERBAR_CHANNELSWITCH), COL_INFOBAR, 0, true); // UTF-8
|
|
}
|
|
|
|
// -- EPG Data Viewer Menu Handler Class
|
|
// -- to be used for calls from Menue
|
|
// -- (2004-03-06 rasc)
|
|
|
|
int CEPGDataHandler::exec(CMenuTarget* parent, const std::string &/*actionkey*/)
|
|
{
|
|
int res = menu_return::RETURN_EXIT_ALL;
|
|
CChannelList *channelList;
|
|
CEpgData *e;
|
|
|
|
|
|
if (parent) {
|
|
parent->hide();
|
|
}
|
|
|
|
e = new CEpgData;
|
|
|
|
channelList = CNeutrinoApp::getInstance()->channelList;
|
|
e->show( channelList->getActiveChannel_ChannelID() );
|
|
delete e;
|
|
|
|
return res;
|
|
}
|