diff -Nru vdr-1.6.0-vanilla/HISTORY-liemikuutio vdr-1.6.0-liemikuutio/HISTORY-liemikuutio --- vdr-1.6.0-vanilla/HISTORY-liemikuutio 1970-01-01 02:00:00.000000000 +0200 +++ vdr-1.6.0-liemikuutio/HISTORY-liemikuutio 2008-04-04 00:24:43.000000000 +0300 @@ -0,0 +1,103 @@ +----------------------------------- +Liemikuutio for Video Disc Recorder + +Maintainer: Rolf Ahrenberg +----------------------------------- + +2006-01-08: Version 1.0 + +- Based on enAIO with these original patches: + Simple recordings sorting by Walter@VDRPortal + Alternate rename recordings by Ralf Müller + Menu selection by Peter Dittmann + Recording length by Tobias Faust + +2006-01-15: Version 1.1 + +- Removed patches already found in vdr-1.3.39. + +2006-01-25: Version 1.2 + +- Added "Main menu command position" feature. + +2006-02-05: Version 1.3 + +- Improved menu selection response. + +2006-04-18: Version 1.4 + +- Added Estonian translation (Thanks to Arthur Konovalov). + +2006-04-30: Version 1.5 + +- Added progress bar view into "What's on now?" menu. + +2006-06-06: Version 1.6 + +- Added French translation (Thanks to ECLiPSE). + +2006-06-14: Version 1.7 + +- Fixed RENR crash. + +2006-07-14: Version 1.8 + +- Fixed RENR/OSD bug. + +2006-08-27: Version 1.9 + +- Some modifications to the recording length and rename recordings + patches (Thanks to Firefly). +- Added k1_k3_jumps_20s patch by Petri Hintukainen. + +2006-08-29: Version 1.10 + +- The cRecording:Title() method now defaults to original formatting. + +2006-09-04: Version 1.11 + +- Removed unused variable from cRecording::Title() method (Thanks to + C.Y.M.). +- Some modifications to the rename recordings patch (Thanks to Firefly). + +2006-09-13: Version 1.12 + +- More modifications to the rename recordings patch (Thanks to Firefly). + +2006-10-01: Version 1.13 + +- Removed unnecessary syslog printing (Thanks to Firefly). + +2007-08-14: Version 1.14 + +- Updated for vdr-1.5.7. + +2007-10-16: Version 1.15 + +- Added recmenu play patch (Thanks to Ville Skyttä). +- Updated French translation (Thanks to ECLiPSE). + +2007-11-04: Version 1.16 + +- Updated for vdr-1.5.11. + +2007-12-08: Version 1.17 + +- Added binary skip patch. +- Removed k1_k3_jumps_20s patch. + +2008-02-17: Version 1.18 + +- Updated for vdr-1.5.15. + +2008-03-02: Version 1.19 + +- Modified binary skip to use kPrev and kNext keys and the skip is now + always shortened after a direction change (Thanks to Timo Eskola). +- Readded k1_k3_jumps_20s patch. + +2008-04-04: Version 1.20 + +- Added bitrate information into rename menu. +- Readded the path editing support of rename recordings patch (Thanks + to Firefly). diff -Nru vdr-1.6.0-vanilla/config.c vdr-1.6.0-liemikuutio/config.c --- vdr-1.6.0-vanilla/config.c 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/config.c 2008-03-27 21:47:57.000000000 +0200 @@ -289,6 +289,11 @@ InitialChannel = 0; InitialVolume = -1; EmergencyExit = 1; + ShowRecDate = 1; + ShowRecTime = 1; + ShowRecLength = 0; + ShowProgressBar = 0; + MenuCmdPosition = 0; } cSetup& cSetup::operator= (const cSetup &s) @@ -462,6 +467,11 @@ else if (!strcasecmp(Name, "InitialChannel")) InitialChannel = atoi(Value); else if (!strcasecmp(Name, "InitialVolume")) InitialVolume = atoi(Value); else if (!strcasecmp(Name, "EmergencyExit")) EmergencyExit = atoi(Value); + else if (!strcasecmp(Name, "ShowRecDate")) ShowRecDate = atoi(Value); + else if (!strcasecmp(Name, "ShowRecTime")) ShowRecTime = atoi(Value); + else if (!strcasecmp(Name, "ShowRecLength")) ShowRecLength = atoi(Value); + else if (!strcasecmp(Name, "ShowProgressBar")) ShowProgressBar = atoi(Value); + else if (!strcasecmp(Name, "MenuCmdPosition")) MenuCmdPosition = atoi(Value); else return false; return true; @@ -545,6 +555,11 @@ Store("InitialChannel", InitialChannel); Store("InitialVolume", InitialVolume); Store("EmergencyExit", EmergencyExit); + Store("ShowRecDate", ShowRecDate); + Store("ShowRecTime", ShowRecTime); + Store("ShowRecLength", ShowRecLength); + Store("ShowProgressBar", ShowProgressBar); + Store("MenuCmdPosition", MenuCmdPosition); Sort(); diff -Nru vdr-1.6.0-vanilla/config.h vdr-1.6.0-liemikuutio/config.h --- vdr-1.6.0-vanilla/config.h 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/config.h 2008-04-03 23:26:41.000000000 +0300 @@ -36,6 +36,8 @@ // plugins to work with newer versions of the core VDR as long as no // VDR header files have changed. +#define LIEMIKUUTIO 120 + #define MAXPRIORITY 99 #define MAXLIFETIME 99 @@ -267,6 +269,7 @@ int InitialChannel; int InitialVolume; int EmergencyExit; + int ShowRecDate, ShowRecTime, ShowRecLength, ShowProgressBar, MenuCmdPosition; int __EndData__; cSetup(void); cSetup& operator= (const cSetup &s); diff -Nru vdr-1.6.0-vanilla/menu.c vdr-1.6.0-liemikuutio/menu.c --- vdr-1.6.0-vanilla/menu.c 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/menu.c 2008-04-04 00:23:09.000000000 +0300 @@ -13,6 +13,7 @@ #include #include #include +#include #include "channels.h" #include "config.h" #include "cutter.h" @@ -705,7 +706,22 @@ Add(new cMenuEditBitItem( tr("VPS"), &data.flags, tfVps)); Add(new cMenuEditIntItem( tr("Priority"), &data.priority, 0, MAXPRIORITY)); Add(new cMenuEditIntItem( tr("Lifetime"), &data.lifetime, 0, MAXLIFETIME)); - Add(new cMenuEditStrItem( tr("File"), data.file, sizeof(data.file))); + + char* p = strrchr(data.file, '~'); + if (p) { + p++; + Utf8Strn0Cpy(name, p, sizeof(name)); + Utf8Strn0Cpy(path, data.file, sizeof(path)); + p = strrchr(path, '~'); + if (p) + p[0] = 0; + } + else { + Utf8Strn0Cpy(name, data.file, sizeof(name)); + Utf8Strn0Cpy(path, "", sizeof(path)); + } + Add(new cMenuEditStrItem( tr("File"), name, sizeof(name), tr(FileNameChars))); + Add(new cMenuEditRecPathItem(tr("Path"), path, sizeof(path))); SetFirstDayItem(); } Timers.IncBeingEdited(); @@ -745,6 +761,10 @@ Skins.Message(mtError, tr("*** Invalid Channel ***")); break; } + if(strlen(path)) + snprintf(data.file, sizeof(data.file), "%s~%s", path, name); + else + snprintf(data.file, sizeof(data.file), "%s", name); if (!*data.file) strcpy(data.file, data.Channel()->ShortName(true)); if (timer) { @@ -1048,7 +1068,8 @@ const cChannel *channel; bool withDate; int timerMatch; - cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL, bool WithDate = false); + bool withBar; + cMenuScheduleItem(const cEvent *Event, cChannel *Channel = NULL, bool WithDate = false, bool WithBar = false); static void SetSortMode(eScheduleSortMode SortMode) { sortMode = SortMode; } static void IncSortMode(void) { sortMode = eScheduleSortMode((sortMode == ssmAllAll) ? ssmAllThis : sortMode + 1); } static eScheduleSortMode SortMode(void) { return sortMode; } @@ -1058,12 +1079,13 @@ cMenuScheduleItem::eScheduleSortMode cMenuScheduleItem::sortMode = ssmAllThis; -cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel, bool WithDate) +cMenuScheduleItem::cMenuScheduleItem(const cEvent *Event, cChannel *Channel, bool WithDate, bool WithBar) { event = Event; channel = Channel; withDate = WithDate; timerMatch = tmNone; + withBar = WithBar; Update(true); } @@ -1080,6 +1102,17 @@ static const char *TimerMatchChars = " tT"; +static const char * const ProgressBar[7] = +{ + "[ ]", + "[| ]", + "[|| ]", + "[||| ]", + "[|||| ]", + "[||||| ]", + "[||||||]" +}; + bool cMenuScheduleItem::Update(bool Force) { bool result = false; @@ -1095,7 +1128,14 @@ if (channel && withDate) buffer = cString::sprintf("%d\t%.*s\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); else if (channel) - buffer = cString::sprintf("%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); + if (Setup.ShowProgressBar && withBar) { + int progress = (int)roundf( (float)(time(NULL) - event->StartTime()) / (float)(event->Duration()) * 6.0 ); + if (progress < 0) progress = 0; + else if (progress > 6) progress = 6; + buffer = cString::sprintf("%d\t%.*s\t%s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), ProgressBar[progress], t, v, r, event->Title()); + } + else + buffer = cString::sprintf("%d\t%.*s\t%s\t%c%c%c\t%s", channel->Number(), Utf8SymChars(csn, 6), csn, *event->GetTimeString(), t, v, r, event->Title()); else buffer = cString::sprintf("%.*s\t%s\t%c%c%c\t%s", Utf8SymChars(eds, 6), *eds, *event->GetTimeString(), t, v, r, event->Title()); SetText(buffer); @@ -1129,7 +1169,7 @@ const cEvent *cMenuWhatsOn::scheduleEvent = NULL; cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now, int CurrentChannelNr) -:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6, 4) +:cOsdMenu(Now ? tr("What's on now?") : tr("What's on next?"), CHNUMWIDTH, 7, 6, 4, 4) { now = Now; helpKeys = -1; @@ -1141,7 +1181,7 @@ if (Schedule) { const cEvent *Event = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent(); if (Event) - Add(new cMenuScheduleItem(Event, Channel), Channel->Number() == CurrentChannelNr); + Add(new cMenuScheduleItem(Event, Channel, false, Now), Channel->Number() == CurrentChannelNr); } } } @@ -1883,7 +1923,7 @@ fileName = strdup(Recording->FileName()); name = NULL; totalEntries = newEntries = 0; - SetText(Recording->Title('\t', true, Level)); + SetText(Recording->Title('\t', true, Level, false)); if (*Text() == '\t') name = strdup(Text() + 2); // 'Text() + 2' to skip the two '\t' } @@ -1899,13 +1939,155 @@ totalEntries++; if (New) newEntries++; - SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name)); + switch (Setup.ShowRecTime + Setup.ShowRecDate + Setup.ShowRecLength) { + case 0: + SetText(cString::sprintf("%s", name)); + break; + case 1: + SetText(cString::sprintf("%d\t%s", totalEntries, name)); + break; + case 2: + default: + SetText(cString::sprintf("%d\t%d\t%s", totalEntries, newEntries, name)); + break; + case 3: + SetText(cString::sprintf("%d\t%d\t\t%s", totalEntries, newEntries, name)); + break; + } +} + +// --- cMenuRenameRecording -------------------------------------------------- + +class cMenuRenameRecording : public cOsdMenu { +private: + int lifetime; + int priority; + char name[MaxFileName]; + char path[MaxFileName]; + cOsdItem *marksItem, *resumeItem; + bool isResume, isMarks; + cRecording *recording; +public: + cMenuRenameRecording(cRecording *Recording); + virtual eOSState ProcessKey(eKeys Key); +}; + +cMenuRenameRecording::cMenuRenameRecording(cRecording *Recording) +:cOsdMenu(tr("Rename recording"), 12) +{ + cMarks marks; + + recording = Recording; + priority = recording->priority; + lifetime = recording->lifetime; + + char* p = strrchr(recording->Name(), '~'); + if (p) { + p++; + Utf8Strn0Cpy(name, p, sizeof(name)); + Utf8Strn0Cpy(path, recording->Name(), sizeof(path)); + p = strrchr(path, '~'); + if (p) + p[0] = 0; + } + else { + Utf8Strn0Cpy(name, recording->Name(), sizeof(name)); + Utf8Strn0Cpy(path, "", sizeof(path)); + } + Add(new cMenuEditStrItem(tr("Name"), name, sizeof(name), tr(FileNameChars))); + Add(new cMenuEditRecPathItem(tr("Path"), path, sizeof(path) )); + Add(new cMenuEditIntItem(tr("Priority"), &priority, 0, MAXPRIORITY )); + Add(new cMenuEditIntItem(tr("Lifetime"), &lifetime, 0, MAXLIFETIME )); + + Add(new cOsdItem("", osUnknown, false)); + + Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Date"), *DayDateTime(recording->start)), osUnknown, false)); + + cChannel *channel = Channels.GetByChannelID(((cRecordingInfo *)recording->Info())->ChannelID()); + if (channel) + Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Channel"), *ChannelString(channel, 0)), osUnknown, false)); + + cIndexFile *index = new cIndexFile(recording->FileName(), false); + int recLen = 0; + if (index) { + recLen = index->Last() / FRAMESPERSEC; + Add(new cOsdItem(cString::sprintf("%s:\t%s", tr("Length"), *IndexToHMSF(index->Last())), osUnknown, false)); + delete index; + } + + int dirSize = DirSizeMB(recording->FileName()); + cString bitRate = recLen ? cString::sprintf(" (%.2f MBit/s)", 8.0 * dirSize / recLen) : cString(""); + Add(new cOsdItem((dirSize > 9999) ? cString::sprintf("%s:\t%.2f GB%s", tr("Size"), dirSize / 1024.0, *bitRate) : cString::sprintf("%s:\t%d MB%s", tr("Size"), dirSize, *bitRate), osUnknown, false)); + + Add(new cOsdItem("", osUnknown, false)); + + isMarks = marks.Load(recording->FileName()) && marks.Count(); + marksItem = new cOsdItem(tr("Delete marks information?"), osUser1, isMarks); + Add(marksItem); + + cResumeFile ResumeFile(recording->FileName()); + isResume = (ResumeFile.Read() != -1); + resumeItem = new cOsdItem(tr("Delete resume information?"), osUser2, isResume); + Add(resumeItem); +} + +eOSState cMenuRenameRecording::ProcessKey(eKeys Key) +{ + eOSState state = cOsdMenu::ProcessKey(Key); + + if (state == osUnknown) { + if (Key == kOk) { + char buffer[MaxFileName]; + if (Utf8StrLen(path)) + snprintf(buffer, sizeof(buffer), "%s~%s", path, name); + else + snprintf(buffer, sizeof(buffer), "%s", name); + if (recording->Rename(buffer, &priority, &lifetime)) { + Recordings.ChangeState(); + Recordings.TouchUpdate(); + return osRecordings; + } + else + Skins.Message(mtError, tr("Error while accessing recording!")); + } + return osContinue; + } + else if (state == osUser1) { + if (isMarks && Interface->Confirm(tr("Delete marks information?"))) { + cMarks marks; + marks.Load(recording->FileName()); + cMark *mark = marks.First(); + while (mark) { + cMark *nextmark = marks.Next(mark); + marks.Del(mark); + mark = nextmark; + } + marks.Save(); + isMarks = false; + marksItem->SetSelectable(isMarks); + SetCurrent(First()); + Display(); + } + return osContinue; + } + else if (state == osUser2) { + if (isResume && Interface->Confirm(tr("Delete resume information?"))) { + cResumeFile ResumeFile(recording->FileName()); + ResumeFile.Delete(); + isResume = false; + resumeItem->SetSelectable(isResume); + SetCurrent(First()); + Display(); + } + return osContinue; + } + return state; } // --- cMenuRecordings ------------------------------------------------------- cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus) -:cOsdMenu(Base ? Base : tr("Recordings"), 9, 7) +:cOsdMenu(Base ? Base : tr("Recordings"), 9, 7, 7) { base = Base ? strdup(Base) : NULL; level = Setup.RecordingDirs ? Level : -1; @@ -2136,6 +2318,19 @@ return osContinue; } +eOSState cMenuRecordings::Rename(void) +{ + if (HasSubMenu() || Count() == 0) + return osContinue; + cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); + if (ri && !ri->IsDirectory()) { + cRecording *recording = GetRecording(ri); + if (recording) + return AddSubMenu(new cMenuRenameRecording(recording)); + } + return osContinue; +} + eOSState cMenuRecordings::ProcessKey(eKeys Key) { bool HadSubMenu = HasSubMenu(); @@ -2150,7 +2345,12 @@ case kYellow: return Delete(); case kInfo: case kBlue: return Info(); - case k1...k9: return Commands(Key); + case k0: DirOrderState = !DirOrderState; + Set(true); + return osContinue; + case k8: return Rename(); + case k9: + case k1...k7: return Commands(Key); case kNone: if (Recordings.StateChanged(recordingsState)) Set(true); break; @@ -2276,6 +2476,7 @@ Add(new cMenuEditBoolItem(tr("Setup.OSD$Scroll wraps"), &data.MenuScrollWrap)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Menu key closes"), &data.MenuKeyCloses)); Add(new cMenuEditBoolItem(tr("Setup.OSD$Recording directories"), &data.RecordingDirs)); + Add(new cMenuEditBoolItem(tr("Setup.OSD$Main menu command position"), &data.MenuCmdPosition, tr("bottom"), tr("top"))); SetCurrent(Get(current)); Display(); } @@ -2380,6 +2581,7 @@ Add(new cMenuEditIntItem( tr("Setup.EPG$EPG scan timeout (h)"), &data.EPGScanTimeout)); Add(new cMenuEditIntItem( tr("Setup.EPG$EPG bugfix level"), &data.EPGBugfixLevel, 0, MAXEPGBUGFIXLEVEL)); Add(new cMenuEditIntItem( tr("Setup.EPG$EPG linger time (min)"), &data.EPGLinger, 0)); + Add(new cMenuEditBoolItem(tr("Setup.EPG$Show progress bar"), &data.ShowProgressBar)); Add(new cMenuEditBoolItem(tr("Setup.EPG$Set system time"), &data.SetSystemTime)); if (data.SetSystemTime) Add(new cMenuEditTranItem(tr("Setup.EPG$Use time from transponder"), &data.TimeTransponder, &data.TimeSource)); @@ -2758,6 +2960,9 @@ Add(new cMenuEditIntItem( tr("Setup.Recording$Instant rec. time (min)"), &data.InstantRecordTime, 1, MAXINSTANTRECTIME)); Add(new cMenuEditIntItem( tr("Setup.Recording$Max. video file size (MB)"), &data.MaxVideoFileSize, MINVIDEOFILESIZE, MAXVIDEOFILESIZE)); Add(new cMenuEditBoolItem(tr("Setup.Recording$Split edited files"), &data.SplitEditedFiles)); + Add(new cMenuEditBoolItem(tr("Setup.Recording$Show date"), &data.ShowRecDate)); + Add(new cMenuEditBoolItem(tr("Setup.Recording$Show time"), &data.ShowRecTime)); + Add(new cMenuEditBoolItem(tr("Setup.Recording$Show length"), &data.ShowRecLength)); } // --- cMenuSetupReplay ------------------------------------------------------ @@ -3045,6 +3250,7 @@ // Replay control: if (replaying && !stopReplayItem) // TRANSLATORS: note the leading blank! + if (Setup.MenuCmdPosition) Ins(stopReplayItem = new cOsdItem(tr(" Stop replaying"), osStopReplay)); else Add(stopReplayItem = new cOsdItem(tr(" Stop replaying"), osStopReplay)); else if (stopReplayItem && !replaying) { Del(stopReplayItem->Index()); @@ -3059,6 +3265,7 @@ bool CutterActive = cCutter::Active(); if (CutterActive && !cancelEditingItem) { // TRANSLATORS: note the leading blank! + if (Setup.MenuCmdPosition) Ins(cancelEditingItem = new cOsdItem(tr(" Cancel editing"), osCancelEdit)); else Add(cancelEditingItem = new cOsdItem(tr(" Cancel editing"), osCancelEdit)); result = true; } @@ -3079,6 +3286,7 @@ while ((s = cRecordControls::GetInstantId(s)) != NULL) { cOsdItem *item = new cOsdItem(osStopRecord); item->SetText(cString::sprintf("%s%s", tr(STOP_RECORDING), s)); + if (Setup.MenuCmdPosition) Ins(item); else Add(item); if (!stopRecordingItem) stopRecordingItem = item; @@ -4059,6 +4267,10 @@ // --- cReplayControl -------------------------------------------------------- +#define REPLAYCONTROLSKIPLIMIT 9 // s +#define REPLAYCONTROLSKIPSECONDS 90 // s +#define REPLAYCONTROLSKIPTIMEOUT 5000 // ms + cReplayControl *cReplayControl::currentReplayControl = NULL; char *cReplayControl::fileName = NULL; char *cReplayControl::title = NULL; @@ -4072,6 +4284,9 @@ lastCurrent = lastTotal = -1; lastPlay = lastForward = false; lastSpeed = -2; // an invalid value + lastSkipKey = kNone; + lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; + lastSkipTimeout.Set(0); timeoutShow = 0; timeSearchActive = false; marks.Load(fileName); @@ -4435,6 +4650,32 @@ case kGreen: SkipSeconds(-60); break; case kYellow|k_Repeat: case kYellow: SkipSeconds( 60); break; + case k1|k_Repeat: + case k1: SkipSeconds(-20); break; + case k3|k_Repeat: + case k3: SkipSeconds( 20); break; + case kPrev|k_Repeat: + case kPrev: if (lastSkipTimeout.TimedOut()) { + lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; + lastSkipKey = kPrev; + } + else if (RAWKEY(lastSkipKey) != kPrev && lastSkipSeconds > (2 * REPLAYCONTROLSKIPLIMIT)) { + lastSkipSeconds /= 2; + lastSkipKey = kNone; + } + lastSkipTimeout.Set(REPLAYCONTROLSKIPTIMEOUT); + SkipSeconds(-lastSkipSeconds); break; + case kNext|k_Repeat: + case kNext: if (lastSkipTimeout.TimedOut()) { + lastSkipSeconds = REPLAYCONTROLSKIPSECONDS; + lastSkipKey = kNext; + } + else if (RAWKEY(lastSkipKey) != kNext && lastSkipSeconds > (2 * REPLAYCONTROLSKIPLIMIT)) { + lastSkipSeconds /= 2; + lastSkipKey = kNone; + } + lastSkipTimeout.Set(REPLAYCONTROLSKIPTIMEOUT); + SkipSeconds(lastSkipSeconds); break; case kStop: case kBlue: Hide(); Stop(); @@ -4444,12 +4685,8 @@ switch (Key) { // Editing: case kMarkToggle: MarkToggle(); break; - case kPrev|k_Repeat: - case kPrev: case kMarkJumpBack|k_Repeat: case kMarkJumpBack: MarkJump(false); break; - case kNext|k_Repeat: - case kNext: case kMarkJumpForward|k_Repeat: case kMarkJumpForward: MarkJump(true); break; case kMarkMoveBack|k_Repeat: diff -Nru vdr-1.6.0-vanilla/menu.h vdr-1.6.0-liemikuutio/menu.h --- vdr-1.6.0-vanilla/menu.h 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/menu.h 2008-04-03 23:24:39.000000000 +0300 @@ -35,6 +35,8 @@ private: cTimer *timer; cTimer data; + char name[MaxFileName]; + char path[MaxFileName]; int channel; bool addIfConfirmed; cMenuEditDateItem *firstday; @@ -163,6 +165,7 @@ eOSState Delete(void); eOSState Info(void); eOSState Commands(eKeys Key = kNone); + eOSState Rename(void); protected: cRecording *GetRecording(cMenuRecordingItem *Item); public: @@ -217,6 +220,9 @@ int lastCurrent, lastTotal; bool lastPlay, lastForward; int lastSpeed; + int lastSkipSeconds; + eKeys lastSkipKey; + cTimeMs lastSkipTimeout; time_t timeoutShow; bool timeSearchActive, timeSearchHide; int timeSearchTime, timeSearchPos; diff -Nru vdr-1.6.0-vanilla/menuitems.c vdr-1.6.0-liemikuutio/menuitems.c --- vdr-1.6.0-vanilla/menuitems.c 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/menuitems.c 2008-04-03 23:26:32.000000000 +0300 @@ -619,6 +619,168 @@ return osContinue; } +// --- cMenuEditRecPathItem -------------------------------------------------- + +cMenuEditRecPathItem::cMenuEditRecPathItem(const char* Name, char* Path, + int Length): cMenuEditStrItem(Name, Path, Length, tr(FileNameChars)) +{ + SetBase(Path); +} + +cMenuEditRecPathItem::~cMenuEditRecPathItem() +{ +} + +void cMenuEditRecPathItem::SetBase(const char* Path) +{ + if (!Path) + base[0] = 0; + Utf8Strn0Cpy(base, Path, sizeof(base)); + char* p = strrchr(base, '~'); + if (p) + p[0] = 0; + else + base[0] = 0; +} + +void cMenuEditRecPathItem::FindNextLevel() +{ + char item[MaxFileName]; + + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) + { + char* p; + Utf8Strn0Cpy(item, recording->Name(), sizeof(item)); + stripspace(value); + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + if (!lengthUtf8) + p = strchr(item, '~'); + else { + if (strstr(item, value) != item) + continue; + if (item[lengthUtf8] != '~') + continue; + p = strchr(item + lengthUtf8 + 1, '~'); + } + if (!p) + continue; + p[0] = 0; + Utf8Strn0Cpy(base, value, length); + Utf8Strn0Cpy(value, item, length); + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + return; + } +} + +void cMenuEditRecPathItem::Find(bool Next) +{ + char item[MaxFileName]; + char lastItem[MaxFileName] = ""; + + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) + { + const char* recName = recording->Name(); + if (Utf8StrLen(base) && strstr(recName, base) != recName) + continue; + if (Utf8StrLen(base) && recName[Utf8StrLen(base)] != '~') + continue; + Utf8Strn0Cpy(item, recName, sizeof(item)); + char* p = strchr(item + Utf8StrLen(base) + 1, '~'); + if (!p) + continue; + p[0] = 0; + if (!Next && (strcmp(item, value) == 0)) { + if (strlen(lastItem)) + Utf8Strn0Cpy(value, lastItem, length); + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + return; + } + if (strcmp(lastItem, item) != 0) { + if(Next && Utf8StrLen(lastItem) && strcmp(lastItem, value) == 0) { + Utf8Strn0Cpy(value, item, length); + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + return; + } + Utf8Strn0Cpy(lastItem, item, sizeof(lastItem)); + } + } +} + +void cMenuEditRecPathItem::SetHelpKeys(void) +{ + cSkinDisplay::Current()->SetButtons(tr("Rename$Up"), tr("Rename$Down"), tr("Rename$Previous"), tr("Rename$Next")); +} + +eOSState cMenuEditRecPathItem::ProcessKey(eKeys Key) +{ + switch (Key) { + case kLeft: + case kRed: // one level up + if (!InEditMode()) + return cMenuEditItem::ProcessKey(Key); + Utf8Strn0Cpy(value, base, lengthUtf8); + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + SetBase(base); + pos = Utf8StrLen(base); + if (pos) + pos++; + if (!lengthUtf8) { + Utf8Strn0Cpy(value, " ", length); + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + } + break; + case kRight: + case kGreen: // one level down + if (InEditMode()) + FindNextLevel(); + else + EnterEditMode(); + if (!lengthUtf8) { + Utf8Strn0Cpy(value, " ", length); + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + } + pos = Utf8StrLen(base); + if (pos) + pos++; + SetHelpKeys(); + break; + case kUp|k_Repeat: + case kUp: + case kYellow|k_Repeat: + case kYellow: // previous directory in list + if (!InEditMode()) + return cMenuEditItem::ProcessKey(Key); + Find(false); + pos = Utf8StrLen(base); + if (pos) + pos++; + break; + case kDown|k_Repeat: + case kDown: + case kBlue|k_Repeat: + case kBlue: // next directory in list + if (!InEditMode()) + return cMenuEditItem::ProcessKey(Key); + Find(true); + pos = Utf8StrLen(base); + if (pos) + pos++; + break; + case kOk: // done + if (!InEditMode()) + return cMenuEditItem::ProcessKey(Key); + stripspace(value); + lengthUtf8 = Utf8ToArray(value, valueUtf8, length); + cSkinDisplay::Current()->SetButtons(NULL); + LeaveEditMode(Key == kOk); + break; + default: + return cMenuEditItem::ProcessKey(Key); + } + Set(); + return osContinue; +} + // --- cMenuEditStraItem ----------------------------------------------------- cMenuEditStraItem::cMenuEditStraItem(const char *Name, int *Value, int NumStrings, const char * const *Strings) diff -Nru vdr-1.6.0-vanilla/menuitems.h vdr-1.6.0-liemikuutio/menuitems.h --- vdr-1.6.0-vanilla/menuitems.h 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/menuitems.h 2008-04-03 23:24:39.000000000 +0300 @@ -78,26 +78,27 @@ class cMenuEditStrItem : public cMenuEditItem { private: - char *value; - int length; - const char *allowed; - int pos, offset; + int offset; bool insert, newchar, uppercase; - int lengthUtf8; - uint *valueUtf8; uint *allowedUtf8; uint *charMapUtf8; uint *currentCharUtf8; eKeys lastKey; cTimeMs autoAdvanceTimeout; - void SetHelpKeys(void); uint *IsAllowed(uint c); void AdvancePos(void); - virtual void Set(void); uint Inc(uint c, bool Up); void Insert(void); void Delete(void); protected: + char *value; + int length; + uint *valueUtf8; + int lengthUtf8; + const char *allowed; + int pos; + void SetHelpKeys(void); + virtual void Set(void); void EnterEditMode(void); void LeaveEditMode(bool SaveValue = false); bool InEditMode(void) { return valueUtf8 != NULL; } @@ -107,6 +108,19 @@ virtual eOSState ProcessKey(eKeys Key); }; +class cMenuEditRecPathItem : public cMenuEditStrItem { +protected: + char base[MaxFileName]; + virtual void SetHelpKeys(void); + void SetBase(const char* Path); + void FindNextLevel(); + void Find(bool Next); +public: + cMenuEditRecPathItem(const char* Name, char* Path, int Length); + ~cMenuEditRecPathItem(); + virtual eOSState ProcessKey(eKeys Key); + }; + class cMenuEditStraItem : public cMenuEditIntItem { private: const char * const *strings; diff -Nru vdr-1.6.0-vanilla/osdbase.c vdr-1.6.0-liemikuutio/osdbase.c --- vdr-1.6.0-vanilla/osdbase.c 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/osdbase.c 2008-03-27 21:47:56.000000000 +0200 @@ -77,6 +77,7 @@ { isMenu = true; digit = 0; + key_nr = -1; hasHotkeys = false; title = NULL; SetTitle(Title); @@ -119,7 +120,7 @@ digit = -1; // prevents automatic hotkeys - input already has them if (digit >= 0) { digit++; - buffer = cString::sprintf(" %c %s", (digit < 10) ? '0' + digit : ' ' , s); + buffer = cString::sprintf(" %2d%s %s", digit, (digit > 9) ? "" : " ", s); s = buffer; } } @@ -448,20 +449,62 @@ } } +#define MENUKEY_TIMEOUT 1500 + eOSState cOsdMenu::HotKey(eKeys Key) { - for (cOsdItem *item = First(); item; item = Next(item)) { + bool match = false; + bool highlight = false; + int item_nr; + int i; + + if (Key == kNone) { + if (lastActivity.TimedOut()) + Key = kOk; + else + return osContinue; + } + else { + lastActivity.Set(MENUKEY_TIMEOUT); + } + for (cOsdItem *item = Last(); item; item = Prev(item)) { const char *s = item->Text(); - if (s && (s = skipspace(s)) != NULL) { - if (*s == Key - k1 + '1') { + i = 0; + item_nr = 0; + if (s && (s = skipspace(s)) != '\0' && '0' <= s[i] && s[i] <= '9') { + do { + item_nr = item_nr * 10 + (s[i] - '0'); + } + while ( !((s[++i] == '\t')||(s[i] == ' ')) && (s[i] != '\0') && ('0' <= s[i]) && (s[i] <= '9')); + if ((Key == kOk) && (item_nr == key_nr)) { current = item->Index(); RefreshCurrent(); Display(); cRemote::Put(kOk, true); + key_nr = -1; break; } + else if (Key != kOk) { + if (!highlight && (item_nr == (Key - k0))) { + highlight = true; + current = item->Index(); + } + if (!match && (key_nr == -1) && ((item_nr / 10) == (Key - k0))) { + match = true; + key_nr = (Key - k0); + } + else if (((key_nr == -1) && (item_nr == (Key - k0))) || (!match && (key_nr >= 0) && (item_nr == (10 * key_nr + Key - k0)))) { + current = item->Index(); + cRemote::Put(kOk, true); + key_nr = -1; + break; + } + } } } + if ((!match) && (Key != kNone)) { + key_nr = -1; + } return osContinue; } @@ -500,8 +543,8 @@ } } switch (Key) { - case k0: return osUnknown; - case k1...k9: return hasHotkeys ? HotKey(Key) : osUnknown; + case kNone: + case k0...k9: return hasHotkeys ? HotKey(Key) : osUnknown; case kUp|k_Repeat: case kUp: CursorUp(); break; case kDown|k_Repeat: diff -Nru vdr-1.6.0-vanilla/osdbase.h vdr-1.6.0-liemikuutio/osdbase.h --- vdr-1.6.0-vanilla/osdbase.h 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/osdbase.h 2008-03-27 21:47:56.000000000 +0200 @@ -95,6 +95,8 @@ char *status; int digit; bool hasHotkeys; + int key_nr; + cTimeMs lastActivity; protected: void SetDisplayMenu(void); cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; } diff -Nru vdr-1.6.0-vanilla/po/de_DE.po vdr-1.6.0-liemikuutio/po/de_DE.po --- vdr-1.6.0-vanilla/po/de_DE.po 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/po/de_DE.po 2008-04-03 23:31:27.000000000 +0300 @@ -998,3 +998,51 @@ #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR wird in %s Minuten ausschalten" + +msgid "Rename recording" +msgstr "Aufzeichnung umbenennen" + +msgid "Date" +msgstr "Datum" + +msgid "Length" +msgstr "Länge" + +msgid "Size" +msgstr "Größe" + +msgid "Path" +msgstr "Pfad" + +msgid "Rename$Up" +msgstr "Höher" + +msgid "Rename$Down" +msgstr "Tiefer" + +msgid "Rename$Previous" +msgstr "Vorheriger" + +msgid "Rename$Next" +msgstr "Nächster" + +msgid "Delete marks information?" +msgstr "Marks löschen?" + +msgid "Delete resume information?" +msgstr "Resume löschen?" + +msgid "Setup.OSD$Main menu command position" +msgstr "Befehle Position im Hauptmenü" + +msgid "Setup.EPG$Show progress bar" +msgstr "Zeitbalken anzeigen" + +msgid "Setup.Recording$Show date" +msgstr "Aufnahmedatum anzeigen" + +msgid "Setup.Recording$Show time" +msgstr "AufnahmeZeit anzeigen" + +msgid "Setup.Recording$Show length" +msgstr "Länge der Aufnahme anzeigen" diff -Nru vdr-1.6.0-vanilla/po/et_EE.po vdr-1.6.0-liemikuutio/po/et_EE.po --- vdr-1.6.0-vanilla/po/et_EE.po 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/po/et_EE.po 2008-04-03 23:38:43.000000000 +0300 @@ -998,3 +998,51 @@ #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR lülitub välja %s minuti pärast" + +msgid "Rename recording" +msgstr "Ümbernimetamine" + +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Path" +msgstr "" + +msgid "Rename$Up" +msgstr "Üles" + +msgid "Rename$Down" +msgstr "Alla" + +msgid "Rename$Previous" +msgstr "Eelmine" + +msgid "Rename$Next" +msgstr "Järgmine" + +msgid "Delete marks information?" +msgstr "" + +msgid "Delete resume information?" +msgstr "" + +msgid "Setup.OSD$Main menu command position" +msgstr "Käsu asukoht peamenüüs" + +msgid "Setup.EPG$Show progress bar" +msgstr "Edenemisriba" + +msgid "Setup.Recording$Show date" +msgstr "Salvestuse kuupäev" + +msgid "Setup.Recording$Show time" +msgstr "Salvestuse kellaaeg" + +msgid "Setup.Recording$Show length" +msgstr "Salvestuse pikkus" diff -Nru vdr-1.6.0-vanilla/po/fi_FI.po vdr-1.6.0-liemikuutio/po/fi_FI.po --- vdr-1.6.0-vanilla/po/fi_FI.po 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/po/fi_FI.po 2008-04-03 23:34:26.000000000 +0300 @@ -1001,3 +1001,51 @@ #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR sammuu %s minuutin kuluttua" + +msgid "Rename recording" +msgstr "Nimeä tallenne" + +msgid "Date" +msgstr "Päiväys" + +msgid "Length" +msgstr "Pituus" + +msgid "Size" +msgstr "Koko" + +msgid "Path" +msgstr "Polku" + +msgid "Rename$Up" +msgstr "Ylemmäs" + +msgid "Rename$Down" +msgstr "Alemmas" + +msgid "Rename$Previous" +msgstr "Edellinen" + +msgid "Rename$Next" +msgstr "Seuraava" + +msgid "Delete marks information?" +msgstr "Poista tallenteen merkinnät?" + +msgid "Delete resume information?" +msgstr "Poista tallenteen paluutiedot?" + +msgid "Setup.OSD$Main menu command position" +msgstr "Komentojen sijainti päävalikossa" + +msgid "Setup.EPG$Show progress bar" +msgstr "Näytä aikajana" + +msgid "Setup.Recording$Show date" +msgstr "Näytä tallenteen päiväys" + +msgid "Setup.Recording$Show time" +msgstr "Näytä tallenteen ajankohta" + +msgid "Setup.Recording$Show length" +msgstr "Näytä tallenteen kesto" diff -Nru vdr-1.6.0-vanilla/po/fr_FR.po vdr-1.6.0-liemikuutio/po/fr_FR.po --- vdr-1.6.0-vanilla/po/fr_FR.po 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/po/fr_FR.po 2008-04-03 23:36:49.000000000 +0300 @@ -1004,3 +1004,51 @@ #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR s'arrêtera dans %s minutes" + +msgid "Rename recording" +msgstr "Renommer l'enregistrement" + +msgid "Date" +msgstr "Date" + +msgid "Length" +msgstr "Longueur" + +msgid "Size" +msgstr "Taille" + +msgid "Path" +msgstr "" + +msgid "Rename$Up" +msgstr "Haut" + +msgid "Rename$Down" +msgstr "Bas" + +msgid "Rename$Previous" +msgstr "Précédent" + +msgid "Rename$Next" +msgstr "Suivant" + +msgid "Delete marks information?" +msgstr "Effacer les informations de marquage" + +msgid "Delete resume information?" +msgstr "Effacer les informations de reprise" + +msgid "Setup.OSD$Main menu command position" +msgstr "Position des commandes dans le menu" + +msgid "Setup.EPG$Show progress bar" +msgstr "Montrer la barre de progression" + +msgid "Setup.Recording$Show date" +msgstr "Montrer la date d'enregistrement" + +msgid "Setup.Recording$Show time" +msgstr "Montrer l'heure d'enregistrement" + +msgid "Setup.Recording$Show length" +msgstr "Montrer la longueur de l'enregistrement" diff -Nru vdr-1.6.0-vanilla/po/ru_RU.po vdr-1.6.0-liemikuutio/po/ru_RU.po --- vdr-1.6.0-vanilla/po/ru_RU.po 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/po/ru_RU.po 2008-03-27 21:47:57.000000000 +0200 @@ -999,3 +999,36 @@ #, c-format msgid "VDR will shut down in %s minutes" msgstr "VDR ÒëÚÛîçØâáï çÕàÕ× %s ÜØÝãâ" + +msgid "Rename recording" +msgstr "¿ÕàÕØÜÕÝÞÒÐâì ×ÐßØáì" + +msgid "Date" +msgstr "" + +msgid "Length" +msgstr "" + +msgid "Size" +msgstr "" + +msgid "Delete marks information?" +msgstr "" + +msgid "Delete resume information?" +msgstr "" + +msgid "Setup.OSD$Main menu command position" +msgstr "ÀÐ×ÜÕéÕÝØÕ ÚÞÜÐÝÔ Ò ÓÛÐÒÝÞÜ ÜÕÝî" + +msgid "Setup.EPG$Show progress bar" +msgstr "" + +msgid "Setup.Recording$Show date" +msgstr "¿ÞÚÐ×ëÒÐâì ÔÐâã" + +msgid "Setup.Recording$Show time" +msgstr "¿ÞÚÐ×ëÒÐâì ÒàÕÜï ×ÐßØáØ" + +msgid "Setup.Recording$Show length" +msgstr "¿ÞÚÐ×ëÒÐâì ßàÞÔÞÛÖØâÕÛìÝÞáâì ×ÐßØáØ" diff -Nru vdr-1.6.0-vanilla/recording.c vdr-1.6.0-liemikuutio/recording.c --- vdr-1.6.0-vanilla/recording.c 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/recording.c 2008-03-27 21:47:56.000000000 +0200 @@ -46,6 +46,7 @@ #endif #define INFOFILESUFFIX "/info.vdr" #define MARKSFILESUFFIX "/marks.vdr" +#define INDEXFILESUFFIX "/index.vdr" #define MINDISKSPACE 1024 // MB @@ -62,6 +63,7 @@ #define MAX_LINK_LEVEL 6 bool VfatFileSystem = false; +bool DirOrderState = false; cRecordings DeletedRecordings(true); @@ -690,6 +692,8 @@ int cRecording::Compare(const cListObject &ListObject) const { cRecording *r = (cRecording *)&ListObject; + if (DirOrderState) + return strcasecmp(FileName(), r->FileName()); return strcasecmp(SortName(), r->SortName()); } @@ -705,7 +709,7 @@ return fileName; } -const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level) const +const char *cRecording::Title(char Delimiter, bool NewIndicator, int Level, bool Original) const { char New = NewIndicator && IsNew() ? '*' : ' '; free(titleBuffer); @@ -718,6 +722,7 @@ s++; else s = name; + if (Original) { titleBuffer = strdup(cString::sprintf("%02d.%02d.%02d%c%02d:%02d%c%c%s", t->tm_mday, t->tm_mon + 1, @@ -728,6 +733,39 @@ New, Delimiter, s)); + } + else { + cString RecLength("---"); + if (Setup.ShowRecLength && FileName()) { + cString filename = cString::sprintf("%s%s", FileName(), INDEXFILESUFFIX); + if (*filename) { + if (access(filename, R_OK) == 0) { + struct stat buf; + if (stat(filename, &buf) == 0) { + struct tIndex { int offset; uchar type; uchar number; short reserved; }; + int delta = buf.st_size % sizeof(tIndex); + if (delta) { + delta = sizeof(tIndex) - delta; + esyslog("ERROR: invalid file size (%ld) in '%s'", buf.st_size, *filename); + } + RecLength = cString::sprintf("%ld'", (buf.st_size + delta) / sizeof(tIndex) / SecondsToFrames(60)); + } + } + } + } + cString RecDate = cString::sprintf("%02d.%02d.%02d", t->tm_mday, t->tm_mon + 1, t->tm_year % 100); + cString RecTime = cString::sprintf("%02d:%02d", t->tm_hour, t->tm_min); + cString RecDelimiter = cString::sprintf("%c", Delimiter); + titleBuffer = strdup(cString::sprintf("%s%s%s%c%s%s%s%s", + (Setup.ShowRecDate ? *RecDate : ""), + (Setup.ShowRecDate && Setup.ShowRecTime ? *RecDelimiter : ""), + (Setup.ShowRecTime ? *RecTime : ""), + New, + (Setup.ShowRecTime || Setup.ShowRecDate ? *RecDelimiter : ""), + (Setup.ShowRecLength ? *RecLength : ""), + (Setup.ShowRecLength ? *RecDelimiter : ""), + s)); + } // let's not display a trailing '~': if (!NewIndicator) stripspace(titleBuffer); @@ -864,6 +902,41 @@ resume = RESUME_NOT_INITIALIZED; } +bool cRecording::Rename(const char *newName, int *newPriority, int *newLifetime) +{ + bool result = false; + struct tm tm_r; + struct tm *t = localtime_r(&start, &tm_r); + char *localNewName = ExchangeChars(strdup(newName), true); + char *newFileName = strdup(cString::sprintf(NAMEFORMAT, VideoDirectory, localNewName, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, *newPriority, *newLifetime)); + free(localNewName); + if (strcmp(FileName(), newFileName)) { + if (access(newFileName, F_OK) == 0) { + isyslog("recording %s already exists", newFileName); + } + else { + isyslog("renaming recording %s to %s", FileName(), newFileName); + result = MakeDirs(newFileName, true); + if (result) + result = RenameVideoFile(FileName(), newFileName); + if (result) { + priority = *newPriority; + lifetime = *newLifetime; + free(fileName); + fileName = strdup(newFileName); + free(name); + name = strdup(newName); + free(sortBuffer); + sortBuffer = NULL; + free(titleBuffer); + titleBuffer = NULL; + } + } + } + free(newFileName); + return result; +} + // --- cRecordings ----------------------------------------------------------- cRecordings Recordings; @@ -1172,8 +1245,6 @@ //XXX+ somewhere else??? // --- cIndexFile ------------------------------------------------------------ -#define INDEXFILESUFFIX "/index.vdr" - // The number of frames to stay off the end in case of time shift: #define INDEXSAFETYLIMIT 150 // frames diff -Nru vdr-1.6.0-vanilla/recording.h vdr-1.6.0-liemikuutio/recording.h --- vdr-1.6.0-vanilla/recording.h 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/recording.h 2008-03-27 21:47:57.000000000 +0200 @@ -19,6 +19,7 @@ #include "tools.h" extern bool VfatFileSystem; +extern bool DirOrderState; void RemoveDeletedRecordings(void); void AssertFreeDiskSpace(int Priority = 0, bool Force = false); @@ -88,7 +89,7 @@ virtual int Compare(const cListObject &ListObject) const; const char *Name(void) const { return name; } const char *FileName(void) const; - const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1) const; + const char *Title(char Delimiter = ' ', bool NewIndicator = false, int Level = -1, bool Original = true) const; const cRecordingInfo *Info(void) const { return info; } const char *PrefixFileName(char Prefix); int HierarchyLevels(void) const; @@ -106,6 +107,9 @@ // Changes the file name so that it will be visible in the "Recordings" menu again and // not processed by cRemoveDeletedRecordingsThread. // Returns false in case of error + bool Rename(const char *newName, int *newPriority, int *newLifetime); + // Changes the file name + // Returns false in case of error }; class cRecordings : public cList, public cThread { diff -Nru vdr-1.6.0-vanilla/svdrp.c vdr-1.6.0-liemikuutio/svdrp.c --- vdr-1.6.0-vanilla/svdrp.c 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/svdrp.c 2008-03-27 21:47:56.000000000 +0200 @@ -296,6 +296,8 @@ "REMO [ on | off ]\n" " Turns the remote control on or off. Without a parameter, the current\n" " status of the remote control is reported.", + "RENR \n" + " Rename recording. Number must be the Number as returned by LSTR command.", "SCAN\n" " Forces an EPG scan. If this is a single DVB device system, the scan\n" " will be done on the primary device unless it is currently recording.", @@ -1472,6 +1474,38 @@ Reply(250, "EPG scan triggered"); } +void cSVDRP::CmdRENR(const char *Option) +{ + bool recordings = Recordings.Update(true); + if (recordings) { + if (*Option) { + char *tail; + int n = strtol(Option, &tail, 10); + cRecording *recording = Recordings.Get(n - 1); + if (recording && tail && tail != Option) { + int priority = recording->priority; + int lifetime = recording->lifetime; + char *oldName = strdup(recording->Name()); + tail = skipspace(tail); + if (recording->Rename(tail, &priority, &lifetime)) { + Reply(250, "Renamed \"%s\" to \"%s\"", oldName, recording->Name()); + Recordings.ChangeState(); + Recordings.TouchUpdate(); + } + else + Reply(501, "Renaming \"%s\" to \"%s\" failed", oldName, tail); + free(oldName); + } + else + Reply(501, "Recording not found or wrong syntax"); + } + else + Reply(501, "Missing Input settings"); + } + else + Reply(550, "No recordings available"); +} + void cSVDRP::CmdSTAT(const char *Option) { if (*Option) { @@ -1587,6 +1621,7 @@ else if (CMD("PLUG")) CmdPLUG(s); else if (CMD("PUTE")) CmdPUTE(s); else if (CMD("REMO")) CmdREMO(s); + else if (CMD("RENR")) CmdRENR(s); else if (CMD("SCAN")) CmdSCAN(s); else if (CMD("STAT")) CmdSTAT(s); else if (CMD("UPDT")) CmdUPDT(s); diff -Nru vdr-1.6.0-vanilla/svdrp.h vdr-1.6.0-liemikuutio/svdrp.h --- vdr-1.6.0-vanilla/svdrp.h 2008-03-27 21:43:25.000000000 +0200 +++ vdr-1.6.0-liemikuutio/svdrp.h 2008-03-27 21:47:56.000000000 +0200 @@ -79,6 +79,7 @@ void CmdPLUG(const char *Option); void CmdPUTE(const char *Option); void CmdREMO(const char *Option); + void CmdRENR(const char *Option); void CmdSCAN(const char *Option); void CmdSTAT(const char *Option); void CmdUPDT(const char *Option);