12 Commits

Author SHA1 Message Date
kamel5
4474b5f5b5 Version 1.2.4 2019-03-23 16:41:50 +01:00
kamel5
d5ecea55a6 Update "services/epgsearch.h" 2019-03-23 15:55:42 +01:00
kamel5
3a940d061c Center channel logos in favorite view 2019-03-23 15:44:46 +01:00
kamel5
10f6d90f16 Eliminate some warnings 2019-03-23 15:42:41 +01:00
kamel5
168973331c Fixed a "invalid lock sequence report" 2019-03-23 12:35:25 +01:00
kamel5
ff599e4cda Add "switchMinsBefore" to setup menu 2019-03-22 15:06:14 +01:00
kamel5
f7e5ac3208 Some cosmetic changes 2019-03-22 13:21:18 +01:00
kamel5
a8ca6f19da Set ff=unix for some files 2019-03-22 13:17:22 +01:00
kamel5
68af1b2086 Correct a switchtimer error 2019-03-20 16:12:54 +01:00
kamel5
d9b8af10e7 Makefile change from imagemagick to graphicsmagick 2019-02-28 14:10:27 +01:00
kamel5
9f98eddc41 Add italian translation 2019-02-28 13:45:22 +01:00
kamel5
431e99d1d4 Support for new SVDRPPeering 2019-02-04 12:02:46 +01:00
26 changed files with 1878 additions and 935 deletions

11
HISTORY
View File

@@ -147,3 +147,14 @@ Version 1.2.3
- Show inactive timer in EPG grid
- Center channel logos in EPG
- Clock in timeline if displaymode horizontal
Version 1.2.4
- Add Support for new SVDRPPeering
- Add italian translation
- Use graphicsmagick instead of imagemagick
- Correct a switchtimer error
- Add "switchMinsBefore" to setup menu
- Eliminate some warnings
- Center channel logos in favorite view
- Update "services/epgsearch.h"

View File

@@ -4,7 +4,8 @@
# $Id$
# External image lib to use: imagemagick, graphicsmagick
IMAGELIB = imagemagick
#IMAGELIB = imagemagick
IMAGELIB = graphicsmagick
# The official name of this plugin.
# This name will be used in the '-P...' option of VDR to load the plugin.
@@ -68,7 +69,8 @@ all: $(SOFILE) i18n
### Implicit rules:
%.o: %.c
$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
@echo CC $@
$(Q)$(CXX) $(CXXFLAGS) -c $(DEFINES) $(INCLUDES) -o $@ $<
### Dependencies:

View File

@@ -69,7 +69,7 @@ const char* cChannelGroups::GetPrev(int group) {
const char* cChannelGroups::GetNext(int group) {
if (group > -1) {
if ((group+1) < channelGroups.size())
if ((group+1) < (int)channelGroups.size())
return channelGroups[group+1].GetName();
}
return "";
@@ -89,7 +89,7 @@ int cChannelGroups::GetNextGroupChannelNumber(const cChannel *channel) {
int currentGroup = GetGroup(channel);
if (currentGroup == -1)
return 0;
if ((currentGroup+1) < channelGroups.size()) {
if ((currentGroup+1) < (int)channelGroups.size()) {
return channelGroups[currentGroup+1].StartChannel();
}
return 0;

View File

@@ -10,8 +10,8 @@ private:
int channel;
cChannelGroups *channelGroups;
int maxChannels;
int startTime;
int timeout;
long unsigned int startTime;
long unsigned int timeout;
cPixmap *pixmapBack;
cPixmap *pixmapText;
void SetPixmaps(void);
@@ -26,4 +26,4 @@ public:
int GetChannel(void) { return channel; };
};
#endif //__TVGUIDE_CHANNELJUMP_H
#endif //__TVGUIDE_CHANNELJUMP_H

View File

@@ -64,6 +64,7 @@ cTvguideConfig::cTvguideConfig() {
favLimitChannels = 0;
favStartChannel = 0;
favStopChannel = 0;
switchMinsBefore = 2;
fontIndex = 0;
fontNameDefault = "VDRSymbols Sans:Book";
FontButtonDelta = 0;
@@ -299,6 +300,7 @@ bool cTvguideConfig::SetupParse(const char *Name, const char *Value) {
else if (strcmp(Name, "favLimitChannels") == 0) favLimitChannels = atoi(Value);
else if (strcmp(Name, "favStartChannel") == 0) favStartChannel = atoi(Value);
else if (strcmp(Name, "favStopChannel") == 0) favStopChannel = atoi(Value);
else if (strcmp(Name, "switchMinsBefore") == 0) switchMinsBefore = atoi(Value);
else if (strcmp(Name, "fontIndex") == 0) fontIndex = atoi(Value);
else if (strcmp(Name, "FontButtonDelta") == 0) FontButtonDelta = atoi(Value);
else if (strcmp(Name, "FontDetailViewDelta") == 0) FontDetailViewDelta = atoi(Value);
@@ -331,4 +333,4 @@ bool cTvguideConfig::SetupParse(const char *Name, const char *Value) {
else if (strcmp(Name, "limitLogoCache") == 0) limitLogoCache = atoi(Value);
else return false;
return true;
}
}

View File

@@ -118,6 +118,7 @@ class cTvguideConfig {
int favLimitChannels;
int favStartChannel;
int favStopChannel;
int switchMinsBefore;
int fontIndex;
const char *fontNameDefault;
int FontButtonDelta;
@@ -252,4 +253,4 @@ 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

32
grid.h
View File

@@ -20,38 +20,38 @@ protected:
bool hasTimer;
bool hasSwitchTimer;
bool intersects(cGrid *neighbor);
virtual time_t Duration(void) {};
virtual time_t Duration(void) { return 0; };
virtual void drawText(void) {};
bool dummy;
public:
cGrid(cChannelColumn *c);
virtual ~cGrid(void);
cChannelColumn *column;
virtual void SetViewportHeight() {};
virtual void PositionPixmap() {};
virtual void SetViewportHeight(void) {};
virtual void PositionPixmap(void) {};
virtual void setText(void) {};
void Draw();
void SetDirty() {dirty = true;};
void SetActive() {dirty = true; active = true;};
void SetInActive() {dirty = true; active = false;};
void Draw(void);
void SetDirty(void) {dirty = true;};
void SetActive(void) {dirty = true; active = true;};
void SetInActive(void) {dirty = true; active = false;};
void SetColor(bool color) {isColor1 = color;};
bool IsColor1() {return isColor1;};
bool IsColor1(void) {return isColor1;};
bool isFirst(void);
virtual const cEvent *GetEvent() {};
virtual const cEvent *GetEvent(void) { return NULL; };
bool Match(time_t t);
virtual time_t StartTime() {};
virtual time_t EndTime() {};
virtual time_t StartTime(void) { return 0; };
virtual time_t EndTime(void) { return 0; };
virtual void SetStartTime(time_t start) {};
virtual void SetEndTime(time_t end) {};
int calcOverlap(cGrid *neighbor);
virtual void SetTimer() {};
virtual void SetSwitchTimer() {};
virtual void SetTimer(void) {};
virtual void SetSwitchTimer(void) {};
virtual cString getText(void) { return cString("");};
virtual cString getTimeString(void) { return cString("");};
bool Active(void) { return active; };
bool HasTimer() {return hasTimer;};
bool HasSwitchTimer() {return hasSwitchTimer;};
bool isDummy() { return dummy; };
bool HasTimer(void) {return hasTimer;};
bool HasSwitchTimer(void) {return hasSwitchTimer;};
bool isDummy(void) { return dummy; };
virtual void debug() {};
};

View File

@@ -351,7 +351,7 @@ cImage *cImageCache::GetLogo(const cChannel *channel) {
} else {
bool success = LoadLogo(channel);
if (success) {
if ((tvguideConfig.limitLogoCache) && (logoCache.size() >= tvguideConfig.numLogosMax)) {
if ((tvguideConfig.limitLogoCache) && ((int)logoCache.size() >= tvguideConfig.numLogosMax)) {
//logo cache is full, don't cache anymore
if (tempStaticLogo) {
delete tempStaticLogo;

View File

@@ -173,7 +173,7 @@ void cImageLoader::CreateGradient(tColor back, tColor blend, int width, int heig
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
PixelPacket *pixel = pixels + y * width + x;
int opacity = (maxw / width * x + maxh - maxh / height * y) / 2;
unsigned int opacity = (maxw / width * x + maxh - maxh / height * y) / 2;
pixel->opacity = (opacity <= MaxRGB) ? opacity : MaxRGB;
}
}
@@ -183,4 +183,4 @@ void cImageLoader::CreateGradient(tColor back, tColor blend, int width, int heig
imgback.composite(imgblend, 0, 0, OverCompositeOp);
buffer = imgback;
}
}

View File

@@ -145,7 +145,7 @@ void cImageMagickWrapper::CreateGradient(tColor back, tColor blend, int width, i
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
PixelPacket *pixel = pixels + y * width + x;
int opacity = (maxw / width * x + maxh - maxh / height * y) / 2;
unsigned int opacity = (maxw / width * x + maxh - maxh / height * y) / 2;
pixel->opacity = (opacity <= MaxRGB) ? opacity : MaxRGB;
}
}
@@ -159,4 +159,4 @@ void cImageMagickWrapper::CreateGradient(tColor back, tColor blend, int width, i
void cImageMagickWrapper::CreateBackground(tColor back, tColor blend, int width, int height) {
CreateGradient(back, blend, width, height, 0.8, 0.8);
}
}

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: 2014-05-10 17:24+0200\n"
"POT-Creation-Date: 2019-03-23 16:23+0100\n"
"PO-Revision-Date: 2012-08-25 17:49+0200\n"
"Last-Translator: Horst\n"
"Language-Team: \n"
@@ -807,6 +807,9 @@ msgstr "Benutzerdef. Zeit 4 in Favoriten benutzen"
msgid "Limit channels in favorites"
msgstr "Kanäle in Favoriten beschränken"
msgid "Minutes a switchtimer switches before start of a show"
msgstr "Umschalten (x)min vor Start der Sendung"
msgid "Create Log Messages for image loading"
msgstr "Log Nachrichten für das Laden der Bilder erzeugen"
@@ -938,4 +941,3 @@ msgstr "TheMovieDB Popularität"
msgid "TheMovieDB Vote Average"
msgstr "TheMovieDB durchschnittliche Bewertung"

941
po/it_IT.po Normal file
View File

@@ -0,0 +1,941 @@
# VDR plugin language source file.
msgid ""
msgstr ""
"Project-Id-Version: vdr-tvguide 0.0.1\n"
"Report-Msgid-Bugs-To: <see README>\n"
"POT-Creation-Date: 2014-05-10 17:24+0200\n"
"PO-Revision-Date: 2012-08-25 17:49+0200\n"
"Last-Translator: fiveten_59\n"
"Language-Team: \n"
"Language: it\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
msgid "Main Program"
msgstr "Programma principale"
msgid "Channel"
msgstr "Canale"
msgid "min"
msgstr "min"
msgid "Reruns of "
msgstr "Riavvio di "
msgid "No reruns found"
msgstr "Nessun riavvio trovato"
msgid "No EPG Information available"
msgstr "Nessuna informazione EPG disponibile"
msgid "Search & Rec"
msgstr "Cerca & Registra"
msgid "Channels back"
msgstr "Canale precedente"
msgid "Channels forward"
msgstr "Canale seguente"
msgid "Switch to Channel"
msgstr "Cambia al Canale"
msgid "Detailed EPG"
msgstr "EPG dettagliato"
msgid "Close detailed EPG"
msgstr "Chiudi EPG dettagliato"
msgid "Favorites"
msgstr "Favoriti"
msgid "images"
msgstr "Immagini"
msgid "root video folder"
msgstr "cartella video di root"
msgid "Transp."
msgstr "Transp."
msgid "Timer Conflict"
msgstr "Timer in conflitto"
msgid "all Channels"
msgstr "Tutti i Canali"
msgid "unknown channel"
msgstr "Canale sconosciuto"
msgid "Duration"
msgstr "Durata"
msgid "recorded at"
msgstr "registrato a"
msgid "from"
msgstr "da"
msgid "Timers for"
msgstr "Timers per"
msgid "Rec"
msgstr "Rec"
msgid "No Timers active"
msgstr "Nessun Timer attivo"
msgid "inactive"
msgstr "inattivo"
msgid "active timers"
msgstr "Timers attivi"
msgid "recordings done"
msgstr "registrazione eseguita"
msgid "What's on now"
msgstr "Was läuft jetzt?"
msgid "What's on next"
msgstr "Was läuft als nächstes?"
msgid "Instant Record"
msgstr "Registrazione immediata"
msgid "Delete Timer"
msgstr "Cancella il Timer"
msgid "Edit Timer"
msgstr "Edita il Timer"
msgid "Timer Timeline"
msgstr "Scadenza del Timer"
msgid "Create Search Timer"
msgstr "Crea Search Timer"
msgid "Search Timers"
msgstr "Search Timers"
msgid "Create Series Timer"
msgstr "Crea Series Timer"
msgid "Create Switch Timer"
msgstr "Crea lo Switch Timer"
msgid "Delete Switch Timer"
msgstr "Rimuovi lo Switch Timer"
msgid "Search"
msgstr "Cerca"
msgid "Check for Timer Conflicts"
msgstr "Verifica conflitti del Timer"
msgid "Search in Recordings"
msgstr "Cerca nelle registrazioni"
msgid "Set Folder for"
msgstr "Crea cartella per"
msgid "Timer created"
msgstr "Timer creato"
msgid "Timer NOT created"
msgstr "Timer non creato"
msgid "OK"
msgstr "OK"
msgid "Timer deleted"
msgstr "Timer eliminato"
msgid "Timer"
msgstr "Timer"
msgid "still recording - really delete?"
msgstr "registrazione in corso - vuoi veramente eliminare?"
msgid "Yes"
msgstr "Si"
msgid "No"
msgstr "No"
msgid "One"
msgstr "Uno"
msgid "detected"
msgstr "rilevato"
msgid "Timer Conflicts"
msgstr "Conflitti del Timer"
msgid "Show conflict"
msgstr "Mostra conflitto"
msgid "timers involved"
msgstr "Timers impegnati"
msgid "Ignore Conflicts"
msgstr "Ignora conflitti"
msgid "Ignore Conflict"
msgstr "Ignora conflitto"
msgid "No Timer Conflicts found"
msgstr "Nessun conflitto rilevato nel Timer"
msgid "Close"
msgstr "Chiudere"
msgid "reruns for"
msgstr "riavvii per"
msgid "rerun for"
msgstr "riavvio per"
msgid "found"
msgstr "trovato"
msgid "Ignore reruns"
msgstr "Wiederholungen ignorieren"
msgid "No reruns found for Event"
msgstr "Nessun riavvio trovato per l'evento"
msgid "Timer for"
msgstr "Timer per"
msgid "replaced by rerun"
msgstr "rimosso dal riavvio"
msgid "Timer Active"
msgstr "Timer attivo"
msgid "Priority"
msgstr "Priorità"
msgid "Lifetime"
msgstr "Durata"
msgid "Day"
msgstr "Giorno"
msgid "Timer start time"
msgstr "Ora d'inizio del Timer"
msgid "Timer stop time"
msgstr "Ora finale del Timer"
msgid "Timer File"
msgstr "File del Timer"
msgid "New Folder"
msgstr "Nuova cartella"
msgid "Save"
msgstr "Salva"
msgid "Cancel"
msgstr "Cancella"
msgid "Create Series Timer based on"
msgstr "Crea il Series Timer basato su"
msgid "Series Timer start time"
msgstr "Ora d'avvio del Series Timer"
msgid "Series Timer stop time"
msgstr "Ora di chiusura del Series Timer"
msgid "Days to record"
msgstr "Giorni da registrare"
msgid "Day to start"
msgstr "Giorno d'inizio"
msgid "Create Timer"
msgstr "Crea il Timer"
msgid "Series Timer created"
msgstr "Series Timer creato"
msgid "Start"
msgstr "Avvio"
msgid "Stop"
msgstr "Ferma"
msgid "Configure Search Timer based on"
msgstr "Configura il Search Timer in serie basato su"
msgid "Search Expression:"
msgstr "Cerca espressione:"
msgid "Continue"
msgstr "Continua"
msgid "Configure Search Timer for Search String"
msgstr "Configura il Search Timer basato su Search String"
msgid "Manually configure Options"
msgstr "Configura manualmente le Opzioni"
msgid "Use Template"
msgstr "Utilizza Template"
msgid "EPGSearch Search Timers"
msgstr "EPGSearch Search Timers"
msgid "No Search Timers Configured"
msgstr "Messun Search Timers configurato"
msgid "Configure Search Timer Options"
msgstr "Configura le opzione del Search Timer"
msgid "Save Search Timer"
msgstr "Salva il Search Timer"
msgid "Search String"
msgstr "Suchbegriff"
msgid "Active"
msgstr "Attivo"
msgid "Search Mode"
msgstr "Modalità di ricerca"
msgid "Use Title"
msgstr "Usa Titolo"
msgid "Use Subtitle"
msgstr "Usa Sottotitolo"
msgid "Use Description"
msgstr "Usa Descrizione"
msgid "Limit Channels"
msgstr "Limite Canale"
msgid "Use Time"
msgstr "Utilizza Time"
msgid "Display advanced Options"
msgstr "Mostra Opzioni avanzate"
msgid "Limit Days of the Week"
msgstr "Limite dei giorni della settimana"
msgid "Time margin for start in minutes"
msgstr "Margine di tempo per l'avvio in minuti"
msgid "Time margin for stop in minutes"
msgstr "Margine di tempo per lo stop in minuti"
msgid "Series Recording"
msgstr "Serie di registrazioni"
msgid "Folder"
msgstr "Cartella"
msgid "Use VPS"
msgstr "Utilizza VPS"
msgid "Avoid Repeats"
msgstr "Evita ripetizioni"
msgid "Use in Favorites"
msgstr "Utilizza nei favoriti"
msgid "Hide advanced Options"
msgstr "Nascondi Opzioni avanzate"
msgid "Display Results for Search Timer"
msgstr "Mostra risultati per il Search Timer"
msgid "Start Channel"
msgstr "Avvia il Canale"
msgid "Stop Channel"
msgstr "Ferma il Canale"
msgid "Start after"
msgstr "Avvia dopo"
msgid "Start before"
msgstr "Avvia prima"
msgid "Select Days"
msgstr "Seleziona i giorni"
msgid "Number of allowed repeats"
msgstr "Numero di ripetizioni permesse"
msgid "Compare Title"
msgstr "Confonta Titolo"
msgid "Compare Subtitle"
msgstr "Confonta Sottotitolo"
msgid "Compare Description"
msgstr "Confonta Descrizione"
msgid "Really delete Search Timer"
msgstr "Veramente eliminare il Search Timer"
msgid "Delete only Search Timer"
msgstr "Elimina solo il Search Timer"
msgid "Delete Search Timer and created Timers"
msgstr "Elimina il Search Timer e Timers creati"
msgid "Search Timer sucessfully created."
msgstr "Search Timer creato con successo"
msgid "Search Timer update initialised"
msgstr "Search Timer aggiornato con successo"
msgid "Search Timer NOT sucessfully created"
msgstr "Suchtimer NICHT erfolgreich angelegt"
msgid "Creating Search Timer"
msgstr "Creando il Search Timer"
msgid "Search Term"
msgstr "Suchbegriff"
msgid "Using Template"
msgstr "Template"
msgid "Use other Template"
msgstr "Anderes Template benutzen"
msgid "search results for Favorite"
msgstr "Suchergebnisse für Favorit"
msgid "search result for Favorite"
msgstr "Suchergebnis für Favorit"
msgid "search results for Search Timer"
msgstr "Treffer für Suchtimer"
msgid "search result for Search Timer"
msgstr "Treffer für Suchtimer"
msgid "Nothing found for Search String"
msgstr "Keine Treffer für Suchbegriff"
msgid "Configure Options for Switchtimer"
msgstr "Optionen für Umschalttimer konfigurieren"
msgid "Minutes before switching"
msgstr "Minuten vor umschalten"
msgid "switch"
msgstr "cambio"
msgid "announce only"
msgstr "Segnala solamente"
msgid "ask for switch"
msgstr "chiedi per cambiare"
msgid "Switch Mode"
msgstr "Modalità Switch"
msgid "Create"
msgstr "Creare"
msgid "Switch Timer sucessfully created"
msgstr "Switch Timer creato con successo"
msgid "Switch Timer NOT sucessfully created"
msgstr "Switch Timer NON creato"
msgid "Switch Timer deleted"
msgstr "Switch Timer eliminato"
msgid "Channel to Search"
msgstr "Canale da cercare"
msgid "Search in title"
msgstr "Cerca nel titolo"
msgid "Search in Subtitle"
msgstr "Cerca nel sottotitolo"
msgid "Search in Description"
msgstr "Cerca nella descrizione"
msgid "Show Search Options"
msgstr "Mostra opzioni di ricerca"
msgid "Perform Search"
msgstr "Fai una ricerca"
msgid "search results for"
msgstr "cerca risultati per"
msgid "search result for"
msgstr "cerca risultato per"
msgid "Adapt Search"
msgstr "Adatta la ricerca"
msgid "Search String has to have at least three letters"
msgstr "Search String deve avere almeno tre lettere"
msgid "Found"
msgstr "Trovato"
msgid "recording"
msgstr "registrazione"
msgid "recordings"
msgstr "registrazioni"
msgid "for"
msgstr "per"
msgid "No recordings found for"
msgstr "Nessuna registrazione trovata per"
msgid "No Favorites available"
msgstr "Nessun Favoriti disponibile"
msgid "whole term must appear"
msgstr "vollständiger Ausdruck"
msgid "all terms must exist"
msgstr "tutte le parole devono esistere"
msgid "one term must exist"
msgstr "ein Wort"
msgid "exact match"
msgstr "exakt"
msgid "regular expression"
msgstr "Regulärer Ausdruck"
msgid "General Settings"
msgstr "Allgemeine Einstellungen"
msgid "Screen Presentation"
msgstr "Anzeigeoptionen"
msgid "Fonts and Fontsizes"
msgstr "Schriften und Schriftgrößen"
msgid "Recording Menus and Favorites"
msgstr "Aufzeichnungsmenü und Favoriten"
msgid "Image Loading and Caching"
msgstr "Image Loading und Caching"
msgid "x channels back / forward"
msgstr "x canali precedente / successivo"
msgid "previous / next channel group"
msgstr "precedente / successivo Gruppo Canali"
msgid "Blue: Channel Switch, Ok: Detailed EPG"
msgstr "Blu: Cambio canale, OK: EPG dettagliat"
msgid "Blue: Detailed EPG, Ok: Channel Switch"
msgstr "Blu: EPG dettagliato, OK: Cambio canale"
msgid "Blue: Favorites / Switch, Ok: Detailed EPG"
msgstr "Blau: Favoriten / Umschalten, OK: Det. EPG"
msgid "Timely Jump"
msgstr "Zeitsprung"
msgid "Jump to specific channel"
msgstr "Passa ad uno specifico canale"
msgid "never"
msgstr "mai"
msgid "if exists"
msgstr "se esiste"
msgid "always"
msgstr "sempre"
msgid "Show Main Menu Entry"
msgstr "Hauptmenüeintrag anzeigen"
msgid "Replace VDR Schedules Menu"
msgstr "VDR Programm Menü ersetzen"
msgid "Use appropriate nOpacity Theme"
msgstr "Entsprechendes nOpacity Theme benutzen"
msgid "Theme"
msgstr "Tema"
msgid "Time to display in minutes"
msgstr "Angezeigte Zeitspanne in Minuten"
msgid "Rounded Corners"
msgstr "Angoli arrotondati"
msgid "Channel Jump Mode (Keys Green / Yellow)"
msgstr "Modalità cambio canale (Tasti verde / giallo)"
msgid "Keys Blue and OK"
msgstr "Tasto Blu e OK"
msgid "Close TVGuide after channel switch"
msgstr "Chiudi TVGuide dopo cambio canale"
msgid "Functionality of numeric Keys"
msgstr "Funzionalità dei tasti numerici"
msgid "Hide last Channel Group"
msgstr "Nascondi l'ultimo Gruppo Canali"
msgid "Big Step (Keys 1 / 3) in hours"
msgstr "Piccolo salto (Tasti 1 / 3) in ore"
msgid "Huge Step (Keys 4 / 6) in hours"
msgstr "Gran salto (Tasti 4 / 6) in ore"
msgid "Time Format (12h/24h)"
msgstr "Formato ora (12h/24h)"
msgid "EPG Window Text Scrolling Speed"
msgstr "Velocità di scorrimento della finestra EPG"
msgid "Display Reruns in detailed EPG View"
msgstr "Wiederholungen in der detailierten EPG Ansicht anzeigen"
msgid "Number of reruns to display"
msgstr "Numero di riavvii da visualizzare"
msgid "Use Subtitle for reruns"
msgstr "Untertitel für Wiederholungssuche nutzen"
msgid "Display Mode"
msgstr "Anzeigemodus"
msgid "Height of Channel Header (Perc. of osd height)"
msgstr "Höhe des Kanalheaders (% der OSD Höhe)"
msgid "Width of Timeline (Perc. of osd width)"
msgstr "Breite der Zeitleiste (% der OSD Breite)"
msgid "Number of Channels to display"
msgstr "Anzahl der angezeigten Kanäle"
msgid "Width of Channel Header (Perc. of osd width)"
msgstr "Breite des Kanalheaders (% der OSD Breite)"
msgid "Height of Timeline (Perc. of osd height)"
msgstr "Höhe der Zeitleiste (% der OSD Höhe)"
msgid "Display time in EPG Grids"
msgstr "Zeit in EPG Grids anzeigen"
msgid "Height of Headers (Status Header and EPG View, Perc. of osd height)"
msgstr "Höhe der Header (Status Header und EPG View, % der OSD Höhe)"
msgid "Height of Footer (Perc. of osd height)"
msgstr "Höhe des Footers (% der OSD Höhe)"
msgid "Display status header"
msgstr "Status Header anzeigen"
msgid "Scale video to upper right corner"
msgstr "Video in obere rechte Ecke skalieren"
msgid "Rounded corners around video frame"
msgstr "Abgerundete Ecken um Videofenster"
msgid "Display Channel Names in Header"
msgstr "Kanalnamen im Header anzeigen"
msgid "Display channel groups"
msgstr "Kanalgruppen anzeigen"
msgid "Height of channel groups (Perc. of osd height)"
msgstr "Höhe der Kanalgruppen (% der OSD Höhe)"
msgid "Width of channel groups (Perc. of osd width)"
msgstr "Breite der Kanalgruppen (% der OSD Breite)"
msgid "Display current time baseline"
msgstr "Linie für aktuelle Uhrzeit anzeigen"
msgid "Show Channel Logos"
msgstr "Kanallogos anzeigen"
msgid "Logo Path used"
msgstr "Benutzer Pfad für Kanallogos"
msgid "Logo Extension"
msgstr "Logo Extension"
msgid "Logo width ratio"
msgstr "Logo Breitenverhältnis"
msgid "Logo height ratio"
msgstr "Logo Höhenverhältnis"
msgid "Text Border in Detailed View (pixel)"
msgstr "Rand im detailierten EPG View"
msgid "Show EPG Images"
msgstr "EPG Bilder anzeigen"
msgid "EPG Images Path used"
msgstr "Benutzer EPG Bilder Pfad"
msgid "EPG Image width"
msgstr "Breite der EPG Bilder"
msgid "EPG Image height"
msgstr "Höhe der EPG Bilder"
msgid "Number of additional EPG Images"
msgstr "Anzahl zusätzlicher EPG Bilder"
msgid "Additional EPG Image width"
msgstr "Breite der zus. EPG Bilder"
msgid "Additional EPG Image height"
msgstr "Höhe der zus. EPG Bilder"
msgid "Font"
msgstr "Font"
msgid "Status Header Font Size"
msgstr "Status Header Schriftgröße"
msgid "Status Header Large Font Size"
msgstr "Status Header große Schriftgröße"
msgid "Detail EPG View Font Size"
msgstr "Detailierte EPG Ansicht Schriftgröße"
msgid "Detail EPG View Header Font Size"
msgstr "Detailierte EPG Ansicht Header Schriftgröße"
msgid "Message Font Size"
msgstr "Nachrichten Schriftgröße"
msgid "Message Large Font Size"
msgstr "Nachrichten große Schriftgröße"
msgid "Button Font Size"
msgstr "Button Schriftgröße"
msgid "Channel Header Font Size"
msgstr "Kanal Header Schriftgröße"
msgid "Channel Groups Font Size"
msgstr "Kanalgruppen Schriftgröße"
msgid "Grid Font Size"
msgstr "Grid Schriftgröße"
msgid "Grid Font Small Size"
msgstr "Grid kleine Schriftgröße"
msgid "Timeline Weekday Font Size"
msgstr "Zeitleiste Wochentag Schriftgröße"
msgid "Timeline Date Font Size"
msgstr "Zeitleiste Datum Schriftgröße"
msgid "Timeline Time Font Size"
msgstr "Zeitleiste Zeit Schriftgröße"
msgid "Search & Recording Menu Font Size"
msgstr "Suchen & Aufnehmen Menu Schriftgröße"
msgid "Search & Recording Menu Small Font Size"
msgstr "Suchen & Aufnehmen Menu kleine Schriftgröße"
msgid "Search & Recording Menu Header Font Size"
msgstr "Suchen & Aufnehmen Menu Header Schriftgröße"
msgid "Always use root video folder"
msgstr "Usa sempre la cartella video di root"
msgid "Select from folder list"
msgstr "Scegli dall'elenco cartelle"
msgid "Use fixed folder"
msgstr "Usa cartella fissa"
msgid "Folder for instant Recordings"
msgstr "Cartella per la registrazione immediata"
msgid "Use Remotetimers"
msgstr "Usa Remotetimers"
msgid "Use \"What's on now\" in favorites"
msgstr "Usa \"In programma ora\" nei favoriti"
msgid "Use \"What's on next\" in favorites"
msgstr "Usa \"Programma prossimo\" nei favoriti"
msgid "Use user defined time 1 in favorites"
msgstr "Usa il tempo definito per l'user 1 in favoriti"
msgid "Description"
msgstr "Descrizione"
msgid "Time"
msgstr "Tempo"
msgid "Use user defined time 2 in favorites"
msgstr "Usa il tempo definito per l'user 2 in favoriti"
msgid "Use user defined time 3 in favorites"
msgstr "Usa il tempo definito per l'user 3 in favoriti"
msgid "Use user defined time 4 in favorites"
msgstr "Usa il tempo definito per l'user 4 in favoriti"
msgid "Limit channels in favorites"
msgstr "Limite dei canali nei favoriti"
msgid "Create Log Messages for image loading"
msgstr "Log Nachrichten für das Laden der Bilder erzeugen"
msgid "Limit Logo Cache"
msgstr "Logo Cash beschränken"
msgid "Maximal number of logos to cache"
msgstr "Maximale Anzahl Logos"
msgid "Number of logos to cache at start"
msgstr "Anzahl der zu cachenden Logos beim Start"
msgid "Cache Sizes"
msgstr "Cache Größe"
msgid "OSD Element Cache"
msgstr "OSD Element Cache"
msgid "Logo cache"
msgstr "Logo Cache"
msgid "EPG Grid Cache"
msgstr "EPG Grid Cache"
msgid "Channel Groups Cache"
msgstr "Cache dei Gruppi Canale"
msgid "Recording Menus Icon Cache"
msgstr "Recording Menüs Icon Cache"
msgid "No Cast available"
msgstr "Nessun cast disponibile"
msgid "Cast"
msgstr "Besetzung"
msgid "EPG Info"
msgstr "EPG Info"
msgid "Reruns"
msgstr "riavvii"
msgid "Recording Information"
msgstr ""
msgid "Image Galery"
msgstr "Bildergalerie"
msgid "TheTVDB Info"
msgstr "TheTVDB Info"
msgid "TheTVDB Information"
msgstr "TheTVDB Information"
msgid "Episode"
msgstr "Episodio"
msgid "Season"
msgstr "Stagione"
msgid "Episode Overview"
msgstr "Episodenüberblick"
msgid "First aired"
msgstr "Erstausstrahlung"
msgid "Guest Stars"
msgstr "Guest Stars"
msgid "TheMovieDB Rating"
msgstr "Voto di TheMovieDB"
msgid "Series Overview"
msgstr "Serienüberblick"
msgid "Genre"
msgstr "Genere"
msgid "Network"
msgstr "Network"
msgid "Status"
msgstr "Status"
msgid "TheMovieDB Information"
msgstr "TheMovieDB Information"
msgid "Original Title"
msgstr "Titolo Originale"
msgid "Tagline"
msgstr "Zusammenfassung"
msgid "Overview"
msgstr "Überblick"
msgid "yes"
msgstr "Si"
msgid "no"
msgstr "No"
msgid "Adult"
msgstr "Per adulti"
msgid "Collection"
msgstr "Kollektion"
msgid "Budget"
msgstr "Budget"
msgid "Revenue"
msgstr "Einnahmen"
msgid "Homepage"
msgstr "Homepage"
msgid "Release Date"
msgstr "Data di rilascio"
msgid "Runtime"
msgstr "Runtime"
msgid "minutes"
msgstr "Minuti"
msgid "TheMovieDB Popularity"
msgstr "TheMovieDB Popularità"
msgid "TheMovieDB Vote Average"
msgstr "Voto medio di TheMovieDB"

View File

@@ -93,6 +93,8 @@ cTimer *cRecManager::createTimer(const cEvent *event, std::string path) {
cTimer *cRecManager::createLocalTimer(const cEvent *event, std::string path) {
cTimer *timer = new cTimer(event);
#if VDRVERSNUM >= 20301
if (Setup.SVDRPPeering && *Setup.SVDRPDefaultHost)
((cTimer*)timer)->SetRemote(Setup.SVDRPDefaultHost);
LOCK_TIMERS_WRITE;
cTimer *t = Timers->GetTimer(timer);
#else
@@ -757,9 +759,8 @@ void cRecManager::GetFavorites(std::vector<cTVGuideSearchTimer> *favorites) {
const cEvent **cRecManager::WhatsOnNow(bool nowOrNext, int &numResults) {
std::vector<const cEvent*> tmpResults;
#if VDRVERSNUM >= 20301
LOCK_SCHEDULES_READ;
LOCK_CHANNELS_READ;
// const cChannels* channels = Channels;
LOCK_SCHEDULES_READ;
const cSchedules* schedules = Schedules;
#else
cSchedulesLock schedulesLock;

View File

@@ -1831,7 +1831,7 @@ void cRecMenuItemEvent::Draw(void) {
if (!tvguideConfig.hideChannelLogos) {
if (imgLoader.LoadLogo(channel, logoWidth, height)) {
cImage logo = imgLoader.GetImage();
pixmapText->DrawImage(cPoint(logoX, 0), logo);
pixmapText->DrawImage(cPoint(logoX, (height - logo.Height()) / 2), logo);
logoX += logoWidth + 5;
}
}

View File

@@ -85,7 +85,7 @@ cRecMenuItem *cRecMenuAskFolder::GetMenuItem(int number) {
if (number == 0) {
cRecMenuItem *result = new cRecMenuItemButton(tr("root video folder"), rmsInstantRecord, false, false, true);
return result;
} else if ((number > 0) && (number < folders.size()+1)) {
} else if ((number > 0) && (number < (int)folders.size() + 1)) {
cRecMenuItem *result = new cRecMenuItemButton(folders[number-1].c_str(), rmsInstantRecord, false, false, true);
return result;
}
@@ -99,7 +99,7 @@ int cRecMenuAskFolder::GetTotalNumMenuItems(void) {
std::string cRecMenuAskFolder::GetFolder(void) {
std::string folder = "";
int folderActive = GetActive();
if (folderActive > 0 && folderActive < folders.size() + 1)
if (folderActive > 0 && folderActive < (int)folders.size() + 1)
folder = folders[folderActive - 1];
return folder;
}
@@ -275,7 +275,7 @@ cRecMenuTimerConflict::cRecMenuTimerConflict(cTVGuideTimerConflict *conflict) {
}
cRecMenuItem *cRecMenuTimerConflict::GetMenuItem(int number) {
if ((number >= 0) && (number < conflict->timerIDs.size())) {
if ((number >= 0) && (number < (int)conflict->timerIDs.size())) {
#if VDRVERSNUM >= 20301
LOCK_TIMERS_READ;
const cTimer *timer = Timers->Get(conflict->timerIDs[number]);
@@ -677,7 +677,7 @@ int cRecMenuSearchTimerTemplates::GetTotalNumMenuItems(void) {
TVGuideEPGSearchTemplate cRecMenuSearchTimerTemplates::GetTemplate(void) {
TVGuideEPGSearchTemplate templ;
int tmplActive = GetActive() - 1;
if (tmplActive >= 0 && tmplActive < templates.size())
if (tmplActive >= 0 && tmplActive < (int)templates.size())
templ = templates[tmplActive];
return templ;
}
@@ -1109,7 +1109,7 @@ cRecMenuSearchTimerNothingFound::cRecMenuSearchTimerNothingFound(std::string sea
// --- cRecMenuSwitchTimer ---------------------------------------------------------
cRecMenuSwitchTimer::cRecMenuSwitchTimer(void) {
switchMinsBefore = 2;
switchMinsBefore = tvguideConfig.switchMinsBefore;
announceOnly = 0;
SetWidthPercent(60);

View File

@@ -31,172 +31,160 @@ The project's page is at http://winni.vdr-developer.org/epgsearch
#include <vdr/osdbase.h>
// Data structure for service "Epgsearch-search-v1.0"
struct Epgsearch_search_v1_0
{
struct Epgsearch_search_v1_0 {
// in
char* query; // search term
int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression)
int channelNr; // channel number to search in (0=any)
bool useTitle; // search in title
bool useSubTitle; // search in subtitle
bool useDescription; // search in description
char* query; // search term
int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression)
int channelNr; // channel number to search in (0=any)
bool useTitle; // search in title
bool useSubTitle; // search in subtitle
bool useDescription; // search in description
// out
cOsdMenu* pResultMenu; // pointer to the menu of results
cOsdMenu* pResultMenu; // pointer to the menu of results
};
// Data structure for service "Epgsearch-exttimeredit-v1.0"
struct Epgsearch_exttimeredit_v1_0
{
struct Epgsearch_exttimeredit_v1_0 {
// in
cTimer* timer; // pointer to the timer to edit
bool bNew; // flag that indicates, if this is a new timer or an existing one
const cEvent* event; // pointer to the event corresponding to this timer (may be NULL)
cTimer* timer; // pointer to the timer to edit
bool bNew; // flag that indicates, if this is a new timer or an existing one
const cEvent* event; // pointer to the event corresponding to this timer (may be NULL)
// out
cOsdMenu* pTimerMenu; // pointer to the menu of results
cOsdMenu* pTimerMenu; // pointer to the menu of results
};
// Data structure for service "Epgsearch-enablesearchtimers-v1.0"
struct Epgsearch_enablesearchtimers_v1_0
{
struct Epgsearch_enablesearchtimers_v1_0 {
// in
bool enable; // enable search timer thread?
bool enable; // enable search timer thread?
};
// Data structure for service "Epgsearch-updatesearchtimers-v1.0"
struct Epgsearch_updatesearchtimers_v1_0
{
struct Epgsearch_updatesearchtimers_v1_0 {
// in
bool showMessage; // inform via osd when finished?
bool showMessage; // inform via osd when finished?
};
// Data structure for service "Epgsearch-osdmessage-v1.0"
struct Epgsearch_osdmessage_v1_0
{
struct Epgsearch_osdmessage_v1_0 {
// in
char* message; // the message to display
eMessageType type;
char* message; // the message to display
eMessageType type;
};
// Data structure for service "EpgsearchMenu-v1.0"
struct EpgSearchMenu_v1_0
{
struct EpgSearchMenu_v1_0 {
// in
// out
cOsdMenu* Menu; // pointer to the menu
cOsdMenu* Menu; // pointer to the menu
};
// Data structure for service "Epgsearch-lastconflictinfo-v1.0"
struct Epgsearch_lastconflictinfo_v1_0
{
struct Epgsearch_lastconflictinfo_v1_0 {
// in
// out
time_t nextConflict; // next conflict date, 0 if none
int relevantConflicts; // number of relevant conflicts
int totalConflicts; // total number of conflicts
time_t nextConflict; // next conflict date, 0 if none
int relevantConflicts; // number of relevant conflicts
int totalConflicts; // total number of conflicts
};
// Data structure for service "Epgsearch-searchresults-v1.0"
struct Epgsearch_searchresults_v1_0
{
struct Epgsearch_searchresults_v1_0 {
// in
char* query; // search term
int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression)
int channelNr; // channel number to search in (0=any)
bool useTitle; // search in title
bool useSubTitle; // search in subtitle
bool useDescription; // search in description
char* query; // search term
int mode; // search mode (0=phrase, 1=and, 2=or, 3=regular expression)
int channelNr; // channel number to search in (0=any)
bool useTitle; // search in title
bool useSubTitle; // search in subtitle
bool useDescription; // search in description
// out
class cServiceSearchResult : public cListObject
{
public:
const cEvent* event;
cServiceSearchResult(const cEvent* Event) : event(Event) {}
};
class cServiceSearchResult : public cListObject
{
public:
const cEvent* event;
cServiceSearchResult(const cEvent* Event) : event(Event) {}
};
cList<cServiceSearchResult>* pResultList; // pointer to the results
cList<cServiceSearchResult>* pResultList; // pointer to the results
};
// Data structure for service "Epgsearch-switchtimer-v1.0"
struct Epgsearch_switchtimer_v1_0
{
struct Epgsearch_switchtimer_v1_0 {
// in
const cEvent* event;
int mode; // mode (0=query existence, 1=add/modify, 2=delete)
const cEvent* event;
int mode; // mode (0=query existence, 1=add/modify, 2=delete)
// in/out
int switchMinsBefore;
int announceOnly;
int switchMinsBefore;
int announceOnly;
// out
bool success; // result
bool success; // result
};
// Data structures for service "Epgsearch-services-v1.0"
class cServiceHandler
{
public:
virtual std::list<std::string> SearchTimerList() = 0;
// returns a list of search timer entries in the same format as used in epgsearch.conf
virtual int AddSearchTimer(const std::string&) = 0;
// adds a new search timer and returns its ID (-1 on error)
virtual bool ModSearchTimer(const std::string&) = 0;
// edits an existing search timer and returns success
virtual bool DelSearchTimer(int) = 0;
// deletes search timer with given ID and returns success
virtual std::list<std::string> QuerySearchTimer(int) = 0;
// returns the search result of the searchtimer with given ID in the same format as used in SVDRP command 'QRYS' (->MANUAL)
virtual std::list<std::string> QuerySearch(std::string) = 0;
// returns the search result of the searchtimer with given settings in the same format as used in SVDRP command 'QRYS' (->MANUAL)
virtual std::list<std::string> ExtEPGInfoList() = 0;
// returns a list of extended EPG categories in the same format as used in epgsearchcats.conf
virtual std::list<std::string> ChanGrpList() = 0;
// returns a list of channel groups maintained by epgsearch
virtual std::list<std::string> BlackList() = 0;
// returns a list of blacklists in the same format as used in epgsearchblacklists.conf
virtual std::set<std::string> DirectoryList() = 0;
// List of all recording directories used in recordings, timers, search timers or in epgsearchdirs.conf
virtual ~cServiceHandler() {}
// Read a setup value
virtual std::string ReadSetupValue(const std::string& entry) = 0;
// Write a setup value
virtual bool WriteSetupValue(const std::string& entry, const std::string& value) = 0;
public:
virtual std::list<std::string> SearchTimerList() = 0;
// returns a list of search timer entries in the same format as used in epgsearch.conf
virtual int AddSearchTimer(const std::string&) = 0;
// adds a new search timer and returns its ID (-1 on error)
virtual bool ModSearchTimer(const std::string&) = 0;
// edits an existing search timer and returns success
virtual bool DelSearchTimer(int) = 0;
// deletes search timer with given ID and returns success
virtual std::list<std::string> QuerySearchTimer(int) = 0;
// returns the search result of the searchtimer with given ID in the same format as used in SVDRP command 'QRYS' (->MANUAL)
virtual std::list<std::string> QuerySearch(std::string) = 0;
// returns the search result of the searchtimer with given settings in the same format as used in SVDRP command 'QRYS' (->MANUAL)
virtual std::list<std::string> ExtEPGInfoList() = 0;
// returns a list of extended EPG categories in the same format as used in epgsearchcats.conf
virtual std::list<std::string> ChanGrpList() = 0;
// returns a list of channel groups maintained by epgsearch
virtual std::list<std::string> BlackList() = 0;
// returns a list of blacklists in the same format as used in epgsearchblacklists.conf
virtual std::set<std::string> DirectoryList() = 0;
// List of all recording directories used in recordings, timers, search timers or in epgsearchdirs.conf
virtual ~cServiceHandler() {}
// Read a setup value
virtual std::string ReadSetupValue(const std::string& entry) = 0;
// Write a setup value
virtual bool WriteSetupValue(const std::string& entry, const std::string& value) = 0;
};
struct Epgsearch_services_v1_0
{
struct Epgsearch_services_v1_0 {
// in/out
std::auto_ptr<cServiceHandler> handler;
std::unique_ptr<cServiceHandler> handler;
};
// Data structures for service "Epgsearch-services-v1.1"
class cServiceHandler_v1_1 : public cServiceHandler
{
public:
// Get timer conflicts
virtual std::list<std::string> TimerConflictList(bool relOnly=false) = 0;
// Check if a conflict check is advised
virtual bool IsConflictCheckAdvised() = 0;
public:
// Get timer conflicts
virtual std::list<std::string> TimerConflictList(bool relOnly = false) = 0;
// Check if a conflict check is advised
virtual bool IsConflictCheckAdvised() = 0;
};
struct Epgsearch_services_v1_1
{
struct Epgsearch_services_v1_1 {
// in/out
std::auto_ptr<cServiceHandler_v1_1> handler;
std::unique_ptr<cServiceHandler_v1_1> handler;
};
// Data structures for service "Epgsearch-services-v1.2"
class cServiceHandler_v1_2 : public cServiceHandler_v1_1
{
public:
// List of all recording directories used in recordings, timers (and optionally search timers or in epgsearchdirs.conf)
virtual std::set<std::string> ShortDirectoryList() = 0;
// Evaluate an expression against an event
virtual std::string Evaluate(const std::string& expr, const cEvent* event) = 0;
public:
// List of all recording directories used in recordings, timers (and optionally search timers or in epgsearchdirs.conf)
virtual std::set<std::string> ShortDirectoryList() = 0;
// Evaluate an expression against an event
virtual std::string Evaluate(const std::string& expr, const cEvent* event) = 0;
};
struct Epgsearch_services_v1_2
{
struct Epgsearch_services_v1_2 {
// in/out
std::auto_ptr<cServiceHandler_v1_2> handler;
std::unique_ptr<cServiceHandler_v1_2> handler;
};
#endif

View File

@@ -121,6 +121,7 @@ void cTvguideSetup::Store(void) {
SetupStore("favLimitChannels", tvguideConfig.favLimitChannels);
SetupStore("favStartChannel", tvguideConfig.favStartChannel);
SetupStore("favStopChannel", tvguideConfig.favStopChannel);
SetupStore("switchMinsBefore", tvguideConfig.switchMinsBefore);
SetupStore("fontIndex", tvguideConfig.fontIndex);
SetupStore("FontButtonDelta", tvguideConfig.FontButtonDelta);
SetupStore("FontDetailViewDelta", tvguideConfig.FontDetailViewDelta);
@@ -419,6 +420,7 @@ void cMenuSetupFavorites::Set(void) {
Add(new cMenuEditChanItem(tr("Start Channel"), &tmpTvguideConfig->favStartChannel));
Add(new cMenuEditChanItem(tr("Stop Channel"), &tmpTvguideConfig->favStopChannel));
}
Add(new cMenuEditIntItem(tr("Minutes a switchtimer switches before start of a show"), &tmpTvguideConfig->switchMinsBefore, 0, 10));
SetCurrent(Get(currentItem));

View File

@@ -82,4 +82,4 @@ class cMenuSetupImageCache : public cMenuSetupSubMenu {
cMenuSetupImageCache(cTvguideConfig *data);
};
#endif //__TVGUIDE_SETUP_H
#endif //__TVGUIDE_SETUP_H

View File

@@ -6,13 +6,15 @@ cSwitchTimers SwitchTimers;
cSwitchTimer::cSwitchTimer(void) {
eventID = 0;
startTime = 0;
switchMinsBefore = 2;
switchMinsBefore = tvguideConfig.switchMinsBefore;
announceOnly = 0;
}
cSwitchTimer::cSwitchTimer(const cEvent* Event) {
eventID = 0;
startTime = 0;
switchMinsBefore = tvguideConfig.switchMinsBefore;
announceOnly = 0;
if (Event) {
eventID = Event->EventID();
channelID = Event->ChannelID();
@@ -20,17 +22,6 @@ cSwitchTimer::cSwitchTimer(const cEvent* Event) {
}
}
#if VDRVERSNUM >= 20305
cSwitchTimer& cSwitchTimer::operator= (const cSwitchTimer &SwitchTimer)
{
this->eventID = SwitchTimer.eventID;
this->startTime = SwitchTimer.startTime;
this->channelID = SwitchTimer.channelID;
this->switchMinsBefore = SwitchTimer.switchMinsBefore;
return *this;
}
#endif
bool cSwitchTimer::Parse(const char *s) {
char *line;
char *pos;

View File

@@ -2,6 +2,7 @@
#define __TVGUIDE_SWITCHTIMER_H
#include <vdr/plugin.h>
#include "config.h"
class cSwitchTimer : public cListObject {
public:
@@ -12,7 +13,15 @@ public:
int announceOnly;
#if VDRVERSNUM >= 20305
cSwitchTimer(const cSwitchTimer &SwitchTimer) { *this = SwitchTimer; };
cSwitchTimer& operator= (const cSwitchTimer &SwitchTimer);
cSwitchTimer& operator= (const cSwitchTimer &SwitchTimer)
{
this->eventID = SwitchTimer.eventID;
this->startTime = SwitchTimer.startTime;
this->channelID = SwitchTimer.channelID;
this->switchMinsBefore = SwitchTimer.switchMinsBefore;
this->announceOnly = SwitchTimer.announceOnly;
return *this;
};
#endif
cSwitchTimer(void);
cSwitchTimer(const cEvent* Event);

View File

@@ -1,187 +1,181 @@
#include <string>
#include <vector>
#include <vdr/timers.h>
#include "tools.h"
#include "timer.h"
#include "timerconflict.h"
cTVGuideTimerConflict::cTVGuideTimerConflict(void) {
time = 0;
timeStart = 0;
timeStop = 0;
overlapStart = 0;
overlapStop = 0;
percentPossible = 0;
timerID = 0;
}
cTVGuideTimerConflict::~cTVGuideTimerConflict(void) {
}
bool cTVGuideTimerConflict::timerInvolved(int involvedID) {
int numConflicts = timerIDs.size();
for (int i=0; i<numConflicts; i++) {
if (timerIDs[i] == involvedID)
return true;
}
return false;
}
// --- cTVGuideTimerConflicts------------------------------------
cTVGuideTimerConflicts::cTVGuideTimerConflicts(void) {
numConflicts = 0;
currentConflict = -1;
}
cTVGuideTimerConflicts::~cTVGuideTimerConflicts(void) {
for(std::vector<cTVGuideTimerConflict*>::const_iterator it = conflicts.begin(); it != conflicts.end(); it++) {
cTVGuideTimerConflict *conf = *it;
delete conf;
}
conflicts.clear();
}
void cTVGuideTimerConflicts::AddConflict(std::string epgSearchConflictLine) {
/* TIMERCONFLICT FORMAT:
The result list looks like this for example when we have 2 timer conflicts at one time:
1190232780:152|30|50#152#45:45|10|50#152#45
'1190232780' is the time of the conflict in seconds since 1970-01-01.
It's followed by list of timers that have a conflict at this time:
'152|30|50#1 int editTimer(cTimer *timer, bool active, int prio, int start, int stop);
52#45' is the description of the first conflicting timer. Here:
'152' is VDR's timer id of this timer as returned from VDR's LSTT command
'30' is the percentage of recording that would be done (0...100)
'50#152#45' is the list of concurrent timers at this conflict
'45|10|50#152#45' describes the next conflict
*/
cTVGuideTimerConflict *conflict = new cTVGuideTimerConflict();
splitstring s(epgSearchConflictLine.c_str());
std::vector<std::string> flds = s.split(':');
if (flds.size() < 2)
return;
conflict->time = atoi(flds[0].c_str());
splitstring s2(flds[1].c_str());
std::vector<std::string> flds2 = s2.split('|');
if (flds2.size() < 3)
return;
conflict->timerID = atoi(flds2[0].c_str());
conflict->percentPossible = atoi(flds2[1].c_str());
splitstring s3(flds2[2].c_str());
std::vector<std::string> flds3 = s3.split('#');
std::vector<int> timerIDs;
for (int k = 0; k < flds3.size(); k++) {
timerIDs.push_back(atoi(flds3[k].c_str()) - 1);
}
conflict->timerIDs = timerIDs;
conflicts.push_back(conflict);
}
void cTVGuideTimerConflicts::CalculateConflicts(void) {
numConflicts = conflicts.size();
// time_t startTime = 0;
// time_t endTime = 0;
for (int i=0; i < numConflicts; i++) {
cTimeInterval *unionSet = NULL;
int numTimers = conflicts[i]->timerIDs.size();
for (int j=0; j < numTimers; j++) {
#if VDRVERSNUM >= 20301
LOCK_TIMERS_READ;
const cTimer *timer = Timers->Get(conflicts[i]->timerIDs[j]);
#else
const cTimer *timer = Timers.Get(conflicts[i]->timerIDs[j]);
#endif
if (timer) {
if (!unionSet) {
unionSet = new cTimeInterval(timer->StartTime(), timer->StopTime());
} else {
cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime());
cTimeInterval *newUnion = unionSet->Union(timerInterval);
delete unionSet;
delete timerInterval;
unionSet = newUnion;
}
}
}
conflicts[i]->timeStart = unionSet->Start();
conflicts[i]->timeStop = unionSet->Stop();
delete unionSet;
cTimeInterval *intersect = NULL;
for (int j=0; j < numTimers; j++) {
#if VDRVERSNUM >= 20301
LOCK_TIMERS_READ;
const cTimer *timer = Timers->Get(conflicts[i]->timerIDs[j]);
#else
const cTimer *timer = Timers.Get(conflicts[i]->timerIDs[j]);
#endif
if (timer) {
if (!intersect) {
intersect = new cTimeInterval(timer->StartTime(), timer->StopTime());
} else {
cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime());
cTimeInterval *newIntersect = intersect->Intersect(timerInterval);
if (newIntersect) {
delete intersect;
intersect = newIntersect;
}
delete timerInterval;
}
}
}
conflicts[i]->overlapStart = intersect->Start();
conflicts[i]->overlapStop = intersect->Stop();
delete intersect;
}
}
cTVGuideTimerConflict *cTVGuideTimerConflicts::GetCurrentConflict(void) {
if (currentConflict < 0)
return NULL;
if (currentConflict > (numConflicts-1))
return NULL;
return conflicts[currentConflict];
}
int cTVGuideTimerConflicts::GetCurrentConflictTimerID(int timerIndex) {
if (currentConflict < 0)
return -1;
if (currentConflict > (numConflicts-1))
return -1;
int numTimersInConflict = conflicts[currentConflict]->timerIDs.size();
if (timerIndex > (numTimersInConflict - 1))
return -1;
return conflicts[currentConflict]->timerIDs[timerIndex];
}
int cTVGuideTimerConflicts::GetCorrespondingConflict(int timerID) {
int conflictIndex = -1;
if (numConflicts > 0) {
for (int i=0; i<numConflicts; i++) {
if (conflicts[i]->timerInvolved(timerID)) {
conflictIndex = i;
break;
}
}
}
return conflictIndex;
}
cTVGuideTimerConflict *cTVGuideTimerConflicts::GetConflict(int conflictIndex) {
if (conflictIndex < 0)
return NULL;
if (conflictIndex > (numConflicts-1))
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;
}
#include <string>
#include <vector>
#include <vdr/timers.h>
#include "tools.h"
#include "timer.h"
#include "timerconflict.h"
cTVGuideTimerConflict::cTVGuideTimerConflict(void) {
time = 0;
timeStart = 0;
timeStop = 0;
overlapStart = 0;
overlapStop = 0;
percentPossible = 0;
timerID = 0;
}
cTVGuideTimerConflict::~cTVGuideTimerConflict(void) {
}
bool cTVGuideTimerConflict::timerInvolved(int involvedID) {
int numConflicts = timerIDs.size();
for (int i=0; i<numConflicts; i++) {
if (timerIDs[i] == involvedID)
return true;
}
return false;
}
// --- cTVGuideTimerConflicts------------------------------------
cTVGuideTimerConflicts::cTVGuideTimerConflicts(void) {
numConflicts = 0;
currentConflict = -1;
}
cTVGuideTimerConflicts::~cTVGuideTimerConflicts(void) {
for(std::vector<cTVGuideTimerConflict*>::const_iterator it = conflicts.begin(); it != conflicts.end(); it++) {
cTVGuideTimerConflict *conf = *it;
delete conf;
}
conflicts.clear();
}
void cTVGuideTimerConflicts::AddConflict(std::string epgSearchConflictLine) {
/* TIMERCONFLICT FORMAT:
The result list looks like this for example when we have 2 timer conflicts at one time:
1190232780:152|30|50#152#45:45|10|50#152#45
'1190232780' is the time of the conflict in seconds since 1970-01-01.
It's followed by list of timers that have a conflict at this time:
'152|30|50#1 int editTimer(cTimer *timer, bool active, int prio, int start, int stop);
52#45' is the description of the first conflicting timer. Here:
'152' is VDR's timer id of this timer as returned from VDR's LSTT command
'30' is the percentage of recording that would be done (0...100)
'50#152#45' is the list of concurrent timers at this conflict
'45|10|50#152#45' describes the next conflict
*/
cTVGuideTimerConflict *conflict = new cTVGuideTimerConflict();
splitstring s(epgSearchConflictLine.c_str());
std::vector<std::string> flds = s.split(':');
if (flds.size() < 2)
return;
conflict->time = atoi(flds[0].c_str());
splitstring s2(flds[1].c_str());
std::vector<std::string> flds2 = s2.split('|');
if (flds2.size() < 3)
return;
conflict->timerID = atoi(flds2[0].c_str());
conflict->percentPossible = atoi(flds2[1].c_str());
splitstring s3(flds2[2].c_str());
std::vector<std::string> flds3 = s3.split('#');
std::vector<int> timerIDs;
for (int k = 0; k < (int)flds3.size(); k++) {
timerIDs.push_back(atoi(flds3[k].c_str()) - 1);
}
conflict->timerIDs = timerIDs;
conflicts.push_back(conflict);
}
void cTVGuideTimerConflicts::CalculateConflicts(void) {
numConflicts = conflicts.size();
for (int i=0; i < numConflicts; i++) {
cTimeInterval *unionSet = NULL;
int numTimers = conflicts[i]->timerIDs.size();
#if VDRVERSNUM >= 20301
LOCK_TIMERS_READ;
const cTimers* timers = Timers;
#else
const cTimers* timers = &Timers;
#endif
for (int j=0; j < numTimers; j++) {
const cTimer *timer = timers->Get(conflicts[i]->timerIDs[j]);
if (timer) {
if (!unionSet) {
unionSet = new cTimeInterval(timer->StartTime(), timer->StopTime());
} else {
cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime());
cTimeInterval *newUnion = unionSet->Union(timerInterval);
delete unionSet;
delete timerInterval;
unionSet = newUnion;
}
}
}
conflicts[i]->timeStart = unionSet->Start();
conflicts[i]->timeStop = unionSet->Stop();
delete unionSet;
cTimeInterval *intersect = NULL;
for (int j=0; j < numTimers; j++) {
const cTimer *timer = timers->Get(conflicts[i]->timerIDs[j]);
if (timer) {
if (!intersect) {
intersect = new cTimeInterval(timer->StartTime(), timer->StopTime());
} else {
cTimeInterval *timerInterval = new cTimeInterval(timer->StartTime(), timer->StopTime());
cTimeInterval *newIntersect = intersect->Intersect(timerInterval);
if (newIntersect) {
delete intersect;
intersect = newIntersect;
}
delete timerInterval;
}
}
}
conflicts[i]->overlapStart = intersect->Start();
conflicts[i]->overlapStop = intersect->Stop();
delete intersect;
}
}
cTVGuideTimerConflict *cTVGuideTimerConflicts::GetCurrentConflict(void) {
if (currentConflict < 0)
return NULL;
if (currentConflict > (numConflicts-1))
return NULL;
return conflicts[currentConflict];
}
int cTVGuideTimerConflicts::GetCurrentConflictTimerID(int timerIndex) {
if (currentConflict < 0)
return -1;
if (currentConflict > (numConflicts-1))
return -1;
int numTimersInConflict = conflicts[currentConflict]->timerIDs.size();
if (timerIndex > (numTimersInConflict - 1))
return -1;
return conflicts[currentConflict]->timerIDs[timerIndex];
}
int cTVGuideTimerConflicts::GetCorrespondingConflict(int timerID) {
int conflictIndex = -1;
if (numConflicts > 0) {
for (int i=0; i<numConflicts; i++) {
if (conflicts[i]->timerInvolved(timerID)) {
conflictIndex = i;
break;
}
}
}
return conflictIndex;
}
cTVGuideTimerConflict *cTVGuideTimerConflicts::GetConflict(int conflictIndex) {
if (conflictIndex < 0)
return NULL;
if (conflictIndex > (numConflicts-1))
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

@@ -1,38 +1,38 @@
#ifndef __TVGUIDE_TIMERCONFLICT_H
#define __TVGUIDE_TIMERCONFLICT_H
class cTVGuideTimerConflict {
public:
cTVGuideTimerConflict(void);
virtual ~cTVGuideTimerConflict(void);
time_t time;
time_t timeStart;
time_t timeStop;
time_t overlapStart;
time_t overlapStop;
int percentPossible;
int timerID;
std::vector<int> timerIDs;
bool timerInvolved(int involvedID);
};
class cTVGuideTimerConflicts {
private:
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);
int GetCorrespondingConflict(int timerID);
cTVGuideTimerConflict *GetConflict(int conflictIndex);
std::vector<cTVGuideTimerConflict*> GetConflictsBetween(time_t start, time_t stop);
};
#endif //__TVGUIDE_RECMMANAGER_H
#ifndef __TVGUIDE_TIMERCONFLICT_H
#define __TVGUIDE_TIMERCONFLICT_H
class cTVGuideTimerConflict {
public:
cTVGuideTimerConflict(void);
virtual ~cTVGuideTimerConflict(void);
time_t time;
time_t timeStart;
time_t timeStop;
time_t overlapStart;
time_t overlapStop;
int percentPossible;
int timerID;
std::vector<int> timerIDs;
bool timerInvolved(int involvedID);
};
class cTVGuideTimerConflicts {
private:
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);
int GetCorrespondingConflict(int timerID);
cTVGuideTimerConflict *GetConflict(int conflictIndex);
std::vector<cTVGuideTimerConflict*> GetConflictsBetween(time_t start, time_t stop);
};
#endif //__TVGUIDE_RECMMANAGER_H

964
tools.c
View File

@@ -1,482 +1,482 @@
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <vdr/osd.h>
#include <vdr/plugin.h>
#include <vdr/skins.h>
#include "services/epgsearch.h"
#include "tools.h"
cPlugin *GetScraperPlugin(void) {
static cPlugin *pScraper = cPluginManager::GetPlugin("scraper2vdr");
if( !pScraper ) // if it doesn't exit, try tvscraper
pScraper = cPluginManager::GetPlugin("tvscraper");
return pScraper;
}
/****************************************************************************************
* CUTTEXT
****************************************************************************************/
std::string CutText(std::string text, int width, const cFont *font) {
if (width <= font->Size())
return text.c_str();
if (font->Width(text.c_str()) < width)
return text.c_str();
cTextWrapper twText;
twText.Set(text.c_str(), font, width);
std::string cuttedTextNative = twText.GetLine(0);
std::stringstream sstrText;
sstrText << cuttedTextNative << "...";
std::string cuttedText = sstrText.str();
int actWidth = font->Width(cuttedText.c_str());
if (actWidth > width) {
int overlap = actWidth - width;
int charWidth = font->Width(".");
if (charWidth == 0)
charWidth = 1;
int cutChars = overlap / charWidth;
if (cutChars > 0) {
cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars);
std::stringstream sstrText2;
sstrText2 << cuttedTextNative << "...";
cuttedText = sstrText2.str();
}
}
return cuttedText;
}
/****************************************************************************************
* StrToLowerCase
****************************************************************************************/
std::string StrToLowerCase(std::string str) {
std::string lowerCase = str;
const int length = lowerCase.length();
for(int i=0; i < length; ++i) {
lowerCase[i] = std::tolower(lowerCase[i]);
}
return lowerCase;
}
/****************************************************************************************
* GetDirectoryFromTimer
****************************************************************************************/
std::string GetDirectoryFromTimer(std::string file) {
std::string dir = "";
size_t found = file.find_last_of('~');
if (found != std::string::npos) {
dir = file.substr(0, found);
}
return dir;
}
/****************************************************************************************
* GetDirectoryFromTimer
****************************************************************************************/
void ReadRecordingDirectories(std::vector<std::string> *folders, cList<cNestedItem> *rootFolders, cString path) {
cPlugin *epgSearchPlugin = NULL;
epgSearchPlugin = cPluginManager::GetPlugin("epgsearch");
if (epgSearchPlugin) {
Epgsearch_services_v1_0 *epgSearch = new Epgsearch_services_v1_0;
if (epgSearchPlugin->Service("Epgsearch-services-v1.0", epgSearch)) {
std::set<std::string> epgSearchDirs = epgSearch->handler->DirectoryList();
std::set<std::string>::iterator it;
for (it = epgSearchDirs.begin(); it != epgSearchDirs.end(); it++) {
std::string newFolder = *it;
std::replace(newFolder.begin(), newFolder.end(), '/', '~');
folders->push_back(newFolder);
}
}
} else {
cList<cNestedItem> *foldersLevel = NULL;
if (rootFolders) {
foldersLevel = rootFolders;
} else {
foldersLevel = &Folders;
}
for (cNestedItem *folder = foldersLevel->First(); folder; folder = foldersLevel->Next(folder)) {
std::string strFolder = *cString::sprintf("%s%s", *path, folder->Text());
std::replace(strFolder.begin(), strFolder.end(), '/', '~');
folders->push_back(strFolder);
cList<cNestedItem> *subItems = folder->SubItems();
if (subItems) {
std::string strFolder2 = *cString::sprintf("%s%s", *path, folder->Text());
std::replace(strFolder2.begin(), strFolder2.end(), '/', '~');
ReadRecordingDirectories(folders, subItems, strFolder2.c_str());
}
}
}
}
/****************************************************************************************
* DrawRoundedCorners
****************************************************************************************/
void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor) {
if( height > 2*radius) {
p->DrawEllipse(cRect(posX, posY, radius, radius), borderColor, -2);
p->DrawEllipse(cRect(posX - borderWidth, posY - borderWidth, radius, radius), clrTransparent, -2);
p->DrawEllipse(cRect(posX+width - radius, posY, radius, radius), borderColor, -1);
p->DrawEllipse(cRect(posX+width - radius + borderWidth, posY - borderWidth, radius, radius), clrTransparent, -1);
p->DrawEllipse(cRect(posX, posY + height - radius, radius, radius), borderColor, -3);
p->DrawEllipse(cRect(posX - borderWidth, posY + height - radius + borderWidth, radius, radius), clrTransparent, -3);
p->DrawEllipse(cRect(posX + width - radius, posY + height - radius, radius, radius), borderColor, -4);
p->DrawEllipse(cRect(posX + width - radius + borderWidth, posY + height - radius + borderWidth, radius, radius), clrTransparent, -4);
}
}
/****************************************************************************************
* SPLTSTRING
****************************************************************************************/
// split: receives a char delimiter; returns a vector of strings
// By default ignores repeated delimiters, unless argument rep == 1.
std::vector<std::string>& splitstring::split(char delim, int rep) {
if (!flds.empty()) flds.clear(); // empty vector if necessary
std::string work = data();
std::string buf = "";
int i = 0;
while (i < work.length()) {
if (work[i] != delim)
buf += work[i];
else if (rep == 1) {
flds.push_back(buf);
buf = "";
} else if (buf.length() > 0) {
flds.push_back(buf);
buf = "";
}
i++;
}
if (!buf.empty())
flds.push_back(buf);
return flds;
}
/****************************************************************************************
* FINDIGNORECASE
****************************************************************************************/
int FindIgnoreCase(const std::string& expr, const std::string& query)
{
const char *p = expr.c_str();
const char *r = strcasestr(p, query.c_str());
if (!r)
return -1;
return r - p;
}
/****************************************************************************************
* GetAuxValue
****************************************************************************************/
char* GetAuxValue(const char* aux, const char* name) {
if (isempty(aux))
return NULL;
char* descr = strdup(aux);
char* beginaux = strstr(descr, "<epgsearch>");
char* endaux = strstr(descr, "</epgsearch>");
if (!beginaux || !endaux) {
free(descr);
return NULL;
}
beginaux += 11; // strlen("<epgsearch>");
endaux[0] = 0;
memmove(descr, beginaux, endaux - beginaux + 1);
if (strcmp(name, "epgsearch") == 0)
return descr; // full aux
int namelen = strlen(name);
char catname[100] = "";
catname[0] = '<';
memcpy(catname + 1, name, namelen);
catname[1 + namelen] = '>';
catname[2 + namelen] = 0;
char* cat = strcasestr(descr, catname);
if (!cat) {
free(descr);
return NULL;
}
cat += namelen + 2;
char* end = strstr(cat, "</");
if (!end) {
free(descr);
return NULL;
}
end[0] = 0;
int catlen = end - cat + 1;
char* value = (char *) malloc(catlen);
memcpy(value, cat, catlen);
free(descr);
return value;
}
char* GetAuxValue(const cRecording *recording, const char* name) {
if (!recording || !recording->Info())
return NULL;
return GetAuxValue(recording->Info()->Aux(), name);
}
char* GetAuxValue(const cTimer *timer, const char* name) {
if (!timer || !timer->Aux())
return NULL;
return GetAuxValue(timer->Aux(), name);
}
/****************************************************************************************
* FUZZYSEARCH
****************************************************************************************/
/******************************************************************************
FUNCTION afuzzy_init()
Initialization of the fuzzy search routine. This applies to the consequent
calls of the afuzzy_CheckRTR (whole string matching) and afuzzy_CheckSUB
(substring match) routines. afuzzy_init() should be called for each
new pattern or error length. The search is case sensitive
ARGUMENTS:
p Pattern
kerr Number of possible errors. Shouldn't exceed pattern length
UseFilter Use agrep filter algorithm that speeds up search.
fuzzy pointer to the structure that will be later passes to Check*
(the first 6 elements should be NULLs for the first call)
RETURN VALUE:
none
ALGORITHM
see. the article on agrep algorithms.
The only change is accounting transpositions as one edit operation .
******************************************************************************/
void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy)
{
int cnt, p_len, i, j, l, d, m, dd;
char PatFilter[sizeof(Uint)*8 + 1];
fuzzy->k = kerr;
m = strlen(p);
fuzzy->FilterSet = 0;
memset(fuzzy->Map, 0 , sizeof(fuzzy->Map) );
if (fuzzy->S)
free(fuzzy->S);
if (fuzzy->R)
free(fuzzy->R);
if (fuzzy->R1)
free(fuzzy->R1);
if (fuzzy->RP)
free(fuzzy->RP);
if (fuzzy->RI)
free(fuzzy->RI);
if (fuzzy->FilterS)
free(fuzzy->FilterS);
fuzzy->FilterS = NULL;
fuzzy->S = (Uint *)calloc(m + 1, sizeof(Uint));
fuzzy->R = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint));
fuzzy->R1 = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint));
fuzzy->RI = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint));
fuzzy->RP = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint));
for (i = 0, cnt = 0; i < m; i++)
{
l = fuzzy->Map[(unsigned char)p[i]];
if (!l)
{
l = fuzzy->Map[(unsigned char)p[i]] = ++cnt;
fuzzy->S[l] = 0;
}
fuzzy->S[l] |= 1 << i;
}
for (d = 0; d <= fuzzy->k; d++)
fuzzy->RI[d] = (1 << d) - 1;
fuzzy->mask_ok = (1 << (m - 1));
fuzzy->r_size = sizeof(Uint) * (fuzzy->k + 1);
p_len = m;
if (p_len > (int) sizeof(Uint)*8)
p_len = (int) sizeof(Uint)*8;
/* If k is zero then no filter is needed! */
if (fuzzy->k && (p_len >= 2*(fuzzy->k + 1)) )
{
if (UseFilter)
{
fuzzy->FilterSet = 1;
memset(fuzzy->FilterMap, 0 , sizeof(fuzzy->FilterMap) );
fuzzy->FilterS = (Uint *)calloc(m + 1, sizeof(Uint));
/* Not let's fill the interleaved pattern */
dd = p_len / (fuzzy->k + 1);
p_len = dd * (fuzzy->k + 1);
for (i = 0, cnt = 0; i < dd; i++)
for (j = 0; j < fuzzy->k + 1; j++, cnt++)
PatFilter[cnt] = (unsigned char)p[j*dd + i];
PatFilter[p_len] = 0;
for (i = 0, cnt = 0; i < p_len; i++)
{
l = fuzzy->FilterMap[(unsigned char)PatFilter[i]];
if (!l)
{
l = fuzzy->FilterMap[(unsigned char)PatFilter[i]] = ++cnt;
fuzzy->FilterS[l] = 0;
}
fuzzy->FilterS[l] |= 1 << i;
}
fuzzy->filter_ok = 0;
for (i = p_len - fuzzy->k - 1; i <= p_len - 1; i++) /* k+1 times */
fuzzy->filter_ok |= 1 << i;
/* k+1 first bits set to 1 */
fuzzy->filter_shift = (1 << (fuzzy->k + 2)) - 1;
}
}
}
/******************************************************************************
FUNCTION afuzzy_free()
Cleaning up after previous afuzzy_init() call.
ARGUMENTS:
fuzzy pointer to the afuzzy parameters structure
RETURN VALUE:
none
******************************************************************************/
void afuzzy_free(AFUZZY *fuzzy)
{
if (fuzzy->S)
{
free(fuzzy->S);
fuzzy->S = NULL;
}
if (fuzzy->R)
{
free(fuzzy->R);
fuzzy->R = NULL;
}
if (fuzzy->R1)
{
free(fuzzy->R1);
fuzzy->R1 = NULL;
}
if (fuzzy->RP)
{
free(fuzzy->RP);
fuzzy->RP = NULL;
}
if (fuzzy->RI)
{
free(fuzzy->RI);
fuzzy->RI = NULL;
}
if (fuzzy->FilterS)
{
free(fuzzy->FilterS);
fuzzy->FilterS = NULL;
}
}
/******************************************************************************
FUNCTION afuzzy_CheckSUB()
Perform a fuzzy pattern substring matching. afuzzy_init() should be
called previously to initialize the pattern and error length.
Positive result means that some part of the string given matches the
pattern with no more than afuzzy->k errors (1 error = 1 letter
replacement or transposition)
ARGUMENTS:
t the string to test
fuzzy pointer to the afuzzy parameters structure
RETURN VALUE:
0 - no match
> 0 - strings match
ALGORITHM
????????????????
******************************************************************************/
int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy)
{
register char c;
register int j, d;
/* For eficciency this case should be little bit optimized */
if (!fuzzy->k)
{
Uint R = 0, R1;
for (j = 0; (c = t[j]) != '\0'; j++)
{
R1 = ( ((R<<1) | 1) & fuzzy->S[fuzzy->Map[(unsigned char)c]]);
R = R1;
if (R1 & fuzzy->mask_ok)
return 1;
} /* end for (register int j = 0 ... */
return 0;
}
if (fuzzy->FilterSet && !afuzzy_checkFLT(t, fuzzy))
return 0;
memcpy(fuzzy->R, fuzzy->RI, fuzzy->r_size); /* R = RI */
for (j = 0; (c = t[j]); j++)
{
for (d = 0; d <= fuzzy->k; d++)
{
fuzzy->R1[d] = (((fuzzy->R[d]<<1) | 1) &
fuzzy->S[fuzzy->Map[(unsigned char)c]]);
if (d > 0)
fuzzy->R1[d] |= ((fuzzy->R[d-1] | fuzzy->R1[d-1])<<1) | 1 |
fuzzy->R[d-1];
}
if (fuzzy->R1[fuzzy->k] & fuzzy->mask_ok)
return j;
memcpy(fuzzy->R, fuzzy->R1, fuzzy->r_size);
} /* end for (register int j = 0 ... */
return 0;
}
int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy)
{
register Uint FilterR = 0;
register Uint FilterR1;
register int j;
for (j = 0; t[j] != '\0'; j++)
{
FilterR1 = ( ((FilterR<<(fuzzy->k+1)) | fuzzy->filter_shift) &
fuzzy->FilterS[fuzzy->FilterMap[(unsigned char)t[j]]]);
if (FilterR1 & fuzzy->filter_ok)
return 1;
FilterR = FilterR1;
} /* end for (register int j = 0 ... */
return 0;
}
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <vdr/osd.h>
#include <vdr/plugin.h>
#include <vdr/skins.h>
#include "services/epgsearch.h"
#include "tools.h"
cPlugin *GetScraperPlugin(void) {
static cPlugin *pScraper = cPluginManager::GetPlugin("scraper2vdr");
if( !pScraper ) // if it doesn't exit, try tvscraper
pScraper = cPluginManager::GetPlugin("tvscraper");
return pScraper;
}
/****************************************************************************************
* CUTTEXT
****************************************************************************************/
std::string CutText(std::string text, int width, const cFont *font) {
if (width <= font->Size())
return text.c_str();
if (font->Width(text.c_str()) < width)
return text.c_str();
cTextWrapper twText;
twText.Set(text.c_str(), font, width);
std::string cuttedTextNative = twText.GetLine(0);
std::stringstream sstrText;
sstrText << cuttedTextNative << "...";
std::string cuttedText = sstrText.str();
int actWidth = font->Width(cuttedText.c_str());
if (actWidth > width) {
int overlap = actWidth - width;
int charWidth = font->Width(".");
if (charWidth == 0)
charWidth = 1;
int cutChars = overlap / charWidth;
if (cutChars > 0) {
cuttedTextNative = cuttedTextNative.substr(0, cuttedTextNative.length() - cutChars);
std::stringstream sstrText2;
sstrText2 << cuttedTextNative << "...";
cuttedText = sstrText2.str();
}
}
return cuttedText;
}
/****************************************************************************************
* StrToLowerCase
****************************************************************************************/
std::string StrToLowerCase(std::string str) {
std::string lowerCase = str;
const int length = lowerCase.length();
for(int i=0; i < length; ++i) {
lowerCase[i] = std::tolower(lowerCase[i]);
}
return lowerCase;
}
/****************************************************************************************
* GetDirectoryFromTimer
****************************************************************************************/
std::string GetDirectoryFromTimer(std::string file) {
std::string dir = "";
size_t found = file.find_last_of('~');
if (found != std::string::npos) {
dir = file.substr(0, found);
}
return dir;
}
/****************************************************************************************
* GetDirectoryFromTimer
****************************************************************************************/
void ReadRecordingDirectories(std::vector<std::string> *folders, cList<cNestedItem> *rootFolders, cString path) {
cPlugin *epgSearchPlugin = NULL;
epgSearchPlugin = cPluginManager::GetPlugin("epgsearch");
if (epgSearchPlugin) {
Epgsearch_services_v1_0 *epgSearch = new Epgsearch_services_v1_0;
if (epgSearchPlugin->Service("Epgsearch-services-v1.0", epgSearch)) {
std::set<std::string> epgSearchDirs = epgSearch->handler->DirectoryList();
std::set<std::string>::iterator it;
for (it = epgSearchDirs.begin(); it != epgSearchDirs.end(); it++) {
std::string newFolder = *it;
std::replace(newFolder.begin(), newFolder.end(), '/', '~');
folders->push_back(newFolder);
}
}
} else {
cList<cNestedItem> *foldersLevel = NULL;
if (rootFolders) {
foldersLevel = rootFolders;
} else {
foldersLevel = &Folders;
}
for (cNestedItem *folder = foldersLevel->First(); folder; folder = foldersLevel->Next(folder)) {
std::string strFolder = *cString::sprintf("%s%s", *path, folder->Text());
std::replace(strFolder.begin(), strFolder.end(), '/', '~');
folders->push_back(strFolder);
cList<cNestedItem> *subItems = folder->SubItems();
if (subItems) {
std::string strFolder2 = *cString::sprintf("%s%s", *path, folder->Text());
std::replace(strFolder2.begin(), strFolder2.end(), '/', '~');
ReadRecordingDirectories(folders, subItems, strFolder2.c_str());
}
}
}
}
/****************************************************************************************
* DrawRoundedCorners
****************************************************************************************/
void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor) {
if( height > 2*radius) {
p->DrawEllipse(cRect(posX, posY, radius, radius), borderColor, -2);
p->DrawEllipse(cRect(posX - borderWidth, posY - borderWidth, radius, radius), clrTransparent, -2);
p->DrawEllipse(cRect(posX+width - radius, posY, radius, radius), borderColor, -1);
p->DrawEllipse(cRect(posX+width - radius + borderWidth, posY - borderWidth, radius, radius), clrTransparent, -1);
p->DrawEllipse(cRect(posX, posY + height - radius, radius, radius), borderColor, -3);
p->DrawEllipse(cRect(posX - borderWidth, posY + height - radius + borderWidth, radius, radius), clrTransparent, -3);
p->DrawEllipse(cRect(posX + width - radius, posY + height - radius, radius, radius), borderColor, -4);
p->DrawEllipse(cRect(posX + width - radius + borderWidth, posY + height - radius + borderWidth, radius, radius), clrTransparent, -4);
}
}
/****************************************************************************************
* SPLTSTRING
****************************************************************************************/
// split: receives a char delimiter; returns a vector of strings
// By default ignores repeated delimiters, unless argument rep == 1.
std::vector<std::string>& splitstring::split(char delim, int rep) {
if (!flds.empty()) flds.clear(); // empty vector if necessary
std::string work = data();
std::string buf = "";
int i = 0;
while (i < (int)work.length()) {
if (work[i] != delim)
buf += work[i];
else if (rep == 1) {
flds.push_back(buf);
buf = "";
} else if (buf.length() > 0) {
flds.push_back(buf);
buf = "";
}
i++;
}
if (!buf.empty())
flds.push_back(buf);
return flds;
}
/****************************************************************************************
* FINDIGNORECASE
****************************************************************************************/
int FindIgnoreCase(const std::string& expr, const std::string& query)
{
const char *p = expr.c_str();
const char *r = strcasestr(p, query.c_str());
if (!r)
return -1;
return r - p;
}
/****************************************************************************************
* GetAuxValue
****************************************************************************************/
char* GetAuxValue(const char* aux, const char* name) {
if (isempty(aux))
return NULL;
char* descr = strdup(aux);
char* beginaux = strstr(descr, "<epgsearch>");
char* endaux = strstr(descr, "</epgsearch>");
if (!beginaux || !endaux) {
free(descr);
return NULL;
}
beginaux += 11; // strlen("<epgsearch>");
endaux[0] = 0;
memmove(descr, beginaux, endaux - beginaux + 1);
if (strcmp(name, "epgsearch") == 0)
return descr; // full aux
int namelen = strlen(name);
char catname[100] = "";
catname[0] = '<';
memcpy(catname + 1, name, namelen);
catname[1 + namelen] = '>';
catname[2 + namelen] = 0;
char* cat = strcasestr(descr, catname);
if (!cat) {
free(descr);
return NULL;
}
cat += namelen + 2;
char* end = strstr(cat, "</");
if (!end) {
free(descr);
return NULL;
}
end[0] = 0;
int catlen = end - cat + 1;
char* value = (char *) malloc(catlen);
memcpy(value, cat, catlen);
free(descr);
return value;
}
char* GetAuxValue(const cRecording *recording, const char* name) {
if (!recording || !recording->Info())
return NULL;
return GetAuxValue(recording->Info()->Aux(), name);
}
char* GetAuxValue(const cTimer *timer, const char* name) {
if (!timer || !timer->Aux())
return NULL;
return GetAuxValue(timer->Aux(), name);
}
/****************************************************************************************
* FUZZYSEARCH
****************************************************************************************/
/******************************************************************************
FUNCTION afuzzy_init()
Initialization of the fuzzy search routine. This applies to the consequent
calls of the afuzzy_CheckRTR (whole string matching) and afuzzy_CheckSUB
(substring match) routines. afuzzy_init() should be called for each
new pattern or error length. The search is case sensitive
ARGUMENTS:
p Pattern
kerr Number of possible errors. Shouldn't exceed pattern length
UseFilter Use agrep filter algorithm that speeds up search.
fuzzy pointer to the structure that will be later passes to Check*
(the first 6 elements should be NULLs for the first call)
RETURN VALUE:
none
ALGORITHM
see. the article on agrep algorithms.
The only change is accounting transpositions as one edit operation .
******************************************************************************/
void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy)
{
int cnt, p_len, i, j, l, d, m, dd;
char PatFilter[sizeof(Uint)*8 + 1];
fuzzy->k = kerr;
m = strlen(p);
fuzzy->FilterSet = 0;
memset(fuzzy->Map, 0 , sizeof(fuzzy->Map) );
if (fuzzy->S)
free(fuzzy->S);
if (fuzzy->R)
free(fuzzy->R);
if (fuzzy->R1)
free(fuzzy->R1);
if (fuzzy->RP)
free(fuzzy->RP);
if (fuzzy->RI)
free(fuzzy->RI);
if (fuzzy->FilterS)
free(fuzzy->FilterS);
fuzzy->FilterS = NULL;
fuzzy->S = (Uint *)calloc(m + 1, sizeof(Uint));
fuzzy->R = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint));
fuzzy->R1 = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint));
fuzzy->RI = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint));
fuzzy->RP = (Uint *)calloc(fuzzy->k + 1, sizeof(Uint));
for (i = 0, cnt = 0; i < m; i++)
{
l = fuzzy->Map[(unsigned char)p[i]];
if (!l)
{
l = fuzzy->Map[(unsigned char)p[i]] = ++cnt;
fuzzy->S[l] = 0;
}
fuzzy->S[l] |= 1 << i;
}
for (d = 0; d <= fuzzy->k; d++)
fuzzy->RI[d] = (1 << d) - 1;
fuzzy->mask_ok = (1 << (m - 1));
fuzzy->r_size = sizeof(Uint) * (fuzzy->k + 1);
p_len = m;
if (p_len > (int) sizeof(Uint)*8)
p_len = (int) sizeof(Uint)*8;
/* If k is zero then no filter is needed! */
if (fuzzy->k && (p_len >= 2*(fuzzy->k + 1)) )
{
if (UseFilter)
{
fuzzy->FilterSet = 1;
memset(fuzzy->FilterMap, 0 , sizeof(fuzzy->FilterMap) );
fuzzy->FilterS = (Uint *)calloc(m + 1, sizeof(Uint));
/* Not let's fill the interleaved pattern */
dd = p_len / (fuzzy->k + 1);
p_len = dd * (fuzzy->k + 1);
for (i = 0, cnt = 0; i < dd; i++)
for (j = 0; j < fuzzy->k + 1; j++, cnt++)
PatFilter[cnt] = (unsigned char)p[j*dd + i];
PatFilter[p_len] = 0;
for (i = 0, cnt = 0; i < p_len; i++)
{
l = fuzzy->FilterMap[(unsigned char)PatFilter[i]];
if (!l)
{
l = fuzzy->FilterMap[(unsigned char)PatFilter[i]] = ++cnt;
fuzzy->FilterS[l] = 0;
}
fuzzy->FilterS[l] |= 1 << i;
}
fuzzy->filter_ok = 0;
for (i = p_len - fuzzy->k - 1; i <= p_len - 1; i++) /* k+1 times */
fuzzy->filter_ok |= 1 << i;
/* k+1 first bits set to 1 */
fuzzy->filter_shift = (1 << (fuzzy->k + 2)) - 1;
}
}
}
/******************************************************************************
FUNCTION afuzzy_free()
Cleaning up after previous afuzzy_init() call.
ARGUMENTS:
fuzzy pointer to the afuzzy parameters structure
RETURN VALUE:
none
******************************************************************************/
void afuzzy_free(AFUZZY *fuzzy)
{
if (fuzzy->S)
{
free(fuzzy->S);
fuzzy->S = NULL;
}
if (fuzzy->R)
{
free(fuzzy->R);
fuzzy->R = NULL;
}
if (fuzzy->R1)
{
free(fuzzy->R1);
fuzzy->R1 = NULL;
}
if (fuzzy->RP)
{
free(fuzzy->RP);
fuzzy->RP = NULL;
}
if (fuzzy->RI)
{
free(fuzzy->RI);
fuzzy->RI = NULL;
}
if (fuzzy->FilterS)
{
free(fuzzy->FilterS);
fuzzy->FilterS = NULL;
}
}
/******************************************************************************
FUNCTION afuzzy_CheckSUB()
Perform a fuzzy pattern substring matching. afuzzy_init() should be
called previously to initialize the pattern and error length.
Positive result means that some part of the string given matches the
pattern with no more than afuzzy->k errors (1 error = 1 letter
replacement or transposition)
ARGUMENTS:
t the string to test
fuzzy pointer to the afuzzy parameters structure
RETURN VALUE:
0 - no match
> 0 - strings match
ALGORITHM
????????????????
******************************************************************************/
int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy)
{
register char c;
register int j, d;
/* For eficciency this case should be little bit optimized */
if (!fuzzy->k)
{
Uint R = 0, R1;
for (j = 0; (c = t[j]) != '\0'; j++)
{
R1 = ( ((R<<1) | 1) & fuzzy->S[fuzzy->Map[(unsigned char)c]]);
R = R1;
if (R1 & fuzzy->mask_ok)
return 1;
} /* end for (register int j = 0 ... */
return 0;
}
if (fuzzy->FilterSet && !afuzzy_checkFLT(t, fuzzy))
return 0;
memcpy(fuzzy->R, fuzzy->RI, fuzzy->r_size); /* R = RI */
for (j = 0; (c = t[j]); j++)
{
for (d = 0; d <= fuzzy->k; d++)
{
fuzzy->R1[d] = (((fuzzy->R[d]<<1) | 1) &
fuzzy->S[fuzzy->Map[(unsigned char)c]]);
if (d > 0)
fuzzy->R1[d] |= ((fuzzy->R[d-1] | fuzzy->R1[d-1])<<1) | 1 |
fuzzy->R[d-1];
}
if (fuzzy->R1[fuzzy->k] & fuzzy->mask_ok)
return j;
memcpy(fuzzy->R, fuzzy->R1, fuzzy->r_size);
} /* end for (register int j = 0 ... */
return 0;
}
int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy)
{
register Uint FilterR = 0;
register Uint FilterR1;
register int j;
for (j = 0; t[j] != '\0'; j++)
{
FilterR1 = ( ((FilterR<<(fuzzy->k+1)) | fuzzy->filter_shift) &
fuzzy->FilterS[fuzzy->FilterMap[(unsigned char)t[j]]]);
if (FilterR1 & fuzzy->filter_ok)
return 1;
FilterR = FilterR1;
} /* end for (register int j = 0 ... */
return 0;
}

142
tools.h
View File

@@ -1,71 +1,71 @@
#ifndef __TVGUIDETOOLS_H
#define __TVGUIDETOOLS_H
#include <string>
#include <vector>
#include <vdr/font.h>
#include <vdr/recording.h>
#include <vdr/plugin.h>
cPlugin *GetScraperPlugin(void);
std::string CutText(std::string text, int width, const cFont *font);
std::string StrToLowerCase(std::string str);
std::string GetDirectoryFromTimer(std::string file);
void ReadRecordingDirectories(std::vector<std::string> *folders, cList<cNestedItem> *rootFolders, cString path);
void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor);
class splitstring : public std::string {
std::vector<std::string> flds;
public:
splitstring(const char *s) : std::string(s) { };
std::vector<std::string>& split(char delim, int rep=0);
};
int FindIgnoreCase(const std::string& expr, const std::string& query);
char* GetAuxValue(const char* aux, const char* name);
char* GetAuxValue(const cRecording *recording, const char* name);
char* GetAuxValue(const cTimer* timer, const char* name);
#ifndef _AFUZZY_H
#define _AFUZZY_H
// source from:
/*
Leonid Boitsov 2002. (itman@narod.ru)
C version of Stas Namin.
This code is a GPL software and is distributed under GNU
public licence without any warranty.
*/
typedef unsigned int Uint;
#define MaxPatSize (sizeof(Uint) * 8)
typedef struct
{
Uint *R,
*R1,
*RP,
*S,
*RI;
Uint *FilterS;
int Map[256];
int FilterMap[256];
int k;
Uint mask_ok;
Uint filter_ok;
Uint filter_shift;
int r_size;
int FilterSet;
} AFUZZY;
void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy);
void afuzzy_free(AFUZZY *fuzzy);
int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy);
int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy);
#endif
#endif // __TVGUIDETOOLS_H
#ifndef __TVGUIDETOOLS_H
#define __TVGUIDETOOLS_H
#include <string>
#include <vector>
#include <vdr/font.h>
#include <vdr/recording.h>
#include <vdr/plugin.h>
cPlugin *GetScraperPlugin(void);
std::string CutText(std::string text, int width, const cFont *font);
std::string StrToLowerCase(std::string str);
std::string GetDirectoryFromTimer(std::string file);
void ReadRecordingDirectories(std::vector<std::string> *folders, cList<cNestedItem> *rootFolders, cString path);
void DrawRoundedCorners(cPixmap *p, int posX, int posY, int width, int height, int radius, int borderWidth, tColor borderColor);
class splitstring : public std::string {
std::vector<std::string> flds;
public:
splitstring(const char *s) : std::string(s) { };
std::vector<std::string>& split(char delim, int rep=0);
};
int FindIgnoreCase(const std::string& expr, const std::string& query);
char* GetAuxValue(const char* aux, const char* name);
char* GetAuxValue(const cRecording *recording, const char* name);
char* GetAuxValue(const cTimer* timer, const char* name);
#ifndef _AFUZZY_H
#define _AFUZZY_H
// source from:
/*
Leonid Boitsov 2002. (itman@narod.ru)
C version of Stas Namin.
This code is a GPL software and is distributed under GNU
public licence without any warranty.
*/
typedef unsigned int Uint;
#define MaxPatSize (sizeof(Uint) * 8)
typedef struct
{
Uint *R,
*R1,
*RP,
*S,
*RI;
Uint *FilterS;
int Map[256];
int FilterMap[256];
int k;
Uint mask_ok;
Uint filter_ok;
Uint filter_shift;
int r_size;
int FilterSet;
} AFUZZY;
void afuzzy_init(const char *p, int kerr, int UseFilter, AFUZZY *fuzzy);
void afuzzy_free(AFUZZY *fuzzy);
int afuzzy_checkSUB(const char *t, AFUZZY *fuzzy);
int afuzzy_checkFLT(const char *t, AFUZZY *fuzzy);
#endif
#endif // __TVGUIDETOOLS_H

View File

@@ -26,7 +26,7 @@
#error "VDR-2.0.0 API version or greater is required!"
#endif
static const char *VERSION = "1.2.3";
static const char *VERSION = "1.2.4";
static const char *DESCRIPTION = "A fancy 2d EPG Viewer";
static const char *MAINMENUENTRY = "Tvguide";

3
view.c
View File

@@ -122,7 +122,6 @@ void cView::DrawHeader(void) {
//REC Icon
eTimerMatch timerMatch=tmNone;
#if VDRVERSNUM >= 20301
// LOCK_TIMERS_READ;
const cTimer *ti;
#else
cTimer *ti;
@@ -284,7 +283,7 @@ void cView::CreateFloatingTextWrapper(cTextWrapper *twNarrow, cTextWrapper *twFu
std::stringstream sstrTextTall;
std::stringstream sstrTextFull;
for (int i=0; i<flds.size(); i++) {
for (int i = 0; i < (int)flds.size(); i++) {
if (!flds[i].size()) {
//empty line
linesDrawn++;