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

menu_dirselect.c

/*
 * menu_commands.c: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */

#include "menu_dirselect.h"
#include "epgsearchext.h"
#include "epgsearchcats.h"
#include "epgsearchtools.h"

set<string> cMenuDirSelect::directorySet;

cDirExts DirExts;

// --- cMenuDirItem ---------------------------------------------------------
class cMenuDirItem : public cOsdItem 
{
 private:
    char* directory;
 public:
    cMenuDirItem(const char* text) : cOsdItem(text) { directory = strdup(text);}
    ~cMenuDirItem(){ if (directory) free(directory);}
    virtual int Compare(const cListObject &ListObject) const;
};

int cMenuDirItem::Compare(const cListObject &ListObject) const
{
    const cMenuDirItem *p = (cMenuDirItem *)&ListObject;
    int hasVars1 = (strchr(directory,'%') != NULL?1:0);
    int hasVars2 = (strchr(p->directory,'%') != NULL?1:0);
    if (hasVars1 || hasVars2)
    {
      if (hasVars1 != hasVars2)
          return hasVars2-hasVars1;
      else
          return strcasecmp(directory, p->directory); 
    }
    else
      return strcasecmp(directory, p->directory);     
}


// --- cMenuDirSelect ---------------------------------------------------------

cMenuDirSelect::cMenuDirSelect(char* szDirectory)
    :cOsdMenu(tr("Select directory"))
{
    Directory = szDirectory;
    yellow=NULL;
    MaxLevel = 1;
    CurLevel = 1;
    Load();
}

cMenuDirSelect::~cMenuDirSelect()
{
    if (yellow) free(yellow);
}

int cMenuDirSelect::Level(const char* szDir)
{
    int iLevel = 1;
    if (strchr(szDir, '%')) // dirs with vars always have level 1
      return 1;
    do
    {
      char* pos = strchr(szDir, '~');
      if (pos)
      {
          iLevel++;
          szDir = pos+1;
      }
      else
          return iLevel;
    }
    while(true);
    return 1;
}

void cMenuDirSelect::AddDistinct(const char* szText)
{
    int iLevel = Level(szText);
    MaxLevel = max(MaxLevel, iLevel);

    if (iLevel > CurLevel) // only show Items of the specified level, except those with vars
      return;

    for(int i=0; i<Count(); i++)
    {    
      const char* ItemText = Get(i)->Text();
      char* itemtext = strdup(ItemText);
      char* sztext = strdup(szText);
      ToLower(itemtext);
      ToLower(sztext);
      if (itemtext && strlen(itemtext) > 0 && strcmp(sztext, itemtext) == 0)
      {
          free(itemtext);
          free(sztext);
          return;
      }
      free(itemtext);
      free(sztext);
    }
    Add(new cMenuDirItem(hk(szText)));
}

void cMenuDirSelect::CreateDirSet()
{
    directorySet.clear();

    // add distinct directories from current recordings
    if (Recordings.Count() == 0)
      Recordings.Load();
    for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) 
    {
      if (recording->HierarchyLevels() > 0)
      {
          char* dir = strdup(recording->Name());
          // strip the trailing rec dir
          char* pos = strrchr(dir, '~');
          if (pos)
          {
            *pos=0;         
            for(int iLevel = 0; iLevel < recording->HierarchyLevels(); iLevel++)            
            {               
                directorySet.insert(dir); 
                char* pos = strrchr(dir, '~');
                if (pos)
                  *pos=0;
            }
          }
          free(dir);
      }
    }
    // add distinct directories from current timers
    for (cTimer *timer = Timers.First(); timer; timer = Timers.Next(timer)) 
    {
      char* dir = strdup(timer->File());
      // strip the trailing name dir
      char* pos = strrchr(dir, '~');
      if (pos)
      {
          *pos=0;     
          do
          {
            directorySet.insert(dir);     
            char* pos = strrchr(dir, '~');
            if (pos)
                *pos=0;
            else break;
          }
          while(true);
      }
      free(dir);
    }
    cMutexLock SearchExtsLock(&SearchExts);
    cSearchExt *searchExt = SearchExts.First();
    // add distinct directories from existing search timers
    while (searchExt) 
    {
      if (strlen(searchExt->directory) > 0)
          directorySet.insert(searchExt->directory);
      searchExt = SearchExts.Next(searchExt);
    }
    // add distinct directories from epgsearchdirs.conf
    DirExts.Load(AddDirectory(CONFIGDIR, "epgsearchdirs.conf"), true);
    cDirExt* DirExt = DirExts.First();
    while (DirExt) 
    {
      directorySet.insert(DirExt->Name());      
      DirExt = DirExts.Next(DirExt);
    }
}


void cMenuDirSelect::Load()
{
    int current = Current();
    char* oldSelection = NULL; // save old selection for reselection
    if (current>-1)
      oldSelection = strdup(Get(current)->Text());
    Clear();

    CreateDirSet();
    std::set<string>::iterator it;
    for (it = directorySet.begin(); it != directorySet.end(); it++) 
      AddDistinct((*it).c_str());

    Sort();
    for(int i=0; i<Count(); i++)
    {
      const char* text = Get(i)->Text();
      if (oldSelection && strchr(text, '%') == NULL && strstr(text, oldSelection) == text) // skip entries with variables
      {
          SetCurrent(Get(i));
          break;
      }
    }
    if (oldSelection) free(oldSelection);

    if (yellow)
    {
      free(yellow);
      yellow = NULL;
    }
    asprintf(&yellow, "%s %d", tr("Button$Level"), (CurLevel==MaxLevel?1:CurLevel+1));
    SetHelp(NULL, NULL, MaxLevel==1?NULL:yellow, tr("Button$Select"));
    Display();
}

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

  if (state == osUnknown) {
     switch (Key) {
       case kBlue|k_Repeat:
       case kYellow:
           if (++CurLevel>MaxLevel)
             CurLevel=1;
           Load();
           return osContinue;
       case kGreen:
       case kRed:
           return osContinue;
       case kBlue:
       case kOk:  
           if (Count() > 0)
             strn0cpy(Directory,Get(Current())->Text(), MaxFileName);
           return osBack;
       default:   break;
       }
     }
  return state;
}


Generated by  Doxygen 1.6.0   Back to index