diff options
Diffstat (limited to 'menu.c')
-rw-r--r-- | menu.c | 506 |
1 files changed, 266 insertions, 240 deletions
@@ -9,14 +9,15 @@ */ #include "menu.h" +#include "visibility.h" #include <vdr/menu.h> #include <vdr/status.h> #include <vdr/interface.h> +#include <sys/time.h> #include <string> #include <sstream> -static inline cOsdItem *SeparatorItem(const char *Label) -{ +static inline cOsdItem *SeparatorItem(const char *Label) { cOsdItem *Item = new cOsdItem(cString::sprintf("----- %s -----", Label)); Item->SetSelectable(false); return Item; @@ -27,13 +28,11 @@ static inline cOsdItem *SeparatorItem(const char *Label) class cDuplicatesReplayControl : public cReplayControl { public: virtual eOSState ProcessKey(eKeys Key); - }; +}; -eOSState cDuplicatesReplayControl::ProcessKey(eKeys Key) -{ +eOSState cDuplicatesReplayControl::ProcessKey(eKeys Key) { eOSState state = cReplayControl::ProcessKey(Key); - if (state == osRecordings) - { + if (state == osRecordings) { cControl::Shutdown(); cRemote::CallPlugin("duplicates"); return osContinue; @@ -53,8 +52,7 @@ public: }; cMenuDuplicate::cMenuDuplicate(const cRecording *Recording) -:cOsdMenu(trVDR("Recording info")) -{ +:cOsdMenu(trVDR("Recording info")) { #if VDRVERSNUM >= 10728 SetMenuCategory(mcRecording); #endif @@ -62,8 +60,7 @@ cMenuDuplicate::cMenuDuplicate(const cRecording *Recording) SetHelp(trVDR("Button$Play")); } -void cMenuDuplicate::Display(void) -{ +void cMenuDuplicate::Display(void) { cOsdMenu::Display(); DisplayMenu()->SetRecording(recording); if (recording->Info()->Description()) @@ -86,7 +83,7 @@ eOSState cMenuDuplicate::ProcessKey(eKeys Key) return osContinue; case kInfo: return osBack; default: break; - } +} eOSState state = cOsdMenu::ProcessKey(Key); @@ -96,58 +93,32 @@ eOSState cMenuDuplicate::ProcessKey(eKeys Key) case kRed: cRemote::Put(Key, true); case kOk: return osBack; default: break; - } } + } return state; } -// --- cMenuDuplicateItem ---------------------------------------------------- - -class cMenuDuplicateItem : public cOsdItem { -private: - char *fileName; -public: - cMenuDuplicateItem(const cRecording *Recording); - ~cMenuDuplicateItem(); - const char *FileName(void) { return fileName; } - }; - -cMenuDuplicateItem::cMenuDuplicateItem(const cRecording *Recording) -{ - fileName = strdup(Recording->FileName()); -#if defined LIEMIKUUTIO && LIEMIKUUTIO < 131 - SetText(Recording->Title('\t', true, -1, false)); -#else - SetText(Recording->Title('\t', true)); -#endif -} - -cMenuDuplicateItem::~cMenuDuplicateItem() -{ - free(fileName); -} - // --- cDuplicateRecording ------------------------------------------------------- class cDuplicateRecording : public cListObject { private: const cRecording *recording; bool checked; -protected: + cVisibility visibility; std::string title; std::string description; public: cDuplicateRecording(const cRecording *Recording); - ~cDuplicateRecording(); - const cRecording *Recording(void); + cDuplicateRecording(const cDuplicateRecording &DuplicateRecording); + const cRecording *Recording(void) const { return recording; } bool HasDescription(void) const { return ! description.empty(); } - bool IsDuplicate(const cDuplicateRecording *DuplicateRecording); + bool IsDuplicate(cDuplicateRecording *DuplicateRecording); void SetChecked(bool chkd = true) { checked = chkd; } bool Checked() { return checked; } - }; + cVisibility Visibility() { return visibility; } +}; -cDuplicateRecording::cDuplicateRecording(const cRecording *Recording) -{ +cDuplicateRecording::cDuplicateRecording(const cRecording *Recording) : visibility(Recording->FileName()) { recording = Recording; checked = false; if (dc.title && recording->Info()->Title()) @@ -174,39 +145,59 @@ cDuplicateRecording::cDuplicateRecording(const cRecording *Recording) } } -cDuplicateRecording::~cDuplicateRecording() -{ - title.clear(); - description.clear(); -} - -const cRecording *cDuplicateRecording::Recording(void) -{ - return recording; -} +cDuplicateRecording::cDuplicateRecording(const cDuplicateRecording &DuplicateRecording) : + recording(DuplicateRecording.recording), + checked(DuplicateRecording.checked), + visibility(DuplicateRecording.visibility), + title(DuplicateRecording.title), + description(DuplicateRecording.description) {} -bool cDuplicateRecording::IsDuplicate(const cDuplicateRecording *DuplicateRecording) -{ +bool cDuplicateRecording::IsDuplicate(cDuplicateRecording *DuplicateRecording) { if (!HasDescription() || !DuplicateRecording->HasDescription()) - return false; + return false; size_t found; - if (dc.title) - { - found = title.size() > DuplicateRecording->title.size() ? - title.find(DuplicateRecording->title) : DuplicateRecording->title.find(title); - if (found == std::string::npos) - return false; + if (dc.title) { + found = title.size() > DuplicateRecording->title.size() ? + title.find(DuplicateRecording->title) : DuplicateRecording->title.find(title); + if (found == std::string::npos) + return false; } found = description.size() > DuplicateRecording->description.size() ? description.find(DuplicateRecording->description) : DuplicateRecording->description.find(description); if (found != std::string::npos) - return true; + return true; return false; } +// --- cMenuDuplicateItem ---------------------------------------------------- + +class cMenuDuplicateItem : public cOsdItem { +private: + char *fileName; + cVisibility visibility; +public: + cMenuDuplicateItem(cDuplicateRecording *DuplicateRecording); + ~cMenuDuplicateItem(); + const char *FileName(void) { return fileName; } + cVisibility Visibility() { return visibility; } +}; + +cMenuDuplicateItem::cMenuDuplicateItem(cDuplicateRecording *DuplicateRecording) : visibility(DuplicateRecording->Visibility()) { + fileName = strdup(DuplicateRecording->Recording()->FileName()); +#if defined LIEMIKUUTIO && LIEMIKUUTIO < 131 + SetText(DuplicateRecording->Recording()->Title('\t', true, -1, false)); +#else + SetText(DuplicateRecording->Recording()->Title('\t', true)); +#endif +} + +cMenuDuplicateItem::~cMenuDuplicateItem() { + free(fileName); +} + // --- cMenuDuplicates ------------------------------------------------------- cMenuDuplicates::cMenuDuplicates() @@ -226,255 +217,290 @@ cMenuDuplicates::cMenuDuplicates() SetHelpKeys(); } -cMenuDuplicates::~cMenuDuplicates() -{ +cMenuDuplicates::~cMenuDuplicates() { helpKeys = -1; } -void cMenuDuplicates::SetHelpKeys(void) -{ +void cMenuDuplicates::SetHelpKeys(void) { cMenuDuplicateItem *ri = (cMenuDuplicateItem *)Get(Current()); int NewHelpKeys = 0; if (ri) { - NewHelpKeys = 1; - cRecording *recording = GetRecording(ri); - if (recording && recording->Info()->Title()) - NewHelpKeys = 2; - } + NewHelpKeys = 1; + if (ri->Visibility().Read() == HIDDEN) + NewHelpKeys = 2; + } if (NewHelpKeys != helpKeys) { - switch (NewHelpKeys) { - case 0: SetHelp(NULL); break; - case 1: - case 2: SetHelp(trVDR("Button$Play"), trVDR("Setup"), trVDR("Button$Delete"), NewHelpKeys == 2 ? trVDR("Button$Info") : NULL); - default: ; - } - helpKeys = NewHelpKeys; - } + switch (NewHelpKeys) { + case 0: SetHelp(NULL); break; + case 1: + case 2: SetHelp(trVDR("Button$Play"), trVDR("Setup"), trVDR("Button$Delete"), NewHelpKeys == 1 ? tr("Hide") : tr("Unhide")); + default: ; + } + helpKeys = NewHelpKeys; + } } -void cMenuDuplicates::Set(bool Refresh) -{ +void cMenuDuplicates::Set(bool Refresh) { + struct timeval startTime, stopTime; + gettimeofday(&startTime, NULL); +#ifdef DEBUG_VISIBILITY + cVisibility::ClearCounters(); + int isDuplicateCount = 0, menuDuplicateItemCount = 0; +#endif const char *CurrentRecording = NULL; int currentIndex = -1; if (Refresh) - currentIndex = Current(); + currentIndex = Current(); else - CurrentRecording = cReplayControl::LastReplayed(); - cList<cDuplicateRecording> *descriptionless = new cList<cDuplicateRecording>; - cList<cDuplicateRecording> *recordings = new cList<cDuplicateRecording>; - cThreadLock RecordingsLock(&Recordings); + CurrentRecording = cReplayControl::LastReplayed(); + cList<cDuplicateRecording> descriptionless; + cList<cDuplicateRecording> recordings; Clear(); - Recordings.Sort(); - for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { + { + cThreadLock RecordingsLock(&Recordings); + Recordings.Sort(); + for (cRecording *recording = Recordings.First(); recording; recording = Recordings.Next(recording)) { cDuplicateRecording *Item = new cDuplicateRecording(recording); if (Item->HasDescription()) - recordings->Add(Item); - else - descriptionless->Add(Item); + recordings.Add(Item); + else if (dc.hidden || Item->Visibility().Read() != HIDDEN) + descriptionless.Add(Item); } - for (cDuplicateRecording *recording = recordings->First(); recording; recording = recordings->Next(recording)) { - if (!recording->Checked()) { - recording->SetChecked(); - cList<cDuplicateRecording> *duplicates = new cList<cDuplicateRecording>; - duplicates->Add(new cDuplicateRecording(recording->Recording())); - for (cDuplicateRecording *compare = recordings->First(); compare; compare = recordings->Next(compare)) { - if (!compare->Checked() && recording->IsDuplicate(compare)) { - duplicates->Add(new cDuplicateRecording(compare->Recording())); - compare->SetChecked(); - } - } - if (duplicates->Count() > 1) { - Add(SeparatorItem(cString::sprintf(tr("%d duplicate recordings"), duplicates->Count()))); - for (cDuplicateRecording *DuplicateRecording = duplicates->First(); DuplicateRecording; DuplicateRecording = duplicates->Next(DuplicateRecording)) { - cMenuDuplicateItem *Item = new cMenuDuplicateItem(DuplicateRecording->Recording()); - if (*Item->Text()) - { - Add(Item); - if (CurrentRecording && strcmp(CurrentRecording, Item->FileName()) == 0) - SetCurrent(Item); - } - else - delete Item; - } - } - delete duplicates; - } + } + for (cDuplicateRecording *recording = recordings.First(); recording; recording = recordings.Next(recording)) { + if (!recording->Checked()) { + recording->SetChecked(); + cList<cDuplicateRecording> duplicates; + duplicates.Add(new cDuplicateRecording(*recording)); + for (cDuplicateRecording *compare = recordings.First(); compare; compare = recordings.Next(compare)) { + if (!compare->Checked()) { +#ifdef DEBUG_VISIBILITY + isDuplicateCount++; +#endif + if (recording->IsDuplicate(compare)) { + duplicates.Add(new cDuplicateRecording(*compare)); + compare->SetChecked(); + } + } } - if (descriptionless->Count() > 0) - Add(SeparatorItem(cString::sprintf(tr("%d recordings without description"), descriptionless->Count()))); - for (cDuplicateRecording *DescriptionlessRecording = descriptionless->First(); DescriptionlessRecording; DescriptionlessRecording = descriptionless->Next(DescriptionlessRecording)) { - cMenuDuplicateItem *Item = new cMenuDuplicateItem(DescriptionlessRecording->Recording()); - if (*Item->Text()) - { - Add(Item); - if (CurrentRecording && strcmp(CurrentRecording, Item->FileName()) == 0) - SetCurrent(Item); - } - else - delete Item; + int count = duplicates.Count(); + if (!dc.hidden && count > 1) { + for (cDuplicateRecording *DuplicateRecording = duplicates.First(); DuplicateRecording; DuplicateRecording = duplicates.Next(DuplicateRecording)) { + if (DuplicateRecording->Visibility().Read() == HIDDEN) + count--; + } } - delete descriptionless; - delete recordings; + if (count > 1) { + Add(SeparatorItem(cString::sprintf(tr("%d duplicate recordings"), duplicates.Count()))); + for (cDuplicateRecording *DuplicateRecording = duplicates.First(); DuplicateRecording; DuplicateRecording = duplicates.Next(DuplicateRecording)) { + if (dc.hidden || DuplicateRecording->Visibility().Read() != HIDDEN) { + cMenuDuplicateItem *Item = new cMenuDuplicateItem(DuplicateRecording); +#ifdef DEBUG_VISIBILITY + menuDuplicateItemCount++; +#endif + if (*Item->Text()) { + Add(Item); + if (CurrentRecording && strcmp(CurrentRecording, Item->FileName()) == 0) + SetCurrent(Item); + } else + delete Item; + } + } + } + } + } + if (descriptionless.Count() > 0) + Add(SeparatorItem(cString::sprintf(tr("%d recordings without description"), descriptionless.Count()))); + for (cDuplicateRecording *DescriptionlessRecording = descriptionless.First(); DescriptionlessRecording; DescriptionlessRecording = descriptionless.Next(DescriptionlessRecording)) { + cMenuDuplicateItem *Item = new cMenuDuplicateItem(DescriptionlessRecording); +#ifdef DEBUG_VISIBILITY + menuDuplicateItemCount++; +#endif + if (*Item->Text()) { + Add(Item); + if (CurrentRecording && strcmp(CurrentRecording, Item->FileName()) == 0) + SetCurrent(Item); + } else + delete Item; + } if (Count() == 0) - Add(SeparatorItem(cString::sprintf(tr("%d duplicate recordings"), 0))); + Add(SeparatorItem(cString::sprintf(tr("%d duplicate recordings"), 0))); if (Refresh) { - if (currentIndex >= 0) { - if(currentIndex >= Count()) - currentIndex = Count() - 1; - cOsdItem *current = Get(currentIndex); - while (current) { - if (current->Selectable()) { - SetCurrent(current); - break; - } - current = Prev(current); - } + if (currentIndex >= 0) { + if(currentIndex >= Count()) + currentIndex = Count() - 1; + cOsdItem *current = Get(currentIndex); + while (current) { + if (current->Selectable()) { + SetCurrent(current); + break; } - Display(); - } + current = Prev(current); + } + } + Display(); + } + gettimeofday(&stopTime, NULL); + double seconds = (((long long)stopTime.tv_sec * 1000000 + stopTime.tv_usec) - ((long long)startTime.tv_sec * 1000000 + startTime.tv_usec)) / 1000000.0; +#ifdef DEBUG_VISIBILITY + dsyslog("duplicates: Displaying of duplicates took %.2f seconds, is duplicate count %d, get count %d, read count %d, access count %d, duplicate item count %d.", + seconds, isDuplicateCount, cVisibility::getCount, cVisibility::readCount, cVisibility::accessCount, menuDuplicateItemCount); +#else + dsyslog("duplicates: Displaying of duplicates took %.2f seconds.", seconds); +#endif } -cRecording *cMenuDuplicates::GetRecording(cMenuDuplicateItem *Item) -{ +cRecording *cMenuDuplicates::GetRecording(cMenuDuplicateItem *Item) { cRecording *recording = Recordings.GetByName(Item->FileName()); if (!recording) - Skins.Message(mtError, trVDR("Error while accessing recording!")); + Skins.Message(mtError, trVDR("Error while accessing recording!")); return recording; } -eOSState cMenuDuplicates::Delete(void) -{ +eOSState cMenuDuplicates::Delete(void) { if (HasSubMenu() || Count() == 0) - return osContinue; + return osContinue; cMenuDuplicateItem *ri = (cMenuDuplicateItem *)Get(Current()); if (ri) { - if (Interface->Confirm(trVDR("Delete recording?"))) { - cRecordControl *rc = cRecordControls::GetRecordControl(ri->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(ri); - if (recording) { - if (cReplayControl::NowReplaying() && strcmp(cReplayControl::NowReplaying(), ri->FileName()) == 0) - cControl::Shutdown(); - if (recording->Delete()) { - cReplayControl::ClearLastReplayed(ri->FileName()); - Recordings.DelByName(ri->FileName()); - Set(true); - SetHelpKeys(); - } - else - Skins.Message(mtError, trVDR("Error while deleting recording!")); - } - } - } + if (Interface->Confirm(trVDR("Delete recording?"))) { + cRecordControl *rc = cRecordControls::GetRecordControl(ri->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(ri); + if (recording) { + if (cReplayControl::NowReplaying() && strcmp(cReplayControl::NowReplaying(), ri->FileName()) == 0) + cControl::Shutdown(); + if (recording->Delete()) { + cReplayControl::ClearLastReplayed(ri->FileName()); + Recordings.DelByName(ri->FileName()); + Recordings.StateChanged(recordingsState); // update state after deletion + Set(true); + SetHelpKeys(); + } else + Skins.Message(mtError, trVDR("Error while deleting recording!")); + } + } + } return osContinue; } -eOSState cMenuDuplicates::Play(void) -{ +eOSState cMenuDuplicates::Play(void) { if (HasSubMenu() || Count() == 0) - return osContinue; + return osContinue; cMenuDuplicateItem *ri = (cMenuDuplicateItem *)Get(Current()); if (ri) { - cRecording *recording = GetRecording(ri); - if (recording) { + cRecording *recording = GetRecording(ri); + if (recording) { #if VDRVERSNUM >= 10728 - cDuplicatesReplayControl::SetRecording(recording->FileName()); + cDuplicatesReplayControl::SetRecording(recording->FileName()); #else - cDuplicatesReplayControl::SetRecording(recording->FileName(), recording->Title()); + cDuplicatesReplayControl::SetRecording(recording->FileName(), recording->Title()); #endif - cControl::Shutdown(); - cControl::Launch(new cDuplicatesReplayControl); - return osEnd; - } - } + cControl::Shutdown(); + cControl::Launch(new cDuplicatesReplayControl); + return osEnd; + } + } return osContinue; } -eOSState cMenuDuplicates::Setup(void) -{ +eOSState cMenuDuplicates::Setup(void) { if (HasSubMenu()) - return osContinue; + return osContinue; cMenuSetupDuplicates *setupMenu = new cMenuSetupDuplicates(this); setupMenu->SetTitle(cString::sprintf("%s - %s", tr("Duplicate recordings"), trVDR("Setup"))); return AddSubMenu(setupMenu); } -eOSState cMenuDuplicates::Info(void) -{ +eOSState cMenuDuplicates::Info(void) { if (HasSubMenu() || Count() == 0) - return osContinue; + return osContinue; cMenuDuplicateItem *ri = (cMenuDuplicateItem *)Get(Current()); if (ri) { - cRecording *recording = GetRecording(ri); - if (recording && recording->Info()->Title()) - return AddSubMenu(new cMenuDuplicate(recording)); - } + cRecording *recording = GetRecording(ri); + if (recording && recording->Info()->Title()) + return AddSubMenu(new cMenuDuplicate(recording)); + } return osContinue; } -eOSState cMenuDuplicates::ProcessKey(eKeys Key) -{ +eOSState cMenuDuplicates::ToggleHidden(void) { + if (HasSubMenu() || Count() == 0) + return osContinue; + cMenuDuplicateItem *ri = (cMenuDuplicateItem *)Get(Current()); + if (ri) { + bool hidden = ri->Visibility().Read() == HIDDEN; + if (Interface->Confirm(hidden ? tr("Unhide recording?") : tr("Hide recording?"))) { + if (ri->Visibility().Write(hidden)) { + if (dc.hidden) + ri->Visibility().Set(!hidden); + else + Set(true); + SetHelpKeys(); + } else + Skins.Message(mtError, tr("Error while setting visibility!")); + } + } + return osContinue; +} + +eOSState cMenuDuplicates::ProcessKey(eKeys Key) { eOSState state = cOsdMenu::ProcessKey(Key); if (state == osUnknown) { - switch (Key) { - case kPlay: - case kRed: return Play(); - case kGreen: return Setup(); - case kYellow: return Delete(); - case kOk: - case kInfo: - case kBlue: return Info(); - case kNone: if (Recordings.StateChanged(recordingsState)) - Set(true); - break; - default: break; - } - } + switch (Key) { + case kPlay: + case kRed: return Play(); + case kGreen: return Setup(); + case kYellow: return Delete(); + case kOk: + case kInfo: return Info(); + case kBlue: return ToggleHidden(); + case kNone: if (Recordings.StateChanged(recordingsState)) + Set(true); + break; + default: break; + } + } if (!HasSubMenu()) { - if (Key != kNone) - SetHelpKeys(); - } + if (Key != kNone) + SetHelpKeys(); + } return state; } // --- cMenuSetupDuplicates -------------------------------------------------- -cMenuSetupDuplicates::cMenuSetupDuplicates(cMenuDuplicates *MenuDuplicates) -{ +cMenuSetupDuplicates::cMenuSetupDuplicates(cMenuDuplicates *MenuDuplicates) { #if VDRVERSNUM >= 10728 SetMenuCategory(mcSetup); #endif menuDuplicates = MenuDuplicates; Add(new cMenuEditBoolItem(tr("Compare title"), &dc.title)); + Add(new cMenuEditBoolItem(tr("Show hidden"), &dc.hidden)); } -void cMenuSetupDuplicates::Store(void) -{ +void cMenuSetupDuplicates::Store(void) { dc.Store(); - if (menuDuplicates != NULL) - { - menuDuplicates->SetCurrent(NULL); - menuDuplicates->Set(); + if (menuDuplicates != NULL) { + menuDuplicates->SetCurrent(NULL); + menuDuplicates->Set(); } } -void cMenuSetupDuplicates::SetTitle(const char *Title) -{ +void cMenuSetupDuplicates::SetTitle(const char *Title) { cMenuSetupPage::SetTitle(Title); } |