diff -ruN vdr-1.7.16/config.c vdr-1.7.16-sortrec/config.c --- vdr-1.7.16/config.c 2010-10-06 19:57:21.123326320 +0200 +++ vdr-1.7.16-sortrec/config.c 2010-10-06 20:04:35.083321724 +0200 @@ -460,6 +460,10 @@ noEPGMode = 0; noEPGList = NULL; #endif /* NOEPG */ +#ifdef USE_SORTRECORDS + RecordingsSortMode = 0; + RecordingsSortDirsFirst = 0; +#endif /* SORTRECORDS */ #ifdef USE_DVLVIDPREFER UseVidPrefer = 0; // default = disabled nVidPrefer = 1; @@ -737,6 +741,10 @@ noEPGList = Value ? strdup(Value) : NULL; } #endif /* NOEPG */ +#ifdef USE_SORTRECORDS + else if (!strcasecmp(Name, "RecordingsSortMode")) RecordingsSortMode = atoi(Value); + else if (!strcasecmp(Name, "RecordingsSortDirsFirst")) RecordingsSortDirsFirst = atoi(Value); +#endif /* SORTRECORDS */ #ifdef USE_DVLVIDPREFER else if (strcasecmp(Name, "UseVidPrefer") == 0) UseVidPrefer = atoi(Value); else if (strcasecmp(Name, "nVidPrefer") == 0) nVidPrefer = atoi(Value); @@ -944,6 +952,10 @@ Store("noEPGMode", noEPGMode); Store("noEPGList", noEPGList ? noEPGList : ""); #endif /* NOEPG */ +#ifdef USE_SORTRECORDS + Store("RecordingsSortMode", RecordingsSortMode); + Store("RecordingsSortDirsFirst", RecordingsSortDirsFirst); +#endif /* SORTRECORDS */ #ifdef USE_DVLVIDPREFER Store ("UseVidPrefer", UseVidPrefer); Store ("nVidPrefer", nVidPrefer); diff -ruN vdr-1.7.16/config.h vdr-1.7.16-sortrec/config.h --- vdr-1.7.16/config.h 2010-10-06 19:57:21.123326320 +0200 +++ vdr-1.7.16-sortrec/config.h 2010-10-06 20:06:13.293323320 +0200 @@ -372,6 +372,10 @@ #ifdef USE_NOEPG int noEPGMode; #endif /* NOEPG */ +#ifdef USE_SORTRECORDS + int RecordingsSortMode; + int RecordingsSortDirsFirst; +#endif /* SORTRECORDS */ #ifdef USE_DVLVIDPREFER int UseVidPrefer; // 0 = VDR's default, 1 = use int nVidPrefer; diff -ruN vdr-1.7.16/Make.config.template vdr-1.7.16-sortrec/Make.config.template --- vdr-1.7.16/Make.config.template 2010-10-06 19:57:21.113331161 +0200 +++ vdr-1.7.16-sortrec/Make.config.template 2010-10-06 19:59:41.643330277 +0200 @@ -43,6 +43,7 @@ ### VDR-Extensions: # Uncomment the patches you need +# SORTRECORDS needs LIEMIEXT enabled # you can only enable MENUORG or SETUP # If you want to enable SETUP, TinyXML must be installed in your system @@ -69,6 +70,7 @@ #PLUGINMISSING = 1 #ROTOR = 1 #SETUP = 1 +#SORTRECORDS = 1 #TIMERINFO = 1 #TTXTSUBS = 1 #VALIDINPUT = 1 @@ -173,6 +175,12 @@ DEFINES += -DUSE_ROTOR endif +ifdef SORTRECORDS +ifdef LIEMIEXT +DEFINES += -DUSE_SORTRECORDS +endif +endif + ifdef TIMERINFO DEFINES += -DUSE_TIMERINFO endif diff -ruN vdr-1.7.16/menu.c vdr-1.7.16-sortrec/menu.c --- vdr-1.7.16/menu.c 2010-10-06 19:57:21.133320759 +0200 +++ vdr-1.7.16-sortrec/menu.c 2010-10-06 20:18:48.173321553 +0200 @@ -2979,6 +2979,13 @@ eOSState state = cOsdMenu::ProcessKey(Key); if (state == osUnknown) { +#ifdef USE_SORTRECORDS + const char *RecordingsSortModeTexts[MAXSORTMODES]; + RecordingsSortModeTexts[0] = tr("main dir alphabetically, subdirs flexible"); + RecordingsSortModeTexts[1] = tr("main dir by date, subdirs flexible"); + RecordingsSortModeTexts[2] = tr("all alphabetically"); + RecordingsSortModeTexts[3] = tr("all by date"); +#endif /* SORTRECORDS */ switch (Key) { case kPlay: case kOk: return Play(); @@ -2987,7 +2994,17 @@ case kYellow: return Delete(); case kInfo: case kBlue: return Info(); -#ifdef USE_LIEMIEXT +#ifdef USE_SORTRECORDS + case k0: Setup.RecordingsSortMode = ++Setup.RecordingsSortMode % MAXSORTMODES; + Set(true); + Skins.Message(mtStatus, cString::sprintf("%s %d: %s", tr("Sorting"), Setup.RecordingsSortMode, RecordingsSortModeTexts[Setup.RecordingsSortMode])); + return osContinue; + case k1...k7: return Commands(Key); + case k8: return Rename(); + case k9: Recordings.ToggleSortOrder(); + Set(true); + return osContinue; +#elif defined (USE_LIEMIEXT) case k0: DirOrderState = !DirOrderState; Set(true); return osContinue; @@ -2996,7 +3013,7 @@ case k1...k7: return Commands(Key); #else case k1...k9: return Commands(Key); -#endif /* LIEMIEXT */ +#endif /* LIEMIEXT & SORTRECORDS */ case kNone: if (Recordings.StateChanged(recordingsState)) Set(true); break; @@ -3656,6 +3673,9 @@ private: const char *pauseKeyHandlingTexts[3]; const char *delTimeshiftRecTexts[3]; +#ifdef USE_SORTRECORDS + const char *RecordingsSortModeTexts[MAXSORTMODES]; +#endif /* SORTRECORDS */ #ifdef USE_DVLVIDPREFER void Set(void); int tmpNVidPrefer, @@ -3699,6 +3719,12 @@ void cMenuSetupRecord::Set(void) { #endif /* DVLVIDPREFER */ +#ifdef USE_SORTRECORDS + RecordingsSortModeTexts[0] = tr("main dir alphabetically, subdirs flexible"); + RecordingsSortModeTexts[1] = tr("main dir by date, subdirs flexible"); + RecordingsSortModeTexts[2] = tr("all alphabetically"); + RecordingsSortModeTexts[3] = tr("all by date"); +#endif /* SORTRECORDS */ pauseKeyHandlingTexts[0] = tr("do not pause live video"); pauseKeyHandlingTexts[1] = tr("confirm pause live video"); pauseKeyHandlingTexts[2] = tr("pause live video"); @@ -3747,6 +3773,10 @@ Add(new cMenuEditBoolItem(tr("Setup.Recording$Show time"), &data.ShowRecTime)); Add(new cMenuEditBoolItem(tr("Setup.Recording$Show length"), &data.ShowRecLength)); #endif /* LIEMIEXT */ +#ifdef USE_SORTRECORDS + Add(new cMenuEditStraItem(tr("Setup.Recording$Sort recordings by"), &data.RecordingsSortMode, MAXSORTMODES, RecordingsSortModeTexts)); + Add(new cMenuEditBoolItem(tr("Setup.Recording$Sort directories before recordings"), &data.RecordingsSortDirsFirst)); +#endif /* SORTRECORDS */ Add(new cMenuEditStraItem(tr("Setup.Recording$Delete timeshift recording"),&data.DelTimeshiftRec, 3, delTimeshiftRecTexts)); } diff -ruN vdr-1.7.16/recording.c vdr-1.7.16-sortrec/recording.c --- vdr-1.7.16/recording.c 2010-10-06 19:57:21.153320756 +0200 +++ vdr-1.7.16-sortrec/recording.c 2010-10-06 20:32:30.593329803 +0200 @@ -607,7 +607,14 @@ { resume = RESUME_NOT_INITIALIZED; titleBuffer = NULL; +#ifdef USE_SORTRECORDS + for (int i = 0; i < MAXSORTMODES; i++) { + sortBuffer[i] = NULL; + lastDirsFirst[i] = -1; + } +#else sortBuffer = NULL; +#endif /* SORTRECORDS */ fileName = NULL; name = NULL; fileSizeMB = -1; // unknown @@ -676,7 +683,14 @@ framesPerSecond = DEFAULTFRAMESPERSECOND; deleted = 0; titleBuffer = NULL; +#ifdef USE_SORTRECORDS + for (int i = 0; i < MAXSORTMODES; i++) { + sortBuffer[i] = NULL; + lastDirsFirst[i] = -1; + } +#else sortBuffer = NULL; +#endif /* SORTRECORDS */ FileName = fileName = strdup(FileName); if (*(fileName + strlen(fileName) - 1) == '/') *(fileName + strlen(fileName) - 1) = 0; @@ -778,7 +792,13 @@ cRecording::~cRecording() { free(titleBuffer); +#ifdef USE_SORTRECORDS + for (int i = 0; i < MAXSORTMODES; i++) { + free(sortBuffer[i]); + } +#else free(sortBuffer); +#endif /* SORTRECORDS */ free(fileName); free(name); delete info; @@ -800,21 +820,46 @@ t++; } if (s1 && s2) +#ifdef USE_SORTRECORDS + if (Setup.RecordingsSortDirsFirst) + *s1 = 'b'; + + if ((Setup.RecordingsSortMode <= 1 && s1 != s && !strchr(".-$ª·", *(s1 - 1))) || + (Setup.RecordingsSortMode == 1 && s1 == s) || + (Setup.RecordingsSortMode == 3)) +#endif /* SORTRECORDS */ memmove(s1 + 1, s2, t - s2 + 1); return s; } char *cRecording::SortName(void) const { +#ifdef USE_SORTRECORDS + if (!sortBuffer[Setup.RecordingsSortMode] || + lastDirsFirst[Setup.RecordingsSortMode] != Setup.RecordingsSortDirsFirst) { + free(sortBuffer[Setup.RecordingsSortMode]); + lastDirsFirst[Setup.RecordingsSortMode] = Setup.RecordingsSortDirsFirst; + char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory))); +#else if (!sortBuffer) { char *s = StripEpisodeName(strdup(FileName() + strlen(VideoDirectory) + 1)); +#endif /* SORTRECORDS */ strreplace(s, '/', 'a'); // some locales ignore '/' when sorting int l = strxfrm(NULL, s, 0) + 1; +#ifdef USE_SORTRECORDS + sortBuffer[Setup.RecordingsSortMode] = MALLOC(char, l); + strxfrm(sortBuffer[Setup.RecordingsSortMode], s, l); +#else sortBuffer = MALLOC(char, l); strxfrm(sortBuffer, s, l); +#endif /* SORTRECORDS */ free(s); } +#ifdef USE_SORTRECORDS + return sortBuffer[Setup.RecordingsSortMode]; +#else return sortBuffer; +#endif /* SORTRECORDS */ } int cRecording::GetResume(void) const @@ -833,7 +878,11 @@ if (DirOrderState) return strcasecmp(FileName(), r->FileName()); #endif /* LIEMIEXT */ +#ifdef USE_SORTRECORDS + return Recordings.GetSortOrder() * strcasecmp(SortName(), r->SortName()); +#else return strcasecmp(SortName(), r->SortName()); +#endif /* USE_SORTRECORDS */ } const char *cRecording::FileName(void) const @@ -1089,8 +1138,15 @@ fileName = strdup(newFileName); free(name); name = strdup(newName); +#ifdef USE_SORTRECORDS + for (int i = 0; i < MAXSORTMODES; i++) { + free(sortBuffer[i]); + sortBuffer[i] = NULL; + } +#else free(sortBuffer); sortBuffer = NULL; +#endif /* SORTRECORDS */ free(titleBuffer); titleBuffer = NULL; } @@ -1114,6 +1170,9 @@ deleted = Deleted; lastUpdate = 0; state = 0; +#ifdef USE_SORTRECORDS + SortOrder = 1; +#endif /* SORTRECORDS */ } cRecordings::~cRecordings() diff -ruN vdr-1.7.16/recording.h vdr-1.7.16-sortrec/recording.h --- vdr-1.7.16/recording.h 2010-10-06 19:57:21.153320756 +0200 +++ vdr-1.7.16-sortrec/recording.h 2010-10-06 20:36:20.863322484 +0200 @@ -84,12 +84,22 @@ bool Write(void) const; }; +#ifdef USE_SORTRECORDS +#define SORTRECORDINGSVERSNUM 3 +#define MAXSORTMODES 4 +#endif /* SORTRECORDS */ + class cRecording : public cListObject { friend class cRecordings; private: mutable int resume; mutable char *titleBuffer; +#ifdef USE_SORTRECORDS + mutable char *sortBuffer[MAXSORTMODES]; + mutable char lastDirsFirst[MAXSORTMODES]; +#else mutable char *sortBuffer; +#endif /* SORTRECORDS */ mutable char *fileName; mutable char *name; mutable int fileSizeMB; @@ -154,6 +164,9 @@ bool deleted; time_t lastUpdate; int state; +#ifdef USE_SORTRECORDS + int SortOrder; +#endif /* SORTRECORDS */ const char *UpdateFileName(void); void Refresh(bool Foreground = false); void ScanVideoDir(const char *DirName, bool Foreground = false, int LinkLevel = 0); @@ -184,6 +197,10 @@ void AddByName(const char *FileName, bool TriggerUpdate = true); void DelByName(const char *FileName); int TotalFileSizeMB(void); ///< Only for deleted recordings! +#ifdef USE_SORTRECORDS + void ToggleSortOrder(void) { SortOrder *= -1; } + const int GetSortOrder(void) { return SortOrder; } +#endif /* SORTRECORDS */ }; extern cRecordings Recordings;