diff options
Diffstat (limited to 'menuundelete.c')
-rw-r--r-- | menuundelete.c | 545 |
1 files changed, 545 insertions, 0 deletions
diff --git a/menuundelete.c b/menuundelete.c new file mode 100644 index 0000000..e059797 --- /dev/null +++ b/menuundelete.c @@ -0,0 +1,545 @@ +/* + * undelete: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: menuundelete.c 0.2 2004/10/10 12:23:20 hflor Exp $ + */ + +#include "menuundelete.h" +#if VDRVERSNUM < 10307 +#include "menuitemtext.h" +#endif +#include "undelete.h" +#include "i18n.h" +#include "vdrtools.h" +#include <vdr/interface.h> +#include <vdr/videodir.h> +#include <vdr/remote.h> +#include <vdr/recording.h> +#ifdef HAVE_ICONPATCH +#include <vdr/iconpatch.h> +#endif + +#ifndef RECEXT +#define RECEXT ".rec" +#define DELEXT ".del" +#endif + +// --- cMenuRecordingSelectItem -------------------------------------------------------- + +cMenuRecordingSelectItem::cMenuRecordingSelectItem(cRecording *Recording, int Level) +{ + filename = strdup(Recording->FileName()); + totalEntries = newEntries = 0; + start = Recording->start; + SetText(Recording->Title('\t', true, Level)); + if ((isdir = (*Text() == '\t'))) + name = strdup(Text() + 2); + else + name = strdup(Recording->Name()); + level = Level; +#ifdef UND_Debug2 + dsyslog("%s: cMenuRecordingSelectItem::cMenuRecordingSelectItem FileName=%s Level=%d Name=%s", plugin_name, filename, level, name); +#endif +} + +cMenuRecordingSelectItem::~cMenuRecordingSelectItem() +{ +#ifdef UND_Debug2 + dsyslog("%s: cMenuRecordingSelectItem::~cMenuRecordingSelectItem FileName=%s Name=%s", plugin_name, filename, name); +#endif + FREENULL(filename); + FREENULL(name); +} + +bool cMenuRecordingSelectItem::operator< (const cListObject &ListObject) +{ + cMenuRecordingSelectItem *temp = (cMenuRecordingSelectItem *)&ListObject; + if (isdir != temp->isdir) + return isdir; + if (isdir) + return strcasecmp(name, temp->name) < 0; + return start < temp->start; +} + +void cMenuRecordingSelectItem::IncrementCounter(bool New) +{ + totalEntries++; + if (New) + newEntries++; + char *buffer = NULL; + asprintf(&buffer, "%d\t%d\t%s", totalEntries, newEntries, name); + SetText(buffer, false); +#ifdef UND_Debug2 + dsyslog("%s: cMenuRecordingSelectItem::IncrementCounter FileName=%s New=%s Buffer=%s", plugin_name, filename, New ? "true" : "false", buffer); +#endif +} + +void cMenuRecordingSelectItem::RefreshCounter(void) +{ +#ifdef UND_Debug2 + dsyslog("%s: cMenuRecordingSelectItem::RefeshCounter FileName=%s", plugin_name, filename); +#endif + if (isdir) + { + char *dirname = DirName(); + if (dirname) + { + totalEntries = 0; + newEntries = 0; + for (cRecording *recording = DeletedRecordings.First(); recording; recording = DeletedRecordings.Next(recording)) + if (strncmp(recording->FileName(), dirname, strlen(dirname)) == 0) + IncrementCounter(recording->IsNew()); + free(dirname); + } + } +} + +char *cMenuRecordingSelectItem::DirName(void) +{ + if (isdir) + { + char *temp = strdup(filename); + char *last = temp + strlen(VideoDirectory) + 1; + for (int i = level; *last && i >= 0; i--) + { + last = strchr(last, '/'); + if (!last) + break; + last++; + } + if (last) + *last = 0; + return temp; + } else + return NULL; +} + +// --- cMenuRecordingSelect -------------------------------------------------------- + +cMenuRecordingSelect::cMenuRecordingSelect(const char *Base, int Level, bool OpenSubMenus) +:cOsdMenu(Base ? Base : tr("Deleted Recordings"), 6, 6, 6) +{ +#ifdef UND_Debug2 + dsyslog("%s: cMenuRecordingSelect::cMenuRecordingSelect Base=%s Level=%d OpenSubMenus=%s", plugin_name, Base, Level, OpenSubMenus ? "true" : "false"); +#endif +#if VDRVERSNUM < 10307 +#ifdef HAVE_ELCHI + Interface->Status(tr("Display$prepare recording display..."), Setup.Theme == themeVanilla ? clrBlack : (eDvbColor)fginfofont, Setup.Theme == themeVanilla ? clrCyan : clrInfoLine); +#else + Interface->Status(tr("Display$prepare recording display...")); +#endif + Interface->Flush(); +#else + STATUS(tr("Display$prepare recording display...")); +#endif + base = Base ? strdup(Base) : NULL; + level = Level; + Display(); + cMenuRecordingSelectItem *LastItem = NULL; + char *LastItemText = NULL; + for (cRecording *recording = DeletedRecordings.First(); recording; recording = DeletedRecordings.Next(recording)) + { + if (!Base || (strstr(recording->Name(), Base) == recording->Name() && recording->Name()[strlen(Base)] == '~')) + { + cMenuRecordingSelectItem *Item = new cMenuRecordingSelectItem(recording, level); + if (*Item->Text() && (!LastItem || strcmp(Item->Text(), LastItemText) != 0)) + { + Add(Item); + LastItem = Item; + FREENULL(LastItemText); + LastItemText = strdup(LastItem->Text()); + } else + delete Item; + if (LastItem) + { + if (LastItem->IsDirectory()) + LastItem->IncrementCounter(recording->IsNew()); + } + } + } + free(LastItemText); + LastItem = Current() < 0 ? NULL : (cMenuRecordingSelectItem *)Get(Current()); + Sort(); + if (LastItem) + { + SetCurrent(LastItem); + if (OpenSubMenus && Open(true) == osContinue) + return; + } else + SetCurrent(First()); + SetHelpKeys(); +} + +cMenuRecordingSelect::~cMenuRecordingSelect() +{ +#ifdef UND_Debug2 + dsyslog("%s: cMenuRecordingSelect::~cMenuRecordingSelect Base=%s Level=%d", plugin_name, base, level); +#endif + FREENULL(base); +} + +void cMenuRecordingSelect::SetHelpKeys(void) +{ +#ifdef UND_Debug2 + dsyslog("%s: cMenuRecordingSelect::SetHelpKeys", plugin_name); +#endif + + cMenuRecordingSelectItem *ri = (cMenuRecordingSelectItem *)Get(Current()); + if (ri) + { + if (ri->IsDirectory()) + SetHelp(tr("Open"), tr("Undelete"), tr("Delete"), NULL); + else + { + cRecording *recording = GetRecording(ri); + SetHelp(NULL, tr("Undelete"), tr("Delete"), (recording && recording->Summary() && *recording->Summary()) ? tr("Summary") : NULL); + } + } else + { + SetHelp(NULL); + } +} + +cRecording *cMenuRecordingSelect::GetRecording(cMenuRecordingSelectItem *Item) +{ + cRecording *recording = DeletedRecordings.GetByName(Item->FileName()); + if (!recording) + ERROR(tr("Error while accessing recording!")); + return recording; +} + +eOSState cMenuRecordingSelect::Open(bool OpenSubMenus) +{ + cMenuRecordingSelectItem *ri = (cMenuRecordingSelectItem *)Get(Current()); + if (ri) + { + if (ri->IsDirectory()) + { + const char *t = ri->Name(); + char *buffer = NULL; + if (base) + { + asprintf(&buffer, "%s~%s", base, t); + t = buffer; + } + AddSubMenu(new cMenuRecordingSelect(t, level + 1, OpenSubMenus)); + FREENULL(buffer); + return osContinue; + } + } + return osUnknown; +} + +eOSState cMenuRecordingSelect::UnDelete(void) +{ + if (HasSubMenu() || Count() == 0) + return osContinue; + if (WorkFilename) + { + esyslog("%s: Error previous jobs not completed (%s)", plugin_name, WorkFilename); + return osContinue; + } + cMenuRecordingSelectItem *ri = (cMenuRecordingSelectItem *)Get(Current()); + if (ri && ((!ri->IsDirectory() && (!confirmundel.u || Interface->Confirm(tr("Question$Undelete recording?")))) || (ri->IsDirectory() && (!confirmundeldir.u || Interface->Confirm(tr("Question$Undelete recordings in directory?")))))) + { + if (ri->IsDirectory()) + WorkFilename = ri->DirName(); // WorkFilename is NULL see up + else + WorkFilename = strdup(ri->FileName()); + cRemote::Put((eKeys)kUnDelRec); + cOsdMenu::Del(Current()); + Display(); + if (!Count()) + return osBack; + } + return osContinue; +} + +eOSState cMenuRecordingSelect::Delete(void) +{ + if (HasSubMenu() || Count() == 0) + return osContinue; + if (WorkFilename) + { + esyslog("%s: Error previous jobs not completed (%s)", plugin_name, WorkFilename); + return osContinue; + } + cMenuRecordingSelectItem *ri = (cMenuRecordingSelectItem *)Get(Current()); + if (ri && ((!ri->IsDirectory() && (!confirmdel.u || Interface->Confirm(tr("Question$Delete recording definitive?")))) || (ri->IsDirectory() && (!confirmdeldir.u || Interface->Confirm(tr("Question$Delete recordings in diretory definitive?")))))) + { + if (ri->IsDirectory()) + WorkFilename = ri->DirName(); // WorkFilename is NULL see up + else + WorkFilename = strdup(ri->FileName()); + cRemote::Put((eKeys)kDelRec); + cOsdMenu::Del(Current()); + Display(); + if (!Count()) + return osBack; + } + return osContinue; +} + +eOSState cMenuRecordingSelect::Summary(void) +{ + if (HasSubMenu() || Count() == 0) + return osContinue; + cMenuRecordingSelectItem *ri = (cMenuRecordingSelectItem *)Get(Current()); + if (ri && !ri->IsDirectory()) + { + cRecording *recording = GetRecording(ri); + if (recording && recording->Summary() && *recording->Summary()) +#if VDRVERSNUM >= 10307 + return AddSubMenu(new cMenuText(tr("Summary"), recording->Summary())); +#else + return AddSubMenu(new cMenuItemText(tr("Summary"), recording->Summary())); +#endif + } + return osContinue; +} + +eOSState cMenuRecordingSelect::ProcessKey(eKeys Key) +{ +#ifdef UND_Debug3 + bool noneKey = Key == kNone; + if (!noneKey) + dsyslog("%s: cMenuRecordingSelect::ProcessKey Key=%s", plugin_name, KeyName(Key)); +#endif + bool hSubMenu = HasSubMenu(); + + eOSState state = cOsdMenu::ProcessKey(Key); +#ifdef UND_Debug3 + if (!noneKey || (state != osUnknown && state != osContinue)) + { + dsyslog("%s: cMenuRecordingSelect::ProcessKey OSState=%s", plugin_name, OSStateName(state)); + noneKey = false; + } +#endif + + + if (hSubMenu && !HasSubMenu()) + { + if (Key == kYellow || Key == kGreen) + { + cOsdMenu::Del(Current()); + if (!Count()) + state = osBack; + } + if (state == osContinue) + { + for (cMenuRecordingSelectItem *ri = (cMenuRecordingSelectItem *)First(); ri; ri = (cMenuRecordingSelectItem *)Next(ri)) + ri->RefreshCounter(); + Display(); + } + } + + switch (state) + { + case osUnknown: switch (Key) + { + case kBack: state = osBack; + case kOk: + case kRed: state = Open(); + break; + case kGreen: state = UnDelete(); + break; + case kYellow: state = Delete(); + break; + case kBlue: state = Summary(); + break; + default: break; + } + break; + default: break; + } + if (!HasSubMenu() && Key != kNone && !WorkFilename) + { + SetHelpKeys(); + cMenuRecordingSelectItem *ri = (cMenuRecordingSelectItem *)Get(Current()); + if (ri) + { + ri->RefreshCounter(); + RefreshCurrent(); + } + } + +#ifdef UND_Debug3 + if (!noneKey || (state != osUnknown && state != osContinue)) + dsyslog("%s: cMenuRecordingSelect::ProcessKey returned OSState=%s", plugin_name, OSStateName(state)); +#endif + return state; +} + +// --- cMenuUndelete -------------------------------------------------------- + +cMenuUndelete::cMenuUndelete(void) +:cOsdMenu(tr("Deleted Recordings"), 6, 6) +{ +#ifdef UND_Debug2 + dsyslog("%s: cMenuUndelete::cMenuUndelete", plugin_name); +#endif +#if VDRVERSNUM < 10307 +#ifdef HAVE_ELCHI + Interface->Status(tr("Display$prepare recording display..."), Setup.Theme == themeVanilla ? clrBlack : (eDvbColor)fginfofont, Setup.Theme == themeVanilla ? clrCyan : clrInfoLine); +#else + Interface->Status(tr("Display$prepare recording display...")); +#endif + Interface->Flush(); +#else + STATUS(tr("Display$prepare recording display...")); +#endif +#if VDRVERSNUM >= 10311 + DeletedRecordings.Load(); +#else + DeletedRecordings.Load(true); +#endif + AddSubMenu(new cMenuRecordingSelect); + PurgeRecording = false; + SalvageRecording = false; +} + +cMenuUndelete::~cMenuUndelete() +{ +#ifdef UND_Debug2 + dsyslog("%s: cMenuUndelete::~cMenuUndelete", plugin_name); +#endif + if (PurgeRecording) + { +#if VDRVERSNUM < 10307 +#ifdef HAVE_ELCHI + Interface->Status(tr("Display$remove empty directories..."), Setup.Theme == themeVanilla ? clrBlack : (eDvbColor)fginfofont, Setup.Theme == themeVanilla ? clrCyan : clrInfoLine); +#else + Interface->Status(tr("Display$remove empty directories...")); +#endif + Interface->Flush(); +#else + STATUS(tr("Display$remove empty directories...")); +#endif + RemoveEmptyVideoDirectories(); + } + DeletedRecordings.Clear(); + +#if VDRVERSNUM >= 10311 + if (SalvageRecording) + Recordings.TriggerUpdate(); +#endif +} + +eOSState cMenuUndelete::ProcessKey(eKeys Key) +{ +#ifdef UND_Debug3 + bool noneKey = Key == kNone; + if (!noneKey) + dsyslog("%s: cMenuUndelete::ProcessKey Key=%s", plugin_name, KeyName(Key)); +#endif + + eOSState state = cOsdMenu::ProcessKey(Key); +#ifdef UND_Debug3 + if (!noneKey || (state != osUnknown && state != osContinue)) + { + dsyslog("%s: cMenuUndelete::ProcessKey OSState=%s", plugin_name, OSStateName(state)); + noneKey = false; + } +#endif + + if (state == osUnknown) + { + cRecording *recording = NULL; + bool processrecording = false; + if (WorkFilename && (Key == kDelRec || Key == kUnDelRec)) + { +#if VDRVERSNUM < 10307 +#ifdef HAVE_ELCHI + Interface->Status(tr("Display$please wait ..."), Setup.Theme == themeVanilla ? clrBlack : (eDvbColor)fginfofont, Setup.Theme == themeVanilla ? clrCyan : clrInfoLine); +#else + Interface->Status(tr("Display$please wait ...")); +#endif + Interface->Flush(); +#else + STATUS(tr("Display$please wait ...")); +#endif + } + switch (Key) + { + case kUnDelRec: state = osContinue; + if (WorkFilename) + { + for (recording = DeletedRecordings.First(); recording; recording = DeletedRecordings.Next(recording)) + if (strncmp(recording->FileName(), WorkFilename, strlen(WorkFilename)) == 0) + { + if (verbose.u) + isyslog("%s: undelete recording=%s", plugin_name, recording->FileName()); + char *NewName = strdup(recording->FileName()); + char *ext = strrchr(NewName, '.'); + if (strcmp(ext, DELEXT) == 0) + { + strncpy(ext, RECEXT, strlen(ext)); + if (access(NewName, F_OK) == 0) + { + ERROR(tr("Error$Recording with the same name exists!")); + if (verbose.u) + isyslog("%s: Recording with the same name exists!", plugin_name); + } else + { + if (!RenameVideoFile(recording->FileName(), NewName)) + esyslog("%s: Error while rename deleted recording (%s) to (%s)", plugin_name, recording->FileName(), NewName); + SalvageRecording = true; + } + } + free(NewName); + cRemote::Put((eKeys)kUnDelRec); + DeletedRecordings.Del(recording); + processrecording = true; + break; + } + } + break; + case kDelRec: state = osContinue; + if (WorkFilename) + { + for (recording = DeletedRecordings.First(); recording; recording = DeletedRecordings.Next(recording)) + if (strncmp(recording->FileName(), WorkFilename, strlen(WorkFilename)) == 0) + { + if (verbose.u) + isyslog("%s: purge deleted recording=%s", plugin_name, recording->FileName()); + if (!RemoveVideoFile(recording->FileName())) + esyslog("%s: Error while remove deleted recording (%s)", plugin_name, recording->FileName()); + PurgeRecording = true; + cRemote::Put((eKeys)kDelRec); + DeletedRecordings.Del(recording); + processrecording = true; + break; + } + } + break; + case kHelpKeys: if (!HasSubMenu()) + state = osBack; + default: break; + } + if (WorkFilename && !processrecording) + { + FREENULL(WorkFilename); // restore Helpkeys in cMenuRecordingSelect::ProcessKey +#if VDRVERSNUM < 10307 +#ifdef HAVE_ELCHI + Interface->Status(NULL, Setup.Theme == themeVanilla ? clrBlack : (eDvbColor)fginfofont, Setup.Theme == themeVanilla ? clrCyan : clrInfoLine); +#else + Interface->Status(NULL); +#endif + Interface->Flush(); +#else + STATUS(NULL); +#endif + cRemote::Put((eKeys)kHelpKeys); + } + } + if (!WorkFilename && !HasSubMenu()) + state = osBack; + +#ifdef UND_Debug3 + if (!noneKey || (state != osUnknown && state != osContinue)) + dsyslog("%s: cMenuUndelete::ProcessKey returned OSState=%s", plugin_name, OSStateName(state)); +#endif + return state; +} |