mirror of
				https://projects.vdr-developer.org/git/vdr-plugin-skindesigner.git
				synced 2023-10-19 15:58:31 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			1125 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			1125 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| diff -Nur vdr-2.4.1/config.c vdr-2.4.1.p/config.c
 | ||
| --- vdr-2.4.1/config.c	2018-02-15 15:40:36.000000000 +0100
 | ||
| +++ vdr-2.4.1.p/config.c	2020-02-07 10:19:48.221678977 +0100
 | ||
| @@ -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.1/config.h vdr-2.4.1.p/config.h
 | ||
| --- vdr-2.4.1/config.h	2019-06-16 11:13:45.000000000 +0200
 | ||
| +++ vdr-2.4.1.p/config.h	2020-02-07 10:19:48.221678977 +0100
 | ||
| @@ -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.1/menu.c vdr-2.4.1.p/menu.c
 | ||
| --- vdr-2.4.1/menu.c	2019-05-28 17:55:44.000000000 +0200
 | ||
| +++ vdr-2.4.1.p/menu.c	2020-02-07 11:13:24.404660741 +0100
 | ||
| @@ -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,799 @@
 | ||
|    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
 | ||
| +         {
 | ||
| +         LOCK_CHANNELS_READ;
 | ||
| +         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
 | ||
| +         {
 | ||
| +         LOCK_CHANNELS_READ;
 | ||
| +         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 = ¤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)
 | ||
| +{
 | ||
| +  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.1/menu.h vdr-2.4.1.p/menu.h
 | ||
| --- vdr-2.4.1/menu.h	2018-04-14 12:24:41.000000000 +0200
 | ||
| +++ vdr-2.4.1.p/menu.h	2020-02-07 10:19:48.222678975 +0100
 | ||
| @@ -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.1/po/de_DE.po vdr-2.4.1.p/po/de_DE.po
 | ||
| --- vdr-2.4.1/po/de_DE.po	2018-04-10 15:22:27.000000000 +0200
 | ||
| +++ vdr-2.4.1.p/po/de_DE.po	2020-02-07 10:19:48.223678974 +0100
 | ||
| @@ -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.1/skins.c vdr-2.4.1.p/skins.c
 | ||
| --- vdr-2.4.1/skins.c	2019-05-29 18:49:48.000000000 +0200
 | ||
| +++ vdr-2.4.1.p/skins.c	2020-02-07 10:19:48.223678974 +0100
 | ||
| @@ -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.1/skins.h vdr-2.4.1.p/skins.h
 | ||
| --- vdr-2.4.1/skins.h	2019-05-29 18:49:48.000000000 +0200
 | ||
| +++ vdr-2.4.1.p/skins.h	2020-02-07 10:19:48.223678974 +0100
 | ||
| @@ -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.1/vdr.c vdr-2.4.1.p/vdr.c
 | ||
| --- vdr-2.4.1/vdr.c	2019-05-23 12:02:45.000000000 +0200
 | ||
| +++ vdr-2.4.1.p/vdr.c	2020-02-07 10:19:48.223678974 +0100
 | ||
| @@ -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;
 | ||
|             }
 | ||
| @@ -1289,7 +1289,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()) {
 | ||
| @@ -1482,7 +1483,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
 |