From d04ad65095872e60613282b584ee10013ea18f44 Mon Sep 17 00:00:00 2001
From: Midas <vdrportal_midas@gmx.de>
Date: Fri, 6 Aug 2010 02:26:00 +0200
Subject: Release 0.0.4. Main menu entry now also deblocks. Replay of recorded
 shows won't stop anymore on block events. Channel +/- work now to change zap
 direction on block events.

---
 HISTORY     |  25 ++++++++++++
 block.c     | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------
 control.c   |  30 +++++++++-----
 event.c     |   3 ++
 event.h     |   4 +-
 i18n.c      |   4 +-
 po/de_DE.po |  33 ++++-----------
 setup.h     |   4 +-
 status.c    |  49 ++++++++++++++--------
 status.h    |   4 +-
 10 files changed, 219 insertions(+), 69 deletions(-)

diff --git a/HISTORY b/HISTORY
index b5f1e09..07f21a0 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,31 @@
 VDR Plugin 'block' Revision History
 -----------------------------------
 
+2010/08/06: Version 0.0.4
+New Features:
+  -The main menu entry now not only adds the title of the current
+   show to the blacklist, but also permanentely removes the title
+   if it is already found in the blacklist.
+
+Bugfixes:
+  -with detection method 'Channel EPG' and while watching
+   a recorded show VDR stopped playback and switched
+   to another channel on a block event. Fixed now.
+
+  -Channel Up and Channel Down keys were not working at all !!
+   I did not notice that because these keys are not configured
+   on my remote and the code seemed pretty much straight-forward. 
+   But it turned out that the key-handling of VDR itself differs 
+   from the one for Up and Down. It was quite hard to find a solution,
+   but finally I found a workaround in sending Up or Down in case the user 
+   presses Channel Up or Channel Down from the plugin code to VDR ;).
+   Subsequently these internally sent Up or Down keys are interpreted 
+   by the plugin in the next main thread loop.
+
+   Thanks to igel who again was the only one reporting this bug ;).
+
+
+**************************************************************************
 2010/06/15: Version 0.0.3
 
 Added experimental parental guidance functions. Please see README 
diff --git a/block.c b/block.c
index def0ebb..be5c1ea 100644
--- a/block.c
+++ b/block.c
@@ -18,13 +18,19 @@
 #include "config.h"
 #include "i18n.h"
 #include "control.h"
+#include "common.h"
+#include <vdr/interface.h>
 
-static const char *VERSION        = "0.0.3";
+static const char *VERSION        = "0.0.4";
 static const char *DESCRIPTION    = trNOOP("Block unwanted shows by EPG title");
-static const char *MAINMENUENTRY  = trNOOP("Block broadcast");
+static const char *MAINMENUENTRY  = trNOOP("(De)Block broadcast");
 
 static int channelnumber=0;
-static char *temptitle=NULL;
+#ifdef LOGGING
+  char *channel_groupsep_string=(char*)"";  
+  char *has_been_checked_string=(char*)"";
+  bool temp_replaying_recording=false;
+#endif
 
 
 class cPluginBlock : public cPlugin {
@@ -50,7 +56,7 @@ cPluginBlock::cPluginBlock(void):
     cPlugin(),
     mStatus(NULL)
 {
-  temptitle=(char*)"";
+  cEventBlock::LastTitle=(char*)"block_dummy_title1";
 }
 
 cPluginBlock::~cPluginBlock()
@@ -86,8 +92,33 @@ cOsdObject *cPluginBlock::MainMenuAction(void)
       return NULL;
 
     const cEvent *present = sched->GetPresentEvent();
-    EventsBlock.Add(new cEventBlock(present->Title()));
-    EventsBlock.Save();
+    
+    if (EventsBlock.Acceptable(present->Title()))
+    {
+     EventsBlock.Add(new cEventBlock(present->Title()));
+     EventsBlock.Save();
+    }
+    else
+    {
+     int index=0;
+     const cEventBlock* blockeventpointer = EventsBlock.First();
+     while (blockeventpointer != NULL)
+     {
+      if (strcmp(blockeventpointer->Pattern(),present->Title())==0)
+       break;
+      index+=1;
+      blockeventpointer=EventsBlock.Next(blockeventpointer);
+     }      
+     cEventBlock *event=EventsBlock.Get(index);
+     if (event!=NULL)
+     {
+      if (Interface->Confirm(tr("Delete keyword?")))
+       EventsBlock.Del(event);
+       EventsBlock.Save();
+     }
+    }
+    
+    cEventBlock::LastTitle="block_dummy_title2";
   }
   return NULL;
 }
@@ -104,27 +135,76 @@ bool cPluginBlock::SetupParse(const char *Name, const char *Value)
 
 void cPluginBlock::MainThreadHook()
 {
+
   if (cSetupBlock::DetectionMethod!=1) return;//other detection method active in setup
-  channelnumber=cDevice::PrimaryDevice()->CurrentChannel();
 
-  if (channelnumber==0) return; //switch in progress
+  if (cEventBlock::ReplayingRecording) //no block events on the underlying channel processed - user watches recording
+  {
+#ifdef LOGGING
+   if (!temp_replaying_recording)
+   {
+    temp_replaying_recording=true;
+    dsyslog("plugin-block: doing nothing because user watches recording");
+   }
+#endif   
+   return;
+  }
+#ifdef LOGGING
+  else
+  {
+   if (temp_replaying_recording)
+   {
+    temp_replaying_recording=false;
+    dsyslog("plugin-block: replay of recording ended. Resuming detection mode.");
+   }
+   return;
+  }
+#endif      
+
+  channelnumber=cDevice::PrimaryDevice()->CurrentChannel();
+  if (channelnumber==0) 
+  {
+#ifdef LOGGING
+   dsyslog("plugin-block: Channel number is 0 => Channel switch on primary device");
+#endif
+   return; //switch in progress
+  }
 
   const cChannel *channel=Channels.GetByNumber(channelnumber);
 
   if (channel != NULL && !channel->GroupSep())
   {
+#ifdef LOGGING
+    char *temp_string;
+    asprintf(&temp_string,"channel: %d channel->GroupSep(): %d", channel->Number(), channel->GroupSep());
+    if (strcmp(temp_string,channel_groupsep_string)!=0)
+    {
+     dsyslog("plugin-block: %s",temp_string);
+     channel_groupsep_string=temp_string;
+    }
+#endif
     cSchedulesLock schedLock;
     const cSchedules *scheds = cSchedules::Schedules(schedLock);
             
     if (scheds == NULL)
     {
+#ifdef LOGGING
+      dsyslog("plugin-block: doing nothing because scheds==NULL");             
+#endif      
       return;
     }
                                     
     const cSchedule *sched = scheds->GetSchedule(channel->GetChannelID());
     if (sched == NULL)
     {
-      return;
+     char *dummy;
+     asprintf(&dummy, "%jd", (intmax_t)time_ms());
+     dsyslog("plugin-block: no EPG data - using dummy for LastTitle: %s",dummy);
+     cEventBlock::LastTitle=(char*)dummy;
+#ifdef LOGGING    
+     dsyslog("plugin-block: doing nothing because sched==NULL");
+#endif
+     return;
     }
                                                                 
     const cEvent *present = sched->GetPresentEvent();
@@ -132,20 +212,46 @@ void cPluginBlock::MainThreadHook()
                                                                         
     if (present == NULL)
     {
+#ifdef LOGGING
+      dsyslog("plugin-block: doing nothing because present==NULL");
+#endif
       return;
     }
                         
     //TODO: check if isrequested is still necessary
 //    if (!cControlBlock::IsRequested() && !EventsBlock.Acceptable(present->Title()))
     const char* title=present->Title();
-    if (strcmp(title,temptitle)==0) return; //current show has already been checked
-    temptitle=(char*)title;
+    if (strcmp(title,"")==0)
+    {
+     char *dummy;
+     asprintf(&dummy, "%jd", (intmax_t)time_ms());
+     dsyslog("plugin-block: no current EPG title - using dummy for LastTitle: %s",title);
+    }
+  
+    if (strcmp(title,cEventBlock::LastTitle)==0) 
+    {
+#ifdef LOGGING
+     char *temp_string;
+     asprintf(&temp_string, "'%s' has already been checked",title);
+     if (strcmp(temp_string,has_been_checked_string)!=0)
+     {
+      dsyslog("plugin-block: %s",temp_string);
+     has_been_checked_string=temp_string;
+     }
+#endif     
+     return; //current show has already been checked
+    }
+#ifdef LOGGING
+    dsyslog("plugin-block: new EPG title detected: '%s' - comparing with '%s'",title, cEventBlock::LastTitle);
+#endif    
+    cEventBlock::LastTitle=(char*)title;
     if (!EventsBlock.Acceptable(title))
     {
-    isyslog("plugin-block: channel %d blocked", channelnumber);
-    cControl::Launch(new cControlBlock(channel, present, follow));
+     isyslog("plugin-block: channel %d blocked", channelnumber);
+     cControl::Launch(new cControlBlock(channel, present, follow));
     }
   }
+  
 }                                                                                                                                                
 
 /*
diff --git a/control.c b/control.c
index 9f805e7..051e456 100644
--- a/control.c
+++ b/control.c
@@ -118,7 +118,9 @@ eOSState cControlBlock::ProcessKey(eKeys Key)
 dsyslog("plugin-block: userint Processing kNone (no user interaction)");
 #endif
 		if (mStart == 0)
+		{
 			Show();
+                }
 		else if (time_ms() - mStart > BlockTimeout()) {
 		direction = mChannel->Number() - cSetupBlock::LastChannel;
 			mSwitch = true;
@@ -126,10 +128,14 @@ dsyslog("plugin-block: userint Processing kNone (no user interaction)");
 		}
 	  return osContinue;
 
-		
-
-	case kUp:
 	case kChanUp:
+                //workaround cause 'normal' code wont work here; vdr does not react on code/destructor here o.O
+                //this is because in case of chan +/- keys have a chance to get eaten by vdr itself
+                cRemote::Put(kUp,true);
+                return osContinue;
+                break;
+        
+	case kUp:                
 #ifdef LOGGING
 dsyslog("plugin-block: userint Processing up event (userrequest)");
 #endif
@@ -137,14 +143,21 @@ dsyslog("plugin-block: userint Processing up event (userrequest)");
 			Show();
 		else 
 		{
-		  mRequested=false;//TODO:necessary? as below
+		  mRequested=false;//TODO:necessary? as above
 		  direction = 1;
 		  mSwitch = true;
 		  return osEnd;
 		}
 	        break;
-	case kDown:
+
 	case kChanDn:
+                //workaround cause 'normal' code wont work here; vdr does not react on code/destructor here o.O
+                //this is because in case of chan +/- keys have a chance to get eaten by vdr itself
+                cRemote::Put(kDown,true);
+                return osContinue;
+                break;
+        
+	case kDown:
 #ifdef LOGGING
 dsyslog("plugin-block: userint Processing down event (userrequest)");
 #endif
@@ -152,16 +165,15 @@ dsyslog("plugin-block: userint Processing down event (userrequest)");
 			Show();
 		else 
 		{
-		  mRequested=false;//TODO:necessary? as below
+		  mRequested=false;//TODO:necessary? as above
 		  direction = -1;
 		  mSwitch = true;
 		  return osEnd;
 		}
 	        break;
 
-
-  default:
-    break;
+        default:
+                break;
   }
   return osContinue;
 }
diff --git a/event.c b/event.c
index d06040a..4ec0b47 100644
--- a/event.c
+++ b/event.c
@@ -17,6 +17,9 @@ static char *duptolower(const char *s) {
 	return c;
 }
 
+const char* cEventBlock::LastTitle="block_dummy_title3";
+const bool* cEventBlock::ReplayingRecording=false;
+
 cEventsBlock EventsBlock;
 
 cEventBlock::cEventBlock(void):
diff --git a/event.h b/event.h
index 3b8c34c..a205aab 100644
--- a/event.h
+++ b/event.h
@@ -40,7 +40,9 @@ public:
   bool Parse(char *s);
 	bool Compile(void);
   bool Save(FILE *f);
-
+  static const char *LastTitle;
+  static const bool *ReplayingRecording;
+    
   const char *Pattern(void) const { return mPattern; }
 };
 
diff --git a/i18n.c b/i18n.c
index f0afccf..a950306 100644
--- a/i18n.c
+++ b/i18n.c
@@ -32,8 +32,8 @@ const tI18nPhrase Phrases[] = {
     "Dansk",
   },
 	*/
-  { "Block broadcast",
-    "Sendung sperren",
+  { "(De)Block broadcast",
+    "Sendung (ent)sperren",
     "",
     "",
     "",
diff --git a/po/de_DE.po b/po/de_DE.po
index b915f02..da05da3 100644
--- a/po/de_DE.po
+++ b/po/de_DE.po
@@ -6,79 +6,62 @@
 msgid ""
 msgstr ""
 "Project-Id-Version: VDR 1.5.7\n"
-"Report-Msgid-Bugs-To: vdrportal_midas at gmx dot de\n"
-"POT-Creation-Date: 2010-06-10 21:29+0200\n"
-"PO-Revision-Date: 2010-06-10 21:29+0200\n"
+"Report-Msgid-Bugs-To: <vdrportal_midas at gmx dot de>\n"
+"POT-Creation-Date: 2010-08-03 05:23+0200\n"
+"PO-Revision-Date: 2010-08-03 05:23+0200\n"
 "Last-Translator: Klaus Schmidinger <kls@cadsoft.de>\n"
 "Language-Team: <vdr@linuxtv.org>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=ISO-8859-15\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: block.c:23
 msgid "Block unwanted shows by EPG title"
 msgstr "Sendung/EPG-Titel sperren"
 
-#: block.c:24
-msgid "Block broadcast"
-msgstr "Sendung sperren"
+msgid "(De)Block broadcast"
+msgstr "Sendung (ent)sperren"
+
+msgid "Delete keyword?"
+msgstr "Schlagwort l�schen?"
 
-#: control.c:79
 msgid "Current show blocked!"
 msgstr "Aktuelle Sendung gesperrt!"
 
-#: control.c:109
 msgid "Permission denied!"
 msgstr "Aktion nicht erlaubt!"
 
-#: event.c:27
 msgid "New Entry"
 msgstr "Neuer Eintrag"
 
-#: setup.c:26
 msgid "Hide Mainmenu Entry"
 msgstr "Hauptmen�eintrag verstecken"
 
-#: setup.c:27
 msgid "Message Timeout [s]"
 msgstr "Wartezeit bis Umschalten [s]"
 
-#: setup.c:29
 msgid "On Switch"
 msgstr "Beim Umschalten"
 
-#: setup.c:30
 msgid "Channel EPG"
 msgstr "Kanal EPG"
 
-#: setup.c:32
 msgid "Detection Method"
 msgstr "Methode"
 
-#: setup.c:33
 msgid "Ok deblocks temporarily"
 msgstr "Ok entsperrt tempor�r"
 
-#: setup.c:47
 msgid "--- Keywords -------------------------------------------------------------------"
 msgstr "--- Schlagworte ----------------------------------------------------------------"
 
-#: setup.c:120
-msgid "Delete keyword?"
-msgstr "Schlagwort l�schen?"
-
-#: setup.c:170
 msgid "Pattern"
 msgstr "Suchmuster"
 
-#: setup.c:171
 msgid "Regular Expression"
 msgstr "Regul�rer Ausdruck"
 
-#: setup.c:172
 msgid "Ignore Case"
 msgstr "Gro�/Kleinschreibung ignorieren"
 
-#: setup.c:183
 msgid "Malformed regular expression!"
 msgstr "Ung�ltiger regul�rer Ausdruck!"
diff --git a/setup.h b/setup.h
index 4a3cbef..fc5f38e 100644
--- a/setup.h
+++ b/setup.h
@@ -15,10 +15,10 @@
 
 class cMenuSetupBlock : public cMenuSetupPage {
 private:
-  cEventsBlock mEventsData;
+  cEventsBlock mEventsData;  
   cSetupBlock  mSetupData;
   const char *DetectionMethods[2];
-  
+
 protected:
   virtual void Store(void);
   virtual eOSState ProcessKey(eKeys Key);
diff --git a/status.c b/status.c
index c8341b4..0a0ae22 100644
--- a/status.c
+++ b/status.c
@@ -19,35 +19,30 @@ cStatusBlock::cStatusBlock(void):
 
 void cStatusBlock::ChannelSwitch(const cDevice *Device, int ChannelNumber)
 {
+  int current_channel=cDevice::CurrentChannel();
+  int device_number=Device->DeviceNumber();  
+
   if (cSetupBlock::LastChannel==0)
   {
 #ifdef LOGGING
     dsyslog("plugin-block: ChannelSwitch returned because LastChannel=0");
 #endif    
-    cSetupBlock::LastChannel=cDevice::CurrentChannel();
+    cSetupBlock::LastChannel=current_channel;
     return;
   }
   if (ChannelNumber==0)
   {
 #ifdef LOGGING
-    dsyslog("plugin-block: ChannelSwitch returned because ChannelNumber=0 (switch in progess)");
+    dsyslog("plugin-block: ChannelSwitch: device switching - setting LastChannel to %d",current_channel);
 #endif
-    cSetupBlock::LastChannel=cDevice::CurrentChannel();
+    cSetupBlock::LastChannel=current_channel;
     return; //Switch in progress;
   }
-    
-  if (cSetupBlock::DetectionMethod!=0) 
-  {
-#ifdef LOGGING
-    dsyslog("plugin-block: ChannelSwitch returned because other detection method active");
-#endif
-    return;
-  }
 
 #ifdef LOGGING
-  dsyslog("plugin-block: cStatusBlock was informed about channel switch at device %d, channel no %d",Device->DeviceNumber(),ChannelNumber);
-  dsyslog("plugin-block: cDevice::CurrentChannel %d",cDevice::CurrentChannel());
-  dsyslog("plugin-block: Device %d, ActualDevice %d, primary Device %d",Device->DeviceNumber(),cDevice::ActualDevice()->DeviceNumber(),cDevice::PrimaryDevice()->DeviceNumber());
+  dsyslog("plugin-block: cStatusBlock noticed channel switch at device %d, channel no %d",device_number,ChannelNumber);
+  dsyslog("plugin-block: cDevice::CurrentChannel %d",current_channel);
+  dsyslog("plugin-block: Device %d, ActualDevice %d, primary Device %d",device_number,cDevice::ActualDevice()->DeviceNumber(),cDevice::PrimaryDevice()->DeviceNumber());
   for (int ii=0;ii<cDevice::NumDevices();ii++)
   {
     cDevice* tmpdev=cDevice::GetDevice(ii);
@@ -55,6 +50,13 @@ void cStatusBlock::ChannelSwitch(const cDevice *Device, int ChannelNumber)
   }
 #endif
 
+  if (cSetupBlock::DetectionMethod!=0) 
+  {
+#ifdef LOGGING
+    dsyslog("plugin-block: ChannelSwitch returned because other detection method active");
+#endif
+    return;
+  }
 
   if (Device->DeviceNumber()!=cDevice::PrimaryDevice()->DeviceNumber())
   {
@@ -64,7 +66,7 @@ void cStatusBlock::ChannelSwitch(const cDevice *Device, int ChannelNumber)
     return;
   }
 
-  if (ChannelNumber!=cDevice::CurrentChannel())
+  if (ChannelNumber!=current_channel)
   {
 #ifdef LOGGING
     dsyslog("plugin-block: Did nothing because ChannelNumber!=CurrentChannel (switch still in progress)");
@@ -89,7 +91,7 @@ void cStatusBlock::ChannelSwitch(const cDevice *Device, int ChannelNumber)
     {
 #ifdef LOGGING
       dsyslog("plugin-block: ChannelSwitch: scheds=null caused return");
-#endif      
+#endif
       return;
     }
 
@@ -116,5 +118,20 @@ void cStatusBlock::ChannelSwitch(const cDevice *Device, int ChannelNumber)
       cControl::Launch(new cControlBlock(channel, present, follow));
     }
   }
+  
 }
   
+void cStatusBlock::Replaying(const cControl *Control,
+                                      const char *Name,
+                                      const char *FileName, bool On)
+{
+ char *replaystate;
+ if (On) replaystate=(char*)"started";
+ else replaystate=(char*)"stopped";
+ cEventBlock::ReplayingRecording=(bool*)On;
+#ifdef LOGGING
+ dsyslog("plugin-block: cStatusBlock: Replay: '%s' from '%s'",Name,FileName);
+#endif                                                                            
+}
+
+                                                                              
\ No newline at end of file
diff --git a/status.h b/status.h
index 0051c28..76507ff 100644
--- a/status.h
+++ b/status.h
@@ -14,7 +14,9 @@ class cStatusBlock : public cStatus {
 
 protected:
   virtual void ChannelSwitch(const cDevice *Device, int ChannelNumber);
-
+  virtual void Replaying(const cControl *Control,
+                         const char *Name,
+                         const char *FileName, bool On);
 public:
   cStatusBlock(void);
 };
-- 
cgit v1.2.3