mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			150 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * entry.c: Data structure to handle still pictures
 | |
|  *
 | |
|  * See the README file for copyright information and how to reach the author.
 | |
|  *
 | |
|  * $Id: entry.c 1.3 2008/02/17 13:42:34 kls Exp $
 | |
|  */
 | |
| 
 | |
| #include "entry.h"
 | |
| 
 | |
| cPictureEntry::cPictureEntry(const char *Name, const cPictureEntry *Parent, bool IsDirectory)
 | |
| {
 | |
|   name = strdup(Name);
 | |
|   parent = Parent;
 | |
|   isDirectory = IsDirectory;
 | |
|   entries = NULL;
 | |
| }
 | |
| 
 | |
| cPictureEntry::~cPictureEntry()
 | |
| {
 | |
|   free(name);
 | |
|   delete entries;
 | |
| }
 | |
| 
 | |
| int cPictureEntry::Compare(const cListObject &ListObject) const
 | |
| {
 | |
|   cPictureEntry *p = (cPictureEntry *)&ListObject;
 | |
|   if (IsDirectory() && !p->IsDirectory())
 | |
|      return -1;
 | |
|   if (!IsDirectory() && p->IsDirectory())
 | |
|      return +1;
 | |
|   if (IsDirectory())
 | |
|      return strcoll(name, p->name);
 | |
|   else
 | |
|      return strcmp(name, p->name); // correctly sorts dsc01234.jpg and dsc01234a.jpg in case pictures have been "squeezed in"
 | |
| }
 | |
| 
 | |
| cString cPictureEntry::Path(void) const
 | |
| {
 | |
|   return parent ? *AddDirectory(parent->Path(), name) : name;
 | |
| }
 | |
| 
 | |
| void cPictureEntry::Load(void) const
 | |
| {
 | |
|   if (isDirectory && !entries) {
 | |
|      cString Directory = Path();
 | |
|      cReadDir d(Directory);
 | |
|      if (d.Ok()) {
 | |
|         struct dirent *e;
 | |
|         while ((e = d.Next()) != NULL) {
 | |
|               if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
 | |
|                  struct stat ds;
 | |
|                  if (stat(AddDirectory(Directory, e->d_name), &ds) == 0) {
 | |
|                     if (!entries)
 | |
|                        entries = new cList<cPictureEntry>;
 | |
|                     entries->Add(new cPictureEntry(e->d_name, this, S_ISDIR(ds.st_mode)));
 | |
|                     }
 | |
|                  }
 | |
|               }
 | |
|         if (entries)
 | |
|            entries->Sort();
 | |
|         }
 | |
|      else
 | |
|         LOG_ERROR_STR(*Directory);
 | |
|      }
 | |
| }
 | |
| 
 | |
| const cList<cPictureEntry> *cPictureEntry::Entries(void) const
 | |
| {
 | |
|   Load();
 | |
|   return entries;
 | |
| }
 | |
| 
 | |
| const cPictureEntry *cPictureEntry::FirstPicture(void) const
 | |
| {
 | |
|   Load();
 | |
|   if (entries) {
 | |
|      for (cPictureEntry *pe = entries->First(); pe; pe = entries->Next(pe)) {
 | |
|          if (pe->IsDirectory()) {
 | |
|             const cPictureEntry *p = pe->FirstPicture();
 | |
|             if (p)
 | |
|                return p;
 | |
|             }
 | |
|          else
 | |
|             return pe;
 | |
|          }
 | |
|      }
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| const cPictureEntry *cPictureEntry::LastPicture(void) const
 | |
| {
 | |
|   Load();
 | |
|   if (entries) {
 | |
|      for (cPictureEntry *pe = entries->Last(); pe; pe = entries->Prev(pe)) {
 | |
|          if (pe->IsDirectory()) {
 | |
|             const cPictureEntry *p = pe->LastPicture();
 | |
|             if (p)
 | |
|                return p;
 | |
|             }
 | |
|          else
 | |
|             return pe;
 | |
|          }
 | |
|      }
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| const cPictureEntry *cPictureEntry::PrevPicture(const cPictureEntry *This) const
 | |
| {
 | |
|   if (This) {
 | |
|      const cPictureEntry *pe = (cPictureEntry *)entries->Prev(This);
 | |
|      if (pe) {
 | |
|         if (pe->IsDirectory()) {
 | |
|            const cPictureEntry *p = pe->LastPicture();
 | |
|            if (p)
 | |
|               return p;
 | |
|            return PrevPicture(pe);
 | |
|            }
 | |
|         return pe;
 | |
|         }
 | |
|      }
 | |
|   if (parent)
 | |
|      return parent->PrevPicture(this);
 | |
|   return NULL;
 | |
| }
 | |
| 
 | |
| const cPictureEntry *cPictureEntry::NextPicture(const cPictureEntry *This) const
 | |
| {
 | |
|   if (This) {
 | |
|      cPictureEntry *pe = (cPictureEntry *)entries->Next(This);
 | |
|      if (pe) {
 | |
|         if (pe->IsDirectory()) {
 | |
|            const cPictureEntry *p = pe->FirstPicture();
 | |
|            if (p)
 | |
|               return p;
 | |
|            return NextPicture(pe);
 | |
|            }
 | |
|         return pe;
 | |
|         }
 | |
|      }
 | |
|   else if (IsDirectory()) {
 | |
|      const cPictureEntry *p = FirstPicture();
 | |
|      if (p)
 | |
|         return p;
 | |
|      }
 | |
|   if (parent)
 | |
|      return parent->NextPicture(this);
 | |
|   return NULL;
 | |
| }
 |