vdr
1.7.27
|
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 }