/* * See the README file for copyright information and how to reach the author. */ #include #include #include #include #include #include #include #include #include #include #include #include "myreplaycontrol.h" #include "mymenurecordings.h" #include "mymenusetup.h" #include "mymenucommands.h" #include "tools.h" using namespace std; // --- myMenuRecordingInfo ---------------------------------------------------- // this class is mostly a copy of VDR's cMenuRecording class, I only adjusted // the Display()-method // ---------------------------------------------------------------------------- class myMenuRecordingInfo:public cOsdMenu { private: const cRecording *recording; bool withButtons; eOSState Play(); eOSState Rewind(); public: myMenuRecordingInfo(const cRecording *Recording,bool WithButtons = false); virtual void Display(void); virtual eOSState ProcessKey(eKeys Key); #ifdef USE_GRAPHTFT virtual const char* MenuKind(){return "MenuExtRecording";} #endif }; myMenuRecordingInfo::myMenuRecordingInfo(const cRecording *Recording, bool WithButtons):cOsdMenu(trVDR("Recording info")) { recording=Recording; withButtons=WithButtons; if(withButtons) SetHelp(tr("Button$Play"),tr("Button$Rewind"),NULL,tr("Button$Back")); } void myMenuRecordingInfo::Display(void) { cOsdMenu::Display(); #ifdef USE_GRAPHTFT cStatus::MsgOsdSetRecording(recording); #endif if(mysetup.UseVDRsRecInfoMenu) { DisplayMenu()->SetRecording(recording); if(recording->Info()->Description()) cStatus::MsgOsdTextItem(recording->Info()->Description()); } else { stringstream text; text << *DateString(recording->start) << ", " << *TimeString(recording->start) << "\n\n"; if(recording->Info()->Title()) { text << recording->Info()->Title() << "\n\n"; if(recording->Info()->Description()) text << recording->Info()->Description() << "\n\n"; } string recname=recording->Name(); string::size_type i=recname.rfind('~'); if(i!=string::npos) text << tr("Name") << ": " << recname.substr(i+1,recname.length()) << "\n" << tr("Path") << ": " << recname.substr(0,i) << "\n"; else text << tr("Name") << ": " << recname << "\n"; cChannel *chan=Channels.GetByChannelID(((cRecordingInfo*)recording->Info())->ChannelID()); if(chan) text << tr("Channel") << ": " << *ChannelString(chan,0) << "\n"; int recmb=DirSizeMB(recording->FileName()); if(recmb<0) recmb=0; if(recmb > 1023) text << tr("Size") << ": " << setprecision(3) << recmb/1024.0 << " GB\n"; else text << tr("Size") << ": " << recmb << " MB\n"; text << trVDR("Priority") << ": " << recording->priority << "\n"; text << trVDR("Lifetime") << ": " << recording->lifetime << "\n"; DisplayMenu()->SetText(text.str().c_str(),false); cStatus::MsgOsdTextItem(text.str().c_str()); } } eOSState myMenuRecordingInfo::ProcessKey(eKeys Key) { switch(Key) { case kUp|k_Repeat: case kUp: case kDown|k_Repeat: case kDown: case kLeft|k_Repeat: case kLeft: case kRight|k_Repeat: case kRight: DisplayMenu()->Scroll(NORMALKEY(Key)==kUp||NORMALKEY(Key)==kLeft,NORMALKEY(Key)==kLeft||NORMALKEY(Key)==kRight); cStatus::MsgOsdTextItem(NULL, NORMALKEY(Key) == kUp); return osContinue; default: break; } eOSState state=cOsdMenu::ProcessKey(Key); if(state==osUnknown) { switch(Key) { case kRed: if(withButtons) Key=kOk; case kGreen: if(!withButtons) break; cRemote::Put(Key,true); case kBlue: case kOk: return osBack; default: break; } } return state; } // --- myMenuRecordingsItem --------------------------------------------------- myMenuRecordingsItem::myMenuRecordingsItem(cRecording *Recording,int Level) { totalentries=newentries=0; isdvd=false; dirismoving=true; name=NULL; filename=Recording->FileName(); // get the level of this recording level=0; const char *s=Recording->Name(); while(*++s) { if(*s=='~') level++; } // create the title of this item if(LevelName(); const char *p=s; while(*++s) { if(*s=='~') { if(Level--) p=s+1; else break; } } title=MALLOC(char,s-p+3); *title='\t'; *(title+1)='\t'; strn0cpy(title+2,p,s-p+1); name=strdup(title+2); uniqid=name; } else { if(Level==level) // recording entry { string buffer; stringstream titlebuffer; stringstream idbuffer; buffer=filename; buffer+="/001.vdr"; if(access(buffer.c_str(),R_OK)) { buffer=filename; buffer+="/dvd.vdr"; isdvd=!access(buffer.c_str(),R_OK); } if(MoveCutterThread->IsMoving(filename)) titlebuffer << Icons::MovingRecording(); // moving recording else if(isdvd) titlebuffer << Icons::DVD(); // archive dvd else if(MoveCutterThread->IsCutting(filename)) titlebuffer << Icons::Scissor(); // cutting recording else if(Recording->IsNew() && !mysetup.PatchNew) titlebuffer << '*'; else if(!Recording->IsNew() && mysetup.PatchNew) titlebuffer << Icons::Continue(); // alternative to new marker / rewind / continue else titlebuffer << ' '; // no icon titlebuffer << '\t'; // date and time of recording struct tm tm_r; struct tm *t=localtime_r(&Recording->start,&tm_r); if(mysetup.ShowRecDate) titlebuffer << setw(2) << setfill('0') << t->tm_mday << '.' << setw(2) << setfill('0') << t->tm_mon+1 << '.' << setw(2) << setfill('0') << t->tm_year%100 << '\t'; if(mysetup.ShowRecTime) titlebuffer << setw(2) << setfill('0') << t->tm_hour << '.' << setw(2) << setfill('0') << t->tm_min << '\t'; idbuffer << t->tm_mday << t->tm_mon << t->tm_year << t->tm_hour << t->tm_min; // recording length if(mysetup.ShowRecLength) { buffer=filename; buffer+="/index.vdr"; struct stat statbuf; if(!stat(buffer.c_str(),&statbuf)) { ostringstream strbuf; strbuf << setw(3) << (int)(statbuf.st_size/12000) << "'"; // replace leading spaces with fixed blank (right align) titlebuffer << myStrReplace(strbuf.str(),' ',Icons::FixedBlank()) << '\t'; } else { // get recording length from file 'length.vdr' buffer=filename; buffer+="/length.vdr"; ifstream in(buffer.c_str()); if(in) { if(!in.eof()) getline(in,buffer); buffer+="'"; // replace leading spaces with fixed blank (right align) while(buffer.length()<=3) buffer.insert(0,Icons::FixedBlank()); titlebuffer << buffer << '\t'; in.close(); } else titlebuffer << '\t'; } } if(!mysetup.ShowRecDate && !mysetup.ShowRecTime && !mysetup.ShowRecLength) titlebuffer << '\t'; // recording title string s=Recording->Name(); string::size_type i=s.rfind('~'); if(i!=string::npos) { titlebuffer << s.substr(i+1,s.length()-i); idbuffer << s.substr(i+1,s.length()-i); } else { titlebuffer << s; idbuffer << s; } title=strdup(titlebuffer.str().c_str()); uniqid=idbuffer.str(); } else { if(Level>level) // any other title=""; } } SetText(title); } myMenuRecordingsItem::~myMenuRecordingsItem() { free(title); free(name); } void myMenuRecordingsItem::IncrementCounter(bool IsNew) { totalentries++; if(IsNew) newentries++; char *buffer=NULL; ostringstream entries; entries << setw(3) << totalentries; if(mysetup.ShowNewRecs) { asprintf(&buffer,"%s\t%s (%d)%s%s%s%s%s", GetDirIsMoving()?Icons::MovingDirectory():Icons::Directory(), // replace leading spaces with fixed blank (right align) myStrReplace(entries.str(),' ',Icons::FixedBlank()).c_str(), newentries, (!mysetup.ShowRecDate&&!mysetup.ShowRecTime&&!mysetup.ShowRecLength)?"\t":"", (mysetup.ShowRecDate||mysetup.ShowRecTime||mysetup.ShowRecLength)?"\t":"", (mysetup.ShowRecDate&&mysetup.ShowRecTime||mysetup.ShowRecTime&&mysetup.ShowRecLength||mysetup.ShowRecLength&&mysetup.ShowRecDate)?"\t":"", (mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength)?"\t":"", name); } else { asprintf(&buffer,"%s\t%s%s%s%s%s%s", GetDirIsMoving()?Icons::MovingDirectory():Icons::Directory(), // replace leading spaces with fixed blank (right align) myStrReplace(entries.str(),' ',Icons::FixedBlank()).c_str(), (!mysetup.ShowRecDate&&!mysetup.ShowRecTime&&!mysetup.ShowRecLength)?"\t":"", (mysetup.ShowRecDate||mysetup.ShowRecTime||mysetup.ShowRecLength)?"\t":"", (mysetup.ShowRecDate&&mysetup.ShowRecTime||mysetup.ShowRecTime&&mysetup.ShowRecLength||mysetup.ShowRecLength&&mysetup.ShowRecDate)?"\t":"", (mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength)?"\t":"", name); } SetText(buffer,false); } // --- myMenuRecordings ------------------------------------------------------- #define MB_PER_MINUTE 25.75 // this is just an estimate! (taken over from VDR) bool myMenuRecordings::golastreplayed=false; bool myMenuRecordings::wasdvd; dev_t myMenuRecordings::fsid=0; int myMenuRecordings::freediskspace=0; myMenuRecordings::myMenuRecordings(const char *Base,int Level):cOsdMenu("") { // set tabs if(mysetup.ShowRecDate&&mysetup.ShowRecTime&&!mysetup.ShowRecLength) // recording date and time are shown, recording length not SetCols(2,8,6); else if(mysetup.ShowRecDate&&mysetup.ShowRecTime) // all details are shown SetCols(2,8,6,4); else if(mysetup.ShowRecDate&&!mysetup.ShowRecTime) // recording time is not shown SetCols(2,8,4); else if(!mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength) // recording date is not shown SetCols(2,6,4); else // recording date and time are not shown; even if recording length should be not shown we must set two tabs because of the details of the directories { if(mysetup.ShowNewRecs) SetCols(2,8,3); else SetCols(2,4,3); } edit=false; level=Level; helpkeys=-1; base=Base?strdup(Base):NULL; Recordings.StateChanged(recordingsstate); Display(); if(wasdvd&&!cControl::Control()) { char *cmd=NULL; asprintf(&cmd,"dvdarchive.sh umount \"%s\"",*strescape(myReplayControl::LastReplayed(),"'\\\"$")); isyslog("[extrecmenu] calling %s to unmount dvd",cmd); int result=SystemExec(cmd); if(result) { result=result/256; if(result==1) Skins.Message(mtError,tr("Error while mounting DVD!")); } isyslog("[extrecmenu] dvdarchive.sh returns %d",result); free(cmd); wasdvd=false; } Set(); if(myReplayControl::LastReplayed()) Open(); Display(); SetHelpKeys(); } myMenuRecordings::~myMenuRecordings() { free(base); } int myMenuRecordings::FreeMB() { if(mysetup.FileSystemFreeMB) { string path=VideoDirectory; path+="/"; char *tmpbase=base?ExchangeChars(strdup(base),true):NULL; if(base) path+=tmpbase; struct stat statdir; if(!stat(path.c_str(),&statdir)) { if(statdir.st_dev!=fsid) { fsid=statdir.st_dev; struct statvfs fsstat; if(!statvfs(path.c_str(),&fsstat)) { freediskspace=int(fsstat.f_bavail/(1024.0*1024.0/fsstat.f_bsize)); for(cRecording *rec=DeletedRecordings.First();rec;rec=DeletedRecordings.Next(rec)) { if(!stat(rec->FileName(),&statdir)) { if(statdir.st_dev==fsid) freediskspace+=DirSizeMB(rec->FileName()); } } } else { esyslog("[extrecmenu] error while getting filesystem size - statvfs (%s): %s",path.c_str(),strerror(errno)); freediskspace=0; } } } else { esyslog("[extrecmenu] error while getting filesystem size - stat (%s): %s",path.c_str(),strerror(errno)); freediskspace=0; } free(tmpbase); } else { int freemb; VideoDiskSpace(&freemb); return freemb; } return freediskspace; } void myMenuRecordings::Title() { int freemb=FreeMB(); int minutes=int(double(freemb)/MB_PER_MINUTE); stringstream buffer; if(MoveCutterThread->IsMoveListEmpty()) buffer << Icons::MovingRecording(); if(MoveCutterThread->IsCutterQueueEmpty()) buffer << Icons::Scissor(); if(MoveCutterThread->IsMoveListEmpty() || MoveCutterThread->IsCutterQueueEmpty()) buffer << ' '; if(base) buffer << base; else buffer << trVDR("Recordings"); buffer << " (" << minutes/60 << ":" << setw(2) << setfill('0') << minutes%60 << " " << trVDR("free") << ")"; SetTitle(buffer.str().c_str()); } void myMenuRecordings::SetHelpKeys() { if(!HasSubMenu()) { myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); int newhelpkeys=0; if(item) { if(item->IsDirectory()) { if(item->GetDirIsMoving()) newhelpkeys=6; else newhelpkeys=1; } else { newhelpkeys=2; cRecording *recording=GetRecording(item); if(recording) { if(mysetup.UseVDRsRecInfoMenu) { if(!recording->Info()->Title()) { newhelpkeys=4; if(MoveCutterThread->IsMoving(recording->FileName()) || MoveCutterThread->IsCutting(recording->FileName())) newhelpkeys=5; } } if(MoveCutterThread->IsMoving(recording->FileName()) || MoveCutterThread->IsCutting(recording->FileName())) newhelpkeys=3; } } if(newhelpkeys!=helpkeys) { switch(newhelpkeys) { case 0: SetHelp(NULL);break; case 1: SetHelp(tr("Button$Open"),NULL,tr("Button$Edit"));break; case 2: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),tr("Button$Edit"),tr("Button$Info"));break; case 3: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),tr("Button$Cancel"),tr("Button$Info"));break; case 4: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),tr("Button$Edit"),NULL);break; case 5: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),tr("Button$Cancel"),NULL);break; case 6: SetHelp(tr("Button$Open"),NULL,tr("Button$Cancel"));break; } } helpkeys=newhelpkeys; } } } // create the menu list void myMenuRecordings::Set(bool Refresh,char *current) { const char *lastreplayed=current?current:myReplayControl::LastReplayed(); cThreadLock RecordingsLock(&Recordings); if(Refresh && !current) { fsid=0; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item) { cRecording *recording=Recordings.GetByName(item->FileName()); if(recording) lastreplayed=recording->FileName(); } } Clear(); // create my own recordings list from VDR's myRecList *list=new myRecList(); for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording)) list->Add(new myRecListItem(recording)); // sort my recordings list string path=VideoDirectory; path+="/"; if(base) path+=base; list->Sort(mySortList->Find(path)); char *lastitemtext=NULL; myMenuRecordingsItem *lastitem=NULL; for(myRecListItem *listitem=list->First();listitem;listitem=list->Next(listitem)) { cRecording *recording=listitem->recording; if(!base||(strstr(listitem->recording->Name(),base)==listitem->recording->Name()&&listitem->recording->Name()[strlen(base)]=='~')) { myMenuRecordingsItem *recitem=new myMenuRecordingsItem(listitem->recording,level); #ifdef WITHPINPLUGIN bool hidepinprotectedrecs=false; cPlugin *pinplugin=cPluginManager::GetPlugin("pin"); if(pinplugin) hidepinprotectedrecs=pinplugin->SetupParse("hideProtectedRecordings","1"); if((*recitem->UniqID() && ((!lastitem || strcmp(recitem->UniqID(),lastitemtext)))) && !((cStatus::MsgReplayProtected(GetRecording(recitem),recitem->Name(),base,recitem->IsDirectory(),true)) && hidepinprotectedrecs)) #else if(*recitem->UniqID() && ((!lastitem || strcmp(recitem->UniqID(),lastitemtext)))) #endif { Add(recitem); lastitem=recitem; free(lastitemtext); lastitemtext=strdup(lastitem->UniqID()); } else delete recitem; if(lastitem) { if(!MoveCutterThread->IsMoving(recording->FileName())) lastitem->SetDirIsMoving(false); if(lastitem->IsDirectory()) lastitem->IncrementCounter(recording->IsNew()); if(lastreplayed && !strcmp(lastreplayed,recording->FileName())) { if(golastreplayed||Refresh) { SetCurrent(lastitem); if(recitem && !recitem->IsDirectory() && !cControl::Control() && !mysetup.GoLastReplayed) golastreplayed=false; } if(recitem&&!recitem->IsDirectory()&&recitem->IsDVD()&&!cControl::Control()) cReplayControl::ClearLastReplayed(cReplayControl::LastReplayed()); } } } } free(lastitemtext); delete list; Title(); if(Refresh) Display(); } // returns the corresponding recording to an item cRecording *myMenuRecordings::GetRecording(myMenuRecordingsItem *Item) { cRecording *recording=Recordings.GetByName(Item->FileName()); if(!recording) Skins.Message(mtError,trVDR("Error while accessing recording!")); return recording; } // opens a subdirectory bool myMenuRecordings::Open() { myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item && item->IsDirectory()) { const char *t=item->Name(); char *buffer=NULL; if(base) { asprintf(&buffer,"%s~%s",base,t); t=buffer; } AddSubMenu(new myMenuRecordings(t,level+1)); free(buffer); return true; } return false; } // plays a recording eOSState myMenuRecordings::Play() { char *msg=NULL; char *name=NULL; char path[MaxFileName]; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item) { #ifdef WITHPINPLUGIN if(cStatus::MsgReplayProtected(GetRecording(item),item->Name(),base,item->IsDirectory())==true) return osContinue; #endif if(item->IsDirectory()) Open(); else { cRecording *recording=GetRecording(item); if(recording) { if(item->IsDVD()) { bool isvideodvd=false; char dvdnr[BUFSIZ]; char *buffer=NULL; FILE *f; asprintf(&buffer,"%s/dvd.vdr",recording->FileName()); if((f=fopen(buffer,"r"))!=NULL) { // get the dvd id if(fgets(dvdnr,sizeof(dvdnr),f)) { char *p=strchr(dvdnr,'\n'); if(p) *p=0; } // determine if dvd is a video dvd char tmp[BUFSIZ]; if(fgets(tmp,sizeof(dvdnr),f)) isvideodvd=true; fclose(f); } free(buffer); asprintf(&msg,tr("Please insert DVD %s"),dvdnr); if(Interface->Confirm(msg)) { free(msg); // recording is a video dvd if(isvideodvd) { cPlugin *plugin=cPluginManager::GetPlugin("dvd"); if(plugin) { cOsdObject *osd=plugin->MainMenuAction(); delete osd; osd=NULL; return osEnd; } else { Skins.Message(mtError,tr("DVD plugin is not installed!")); return osContinue; } } // recording is an archive dvd else { strcpy(path,recording->FileName()); name=strrchr(path,'/')+1; asprintf(&msg,"dvdarchive.sh mount \"%s\" '%s'",*strescape(path,"'"),*strescape(name,"'\\\"$")); isyslog("[extrecmenu] calling %s to mount dvd",msg); int result=SystemExec(msg); isyslog("[extrecmenu] dvdarchive.sh returns %d",result); free(msg); if(result) { result=result/256; if(result==1) Skins.Message(mtError,tr("Error while mounting DVD!")); if(result==2) Skins.Message(mtError,tr("No DVD in drive!")); if(result==3) Skins.Message(mtError,tr("Recording not found on DVD!")); if(result==4) Skins.Message(mtError,tr("Error while linking [0-9]*.vdr!")); if(result==5) Skins.Message(mtError,tr("sudo or mount --bind / umount error (vfat system)")); if(result==127) Skins.Message(mtError,tr("Script 'dvdarchive.sh' not found!")); return osContinue; } wasdvd=true; } } else { free(msg); return osContinue; } } golastreplayed=true; myReplayControl::SetRecording(recording->FileName(),recording->Title()); cControl::Shutdown(); isyslog("[extrecmenu] starting replay of recording"); cControl::Launch(new myReplayControl()); return osEnd; } } } return osContinue; } // plays a recording from the beginning eOSState myMenuRecordings::Rewind() { if(HasSubMenu()||Count()==0) return osContinue; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item&&!item->IsDirectory()) { cDevice::PrimaryDevice()->StopReplay(); cResumeFile ResumeFile(item->FileName()); ResumeFile.Delete(); return Play(); } return osContinue; } // delete a recording eOSState myMenuRecordings::Delete() { if(HasSubMenu()||Count()==0) return osContinue; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item&&!item->IsDirectory()) { if(Interface->Confirm(trVDR("Delete recording?"))) { cRecordControl *rc=cRecordControls::GetRecordControl(item->FileName()); if(rc) { if(Interface->Confirm(trVDR("Timer still recording - really delete?"))) { cTimer *timer=rc->Timer(); if(timer) { timer->Skip(); cRecordControls::Process(time(NULL)); if(timer->IsSingleEvent()) { isyslog("deleting timer %s",*timer->ToDescr()); Timers.Del(timer); } Timers.SetModified(); } } else return osContinue; } cRecording *recording=GetRecording(item); if(recording) { if(recording->Delete()) { cRecordingUserCommand::InvokeCommand("delete",item->FileName()); myReplayControl::ClearLastReplayed(item->FileName()); Recordings.DelByName(item->FileName()); cOsdMenu::Del(Current()); SetHelpKeys(); Display(); if(!Count()) return osBack; } else Skins.Message(mtError,trVDR("Error while deleting recording!")); } } } return osContinue; } // renames a recording eOSState myMenuRecordings::Rename() { if(HasSubMenu()||Count()==0) return osContinue; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item) { if(item->IsDirectory()) return AddSubMenu(new myMenuRenameRecording(NULL,base,item->Name())); else { cRecording *recording=GetRecording(item); if(recording) return AddSubMenu(new myMenuRenameRecording(recording,NULL,NULL)); } } return osContinue; } // edit details of a recording eOSState myMenuRecordings::Details() { if(HasSubMenu()||Count()==0) return osContinue; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item && !item->IsDirectory()) { cRecording *recording=GetRecording(item); if(recording) return AddSubMenu(new myMenuRecordingDetails(recording)); } return osContinue; } // moves a recording eOSState myMenuRecordings::MoveRec() { if(HasSubMenu() || Count()==0) return osContinue; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item) { myMenuMoveRecording::clearall=false; if(item->IsDirectory()) return AddSubMenu(new myMenuMoveRecording(NULL,base,item->Name())); else { cRecording *recording=GetRecording(item); if(recording) return AddSubMenu(new myMenuMoveRecording(recording,NULL,NULL)); } } return osContinue; } // opens an info screen to a recording eOSState myMenuRecordings::Info(void) { if(HasSubMenu() || Count()==0) return osContinue; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item && !item->IsDirectory()) { cRecording *recording=GetRecording(item); if(mysetup.UseVDRsRecInfoMenu && (!recording || recording && !recording->Info()->Title())) return osContinue; else return AddSubMenu(new myMenuRecordingInfo(recording,true)); } return osContinue; } // execute a command for a recording eOSState myMenuRecordings::Commands(eKeys Key) { if(HasSubMenu() || Count()==0) return osContinue; myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item && !item->IsDirectory()) { cRecording *recording=GetRecording(item); if(recording) { char *parameter=NULL; asprintf(¶meter,"\"%s\"",recording->FileName()); myMenuCommands *menu; eOSState state=AddSubMenu(menu=new myMenuCommands(trVDR("Recording commands"),&RecordingCommands,parameter)); free(parameter); if(Key!=kNone) state=menu->ProcessKey(Key); return state; } } return osContinue; } // change sorting eOSState myMenuRecordings::ChangeSorting() { string path=VideoDirectory; path+="/"; if(base) path+=base; for(SortListItem *item=mySortList->First();item;item=mySortList->Next(item)) { if(path==item->Path()) { mySortList->Del(item); mySortList->WriteConfigFile(); Set(true); Skins.Message(mtInfo,tr("Sort by date"),1); return osContinue; } } mySortList->Add(new SortListItem(path)); mySortList->WriteConfigFile(); Set(true); Skins.Message(mtInfo,tr("Sort by name"),1); return osContinue; } eOSState myMenuRecordings::ProcessKey(eKeys Key) { eOSState state; if(edit) { myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(Key==kRed || Key==kGreen || Key==kYellow || (!item->IsDVD() && Key==kBlue) || Key==kBack) { edit=false; helpkeys=-1; } switch(Key) { case kRed: return Rename(); case kGreen: return MoveRec(); case kYellow: return Delete(); case kBlue: if(item&&!item->IsDVD()) return Details(); else break; case kBack: SetHelpKeys(); default: break; } state=osContinue; } else { state=cOsdMenu::ProcessKey(Key); if(state==osUnknown) { switch(Key) { case kOk: return Play(); case kRed: return (helpkeys>1 && RecordingCommands.Count())?Commands():Play(); case kGreen: return Rewind(); case kYellow: { if(!HasSubMenu()) { myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current()); if(item) { if(item->IsDirectory()) { if(item->GetDirIsMoving()) { string path; if(base) { path=base; path+="~"; path+=item->Name(); } else path=item->Name(); if(Interface->Confirm(tr("Cancel moving?"))) { for(cRecording *rec=Recordings.First();rec;rec=Recordings.Next(rec)) { if(!strncmp(path.c_str(),rec->Name(),path.length())) MoveCutterThread->CancelMove(rec->FileName()); } Set(true); } } else { edit=true; SetHelp(tr("Button$Rename"),tr("Button$Move")); } } else { cRecording *rec=GetRecording(item); if(rec) { #ifdef WITHPINPLUGIN if(cStatus::MsgReplayProtected(rec,item->Name(),base,item->IsDirectory())==true) break; #endif if(MoveCutterThread->IsCutting(rec->FileName())) { if(Interface->Confirm(trVDR("Cancel editing?"))) { MoveCutterThread->CancelCut(rec->FileName()); Set(true); } } else if(MoveCutterThread->IsMoving(rec->FileName())) { if(Interface->Confirm(tr("Cancel moving?"))) { MoveCutterThread->CancelMove(rec->FileName()); Set(true); } } else { edit=true; SetHelp(tr("Button$Rename"),tr("Button$Move"),tr("Button$Delete"),(!item->IsDVD())?tr("Details"):NULL); } } } } } } break; case kBlue: return Info(); case k1...k9: return Commands(Key); case k0: return ChangeSorting(); default: break; } } if(Recordings.StateChanged(recordingsstate) || MoveCutterThread->IsCutterQueueEmpty()) Set(true); if(!Count() && level>0) state=osBack; if(!HasSubMenu() && Key!=kNone) SetHelpKeys(); } return state; }