Logo Search packages:      
Sourcecode: vdr-plugin-epgsearch version File versions

changrp.c

#include "changrp.h"
#include "epgsearchtools.h"
#include "epgsearchcfg.h"
#include "epgsearchext.h"
#include <vdr/interface.h>

// -- cChannelGroup -----------------------------------------------------------------
cChannelGroup::cChannelGroup(void)
{
    strcpy(name, "");
    channels.Clear();
}

cChannelGroup::~cChannelGroup(void)
{
    channels.Clear();
}

bool cChannelGroup::Parse(const char *s)
{
  char *line;
  char *pos;
  char *pos_next;
  int parameter = 1;
  int valuelen;
#define MAXVALUELEN (10 * MaxFileName)

  char value[MAXVALUELEN];

  pos = line = strdup(s);
  pos_next = pos + strlen(pos);
  if (*pos_next == '\n') *pos_next = 0;
  while (*pos) {
    while (*pos == ' ') pos++;
    if (*pos) {
      if (*pos != '|') {
        pos_next = strchr(pos, '|');
        if (!pos_next)
          pos_next = pos + strlen(pos);
        valuelen = pos_next - pos + 1;
        if (valuelen > MAXVALUELEN) 
      {
          LogFile.eSysLog("entry '%s' is too long. Will be truncated!", pos);  
          valuelen = MAXVALUELEN;
      }
        strn0cpy(value, pos, valuelen);
        pos = pos_next;
        switch (parameter) {
          case 1:  strcpy(name,value);
            break;
          default:
          {
            char *channelbuffer = NULL;
            int numChannels = sscanf(value, "%a[^|]", &channelbuffer);
            if (numChannels == 1)
            {
                cChannel* channel = Channels.GetByChannelID(tChannelID::FromString(channelbuffer), true, true);
                if (channel)
                {
                  cChannelGroupItem* channelitem = new cChannelGroupItem(channel);
                  channels.Add(channelitem);
                }
            }
            free(channelbuffer);
          }
          break;
        } //switch
      }
      parameter++;
    }
    if (*pos) pos++;
  } //while
  
  free(line);
  return (parameter >= 1) ? true : false;
}

const char *cChannelGroup::ToText(void)
{
    char* channelbuffer = NULL;
    cChannelGroupItem* ChannelGroupItem = channels.First();
    int index = 0;
    while (ChannelGroupItem) 
    {
      cChannel* channel = ChannelGroupItem->channel;
      if (index++ == 0)
          channelbuffer = strdup(CHANNELSTRING(channel));
      else
      {
          char* temp = channelbuffer;           
          asprintf(&channelbuffer, "%s|%s", channelbuffer, CHANNELSTRING(channel));
          free(temp);
      }
      ChannelGroupItem = channels.Next(ChannelGroupItem);
    } 
    char* buffer = NULL;
    asprintf(&buffer, "%s|%s", name, channelbuffer);
    free(channelbuffer);
    return buffer;
}

int* cChannelGroup::CreateChannelSel()
{
    int* channelSel = (int*) malloc(Channels.Count() * sizeof(int));
    cChannel* channel = Channels.First();
    int index = 0;
    while (channel) 
    {
      if (channel->GroupSep())
      {
          channel = Channels.Next(channel);
          continue;
      }
      channelSel[index] = 0;
      cChannelGroupItem* channelInGroup = channels.First();
      while (channelInGroup) 
      {     
          if (channel == channelInGroup->channel)
          {
            channelSel[index] = 1;
            break;
          }
          channelInGroup = channels.Next(channelInGroup);
      }     
      index++;
      channel = Channels.Next(channel);
    } 
    return channelSel;
}

void cChannelGroup::CreateChannelList(int* channelSel)
{
    channels.Clear();
    cChannel* channel = Channels.First();
    int index = 0;
    while (channel) 
    {
      if (!channel->GroupSep())
      {
          if (channelSel[index] == 1)
            channels.Add(new cChannelGroupItem(channel));
          index++;
      }
      channel = Channels.Next(channel);
    } 
}

bool cChannelGroup::Save(FILE *f)
{
    return fprintf(f, "%s\n", ToText()) > 0;
}

bool cChannelGroup::ChannelInGroup(cChannel* channel)
{
    cChannelGroupItem* channelInGroup = channels.First();
    while (channelInGroup) 
    {
      if (channel == channelInGroup->channel)
          return true;
      channelInGroup = channels.Next(channelInGroup);
    } 
    return false;
}

// -- cChannelGroups -----------------------------------------------------------------
int cChannelGroups::GetIndex(char* channelGroup)
{
    if (!channelGroup)
      return -1;
    cChannelGroup* ChannelGroup = First();
    int index = 0;
    while (ChannelGroup) 
    {
      if (strcmp(channelGroup, ChannelGroup->name) == 0)
          return index;
      index++;
      ChannelGroup = Next(ChannelGroup);
    } 
    return -1;
}

cChannelGroup* cChannelGroups::GetGroupByName(const char* channelGroup)
{
    if (!channelGroup)
      return NULL;
    cChannelGroup* ChannelGroup = First();
    while (ChannelGroup) 
    {
      if (strcmp(channelGroup, ChannelGroup->name) == 0)
          return ChannelGroup;
      ChannelGroup = Next(ChannelGroup);
    } 
    return NULL;
}

cSearchExt* cChannelGroups::Used(cChannelGroup* group)
{
    if (!group)
      return NULL;

    if (SearchExts.Count() == 0)
      SearchExts.Load(AddDirectory(CONFIGDIR, "epgsearch.conf"));

    cMutexLock SearchExtsLock(&SearchExts);
    cSearchExt *SearchExt = SearchExts.First();
    while (SearchExt) 
    {
      if (SearchExt->useChannel == 2 && strcmp(SearchExt->channelGroup, group->name) == 0)
          return SearchExt;
      SearchExt = SearchExts.Next(SearchExt);
    }
    return NULL;
}

char** cChannelGroups::CreateMenuitemsList()
{
    char** menuitemsChGr = new char*[ChannelGroups.Count()+1];
    cChannelGroup* ChannelGroup = First();
    menuitemsChGr[0] = strdup("");
    int index = 1;
    while (ChannelGroup) 
    {
      menuitemsChGr[index++] = ChannelGroup->name;
      ChannelGroup = Next(ChannelGroup);
    }
    return menuitemsChGr;
}

// -- cMenuChannelGroupItem -----------------------------------------------------------------
cMenuChannelGroupItem::cMenuChannelGroupItem(cChannelGroup* Group)
{
    group = Group;
    Set();
}

void cMenuChannelGroupItem::Set(void)
{
    char* channelbuffer = NULL;

    cChannelGroupItem* channelInGroup = group->channels.First(); 
    int channelNr, chIntBegin = -1, chIntEnd = -1, chLast = -1;
    while (channelInGroup) 
    {
      channelNr = channelInGroup->channel->Number();
      if (chIntBegin == -1)
          chIntBegin = channelNr;
      if (chIntEnd == -1)
          chIntEnd = channelNr;

      if (chLast == channelNr-1)
          chIntEnd = channelNr;
      else
      {
          chIntEnd = chLast;
          if(chIntBegin == chIntEnd)
            asprintf(&channelbuffer, "%s %d", channelbuffer?channelbuffer:"", chIntBegin);
          else if (chIntEnd != -1)
            asprintf(&channelbuffer, "%s %d-%d", channelbuffer?channelbuffer:"", chIntBegin, chIntEnd);
          chIntBegin = chIntEnd = channelNr;
      }

      chLast = channelNr;
      channelInGroup = group->channels.Next(channelInGroup);
      if (!channelInGroup)
      {
          if(chLast == chIntBegin)
            asprintf(&channelbuffer, "%s %d", channelbuffer?channelbuffer:"", chIntBegin);
          else
            asprintf(&channelbuffer, "%s %d-%d", channelbuffer?channelbuffer:"", chIntBegin, chLast);
      }
    }

    
    char* buffer = NULL;
    asprintf(&buffer, "%s\t%s", group->name, channelbuffer?channelbuffer:"");
    free(channelbuffer);
    SetText(buffer, false);
}

// --- cMenuChannelGroups ----------------------------------------------------------
cMenuChannelGroups::cMenuChannelGroups(char** GroupName)
:cOsdMenu(tr("Channel groups"),20)
{
    groupSel = -1;
    groupName = GroupName;
    if (groupName && *groupName)
      groupSel = ChannelGroups.GetIndex(*groupName); 

    cChannelGroup* ChannelGroup = ChannelGroups.First();
    int index = 0;
    while (ChannelGroup) 
    {
      Add(new cMenuChannelGroupItem(ChannelGroup), (index == groupSel?true:false));
      ChannelGroup = ChannelGroups.Next(ChannelGroup);
      index++;
    } 
    
    if (groupName && *groupName)
      SetHelp(tr("Button$Edit"), tr("Button$New"), tr("Button$Delete"), tr("Button$Select"));
    else
      SetHelp(tr("Button$Edit"), tr("Button$New"), tr("Button$Delete"), NULL);
    Sort();
    Display();
}

cChannelGroup *cMenuChannelGroups::CurrentGroup(void)
{
    cMenuChannelGroupItem *item = (cMenuChannelGroupItem *)Get(Current());
    return item ? item->group : NULL;
}

eOSState cMenuChannelGroups::New(void)
{
    if (HasSubMenu())
      return osContinue;
    return AddSubMenu(new cMenuEditChannelGroup(new cChannelGroup, true));
}

eOSState cMenuChannelGroups::Delete(void)
{
  cChannelGroup *curGroup = CurrentGroup();
  if (curGroup) {
      cSearchExt* search = ChannelGroups.Used(curGroup);
      if (search)
      {
        char* Message = NULL;
        asprintf(&Message, "%s %s", tr("Channel group used by: "), search->search);
        Skins.Message(mtInfo, Message);
        free(Message);
        return osContinue;
      }
      if (Interface->Confirm(tr("Edit$Delete group?"))) {
        ChannelGroups.Del(curGroup);
        ChannelGroups.Save();
        cOsdMenu::Del(Current());
        Display();
      }
  }
  return osContinue;
}

eOSState cMenuChannelGroups::ProcessKey(eKeys Key)
{
    int GroupNumber = HasSubMenu() ? Count() : -1;
    
    eOSState state = cOsdMenu::ProcessKey(Key);
    if (state == osUnknown) 
    {
      if (HasSubMenu())
          return osContinue;
      switch (Key) 
      {
          case kRed:
            if (CurrentGroup())
                state = AddSubMenu(new cMenuEditChannelGroup(CurrentGroup()));
            else
                state = osContinue;
            break;
          case kGreen: state = New(); break;
          case kYellow: state = Delete(); break;

          case kOk:
          case kBlue:
            if (groupName && *groupName)
            {
                free(*groupName);
                *groupName = strdup(CurrentGroup()->name);
                return osBack;
            }
          default: break;
      }
    }
    if (GroupNumber >= 0 && !HasSubMenu() && ChannelGroups.Get(GroupNumber)) 
    {
      // a newly created group was confirmed with Ok
      cChannelGroup* group = ChannelGroups.Get(GroupNumber);
      Add(new cMenuChannelGroupItem(group), true);
      Display();
    }
    
    return state;
}

// --- cMenuEditChannelGroup --------------------------------------------------------
cMenuEditChannelGroup::cMenuEditChannelGroup(cChannelGroup *Group, bool New)
:cOsdMenu(tr("Edit channel group"),30)
{
    group = Group;
    channelSel = group->CreateChannelSel();
    strcpy(name, group->name);
    addIfConfirmed = New;
    if (group) 
      Set();
}

cMenuEditChannelGroup::~cMenuEditChannelGroup()
{
    free(channelSel);
}

void cMenuEditChannelGroup::Set()
{
    int current = Current();
    Clear();

    Add(new cMenuEditStrItem( tr("Group name"), name, sizeof(group->name), tr(FileNameChars)));
    cChannel* channel = Channels.First();
    int index = 0;
    while (channel) 
    {
      if (channel->GroupSep())
      {
          channel = Channels.Next(channel);
          continue;
      }
      Add(new cMenuEditBoolItem( CHANNELNAME(channel), &channelSel[index++], tr("no"), tr("yes")));
      channel = Channels.Next(channel);
    } 
    
    SetCurrent(Get(current));

}

eOSState cMenuEditChannelGroup::ProcessKey(eKeys Key)
{
  eOSState state = cOsdMenu::ProcessKey(Key);

  const char* ItemText = Get(Current())->Text();
  if (strlen(ItemText) > 0 && strstr(ItemText, tr("Group name")) != ItemText)
      SetHelp(tr("Button$Invert selection"), tr("Button$All yes"), tr("Button$All no"), NULL);
  else if (!InEditMode(ItemText, tr("Group name"), name))
      SetHelp(NULL, NULL, NULL, NULL);

  if (state == osUnknown) {
      switch (Key) {
        case kOk:
            if (strlen(name) == 0)
            {
              Skins.Message(mtError, tr("Group name is empty!"));
              return osContinue;
            }
            if (addIfConfirmed && ChannelGroups.GetGroupByName(name))
            {
              Skins.Message(mtError, tr("Group name already exists!"));
              return osContinue;
            }
            
            {
              bool saveSearchExts = false;
              if (strcmp(group->name, name) != 0 && !addIfConfirmed) // if group name changed, update searches
              {
                  cMutexLock SearchExtsLock(&SearchExts);
                  cSearchExt *SearchExt = SearchExts.First();
                  while (SearchExt) {
                    if (SearchExt->useChannel == 2 && 
                        SearchExt->channelGroup && 
                        strcmp(SearchExt->channelGroup, group->name) == 0)
                    {
                        free(SearchExt->channelGroup);
                        SearchExt->channelGroup = strdup(name);
                    }
                    SearchExt = SearchExts.Next(SearchExt);
                  }
                  saveSearchExts = true; // save them after groups are saved!
              }

              strcpy(group->name, name);
              group->CreateChannelList(channelSel);
              if (addIfConfirmed)
                  ChannelGroups.Add(group);
              ChannelGroups.Save();
              if (saveSearchExts)
                  SearchExts.Save();
            }
            addIfConfirmed = false;
            return osBack;
            break;
        case kRed:
        case kGreen:          
        case kYellow:
        {
            cChannel* channel = Channels.First();
            int index = 0;
            while (channel) 
            {
              if (channel->GroupSep())
              {
                  channel = Channels.Next(channel);
                  continue;
              }

              channelSel[index] = (Key == kGreen?1:(Key == kRed?1-channelSel[index]:0));
              index++;
              channel = Channels.Next(channel);
            }     
            Set();
            Display();
            return osContinue;
        }

        default: break;
      }
  }
  return state;
}

Generated by  Doxygen 1.6.0   Back to index