Implemented sort mode for recordings

This commit is contained in:
Klaus Schmidinger 2012-06-09 14:32:29 +02:00
parent 0b6c96a515
commit 440c119b0a
6 changed files with 121 additions and 18 deletions

View File

@ -7148,7 +7148,7 @@ Video Disk Recorder Revision History
caching the information whether a recording is stored on the video directory file
system within the cRecording data (based on a patch from Torsten Lang).
2012-06-08: Version 1.7.29
2012-06-09: Version 1.7.29
- Added a missing template specification to the c'tor of cSortedTimers (thanks to Udo
Richter).
@ -7170,3 +7170,8 @@ Video Disk Recorder Revision History
- Removed the gap from the main menu buttons in the LCARS skin.
- Fixed some copy&paste errors in PLUGINS.html (thanks to Winfried Köhler).
- The LCARS skin's main menu now only displays timers that are actually activated.
- Within the "Recordings" menu, pressing the '0' key now toggles sorting between
"by time" and "by name". The selected sort mode is stored separately for each
folder (provided you have write access to that folder).
If a folder is newly created by a repeating timer, the sort mode for that
folder is initially set to "by time".

12
MANUAL
View File

@ -24,7 +24,7 @@ Version 1.6
Green - Audio New New Ins/Ovr Rewind Skip -60s -
Yellow - Pause live Delete Delete Delete Delete Skip +60s -
Blue - Stop/Resume Mark Info - Info Stop -
0..9 Ch select - Sort(2) Day(3) Numeric inp. Exec cmd(1) Editing -
0..9 Ch select - Sort(2) Day(3) Numeric inp. Sort/Exec cmd(1) Editing -
In a numerical input field (like the response to a CAM enquiry) the keys 0..9
are used to enter the data, and the Left key can be used to delete the last
@ -81,7 +81,7 @@ Version 1.6
Yellow Info
Blue Timers menu
(1) See "Processing Recordings" below.
(1) See "Sort Recordings" and "Processing Recordings" below.
(2) In the "Channels" menu the '0' key switches the sort mode through "by number",
"by name" and "by provider". Other numeric input positions the cursor to
the channel with the number entered so far. If there is no channel with that
@ -301,6 +301,14 @@ Version 1.6
A previously stopped playback session can be resumed by pressing the "Blue"
key in the "VDR" menu.
* Sort Recordings
Within the "Recordings" menu, pressing the '0' key toggles sorting between
"by time" and "by name". The selected sort mode is stored separately for each
folder (provided you have write access to that folder).
If a folder is newly created by a repeating timer, the sort mode for that
folder is initially set to "by time".
* Processing Recordings
The configuration file 'reccmds.conf' can be used to define system commands

38
menu.c
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.c 2.54 2012/05/12 13:08:23 kls Exp $
* $Id: menu.c 2.55 2012/06/09 14:27:02 kls Exp $
*/
#include "menu.h"
@ -2247,6 +2247,7 @@ void cMenuRecordings::Set(bool Refresh)
}
}
Clear();
GetRecordingsSortMode(DirectoryName());
Recordings.Sort();
for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == FOLDERDELIMCHAR)) {
@ -2272,6 +2273,17 @@ void cMenuRecordings::Set(bool Refresh)
Display();
}
cString cMenuRecordings::DirectoryName(void)
{
cString d(VideoDirectory);
if (base) {
char *s = ExchangeChars(strdup(base), true);
d = AddDirectory(d, s);
free(s);
}
return d;
}
cRecording *cMenuRecordings::GetRecording(cMenuRecordingItem *Item)
{
cRecording *recording = Recordings.GetByName(Item->FileName());
@ -2417,6 +2429,15 @@ eOSState cMenuRecordings::Commands(eKeys Key)
return osContinue;
}
eOSState cMenuRecordings::Sort(void)
{
if (HasSubMenu())
return osContinue;
IncRecordingsSortMode(DirectoryName());
Set(true);
return osContinue;
}
eOSState cMenuRecordings::ProcessKey(eKeys Key)
{
bool HadSubMenu = HasSubMenu();
@ -2431,6 +2452,7 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
case kYellow: return Delete();
case kInfo:
case kBlue: return Info();
case k0: return Sort();
case k1...k9: return Commands(Key);
case kNone: if (Recordings.StateChanged(recordingsState))
Set(true);
@ -4149,6 +4171,20 @@ cRecordControl::cRecordControl(cDevice *Device, cTimer *Timer, bool Pause)
if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
cReplayControl::SetRecording(fileName);
Recordings.AddByName(fileName);
if (!Timer->IsSingleEvent()) {
char *Directory = strdup(fileName);
// going up two directory levels to get the series folder
if (char *p = strrchr(Directory, '/')) {
while (p > Directory && *--p != '/')
;
*p = 0;
if (!HasRecordingsSortMode(Directory)) {
dsyslog("setting %s to be sorted by time", Directory);
SetRecordingsSortMode(Directory, rsmTime);
}
}
free(Directory);
}
return;
}
else

4
menu.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: menu.h 2.9 2012/05/12 11:48:04 kls Exp $
* $Id: menu.h 2.10 2012/06/09 12:12:43 kls Exp $
*/
#ifndef __MENU_H
@ -203,8 +203,10 @@ private:
eOSState Rewind(void);
eOSState Delete(void);
eOSState Info(void);
eOSState Sort(void);
eOSState Commands(eKeys Key = kNone);
protected:
cString DirectoryName(void);
cRecording *GetRecording(cMenuRecordingItem *Item);
public:
cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false);

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.c 2.56 2012/06/03 09:51:27 kls Exp $
* $Id: recording.c 2.57 2012/06/09 13:57:30 kls Exp $
*/
#include "recording.h"
@ -53,6 +53,8 @@
#define INFOFILESUFFIX "/info"
#define MARKSFILESUFFIX "/marks"
#define SORTMODEFILE ".sort"
#define MINDISKSPACE 1024 // MB
#define REMOVECHECKDELTA 60 // seconds between checks for removing deleted files
@ -610,7 +612,7 @@ cRecording::cRecording(cTimer *Timer, const cEvent *Event)
{
resume = RESUME_NOT_INITIALIZED;
titleBuffer = NULL;
sortBuffer = NULL;
sortBufferName = sortBufferTime = NULL;
fileName = NULL;
name = NULL;
fileSizeMB = -1; // unknown
@ -683,7 +685,7 @@ cRecording::cRecording(const char *FileName)
numFrames = -1;
deleted = 0;
titleBuffer = NULL;
sortBuffer = NULL;
sortBufferName = sortBufferTime = NULL;
FileName = fileName = strdup(FileName);
if (*(fileName + strlen(fileName) - 1) == '/')
*(fileName + strlen(fileName) - 1) = 0;
@ -795,7 +797,8 @@ cRecording::cRecording(const char *FileName)
cRecording::~cRecording()
{
free(titleBuffer);
free(sortBuffer);
free(sortBufferName);
free(sortBufferTime);
free(fileName);
free(name);
delete info;
@ -816,22 +819,27 @@ char *cRecording::StripEpisodeName(char *s)
}
t++;
}
if (s1 && s2)
memmove(s1 + 1, s2, t - s2 + 1);
if (s1 && s2) {
s1++;
memmove(s1, s2, t - s2 + 1);
*s1 = 0xFF; // sorts folders before plain recordings
}
return s;
}
char *cRecording::SortName(void) const
{
if (!sortBuffer) {
char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory) + 1));
char **sb = (RecordingsSortMode == rsmName) ? &sortBufferName : &sortBufferTime;
if (!*sb) {
char *s = (RecordingsSortMode == rsmName) ? strdup(FileName() + strlen(VideoDirectory) + 1)
: StripEpisodeName(strdup(FileName() + strlen(VideoDirectory) + 1));
strreplace(s, '/', 'a'); // some locales ignore '/' when sorting
int l = strxfrm(NULL, s, 0) + 1;
sortBuffer = MALLOC(char, l);
strxfrm(sortBuffer, s, l);
*sb = MALLOC(char, l);
strxfrm(*sb, s, l);
free(s);
}
return sortBuffer;
return *sb;
}
int cRecording::GetResume(void) const
@ -2133,3 +2141,39 @@ int ReadFrame(cUnbufferedFile *f, uchar *b, int Length, int Max)
LOG_ERROR;
return r;
}
// --- Recordings Sort Mode --------------------------------------------------
eRecordingsSortMode RecordingsSortMode = rsmName;
bool HasRecordingsSortMode(const char *Directory)
{
return access(AddDirectory(Directory, SORTMODEFILE), R_OK) == 0;
}
void GetRecordingsSortMode(const char *Directory)
{
if (FILE *f = fopen(AddDirectory(Directory, SORTMODEFILE), "r")) {
char buf[8];
if (fgets(buf, sizeof(buf), f))
RecordingsSortMode = eRecordingsSortMode(constrain(atoi(buf), 0, int(rsmTime)));
fclose(f);
}
}
void SetRecordingsSortMode(const char *Directory, eRecordingsSortMode SortMode)
{
if (FILE *f = fopen(AddDirectory(Directory, SORTMODEFILE), "w")) {
fputs(cString::sprintf("%d\n", SortMode), f);
fclose(f);
}
}
void IncRecordingsSortMode(const char *Directory)
{
GetRecordingsSortMode(Directory);
RecordingsSortMode = eRecordingsSortMode(int(RecordingsSortMode) + 1);
if (RecordingsSortMode > rsmTime)
RecordingsSortMode = eRecordingsSortMode(0);
SetRecordingsSortMode(Directory, RecordingsSortMode);
}

View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: recording.h 2.33 2012/06/03 09:49:09 kls Exp $
* $Id: recording.h 2.34 2012/06/09 13:55:22 kls Exp $
*/
#ifndef __RECORDING_H
@ -83,7 +83,8 @@ class cRecording : public cListObject {
private:
mutable int resume;
mutable char *titleBuffer;
mutable char *sortBuffer;
mutable char *sortBufferName;
mutable char *sortBufferTime;
mutable char *fileName;
mutable char *name;
mutable int fileSizeMB;
@ -333,4 +334,11 @@ char *ExchangeChars(char *s, bool ToFileSystem);
bool GenerateIndex(const char *FileName);
enum eRecordingsSortMode { rsmName, rsmTime };
extern eRecordingsSortMode RecordingsSortMode;
bool HasRecordingsSortMode(const char *Directory);
void GetRecordingsSortMode(const char *Directory);
void SetRecordingsSortMode(const char *Directory, eRecordingsSortMode SortMode);
void IncRecordingsSortMode(const char *Directory);
#endif //__RECORDING_H