diff options
Diffstat (limited to 'patches/vdr-2.2.0_zapcockpit.patch')
-rw-r--r-- | patches/vdr-2.2.0_zapcockpit.patch | 1015 |
1 files changed, 1015 insertions, 0 deletions
diff --git a/patches/vdr-2.2.0_zapcockpit.patch b/patches/vdr-2.2.0_zapcockpit.patch new file mode 100644 index 0000000..1eda556 --- /dev/null +++ b/patches/vdr-2.2.0_zapcockpit.patch @@ -0,0 +1,1015 @@ +diff -Naur vdr-2.2.0/config.c vdr-2.2.0_zapcockpit/config.c +--- vdr-2.2.0/config.c 2015-02-10 13:24:13.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/config.c 2016-05-26 07:29:05.736117301 +0200 +@@ -414,6 +414,10 @@ + SVDRPTimeout = 300; + ZapTimeout = 3; + ChannelEntryTimeout = 1000; ++ ZapcockpitUseGroups = 1; ++ ZapcockpitUseHints = 1; ++ ZapcockpitUseInfo = 1; ++ ZapcockpitHideLastGroup = 0; + RcRepeatDelay = 300; + RcRepeatDelta = 100; + DefaultPriority = 50; +@@ -636,6 +640,10 @@ + else if (!strcasecmp(Name, "SVDRPTimeout")) SVDRPTimeout = atoi(Value); + 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, "RcRepeatDelay")) RcRepeatDelay = atoi(Value); + else if (!strcasecmp(Name, "RcRepeatDelta")) RcRepeatDelta = atoi(Value); + else if (!strcasecmp(Name, "DefaultPriority")) DefaultPriority = atoi(Value); +@@ -762,6 +770,10 @@ + Store("SVDRPTimeout", SVDRPTimeout); + Store("ZapTimeout", ZapTimeout); + Store("ChannelEntryTimeout",ChannelEntryTimeout); ++ Store("ZapcockpitUseGroups",ZapcockpitUseGroups); ++ Store("ZapcockpitUseHints", ZapcockpitUseHints); ++ Store("ZapcockpitUseInfo", ZapcockpitUseInfo); ++ Store("ZapcockpitHideLastGroup", ZapcockpitHideLastGroup); + Store("RcRepeatDelay", RcRepeatDelay); + Store("RcRepeatDelta", RcRepeatDelta); + Store("DefaultPriority", DefaultPriority); +diff -Naur vdr-2.2.0/config.h vdr-2.2.0_zapcockpit/config.h +--- vdr-2.2.0/config.h 2015-02-13 16:39:08.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/config.h 2016-05-26 07:29:05.708117300 +0200 +@@ -290,6 +290,10 @@ + int SVDRPTimeout; + int ZapTimeout; + int ChannelEntryTimeout; ++ int ZapcockpitUseGroups; ++ int ZapcockpitUseHints; ++ int ZapcockpitUseInfo; ++ int ZapcockpitHideLastGroup; + int RcRepeatDelay; + int RcRepeatDelta; + int DefaultPriority, DefaultLifetime; +diff -Naur vdr-2.2.0/menu.c vdr-2.2.0_zapcockpit/menu.c +--- vdr-2.2.0/menu.c 2015-02-10 13:37:06.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/menu.c 2016-05-26 07:29:05.880117306 +0200 +@@ -3759,6 +3759,10 @@ + Add(new cMenuEditIntItem( tr("Setup.Miscellaneous$SVDRP timeout (s)"), &data.SVDRPTimeout)); + 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 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"))); +@@ -4207,7 +4211,7 @@ + lastTime.Set(); + } + +-cDisplayChannel::cDisplayChannel(eKeys FirstKey) ++cDisplayChannel::cDisplayChannel(eKeys FirstKey, bool processKey) + :cOsdObject(true) + { + currentDisplayChannel = this; +@@ -4220,7 +4224,8 @@ + displayChannel = Skins.Current()->DisplayChannel(withInfo); + positioner = NULL; + channel = Channels.GetByNumber(cDevice::CurrentChannel()); +- ProcessKey(FirstKey); ++ if (processKey) ++ ProcessKey(FirstKey); + } + + cDisplayChannel::~cDisplayChannel() +@@ -4461,6 +4466,700 @@ + return osEnd; + } + ++// --- cDisplayChannelExtended ------------------------------------------------------- ++cDisplayChannelExtended::cDisplayChannelExtended(int Number, bool Switched) ++:cDisplayChannel(Number, Switched) ++{ ++ state = esDefault; ++ numItemsChannel = 0; ++ currentChannel = -1; ++ startChannel = -1; ++ numItemsGroup = 0; ++ currentGroup = -1; ++ startGroup = -1; ++} ++ ++cDisplayChannelExtended::cDisplayChannelExtended(eKeys FirstKey) ++:cDisplayChannel(FirstKey, false) ++{ ++ state = esInit; ++ 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; ++ } ++ } ++ //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; ++ int selectedChannel = number > Channels.MaxNumber() ? key - k0 : number * 10 + key - k0; ++ int candidateStartNumber = selectedChannel * 10; ++ channellist.Clear(); ++ cChannel *candidatesStart = Channels.GetByNumber(candidateStartNumber); ++ int numHints = 0; ++ for (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 (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) ++{ ++ bool keyHandeled = false; ++ switch (key) { ++ //left openes groups list ++ 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(); ++ InitGroupList(dcExt); ++ state = esGroupsList; ++ keyHandeled = true; ++ break; ++ } ++ //right openes channels list ++ 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(); ++ InitChannelList(dcExt); ++ state = esChannelList; ++ 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) ++{ ++ 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; ++ } ++ //left openes groups list ++ case kLeft|k_Repeat: case kLeft: ++ case kPrev|k_Repeat: case kPrev: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ InitGroupList(dcExt); ++ state = esGroupsList; ++ keyHandeled = true; ++ break; ++ } ++ //right openes channels list ++ case kRight|k_Repeat: case kRight: ++ case kNext|k_Repeat: case kNext: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ InitChannelList(dcExt); ++ state = esChannelList; ++ 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; ++ //left openes groups list ++ case kLeft|k_Repeat: case kLeft: ++ case kPrev|k_Repeat: case kPrev: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ InitGroupList(dcExt); ++ state = esGroupsList; ++ keyHandeled = true; ++ break; ++ } ++ //right openes channels list ++ case kRight|k_Repeat: case kRight: ++ case kNext|k_Repeat: case kNext: { ++ if (!Setup.ZapcockpitUseGroups) ++ return false; ++ InitChannelList(dcExt); ++ state = esChannelList; ++ 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; ++ //left closes channel list ++ case kLeft|k_Repeat: case kLeft: { ++ if (state == esChannelList) { ++ keyHandeled = true; ++ dcExt->SetViewType(dcDefault); ++ state = esDefault; ++ } else if (state == esChannelListInfo) { ++ keyHandeled = true; ++ dcExt->SetViewType(dcChannelList); ++ state = esChannelList; ++ } ++ break; } ++ //right shows extended info of currently selected channel ++ case kRight|k_Repeat: case kRight: { ++ keyHandeled = true; ++ if (state != esChannelList) ++ break; ++ cChannelListItem *li = channellist.Get(currentChannel); ++ if (li) { ++ const cChannel *selected = li->Channel(); ++ if (selected) { ++ dcExt->SetViewType(dcChannelListInfo); ++ dcExt->SetChannelInfo(selected); ++ state = esChannelListInfo; ++ } ++ } ++ 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; ++ //left shows channel list of selected group ++ case kLeft|k_Repeat: case kLeft: ++ state = esGroupsChannelList; ++ InitGroupChannelList(dcExt); ++ keyHandeled = true; ++ break; ++ //right closes group list ++ case kRight|k_Repeat: case kRight: ++ keyHandeled = true; ++ dcExt->SetViewType(dcDefault); ++ state = esDefault; ++ 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; ++ //left shows extended info of currently selected channel ++ case kLeft|k_Repeat: case kLeft: { ++ keyHandeled = true; ++ if (state != esGroupsChannelList) ++ break; ++ cChannelListItem *li = channellist.Get(currentChannel); ++ if (li) { ++ const cChannel *selected = li->Channel(); ++ if (selected) { ++ dcExt->SetViewType(dcGroupsChannelListInfo); ++ dcExt->SetChannelInfo(selected); ++ state = esGroupsChannelListInfo; ++ } ++ } ++ break; ++ } ++ //right closes channel list or channel info ++ case kRight|k_Repeat: case kRight: { ++ if (state == esGroupsChannelList) { ++ state = esGroupsList; ++ dcExt->SetViewType(dcGroupsList); ++ keyHandeled = true; ++ } else if (state == esGroupsChannelListInfo) { ++ state = esGroupsChannelList; ++ dcExt->SetViewType(dcGroupsChannelList); ++ keyHandeled = true; ++ } ++ break; ++ } ++ default: ++ break; ++ } ++ return keyHandeled; ++} ++ ++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(); ++ cChannel *lastSep = NULL; ++ if (Setup.ZapcockpitHideLastGroup) ++ lastSep = LastChannelSep(); ++ for (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(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(); ++ cChannel *lastSep = NULL; ++ if (Setup.ZapcockpitHideLastGroup) ++ lastSep = LastChannelSep(); ++ int numChannels = 0; ++ cGroupListItem *item = NULL; ++ for (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(cChannel *cur) ++{ ++ cChannel *group = NULL; ++ for (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; ++ cChannel *curChannel = curGroup->Channel(); ++ if (!curChannel) ++ return; ++ channellist.Clear(); ++ for (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 = ¤tChannel; ++ numItems = &numItemsChannel; ++ } else if (state == esGroupsList) { ++ start = &startGroup; ++ current = ¤tGroup; ++ 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 = ¤tChannel; ++ numItems = &numItemsChannel; ++ } else if (state == esGroupsList) { ++ start = &startGroup; ++ current = ¤tGroup; ++ 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) ++{ ++ 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; ++ cChannel *cGroup = item->Channel(); ++ for (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 ++ Channels.SwitchTo(newChannel->Number()); ++ SetTrackDescriptions(newChannel->Number()); // switching the channel has cleared them ++ channel = newChannel; ++ return true; ++} ++ ++cChannel *cDisplayChannelExtended::LastChannelSep(void) ++{ ++ for (cChannel *c = Channels.Last(); c; c = Channels.Prev(c)) ++ if (c->GroupSep()) ++ return c; ++ return NULL; ++} ++ + // --- cDisplayVolume -------------------------------------------------------- + + #define VOLUMETIMEOUT 1000 //ms +diff -Naur vdr-2.2.0/menu.h vdr-2.2.0_zapcockpit/menu.h +--- vdr-2.2.0/menu.h 2015-02-06 10:47:30.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/menu.h 2016-05-26 07:29:05.680117299 +0200 +@@ -115,30 +115,99 @@ + + class cDisplayChannel : public cOsdObject { + private: +- cSkinDisplayChannel *displayChannel; + int group; + bool withInfo; +- cTimeMs lastTime; +- int number; + bool timeout; +- int osdState; + const cPositioner *positioner; +- cChannel *channel; + const cEvent *lastPresent; + const cEvent *lastFollowing; + static cDisplayChannel *currentDisplayChannel; +- void DisplayChannel(void); +- void DisplayInfo(void); + void Refresh(void); + cChannel *NextAvailableChannel(cChannel *Channel, int Direction); ++protected: ++ cSkinDisplayChannel *displayChannel; ++ cTimeMs lastTime; ++ int number; ++ 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 ++ }; ++ ++class cChannelListItem : public cListObject { ++private: ++ cChannel *channel; ++public: ++ cChannelListItem(cChannel *Channel) { channel = Channel; }; ++ virtual ~cChannelListItem(void) { }; ++ cChannel *Channel(void) { return channel; } ++ }; ++ ++class cGroupListItem : public cListObject { ++private: ++ cChannel *channel; ++ int numChannels; ++public: ++ cGroupListItem(cChannel *Channel) { channel = Channel; numChannels = 0; }; ++ virtual ~cGroupListItem(void) { }; ++ const char *GroupName(void) { return channel->Name(); } ++ void SetNumChannels(int NumChannels) { numChannels = NumChannels; }; ++ int NumChannels(void) { return numChannels; }; ++ cChannel *Channel(void) { return channel; } ++ }; ++ ++class cDisplayChannelExtended : public cDisplayChannel { ++private: ++ eExtendedState state; ++ 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 InitChannelList(cSkinDisplayChannelExtended *dcExt); ++ void SetChannelList(void); ++ int GetIndexChannel(cChannel *c); ++ void InitGroupList(cSkinDisplayChannelExtended *dcExt); ++ void SetGroupList(void); ++ int GetIndexGroup(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); ++ 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 -Naur vdr-2.2.0/po/de_DE.po vdr-2.2.0_zapcockpit/po/de_DE.po +--- vdr-2.2.0/po/de_DE.po 2015-02-19 10:12:22.401201125 +0100 ++++ vdr-2.2.0_zapcockpit/po/de_DE.po 2016-05-26 07:29:05.836117304 +0200 +@@ -8,7 +8,7 @@ + msgstr "" + "Project-Id-Version: VDR 2.2.0\n" + "Report-Msgid-Bugs-To: <vdr-bugs@tvdr.de>\n" +-"POT-Creation-Date: 2015-02-10 13:40+0100\n" ++"POT-Creation-Date: 2016-05-22 09:17+0200\n" + "PO-Revision-Date: 2015-02-10 13:45+0100\n" + "Last-Translator: Klaus Schmidinger <vdr@tvdr.de>\n" + "Language-Team: German <vdr@linuxtv.org>\n" +@@ -1284,6 +1284,18 @@ + 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$Remote control repeat delay (ms)" + msgstr "Fernbedienung Wiederholverzögerung (ms)" + +diff -Naur vdr-2.2.0/skins.c vdr-2.2.0_zapcockpit/skins.c +--- vdr-2.2.0/skins.c 2013-08-18 14:07:22.000000000 +0200 ++++ vdr-2.2.0_zapcockpit/skins.c 2016-05-26 07:29:05.788117303 +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 -Naur vdr-2.2.0/skins.h vdr-2.2.0_zapcockpit/skins.h +--- vdr-2.2.0/skins.h 2015-01-15 11:45:47.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/skins.h 2016-05-26 07:29:05.740117301 +0200 +@@ -88,6 +88,33 @@ + */ + }; + ++#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 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 -Naur vdr-2.2.0/vdr.c vdr-2.2.0_zapcockpit/vdr.c +--- vdr-2.2.0/vdr.c 2015-02-10 15:13:12.000000000 +0100 ++++ vdr-2.2.0_zapcockpit/vdr.c 2016-05-26 07:29:05.676117299 +0200 +@@ -996,7 +996,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; + } +@@ -1174,8 +1174,10 @@ + case kChanUp: + case kChanDn|k_Repeat: + case kChanDn: +- if (!Interact) +- Menu = new cDisplayChannel(NORMALKEY(key)); ++ if (!Interact) { ++ Menu = new cDisplayChannelExtended(NORMALKEY(key)); ++ Menu->ProcessKey(NORMALKEY(key)); ++ } + else if (cDisplayChannel::IsOpen() || cControl::Control()) { + Interact->ProcessKey(key); + continue; +@@ -1368,7 +1370,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 |