2014-09-27 09:25:14 +02:00
|
|
|
#include "designer.h"
|
|
|
|
#include "libcore/helpers.h"
|
|
|
|
|
2014-10-03 15:54:23 +02:00
|
|
|
cSkinDesigner::cSkinDesigner(string skin) : cSkin(skin.c_str(), &::Theme) {
|
|
|
|
init = true;
|
|
|
|
this->skin = skin;
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
backupSkin = NULL;
|
|
|
|
useBackupSkin = false;
|
|
|
|
|
2014-10-03 15:54:23 +02:00
|
|
|
globals = NULL;
|
|
|
|
channelTemplate = NULL;
|
|
|
|
menuTemplate = NULL;
|
|
|
|
messageTemplate = NULL;
|
|
|
|
replayTemplate = NULL;
|
|
|
|
volumeTemplate = NULL;
|
|
|
|
audiotracksTemplate = NULL;
|
|
|
|
dsyslog("skindesigner: skin %s started", skin.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDesigner::~cSkinDesigner(void) {
|
|
|
|
if (globals)
|
|
|
|
delete globals;
|
|
|
|
DeleteTemplates();
|
|
|
|
if (backupSkin)
|
|
|
|
delete backupSkin;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *cSkinDesigner::Description(void) {
|
|
|
|
return skin.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::Init(void) {
|
|
|
|
dsyslog("skindesigner: initializing skin %s", skin.c_str());
|
2014-09-27 09:25:14 +02:00
|
|
|
SetOSDSize();
|
2014-09-28 10:47:54 +02:00
|
|
|
osdSkin = Setup.OSDSkin;
|
2014-09-27 09:25:14 +02:00
|
|
|
osdTheme = Setup.OSDTheme;
|
2014-09-28 10:47:54 +02:00
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
config.SetChannelLogoSize();
|
|
|
|
config.CheckDecimalPoint();
|
2014-10-03 15:54:23 +02:00
|
|
|
|
|
|
|
if (fontManager)
|
|
|
|
delete fontManager;
|
2014-09-27 09:25:14 +02:00
|
|
|
fontManager = new cFontManager();
|
2014-10-03 15:54:23 +02:00
|
|
|
if (imgCache)
|
|
|
|
delete imgCache;
|
2014-09-27 09:25:14 +02:00
|
|
|
imgCache = new cImageCache();
|
2014-10-03 15:54:23 +02:00
|
|
|
imgCache->SetPathes();
|
2014-09-27 09:25:14 +02:00
|
|
|
|
|
|
|
cStopWatch watch;
|
|
|
|
bool ok = LoadTemplates();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
|
|
|
|
backupSkin = new cSkinLCARS();
|
|
|
|
useBackupSkin = true;
|
|
|
|
} else {
|
|
|
|
CacheTemplates();
|
|
|
|
watch.Stop("templates loaded and cache created");
|
|
|
|
}
|
2014-10-03 15:54:23 +02:00
|
|
|
init = false;
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayChannel *cSkinDesigner::DisplayChannel(bool WithInfo) {
|
2014-10-03 15:54:23 +02:00
|
|
|
if (init) {
|
|
|
|
Init();
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayChannel *displayChannel = NULL;
|
|
|
|
if (!useBackupSkin) {
|
|
|
|
ReloadCaches();
|
|
|
|
displayChannel = new cSDDisplayChannel(channelTemplate, WithInfo);
|
|
|
|
} else {
|
|
|
|
displayChannel = backupSkin->DisplayChannel(WithInfo);
|
|
|
|
}
|
|
|
|
return displayChannel;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayMenu *cSkinDesigner::DisplayMenu(void) {
|
2014-10-03 15:54:23 +02:00
|
|
|
if (init) {
|
|
|
|
Init();
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayMenu *displayMenu = NULL;
|
|
|
|
if (!useBackupSkin) {
|
|
|
|
ReloadCaches();
|
2014-09-28 10:47:54 +02:00
|
|
|
firstDisplay = false;
|
2014-09-27 09:25:14 +02:00
|
|
|
displayMenu = new cSDDisplayMenu(menuTemplate);
|
|
|
|
} else {
|
|
|
|
displayMenu = backupSkin->DisplayMenu();
|
|
|
|
}
|
|
|
|
return displayMenu;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayReplay *cSkinDesigner::DisplayReplay(bool ModeOnly) {
|
2014-10-03 15:54:23 +02:00
|
|
|
if (init) {
|
|
|
|
Init();
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayReplay *displayReplay = NULL;
|
|
|
|
if (!useBackupSkin) {
|
|
|
|
ReloadCaches();
|
|
|
|
displayReplay = new cSDDisplayReplay(replayTemplate, ModeOnly);
|
|
|
|
} else {
|
|
|
|
displayReplay = backupSkin->DisplayReplay(ModeOnly);
|
|
|
|
}
|
|
|
|
return displayReplay;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayVolume *cSkinDesigner::DisplayVolume(void) {
|
2014-10-03 15:54:23 +02:00
|
|
|
if (init) {
|
|
|
|
Init();
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayVolume *displayVolume = NULL;
|
|
|
|
if (!useBackupSkin) {
|
|
|
|
ReloadCaches();
|
|
|
|
displayVolume = new cSDDisplayVolume(volumeTemplate);
|
|
|
|
} else {
|
|
|
|
displayVolume = backupSkin->DisplayVolume();
|
|
|
|
}
|
|
|
|
return displayVolume;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayTracks *cSkinDesigner::DisplayTracks(const char *Title, int NumTracks, const char * const *Tracks) {
|
2014-10-03 15:54:23 +02:00
|
|
|
if (init) {
|
|
|
|
Init();
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayTracks *displayTracks = NULL;
|
|
|
|
if (!useBackupSkin) {
|
|
|
|
ReloadCaches();
|
|
|
|
displayTracks = new cSDDisplayTracks(audiotracksTemplate, Title, NumTracks, Tracks);
|
|
|
|
} else {
|
|
|
|
displayTracks = backupSkin->DisplayTracks(Title, NumTracks, Tracks);
|
|
|
|
}
|
|
|
|
return displayTracks;
|
|
|
|
}
|
|
|
|
|
|
|
|
cSkinDisplayMessage *cSkinDesigner::DisplayMessage(void) {
|
2014-10-03 15:54:23 +02:00
|
|
|
if (init) {
|
|
|
|
Init();
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
cSkinDisplayMessage *displayMessage = NULL;
|
|
|
|
if (!useBackupSkin) {
|
|
|
|
ReloadCaches();
|
|
|
|
displayMessage = new cSDDisplayMessage(messageTemplate);
|
|
|
|
} else {
|
|
|
|
displayMessage = backupSkin->DisplayMessage();
|
|
|
|
}
|
|
|
|
return displayMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::Reload(void) {
|
|
|
|
dsyslog("skindesigner: forcing full reload of templates");
|
|
|
|
if (cOsd::IsOpen()) {
|
|
|
|
esyslog("skindesigner: OSD is open, close first!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
DeleteTemplates();
|
|
|
|
cStopWatch watch;
|
|
|
|
bool ok = LoadTemplates();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error during loading of templates - using LCARS as backup");
|
|
|
|
if (!backupSkin)
|
|
|
|
backupSkin = new cSkinLCARS();
|
|
|
|
useBackupSkin = true;
|
|
|
|
} else {
|
|
|
|
CacheTemplates();
|
|
|
|
useBackupSkin = false;
|
|
|
|
watch.Stop("templates reloaded and cache created");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::ListAvailableFonts(void) {
|
|
|
|
fontManager->ListAvailableFonts();
|
|
|
|
}
|
|
|
|
|
2014-10-11 16:31:39 +02:00
|
|
|
bool cSkinDesigner::SetCustomToken(string option) {
|
|
|
|
splitstring s(option.c_str());
|
|
|
|
vector<string> flds = s.split('=', 0);
|
|
|
|
|
|
|
|
if (flds.size() != 2)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
string key = trim(flds[0]);
|
|
|
|
string val = trim(flds[1]);
|
|
|
|
|
|
|
|
if (!globals)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
map<string, string>::iterator hit = globals->customTokens.find(key);
|
|
|
|
if (hit != globals->customTokens.end()) {
|
|
|
|
globals->customTokens.erase(key);
|
|
|
|
}
|
|
|
|
globals->customTokens.insert(pair<string,string>(key, val));
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::ListCustomTokens(void) {
|
|
|
|
if (!globals)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (map<string, string>::iterator it = globals->customTokens.begin(); it != globals->customTokens.end(); it++) {
|
|
|
|
dsyslog("skindesigner: custom token \"%s\" = \"%s\"", (it->first).c_str(), (it->second).c_str());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-09-27 09:25:14 +02:00
|
|
|
/*********************************************************************************
|
|
|
|
* PRIVATE FUNCTIONS
|
|
|
|
*********************************************************************************/
|
|
|
|
void cSkinDesigner::DeleteTemplates(void) {
|
|
|
|
if (channelTemplate) {
|
|
|
|
delete channelTemplate;
|
|
|
|
channelTemplate = NULL;
|
|
|
|
}
|
|
|
|
if (menuTemplate) {
|
|
|
|
delete menuTemplate;
|
|
|
|
menuTemplate = NULL;
|
|
|
|
}
|
|
|
|
if (messageTemplate) {
|
|
|
|
delete messageTemplate;
|
|
|
|
messageTemplate = NULL;
|
|
|
|
}
|
|
|
|
if (replayTemplate) {
|
|
|
|
delete replayTemplate;
|
|
|
|
replayTemplate = NULL;
|
|
|
|
}
|
|
|
|
if (volumeTemplate) {
|
|
|
|
delete volumeTemplate;
|
|
|
|
volumeTemplate = NULL;
|
|
|
|
}
|
|
|
|
if (audiotracksTemplate) {
|
|
|
|
delete audiotracksTemplate;
|
|
|
|
audiotracksTemplate = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cSkinDesigner::LoadTemplates(void) {
|
|
|
|
|
|
|
|
globals = new cGlobals();
|
|
|
|
bool ok = globals->ReadFromXML();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error parsing globals, aborting");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
DeleteTemplates();
|
|
|
|
|
|
|
|
channelTemplate = new cTemplate(vtDisplayChannel);
|
|
|
|
channelTemplate->SetGlobals(globals);
|
|
|
|
ok = channelTemplate->ReadFromXML();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displaychannel template, aborting");
|
|
|
|
DeleteTemplates();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
channelTemplate->Translate();
|
|
|
|
|
|
|
|
menuTemplate = new cTemplate(vtDisplayMenu);
|
|
|
|
menuTemplate->SetGlobals(globals);
|
|
|
|
ok = menuTemplate->ReadFromXML();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displaymenu template, aborting");
|
|
|
|
DeleteTemplates();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
menuTemplate->Translate();
|
|
|
|
|
|
|
|
messageTemplate = new cTemplate(vtDisplayMessage);
|
|
|
|
messageTemplate->SetGlobals(globals);
|
|
|
|
ok = messageTemplate->ReadFromXML();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displaymessage template, aborting");
|
|
|
|
DeleteTemplates();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
messageTemplate->Translate();
|
|
|
|
|
|
|
|
replayTemplate = new cTemplate(vtDisplayReplay);
|
|
|
|
replayTemplate->SetGlobals(globals);
|
|
|
|
ok = replayTemplate->ReadFromXML();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displayreplay template, aborting");
|
|
|
|
DeleteTemplates();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
replayTemplate->Translate();
|
|
|
|
|
|
|
|
volumeTemplate = new cTemplate(vtDisplayVolume);
|
|
|
|
volumeTemplate->SetGlobals(globals);
|
|
|
|
ok = volumeTemplate->ReadFromXML();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displayvolume template, aborting");
|
|
|
|
DeleteTemplates();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
volumeTemplate->Translate();
|
|
|
|
|
|
|
|
audiotracksTemplate = new cTemplate(vtDisplayAudioTracks);
|
|
|
|
audiotracksTemplate->SetGlobals(globals);
|
|
|
|
ok = audiotracksTemplate->ReadFromXML();
|
|
|
|
if (!ok) {
|
|
|
|
esyslog("skindesigner: error reading displayaudiotracks template, aborting");
|
|
|
|
DeleteTemplates();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
audiotracksTemplate->Translate();
|
|
|
|
|
|
|
|
dsyslog("skindesigner: templates successfully validated and parsed");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::CacheTemplates(void) {
|
|
|
|
channelTemplate->PreCache();
|
|
|
|
menuTemplate->PreCache();
|
|
|
|
messageTemplate->PreCache();
|
|
|
|
replayTemplate->PreCache();
|
|
|
|
volumeTemplate->PreCache();
|
|
|
|
audiotracksTemplate->PreCache();
|
|
|
|
dsyslog("skindesigner: templates cached");
|
|
|
|
fontManager->CacheFonts(channelTemplate);
|
|
|
|
fontManager->CacheFonts(menuTemplate);
|
|
|
|
fontManager->CacheFonts(messageTemplate);
|
|
|
|
fontManager->CacheFonts(replayTemplate);
|
|
|
|
fontManager->CacheFonts(volumeTemplate);
|
|
|
|
fontManager->CacheFonts(audiotracksTemplate);
|
|
|
|
dsyslog("skindesigner: fonts cached");
|
|
|
|
dsyslog("skindesigner: caching images...");
|
|
|
|
imgCache->Clear();
|
2014-10-03 15:54:23 +02:00
|
|
|
imgCache->SetPathes();
|
2014-09-27 09:25:14 +02:00
|
|
|
channelTemplate->CacheImages();
|
|
|
|
menuTemplate->CacheImages();
|
|
|
|
messageTemplate->CacheImages();
|
|
|
|
replayTemplate->CacheImages();
|
|
|
|
volumeTemplate->CacheImages();
|
|
|
|
audiotracksTemplate->CacheImages();
|
|
|
|
imgCache->Debug(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::ReloadCaches(void) {
|
|
|
|
if (OsdSizeChanged() || ThemeChanged()) {
|
|
|
|
cStopWatch watch;
|
|
|
|
bool ok = LoadTemplates();
|
|
|
|
if (ok) {
|
|
|
|
CacheTemplates();
|
|
|
|
}
|
|
|
|
watch.Stop("templates reloaded and cache recreated");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cSkinDesigner::SetOSDSize(void) {
|
|
|
|
osdSize.SetWidth(cOsd::OsdWidth());
|
|
|
|
osdSize.SetHeight(cOsd::OsdHeight());
|
|
|
|
osdSize.SetX(cOsd::OsdLeft());
|
|
|
|
osdSize.SetY(cOsd::OsdTop());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cSkinDesigner::OsdSizeChanged(void) {
|
|
|
|
if ((osdSize.Width() != cOsd::OsdWidth()) ||
|
|
|
|
(osdSize.Height() != cOsd::OsdHeight()) ||
|
|
|
|
(osdSize.X() != cOsd::OsdLeft()) ||
|
|
|
|
(osdSize.Y() != cOsd::OsdTop())) {
|
|
|
|
dsyslog("skindesigner: osd size changed");
|
|
|
|
dsyslog("skindesigner: old osd size: top %d left %d size %d * %d", osdSize.X(), osdSize.Y(), osdSize.Width(), osdSize.Height());
|
|
|
|
SetOSDSize();
|
|
|
|
dsyslog("skindesigner: new osd size: top %d left %d size %d * %d", osdSize.X(), osdSize.Y(), osdSize.Width(), osdSize.Height());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool cSkinDesigner::ThemeChanged(void) {
|
2014-09-28 10:47:54 +02:00
|
|
|
bool changed = false;
|
|
|
|
if (osdSkin.compare(Setup.OSDSkin) != 0) {
|
|
|
|
osdSkin = Setup.OSDSkin;
|
|
|
|
changed = true;
|
|
|
|
}
|
2014-09-27 09:25:14 +02:00
|
|
|
if (osdTheme.compare(Setup.OSDTheme) != 0) {
|
|
|
|
osdTheme = Setup.OSDTheme;
|
2014-09-28 10:47:54 +02:00
|
|
|
changed = true;
|
2014-09-27 09:25:14 +02:00
|
|
|
}
|
2014-09-28 10:47:54 +02:00
|
|
|
return changed;
|
2014-09-28 11:04:55 +02:00
|
|
|
}
|