summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY5
-rw-r--r--Makefile2
-rw-r--r--Makefile-vdr-1.7.332
-rw-r--r--config.c5
-rw-r--r--config.h1
-rw-r--r--duplicates.c54
-rw-r--r--menu.c506
-rw-r--r--menu.h5
-rw-r--r--po/de_DE.po26
-rw-r--r--po/fi_FI.po20
-rw-r--r--po/it_IT.po20
-rw-r--r--visibility.c75
-rw-r--r--visibility.h41
13 files changed, 475 insertions, 287 deletions
diff --git a/HISTORY b/HISTORY
index fda6afc..db60e8a 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,11 @@
VDR Plugin 'duplicates' Revision History
----------------------------------------
+2015-08-31: Version 0.1.0
+
+- Added hiding of duplicate recordings.
+- Updated German translations, thanks to Joerg Bornkessel.
+
2015-06-05: Version 0.0.6
- Added patch from Joerg Bornkessel:
diff --git a/Makefile b/Makefile
index 812ffce..813bdb4 100644
--- a/Makefile
+++ b/Makefile
@@ -53,7 +53,7 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
-OBJS = $(PLUGIN).o menu.o config.o
+OBJS = $(PLUGIN).o menu.o config.o visibility.o
### The main target:
diff --git a/Makefile-vdr-1.7.33 b/Makefile-vdr-1.7.33
index 2eef0b0..7a75f82 100644
--- a/Makefile-vdr-1.7.33
+++ b/Makefile-vdr-1.7.33
@@ -51,7 +51,7 @@ DEFINES += -D_GNU_SOURCE -DPLUGIN_NAME_I18N='"$(PLUGIN)"'
### The object files (add further files here):
-OBJS = $(PLUGIN).o menu.o config.o
+OBJS = $(PLUGIN).o menu.o config.o visibility.o
### The main target:
diff --git a/config.c b/config.c
index 5818ebf..3b27a68 100644
--- a/config.c
+++ b/config.c
@@ -13,13 +13,14 @@
cDuplicatesConfig::cDuplicatesConfig() {
title = 1;
+ hidden = 0;
}
-cDuplicatesConfig::~cDuplicatesConfig() { }
-
+cDuplicatesConfig::~cDuplicatesConfig() {}
bool cDuplicatesConfig::SetupParse(const char *Name, const char *Value) {
if (!strcasecmp(Name, "title")) title = atoi(Value);
+ else if (!strcasecmp(Name, "hidden")) hidden = atoi(Value);
else
return false;
return true;
diff --git a/config.h b/config.h
index 810721e..f1dfacb 100644
--- a/config.h
+++ b/config.h
@@ -13,6 +13,7 @@ class cDuplicatesConfig {
public:
// variables
int title;
+ int hidden;
// member functions
cDuplicatesConfig();
~cDuplicatesConfig();
diff --git a/duplicates.c b/duplicates.c
index acd714f..54c9834 100644
--- a/duplicates.c
+++ b/duplicates.c
@@ -10,8 +10,9 @@
#include <vdr/plugin.h>
#include "config.h"
#include "menu.h"
+#include "visibility.h"
-static const char *VERSION = "0.0.6";
+static const char *VERSION = "0.1.0";
static const char *DESCRIPTION = trNOOP("Shows duplicate recordings");
static const char *MAINMENUENTRY = trNOOP("Duplicate recordings");
@@ -41,102 +42,85 @@ public:
virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
};
-cPluginDuplicates::cPluginDuplicates(void)
-{
+cPluginDuplicates::cPluginDuplicates(void) {
// Initialize any member variables here.
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
}
-cPluginDuplicates::~cPluginDuplicates()
-{
+cPluginDuplicates::~cPluginDuplicates() {
// Clean up after yourself!
}
-const char *cPluginDuplicates::CommandLineHelp(void)
-{
+const char *cPluginDuplicates::CommandLineHelp(void) {
// Return a string that describes all known command line options.
return NULL;
}
-bool cPluginDuplicates::ProcessArgs(int argc, char *argv[])
-{
+bool cPluginDuplicates::ProcessArgs(int argc, char *argv[]) {
// Implement command line argument processing here if applicable.
return true;
}
-bool cPluginDuplicates::Initialize(void)
-{
+bool cPluginDuplicates::Initialize(void) {
// Initialize any background activities the plugin shall perform.
return true;
}
-bool cPluginDuplicates::Start(void)
-{
+bool cPluginDuplicates::Start(void) {
// Start any background activities the plugin shall perform.
return true;
}
-void cPluginDuplicates::Stop(void)
-{
+void cPluginDuplicates::Stop(void) {
// Stop any background activities the plugin is performing.
}
-void cPluginDuplicates::Housekeeping(void)
-{
+void cPluginDuplicates::Housekeeping(void) {
// Perform any cleanup or other regular tasks.
}
-void cPluginDuplicates::MainThreadHook(void)
-{
+void cPluginDuplicates::MainThreadHook(void) {
// Perform actions in the context of the main program thread.
// WARNING: Use with great care - see PLUGINS.html!
}
-cString cPluginDuplicates::Active(void)
-{
+cString cPluginDuplicates::Active(void) {
// Return a message string if shutdown should be postponed
return NULL;
}
-time_t cPluginDuplicates::WakeupTime(void)
-{
+time_t cPluginDuplicates::WakeupTime(void) {
// Return custom wakeup time for shutdown script
return 0;
}
-cOsdObject *cPluginDuplicates::MainMenuAction(void)
-{
+cOsdObject *cPluginDuplicates::MainMenuAction(void) {
// Perform the action when selected from the main VDR menu.
return new cMenuDuplicates();
}
-cMenuSetupPage *cPluginDuplicates::SetupMenu(void)
-{
+cMenuSetupPage *cPluginDuplicates::SetupMenu(void) {
// Return a setup menu in case the plugin supports one.
return new cMenuSetupDuplicates;
}
-bool cPluginDuplicates::SetupParse(const char *Name, const char *Value)
-{
+bool cPluginDuplicates::SetupParse(const char *Name, const char *Value) {
// Parse your own setup parameters and store their values.
return dc.SetupParse(Name, Value);;
}
-bool cPluginDuplicates::Service(const char *Id, void *Data)
-{
+bool cPluginDuplicates::Service(const char *Id, void *Data) {
// Handle custom service requests from other plugins
return false;
}
-const char **cPluginDuplicates::SVDRPHelpPages(void)
-{
+const char **cPluginDuplicates::SVDRPHelpPages(void) {
// Return help text for SVDRP commands this plugin implements
return NULL;
}
-cString cPluginDuplicates::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
-{
+cString cPluginDuplicates::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode) {
// Process SVDRP commands this plugin implements
return NULL;
}
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);
}
diff --git a/menu.h b/menu.h
index 302965f..f364d47 100644
--- a/menu.h
+++ b/menu.h
@@ -32,13 +32,14 @@ private:
eOSState Setup(void);
eOSState Delete(void);
eOSState Info(void);
+ eOSState ToggleHidden(void);
protected:
cRecording *GetRecording(cMenuDuplicateItem *Item);
public:
cMenuDuplicates();
~cMenuDuplicates();
virtual eOSState ProcessKey(eKeys Key);
- };
+};
// --- cMenuSetupDuplicates --------------------------------------------------
@@ -50,6 +51,6 @@ protected:
public:
cMenuSetupDuplicates(cMenuDuplicates *menuDuplicates = NULL);
void SetTitle(const char *Title);
- };
+};
#endif
diff --git a/po/de_DE.po b/po/de_DE.po
index 5d65e1c..7dc70b7 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -5,12 +5,12 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: vdr-duplicates 0.0.6\n"
+"Project-Id-Version: vdr-duplicates 0.1.0\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2011-12-20 18:14+0200\n"
-"PO-Revision-Date: 2015-02-03 11:12+0100\n"
+"POT-Creation-Date: 2015-08-31 11:33+0300\n"
+"PO-Revision-Date: 2015-09-06 17:57+0100\n"
"Last-Translator: Joerg Bornkessel <hd_brummy@gentoo.org>\n"
-"Language-Team: \n"
+"Language-Team: Deutsch\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -25,6 +25,12 @@ msgstr "Zeigt doppelte Aufnahmen an"
msgid "Duplicate recordings"
msgstr "Doppelte Aufnahmen anzeigen"
+msgid "Hide"
+msgstr "Verstecken"
+
+msgid "Unhide"
+msgstr "Aufnahme sichtbar machen"
+
#, c-format
msgid "%d duplicate recordings"
msgstr "%d doppelte Aufnahmen"
@@ -33,5 +39,17 @@ msgstr "%d doppelte Aufnahmen"
msgid "%d recordings without description"
msgstr "%d Aufnahmen ohne Beschreibung"
+msgid "Unhide recording?"
+msgstr "Versteckte Aufnahme sichtbar machen?"
+
+msgid "Hide recording?"
+msgstr "Aufnahme verstecken?"
+
+msgid "Error while setting visibility!"
+msgstr "Fehler bei dem sichtbar machen der Aufnahme!"
+
msgid "Compare title"
msgstr "Vergleiche Titel"
+
+msgid "Show hidden"
+msgstr "Zeige versteckte Aufnahmen"
diff --git a/po/fi_FI.po b/po/fi_FI.po
index ada4590..fd94d10 100644
--- a/po/fi_FI.po
+++ b/po/fi_FI.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-duplicates 0.0.1\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2011-12-20 18:14+0200\n"
+"POT-Creation-Date: 2015-08-31 11:33+0300\n"
"PO-Revision-Date: 2011-12-12 19:57+0300\n"
"Last-Translator: Timo Eskola <timo@tolleri.net>\n"
"Language-Team: Finnish\n"
@@ -24,6 +24,12 @@ msgstr "Näyttää päällekkäiset tallenteet"
msgid "Duplicate recordings"
msgstr "Päällekkäiset tallenteet"
+msgid "Hide"
+msgstr "Piilota"
+
+msgid "Unhide"
+msgstr "Älä piilota"
+
#, c-format
msgid "%d duplicate recordings"
msgstr "%d päällekkäistä tallennetta"
@@ -32,5 +38,17 @@ msgstr "%d päällekkäistä tallennetta"
msgid "%d recordings without description"
msgstr "%d tallennetta ilman kuvausta"
+msgid "Unhide recording?"
+msgstr "Älä piilota tallennetta?"
+
+msgid "Hide recording?"
+msgstr "Piilota tallenne?"
+
+msgid "Error while setting visibility!"
+msgstr "Näkyvyyden asettaminen epäonnistui!"
+
msgid "Compare title"
msgstr "Vertaa otsikkoa"
+
+msgid "Show hidden"
+msgstr "Näytä piilotetut"
diff --git a/po/it_IT.po b/po/it_IT.po
index eaa4c47..6282908 100644
--- a/po/it_IT.po
+++ b/po/it_IT.po
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: vdr-duplicates 0.0.1\n"
"Report-Msgid-Bugs-To: <see README>\n"
-"POT-Creation-Date: 2011-12-20 18:14+0200\n"
+"POT-Creation-Date: 2015-08-31 11:33+0300\n"
"PO-Revision-Date: 2011-06-05 23:37+0100\n"
"Last-Translator: Diego Pierotto <vdr-italian@tiscali.it>\n"
"Language-Team: \n"
@@ -27,6 +27,12 @@ msgstr "Mostra registrazioni duplicate"
msgid "Duplicate recordings"
msgstr "Registrazioni duplicate"
+msgid "Hide"
+msgstr ""
+
+msgid "Unhide"
+msgstr ""
+
#, c-format
msgid "%d duplicate recordings"
msgstr "%d registrazioni duplicate"
@@ -35,5 +41,17 @@ msgstr "%d registrazioni duplicate"
msgid "%d recordings without description"
msgstr "%d registrazioni senza descrizione"
+msgid "Unhide recording?"
+msgstr ""
+
+msgid "Hide recording?"
+msgstr ""
+
+msgid "Error while setting visibility!"
+msgstr ""
+
msgid "Compare title"
msgstr ""
+
+msgid "Show hidden"
+msgstr ""
diff --git a/visibility.c b/visibility.c
new file mode 100644
index 0000000..35bdd97
--- /dev/null
+++ b/visibility.c
@@ -0,0 +1,75 @@
+/*
+ * visibility.c: Visibility classes for duplicates plugin.
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id$
+ */
+
+#include "visibility.h"
+
+// --- cVisibility -----------------------------------------------------------
+
+#ifdef DEBUG_VISIBILITY
+int cVisibility::getCount = 0;
+int cVisibility::readCount = 0;
+int cVisibility::accessCount = 0;
+#endif
+
+cVisibility::cVisibility(const char *fileName) {
+ hiddenFileName = AddDirectory(fileName, "duplicates.hidden");
+ visibility = UNKNOWN;
+}
+
+cVisibility::cVisibility(const cVisibility &Visibility) :
+ hiddenFileName(Visibility.hiddenFileName),
+ visibility(Visibility.visibility) {}
+
+eVisibility cVisibility::Get(void) {
+#ifdef DEBUG_VISIBILITY
+ getCount++;
+#endif
+ return visibility;
+}
+
+void cVisibility::Set(bool visible) {
+ visibility = visible ? VISIBLE : HIDDEN;
+}
+
+eVisibility cVisibility::Read(void) {
+#ifdef DEBUG_VISIBILITY
+ readCount++;
+#endif
+ if (visibility == UNKNOWN) {
+#ifdef DEBUG_VISIBILITY
+ accessCount++;
+#endif
+ visibility = access(hiddenFileName, F_OK) == 0 ? HIDDEN : VISIBLE;
+ }
+ return visibility;
+}
+
+bool cVisibility::Write(bool visible) {
+ if (visible) {
+ if (remove(hiddenFileName) == 0) {
+ visibility = VISIBLE;
+ return true;
+ }
+ } else {
+ FILE *f = fopen(hiddenFileName, "w");
+ if (f) {
+ fclose(f);
+ visibility = HIDDEN;
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifdef DEBUG_VISIBILITY
+void cVisibility::ClearCounters(void) {
+ getCount = 0;
+ readCount = 0;
+ accessCount = 0;
+}
+#endif
diff --git a/visibility.h b/visibility.h
new file mode 100644
index 0000000..dd29bf6
--- /dev/null
+++ b/visibility.h
@@ -0,0 +1,41 @@
+/*
+ * visibility.h: Visibility classes for duplicates plugin.
+ *
+ * See the README file for copyright information and how to reach the author.
+ *
+ * $Id$
+ */
+
+#ifndef _DUPLICATES_VISIBILITY_H
+#define _DUPLICATES_VISIBILITY_H
+
+//#define DEBUG_VISIBILITY
+
+#include <vdr/recording.h>
+
+// --- eVisibility -----------------------------------------------------------
+
+enum eVisibility {UNKNOWN, VISIBLE, HIDDEN};
+
+// --- cVisibility -----------------------------------------------------------
+
+class cVisibility {
+private:
+ cString hiddenFileName;
+ eVisibility visibility;
+public:
+ cVisibility(const char *fileName);
+ cVisibility(const cVisibility &Visibility);
+ eVisibility Get(void);
+ void Set(bool visible);
+ eVisibility Read(void);
+ bool Write(bool visible);
+#ifdef DEBUG_VISIBILITY
+ static int getCount;
+ static int readCount;
+ static int accessCount;
+ static void ClearCounters(void);
+#endif
+};
+
+#endif