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 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). 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 - Added a missing template specification to the c'tor of cSortedTimers (thanks to Udo
Richter). Richter).
@ -7170,3 +7170,8 @@ Video Disk Recorder Revision History
- Removed the gap from the main menu buttons in the LCARS skin. - 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). - 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. - 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 - Green - Audio New New Ins/Ovr Rewind Skip -60s -
Yellow - Pause live Delete Delete Delete Delete Skip +60s - Yellow - Pause live Delete Delete Delete Delete Skip +60s -
Blue - Stop/Resume Mark Info - Info Stop - 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 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 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 Yellow Info
Blue Timers menu 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", (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 "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 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" A previously stopped playback session can be resumed by pressing the "Blue"
key in the "VDR" menu. 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 * Processing Recordings
The configuration file 'reccmds.conf' can be used to define system commands 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 * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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" #include "menu.h"
@ -2247,6 +2247,7 @@ void cMenuRecordings::Set(bool Refresh)
} }
} }
Clear(); Clear();
GetRecordingsSortMode(DirectoryName());
Recordings.Sort(); Recordings.Sort();
for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) {
if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == FOLDERDELIMCHAR)) { if (!base || (strstr(recording->Name(), base) == recording->Name() && recording->Name()[strlen(base)] == FOLDERDELIMCHAR)) {
@ -2272,6 +2273,17 @@ void cMenuRecordings::Set(bool Refresh)
Display(); 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 *cMenuRecordings::GetRecording(cMenuRecordingItem *Item)
{ {
cRecording *recording = Recordings.GetByName(Item->FileName()); cRecording *recording = Recordings.GetByName(Item->FileName());
@ -2417,6 +2429,15 @@ eOSState cMenuRecordings::Commands(eKeys Key)
return osContinue; return osContinue;
} }
eOSState cMenuRecordings::Sort(void)
{
if (HasSubMenu())
return osContinue;
IncRecordingsSortMode(DirectoryName());
Set(true);
return osContinue;
}
eOSState cMenuRecordings::ProcessKey(eKeys Key) eOSState cMenuRecordings::ProcessKey(eKeys Key)
{ {
bool HadSubMenu = HasSubMenu(); bool HadSubMenu = HasSubMenu();
@ -2431,6 +2452,7 @@ eOSState cMenuRecordings::ProcessKey(eKeys Key)
case kYellow: return Delete(); case kYellow: return Delete();
case kInfo: case kInfo:
case kBlue: return Info(); case kBlue: return Info();
case k0: return Sort();
case k1...k9: return Commands(Key); case k1...k9: return Commands(Key);
case kNone: if (Recordings.StateChanged(recordingsState)) case kNone: if (Recordings.StateChanged(recordingsState))
Set(true); 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() if (!Timer && !cReplayControl::LastReplayed()) // an instant recording, maybe from cRecordControls::PauseLiveVideo()
cReplayControl::SetRecording(fileName); cReplayControl::SetRecording(fileName);
Recordings.AddByName(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; return;
} }
else else

4
menu.h
View File

@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef __MENU_H
@ -203,8 +203,10 @@ private:
eOSState Rewind(void); eOSState Rewind(void);
eOSState Delete(void); eOSState Delete(void);
eOSState Info(void); eOSState Info(void);
eOSState Sort(void);
eOSState Commands(eKeys Key = kNone); eOSState Commands(eKeys Key = kNone);
protected: protected:
cString DirectoryName(void);
cRecording *GetRecording(cMenuRecordingItem *Item); cRecording *GetRecording(cMenuRecordingItem *Item);
public: public:
cMenuRecordings(const char *Base = NULL, int Level = 0, bool OpenSubMenus = false); 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 * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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" #include "recording.h"
@ -53,6 +53,8 @@
#define INFOFILESUFFIX "/info" #define INFOFILESUFFIX "/info"
#define MARKSFILESUFFIX "/marks" #define MARKSFILESUFFIX "/marks"
#define SORTMODEFILE ".sort"
#define MINDISKSPACE 1024 // MB #define MINDISKSPACE 1024 // MB
#define REMOVECHECKDELTA 60 // seconds between checks for removing deleted files #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; resume = RESUME_NOT_INITIALIZED;
titleBuffer = NULL; titleBuffer = NULL;
sortBuffer = NULL; sortBufferName = sortBufferTime = NULL;
fileName = NULL; fileName = NULL;
name = NULL; name = NULL;
fileSizeMB = -1; // unknown fileSizeMB = -1; // unknown
@ -683,7 +685,7 @@ cRecording::cRecording(const char *FileName)
numFrames = -1; numFrames = -1;
deleted = 0; deleted = 0;
titleBuffer = NULL; titleBuffer = NULL;
sortBuffer = NULL; sortBufferName = sortBufferTime = NULL;
FileName = fileName = strdup(FileName); FileName = fileName = strdup(FileName);
if (*(fileName + strlen(fileName) - 1) == '/') if (*(fileName + strlen(fileName) - 1) == '/')
*(fileName + strlen(fileName) - 1) = 0; *(fileName + strlen(fileName) - 1) = 0;
@ -795,7 +797,8 @@ cRecording::cRecording(const char *FileName)
cRecording::~cRecording() cRecording::~cRecording()
{ {
free(titleBuffer); free(titleBuffer);
free(sortBuffer); free(sortBufferName);
free(sortBufferTime);
free(fileName); free(fileName);
free(name); free(name);
delete info; delete info;
@ -816,22 +819,27 @@ char *cRecording::StripEpisodeName(char *s)
} }
t++; t++;
} }
if (s1 && s2) if (s1 && s2) {
memmove(s1 + 1, s2, t - s2 + 1); s1++;
memmove(s1, s2, t - s2 + 1);
*s1 = 0xFF; // sorts folders before plain recordings
}
return s; return s;
} }
char *cRecording::SortName(void) const char *cRecording::SortName(void) const
{ {
if (!sortBuffer) { char **sb = (RecordingsSortMode == rsmName) ? &sortBufferName : &sortBufferTime;
char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory) + 1)); 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 strreplace(s, '/', 'a'); // some locales ignore '/' when sorting
int l = strxfrm(NULL, s, 0) + 1; int l = strxfrm(NULL, s, 0) + 1;
sortBuffer = MALLOC(char, l); *sb = MALLOC(char, l);
strxfrm(sortBuffer, s, l); strxfrm(*sb, s, l);
free(s); free(s);
} }
return sortBuffer; return *sb;
} }
int cRecording::GetResume(void) const int cRecording::GetResume(void) const
@ -2133,3 +2141,39 @@ int ReadFrame(cUnbufferedFile *f, uchar *b, int Length, int Max)
LOG_ERROR; LOG_ERROR;
return r; 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 * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * 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 #ifndef __RECORDING_H
@ -83,7 +83,8 @@ class cRecording : public cListObject {
private: private:
mutable int resume; mutable int resume;
mutable char *titleBuffer; mutable char *titleBuffer;
mutable char *sortBuffer; mutable char *sortBufferName;
mutable char *sortBufferTime;
mutable char *fileName; mutable char *fileName;
mutable char *name; mutable char *name;
mutable int fileSizeMB; mutable int fileSizeMB;
@ -333,4 +334,11 @@ char *ExchangeChars(char *s, bool ToFileSystem);
bool GenerateIndex(const char *FileName); 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 #endif //__RECORDING_H