summaryrefslogtreecommitdiff
path: root/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'menu.c')
-rw-r--r--menu.c506
1 files changed, 266 insertions, 240 deletions
diff --git a/menu.c b/menu.c
index 2d8c0e6..a605d82 100644
--- a/menu.c
+++ b/menu.c
@@ -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);
}