[SCM] vdr packaging repository branch, e-tobi, updated. debian/1.7.21-1_ctvdr3-19-g0495185

etobi git at e-tobi.net
Mon Dec 12 21:27:25 UTC 2011


The following commit has been merged in the e-tobi branch:
commit 3c29c27a2ddb9522ef2ada16d9267550c4cfcbe1
Author: etobi <git at e-tobi.net>
Date:   Sat Dec 10 22:34:29 2011 +0100

    Upgraded opt-20_liemikuutio.dpatch to version 1.33

diff --git a/debian/.vdr-patches.multipatch b/debian/.vdr-patches.multipatch
index 28c06de..caf163d 100644
--- a/debian/.vdr-patches.multipatch
+++ b/debian/.vdr-patches.multipatch
@@ -7,7 +7,7 @@ debian/patches/06_default_svdrp_port_0.dpatch:653e14e8ab093c456f9bbd8faa5e1ff7
 debian/patches/82_valgrind.dpatch:503ddba49c243fff798a36a1c12bb5ae
 debian/patches/opt-42-x_MainMenuHooks.dpatch:1c4c782b5c88c4f0408890a5f50b217b
 debian/patches/opt-44_rotor.dpatch:43c8707dac3db0702183c91d0e22874a
-debian/patches/opt-20_liemikuutio.dpatch:b1d074dc381527e29db4a5ad48c8fa07
+debian/patches/opt-20_liemikuutio.dpatch:1e05ed4920386b639efdda6832246766
 debian/patches/opt-21_internal-cam-devices.dpatch:7bbaad57abb1ae2995b85d9f1a1fd23f
 debian/patches/opt-41-x_timer-info.dpatch:04511ae02243eb1bab94f3f45b59e574
 debian/patches/opt-24_jumpplay.dpatch:f23cbe88f71917a25683b6f6c255fb2c
diff --git a/debian/changelog b/debian/changelog
index 1a7e637..bf1e462 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -5,6 +5,7 @@ vdr (1.7.22-1~ctvdr1) unstable; urgency=low
   * Dropped multipatch patches - these are available in the etobi-branch
     of the Git repository
   * Updated opt-39_noepg.dpatch and opt-44_rotor.dpatch
+  * Upgraded opt-20_liemikuutio.dpatch to version 1.33
 
  -- Tobias Grimm <etobi at debian.org>  Sat, 10 Dec 2011 21:51:31 +0100
 
diff --git a/debian/patches/opt-20_liemikuutio.dpatch b/debian/patches/opt-20_liemikuutio.dpatch
index 65f444b..ff6db7e 100644
--- a/debian/patches/opt-20_liemikuutio.dpatch
+++ b/debian/patches/opt-20_liemikuutio.dpatch
@@ -1,27 +1,27 @@
 #! /bin/sh /usr/share/dpatch/dpatch-run
 ## opt-20_liemikuutio.dpatch by Rolf Ahrenberg <Rolf.Ahrenberg AT sci.fi>
-## http://www.saunalahti.fi/~rahrenbe/vdr/patches/vdr-1.7.21-liemikuutio-1.31.patch.gz
+## http://www.saunalahti.fi/~rahrenbe/vdr/patches/vdr-1.7.22-liemikuutio-1.33.patch.gz
 ##
 ## All lines beginning with `## DP:' are a description of the patch.
 ## DP: Patch collection - see HISTORY-liemikuutio for details.
 
 @DPATCH@
-diff -Nru vdr-1.7.21-vanilla/config.h vdr-1.7.21-liemikuutio/config.h
---- vdr-1.7.21-vanilla/config.h	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/config.h	2011-09-04 16:54:42.000000000 +0300
+diff -Nru vdr-1.7.22-vanilla/config.h vdr-1.7.22-liemikuutio/config.h
+--- vdr-1.7.22-vanilla/config.h	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/config.h	2011-12-04 18:39:13.000000000 +0200
 @@ -36,6 +36,8 @@
  // plugins to work with newer versions of the core VDR as long as no
  // VDR header files have changed.
  
-+#define LIEMIKUUTIO  131
++#define LIEMIKUUTIO  133
 +
  #define MAXPRIORITY 99
  #define MAXLIFETIME 99
  
-diff -Nru vdr-1.7.21-vanilla/device.c vdr-1.7.21-liemikuutio/device.c
---- vdr-1.7.21-vanilla/device.c	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/device.c	2011-09-04 16:54:42.000000000 +0300
-@@ -1027,7 +1027,8 @@
+diff -Nru vdr-1.7.22-vanilla/device.c vdr-1.7.22-liemikuutio/device.c
+--- vdr-1.7.22-vanilla/device.c	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/device.c	2011-12-04 18:39:13.000000000 +0200
+@@ -1041,7 +1041,8 @@
       int LanguagePreference = INT_MAX; // higher than the maximum possible value
       for (int i = ttSubtitleFirst; i <= ttSubtitleLast; i++) {
           const tTrackId *TrackId = GetTrack(eTrackType(i));
@@ -31,10 +31,345 @@ diff -Nru vdr-1.7.21-vanilla/device.c vdr-1.7.21-liemikuutio/device.c
              PreferredTrack = eTrackType(i);
           }
       // Make sure we're set to an available subtitle track:
-diff -Nru vdr-1.7.21-vanilla/HISTORY-liemikuutio vdr-1.7.21-liemikuutio/HISTORY-liemikuutio
---- vdr-1.7.21-vanilla/HISTORY-liemikuutio	1970-01-01 02:00:00.000000000 +0200
-+++ vdr-1.7.21-liemikuutio/HISTORY-liemikuutio	2011-09-04 17:15:08.000000000 +0300
-@@ -0,0 +1,151 @@
+diff -Nru vdr-1.7.22-vanilla/filetransfer.c vdr-1.7.22-liemikuutio/filetransfer.c
+--- vdr-1.7.22-vanilla/filetransfer.c	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.7.22-liemikuutio/filetransfer.c	2011-12-04 18:39:13.000000000 +0200
+@@ -0,0 +1,294 @@
++/*
++ * filetransfer.c: The video file transfer facilities
++ *
++ * See the main source file 'vdr.c' for copyright information and
++ * how to reach the author.
++ *
++ * $Id: $
++ */
++
++#include "videodir.h"
++#include "filetransfer.h"
++
++static cString NewVideoFileName(const char *FileName, const char *NewDirName)
++{
++  char *NewDir = ExchangeChars(strdup(NewDirName), true);
++  if (NewDir) {
++     const char *p = FileName + strlen(FileName); // p points at the terminating 0
++     while (p-- > FileName) {
++           if (*p == '/')
++              break;
++           }
++     cString NewName = cString::sprintf("%s/%s%s", VideoDirectory, NewDir, p);
++     free(NewDir);
++     return NewName;
++  }
++  return NULL;
++}
++
++static cString StripLastDirectory(const char *DirName)
++{
++  if (DirName && *DirName) {
++     cString s(DirName);
++     int l = strlen(*s);
++     const char *p = *s + l;
++     while (l > 0) {
++           if (*p-- == '/')
++              break;
++           l--;
++           }
++     if (l)
++        s = s.Truncate(l);
++     return s;
++     }
++  return NULL;
++}
++
++// --- cCopyingThread --------------------------------------------------------
++
++class cCopyingThread : public cThread {
++private:
++  const char *error;
++  bool deleteSource;
++  cString source;
++  cString target;
++protected:
++  virtual void Action(void);
++public:
++  cCopyingThread(const char *SourceName, const char *ToFileName, bool DeleteSource = false);
++  virtual ~cCopyingThread();
++  const char *Error(void) { return error; }
++  };
++
++cCopyingThread::cCopyingThread(const char *SourceName, const char *TargetName, bool DeleteSource)
++:cThread("copying"),
++ error(NULL),
++ deleteSource(DeleteSource),
++ source(SourceName),
++ target(TargetName)
++{
++  // add missing directory delimiters
++  const char *delim = "/";
++  if (!endswith(*source, delim))
++     source = cString::sprintf("%s%s", *source, delim);
++  if (!endswith(*target, delim))
++     target = cString::sprintf("%s%s", *target, delim);
++
++  Start();
++}
++
++cCopyingThread::~cCopyingThread()
++{
++  Cancel(3);
++}
++
++void cCopyingThread::Action(void)
++{
++  SetPriority(19);
++  SetIOPriority(7);
++
++  if (strcmp(*source, *target)) {
++     // validate target directory
++     if (strstr(*target, *source)) {
++        error = "invalid target";
++        return;
++        }
++
++     // recordings methods require the last directory delimiter to be stripped off
++     cString recname = target;
++     recname.Truncate(strlen(*recname) - 1);
++     Recordings.AddByName(*recname, false);
++
++     RemoveFileOrDir(*target);
++     if (!MakeDirs(*target, true)) {
++        error = "MakeDirs";
++        return;
++        }
++
++     if (deleteSource && EntriesOnSameFileSystem(*source, *target)) {
++        if (rename(*source, *target) == -1) {
++           error = "rename";
++           return;
++           }
++        // delete all empty source directories
++        recname = source;
++        recname.Truncate(strlen(*recname) - 1);
++        recname = StripLastDirectory(*recname);
++        do {
++           if (!RemoveEmptyDirectories(*recname, true))
++              break;
++           recname = StripLastDirectory(*recname);
++           }
++        while (strcmp(*recname, VideoDirectory));
++        }
++     else {
++        int required = DirSizeMB(*source);
++        int available = FreeDiskSpaceMB(*target);
++
++        // validate free space
++        if (required < available) {
++           cReadDir d(*source);
++           struct dirent *e;
++           bool success = true;
++
++           // allocate copying buffer
++           const int len = 1024 * 1024;
++           char *buffer = MALLOC(char, len);
++           if (!buffer) {
++              error = "MALLOC";
++              return;
++              }
++
++           // loop through all files, but skip all sub-directories
++           while (Running() && (e = d.Next()) != NULL) {
++                 // skip generic entries
++                 if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) {
++                    cString sourceFile = cString::sprintf("%s%s", *source, e->d_name);
++                    cString targetFile = cString::sprintf("%s%s", *target, e->d_name);
++
++                    // copy only regular files
++                    struct stat sts;
++                    if (!stat(*sourceFile, &sts) && S_ISREG(sts.st_mode)) {
++                       int r = -1, w = -1;
++                       cUnbufferedFile *inputFile = cUnbufferedFile::Create(*sourceFile, O_RDONLY | O_LARGEFILE);
++                       cUnbufferedFile *outputFile = cUnbufferedFile::Create(*targetFile, O_RDWR | O_CREAT | O_LARGEFILE);
++
++                       // validate files
++                       if (!inputFile || !outputFile) {
++                          success = false;
++                          break;
++                          }
++
++                       // do actual copy
++                       do {
++                         r = inputFile->Read(buffer, len);
++                         if (r > 0)
++                            w = outputFile->Write(buffer, r);
++                         else
++                            w = 0;
++                       } while (Running() && r > 0 && w > 0);
++                       DELETENULL(inputFile);
++                       DELETENULL(outputFile);
++
++                       // validate result
++                       if (!Running() || r < 0 || w < 0) {
++                          success = false;
++                          break;
++                          }
++                       }
++                   }
++                }
++
++           // release allocated buffer
++           free(buffer);
++
++           // delete all created target files and directories
++           if (!success) {
++              target = StripLastDirectory(*target);
++              RemoveFileOrDir(*target, true);
++              target = StripLastDirectory(*target);
++              RemoveEmptyDirectories(*target, true);
++              error = "copy failed";
++              return;
++              }
++           }
++        else {
++           // delete all created empty target directories
++           recname = target;
++           recname.Truncate(strlen(*recname) - 1);
++           recname = StripLastDirectory(*recname);
++           do {
++              if (!RemoveEmptyDirectories(*recname, true))
++                 break;
++              recname = StripLastDirectory(*recname);
++              }
++           while (strcmp(*recname, VideoDirectory));
++           error = "insufficient free space";
++           return;
++           }
++        }
++
++     if (deleteSource) {
++        // Recordings' methods require the last directory delimiter to be stripped off
++        source.Truncate(strlen(*source) - 1);
++        cRecording *recording = Recordings.GetByName(*source);
++        if (recording->Delete())
++           Recordings.DelByName(*source, false);
++        }
++     else
++        Recordings.TouchUpdate();
++     }
++}
++
++// --- cFileTransfer ----------------------------------------------------------------
++
++cMutex cFileTransfer::mutex;
++char *cFileTransfer::copiedVersionName = NULL;
++cCopyingThread *cFileTransfer::copyingThread = NULL;
++bool cFileTransfer::error = false;
++bool cFileTransfer::ended = false;
++
++bool cFileTransfer::Start(cRecording *Recording, const char *FileName, bool CopyOnly)
++{
++  cMutexLock MutexLock(&mutex);
++  if (!copyingThread) {
++     cString NewName = NewVideoFileName(Recording->FileName(), FileName);
++     error = false;
++     ended = false;
++     if (strlen(*NewName)) {
++        copiedVersionName = strdup(*NewName);
++        copyingThread = new cCopyingThread(Recording->FileName(), copiedVersionName, !CopyOnly);
++        return true;
++        }
++     }
++  return false;
++}
++
++void cFileTransfer::Stop(void)
++{
++  cMutexLock MutexLock(&mutex);
++  bool Interrupted = copyingThread && copyingThread->Active();
++  const char *Error = copyingThread ? copyingThread->Error() : NULL;
++  DELETENULL(copyingThread);
++  if ((Interrupted || Error)) {
++     if (Interrupted)
++        isyslog("file transfer has been interrupted");
++     if (Error)
++        esyslog("ERROR: '%s' during file transfer", Error);
++     RemoveVideoFile(copiedVersionName); //XXX what if this file is currently being replayed?
++     Recordings.DelByName(copiedVersionName);
++     free(copiedVersionName);
++     copiedVersionName = NULL;
++     }
++}
++
++bool cFileTransfer::Active(void)
++{
++  cMutexLock MutexLock(&mutex);
++  if (copyingThread) {
++     if (copyingThread->Active())
++        return true;
++     error = copyingThread->Error();
++     Stop();
++     free(copiedVersionName);
++     copiedVersionName = NULL;
++     ended = true;
++     }
++  return false;
++}
++
++bool cFileTransfer::Error(void)
++{
++  cMutexLock MutexLock(&mutex);
++  bool result = error;
++  error = false;
++  return result;
++}
++
++bool cFileTransfer::Ended(void)
++{
++  cMutexLock MutexLock(&mutex);
++  bool result = ended;
++  ended = false;
++  return result;
++}
+diff -Nru vdr-1.7.22-vanilla/filetransfer.h vdr-1.7.22-liemikuutio/filetransfer.h
+--- vdr-1.7.22-vanilla/filetransfer.h	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.7.22-liemikuutio/filetransfer.h	2011-12-04 18:39:13.000000000 +0200
+@@ -0,0 +1,33 @@
++/*
++ * filetransfer.h: The video file transfer facilities
++ *
++ * See the main source file 'vdr.c' for copyright information and
++ * how to reach the author.
++ *
++ * $Id: $
++ */
++
++#ifndef __FILETRANSFER_H
++#define __FILETRANSFER_H
++
++#include "recording.h"
++#include "thread.h"
++
++class cCopyingThread;
++
++class cFileTransfer {
++private:
++  static cMutex mutex;
++  static char *copiedVersionName;
++  static cCopyingThread *copyingThread;
++  static bool error;
++  static bool ended;
++public:
++  static bool Start(cRecording *Recording, const char *NewName, bool CopyOnly = false);
++  static void Stop(void);
++  static bool Active(void);
++  static bool Error(void);
++  static bool Ended(void);
++  };
++
++#endif //__FILETRANSFER_H
+diff -Nru vdr-1.7.22-vanilla/HISTORY-liemikuutio vdr-1.7.22-liemikuutio/HISTORY-liemikuutio
+--- vdr-1.7.22-vanilla/HISTORY-liemikuutio	1970-01-01 02:00:00.000000000 +0200
++++ vdr-1.7.22-liemikuutio/HISTORY-liemikuutio	2011-12-04 18:39:13.000000000 +0200
+@@ -0,0 +1,160 @@
 +-----------------------------------
 +Liemikuutio for Video Disc Recorder
 +
@@ -186,16 +521,47 @@ diff -Nru vdr-1.7.21-vanilla/HISTORY-liemikuutio vdr-1.7.21-liemikuutio/HISTORY-
 +- Removed progress bar view form "What's on now?" menu.
 +- Removed "Main menu command position" and recordings length/sorting features.
 +- Changed renaming functionality to support different filesystems and binded it to key '0'.
-diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
---- vdr-1.7.21-vanilla/menu.c	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/menu.c	2011-09-04 17:04:53.000000000 +0300
-@@ -2196,6 +2196,153 @@
++
++2011-10-19: Version 1.32
++
++- Refactored renaming functionality to support both background moving and copying.
++- Removed main menu command position changes completely.
++
++2011-11-16: Version 1.33
++
++- Updated the filetransfer patch.
+diff -Nru vdr-1.7.22-vanilla/Makefile vdr-1.7.22-liemikuutio/Makefile
+--- vdr-1.7.22-vanilla/Makefile	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/Makefile	2011-12-04 18:39:13.000000000 +0200
+@@ -41,8 +41,8 @@
+ SILIB    = $(LSIDIR)/libsi.a
+ 
+ OBJS = audio.o channels.o ci.o config.o cutter.o device.o diseqc.o dvbdevice.o dvbci.o\
+-       dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filter.o font.o i18n.o interface.o keys.o\
+-       lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\
++       dvbplayer.o dvbspu.o dvbsubtitle.o eit.o eitscan.o epg.o filetransfer.o filter.o font.o i18n.o\
++       interface.o keys.o lirc.o menu.o menuitems.o nit.o osdbase.o osd.o pat.o player.o plugin.o rcu.o\
+        receiver.o recorder.o recording.o remote.o remux.o ringbuffer.o sdt.o sections.o shutdown.o\
+        skinclassic.o skins.o skinsttng.o sourceparams.o sources.o spu.o status.o svdrp.o themes.o thread.o\
+        timers.o tools.o transfer.o vdr.o videodir.o
+diff -Nru vdr-1.7.22-vanilla/menu.c vdr-1.7.22-liemikuutio/menu.c
+--- vdr-1.7.22-vanilla/menu.c	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/menu.c	2011-12-04 18:39:13.000000000 +0200
+@@ -18,6 +18,7 @@
+ #include "config.h"
+ #include "cutter.h"
+ #include "eitscan.h"
++#include "filetransfer.h"
+ #include "i18n.h"
+ #include "interface.h"
+ #include "plugin.h"
+@@ -2196,6 +2197,173 @@
    SetText(cString::sprintf("%d\t\t%d\t%s", totalEntries, newEntries, name));
  }
  
-+// --- cMenuRenameRecording --------------------------------------------------
++// --- cMenuEditRecording ----------------------------------------------------
 +
-+class cMenuRenameRecording : public cOsdMenu {
++class cMenuEditRecording : public cOsdMenu {
 +private:
 +  char name[MaxFileName];
 +  cMenuEditStrItem *file;
@@ -205,12 +571,12 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
 +  void SetHelpKeys(void);
 +  eOSState SetFolder(void);
 +public:
-+  cMenuRenameRecording(cRecording *Recording);
++  cMenuEditRecording(cRecording *Recording);
 +  virtual eOSState ProcessKey(eKeys Key);
 +};
 +
-+cMenuRenameRecording::cMenuRenameRecording(cRecording *Recording)
-+:cOsdMenu(tr("Rename recording"), 12)
++cMenuEditRecording::cMenuEditRecording(cRecording *Recording)
++:cOsdMenu(tr("Edit recording"), 12)
 +{
 +  cMarks marks;
 +
@@ -255,12 +621,12 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
 +  SetHelpKeys();
 +}
 +
-+void cMenuRenameRecording::SetHelpKeys(void)
++void cMenuEditRecording::SetHelpKeys(void)
 +{
-+  SetHelp(tr("Button$Folder"));
++  SetHelp(tr("Button$Folder"), tr("Button$Cut"), tr("Button$Copy"), tr("Button$Move"));
 +}
 +
-+eOSState cMenuRenameRecording::SetFolder(void)
++eOSState cMenuEditRecording::SetFolder(void)
 +{
 +  cMenuFolder *mf = (cMenuFolder *)SubMenu();
 +  if (mf) {
@@ -280,24 +646,42 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
 +  return CloseSubMenu();
 +}
 +
-+eOSState cMenuRenameRecording::ProcessKey(eKeys Key)
++eOSState cMenuEditRecording::ProcessKey(eKeys Key)
 +{
 +  eOSState state = cOsdMenu::ProcessKey(Key);
 +
 +  if (state == osUnknown) {
 +     switch (Key) {
 +       case kOk:
-+            if (recording->Rename(name)) {
-+               Recordings.ChangeState();
-+               Recordings.TouchUpdate();
-+               return osRecordings;
-+               }
-+            else
-+               Skins.Message(mtError, tr("Error while accessing recording!"));
-+            break;
++            return osBack;
 +       case kRed:
 +            return AddSubMenu(new cMenuFolder(tr("Select folder"), &Folders, name));
 +            break;
++       case kGreen:
++            if (!cCutter::Active()) {
++               if (isMarks)
++                  Skins.Message(mtError, tr("No editing marks defined!"));
++               else if (!cCutter::Start(recording->Name()))
++                  Skins.Message(mtError, tr("Can't start editing process!"));
++               else
++                  Skins.Message(mtInfo, tr("Editing process started"));
++               }
++            else
++               Skins.Message(mtError, tr("Editing process already active!"));
++            return osContinue;
++       case kYellow:
++       case kBlue:
++            if (strcmp(recording->Name(), name)) {
++               if (!cFileTransfer::Active()) {
++                  if (cFileTransfer::Start(recording, name, (Key == kYellow)))
++                     Skins.Message(mtInfo, tr("File transfer started"));
++                  else
++                     Skins.Message(mtError, tr("Can't start file transfer!"));
++                  }
++               else
++                  Skins.Message(mtError, tr("File transfer already active!"));
++               }
++            return osRecordings;
 +       default:
 +            break;
 +       }
@@ -313,10 +697,10 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
 +        marks.Load(recording->FileName(), recording->FramesPerSecond(), recording->IsPesRecording());
 +        cMark *mark = marks.First();
 +        while (mark) {
-+          cMark *nextmark = marks.Next(mark);
-+          marks.Del(mark);
-+          mark = nextmark;
-+          }
++              cMark *nextmark = marks.Next(mark);
++              marks.Del(mark);
++              mark = nextmark;
++              }
 +        marks.Save();
 +        isMarks = false;
 +        marksItem->SetSelectable(isMarks);
@@ -336,6 +720,8 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
 +        }
 +     return osContinue;
 +     }
++  else if (!HasSubMenu() && (Key != kNone))
++     SetHelpKeys();
 +
 +  return state;
 +}
@@ -343,11 +729,11 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
  // --- cMenuRecordings -------------------------------------------------------
  
  cMenuRecordings::cMenuRecordings(const char *Base, int Level, bool OpenSubMenus)
-@@ -2434,6 +2581,19 @@
+@@ -2434,6 +2602,19 @@
    return osContinue;
  }
  
-+eOSState cMenuRecordings::Rename(void)
++eOSState cMenuRecordings::Edit(void)
 +{
 +  if (HasSubMenu() || Count() == 0)
 +     return osContinue;
@@ -355,7 +741,7 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
 +  if (ri && !ri->IsDirectory()) {
 +     cRecording *recording = GetRecording(ri);
 +     if (recording)
-+        return AddSubMenu(new cMenuRenameRecording(recording));
++        return AddSubMenu(new cMenuEditRecording(recording));
 +     }
 +  return osContinue;
 +}
@@ -363,42 +749,56 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
  eOSState cMenuRecordings::ProcessKey(eKeys Key)
  {
    bool HadSubMenu = HasSubMenu();
-@@ -2448,6 +2608,7 @@
+@@ -2448,6 +2629,7 @@
         case kYellow: return Delete();
         case kInfo:
         case kBlue:   return Info();
-+       case k0:      return Rename();
++       case k0:      return Edit();
         case k1...k9: return Commands(Key);
         case kNone:   if (Recordings.StateChanged(recordingsState))
                          Set(true);
-@@ -3363,7 +3524,7 @@
-      // Replay control:
-      if (replaying && !stopReplayItem)
-         // TRANSLATORS: note the leading blank!
--        Add(stopReplayItem = new cOsdItem(tr(" Stop replaying"), osStopReplay));
-+        Ins(stopReplayItem = new cOsdItem(tr(" Stop replaying"), osStopReplay));
-      else if (stopReplayItem && !replaying) {
-         Del(stopReplayItem->Index());
-         stopReplayItem = NULL;
-@@ -3377,7 +3538,7 @@
-   bool CutterActive = cCutter::Active();
-   if (CutterActive && !cancelEditingItem) {
-      // TRANSLATORS: note the leading blank!
--     Add(cancelEditingItem = new cOsdItem(tr(" Cancel editing"), osCancelEdit));
-+     Ins(cancelEditingItem = new cOsdItem(tr(" Cancel editing"), osCancelEdit));
+@@ -3308,6 +3490,7 @@
+   replaying = false;
+   stopReplayItem = NULL;
+   cancelEditingItem = NULL;
++  cancelFileTransferItem = NULL;
+   stopRecordingItem = NULL;
+   recordControlsState = 0;
+   Set();
+@@ -3409,6 +3592,19 @@
       result = true;
       }
-   else if (cancelEditingItem && !CutterActive) {
-@@ -3397,7 +3558,7 @@
-      while ((s = cRecordControls::GetInstantId(s)) != NULL) {
-            cOsdItem *item = new cOsdItem(osStopRecord);
-            item->SetText(cString::sprintf("%s%s", tr(STOP_RECORDING), s));
--           Add(item);
-+           Ins(item);
-            if (!stopRecordingItem)
-               stopRecordingItem = item;
-            }
-@@ -4387,6 +4548,10 @@
+ 
++  // File transfer control:
++  bool FileTransferActive = cFileTransfer::Active();
++  if (FileTransferActive && !cancelFileTransferItem) {
++     // TRANSLATORS: note the leading blank!
++     Add(cancelFileTransferItem = new cOsdItem(tr(" Cancel file transfer"), osCancelTransfer));
++     result = true;
++     }
++  else if (cancelFileTransferItem && !FileTransferActive) {
++     Del(cancelFileTransferItem->Index());
++     cancelFileTransferItem = NULL;
++     result = true;
++     }
++
+   // Record control:
+   if (cRecordControls::StateChanged(recordControlsState)) {
+      while (stopRecordingItem) {
+@@ -3457,6 +3653,12 @@
+                           return osEnd;
+                           }
+                        break;
++    case osCancelTransfer:
++                       if (Interface->Confirm(tr("Cancel file transfer?"))) {
++                          cFileTransfer::Stop();
++                          return osEnd;
++                          }
++                       break;
+     case osPlugin:     {
+                          cMenuPluginItem *item = (cMenuPluginItem *)Get(Current());
+                          if (item) {
+@@ -4410,6 +4612,10 @@
  
  // --- cReplayControl --------------------------------------------------------
  
@@ -409,7 +809,7 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
  cReplayControl *cReplayControl::currentReplayControl = NULL;
  char *cReplayControl::fileName = NULL;
  char *cReplayControl::title = NULL;
-@@ -4400,6 +4565,9 @@
+@@ -4423,6 +4629,9 @@
    lastCurrent = lastTotal = -1;
    lastPlay = lastForward = false;
    lastSpeed = -2; // an invalid value
@@ -419,7 +819,7 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
    timeoutShow = 0;
    timeSearchActive = false;
    cRecording Recording(fileName);
-@@ -4798,6 +4966,32 @@
+@@ -4821,6 +5030,32 @@
      case kGreen:   SkipSeconds(-60); break;
      case kYellow|k_Repeat:
      case kYellow:  SkipSeconds( 60); break;
@@ -452,7 +852,7 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
      case kStop:
      case kBlue:    Hide();
                     Stop();
-@@ -4807,12 +5001,8 @@
+@@ -4830,12 +5065,8 @@
        switch (int(Key)) {
          // Editing:
          case kMarkToggle:      MarkToggle(); break;
@@ -465,18 +865,26 @@ diff -Nru vdr-1.7.21-vanilla/menu.c vdr-1.7.21-liemikuutio/menu.c
          case kMarkJumpForward|k_Repeat:
          case kMarkJumpForward: MarkJump(true); break;
          case kMarkMoveBack|k_Repeat:
-diff -Nru vdr-1.7.21-vanilla/menu.h vdr-1.7.21-liemikuutio/menu.h
---- vdr-1.7.21-vanilla/menu.h	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/menu.h	2011-09-04 16:54:42.000000000 +0300
-@@ -204,6 +204,7 @@
+diff -Nru vdr-1.7.22-vanilla/menu.h vdr-1.7.22-liemikuutio/menu.h
+--- vdr-1.7.22-vanilla/menu.h	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/menu.h	2011-12-04 18:39:13.000000000 +0200
+@@ -100,6 +100,7 @@
+   bool replaying;
+   cOsdItem *stopReplayItem;
+   cOsdItem *cancelEditingItem;
++  cOsdItem *cancelFileTransferItem;
+   cOsdItem *stopRecordingItem;
+   int recordControlsState;
+   static cOsdObject *pluginOsdObject;
+@@ -204,6 +205,7 @@
    eOSState Delete(void);
    eOSState Info(void);
    eOSState Commands(eKeys Key = kNone);
-+  eOSState Rename(void);
++  eOSState Edit(void);
  protected:
    cRecording *GetRecording(cMenuRecordingItem *Item);
  public:
-@@ -258,6 +259,9 @@
+@@ -258,6 +260,9 @@
    int lastCurrent, lastTotal;
    bool lastPlay, lastForward;
    int lastSpeed;
@@ -486,9 +894,9 @@ diff -Nru vdr-1.7.21-vanilla/menu.h vdr-1.7.21-liemikuutio/menu.h
    time_t timeoutShow;
    bool timeSearchActive, timeSearchHide;
    int timeSearchTime, timeSearchPos;
-diff -Nru vdr-1.7.21-vanilla/osdbase.c vdr-1.7.21-liemikuutio/osdbase.c
---- vdr-1.7.21-vanilla/osdbase.c	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/osdbase.c	2011-09-04 16:54:42.000000000 +0300
+diff -Nru vdr-1.7.22-vanilla/osdbase.c vdr-1.7.22-liemikuutio/osdbase.c
+--- vdr-1.7.22-vanilla/osdbase.c	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/osdbase.c	2011-12-04 18:39:13.000000000 +0200
 @@ -77,6 +77,7 @@
  {
    isMenu = true;
@@ -506,7 +914,7 @@ diff -Nru vdr-1.7.21-vanilla/osdbase.c vdr-1.7.21-liemikuutio/osdbase.c
          s = buffer;
          }
       }
-@@ -449,20 +450,62 @@
+@@ -449,20 +450,60 @@
       }
  }
  
@@ -526,9 +934,8 @@ diff -Nru vdr-1.7.21-vanilla/osdbase.c vdr-1.7.21-liemikuutio/osdbase.c
 +     else
 +        return osContinue;
 +     }
-+  else {
++  else
 +     lastActivity.Set(MENUKEY_TIMEOUT);
-+     }
 +  for (cOsdItem *item = Last(); item; item = Prev(item)) {
        const char *s = item->Text();
 -      if (s && (s = skipspace(s)) != NULL) {
@@ -566,13 +973,12 @@ diff -Nru vdr-1.7.21-vanilla/osdbase.c vdr-1.7.21-liemikuutio/osdbase.c
 +            }
           }
        }
-+  if ((!match) && (Key != kNone)) {
++  if ((!match) && (Key != kNone))
 +     key_nr = -1;
-+     }
    return osContinue;
  }
  
-@@ -501,8 +544,8 @@
+@@ -501,8 +542,8 @@
          }
       }
    switch (int(Key)) {
@@ -583,10 +989,18 @@ diff -Nru vdr-1.7.21-vanilla/osdbase.c vdr-1.7.21-liemikuutio/osdbase.c
      case kUp|k_Repeat:
      case kUp:   CursorUp();   break;
      case kDown|k_Repeat:
-diff -Nru vdr-1.7.21-vanilla/osdbase.h vdr-1.7.21-liemikuutio/osdbase.h
---- vdr-1.7.21-vanilla/osdbase.h	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/osdbase.h	2011-09-04 16:54:42.000000000 +0300
-@@ -95,6 +95,8 @@
+diff -Nru vdr-1.7.22-vanilla/osdbase.h vdr-1.7.22-liemikuutio/osdbase.h
+--- vdr-1.7.22-vanilla/osdbase.h	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/osdbase.h	2011-12-04 18:39:13.000000000 +0200
+@@ -30,6 +30,7 @@
+                 osStopRecord,
+                 osStopReplay,
+                 osCancelEdit,
++                osCancelTransfer,
+                 osSwitchDvb,
+                 osBack,
+                 osEnd,
+@@ -95,6 +96,8 @@
    char *status;
    int digit;
    bool hasHotkeys;
@@ -595,16 +1009,25 @@ diff -Nru vdr-1.7.21-vanilla/osdbase.h vdr-1.7.21-liemikuutio/osdbase.h
  protected:
    void SetDisplayMenu(void);
    cSkinDisplayMenu *DisplayMenu(void) { return displayMenu; }
-diff -Nru vdr-1.7.21-vanilla/po/de_DE.po vdr-1.7.21-liemikuutio/po/de_DE.po
---- vdr-1.7.21-vanilla/po/de_DE.po	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/po/de_DE.po	2011-09-04 16:54:42.000000000 +0300
-@@ -1322,3 +1322,30 @@
+diff -Nru vdr-1.7.22-vanilla/po/de_DE.po vdr-1.7.22-liemikuutio/po/de_DE.po
+--- vdr-1.7.22-vanilla/po/de_DE.po	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/po/de_DE.po	2011-12-04 18:39:13.000000000 +0200
+@@ -1329,3 +1329,67 @@
  #, c-format
  msgid "VDR will shut down in %s minutes"
  msgstr "VDR wird in %s Minuten ausschalten"
 +
-+msgid "Rename recording"
-+msgstr "Aufzeichnung umbenennen"
++msgid "Edit recording"
++msgstr ""
++
++msgid "Button$Cut"
++msgstr ""
++
++msgid "Button$Copy"
++msgstr ""
++
++msgid "Button$Move"
++msgstr ""
 +
 +msgid "Date"
 +msgstr "Datum"
@@ -629,16 +1052,53 @@ diff -Nru vdr-1.7.21-vanilla/po/de_DE.po vdr-1.7.21-liemikuutio/po/de_DE.po
 +
 +msgid "Delete resume information?"
 +msgstr "Resume löschen?"
-diff -Nru vdr-1.7.21-vanilla/po/et_EE.po vdr-1.7.21-liemikuutio/po/et_EE.po
---- vdr-1.7.21-vanilla/po/et_EE.po	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/po/et_EE.po	2011-09-04 16:54:42.000000000 +0300
-@@ -1322,3 +1322,30 @@
++
++msgid "File transfer started"
++msgstr ""
++
++msgid "Can't start file transfer!"
++msgstr ""
++
++msgid "File transfer already active!"
++msgstr ""
++
++#. TRANSLATORS: note the leading blank!
++msgid " Cancel file transfer"
++msgstr ""
++
++msgid "Cancel file transfer?"
++msgstr ""
++
++msgid "Transfering file - shut down anyway?"
++msgstr ""
++
++msgid "Transfering file - restart anyway?"
++msgstr ""
++
++msgid "File transfer failed!"
++msgstr ""
++
++msgid "File transfer finished"
++msgstr ""
+diff -Nru vdr-1.7.22-vanilla/po/et_EE.po vdr-1.7.22-liemikuutio/po/et_EE.po
+--- vdr-1.7.22-vanilla/po/et_EE.po	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/po/et_EE.po	2011-12-04 18:39:13.000000000 +0200
+@@ -1329,3 +1329,67 @@
  #, c-format
  msgid "VDR will shut down in %s minutes"
  msgstr "VDR lülitub välja %s minuti pärast"
 +
-+msgid "Rename recording"
-+msgstr "Ümbernimetamine"
++msgid "Edit recording"
++msgstr ""
++
++msgid "Button$Cut"
++msgstr ""
++
++msgid "Button$Copy"
++msgstr ""
++
++msgid "Button$Move"
++msgstr ""
 +
 +msgid "Date"
 +msgstr "Kuupäev"
@@ -663,16 +1123,53 @@ diff -Nru vdr-1.7.21-vanilla/po/et_EE.po vdr-1.7.21-liemikuutio/po/et_EE.po
 +
 +msgid "Delete resume information?"
 +msgstr "Kustutada jätkamise info?"
-diff -Nru vdr-1.7.21-vanilla/po/fi_FI.po vdr-1.7.21-liemikuutio/po/fi_FI.po
---- vdr-1.7.21-vanilla/po/fi_FI.po	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/po/fi_FI.po	2011-09-04 16:54:42.000000000 +0300
-@@ -1325,3 +1325,30 @@
++
++msgid "File transfer started"
++msgstr ""
++
++msgid "Can't start file transfer!"
++msgstr ""
++
++msgid "File transfer already active!"
++msgstr ""
++
++#. TRANSLATORS: note the leading blank!
++msgid " Cancel file transfer"
++msgstr ""
++
++msgid "Cancel file transfer?"
++msgstr ""
++
++msgid "Transfering file - shut down anyway?"
++msgstr ""
++
++msgid "Transfering file - restart anyway?"
++msgstr ""
++
++msgid "File transfer failed!"
++msgstr ""
++
++msgid "File transfer finished"
++msgstr ""
+diff -Nru vdr-1.7.22-vanilla/po/fi_FI.po vdr-1.7.22-liemikuutio/po/fi_FI.po
+--- vdr-1.7.22-vanilla/po/fi_FI.po	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/po/fi_FI.po	2011-12-04 18:39:13.000000000 +0200
+@@ -1332,3 +1332,67 @@
  #, c-format
  msgid "VDR will shut down in %s minutes"
  msgstr "VDR sammuu %s minuutin kuluttua"
 +
-+msgid "Rename recording"
-+msgstr "Nimeä tallenne"
++msgid "Edit recording"
++msgstr "Muokkaa tallennetta"
++
++msgid "Button$Cut"
++msgstr "Leikkaa"
++
++msgid "Button$Copy"
++msgstr "Kopioi"
++
++msgid "Button$Move"
++msgstr "Siirrä"
 +
 +msgid "Date"
 +msgstr "Päiväys"
@@ -680,9 +1177,6 @@ diff -Nru vdr-1.7.21-vanilla/po/fi_FI.po vdr-1.7.21-liemikuutio/po/fi_FI.po
 +msgid "Length"
 +msgstr "Pituus"
 +
-+msgid "Size"
-+msgstr "Koko"
-+
 +msgid "Format"
 +msgstr "Tiedostomuoto"
 +
@@ -692,21 +1186,61 @@ diff -Nru vdr-1.7.21-vanilla/po/fi_FI.po vdr-1.7.21-liemikuutio/po/fi_FI.po
 +msgid "TS"
 +msgstr "TS"
 +
++msgid "Size"
++msgstr "Koko"
++
 +msgid "Delete marks information?"
 +msgstr "Poista tallenteen merkinnät?"
 +
 +msgid "Delete resume information?"
 +msgstr "Poista tallenteen paluutiedot?"
-diff -Nru vdr-1.7.21-vanilla/po/fr_FR.po vdr-1.7.21-liemikuutio/po/fr_FR.po
---- vdr-1.7.21-vanilla/po/fr_FR.po	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/po/fr_FR.po	2011-09-04 16:54:42.000000000 +0300
-@@ -1328,3 +1328,30 @@
++
++msgid "File transfer started"
++msgstr "Tiedoston siirto aloitettu"
++
++msgid "Can't start file transfer!"
++msgstr "Tiedoston siirron aloitus epäonnistui!"
++
++msgid "File transfer already active!"
++msgstr "Tiedoston siirto on jo käynnissä!"
++ 
++#. TRANSLATORS: note the leading blank!
++msgid " Cancel file transfer"
++msgstr " Peru tiedoston siirto"
++
++msgid "Cancel file transfer?"
++msgstr "Perutaanko tiedoston siirto?"
++
++msgid "Transfering file - shut down anyway?"
++msgstr "Tiedoston siirto kesken - sammutetaanko?"
++
++msgid "Transfering file - restart anyway?"
++msgstr "Tiedoston siirto kesken - käynnistetäänkö uudelleen?"
++
++msgid "File transfer failed!"
++msgstr "Tiedoston siirto epäonnistui!"
++
++msgid "File transfer finished"
++msgstr "Tiedoston siirto valmis"
+diff -Nru vdr-1.7.22-vanilla/po/fr_FR.po vdr-1.7.22-liemikuutio/po/fr_FR.po
+--- vdr-1.7.22-vanilla/po/fr_FR.po	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/po/fr_FR.po	2011-12-04 18:39:13.000000000 +0200
+@@ -1335,3 +1335,67 @@
  #, c-format
  msgid "VDR will shut down in %s minutes"
  msgstr "VDR s'arrêtera dans %s minutes"
 +
-+msgid "Rename recording"
-+msgstr "Renommer l'enregistrement"
++msgid "Edit recording"
++msgstr ""
++
++msgid "Button$Cut"
++msgstr ""
++
++msgid "Button$Copy"
++msgstr ""
++
++msgid "Button$Move"
++msgstr ""
 +
 +msgid "Date"
 +msgstr "Date"
@@ -731,16 +1265,53 @@ diff -Nru vdr-1.7.21-vanilla/po/fr_FR.po vdr-1.7.21-liemikuutio/po/fr_FR.po
 +
 +msgid "Delete resume information?"
 +msgstr "Effacer les informations de reprise"
-diff -Nru vdr-1.7.21-vanilla/po/ru_RU.po vdr-1.7.21-liemikuutio/po/ru_RU.po
---- vdr-1.7.21-vanilla/po/ru_RU.po	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/po/ru_RU.po	2011-09-04 16:54:42.000000000 +0300
-@@ -1323,3 +1323,30 @@
++
++msgid "File transfer started"
++msgstr ""
++
++msgid "Can't start file transfer!"
++msgstr ""
++
++msgid "File transfer already active!"
++msgstr ""
++
++#. TRANSLATORS: note the leading blank!
++msgid " Cancel file transfer"
++msgstr ""
++
++msgid "Cancel file transfer?"
++msgstr ""
++
++msgid "Transfering file - shut down anyway?"
++msgstr ""
++
++msgid "Transfering file - restart anyway?"
++msgstr ""
++
++msgid "File transfer failed!"
++msgstr ""
++
++msgid "File transfer finished"
++msgstr ""
+diff -Nru vdr-1.7.22-vanilla/po/ru_RU.po vdr-1.7.22-liemikuutio/po/ru_RU.po
+--- vdr-1.7.22-vanilla/po/ru_RU.po	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/po/ru_RU.po	2011-12-04 18:39:13.000000000 +0200
+@@ -1330,3 +1330,67 @@
  #, c-format
  msgid "VDR will shut down in %s minutes"
  msgstr "VDR ÒëÚÛîçØâáï çÕàÕ× %s ÜØÝãâ"
 +
-+msgid "Rename recording"
-+msgstr "¿ÕàÕØÜÕÝÞÒÐâì ×ÐßØáì"
++msgid "Edit recording"
++msgstr ""
++
++msgid "Button$Cut"
++msgstr ""
++
++msgid "Button$Copy"
++msgstr ""
++
++msgid "Button$Move"
++msgstr ""
 +
 +msgid "Date"
 +msgstr ""
@@ -765,83 +1336,140 @@ diff -Nru vdr-1.7.21-vanilla/po/ru_RU.po vdr-1.7.21-liemikuutio/po/ru_RU.po
 +
 +msgid "Delete resume information?"
 +msgstr ""
-diff -Nru vdr-1.7.21-vanilla/recording.c vdr-1.7.21-liemikuutio/recording.c
---- vdr-1.7.21-vanilla/recording.c	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/recording.c	2011-09-04 17:06:59.000000000 +0300
-@@ -1056,6 +1056,40 @@
-   return -1;
++
++msgid "File transfer started"
++msgstr ""
++
++msgid "Can't start file transfer!"
++msgstr ""
++
++msgid "File transfer already active!"
++msgstr ""
++
++#. TRANSLATORS: note the leading blank!
++msgid " Cancel file transfer"
++msgstr ""
++
++msgid "Cancel file transfer?"
++msgstr ""
++
++msgid "Transfering file - shut down anyway?"
++msgstr ""
++
++msgid "Transfering file - restart anyway?"
++msgstr ""
++
++msgid "File transfer failed!"
++msgstr ""
++
++msgid "File transfer finished"
++msgstr ""
+diff -Nru vdr-1.7.22-vanilla/recording.c vdr-1.7.22-liemikuutio/recording.c
+--- vdr-1.7.22-vanilla/recording.c	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/recording.c	2011-12-04 18:39:13.000000000 +0200
+@@ -1208,7 +1208,7 @@
+      }
  }
  
-+bool cRecording::Rename(const char *newName)
-+{
-+  bool result = false;
-+  struct tm tm_r;
-+  struct tm *t = localtime_r(&start, &tm_r);
-+  char *localNewName = ExchangeChars(strdup(newName), true);
-+  const char *fmt = isPesRecording ? NAMEFORMATPES : NAMEFORMATTS;
-+  int ch = isPesRecording ? priority : channel;
-+  int ri = isPesRecording ? lifetime : instanceId;
-+  char *newFileName = strdup(cString::sprintf(fmt, VideoDirectory, localNewName, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, ch, ri));
-+  free(localNewName);
-+  if (strcmp(FileName(), newFileName)) {
-+     if (access(newFileName, F_OK) == 0) {
-+        esyslog("recording %s already exists", newFileName);
-+        }
-+     else {
-+        isyslog("renaming recording %s to %s", FileName(), newFileName);
-+        result = MoveVideoFile(FileName(), newFileName);
-+        if (result) {
-+           free(fileName);
-+           fileName = strdup(newFileName);
-+           free(name);
-+           name = strdup(newName);
-+           free(sortBuffer);
-+           sortBuffer = NULL;
-+           free(titleBuffer);
-+           titleBuffer = NULL;
-+           }
-+        }
+-void cRecordings::DelByName(const char *FileName)
++void cRecordings::DelByName(const char *FileName, bool RemoveRecording)
+ {
+   LOCK_THREAD;
+   cRecording *recording = GetByName(FileName);
+@@ -1216,7 +1216,7 @@
+      cThreadLock DeletedRecordingsLock(&DeletedRecordings);
+      Del(recording, false);
+      char *ext = strrchr(recording->fileName, '.');
+-     if (ext) {
++     if (ext && RemoveRecording) {
+         strncpy(ext, DELEXT, strlen(ext));
+         recording->fileSizeMB = DirSizeMB(recording->FileName());
+         recording->deleted = time(NULL);
+diff -Nru vdr-1.7.22-vanilla/recording.h vdr-1.7.22-liemikuutio/recording.h
+--- vdr-1.7.22-vanilla/recording.h	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/recording.h	2011-12-04 18:39:13.000000000 +0200
+@@ -188,7 +188,7 @@
+   void ResetResume(const char *ResumeFileName = NULL);
+   cRecording *GetByName(const char *FileName);
+   void AddByName(const char *FileName, bool TriggerUpdate = true);
+-  void DelByName(const char *FileName);
++  void DelByName(const char *FileName, bool RemoveRecording = true);
+   void UpdateByName(const char *FileName);
+   int TotalFileSizeMB(void); ///< Only for deleted recordings!
+   };
+diff -Nru vdr-1.7.22-vanilla/shutdown.c vdr-1.7.22-liemikuutio/shutdown.c
+--- vdr-1.7.22-vanilla/shutdown.c	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/shutdown.c	2011-12-04 18:39:13.000000000 +0200
+@@ -17,6 +17,7 @@
+ #include "channels.h"
+ #include "config.h"
+ #include "cutter.h"
++#include "filetransfer.h"
+ #include "i18n.h"
+ #include "interface.h"
+ #include "menu.h"
+@@ -166,6 +167,10 @@
+      if (!Interactive || !Interface->Confirm(tr("Editing - shut down anyway?")))
+         return false;
+      }
++  if (cFileTransfer::Active()) {
++     if (!Interactive || !Interface->Confirm(tr("Transfering file - shut down anyway?")))
++        return false;
 +     }
-+  free(newFileName);
-+  return result;
-+}
-+
- // --- cRecordings -----------------------------------------------------------
  
- cRecordings Recordings;
-diff -Nru vdr-1.7.21-vanilla/recording.h vdr-1.7.21-liemikuutio/recording.h
---- vdr-1.7.21-vanilla/recording.h	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/recording.h	2011-09-04 16:57:00.000000000 +0300
-@@ -152,6 +152,9 @@
-        ///< Changes the file name so that it will be visible in the "Recordings" menu again and
-        ///< not processed by cRemoveDeletedRecordingsThread.
-        ///< Returns false in case of error
-+  bool Rename(const char *newName);
-+       ///< Changes the file name
-+       ///< Returns false in case of error
-   };
+   cTimer *timer = Timers.GetNextActiveTimer();
+   time_t Next = timer ? timer->StartTime() : 0;
+@@ -209,6 +214,10 @@
+      if (!Interactive || !Interface->Confirm(tr("Editing - restart anyway?")))
+         return false;
+      }
++  if (cFileTransfer::Active()) {
++     if (!Interactive || !Interface->Confirm(tr("Transfering file - restart anyway?")))
++        return false;
++     }
  
- class cRecordings : public cList<cRecording>, public cThread {
-diff -Nru vdr-1.7.21-vanilla/svdrp.c vdr-1.7.21-liemikuutio/svdrp.c
---- vdr-1.7.21-vanilla/svdrp.c	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/svdrp.c	2011-09-04 17:09:02.000000000 +0300
-@@ -306,6 +306,11 @@
-   "REMO [ on | off ]\n"
-   "    Turns the remote control on or off. Without a parameter, the current\n"
-   "    status of the remote control is reported.",
-+  "RENR <number> <new name>\n"
-+  "    Rename the recording with the given number. Before a recording can be\n"
-+  "    renamed, an LSTR command must have been executed in order to retrieve\n"
-+  "    the recording numbers. The numbers don't change during subsequent RENR\n"
-+  "    commands.\n"
-   "SCAN\n"
-   "    Forces an EPG scan. If this is a single DVB device system, the scan\n"
-   "    will be done on the primary device unless it is currently recording.",
-@@ -1510,6 +1515,31 @@
-   Reply(250, "EPG scan triggered");
+   cTimer *timer = Timers.GetNextActiveTimer();
+   time_t Next  = timer ? timer->StartTime() : 0;
+diff -Nru vdr-1.7.22-vanilla/svdrp.c vdr-1.7.22-liemikuutio/svdrp.c
+--- vdr-1.7.22-vanilla/svdrp.c	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/svdrp.c	2011-12-04 18:39:13.000000000 +0200
+@@ -31,6 +31,7 @@
+ #include "cutter.h"
+ #include "device.h"
+ #include "eitscan.h"
++#include "filetransfer.h"
+ #include "keys.h"
+ #include "menu.h"
+ #include "plugin.h"
+@@ -193,6 +194,11 @@
+   "    After a CLRE command, no further EPG processing is done for 10\n"
+   "    seconds, so that data sent with subsequent PUTE commands doesn't\n"
+   "    interfere with data from the broadcasters.",
++  "CPYR <number> <new name>\n"
++  "    Copy the recording with the given number. Before a recording can be\n"
++  "    copied, an LSTR command must have been executed in order to retrieve\n"
++  "    the recording numbers. The numbers don't change during subsequent CPYR\n"
++  "    commands.",
+   "DELC <number>\n"
+   "    Delete channel.",
+   "DELR <number>\n"
+@@ -256,6 +262,11 @@
+   "    used to easily activate or deactivate a timer.",
+   "MOVC <number> <to>\n"
+   "    Move a channel to a new position.",
++  "MOVR <number> <new name>\n"
++  "    Move the recording with the given number. Before a recording can be\n"
++  "    moved, an LSTR command must have been executed in order to retrieve\n"
++  "    the recording numbers. The numbers don't change during subsequent MOVR\n"
++  "    commands.",
+   "MOVT <number> <to>\n"
+   "    Move a timer to a new position.",
+   "NEWC <settings>\n"
+@@ -605,6 +616,32 @@
+      }
  }
  
-+void cSVDRP::CmdRENR(const char *Option)
++void cSVDRP::CmdCPYR(const char *Option)
 +{
 +  if (*Option) {
 +     char *tail;
@@ -850,238 +1478,132 @@ diff -Nru vdr-1.7.21-vanilla/svdrp.c vdr-1.7.21-liemikuutio/svdrp.c
 +     if (recording && tail && tail != Option) {
 +        char *oldName = strdup(recording->Name());
 +        tail = skipspace(tail);
-+        if (recording->Rename(tail)) {
-+           Reply(250, "Recording \"%s\" renamed to \"%s\"", oldName, recording->Name());
-+           ::Recordings.ChangeState();
-+           ::Recordings.TouchUpdate();
++        if (!cFileTransfer::Active()) {
++           if (cFileTransfer::Start(recording, tail, true))
++              Reply(250, "Copying recording \"%s\" to \"%s\"", oldName, tail);
++           else
++              Reply(554, "Can't start file transfer");
 +           }
 +        else
-+           Reply(554, "Error while renaming recording \"%s\" to \"%s\"!", oldName, tail);
++           Reply(554, "File transfer already active");
 +        free(oldName);
 +        }
 +     else
-+        Reply(550, "Recording \"%d\" not found%s", n, Recordings.Count() ? "" : " (use LSTR before renaming)");
++        Reply(550, "Recording \"%d\" not found%s", n, Recordings.Count() ? "" : " (use LSTR before copying)");
 +     }
 +  else
 +     Reply(501, "Invalid Option \"%s\"", Option);
 +}
-+						
- void cSVDRP::CmdSTAT(const char *Option)
- {
-   if (*Option) {
-@@ -1625,6 +1655,7 @@
-   else if (CMD("PLUG"))  CmdPLUG(s);
-   else if (CMD("PUTE"))  CmdPUTE(s);
-   else if (CMD("REMO"))  CmdREMO(s);
-+  else if (CMD("RENR"))  CmdRENR(s);
-   else if (CMD("SCAN"))  CmdSCAN(s);
-   else if (CMD("STAT"))  CmdSTAT(s);
-   else if (CMD("UPDT"))  CmdUPDT(s);
-diff -Nru vdr-1.7.21-vanilla/svdrp.h vdr-1.7.21-liemikuutio/svdrp.h
---- vdr-1.7.21-vanilla/svdrp.h	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/svdrp.h	2011-09-04 16:54:42.000000000 +0300
-@@ -79,6 +79,7 @@
-   void CmdPLUG(const char *Option);
-   void CmdPUTE(const char *Option);
-   void CmdREMO(const char *Option);
-+  void CmdRENR(const char *Option);
-   void CmdSCAN(const char *Option);
-   void CmdSTAT(const char *Option);
-   void CmdUPDT(const char *Option);
-diff -Nru vdr-1.7.21-vanilla/tools.c vdr-1.7.21-liemikuutio/tools.c
---- vdr-1.7.21-vanilla/tools.c	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/tools.c	2011-09-04 17:09:44.000000000 +0300
-@@ -285,6 +285,24 @@
-   return n;
- }
- 
-+cString StripLastDirectory(const char *DirName)
-+{
-+  if (DirName && *DirName) {
-+     cString s(DirName);
-+     int l = strlen(*s);
-+     const char *p = *s + l;
-+     while (l > 0) {
-+           if (*p-- == '/')
-+              break;
-+           l--;
-+           }
-+     if (l)
-+        s = s.Truncate(l);
-+     return s; 
-+     }
-+  return NULL;
-+}
 +
- cString AddDirectory(const char *DirName, const char *FileName)
+ void cSVDRP::CmdDELC(const char *Option)
  {
-   return cString::sprintf("%s/%s", DirName && *DirName ? DirName : ".", FileName);
-diff -Nru vdr-1.7.21-vanilla/tools.h vdr-1.7.21-liemikuutio/tools.h
---- vdr-1.7.21-vanilla/tools.h	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/tools.h	2011-09-04 17:10:11.000000000 +0300
-@@ -212,6 +212,7 @@
-     ///< (based on 1024). Everything after the first non-numeric character is
-     ///< silently ignored, as are any characters other than the ones mentionend here.
- cString itoa(int n);
-+cString StripLastDirectory(const char *DirName);
- cString AddDirectory(const char *DirName, const char *FileName);
- bool EntriesOnSameFileSystem(const char *File1, const char *File2);
- int FreeDiskSpaceMB(const char *Directory, int *UsedMB = NULL);
-diff -Nru vdr-1.7.21-vanilla/videodir.c vdr-1.7.21-liemikuutio/videodir.c
---- vdr-1.7.21-vanilla/videodir.c	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/videodir.c	2011-09-04 17:10:44.000000000 +0300
-@@ -163,6 +163,143 @@
-   return true;
+   if (*Option) {
+@@ -1279,6 +1316,32 @@
+      Reply(501, "Missing channel number");
  }
  
-+bool MoveVideoFile(const char *SourceName, const char *TargetName, bool MakeCopy)
++void cSVDRP::CmdMOVR(const char *Option)
 +{
-+  const char* delim = "/";
-+  cString source = SourceName;
-+  cString target = TargetName;
-+
-+  // add missing directory delimiters
-+  if (!endswith(*source, delim))
-+     source = cString::sprintf("%s%s", *source, delim);
-+  if (!endswith(*target, delim))
-+     target = cString::sprintf("%s%s", *target, delim);
-+
-+  if (strcmp(*source, *target)) {
-+     // validate target directory
-+     if (strstr(*target, *source)) {
-+        esyslog("ERROR: cannot move directory under its' sub-directory!\n");
-+        return false;
-+        }
-+
-+     RemoveFileOrDir(*target);
-+     if (!MakeDirs(*target, true)) {
-+        esyslog("ERROR: cannot create directory %s", *target);
-+        return false;
-+        }
-+
-+     if (!MakeCopy && EntriesOnSameFileSystem(*source, *target)) {
-+        if (rename(*source, *target) == -1) {
-+           LOG_ERROR_STR(*source);
-+           return false;
-+           }
-+        }
-+     else {
-+        int required = DirSizeMB(*source);
-+        int available = FreeDiskSpaceMB(*target);
-+
-+        // validate free space
-+        if (required < available) {
-+           cReadDir d(*source);
-+           struct dirent *e;
-+           bool success = true;
-+
-+           // allocate copying buffer
-+           const int len = 1024 * 1024;
-+           char *buffer = MALLOC(char, len);
-+           if (!buffer) {
-+              esyslog("ERROR: cannot allocate renaming buffer");
-+              return false;
-+              }
-+
-+           // loop through all files, but skip all sub-directories
-+           while ((e = d.Next()) != NULL) {
-+                 // skip generic entries
-+                 if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..") && strcmp(e->d_name, "lost+found")) {
-+                    cString sourceFile = cString::sprintf("%s%s", *source, e->d_name);
-+                    cString targetFile = cString::sprintf("%s%s", *target, e->d_name);
-+
-+                    // copy only regular files
-+                    struct stat sts;
-+                    if (!stat(*sourceFile, &sts) && S_ISREG(sts.st_mode)) {
-+                       int r = -1, w = -1;
-+                       cUnbufferedFile *inputFile = cUnbufferedFile::Create(*sourceFile, O_RDONLY | O_LARGEFILE);
-+                       cUnbufferedFile *outputFile = cUnbufferedFile::Create(*targetFile, O_RDWR | O_CREAT | O_LARGEFILE);
-+
-+                       // validate files
-+                       if (!inputFile || !outputFile) {
-+                          esyslog("ERROR: cannot open file %s or %s", *sourceFile, *targetFile);
-+                          success = false;
-+                          break;
-+                          }
-+
-+                       // do actual copy
-+                       dsyslog("copying %s to %s", *sourceFile, *targetFile);
-+                       do {
-+                         r = inputFile->Read(buffer, len);
-+                         if (r > 0)
-+                            w = outputFile->Write(buffer, r);
-+                         else
-+                            w = 0;
-+                       } while (r > 0 && w > 0);
-+                       DELETENULL(inputFile);
-+                       DELETENULL(outputFile);
-+
-+                       // validate result
-+                       if (r < 0 || w < 0) {
-+                          success = false;
-+                          break;
-+                          }
-+                       }
-+                    }
-+                 }
-+
-+           // release allocated buffer
-+           free(buffer);
-+
-+           // delete all created target files and directories
-+           if (!success) {
-+              target = StripLastDirectory(*target);
-+              if (!RemoveFileOrDir(*target, true))
-+                 esyslog("ERROR: cannot remove target %s", *target);
-+              target = StripLastDirectory(*target);
-+              if (!RemoveEmptyDirectories(*target, true))
-+                 esyslog("ERROR: cannot remove target directory %s", *target);
-+              esyslog("ERROR: copying failed");
-+              return false;
-+              }
-+           else if (!MakeCopy && !RemoveFileOrDir(*source, true)) { // delete source files
-+              esyslog("ERROR: cannot remove source directory %s", *source);
-+              return false;
-+              }
-+
-+           // delete all empty source directories
-+           if (!MakeCopy) {
-+              source = StripLastDirectory(*source);
-+              while (!strcmp(*source, VideoDirectory)) {
-+                    source = StripLastDirectory(*source);
-+                    if (!RemoveEmptyDirectories(*source, true))
-+                        break;
-+                    }
-+              }
-+           }
-+        else {
-+           esyslog("ERROR: %sing requires %dMB - only %dMB available", MakeCopy ? "copy" : "mov", required, available);
-+           // delete all created empty target directories
-+           target = StripLastDirectory(*target);
-+           while (!strcmp(*target, VideoDirectory)) {
-+                 target = StripLastDirectory(*target);
-+                 if (!RemoveEmptyDirectories(*target, true))
-+                     break;
-+                 }
-+           return false;
++  if (*Option) {
++     char *tail;
++     int n = strtol(Option, &tail, 10);
++     cRecording *recording = Recordings.Get(n - 1);
++     if (recording && tail && tail != Option) {
++        char *oldName = strdup(recording->Name());
++        tail = skipspace(tail);
++        if (!cFileTransfer::Active()) {
++           if (cFileTransfer::Start(recording, tail))
++              Reply(250, "Moving recording \"%s\" to \"%s\"", oldName, tail);
++           else
++              Reply(554, "Can't start file transfer");
 +           }
++        else
++           Reply(554, "File transfer already active");
++        free(oldName);
 +        }
++     else
++        Reply(550, "Recording \"%d\" not found%s", n, Recordings.Count() ? "" : " (use LSTR before moving)");
 +     }
-+
-+  return true;
++  else
++     Reply(501, "Invalid Option \"%s\"", Option);
 +}
 +
- bool RemoveVideoFile(const char *FileName)
+ void cSVDRP::CmdMOVT(const char *Option)
  {
-   return RemoveFileOrDir(FileName, true);
-diff -Nru vdr-1.7.21-vanilla/videodir.h vdr-1.7.21-liemikuutio/videodir.h
---- vdr-1.7.21-vanilla/videodir.h	2011-09-04 16:52:40.000000000 +0300
-+++ vdr-1.7.21-liemikuutio/videodir.h	2011-09-04 17:10:59.000000000 +0300
-@@ -18,6 +18,7 @@
- cUnbufferedFile *OpenVideoFile(const char *FileName, int Flags);
- int CloseVideoFile(cUnbufferedFile *File);
- bool RenameVideoFile(const char *OldName, const char *NewName);
-+bool MoveVideoFile(const char *SourceName, const char *TargetName, bool MakeCopy = false);
- bool RemoveVideoFile(const char *FileName);
- bool VideoFileSpaceAvailable(int SizeMB);
- int VideoDiskSpace(int *FreeMB = NULL, int *UsedMB = NULL); // returns the used disk space in percent
+   //TODO combine this with menu action
+@@ -1613,6 +1676,7 @@
+   s = skipspace(s);
+   if      (CMD("CHAN"))  CmdCHAN(s);
+   else if (CMD("CLRE"))  CmdCLRE(s);
++  else if (CMD("CPYR"))  CmdCPYR(s);
+   else if (CMD("DELC"))  CmdDELC(s);
+   else if (CMD("DELR"))  CmdDELR(s);
+   else if (CMD("DELT"))  CmdDELT(s);
+@@ -1628,6 +1692,7 @@
+   else if (CMD("MODC"))  CmdMODC(s);
+   else if (CMD("MODT"))  CmdMODT(s);
+   else if (CMD("MOVC"))  CmdMOVC(s);
++  else if (CMD("MOVR"))  CmdMOVR(s);
+   else if (CMD("MOVT"))  CmdMOVT(s);
+   else if (CMD("NEWC"))  CmdNEWC(s);
+   else if (CMD("NEWT"))  CmdNEWT(s);
+diff -Nru vdr-1.7.22-vanilla/svdrp.h vdr-1.7.22-liemikuutio/svdrp.h
+--- vdr-1.7.22-vanilla/svdrp.h	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/svdrp.h	2011-12-04 18:39:13.000000000 +0200
+@@ -56,6 +56,7 @@
+   void PrintHelpTopics(const char **hp);
+   void CmdCHAN(const char *Option);
+   void CmdCLRE(const char *Option);
++  void CmdCPYR(const char *Option);
+   void CmdDELC(const char *Option);
+   void CmdDELR(const char *Option);
+   void CmdDELT(const char *Option);
+@@ -71,6 +72,7 @@
+   void CmdMODC(const char *Option);
+   void CmdMODT(const char *Option);
+   void CmdMOVC(const char *Option);
++  void CmdMOVR(const char *Option);
+   void CmdMOVT(const char *Option);
+   void CmdNEWC(const char *Option);
+   void CmdNEWT(const char *Option);
+diff -Nru vdr-1.7.22-vanilla/vdr.c vdr-1.7.22-liemikuutio/vdr.c
+--- vdr-1.7.22-vanilla/vdr.c	2011-12-04 18:37:58.000000000 +0200
++++ vdr-1.7.22-liemikuutio/vdr.c	2011-12-04 18:39:13.000000000 +0200
+@@ -45,6 +45,7 @@
+ #include "dvbdevice.h"
+ #include "eitscan.h"
+ #include "epg.h"
++#include "filetransfer.h"
+ #include "i18n.h"
+ #include "interface.h"
+ #include "keys.h"
+@@ -1256,6 +1257,12 @@
+               else
+                  Skins.Message(mtInfo, tr("Editing process finished"));
+               }
++           if (!cFileTransfer::Active() && cFileTransfer::Ended()) {
++              if (cFileTransfer::Error())
++                 Skins.Message(mtError, tr("File transfer failed!"));
++              else
++                 Skins.Message(mtInfo, tr("File transfer finished"));
++              }
+            }
+ 
+         // SIGHUP shall cause a restart:
+@@ -1271,7 +1278,7 @@
+               ShutdownHandler.countdown.Cancel();
+            }
+ 
+-        if ((Now - LastInteract) > ACTIVITYTIMEOUT && !cRecordControls::Active() && !cCutter::Active() && !Interface->HasSVDRPConnection() && (Now - cRemote::LastActivity()) > ACTIVITYTIMEOUT) {
++        if ((Now - LastInteract) > ACTIVITYTIMEOUT && !cRecordControls::Active() && !cCutter::Active() && !cFileTransfer::Active() && !Interface->HasSVDRPConnection() && (Now - cRemote::LastActivity()) > ACTIVITYTIMEOUT) {
+            // Handle housekeeping tasks
+ 
+            // Shutdown:
+@@ -1318,6 +1325,7 @@
+ 
+   PluginManager.StopPlugins();
+   cRecordControls::Shutdown();
++  cFileTransfer::Stop();
+   cCutter::Stop();
+   delete Menu;
+   cControl::Shutdown();

-- 
vdr packaging repository



More information about the pkg-vdr-dvb-changes mailing list