diff options
Diffstat (limited to 'menuplaylists.c')
-rw-r--r-- | menuplaylists.c | 569 |
1 files changed, 569 insertions, 0 deletions
diff --git a/menuplaylists.c b/menuplaylists.c new file mode 100644 index 0000000..aacb9b2 --- /dev/null +++ b/menuplaylists.c @@ -0,0 +1,569 @@ +/* + * playlist: A plugin for the Video Disk Recorder + * + * See the README file for copyright information and how to reach the author. + * + * $Id: menuplaylists.c 0.2 2004/10/08 02:34:00 hflor Exp $ + */ + +#include "menuplaylists.h" +#include "dataplaylist.h" +#include "playlist.h" +#include "menuplaylist.h" +#include "i18n.h" +#include "vdrtools.h" +#include <vdr/interface.h> + +// --- cMenuPlaylistEdit ----------------------------------------------------------- + +cMenuPlaylistEdit::cMenuPlaylistEdit(cPlaylist *Playlist, bool New) +:cOsdMenu(New ? tr("Edit$Create Playlist") : tr("Edit$Edit Playlist"), 33) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylistEdit::cMenuPlaylistEdit Playlist=%s new=%s", plugin_name, Playlist ? Playlist->Name() : "(null)", New ? "true" : "false"); +#endif + playlist = Playlist; + addIfConfirmed = New; + DisplayStatus[0] = 0; + if (playlist) + { + data = *playlist; + Set(); + } + if (New) + AddSubMenu(new cMenuPlaylist(playlist)); +} + +cMenuPlaylistEdit::~cMenuPlaylistEdit() +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylistEdit::~cMenuPlaylistEdit Playlist=%s addIfConfirmed=%s", plugin_name, playlist ? playlist->Name() : "(null)", addIfConfirmed ? "true" : "false"); +#endif + data.lastrecord = NULL; + data.recordcol = NULL; + if (playlist && addIfConfirmed) + delete playlist; // apparently it wasn't confirmed +} + +void cMenuPlaylistEdit::Set(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylistEdit::Set Current=%d", plugin_name, Current()); +#endif + for (int i = 0; i < MAXOptionLines; i++) + displayoption[i] = Option_max; + int current = Current(); + Clear(); + Add(new cMenuEditStrItem(tr("OptionPL$Name"), data.name, sizeof(data.name), tr(FileNameChars))); + displayoption[Count()] = Option_playoption1; + Add(new cMenuEditStraItem(tr("OptionPL$In playlistview starts play at"), &data.options[Option_playoption1], PlayOptions_max, PlayOptions)); + displayoption[Count()] = Option_playoption2; + Add(new cMenuEditStraItem(tr("OptionPL$In detailview starts play at"), &data.options[Option_playoption2], PlayOptions_max, PlayOptions)); + displayoption[Count()] = Option_searchnewrecord; + Add(new cMenuEditStraItem(tr("OptionPL$Search new records on folders"), &data.options[Option_searchnewrecord], 3, NoYesDefault)); + displayoption[Count()] = Option_searchrecordsub; + Add(new cMenuEditStraItem(tr("OptionPL$Search records on subfolders"), &data.options[Option_searchrecordsub], 3, NoYesDefault)); + displayoption[Count()] = Option_playonlynew; + Add(new cMenuEditStraItem(tr("OptionPL$Play only new Records"), &data.options[Option_playonlynew], 3, NoYesDefault)); + displayoption[Count()] = Option_jumpmark; + Add(new cMenuEditStraItem(tr("OptionPL$Jump to first segment of movie"), &data.options[Option_jumpmark], 3, NoYesDefault)); + displayoption[Count()] = Option_confirmstartnewrecord; + Add(new cMenuEditStraItem(tr("OptionPL$Confirm start new record"), &data.options[Option_confirmstartnewrecord], 3, NoYesDefault)); + displayoption[Count()] = Option_deletefromlist; + Add(new cMenuEditStraItem(tr("OptionPL$Remove records after play from list"), &data.options[Option_deletefromlist], 3, NoYesDefault)); + displayoption[Count()] = Option_deleterecord; + Add(new cMenuEditStraItem(tr("OptionPL$Delete records after play"), &data.options[Option_deleterecord], 3, NoYesDefault)); + if (data.options[Option_deleterecord] != NoYesDefault_no) + { + displayoption[Count()] = Option_confirmdeleterecord; + Add(new cMenuEditStraItem(tr("OptionPL$ Confirm delete records"), &data.options[Option_confirmdeleterecord], 3, NoYesDefault)); + } + SetCurrent(Get(current)); +} + +eOSState cMenuPlaylistEdit::ProcessKey(eKeys Key) +{ +#ifdef PL_Debug3 + bool noneKey = Key == kNone; + if (!noneKey) + dsyslog("%s: cMenuPlaylistEdit::ProcessKey Key=%s", plugin_name, KeyName(Key)); +#endif + int m_searchnewrecord = data.options[Option_searchnewrecord]; + int m_jumpmark = data.options[Option_jumpmark]; + int m_deleterecord = data.options[Option_deleterecord]; + int m_playoption = data.options[Option_playoption1]; + bool hSubMenu = HasSubMenu(); + + eOSState state = cOsdMenu::ProcessKey(Key); +#ifdef PL_Debug3 + if (!noneKey || (state != osUnknown && state != osContinue)) + { + dsyslog("%s: cMenuPlaylistEdit::ProcessKey OSState=%s", plugin_name, OSStateName(state)); + noneKey = false; + } +#endif + + if (m_searchnewrecord != data.options[Option_searchnewrecord] || m_jumpmark != data.options[Option_jumpmark] || m_deleterecord != data.options[Option_deleterecord]) + { + Set(); + Display(); + } else if (m_playoption != data.options[Option_playoption1] && data.options[Option_playoption1] == PlayOptions_selectpos) + { + data.options[Option_playoption1] = m_playoption < PlayOptions_selectpos ? PlayOptions_question : PlayOptions_lastplay; + RefreshCurrent(); + } + + char *buffer = NULL; + eOptions display = (Current() >= 0) && (Current() < MAXOptionLines) ? displayoption[Current()] : Option_max; + if (display < Option_max && data.OptionInherited(display)) + asprintf(&buffer, "%s %s", tr("OptionPL$Effective setting is:"), (display == Option_playoption1 || display == Option_playoption2) ? PlayOptions[data.Playoption(display)] : NoYesDefault[data.Option(display)]); + if (buffer) + { + if (strcmp(DisplayStatus, buffer)) + { + strn0cpy(DisplayStatus, buffer, MAXOSDTEXTWIDTH); + SetStatus(DisplayStatus); + } + free(buffer); + } else + { + if (strlen(DisplayStatus)) + { + DisplayStatus[0] = 0; + SetStatus(NULL); + } + } + if (hSubMenu && !HasSubMenu()) + { + if (playlist && playlist->RecordCol2() && !playlist->RecordCol2()->Count()) + state = osBack; // empty new list +//TODO name + RefreshCurrent(); // name + } + + cPlaylist *tempplaylist = NULL; + bool namefound = false; + switch (state) + { + case osUnknown: switch (Key) + { + case kOk: strn0cpy(data.name, skipspace(stripspace(data.name)), sizeof(data.name)); + Display(); + if (!strlen(data.name)) + { + ERROR(tr("Error$Missing playlist name!")); + break; + } + tempplaylist = PlaylistCol.First(); + while (tempplaylist) + { + if (tempplaylist != playlist && !strcasecmp(tempplaylist->name, data.name)) + { + namefound = true; + break; + } + tempplaylist = PlaylistCol.Next(tempplaylist); + } + if (namefound) + { + ERROR(tr("Error$same name of playlist exists!")); + break; + } + if (playlist) + { + if (data != *playlist) + { + if (strcmp(data.name, playlist->name)) + playlist->SetChange(); + *playlist = data; + if (addIfConfirmed) + PlaylistCol.Add(playlist); + PlaylistCol.Save(); + if (verbose.u) + isyslog("%s: playlist %d %s (%s)", plugin_name, playlist->Index() + 1, addIfConfirmed ? "added" : "modified", playlist->name); + addIfConfirmed = false; + } + state = osBack; + } + break; + case kRed: + case kGreen: + case kYellow: + case kBlue: state = osContinue; + break; + default: break; + } + break; + case osBack: if (playlist && !strlen(playlist->name) && playlist->RecordCol2() && playlist->RecordCol2()->Count() && playlist->RecordCol2()->GetChange() && !Interface->Confirm(tr("Discard all changes?"))) + state = osContinue; + default: break; + } + +#ifdef PL_Debug3 + if (!noneKey || (state != osUnknown && state != osContinue)) + dsyslog("%s: cMenuPlaylistEdit::ProcessKey returned OSState=%s", plugin_name, OSStateName(state)); +#endif + return state; +} + +// --- cMenuPlaylistsItem -------------------------------------------------------- + +cMenuPlaylistsItem::cMenuPlaylistsItem(cPlaylist *Playlist) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylistsItem::cMenuPlaylistsItem Playlist=%s", plugin_name, Playlist ? Playlist->Name() : "(null)"); +#endif + playlist = Playlist; + Set(); +} + +cMenuPlaylistsItem::~cMenuPlaylistsItem() +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylistsItem::~cMenuPlaylistsItem Playlist=%s", plugin_name, playlist ? playlist->Name() : "(null)"); +#endif +} + +bool cMenuPlaylistsItem::operator< (const cListObject &ListObject) +{ + return strcmp(playlist->Name(), ((cMenuPlaylistsItem *)&ListObject)->playlist->Name()) < 0; +} + +void cMenuPlaylistsItem::Set(void) +{ + char *buffer = NULL; + asprintf(&buffer, "%d\t%d\t%s", playlist->RecordCount(), playlist->RecordNew(), playlist->Name()); + SetText(buffer, false); +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylistsItem::Set SetText=%s", plugin_name, buffer); +#endif +} + +// --- cMenuPlaylists ----------------------------------------------------------- + +cMenuPlaylists::cMenuPlaylists(void) +:cOsdMenu(tr("Display$Display Playlists"), 4, 4) +{ +#ifdef PL_Debug1 + dsyslog("%s: cMenuPlaylists::cMenuPlaylists", plugin_name); +#endif + helpkeys = 1; + +#if VDRVERSNUM >= 10311 + if (Recordings.NeedsUpdate()) + { + STATUS(tr("scanning recordings...")); +#else + if (time(NULL) - LoadTime_Recordings > 3600) + { + LoadTime_Recordings = time(NULL); +#ifdef HAVE_ELCHI + Interface->Status(tr("scanning recordings..."), Setup.Theme == themeVanilla ? clrBlack : (eDvbColor)fginfofont, Setup.Theme == themeVanilla ? clrCyan : clrInfoLine); +#else + Interface->Status(tr("scanning recordings...")); +#endif + Interface->Flush(); +#endif + if (verbose.u) + isyslog("%s: loading recordings", plugin_name); + Recordings.Load(); + if (verbose.u) + isyslog("%s: %d recordings loaded", plugin_name, Recordings.Count()); + PlaylistSort.Clear(); + PlaylistMark.Clear(); + } else + { +#if VDRVERSNUM < 10311 +#ifdef HAVE_ELCHI + Interface->Status(tr("Display$prepare playlists display..."), Setup.Theme == themeVanilla ? clrBlack : (eDvbColor)fginfofont, Setup.Theme == themeVanilla ? clrCyan : clrInfoLine); +#else + Interface->Status(tr("Display$prepare playlists display...")); +#endif + Interface->Flush(); +#else + STATUS(tr("Display$prepare playlists display...")); +#endif + } + if (verbose.u) + isyslog("%s: loading playlists", plugin_name); + SelectPLR = NULL; + cMenuPlaylistsItem *selitem = NULL; + PlaylistCol.Load(PluginPlaylist->ExpandPath("playlists.conf"), false); + for (cPlaylist *playlist = PlaylistCol.First(); playlist; playlist = PlaylistCol.Next(playlist)) + if (playlist->RecordCol2()) + { + char *tempname = NULL; + asprintf(&tempname, "playlists.%s.conf", playlist->Name()); + playlist->RecordCol2()->Load(PluginPlaylist->ExpandPath(tempname), false); + free(tempname); + cPlaylistRecord *plr_n = NULL; + for (cPlaylistRecord *plr = playlist->First_PLR(); plr; plr = plr_n) + { + plr->Playlist(playlist); + plr_n = playlist->Next_PLR(plr); + if (!plr->IsDir() && plr->Start() == 0) + playlist->RecordCol2()->Del(plr); + } + if (playlist->SearchRecords()) + playlist->RecordCol2()->SaveWithFilename(); + if (verbose.u) + isyslog("%s playlist '%s' contain %d records, %d new", plugin_name, playlist->Name(), playlist->RecordCount(), playlist->RecordNew()); + cMenuPlaylistsItem *item = new cMenuPlaylistsItem(playlist); + Add(item); + if (strcasecmp(playlist->Name(), lastplaylist.u) == 0) + { + selitem = item; + SelectPLR = playlist->First_PLR(); + } + } + Sort(); + SetStatus(NULL); + if (selitem) + SetCurrent(selitem); + SetHelpKeys(); + Display(); +} + +cMenuPlaylists::~cMenuPlaylists(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylists::~cMenuPlaylists", plugin_name); +#endif +} + +void cMenuPlaylists::SetHelpKeys(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylists::SetHelpKeys", plugin_name); +#endif + if (Count()) + switch (helpkeys) + { + case 1: SetHelp(okstartplay.u ? tr("Edit") : tr("Play"), tr("New"), tr("Delete"), "-->"); break; + case 2: SetHelp("<--", okstartplay.u ? NULL : tr("Edit"), tr("Option"), NULL); break; + } + else + { + helpkeys = 1; + SetHelp(NULL, tr("New"), NULL, NULL); + } +} + +eOSState cMenuPlaylists::Play(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylists::Play", plugin_name); +#endif + cPlaylist *playlist = CurrentPlaylist(); + if (HasSubMenu() || !playlist) + return osContinue; + if (verbose.u) + isyslog("%s: start play Playlist %d Option=%d", plugin_name, playlist->Index() + 1, playlist->Playoption(Option_playoption1)); + playlist->SearchRecords(); + cPlaylistRecord *plr_firstnomal = playlist->Firstnormal_PLR(); + cPlaylistRecord *plr_firstnew = playlist->Firstnew_PLR(); + cPlaylistRecord *plr_lastplayed = playlist->Lastplayed_PLR(); + switch (playlist->Playoption(Option_playoption1)) + { + case PlayOptions_selectpos: // select not allow + case PlayOptions_firstpos: SelectPLR = plr_firstnomal; + break; + case PlayOptions_firstnew: if (plr_firstnew) + SelectPLR = plr_firstnew; + else + SelectPLR = Interface->Confirm(tr("Question$No new recording found! Play first?")) ? plr_firstnomal : NULL; + break; + case PlayOptions_lastplay: if (plr_lastplayed) + { + SelectPLR = plr_lastplayed; + break; + } + // no break! + case PlayOptions_question: if (plr_lastplayed && Interface->Confirm(tr("Question$Play last played recording?"))) + { + SelectPLR = plr_lastplayed; + break; + } + if (plr_firstnew && plr_firstnew != plr_firstnomal && Interface->Confirm(tr("Question$Play first new recording?"))) + { + SelectPLR = plr_firstnew; + break; + } + SelectPLR = plr_firstnomal; + break; + } + return SelectPLR ? osUser9 : osContinue; // osUSer9 starts play playlist with SelectPLR in cControlMenu::ProcessKey +} + +eOSState cMenuPlaylists::New(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylists::New", plugin_name); +#endif + if (HasSubMenu()) + return osContinue; + FREENULL(LastSelectedRecord); + return AddSubMenu(new cMenuPlaylistEdit(new cPlaylist, true)); +} + +eOSState cMenuPlaylists::Delete(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylists::Delete", plugin_name); +#endif + cPlaylist *playlist = CurrentPlaylist(); + if (PlayedPLR && PlayedPLR->Playlist() == playlist) + { + ERROR(tr("Error$Playlist is currently used by played recording")); + return osContinue; + } + if (playlist && playlist->RecordCol2()) + { + if (Interface->Confirm(tr("Edit$Delete Playlist?"))) + { + if (verbose.u) + isyslog("%s: Playlist %d deleted", plugin_name, playlist->Index() + 1); + playlist->RecordCol2()->DeleteFile(); + PlaylistCol.Del(playlist); + PlaylistCol.Save(); + cOsdMenu::Del(Current()); + Display(); + } + } + return osContinue; +} + +eOSState cMenuPlaylists::EditPlaylist(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylists::EditPlaylist", plugin_name); +#endif + if (HasSubMenu() || !CurrentPlaylist()) + return osContinue; + isyslog("%s: editing Playlist %d", plugin_name, CurrentPlaylist()->Index() + 1); + cPlaylist *playlist = CurrentPlaylist(); + if (playlist) + playlist->SearchRecords(); + return AddSubMenu(new cMenuPlaylist(playlist)); +} + +eOSState cMenuPlaylists::EditOption(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylists::EditOption", plugin_name); +#endif + if (HasSubMenu() || !CurrentPlaylist()) + return osContinue; + isyslog("%s: editing option Playlist %d", plugin_name, CurrentPlaylist()->Index() + 1); + return AddSubMenu(new cMenuPlaylistEdit(CurrentPlaylist())); +} + +cPlaylist *cMenuPlaylists::CurrentPlaylist(void) +{ +#ifdef PL_Debug2 + dsyslog("%s: cMenuPlaylists::CurrentPlaylist", plugin_name); +#endif + cMenuPlaylistsItem *item = (cMenuPlaylistsItem *)Get(Current()); + return item ? item->Playlist() : NULL; +} + +eOSState cMenuPlaylists::ProcessKey(eKeys Key) +{ +#ifdef PL_Debug3 + bool noneKey = Key == kNone; + if (!noneKey) + dsyslog("%s: cMenuPlaylists::ProcessKey Key=%s", plugin_name, KeyName(Key)); +#endif + cOsdItem *Item; + int n; + int nPlaylists = PlaylistCol.Count(); + bool hSubMenu = HasSubMenu(); + + eOSState state = cOsdMenu::ProcessKey(Key); +#ifdef PL_Debug3 + if (!noneKey || (state != osUnknown && state != osContinue)) + { + dsyslog("%s: cMenuPlaylists::ProcessKey OSState=%s", plugin_name, OSStateName(state)); + noneKey = false; + } +#endif + + if (!HasSubMenu() && hSubMenu) + { + if (nPlaylists == PlaylistCol.Count()) + { + Item = Get(Current()); + RefreshCurrent(); + } else + Add((Item = new cMenuPlaylistsItem(PlaylistCol.Get(nPlaylists)))); + Sort(); + SetCurrent(Item); + cPlaylist *playlist = CurrentPlaylist(); + if (playlist) + { + playlist->SearchRecords(); + RefreshCurrent(); + Display(); + playlist->SaveRecordCol(); + } else + { + RefreshCurrent(); + Display(); + } + } + + switch (state) + { + case osUnknown: switch (Key) + { + case k0...k9: n = (Key == k0) ? 10 : (Key - k0); + if (n > Count()) + break; + SetCurrent(Get(--n)); + // no break! + case kOk: state = okstartplay.u ? Play() : EditPlaylist(); + break; + case kRed: switch (helpkeys) + { + case 1: okstartplay.u ? EditPlaylist() : state = Play(); break; + case 2: helpkeys = 1; break; + } + break; + case kGreen: switch (helpkeys) + { + case 1: state = New(); break; + case 2: state = okstartplay.u ? osUnknown : EditPlaylist(); break; + } + break; + case kYellow: switch (helpkeys) + { + case 1: state = Delete(); break; + case 2: state = EditOption(); break; + } + break; + case kBlue: switch (helpkeys) + { + case 1: helpkeys = 2; break; + case 2: break; + } + break; + case kUser1: state = EditPlaylist(); + break; + case kUser2: state = Play(); + break; + case kUser3: state = New(); + break; + default: break; + } + break; + default: break; + } + if (!HasSubMenu() && Key != kNone) + SetHelpKeys(); + +#ifdef PL_Debug3 + if (!noneKey || (state != osUnknown && state != osContinue)) + dsyslog("%s: cMenuPlaylists::ProcessKey returned OSState=%s", plugin_name, OSStateName(state)); +#endif + return state; +} |