vdr  1.7.27
entry.c
Go to the documentation of this file.
00001 /*
00002  * entry.c: Data structure to handle still pictures
00003  *
00004  * See the README file for copyright information and how to reach the author.
00005  *
00006  * $Id: entry.c 2.1 2012/02/17 14:00:28 kls Exp $
00007  */
00008 
00009 #include "entry.h"
00010 
00011 cPictureEntry::cPictureEntry(const char *Name, const cPictureEntry *Parent, bool IsDirectory)
00012 {
00013   name = strdup(Name);
00014   parent = Parent;
00015   isDirectory = IsDirectory;
00016   entries = NULL;
00017 }
00018 
00019 cPictureEntry::~cPictureEntry()
00020 {
00021   free(name);
00022   delete entries;
00023 }
00024 
00025 int cPictureEntry::Compare(const cListObject &ListObject) const
00026 {
00027   cPictureEntry *p = (cPictureEntry *)&ListObject;
00028   if (IsDirectory() && !p->IsDirectory())
00029      return -1;
00030   if (!IsDirectory() && p->IsDirectory())
00031      return +1;
00032   if (IsDirectory())
00033      return strcoll(name, p->name);
00034   else
00035      return strcmp(name, p->name); // correctly sorts dsc01234.jpg and dsc01234a.jpg in case pictures have been "squeezed in"
00036 }
00037 
00038 cString cPictureEntry::Path(void) const
00039 {
00040   return parent ? *AddDirectory(parent->Path(), name) : name;
00041 }
00042 
00043 void cPictureEntry::Load(void) const
00044 {
00045   if (isDirectory && !entries) {
00046      cString Directory = Path();
00047      cReadDir d(Directory);
00048      if (d.Ok()) {
00049         struct dirent *e;
00050         while ((e = d.Next()) != NULL) {
00051               struct stat ds;
00052               if (stat(AddDirectory(Directory, e->d_name), &ds) == 0) {
00053                  if (!entries)
00054                     entries = new cList<cPictureEntry>;
00055                  entries->Add(new cPictureEntry(e->d_name, this, S_ISDIR(ds.st_mode)));
00056                  }
00057               }
00058         if (entries)
00059            entries->Sort();
00060         }
00061      else
00062         LOG_ERROR_STR(*Directory);
00063      }
00064 }
00065 
00066 const cList<cPictureEntry> *cPictureEntry::Entries(void) const
00067 {
00068   Load();
00069   return entries;
00070 }
00071 
00072 const cPictureEntry *cPictureEntry::FirstPicture(void) const
00073 {
00074   Load();
00075   if (entries) {
00076      for (cPictureEntry *pe = entries->First(); pe; pe = entries->Next(pe)) {
00077          if (pe->IsDirectory()) {
00078             const cPictureEntry *p = pe->FirstPicture();
00079             if (p)
00080                return p;
00081             }
00082          else
00083             return pe;
00084          }
00085      }
00086   return NULL;
00087 }
00088 
00089 const cPictureEntry *cPictureEntry::LastPicture(void) const
00090 {
00091   Load();
00092   if (entries) {
00093      for (cPictureEntry *pe = entries->Last(); pe; pe = entries->Prev(pe)) {
00094          if (pe->IsDirectory()) {
00095             const cPictureEntry *p = pe->LastPicture();
00096             if (p)
00097                return p;
00098             }
00099          else
00100             return pe;
00101          }
00102      }
00103   return NULL;
00104 }
00105 
00106 const cPictureEntry *cPictureEntry::PrevPicture(const cPictureEntry *This) const
00107 {
00108   if (This) {
00109      const cPictureEntry *pe = (cPictureEntry *)entries->Prev(This);
00110      if (pe) {
00111         if (pe->IsDirectory()) {
00112            const cPictureEntry *p = pe->LastPicture();
00113            if (p)
00114               return p;
00115            return PrevPicture(pe);
00116            }
00117         return pe;
00118         }
00119      }
00120   if (parent)
00121      return parent->PrevPicture(this);
00122   return NULL;
00123 }
00124 
00125 const cPictureEntry *cPictureEntry::NextPicture(const cPictureEntry *This) const
00126 {
00127   if (This) {
00128      cPictureEntry *pe = (cPictureEntry *)entries->Next(This);
00129      if (pe) {
00130         if (pe->IsDirectory()) {
00131            const cPictureEntry *p = pe->FirstPicture();
00132            if (p)
00133               return p;
00134            return NextPicture(pe);
00135            }
00136         return pe;
00137         }
00138      }
00139   else if (IsDirectory()) {
00140      const cPictureEntry *p = FirstPicture();
00141      if (p)
00142         return p;
00143      }
00144   if (parent)
00145      return parent->NextPicture(this);
00146   return NULL;
00147 }