vdr-plugin-skindesigner/patches/vdr-2.4.0_zapcockpit.patch

1119 lines
37 KiB
Diff
Raw Blame History

diff -Nur vdr-2.4.0/config.c vdr-2.4.0.p/config.c
--- vdr-2.4.0/config.c 2018-02-15 15:40:36.000000000 +0100
+++ vdr-2.4.0.p/config.c 2019-04-04 14:57:48.234702963 +0200
@@ -417,6 +417,11 @@
strcpy(SVDRPDefaultHost, "");
ZapTimeout = 3;
ChannelEntryTimeout = 1000;
+ ZapcockpitUseGroups = 1;
+ ZapcockpitUseHints = 1;
+ ZapcockpitUseInfo = 1;
+ ZapcockpitHideLastGroup = 0;
+ ZapcockpitShowAllChannels = 0;
RcRepeatDelay = 300;
RcRepeatDelta = 100;
DefaultPriority = 50;
@@ -645,6 +650,11 @@
else if (!strcasecmp(Name, "SVDRPDefaultHost")) strn0cpy(SVDRPDefaultHost, Value, sizeof(SVDRPDefaultHost));
else if (!strcasecmp(Name, "ZapTimeout")) ZapTimeout = atoi(Value);
else if (!strcasecmp(Name, "ChannelEntryTimeout")) ChannelEntryTimeout= atoi(Value);
+ else if (!strcasecmp(Name, "ZapcockpitUseGroups")) ZapcockpitUseGroups= atoi(Value);
+ else if (!strcasecmp(Name, "ZapcockpitUseHints")) ZapcockpitUseHints = atoi(Value);
+ else if (!strcasecmp(Name, "ZapcockpitUseInfo")) ZapcockpitUseInfo = atoi(Value);
+ else if (!strcasecmp(Name, "ZapcockpitHideLastGroup")) ZapcockpitHideLastGroup = atoi(Value);
+ else if (!strcasecmp(Name, "ZapcockpitShowAllChannels")) ZapcockpitShowAllChannels = atoi(Value);
else if (!strcasecmp(Name, "RcRepeatDelay")) RcRepeatDelay = atoi(Value);
else if (!strcasecmp(Name, "RcRepeatDelta")) RcRepeatDelta = atoi(Value);
else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value);
@@ -777,6 +787,11 @@
Store("SVDRPDefaultHost", SVDRPDefaultHost);
Store("ZapTimeout", ZapTimeout);
Store("ChannelEntryTimeout",ChannelEntryTimeout);
+ Store("ZapcockpitUseGroups",ZapcockpitUseGroups);
+ Store("ZapcockpitUseHints", ZapcockpitUseHints);
+ Store("ZapcockpitUseInfo", ZapcockpitUseInfo);
+ Store("ZapcockpitHideLastGroup", ZapcockpitHideLastGroup);
+ Store("ZapcockpitShowAllChannels", ZapcockpitShowAllChannels);
Store("RcRepeatDelay", RcRepeatDelay);
Store("RcRepeatDelta", RcRepeatDelta);
Store("DefaultPriority", DefaultPriority);
diff -Nur vdr-2.4.0/config.h vdr-2.4.0.p/config.h
--- vdr-2.4.0/config.h 2018-03-19 16:06:46.000000000 +0100
+++ vdr-2.4.0.p/config.h 2019-04-04 14:57:48.235702949 +0200
@@ -293,6 +293,11 @@
char SVDRPDefaultHost[HOST_NAME_MAX];
int ZapTimeout;
int ChannelEntryTimeout;
+ int ZapcockpitUseGroups;
+ int ZapcockpitUseHints;
+ int ZapcockpitUseInfo;
+ int ZapcockpitHideLastGroup;
+ int ZapcockpitShowAllChannels;
int RcRepeatDelay;
int RcRepeatDelta;
int DefaultPriority, DefaultLifetime;
diff -Nur vdr-2.4.0/menu.c vdr-2.4.0.p/menu.c
--- vdr-2.4.0/menu.c 2019-04-04 15:47:25.722519143 +0200
+++ vdr-2.4.0.p/menu.c 2019-04-04 15:29:02.650105356 +0200
@@ -4184,6 +4184,11 @@
}
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Zap timeout (s)"), &data.ZapTimeout));
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Channel entry timeout (ms)"), &data.ChannelEntryTimeout, 0));
+ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: 2nd ok shows info"), &data.ZapcockpitUseInfo));
+ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: Use extended channel group display"), &data.ZapcockpitUseGroups));
+ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: Use channel hints"), &data.ZapcockpitUseHints));
+ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: Hide last channel group"), &data.ZapcockpitHideLastGroup));
+ Add(new cMenuEditBoolItem( tr("Setup.Miscellaneous$Zapcockpit: Show \"All Channels\" Item in Group List"), &data.ZapcockpitShowAllChannels));
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Remote control repeat delay (ms)"), &data.RcRepeatDelay, 0));
Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$Remote control repeat delta (ms)"), &data.RcRepeatDelta, 0));
Add(new cMenuEditChanItem(tr("Setup.Miscellaneous$Initial channel"), &data.InitialChannel, tr("Setup.Miscellaneous$as before")));
@@ -4654,7 +4659,7 @@
lastTime.Set();
}
-cDisplayChannel::cDisplayChannel(eKeys FirstKey)
+cDisplayChannel::cDisplayChannel(eKeys FirstKey, bool processKey)
:cOsdObject(true)
{
currentDisplayChannel = this;
@@ -4672,7 +4677,8 @@
LOCK_CHANNELS_READ;
channel = Channels->GetByNumber(cDevice::CurrentChannel());
}
- ProcessKey(FirstKey);
+ if (processKey)
+ ProcessKey(FirstKey);
}
cDisplayChannel::~cDisplayChannel()
@@ -4922,6 +4928,793 @@
return osEnd;
}
+// --- cGroupListItem -------------------------------------------------------
+const char *cGroupListItem::GroupName(void) {
+ if (channel)
+ return channel->Name();
+ return tr("Setup.Miscellaneous$All Channels");
+}
+
+// --- cDisplayChannelExtended -------------------------------------------------------
+cDisplayChannelExtended::cDisplayChannelExtended(int Number, bool Switched)
+:cDisplayChannel(Number, Switched)
+{
+ state = esDefault;
+ keyRightOpensChannellist = -1;
+ numItemsChannel = 0;
+ currentChannel = -1;
+ startChannel = -1;
+ numItemsGroup = 0;
+ currentGroup = -1;
+ startGroup = -1;
+}
+
+cDisplayChannelExtended::cDisplayChannelExtended(eKeys FirstKey)
+:cDisplayChannel(FirstKey, false)
+{
+ state = esInit;
+ keyRightOpensChannellist = -1;
+ numItemsChannel = 0;
+ currentChannel = -1;
+ startChannel = -1;
+ numItemsGroup = 0;
+ currentGroup = -1;
+ startGroup = -1;
+}
+
+cDisplayChannelExtended::~cDisplayChannelExtended()
+{
+}
+
+eOSState cDisplayChannelExtended::ProcessKey(eKeys Key)
+{
+ cSkinDisplayChannelExtended *displayChannelExtended = dynamic_cast<cSkinDisplayChannelExtended*>(displayChannel);
+ if (!displayChannelExtended)
+ return cDisplayChannel::ProcessKey(Key);
+
+ if (Key != kNone)
+ lastTime.Set();
+
+ bool keyHandeled = false;
+ //number keys are always handled by default state
+ if ((int)Key >= k0 && (int)Key <= k9) {
+ displayChannelExtended->SetViewType(dcDefault);
+ StateNumberKey((int)Key, displayChannelExtended);
+ state = esDefault;
+ } else if (number <= 0) {
+ switch (state) {
+ case esInit:
+ keyHandeled = StateInit((int)Key, displayChannelExtended);
+ break;
+ case esDefault:
+ keyHandeled = StateDefault((int)Key, displayChannelExtended);
+ break;
+ case esChannelInfo:
+ keyHandeled = StateChannelInfo((int)Key, displayChannelExtended);
+ break;
+ case esChannelList:
+ case esChannelListInfo:
+ keyHandeled = StateChannelList((int)Key, displayChannelExtended);
+ break;
+ case esGroupsList:
+ keyHandeled = StateGroupList((int)Key, displayChannelExtended);
+ break;
+ case esGroupsChannelList:
+ case esGroupsChannelListInfo:
+ keyHandeled = StateGroupChannelList((int)Key, displayChannelExtended);
+ break;
+ default:
+ break;
+ }
+ }
+ if (state == esClose)
+ return osEnd;
+ //in extended state, no timeout
+ if (state != esDefault)
+ lastTime.Set();
+
+ //do own flush for all lists
+ if (keyHandeled || (Key == kNone && state > esChannelInfo)) {
+ SetNeedsFastResponse(false);
+ displayChannel->Flush();
+ return osContinue;
+ }
+
+ return cDisplayChannel::ProcessKey(Key);
+}
+
+void cDisplayChannelExtended::StateNumberKey(int key, cSkinDisplayChannelExtended *dcExt)
+{
+ if (!Setup.ZapcockpitUseHints)
+ return;
+ if (number < 0)
+ return;
+ LOCK_CHANNELS_READ;
+ int selectedChannel = number > Channels->MaxNumber() ? key - k0 : number * 10 + key - k0;
+ int candidateStartNumber = selectedChannel * 10;
+ channellist.Clear();
+ const cChannel *candidatesStart = Channels->GetByNumber(candidateStartNumber);
+ int numHints = 0;
+ for (const cChannel *candidate = candidatesStart; candidate; candidate = Channels->Next(candidate)) {
+ if (candidate->GroupSep())
+ continue;
+ numHints++;
+ if (candidate->Number() >= candidateStartNumber + 9)
+ break;
+ }
+ if (numHints == 0)
+ return;
+ dcExt->SetNumChannelHints(numHints);
+ for (const cChannel *candidate = candidatesStart; candidate; candidate = Channels->Next(candidate)) {
+ if (candidate->GroupSep())
+ continue;
+ dcExt->SetChannelHint(candidate);
+ if (candidate->Number() >= candidateStartNumber + 9)
+ break;
+ }
+}
+
+bool cDisplayChannelExtended::StateInit(int key, cSkinDisplayChannelExtended *dcExt)
+{
+ if (keyRightOpensChannellist == -1)
+ keyRightOpensChannellist = dcExt->KeyRightOpensChannellist() ? 1 : 0;
+
+ bool keyHandeled = false;
+ switch (key) {
+ case kLeft|k_Repeat: case kLeft:
+ case kPrev|k_Repeat: case kPrev: {
+ if (!Setup.ZapcockpitUseGroups)
+ return false;
+ cOsdProvider::OsdSizeChanged(osdState); // just to get the current state
+ DisplayChannel();
+ DisplayInfo();
+ if (keyRightOpensChannellist) {
+ InitGroupList(dcExt);
+ state = esGroupsList;
+ } else {
+ InitChannelList(dcExt);
+ state = esChannelList;
+ }
+ keyHandeled = true;
+ break;
+ }
+ case kRight|k_Repeat: case kRight:
+ case kNext|k_Repeat: case kNext: {
+ if (!Setup.ZapcockpitUseGroups)
+ return false;
+ cOsdProvider::OsdSizeChanged(osdState); // just to get the current state
+ DisplayChannel();
+ DisplayInfo();
+ if (keyRightOpensChannellist) {
+ InitChannelList(dcExt);
+ state = esChannelList;
+ } else {
+ InitGroupList(dcExt);
+ state = esGroupsList;
+ }
+ keyHandeled = true;
+ break;
+ }
+ //other keys are handled by cDisplayChannel::ProcessKeys()
+ default:
+ dcExt->SetViewType(dcDefault);
+ state = esDefault;
+ break;
+ }
+ return keyHandeled;
+}
+
+bool cDisplayChannelExtended::StateDefault(int key, cSkinDisplayChannelExtended *dcExt)
+{
+ if (keyRightOpensChannellist == -1)
+ keyRightOpensChannellist = dcExt->KeyRightOpensChannellist() ? 1 : 0;
+ bool keyHandeled = false;
+ switch (key) {
+ //2nd ok opens extended info for current channel
+ case kOk: {
+ if (!Setup.ZapcockpitUseInfo)
+ return false;
+ dcExt->SetViewType(dcChannelInfo);
+ dcExt->SetChannelInfo(channel);
+ state = esChannelInfo;
+ keyHandeled = true;
+ break;
+ }
+ case kLeft|k_Repeat: case kLeft:
+ case kPrev|k_Repeat: case kPrev: {
+ if (!Setup.ZapcockpitUseGroups)
+ return false;
+ if (keyRightOpensChannellist) {
+ InitGroupList(dcExt);
+ state = esGroupsList;
+ } else {
+ InitChannelList(dcExt);
+ state = esChannelList;
+ }
+ keyHandeled = true;
+ break;
+ }
+ case kRight|k_Repeat: case kRight:
+ case kNext|k_Repeat: case kNext: {
+ if (!Setup.ZapcockpitUseGroups)
+ return false;
+ if (keyRightOpensChannellist) {
+ InitChannelList(dcExt);
+ state = esChannelList;
+ } else {
+ InitGroupList(dcExt);
+ state = esGroupsList;
+ }
+ keyHandeled = true;
+ break;
+ }
+ //other keys are handled by cDisplayChannel::ProcessKeys()
+ default:
+ break;
+ }
+ return keyHandeled;
+}
+
+bool cDisplayChannelExtended::StateChannelInfo(int key, cSkinDisplayChannelExtended *dcExt)
+{
+ bool keyHandeled = false;
+ switch (key) {
+ //ok closes here
+ case kOk:
+ state = esDefault;
+ break;
+ //channel switching is handled by default state
+ case kUp|k_Repeat: case kUp:
+ case kDown|k_Repeat: case kDown:
+ case kChanUp|k_Repeat: case kChanUp:
+ case kChanDn|k_Repeat: case kChanDn:
+ dcExt->SetViewType(dcDefault);
+ state = esDefault;
+ break;
+ case kUp|k_Release: case kDown|k_Release:
+ case kChanUp|k_Release: case kChanDn|k_Release:
+ case kNext|k_Release: case kPrev|k_Release:
+ dcExt->SetViewType(dcDefault);
+ state = esDefault;
+ break;
+ case kLeft|k_Repeat: case kLeft:
+ case kPrev|k_Repeat: case kPrev: {
+ if (!Setup.ZapcockpitUseGroups)
+ return false;
+ if (keyRightOpensChannellist) {
+ InitGroupList(dcExt);
+ state = esGroupsList;
+ } else {
+ InitChannelList(dcExt);
+ state = esChannelList;
+ }
+ keyHandeled = true;
+ break;
+ }
+ case kRight|k_Repeat: case kRight:
+ case kNext|k_Repeat: case kNext: {
+ if (!Setup.ZapcockpitUseGroups)
+ return false;
+ if (keyRightOpensChannellist) {
+ InitChannelList(dcExt);
+ state = esChannelList;
+ } else {
+ InitGroupList(dcExt);
+ state = esGroupsList;
+ }
+ keyHandeled = true;
+ break;
+ }
+ default:
+ break;
+ }
+ return keyHandeled;
+}
+
+bool cDisplayChannelExtended::StateChannelList(int key, cSkinDisplayChannelExtended *dcExt)
+{
+ bool keyHandeled = false;
+ switch (key) {
+ //ok switches to the selected channel
+ case kOk: {
+ bool ok = SwitchChannel();
+ dcExt->SetViewType(dcDefault);
+ if (!ok)
+ keyHandeled = true;
+ state = esDefault;
+ break;
+ }
+ //scrolling up / down
+ case kUp|k_Repeat: case kUp:
+ state = esChannelList;
+ dcExt->SetViewType(dcChannelList);
+ CursorUp(dcExt);
+ keyHandeled = true;
+ break;
+ case kDown|k_Repeat: case kDown:
+ state = esChannelList;
+ dcExt->SetViewType(dcChannelList);
+ CursorDown(dcExt);
+ keyHandeled = true;
+ break;
+ case kLeft|k_Repeat: case kLeft: {
+ keyHandeled = true;
+ if (keyRightOpensChannellist) {
+ if (state == esChannelList) {
+ state = esClose;
+ } else if (state == esChannelListInfo) {
+ dcExt->SetViewType(dcChannelList);
+ state = esChannelList;
+ }
+ } else
+ ShowChannellistInfo(dcExt, dcChannelListInfo);
+ break;
+ }
+ //right shows extended info of currently selected channel
+ case kRight|k_Repeat: case kRight: {
+ keyHandeled = true;
+ if (keyRightOpensChannellist)
+ ShowChannellistInfo(dcExt, dcChannelListInfo);
+ else {
+ if (state == esChannelList) {
+ state = esClose;
+ } else if (state == esChannelListInfo) {
+ dcExt->SetViewType(dcChannelList);
+ state = esChannelList;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return keyHandeled;
+}
+
+bool cDisplayChannelExtended::StateGroupList(int key, cSkinDisplayChannelExtended *dcExt)
+{
+ bool keyHandeled = false;
+ switch (key) {
+ //ok switches to first channel in group
+ case kOk: {
+ bool ok = SwitchChannel();
+ dcExt->SetViewType(dcDefault);
+ if (!ok)
+ keyHandeled = true;
+ state = esDefault;
+ break;
+ }
+ //scrolling up / down
+ case kUp|k_Repeat: case kUp:
+ state = esGroupsList;
+ CursorUp(dcExt);
+ dcExt->SetViewType(dcGroupsList);
+ keyHandeled = true;
+ break;
+ case kDown|k_Repeat: case kDown:
+ state = esGroupsList;
+ CursorDown(dcExt);
+ dcExt->SetViewType(dcGroupsList);
+ keyHandeled = true;
+ break;
+ case kLeft|k_Repeat: case kLeft:
+ keyHandeled = true;
+ if (keyRightOpensChannellist) {
+ state = esGroupsChannelList;
+ InitGroupChannelList(dcExt);
+ } else
+ state = esClose;
+ break;
+ case kRight|k_Repeat: case kRight:
+ keyHandeled = true;
+ if (keyRightOpensChannellist)
+ state = esClose;
+ else {
+ state = esGroupsChannelList;
+ InitGroupChannelList(dcExt);
+ }
+ break;
+ default:
+ break;
+ }
+ return keyHandeled;
+}
+
+bool cDisplayChannelExtended::StateGroupChannelList(int key, cSkinDisplayChannelExtended *dcExt)
+{
+ bool keyHandeled = false;
+ switch (key) {
+ //ok switches to the selected channel
+ case kOk: {
+ bool ok = SwitchChannel();
+ dcExt->SetViewType(dcDefault);
+ if (!ok)
+ keyHandeled = true;
+ state = esDefault;
+ break;
+ }
+ //scrolling up / down
+ case kUp|k_Repeat: case kUp:
+ state = esGroupsChannelList;
+ dcExt->SetViewType(dcGroupsChannelList);
+ CursorUp(dcExt);
+ keyHandeled = true;
+ break;
+ case kDown|k_Repeat: case kDown:
+ state = esGroupsChannelList;
+ dcExt->SetViewType(dcGroupsChannelList);
+ CursorDown(dcExt);
+ keyHandeled = true;
+ break;
+ case kLeft|k_Repeat: case kLeft: {
+ keyHandeled = true;
+ if (keyRightOpensChannellist)
+ ShowChannellistInfo(dcExt, dcGroupsChannelListInfo);
+ else {
+ if (state == esGroupsChannelList) {
+ state = esGroupsList;
+ dcExt->SetViewType(dcGroupsList);
+ } else if (state == esGroupsChannelListInfo) {
+ state = esGroupsChannelList;
+ dcExt->SetViewType(dcGroupsChannelList);
+ }
+ }
+ break;
+ }
+ case kRight|k_Repeat: case kRight: {
+ keyHandeled = true;
+ if (keyRightOpensChannellist) {
+ if (state == esGroupsChannelList) {
+ state = esGroupsList;
+ dcExt->SetViewType(dcGroupsList);
+ } else if (state == esGroupsChannelListInfo) {
+ state = esGroupsChannelList;
+ dcExt->SetViewType(dcGroupsChannelList);
+ }
+ } else
+ ShowChannellistInfo(dcExt, dcGroupsChannelListInfo);
+ break;
+ }
+ default:
+ break;
+ }
+ return keyHandeled;
+}
+
+void cDisplayChannelExtended::ShowChannellistInfo(cSkinDisplayChannelExtended *dcExt, eDisplaychannelView newViewType) {
+ if (newViewType == dcChannelListInfo && state != esChannelList)
+ return;
+ if (newViewType == dcGroupsChannelListInfo && state != esGroupsChannelList)
+ return;
+
+ cChannelListItem *li = channellist.Get(currentChannel);
+ if (li) {
+ const cChannel *selected = li->Channel();
+ if (selected) {
+ dcExt->SetViewType(newViewType);
+ dcExt->SetChannelInfo(selected);
+ state = (newViewType == dcChannelListInfo) ? esChannelListInfo : esGroupsChannelListInfo;
+ }
+ }
+}
+
+void cDisplayChannelExtended::InitChannelList(cSkinDisplayChannelExtended *dcExt)
+{
+ dcExt->SetViewType(dcChannelList);
+ numItemsChannel = dcExt->MaxItems();
+ if (numItemsChannel < 1)
+ return;
+ SetChannelList();
+ currentChannel = GetIndexChannel(channel);
+ if (currentChannel < 0)
+ currentChannel = 0;
+ startChannel = max(0, currentChannel - numItemsChannel/2 + 1);
+ DisplayChannelList(dcExt);
+}
+
+void cDisplayChannelExtended::SetChannelList(void)
+{
+ channellist.Clear();
+ const cChannel *lastSep = NULL;
+ if (Setup.ZapcockpitHideLastGroup)
+ lastSep = LastChannelSep();
+ LOCK_CHANNELS_READ;
+ for (const cChannel *c = Channels->First(); c; c = Channels->Next(c)) {
+ if (c->GroupSep()) {
+ if (Setup.ZapcockpitHideLastGroup && c == lastSep)
+ break;
+ else
+ continue;
+ }
+ channellist.Add(new cChannelListItem(c));
+ }
+}
+
+int cDisplayChannelExtended::GetIndexChannel(const cChannel *c)
+{
+ int i=0;
+ for (cChannelListItem *li = channellist.First(); li; li = channellist.Next(li)) {
+ if (li->Channel() == c)
+ return i;
+ i++;
+ }
+ return -1;
+}
+
+void cDisplayChannelExtended::InitGroupList(cSkinDisplayChannelExtended *dcExt)
+{
+ dcExt->SetViewType(dcGroupsList);
+ numItemsGroup = dcExt->MaxItems();
+ if (numItemsGroup < 1)
+ return;
+ SetGroupList();
+ currentGroup = GetIndexGroup(channel);
+ if (currentGroup < 0)
+ currentGroup = 0;
+ startGroup = max(0, numItemsGroup >= grouplist.Count() ? 0 : currentGroup - numItemsGroup/2 + 1);
+ DisplayGroupList(dcExt);
+}
+
+void cDisplayChannelExtended::SetGroupList(void)
+{
+ grouplist.Clear();
+ if (Setup.ZapcockpitShowAllChannels) {
+ cGroupListItem *allChannels = new cGroupListItem(NULL);
+ int totalNumChannels = 0;
+ const cChannel *lastSep = NULL;
+ if (Setup.ZapcockpitHideLastGroup)
+ lastSep = LastChannelSep();
+ LOCK_CHANNELS_READ;
+ for (const cChannel *c = Channels->First(); c; c = Channels->Next(c)) {
+ if (c->GroupSep()) {
+ if (Setup.ZapcockpitHideLastGroup && c == lastSep)
+ break;
+ else
+ continue;
+ }
+ totalNumChannels++;
+ }
+ allChannels->SetNumChannels(totalNumChannels);
+ grouplist.Add(allChannels);
+ }
+
+ const cChannel *lastSep = NULL;
+ if (Setup.ZapcockpitHideLastGroup)
+ lastSep = LastChannelSep();
+ int numChannels = 0;
+ cGroupListItem *item = NULL;
+ LOCK_CHANNELS_READ;
+ for (const cChannel *c = Channels->First(); c; c = Channels->Next(c)) {
+ if (c->GroupSep()) {
+ if (item) {
+ item->SetNumChannels(numChannels);
+ numChannels = 0;
+ }
+ if (Setup.ZapcockpitHideLastGroup && c == lastSep)
+ break;
+ item = new cGroupListItem(c);
+ grouplist.Add(item);
+ } else
+ numChannels++;
+ }
+ if (grouplist.Count() > 0 && numChannels)
+ grouplist.Last()->SetNumChannels(numChannels);
+}
+
+int cDisplayChannelExtended::GetIndexGroup(const cChannel *cur)
+{
+ const cChannel *group = NULL;
+ LOCK_CHANNELS_READ;
+ for (const cChannel *c = cur; c; c = Channels->Prev(c)) {
+ if (c->GroupSep()) {
+ group = c;
+ break;
+ }
+ }
+ if (!group)
+ return -1;
+ int i=0;
+ for (cGroupListItem *li = grouplist.First(); li; li = grouplist.Next(li)) {
+ if (li->Channel() == group)
+ return i;
+ i++;
+ }
+ return -1;
+}
+
+void cDisplayChannelExtended::InitGroupChannelList(cSkinDisplayChannelExtended *dcExt)
+{
+ dcExt->SetViewType(dcGroupsChannelList);
+ numItemsChannel = dcExt->MaxItems();
+ if (numItemsChannel < 1)
+ return;
+ SetGroupChannelList(dcExt);
+ currentChannel = 0;
+ startChannel = 0;
+ DisplayChannelList(dcExt);
+}
+
+void cDisplayChannelExtended::SetGroupChannelList(cSkinDisplayChannelExtended *dcExt)
+{
+ cGroupListItem *curGroup = grouplist.Get(currentGroup);
+ if (!curGroup)
+ return;
+ const cChannel *curChannel = curGroup->Channel();
+ if (!curChannel) {
+ if (Setup.ZapcockpitShowAllChannels)
+ SetChannelList();
+ return;
+ }
+ channellist.Clear();
+ LOCK_CHANNELS_READ;
+ for (const cChannel *c = dynamic_cast<cChannel*>(curChannel->Next()); c; c = Channels->Next(c)) {
+ if (c->GroupSep())
+ break;
+ channellist.Add(new cChannelListItem(c));
+ }
+}
+
+void cDisplayChannelExtended::CursorUp(cSkinDisplayChannelExtended *dcExt)
+{
+ int *start, *current, *numItems;
+ if (state == esChannelList || state == esGroupsChannelList) {
+ start = &startChannel;
+ current = &currentChannel;
+ numItems = &numItemsChannel;
+ } else if (state == esGroupsList) {
+ start = &startGroup;
+ current = &currentGroup;
+ numItems = &numItemsGroup;
+ } else
+ return;
+
+ if (*current == 0) {
+ dcExt->ClearList();
+ int itemsTotal = (state == esChannelList || state == esGroupsChannelList)?channellist.Count():((state == esGroupsList)?grouplist.Count():0);
+ *current = itemsTotal-1;
+ *start = max(0, itemsTotal - *numItems);
+ if (state == esChannelList || state == esGroupsChannelList)
+ DisplayChannelList(dcExt);
+ else if (state == esGroupsList)
+ DisplayGroupList(dcExt);
+ return;
+ }
+ int curRel = *current - *start;
+ if (curRel > 0) {
+ if (state == esChannelList || state == esGroupsChannelList) {
+ const cChannel *prev = channellist.Get(*current-1)->Channel();
+ dcExt->SetChannelList(channellist.Get(*current)->Channel(), curRel, false);
+ dcExt->SetChannelList(prev, curRel-1, true);
+ (*current)--;
+ return;
+ } else if (state = esGroupsList) {
+ cGroupListItem *prev = grouplist.Get(*current-1);
+ cGroupListItem *old = grouplist.Get(*current);
+ dcExt->SetGroupList(old->GroupName(), old->NumChannels(), curRel, false);
+ dcExt->SetGroupList(prev->GroupName(), prev->NumChannels(), curRel-1, true);
+ (*current)--;
+ return;
+ }
+ }
+ dcExt->ClearList();
+ (*current)--;
+ *start = max(0, *start-*numItems);
+
+ if (state == esChannelList || state == esGroupsChannelList)
+ DisplayChannelList(dcExt);
+ else if (state == esGroupsList)
+ DisplayGroupList(dcExt);
+}
+
+void cDisplayChannelExtended::CursorDown(cSkinDisplayChannelExtended *dcExt)
+{
+ int *start, *current, *numItems;
+ if (state == esChannelList || state == esGroupsChannelList) {
+ start = &startChannel;
+ current = &currentChannel;
+ numItems = &numItemsChannel;
+ } else if (state == esGroupsList) {
+ start = &startGroup;
+ current = &currentGroup;
+ numItems = &numItemsGroup;
+ } else
+ return;
+
+ int curRel = *current - *start;
+ if (curRel < *numItems - 1) {
+ if (state == esChannelList || state == esGroupsChannelList) {
+ cChannelListItem *next = channellist.Get(*current+1);
+ if (next) {
+ dcExt->SetChannelList(channellist.Get(*current)->Channel(), curRel, false);
+ dcExt->SetChannelList(next->Channel(), curRel+1, true);
+ (*current)++;
+ return;
+ }
+ } else if (state == esGroupsList) {
+ cGroupListItem *next = grouplist.Get(*current+1);
+ if (next) {
+ cGroupListItem *old = grouplist.Get(*current);
+ dcExt->SetGroupList(old->GroupName(), old->NumChannels(), curRel, false);
+ dcExt->SetGroupList(next->GroupName(), next->NumChannels(), curRel+1, true);
+ (*current)++;
+ return;
+ }
+ }
+ }
+ if (((state == esChannelList || state == esGroupsChannelList) && *current+1 == channellist.Count()) ||
+ (state == esGroupsList && *current+1 == grouplist.Count()))
+ *start = *current = 0;
+ else
+ *start = *current = *current+1;
+ dcExt->ClearList();
+
+ if (state == esChannelList || state == esGroupsChannelList)
+ DisplayChannelList(dcExt);
+ else if (state == esGroupsList)
+ DisplayGroupList(dcExt);
+}
+
+void cDisplayChannelExtended::DisplayChannelList(cSkinDisplayChannelExtended *dcExt)
+{
+ int index = 0;
+ for (cChannelListItem *c = channellist.Get(startChannel); c; c = channellist.Next(c)) {
+ dcExt->SetChannelList(c->Channel(), index, (startChannel + index == currentChannel) ? true : false);
+ if (++index == numItemsChannel)
+ break;
+ }
+}
+
+void cDisplayChannelExtended::DisplayGroupList(cSkinDisplayChannelExtended *dcExt)
+{
+ int index = 0;
+ for (cGroupListItem *g = grouplist.Get(startGroup); g; g = grouplist.Next(g)) {
+ dcExt->SetGroupList(g->GroupName(), g->NumChannels(), index, (startGroup + index == currentGroup) ? true : false);
+ if (++index == numItemsGroup)
+ break;
+ }
+}
+
+bool cDisplayChannelExtended::SwitchChannel(void)
+{
+ const cChannel *newChannel = NULL;
+ if ( state == esChannelList ||
+ state == esChannelListInfo ||
+ state == esGroupsChannelList ||
+ state == esGroupsChannelListInfo ) {
+ cChannelListItem *li = channellist.Get(currentChannel);
+ if (li)
+ newChannel = li->Channel();
+ } else if (state == esGroupsList) {
+ cGroupListItem *item = grouplist.Get(currentGroup);
+ if (!item)
+ return false;
+ const cChannel *cGroup = item->Channel();
+ LOCK_CHANNELS_READ;
+ for (const cChannel *c = cGroup; c; c = Channels->Next(c))
+ if (!c->GroupSep()) {
+ newChannel = c;
+ break;
+ }
+ }
+ if (!newChannel || newChannel == channel)
+ return false;
+ SetTrackDescriptions(newChannel->Number()); // to make them immediately visible in the channel display
+ LOCK_CHANNELS_READ;
+ Channels->SwitchTo(newChannel->Number());
+ SetTrackDescriptions(newChannel->Number()); // switching the channel has cleared them
+ channel = newChannel;
+ return true;
+}
+
+const cChannel *cDisplayChannelExtended::LastChannelSep(void)
+{
+ LOCK_CHANNELS_READ;
+ for (const cChannel *c = Channels->Last(); c; c = Channels->Prev(c))
+ if (c->GroupSep())
+ return c;
+ return NULL;
+}
+
// --- cDisplayVolume --------------------------------------------------------
#define VOLUMETIMEOUT 1000 //ms
diff -Nur vdr-2.4.0/menu.h vdr-2.4.0.p/menu.h
--- vdr-2.4.0/menu.h 2018-04-14 12:24:41.000000000 +0200
+++ vdr-2.4.0.p/menu.h 2019-04-04 15:27:27.648451092 +0200
@@ -119,30 +119,102 @@
class cDisplayChannel : public cOsdObject {
private:
- cSkinDisplayChannel *displayChannel;
int group;
bool withInfo;
- cTimeMs lastTime;
- int number;
bool timeout;
- int osdState;
const cPositioner *positioner;
- const cChannel *channel;
const cEvent *lastPresent;
const cEvent *lastFollowing;
static cDisplayChannel *currentDisplayChannel;
- void DisplayChannel(void);
- void DisplayInfo(void);
void Refresh(void);
const cChannel *NextAvailableChannel(const cChannel *Channel, int Direction);
+protected:
+ cSkinDisplayChannel *displayChannel;
+ cTimeMs lastTime;
+ int number;
+ const cChannel *channel;
+ int osdState;
+ void DisplayChannel(void);
+ void DisplayInfo(void);
public:
cDisplayChannel(int Number, bool Switched);
- cDisplayChannel(eKeys FirstKey);
+ cDisplayChannel(eKeys FirstKey, bool processKey = true);
virtual ~cDisplayChannel();
virtual eOSState ProcessKey(eKeys Key);
static bool IsOpen(void) { return currentDisplayChannel != NULL; }
};
+enum eExtendedState {
+ esInit = 0,
+ esDefault,
+ esChannelInfo,
+ esChannelList,
+ esChannelListInfo,
+ esGroupsList,
+ esGroupsChannelList,
+ esGroupsChannelListInfo,
+ esClose
+ };
+
+class cChannelListItem : public cListObject {
+private:
+ const cChannel *channel;
+public:
+ cChannelListItem(const cChannel *Channel) { channel = Channel; };
+ virtual ~cChannelListItem(void) { };
+ const cChannel *Channel(void) { return channel; }
+ };
+
+class cGroupListItem : public cListObject {
+private:
+ const cChannel *channel;
+ int numChannels;
+public:
+ cGroupListItem(const cChannel *Channel) { channel = Channel; numChannels = 0; };
+ virtual ~cGroupListItem(void) { };
+ const char *GroupName(void);
+ void SetNumChannels(int NumChannels) { numChannels = NumChannels; };
+ int NumChannels(void) { return numChannels; };
+ const cChannel *Channel(void) { return channel; }
+ };
+
+class cDisplayChannelExtended : public cDisplayChannel {
+private:
+ eExtendedState state;
+ int keyRightOpensChannellist;
+ int numItemsChannel, startChannel, currentChannel;
+ int numItemsGroup, startGroup, currentGroup;
+ cList<cChannelListItem> channellist;
+ cList<cGroupListItem> grouplist;
+ void StateNumberKey(int key, cSkinDisplayChannelExtended *dcExt);
+ bool StateInit(int key, cSkinDisplayChannelExtended *dcExt);
+ bool StateDefault(int key, cSkinDisplayChannelExtended *dcExt);
+ bool StateChannelInfo(int key, cSkinDisplayChannelExtended *dcExt);
+ bool StateChannelList(int key, cSkinDisplayChannelExtended *dcExt);
+ bool StateGroupList(int key, cSkinDisplayChannelExtended *dcExt);
+ bool StateGroupChannelList(int key, cSkinDisplayChannelExtended *dcExt);
+ void ShowChannellistInfo(cSkinDisplayChannelExtended *dcExt, eDisplaychannelView newViewType);
+ void InitChannelList(cSkinDisplayChannelExtended *dcExt);
+ void SetChannelList(void);
+ int GetIndexChannel(const cChannel *c);
+ void InitGroupList(cSkinDisplayChannelExtended *dcExt);
+ void SetGroupList(void);
+ int GetIndexGroup(const cChannel *c);
+ void InitGroupChannelList(cSkinDisplayChannelExtended *dcExt);
+ void SetGroupChannelList(cSkinDisplayChannelExtended *dcExt);
+ void CursorUp(cSkinDisplayChannelExtended *dcExt);
+ void CursorDown(cSkinDisplayChannelExtended *dcExt);
+ void DisplayChannelList(cSkinDisplayChannelExtended *dcExt);
+ void DisplayGroupList(cSkinDisplayChannelExtended *dcExt);
+ bool SwitchChannel(void);
+ const cChannel *LastChannelSep(void);
+public:
+ cDisplayChannelExtended(int Number, bool Switched);
+ cDisplayChannelExtended(eKeys FirstKey);
+ virtual ~cDisplayChannelExtended();
+ virtual eOSState ProcessKey(eKeys Key);
+ };
+
class cDisplayVolume : public cOsdObject {
private:
cSkinDisplayVolume *displayVolume;
diff -Nur vdr-2.4.0/po/de_DE.po vdr-2.4.0.p/po/de_DE.po
--- vdr-2.4.0/po/de_DE.po 2019-04-04 15:47:31.199441881 +0200
+++ vdr-2.4.0.p/po/de_DE.po 2019-04-04 15:29:21.903832616 +0200
@@ -1347,6 +1347,21 @@
msgid "Setup.Miscellaneous$Channel entry timeout (ms)"
msgstr "Zeitlimit f<>r Kanaleingabe (ms)"
+msgid "Setup.Miscellaneous$Zapcockpit: 2nd ok shows info"
+msgstr "Zapcockpit: zweites OK zeigt Info"
+
+msgid "Setup.Miscellaneous$Zapcockpit: Use extended channel group display"
+msgstr "Zapcockpit: Erweiterte Kanalgruppen Anzeige benutzen"
+
+msgid "Setup.Miscellaneous$Zapcockpit: Use channel hints"
+msgstr "Zapcockpit: Kanalhinweise benutzen"
+
+msgid "Setup.Miscellaneous$Zapcockpit: Hide last channel group"
+msgstr "Zapcockpit: letzte Kanalgruppe ausblenden"
+
+msgid "Setup.Miscellaneous$Zapcockpit: Show \"All Channels\" Item in Group List"
+msgstr "Zapcockpit: Zeige \"Alle Kan<61>le\" in Kanalgruppen Liste"
+
msgid "Setup.Miscellaneous$Remote control repeat delay (ms)"
msgstr "Fernbedienung Wiederholverz<72>gerung (ms)"
@@ -1419,6 +1434,9 @@
msgid "Cancel editing?"
msgstr "Bearbeitung abbrechen?"
+msgid "Setup.Miscellaneous$All Channels"
+msgstr "Alle Kan<61>le"
+
msgid "No audio available!"
msgstr "Kein Audio verf<72>gbar!"
diff -Nur vdr-2.4.0/skins.c vdr-2.4.0.p/skins.c
--- vdr-2.4.0/skins.c 2019-04-04 15:47:25.665519948 +0200
+++ vdr-2.4.0.p/skins.c 2019-04-04 14:57:48.240702878 +0200
@@ -79,6 +79,13 @@
SetMessage(mtInfo, cString::sprintf(tr("Moving dish to %.1f..."), double(positioner->TargetLongitude()) / 10));
}
+cSkinDisplayChannelExtended::cSkinDisplayChannelExtended(void)
+: cSkinDisplayChannel()
+{
+
+}
+
+
// --- cSkinDisplayMenu ------------------------------------------------------
cSkinDisplayMenu::cSkinDisplayMenu(void)
diff -Nur vdr-2.4.0/skins.h vdr-2.4.0.p/skins.h
--- vdr-2.4.0/skins.h 2017-11-02 16:04:56.000000000 +0100
+++ vdr-2.4.0.p/skins.h 2019-04-04 14:57:48.241702864 +0200
@@ -101,6 +101,34 @@
*/
};
+#define USE_ZAPCOCKPIT 1
+
+enum eDisplaychannelView {
+ dcDefault = 0,
+ dcChannelInfo,
+ dcChannelList,
+ dcChannelListInfo,
+ dcGroupsList,
+ dcGroupsChannelList,
+ dcGroupsChannelListInfo
+ };
+
+class cSkinDisplayChannelExtended : public cSkinDisplayChannel {
+private:
+public:
+ cSkinDisplayChannelExtended(void);
+ virtual void SetViewType(eDisplaychannelView ViewType) = 0;
+ virtual int MaxItems(void) = 0;
+ virtual bool KeyRightOpensChannellist(void) = 0;
+ virtual void SetChannelInfo(const cChannel *Channel) = 0;
+ virtual void SetChannelList(const cChannel *Channel, int Index, bool Current) = 0;
+ virtual void SetGroupList(const char *Group, int NumChannels, int Index, bool Current) = 0;
+ virtual void SetGroupChannelList(const cChannel *Channel, int Index, bool Current) = 0;
+ virtual void ClearList(void) = 0;
+ virtual void SetNumChannelHints(int Num) = 0;
+ virtual void SetChannelHint(const cChannel *Channel) = 0;
+};
+
enum eMenuCategory {
mcUndefined = -1,
mcUnknown = 0,
diff -Nur vdr-2.4.0/vdr.c vdr-2.4.0.p/vdr.c
--- vdr-2.4.0/vdr.c 2019-04-04 15:47:25.719519186 +0200
+++ vdr-2.4.0.p/vdr.c 2019-04-04 14:57:48.241702864 +0200
@@ -1088,7 +1088,7 @@
// Channel display:
if (!EITScanner.Active() && cDevice::CurrentChannel() != LastChannel) {
if (!Menu)
- Menu = new cDisplayChannel(cDevice::CurrentChannel(), LastChannel >= 0);
+ Menu = new cDisplayChannelExtended(cDevice::CurrentChannel(), LastChannel >= 0);
LastChannel = cDevice::CurrentChannel();
LastChannelChanged = Now;
}
@@ -1287,7 +1287,8 @@
case kChanDn|k_Repeat:
case kChanDn:
if (!Interact) {
- Menu = new cDisplayChannel(NORMALKEY(key));
+ Menu = new cDisplayChannelExtended(NORMALKEY(key));
+ Menu->ProcessKey(NORMALKEY(key));
continue;
}
else if (cDisplayChannel::IsOpen() || cControl::Control()) {
@@ -1480,7 +1481,8 @@
case kUp:
case kDown|k_Repeat:
case kDown:
- Menu = new cDisplayChannel(NORMALKEY(key));
+ Menu = new cDisplayChannelExtended(NORMALKEY(key));
+ Menu->ProcessKey(NORMALKEY(key));
break;
// Viewing Control:
case kOk: LastChannel = -1; break; // forces channel display