summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--HISTORY21
-rw-r--r--README36
-rw-r--r--extrecmenu.c21
-rw-r--r--i18n.c232
-rw-r--r--i18n.c.orig1087
-rw-r--r--mymenueditrecording.c304
-rw-r--r--mymenurecordings.c723
-rw-r--r--mymenurecordings.h35
-rw-r--r--mymenusetup.c16
-rw-r--r--mymenusetup.h8
-rw-r--r--myreplaycontrol.c25
-rw-r--r--myreplaycontrol.h4
-rw-r--r--patchfont.c98
-rw-r--r--tools.c329
-rw-r--r--tools.h65
15 files changed, 2424 insertions, 580 deletions
diff --git a/HISTORY b/HISTORY
index ca4c3dc..c2bbeaf 100644
--- a/HISTORY
+++ b/HISTORY
@@ -1,6 +1,25 @@
VDR Plugin 'extrecmenu' Revision History
----------------------------------------
+2007-01-??: Version 0.13
+- added two setup option to adjust the plugin behaviour to whose of VDR's
+ recording menu (jumping to last replayed recording, call plugin after
+ replay ends)
+- only editing of cutting recordings is prevented now
+- moving recordings between filesystems is now possible; includes:
+ * check for enough free disk space on target filesystem
+ * switch to limit bandwith (a.t.m. 2MBytes/sec)
+ * prevent editing of recordings that are moved
+ * marker for recordings, that are moved
+- added marker for cutting and moving recording entries
+- added marker to title bar for cutting and moving recordings
+- recording info menu shows additional informations (name, path, channel,
+ size, lifetime, priority)
+- added setup option to select between plugin's and VDR's recording info menu
+- dvd.vdr is ignored, as long as a 001.vdr is present
+- fixed following issue (again): if there are more then one recording with the
+ same name, only one of it is shown if all recording details are hidden
+
2006-12-31: Version 0.12c
- dvd id for archive dvd would be first read out when the corresponding entry
is selected; this should prevent delays while opening the plugin
@@ -59,7 +78,7 @@ VDR Plugin 'extrecmenu' Revision History
- 'Play' and 'Menu'->'Blue' for resuming a replay work now; BUT: the replay
isn't done with the plugin if you start replaying this way, means if you stop
the replay you come to VDR's recordings menu
-- switched off editing of details (priority and lifetime) or archive dvd
+- switched off editing of details (priority and lifetime) of archive dvd
recordings to avoid trouble with the dir name that identifies it on the media
- added option to mark last replayed recording while opening the plugin
- added possibilty to include video dvds into the recordings hierarchy; see
diff --git a/README b/README
index 9d77c97..0997126 100644
--- a/README
+++ b/README
@@ -1,6 +1,7 @@
This is a "plugin" for the Video Disk Recorder (VDR).
+
Written by: Martin Prochnow (nordlicht@martins-kabuff.de)
-Project's homepage: http://martins-kabuff.de/extrecmenu.html
+Project's homepage: http://martins-kabuff.de/extrecmenu_en.html
See the file COPYING for license information. See top of *.c for additional
copyright information.
@@ -14,13 +15,23 @@ I want to thank to following contributors:
-------------------------------------------------------------------------------
Description
-------------------------------------------------------------------------------
-This plugin provides a recordings menu enhanced with the possibility to
-rename or move recordings and directories. The display of recording date, time
-and length is configurable. Sorting by name or date is selectable for each
-directory. If you use the PIN-plugin, the replay and editing of recordings is
-protected. The plugin also handles archive dvds of VDR recordings (as known
-from the DVDArchive-patch for VDR). This plugin extends VDR's '-r'-option with
-messages for deleting, moving and renaming a recording.
+The EXTended RECordings MENU plugin provides additional functions to VDR's
+recordings menu:
+
+* renaming recordings and directories
+* moving recordings and directories, also between different filesystems
+* functionality of the DVDArchiv-patch (see below)
+* adjustable display of recording's length, date and size
+* directories are always shown on top of the list
+* reworked layout using icons for showing the status of list entries
+ (directory, new recording, moving recording, cutting recording, dvd archiv
+ entry)
+* sorting by name or date, adjustable for each directory
+* ascending/descending sorting
+* extends VDR's '-r'-option commands with 'move' and 'rename'
+* extended recordings info menu, shows name, path, channel, size, lifetime and
+ priority of the recording
+* protects recordings in co-work with the PIN-plugin
-------------------------------------------------------------------------------
Installation
@@ -56,7 +67,9 @@ renaming will be executed.
Moving: Press 'Yellow', then 'Green'. Now you are at the base directory of the
/video-directory-hierarchy. 'Ok' opens sub-directories, with 'Yellow' you can
-create new dirs. With 'Blue' moving to the selected dir will be executed.
+create new dirs. With 'Blue' moving to the selected dir will be executed. At
+the moment it is only possible to move one recording or directory to another
+filesystem.
Details: Select a recording, press 'Yellow', then 'Blue'. In this menu you can
edit the lifetime and priority of the selected recording. Editing the details
@@ -66,7 +79,8 @@ which the recording is found on the disc.
Sort recordings
-------------------------------------------------------------------------------
All directories are sorted by date by default. To change the sorting, simply
-press '0'.
+press '0'. Ascending or descending sorting is selectable at plugin's setup
+menu.
-------------------------------------------------------------------------------
Archiv-DVD-functionality
@@ -102,5 +116,5 @@ is started to play the video dvd.
-------------------------------------------------------------------------------
Do you like this plugin? Support the developer! Go to the project homepage and
-make a donation over the PayPal donation button.
+make a donation over the PayPal button.
-------------------------------------------------------------------------------
diff --git a/extrecmenu.c b/extrecmenu.c
index 87c0321..0b900a8 100644
--- a/extrecmenu.c
+++ b/extrecmenu.c
@@ -2,13 +2,16 @@
* See the README file for copyright information and how to reach the author.
*/
+#include <string>
#include <vdr/plugin.h>
#include "mymenusetup.h"
#include "mymenurecordings.h"
#include "i18n.h"
#include "tools.h"
-static const char *VERSION = "0.12c";
+using namespace std;
+
+static const char *VERSION = "0.13";
static const char *DESCRIPTION = "Extended recordings menu";
static const char *MAINMENUENTRY = "ExtRecMenu";
@@ -29,6 +32,7 @@ class cPluginExtrecmenu:public cPlugin
virtual bool Start(void);
virtual void Stop(void);
virtual void Housekeeping(void);
+ virtual cString Active(void);
virtual const char *MainMenuEntry(void){return mysetup.HideMainMenuEntry?NULL:MAINMENUENTRY;}
virtual cOsdObject *MainMenuAction(void);
virtual cMenuSetupPage *SetupMenu(void);
@@ -80,6 +84,13 @@ void cPluginExtrecmenu::Housekeeping(void)
{
}
+cString cPluginExtrecmenu::Active(void)
+{
+ if(MoveThread.Active())
+ return tr("Move recordings in progress");
+ return NULL;
+}
+
cOsdObject *cPluginExtrecmenu::MainMenuAction(void)
{
return new myMenuRecordings();
@@ -111,6 +122,14 @@ bool cPluginExtrecmenu::SetupParse(const char *Name,const char *Value)
mysetup.ShowNewRecs=atoi(Value);
else if(!strcasecmp(Name,"DescendSorting"))
mysetup.DescendSorting=atoi(Value);
+ else if(!strcasecmp(Name,"GoLastReplayed"))
+ mysetup.GoLastReplayed=atoi(Value);
+ else if(!strcasecmp(Name,"ReturnToPlugin"))
+ mysetup.ReturnToPlugin=atoi(Value);
+ else if(!strcasecmp(Name,"LimitBandwidth"))
+ mysetup.LimitBandwidth=atoi(Value);
+ else if(!strcasecmp(Name,"UseVDRsRecInfoMenu"))
+ mysetup.UseVDRsRecInfoMenu=atoi(Value);
else
return false;
return true;
diff --git a/i18n.c b/i18n.c
index 2e0afaa..5ae2d35 100644
--- a/i18n.c
+++ b/i18n.c
@@ -55,6 +55,7 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
+ "Retour",
"",
"",
"",
@@ -68,8 +69,7 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "",
- "",
+ "Zpět",
},
{ "Button$Cancel",
"Abbrechen",
@@ -451,7 +451,7 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "",
+ "Afficher les nouveaux symbols alternatifs",
"",
"Merkitse uudet tallenteet symbolilla",
"",
@@ -627,7 +627,7 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "",
+ "Erreur sudo ou mount --bind / umount (Systeme VFAT)",
"",
"Sudo tai mount --bind / umount -komento epäonnistui (VFAT)!",
"",
@@ -709,15 +709,15 @@ const tI18nPhrase Phrases[] = {
"",
"Přejmenování/Přesun selhal!",
},
- { "Creating directories failed!",
- "Verzeichnisse anlegen fehlgeschlagen!",
+ { "Invalid filename!",
+ "Ungültiger Dateiname!",
"",
"",
"",
"",
- "Echecs lors de la création du dossier!",
+ "Nom de fichiers n'est pas valide'",
"",
- "Hakemiston luonti epäonnistui!",
+ "Virheellinen tiedoston nimi!",
"",
"",
"",
@@ -729,17 +729,17 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "Selhalo vytvoření adresáře!",
+ "Chybné jméno souboru!",
},
- { "Invalid filename!",
- "Ungültiger Dateiname!",
+ { "Moving into own sub-directory not allowed!",
+ "Verschieben in eigenes Unterverzeichnis nicht erlaubt!",
"",
"",
"",
"",
- "Nom de fichiers n'est pas valide'",
+ "Déplacer dans le sous-dossier propre, n'est pas possible!",
"",
- "Virheellinen tiedoston nimi!",
+ "Siirto omaan alihakemistoon ei ole sallittu!",
"",
"",
"",
@@ -751,17 +751,17 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "Chybné jméno souboru!",
+ "Přesun do vlastního podadresáře není povolen!",
},
- { "Editing not allowed while cutting!",
- "Editieren während des Schneidens nicht erlaubt!",
+ { "Sort by name",
+ "Sortieren nach Namen",
"",
"",
"",
"",
- "Editer pendant la découpe n'est pas possible!",
+ "Triage selon le nom",
"",
- "Muokkaus leikkauksen aikana ei ole sallittu!",
+ "Tallenteet järjestetään nimen mukaan",
"",
"",
"",
@@ -773,17 +773,17 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "Je spuštěn střih - Editovat nyní nelze!",
+ "Třídit podle jména",
},
- { "Moving into own sub-directory not allowed!",
- "Verschieben in eigenes Unterverzeichnis nicht erlaubt!",
+ { "Sort by date",
+ "Sortieren nach Datum",
"",
"",
"",
"",
- "Déplacer dans le sous-dossier propre, n'est pas possible!",
+ "Triage selon date",
"",
- "Siirto omaan alihakemistoon ei ole sallittu!",
+ "Tallenteet järjestetään päivämäärän mukaan",
"",
"",
"",
@@ -795,22 +795,41 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
- "Přesun do vlastního podadresáře není povolen!",
+ "Třídit podle data",
},
- { "Sort by name",
- "Sortieren nach Namen",
+ { "Show nr. of new recordings in a directory",
+ "Anzahl der neuen Aufz. im Ordner anzeigen",
+ "",
+ "",
+ "",
+ "",
+ "Afficher le nombre de nouveaux enregistrements dans les dossiers",
+ "",
+ "Näytä uusien tallenteiden lukumäärä",
"",
"",
"",
"",
"",
"",
- "Tallenteet järjestetään nimen mukaan",
"",
"",
"",
"",
"",
+ "Zobrazovat počet nových nahrávek v adresáři",
+ },
+ { "Sorting",
+ "Sortierung",
+ "",
+ "",
+ "",
+ "",
+ "Triage",
+ "",
+ "Järjestys",
+ "",
+ "",
"",
"",
"",
@@ -818,16 +837,23 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
+ "",
+ "",
+ "Třídění",
},
- { "Sort by date",
- "Sortieren nach Datum",
+ { "ascending",
+ "aufsteigend",
"",
"",
"",
"",
+ "montant",
+ "",
+ "nouseva",
+ "",
+ "",
"",
"",
- "Tallenteet järjestetään päivämäärän mukaan",
"",
"",
"",
@@ -835,21 +861,42 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
+ "vzestupně",
+ },
+ { "descending",
+ "absteigend",
+ "",
+ "",
+ "",
+ "",
+ "descendant",
+ "",
+ "laskeva",
+ "",
+ "",
"",
"",
"",
"",
"",
+ "",
+ "",
+ "",
+ "",
+ "sestupně",
},
- { "Show nr. of new recordings in a directory",
- "Anzahl der neuen Aufn. im Ordners anzeigen",
+ { "Jump to last replayed recording",
+ "Springe zur zuletzt abgespielten Aufzeichnung",
"",
"",
"",
"",
+ "Retour au dernier enregistrement lu",
+ "",
+ "Siirry viimeksi toistettuun tallenteeseen",
+ "",
"",
"",
- "Näytä uusien tallenteiden lukumäärä",
"",
"",
"",
@@ -858,13 +905,41 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
+ "Skočit na poslední přehrávanou nahrávku",
+ },
+ { "Call plugin after playback",
+ "Nach Wiedergabe Plugin aufrufen",
+ "",
"",
"",
"",
+ "Aprčs la lecture démarer le plugin",
"",
+ "Avaa laajennos toiston loputtua",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Návrat do modulu po ukončení přehrávání",
},
- { "Sorting",
- "Sortierung",
+ { "Move recordings already in progress!",
+ "Es werden schon Aufzeichnungen verschoben!",
+ "",
+ "",
+ "",
+ "",
+ "Des enregistrements sont déjŕ en déplacement!",
+ "",
+ "Tallenteiden siirto on jo käynnissä!",
+ "",
+ "",
"",
"",
"",
@@ -874,7 +949,17 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
+ "Právě probíhá přesouvání nahrávek!",
+ },
+ { "Move recordings in progress",
+ "Es werden Aufzeichungen verschoben",
+ "",
+ "",
+ "",
+ "",
+ "Enregistrements en cours de déplacement",
"",
+ "Tallenteiden siirto käynnissä",
"",
"",
"",
@@ -884,13 +969,19 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
+ "",
+ "",
+ "Probíhá přesouvání nahrávek",
},
- { "ascending",
- "aufsteigend",
+ { "Limit bandwidth for move recordings",
+ "Bandbreite beim Verschieben begrenzen",
+ "",
"",
"",
"",
+ "Limiter la bande passante lors du déplacement",
"",
+ "Rajoita tallenteiden siirtokaistaa",
"",
"",
"",
@@ -902,13 +993,76 @@ const tI18nPhrase Phrases[] = {
"",
"",
"",
+ "Omezit rychlost pro přesun nahrávek",
+ },
+ { "Target filesystem filled- try anyway?",
+ "Zielpartition voll - trotzdem versuchen?",
+ "",
+ "",
+ "",
+ "",
+ "La partition de déstination est pleine - essayer tout de męme?",
+ "",
+ "Kohdepartitio täynnä - yritetäänkö silti?",
+ "",
+ "",
+ "",
+ "",
"",
"",
"",
"",
+ "",
+ "",
+ "",
+ "Cílový oddíl je plný - zkusit znovu?",
},
- { "descending",
- "absteigend",
+ { "Path",
+ "Pfad",
+ "",
+ "",
+ "",
+ "",
+ "Chemin",
+ "",
+ "Polku",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Cesta",
+ },
+ { "Size",
+ "Größe",
+ "",
+ "",
+ "",
+ "",
+ "Taille",
+ "",
+ "Koko",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Velikost",
+ },
+ { "Use VDR's recording info menu",
+ "VDR-Aufz.-Info-Menü benutzen",
"",
"",
"",
diff --git a/i18n.c.orig b/i18n.c.orig
new file mode 100644
index 0000000..bdf130f
--- /dev/null
+++ b/i18n.c.orig
@@ -0,0 +1,1087 @@
+/*
+ * See the README file for copyright information and how to reach the author.
+ */
+
+#include "i18n.h"
+
+const tI18nPhrase Phrases[] = {
+ { "Extended recordings menu",
+ "Erweitertes Aufzeichnungs-Menü",
+ "",
+ "",
+ "",
+ "",
+ "Menu enregistrement étandu",
+ "",
+ "Laajennettu tallennevalikko",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Rozšířené menu nahrávek",
+ },
+ { "Button$Open",
+ "Öffnen",
+ "",
+ "",
+ "",
+ "",
+ "Ouvrir",
+ "",
+ "Avaa",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Otevřít",
+ },
+ { "Button$Back",
+ "Zurück",
+ "",
+ "",
+ "",
+ "",
+ "Retour",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Button$Cancel",
+ "Abbrechen",
+ "",
+ "",
+ "",
+ "",
+ "Interrompre",
+ "",
+ "Peruuta",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Zrušit",
+ },
+ { "Button$Play",
+ "Wiedergabe",
+ "",
+ "",
+ "",
+ "",
+ "Montrer",
+ "",
+ "Toista",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Přehrát",
+ },
+ { "Button$Commands",
+ "Befehle",
+ "",
+ "",
+ "",
+ "",
+ "Commande",
+ "",
+ "Komennot",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Příkazy",
+ },
+ { "Button$Rewind",
+ "Anfang",
+ "",
+ "",
+ "",
+ "",
+ "Début",
+ "",
+ "Alkuun",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Na začátek",
+ },
+ { "Button$Create",
+ "Anlegen",
+ "",
+ "",
+ "",
+ "",
+ "Créer",
+ "",
+ "Luo",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Vytvořit",
+ },
+ { "Button$Edit",
+ "Editieren",
+ "",
+ "",
+ "",
+ "",
+ "Éditer",
+ "",
+ "Muokkaa",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Editovat",
+ },
+ { "Button$Rename",
+ "Umbenennen",
+ "",
+ "",
+ "",
+ "",
+ "Renommer",
+ "",
+ "Nimeä",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Přejmenovat",
+ },
+ { "Button$Move",
+ "Verschieben",
+ "",
+ "",
+ "",
+ "",
+ "Déplacer",
+ "",
+ "Siirrä",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Přesunout",
+ },
+ { "Button$Delete",
+ "Löschen",
+ "",
+ "",
+ "",
+ "",
+ "Effacer",
+ "",
+ "Poista",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Smazat",
+ },
+ { "Button$Info",
+ "Info",
+ "",
+ "",
+ "",
+ "",
+ "Info",
+ "",
+ "Tiedot",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Info",
+ },
+ { "New folder",
+ "Neues Verzeichnis",
+ "",
+ "",
+ "",
+ "",
+ "Nouveau dossier",
+ "",
+ "Uusi kansio",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Nový adresář",
+ },
+ { "Rename",
+ "Umbenennen",
+ "",
+ "",
+ "",
+ "",
+ "Renommer",
+ "",
+ "Nimeä",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Přejmenovat",
+ },
+ { "Show recording date",
+ "Aufnahmedatum anzeigen",
+ "",
+ "",
+ "",
+ "",
+ "Afiicher la date d'enregistrement",
+ "",
+ "Näytä tallenteen päiväys",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Zobrazit datum nahrávky",
+ },
+ { "Show recording time",
+ "Aufnahmezeit anzeigen",
+ "",
+ "",
+ "",
+ "",
+ "Afficher l'heure d'enregistrement",
+ "",
+ "Näytä tallenteen ajankohta",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Zobrazit čas nahrávky",
+ },
+ { "Show recording length",
+ "Aufnahmelänge anzeigen",
+ "",
+ "",
+ "",
+ "",
+ "Afficher la longeur de l'enregistrement",
+ "",
+ "Näytä tallenteen kesto",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Zobrazit délku nahrávky",
+ },
+ { "Hide main menu entry",
+ "Hauptmenüeintrag ausblenden",
+ "",
+ "",
+ "",
+ "",
+ "Menu Enregistrement étandu invisible",
+ "",
+ "Piilota valinta päävalikosta",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Skrýt položku v hlavním menu",
+ },
+ { "Replace original recordings menu",
+ "Originales Aufzeichnungsmenü ersetzen",
+ "",
+ "",
+ "",
+ "",
+ "Remplacer le nenu original Enregistrement",
+ "",
+ "Korvaa alkuperäinen tallennevalikko",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Nahradit originální menu nahrávek",
+ },
+ { "Show alternative to new marker",
+ "Alternative zu Neu-Marker anzeigen",
+ "",
+ "",
+ "",
+ "",
+ "Afficher les nouveaux symbols alternatifs",
+ "",
+ "Merkitse uudet tallenteet symbolilla",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Zobrazit alternativu k novým značkám",
+ },
+ { "Please insert DVD %s",
+ "Bitte DVD %s einlegen",
+ "",
+ "",
+ "",
+ "",
+ "Mettez le DVD %s dans le lecteur",
+ "",
+ "Laita DVD %s asemaan",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Vložte prosím DVD %s",
+ },
+ { "Error while mounting DVD!",
+ "Fehler beim Einhängen der DVD!",
+ "",
+ "",
+ "",
+ "",
+ "Erreur lors du montage du DVD!",
+ "",
+ "DVD:n avaaminen epäonnistui!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Chyba během připojování DVD!",
+ },
+ { "Recording not found on DVD!",
+ "Aufzeichnung auf DVD nicht gefunden!",
+ "",
+ "",
+ "",
+ "",
+ "Il n'y a pas d'enregistrement sur le DVD!",
+ "",
+ "Tallennetta ei löydy DVD:ltä!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Nahrávka nebyla na DVD nalezena!",
+ },
+ { "Script 'dvdarchive.sh' not found!",
+ "Skript 'dvdarchive.sh' wurde nicht gefunden!",
+ "",
+ "",
+ "",
+ "",
+ "Impossible de trouver le script 'dvdarchive.sh'!",
+ "",
+ "'dvdarchive.sh'-skriptiä ei löydetä!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Skript 'dvdarchive.sh' nebyl nalezen!",
+ },
+ { "[base dir]",
+ "[Stammverzeichnis]",
+ "",
+ "",
+ "",
+ "",
+ "[Dossier racine]",
+ "",
+ "[juurihakemisto]",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "[základní adresář]",
+ },
+ { "No DVD in drive!",
+ "Keine DVD im Laufwerk!",
+ "",
+ "",
+ "",
+ "",
+ "Pas de DVD dans le lecteur!",
+ "",
+ "Asemassa ei ole DVD-levyä!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "V jednotce není DVD!",
+ },
+ { "Error while linking [0-9]*.vdr!",
+ "Fehler beim Anlegen der Symlinks [0-9]*.vdr!",
+ "",
+ "",
+ "",
+ "",
+ "Erreur lors de la création des racourcis [0-9]*.vdr!",
+ "",
+ "Tiedostojen [0-9]*.vdr linkittäminen epäonnistui!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Chyba při spojování [0-9]*.vdr!",
+ },
+ { "sudo or mount --bind / umount error (vfat system)",
+ "sudo oder mount --bind / umount Fehler (VFAT-System)",
+ "",
+ "",
+ "",
+ "",
+ "Erreur sudo ou mount --bind / umount (Systeme VFAT)",
+ "",
+ "Sudo tai mount --bind / umount -komento epäonnistui (VFAT)!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "sudo nebo mount --bind / umount selhal (VFAT-systém)",
+ },
+ { "Details",
+ "Details",
+ "",
+ "",
+ "",
+ "",
+ "Détails",
+ "",
+ "Lisätiedot",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Detaily",
+ },
+ { "DVD plugin is not installed!",
+ "Das DVD-Plugin ist nicht installiert!",
+ "",
+ "",
+ "",
+ "",
+ "Le plugin DVD n'est pas installé!",
+ "",
+ "DVD-laajennosta ei löydy!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Modul DVD není nainstalován!",
+ },
+ { "Rename/Move failed!",
+ "Umbenennen/Verschieben fehlgeschlagen!",
+ "",
+ "",
+ "",
+ "",
+ "Renommer/déplacer ŕ échoué!",
+ "",
+ "Nimeäminen/siirto epäonnistui!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Přejmenování/Přesun selhal!",
+ },
+ { "Invalid filename!",
+ "Ungültiger Dateiname!",
+ "",
+ "",
+ "",
+ "",
+ "Nom de fichiers n'est pas valide'",
+ "",
+ "Virheellinen tiedoston nimi!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Chybné jméno souboru!",
+ },
+ { "Moving into own sub-directory not allowed!",
+ "Verschieben in eigenes Unterverzeichnis nicht erlaubt!",
+ "",
+ "",
+ "",
+ "",
+ "Déplacer dans le sous-dossier propre, n'est pas possible!",
+ "",
+ "Siirto omaan alihakemistoon ei ole sallittu!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Přesun do vlastního podadresáře není povolen!",
+ },
+ { "Sort by name",
+ "Sortieren nach Namen",
+ "",
+ "",
+ "",
+ "",
+ "Triage selon le nom",
+ "",
+ "Tallenteet järjestetään nimen mukaan",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Sort by date",
+ "Sortieren nach Datum",
+ "",
+ "",
+ "",
+ "",
+ "Triage selon date",
+ "",
+ "Tallenteet järjestetään päivämäärän mukaan",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Show nr. of new recordings in a directory",
+ "Anzahl der neuen Aufz. im Ordner anzeigen",
+ "",
+ "",
+ "",
+ "",
+ "Afficher le nombre de nouveaux enregistrements dans les dossiers",
+ "",
+ "Näytä uusien tallenteiden lukumäärä",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Sorting",
+ "Sortierung",
+ "",
+ "",
+ "",
+ "",
+ "Triage",
+ "",
+ "Järjestys",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "ascending",
+ "aufsteigend",
+ "",
+ "",
+ "",
+ "",
+ "montant",
+ "",
+ "nouseva",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "descending",
+ "absteigend",
+ "",
+ "",
+ "",
+ "",
+ "descendant",
+ "",
+ "laskeva",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Jump to last replayed recording",
+ "Springe zur zuletzt abgespielten Aufzeichnung",
+ "",
+ "",
+ "",
+ "",
+ "Retour au dernier enregistrement lu",
+ "",
+ "Siirry viimeksi toistettuun tallenteeseen",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Call plugin after playback",
+ "Nach Wiedergabe Plugin aufrufen",
+ "",
+ "",
+ "",
+ "",
+ "Aprčs la lecture démarer le plugin",
+ "",
+ "Avaa laajennos toiston loputtua",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Move recordings already in progress!",
+ "Es werden schon Aufzeichnungen verschoben!",
+ "",
+ "",
+ "",
+ "",
+ "Des enregistrements sont déjŕ en déplacement!",
+ "",
+ "Tallenteiden siirto on jo käynnissä!",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Move recordings in progress",
+ "Es werden Aufzeichungen verschoben",
+ "",
+ "",
+ "",
+ "",
+ "Enregistrements en cours de déplacement",
+ "",
+ "Tallenteiden siirto käynnissä",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Limit bandwidth for move recordings",
+ "Bandbreite beim Verschieben begrenzen",
+ "",
+ "",
+ "",
+ "",
+ "Limiter la bande passante lors du déplacement",
+ "",
+ "Rajoita tallenteiden siirtokaistaa",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Target filesystem filled- try anyway?",
+ "Zielpartition voll - trotzdem versuchen?",
+ "",
+ "",
+ "",
+ "",
+ "La partition de déstination est pleine - essayer tout de męme?",
+ "",
+ "Kohdepartitio täynnä - yritetäänkö silti?",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Path",
+ "Pfad",
+ "",
+ "",
+ "",
+ "",
+ "Chemin",
+ "",
+ "Polku",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Size",
+ "Größe",
+ "",
+ "",
+ "",
+ "",
+ "Taille",
+ "",
+ "Koko",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { "Use VDR's recording info menu",
+ "VDR-Aufz.-Info-Menü benutzen",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ },
+ { NULL }
+ };
diff --git a/mymenueditrecording.c b/mymenueditrecording.c
index 3c89292..f9ce9eb 100644
--- a/mymenueditrecording.c
+++ b/mymenueditrecording.c
@@ -2,12 +2,17 @@
* See the README file for copyright information and how to reach the author.
*/
+#include <sys/vfs.h>
+#include <string>
#include <vdr/videodir.h>
#include <vdr/remote.h>
#include <vdr/menu.h>
+#include <vdr/interface.h>
#include "mymenurecordings.h"
#include "tools.h"
+using namespace std;
+
// --- myMenuRenameRecording --------------------------------------------------
myMenuRenameRecording::myMenuRenameRecording(myMenuRecordings *MenuRecordings,cRecording *Recording,const char *DirBase,const char *DirName):cOsdMenu(tr("Rename"),12)
{
@@ -53,50 +58,54 @@ myMenuRenameRecording::~myMenuRenameRecording()
eOSState myMenuRenameRecording::ProcessKey(eKeys Key)
{
- eOSState state=cOsdMenu::ProcessKey(Key);
- if(state==osContinue)
- {
- if(Key==kOk)
+ eOSState state=cOsdMenu::ProcessKey(Key);
+ if(state==osContinue)
{
- char *oldname=NULL;
- char *newname=NULL;
- char *tmppath=path[0]?ExchangeChars(strdup(path),true):NULL;
- char *tmpname=name[0]?ExchangeChars(strdup(name),true):NULL;
-
- if(strchr(name,'.')==name||!strlen(name))
- {
- Skins.Message(mtError,tr("Invalid filename!"));
- cRemote::Put(kRight);
- return osContinue;
- }
-
- if(isdir)
- asprintf(&oldname,"%s%s%s/%s",VideoDirectory,tmppath?"/":"",dirbase?dirbase:"",dirname);
- else
- oldname=strdup(recording->FileName());
-
- asprintf(&newname,"%s%s%s/%s%s",VideoDirectory,tmppath?"/":"",tmppath?tmppath:"",tmpname,isdir?"":strrchr(recording->FileName(),'/'));
-
- if(MoveRename(oldname,newname,isdir?NULL:recording,false))
- {
- state=osBack;
- menurecordings->Set(true,isdir?NULL:newname);
- }
- else
- {
- cRemote::Put(kRight);
- state=osContinue;
- }
-
- free(oldname);
- free(newname);
- free(tmppath);
- free(tmpname);
+ if(Key==kOk)
+ {
+ char *oldname=NULL;
+ char *newname=NULL;
+ char *tmppath=path[0]?ExchangeChars(strdup(path),true):NULL;
+ char *tmpname=name[0]?ExchangeChars(strdup(name),true):NULL;
+
+ if(strchr(name,'.')==name||!strlen(name))
+ {
+ Skins.Message(mtError,tr("Invalid filename!"));
+ cRemote::Put(kRight);
+ return osContinue;
+ }
+
+ if(isdir)
+ asprintf(&oldname,"%s%s%s/%s",VideoDirectory,tmppath?"/":"",dirbase?dirbase:"",dirname);
+ else
+ oldname=strdup(recording->FileName());
+
+ asprintf(&newname,"%s%s%s/%s%s",VideoDirectory,tmppath?"/":"",tmppath?tmppath:"",tmpname,isdir?"":strrchr(recording->FileName(),'/'));
+
+ if(!MakeDirs(newname,true))
+ Skins.Message(mtError,tr("Creating directories failed!"));
+ else
+ {
+ if(MoveRename(oldname,newname,isdir?NULL:recording,false))
+ {
+ state=osBack;
+ menurecordings->Set(true,isdir?NULL:newname);
+ }
+ else
+ {
+ cRemote::Put(kRight);
+ state=osContinue;
+ }
+ }
+ free(oldname);
+ free(newname);
+ free(tmppath);
+ free(tmpname);
+ }
+ if(Key==kBack)
+ return osBack;
}
- if(Key==kBack)
- return osBack;
- }
- return state;
+ return state;
}
// --- myMenuNewName ----------------------------------------------------------
@@ -222,38 +231,38 @@ myMenuMoveRecording::~myMenuMoveRecording()
void myMenuMoveRecording::Set()
{
- if(level==0)
- Add(new myMenuMoveRecordingItem(tr("[base dir]"),0));
+ if(level==0)
+ Add(new myMenuMoveRecordingItem(tr("[base dir]"),0));
- char *lastitemtext=NULL;
- myMenuMoveRecordingItem *lastitem=NULL;
- for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
- {
- if(!base||(strstr(recording->Name(),base)==recording->Name()&&recording->Name()[strlen(base)]=='~'))
+ char *lastitemtext=NULL;
+ myMenuMoveRecordingItem *lastitem=NULL;
+ for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
{
- myMenuMoveRecordingItem *item=new myMenuMoveRecordingItem(recording,level);
- if(*item->Text())
- {
- if(lastitemtext&&!strcmp(lastitemtext,item->Text())) // same text
- {
- if(lastitem&&lastitem->Level()<item->Level()) // if level of the previous item is lower, set it to the new value
- lastitem->SetLevel(item->Level());
-
- delete item;
- }
- else
+ if(!base||(strstr(recording->Name(),base)==recording->Name()&&recording->Name()[strlen(base)]=='~'))
{
- Add(item); // different text means a new item to add
- lastitem=item;
- free(lastitemtext);
- lastitemtext=strdup(lastitem->Text());
+ myMenuMoveRecordingItem *item=new myMenuMoveRecordingItem(recording,level);
+ if(*item->Text())
+ {
+ if(lastitemtext&&!strcmp(lastitemtext,item->Text())) // same text
+ {
+ if(lastitem&&lastitem->Level()<item->Level()) // if level of the previous item is lower, set it to the new value
+ lastitem->SetLevel(item->Level());
+
+ delete item;
+ }
+ else
+ {
+ Add(item); // different text means a new item to add
+ lastitem=item;
+ free(lastitemtext);
+ lastitemtext=strdup(lastitem->Text());
+ }
+ }
+ else
+ delete item;
}
- }
- else
- delete item;
}
- }
- free(lastitemtext);
+ free(lastitemtext);
}
eOSState myMenuMoveRecording::Open()
@@ -278,70 +287,123 @@ eOSState myMenuMoveRecording::Open()
eOSState myMenuMoveRecording::MoveRec()
{
- char *oldname=NULL;
- char *newname=NULL;
- char *dir=NULL;
- char *tmpdirbase=dirbase?ExchangeChars(strdup(dirbase),true):NULL;
- char *tmpdirname=dirname?ExchangeChars(strdup(dirname),true):NULL;
+ char *oldname=NULL;
+ char *newname=NULL;
+ char *dir=NULL;
+ char *tmpdirbase=dirbase?ExchangeChars(strdup(dirbase),true):NULL;
+ char *tmpdirname=dirname?ExchangeChars(strdup(dirname),true):NULL;
- eOSState state=osContinue;
+ eOSState state=osContinue;
- if(dirname)
- asprintf(&oldname,"%s%s%s/%s",VideoDirectory,dirbase?"/":"",tmpdirbase?tmpdirbase:"",tmpdirname);
- else
- oldname=strdup(recording->FileName());
+ if(dirname)
+ asprintf(&oldname,"%s%s%s/%s",VideoDirectory,dirbase?"/":"",tmpdirbase?tmpdirbase:"",tmpdirname);
+ else
+ oldname=strdup(recording->FileName());
- myMenuMoveRecordingItem *item=(myMenuMoveRecordingItem*)Get(Current());
- if(item)
- {
- if(strcmp(tr("[base dir]"),item->Text()))
+ myMenuMoveRecordingItem *item=(myMenuMoveRecordingItem*)Get(Current());
+ if(item)
{
- if(dirname)
- asprintf(&dir,"%s%s%s",base?base:"",base?"~":"",item->Text());
- else
- {
- char *p=strrchr(recording->Name(),'~');
- asprintf(&dir,"%s%s%s~%s",base?base:"",base?"~":"",item->Text(),p?p+1:recording->Name());
- }
+ if(strcmp(tr("[base dir]"),item->Text()))
+ {
+ if(dirname)
+ asprintf(&dir,"%s%s%s",base?base:"",base?"~":"",item->Text());
+ else
+ {
+ char *p=strrchr(recording->Name(),'~');
+ asprintf(&dir,"%s%s%s~%s",base?base:"",base?"~":"",item->Text(),p?p+1:recording->Name());
+ }
+ }
+ else
+ {
+ if(!dirname)
+ {
+ char *p=strrchr(recording->Name(),'~');
+ asprintf(&dir,"%s",p?++p:recording->Name());
+ }
+ }
}
else
{
- if(!dirname)
- {
- char *p=strrchr(recording->Name(),'~');
- asprintf(&dir,"%s",p?++p:recording->Name());
- }
+ if(dirname)
+ asprintf(&dir,"%s",base);
+ else
+ {
+ char *p=strrchr(recording->Name(),'~');
+ asprintf(&dir,"%s~%s",base,p?p:recording->Name());
+ }
}
- }
- else
- {
- if(dirname)
- asprintf(&dir,"%s",base);
+ if(dir)
+ dir=ExchangeChars(dir,true);
+
+ asprintf(&newname,"%s%s%s%s",VideoDirectory,dir?"/":"",dir?dir:"",strrchr(dirname?oldname:recording->FileName(),'/'));
+
+ if(!MakeDirs(newname,true))
+ Skins.Message(mtError,tr("Creating directories failed!"));
else
{
- char *p=strrchr(recording->Name(),'~');
- asprintf(&dir,"%s~%s",base,p?p:recording->Name());
+ struct stat stat1,stat2;
+ stat(oldname,&stat1);
+ stat(newname,&stat2);
+ if(stat1.st_dev==stat2.st_dev)
+ {
+ if(MoveRename(oldname,newname,dirname?NULL:recording,true))
+ {
+ clearall=true;
+ state=osBack;
+ menurecordings->Set(true);
+ }
+ }
+ else
+ {
+ if(MoveThread.Active())
+ Skins.Message(mtError,tr("Move recordings already in progress!"));
+ else
+ {
+ struct statfs fsstat;
+ statfs(newname,&fsstat);
+ int freemb=int(fsstat.f_bavail/(1024*1024/fsstat.f_bsize));
+ int recmb=0;
+
+ if(recording)
+ recmb=DirSizeMB(recording->FileName());
+ else
+ {
+ for(cRecording *rec=Recordings.First();rec;rec=Recordings.Next(rec))
+ {
+ if(!strncmp(oldname,rec->FileName(),strlen(oldname)))
+ recmb+=DirSizeMB(rec->FileName());
+ }
+ }
+
+ if(freemb-recmb <= 0)
+ {
+ if(Interface->Confirm(tr("Target filesystem filled - try anyway?")))
+ {
+ MoveThread.Start(oldname,newname,dirname?NULL:recording);
+ clearall=true;
+ state=osBack;
+ menurecordings->Set(true);
+ }
+ else
+ remove(newname); // remove created directory
+ }
+ else
+ {
+ MoveThread.Start(oldname,newname,dirname?NULL:recording);
+ clearall=true;
+ state=osBack;
+ menurecordings->Set(true);
+ }
+ }
+ }
}
- }
- if(dir)
- dir=ExchangeChars(dir,true);
+ free(oldname);
+ free(newname);
+ free(dir);
+ free(tmpdirbase);
+ free(tmpdirname);
- asprintf(&newname,"%s%s%s%s",VideoDirectory,dir?"/":"",dir?dir:"",strrchr(dirname?oldname:recording->FileName(),'/'));
-
- if(MoveRename(oldname,newname,dirname?NULL:recording,true))
- {
- clearall=true;
- state=osBack;
- menurecordings->Set(true);
- }
-
- free(oldname);
- free(newname);
- free(dir);
- free(tmpdirbase);
- free(tmpdirname);
-
- return state;
+ return state;
}
eOSState myMenuMoveRecording::Create()
diff --git a/mymenurecordings.c b/mymenurecordings.c
index 7eb996d..d0cabc1 100644
--- a/mymenurecordings.c
+++ b/mymenurecordings.c
@@ -2,11 +2,16 @@
* See the README file for copyright information and how to reach the author.
*/
+#include <string>
+#include <sstream>
+#include <iomanip>
+#include <fstream>
#include <vdr/interface.h>
#include <vdr/videodir.h>
#include <vdr/status.h>
#include <vdr/plugin.h>
#include <vdr/cutter.h>
+#include <vdr/menu.h>
#include "myreplaycontrol.h"
#include "mymenurecordings.h"
#include "mymenusetup.h"
@@ -14,6 +19,8 @@
#include "patchfont.h"
#include "tools.h"
+using namespace std;
+
extern SortList *mySortList;
// --- myMenuRecordingInfo ----------------------------------------------------
@@ -40,9 +47,52 @@ myMenuRecordingInfo::myMenuRecordingInfo(const cRecording *Recording, bool WithB
void myMenuRecordingInfo::Display(void)
{
- cOsdMenu::Display();
- DisplayMenu()->SetRecording(recording);
- cStatus::MsgOsdTextItem(recording->Info()->Description());
+ cOsdMenu::Display();
+
+ if(mysetup.UseVDRsRecInfoMenu)
+ {
+ DisplayMenu()->SetRecording(recording);
+ if(recording->Info()->Description())
+ cStatus::MsgOsdTextItem(recording->Info()->Description());
+ }
+ else
+ {
+ stringstream text;
+ text << *DateString(recording->start) << ", " << *TimeString(recording->start) << "\n\n";
+
+ if(recording->Info()->Title())
+ {
+ text << recording->Info()->Title() << "\n\n";
+ if(recording->Info()->Description())
+ text << recording->Info()->Description() << "\n\n";
+ }
+
+ string recname=recording->Name();
+ string::size_type i=recname.rfind('~');
+ if(i!=string::npos)
+ text << tr("Name") << ": " << recname.substr(i+1,recname.length()) << "\n"
+ << tr("Path") << ": " << recname.substr(0,i) << "\n";
+ else
+ text << tr("Name") << ": " << recname << "\n";
+
+ cChannel *chan=Channels.GetByChannelID(((cRecordingInfo*)recording->Info())->ChannelID());
+ if(chan)
+ text << tr("Channel") << ": " << *ChannelString(chan,0) << "\n";
+
+ int recmb=DirSizeMB(recording->FileName());
+ if(recmb<0)
+ recmb=0;
+ if(recmb > 1023)
+ text << tr("Size") << ": " << setprecision(3) << recmb/1024.0 << " GB\n";
+ else
+ text << tr("Size") << ": " << recmb << " MB\n";
+
+ text << tr("Priority") << ": " << recording->priority << "\n";
+ text << tr("Lifetime") << ": " << recording->lifetime << "\n";
+
+ DisplayMenu()->SetText(text.str().c_str(),false);
+ cStatus::MsgOsdTextItem(recording->Info()->Description());
+ }
}
eOSState myMenuRecordingInfo::ProcessKey(eKeys Key)
@@ -83,185 +133,198 @@ eOSState myMenuRecordingInfo::ProcessKey(eKeys Key)
// --- myMenuRecordingsItem ---------------------------------------------------
myMenuRecordingsItem::myMenuRecordingsItem(cRecording *Recording,int Level)
{
- totalentries=newentries=0;
- isdvd=false;
- name=NULL;
- filename=Recording->FileName();
-
- // get the level of this recording
- level=0;
- const char *s=Recording->Name();
- while(*++s)
- {
- if(*s=='~')
- level++;
- }
-
- // create the title of this item
- if(Level<level) // directory entries
- {
- s=Recording->Name();
- const char *p=s;
+ totalentries=newentries=0;
+ isdvd=false;
+ name=NULL;
+ filename=Recording->FileName();
+
+ // get the level of this recording
+ level=0;
+ const char *s=Recording->Name();
while(*++s)
{
- if(*s=='~')
- {
- if(Level--)
- p=s+1;
- else
- break;
- }
+ if(*s=='~')
+ level++;
}
- title=MALLOC(char,s-p+3);
- *title='\t';
- *(title+1)='\t';
- strn0cpy(title+2,p,s-p+1);
- name=strdup(title+2);
- }
- else
- {
- if(Level==level) // recording entries
- {
- char *buffer=NULL;
- string titlebuffer;
-
- // dvdarchive-patch functionality
- asprintf(&buffer,"%s/dvd.vdr",filename);
- isdvd=!access(buffer,R_OK);
-
- // marker
- titlebuffer=' ';
- if(Recording->IsNew()&&!mysetup.PatchNew)
- titlebuffer='*';
- if(!Recording->IsNew()&&mysetup.PatchNew)
- titlebuffer=char(128);
- if(isdvd)
- titlebuffer=char(129);
-
- titlebuffer+='\t';
-
- // date and time of recording
- struct tm tm_r;
- struct tm *t=localtime_r(&Recording->start,&tm_r);
-
- char recdate[9],rectime[6];
- strn0cpy(recdate,"",sizeof(recdate));
- strn0cpy(rectime,"",sizeof(rectime));
- snprintf(recdate,sizeof(recdate),"%02d.%02d.%02d",t->tm_mday,t->tm_mon+1,t->tm_year%100);
- snprintf(rectime,sizeof(rectime),"%02d:%02d",t->tm_hour,t->tm_min);
-
- if(mysetup.ShowRecDate)
- {
- titlebuffer+=recdate;
- titlebuffer+='\t';
- }
-
- if(mysetup.ShowRecTime)
- {
- titlebuffer+=rectime;
- titlebuffer+='\t';
- }
-
- // recording length
- if(mysetup.ShowRecLength)
- {
- char reclength[21];
- strn0cpy(reclength,"",sizeof(reclength));
- asprintf(&buffer,"%s/index.vdr",filename);
- int haslength=!access(buffer,R_OK);
- if(haslength) // calculate recording length from the size of index.vdr
- {
- struct stat buf;
- if(!stat(buffer,&buf))
- snprintf(reclength,sizeof(reclength),"%3d'",(int)(buf.st_size/12000));
- }
- else // no index -> is there a length.vdr, containing recording length as a string?
+ // create the title of this item
+ if(Level<level) // directory entries
+ {
+ s=Recording->Name();
+ const char *p=s;
+ while(*++s)
{
- free(buffer);
- asprintf(&buffer,"%s/length.vdr",filename);
- FILE *f;
- if((f=fopen(buffer,"r"))!=NULL)
- {
- char buf[8];
- if(fgets(buf,sizeof(buf),f))
+ if(*s=='~')
{
- char *p=strchr(buf,'\n');
- if(p)
- *p=0;
+ if(Level--)
+ p=s+1;
+ else
+ break;
}
- fclose(f);
- snprintf(reclength,sizeof(reclength),"%3s'\n",buf);
- }
}
- free(buffer);
-
- strreplace(reclength,' ',char(131));
-
- titlebuffer+=reclength;
- titlebuffer+='\t';
- }
-
- if(!mysetup.ShowRecDate&&!mysetup.ShowRecTime&&!mysetup.ShowRecLength)
- titlebuffer+='\t';
-
- // recording title
- s=strrchr(Recording->Name(),'~');
- titlebuffer+=s?s+1:Recording->Name();
-
- title=strdup(titlebuffer.c_str());
+ title=MALLOC(char,s-p+3);
+ *title='\t';
+ *(title+1)='\t';
+ strn0cpy(title+2,p,s-p+1);
+ name=strdup(title+2);
+ uniqid=name;
}
else
{
- if(Level>level) // any other
- title="";
- }
- }
+ if(Level==level) // recording entries
+ {
+ string buffer;
+ stringstream titlebuffer;
+ stringstream idbuffer;
+
+ buffer=filename;
+ buffer+="/001.vdr";
+ if(access(buffer.c_str(),R_OK))
+ {
+ buffer=filename;
+ buffer+="/dvd.vdr";
+ isdvd=!access(buffer.c_str(),R_OK);
+ }
+
+ // marker
+ if(MoveThread.IsMoving(filename))
+ titlebuffer << char(133); // move in progress
+ else if(isdvd)
+ titlebuffer << char(129); // dvd-archiv
+ else if(cCutter::Active() && myReplayControl::Cut && myReplayControl::Cutted &&
+ (!strcmp(filename,myReplayControl::Cut) || !strcmp(filename,myReplayControl::Cutted)))
+ titlebuffer << char(132); // cut in progress
+ else if(Recording->IsNew() && !mysetup.PatchNew)
+ titlebuffer << '*'; // new recording
+ else if(!Recording->IsNew() && mysetup.PatchNew)
+ titlebuffer << char(128); // alternative to new marker
+ else titlebuffer << ' ';
+
+ titlebuffer << '\t';
+
+ // date and time of recording
+ struct tm tm_r;
+ struct tm *t=localtime_r(&Recording->start,&tm_r);
+
+ if(mysetup.ShowRecDate)
+ titlebuffer << setw(2) << setfill('0') << t->tm_mday << '.'
+ << setw(2) << setfill('0') << t->tm_mon+1 << '.'
+ << setw(2) << setfill('0') << t->tm_year%100 << '\t';
+
+ if(mysetup.ShowRecTime)
+ titlebuffer << setw(2) << setfill('0') << t->tm_hour << '.'
+ << setw(2) << setfill('0') << t->tm_min << '\t';
+
+
+ idbuffer << t->tm_mday << t->tm_mon << t->tm_year
+ << t->tm_hour << t->tm_min;
- SetText(title);
+ // recording length
+ if(mysetup.ShowRecLength)
+ {
+ buffer=filename;
+ buffer+="/index.vdr";
+ struct stat statbuf;
+ if(!stat(buffer.c_str(),&statbuf))
+ {
+ ostringstream strbuf;
+ strbuf << setw(3) << setfill(' ') << right << (int)(statbuf.st_size/12000) << "'";
+
+ titlebuffer << myStrReplace(strbuf.str(),' ',char(131)) << '\t';
+ }
+ else
+ {
+ // get recording length from file 'length.vdr'
+ buffer=filename;
+ buffer+="/length.vdr";
+
+ ifstream in(buffer.c_str());
+ if(in)
+ {
+ if(!in.eof())
+ getline(in,buffer);
+
+ buffer+="'";
+
+ while(buffer.length()<=3)
+ buffer.insert(0,1,char(131));
+
+ titlebuffer << buffer << '\t';
+
+ in.close();
+ }
+ }
+ }
+ if(!mysetup.ShowRecDate && !mysetup.ShowRecTime && !mysetup.ShowRecLength)
+ titlebuffer << '\t';
+
+ // recording title
+ string s=Recording->Name();
+ string::size_type i=s.rfind('~');
+ if(i!=string::npos)
+ {
+ titlebuffer << s.substr(i+1,s.length()-i);
+ idbuffer << s.substr(i+1,s.length()-i);
+ }
+ else
+ {
+ titlebuffer << s;
+ idbuffer << s;
+ }
+
+ title=strdup(titlebuffer.str().c_str());
+ uniqid=idbuffer.str();
+ }
+ else
+ {
+ if(Level>level) // any other
+ title="";
+ }
+ }
+ SetText(title);
}
myMenuRecordingsItem::~myMenuRecordingsItem()
{
- free(title);
- free(name);
+ free(title);
+ free(name);
}
void myMenuRecordingsItem::IncrementCounter(bool IsNew)
{
- totalentries++;
- if(IsNew)
- newentries++;
+ totalentries++;
+ if(IsNew)
+ newentries++;
- char *buffer=NULL;
- char entries[8];
- snprintf(entries,sizeof(entries),"%3d",totalentries);
- strreplace(entries,' ',char(131));
+ char *buffer=NULL;
+ char entries[8];
+ snprintf(entries,sizeof(entries),"%3d",totalentries);
+ strreplace(entries,' ',char(131));
- if(mysetup.ShowNewRecs)
- {
- asprintf(&buffer,"%c\t%s (%d)%s%s%s%s%s",
- char(130),
- entries,
- newentries,
- (!mysetup.ShowRecDate&&!mysetup.ShowRecTime&&!mysetup.ShowRecLength)?"\t":"",
- (mysetup.ShowRecDate||mysetup.ShowRecTime||mysetup.ShowRecLength)?"\t":"",
- (mysetup.ShowRecDate&&mysetup.ShowRecTime||mysetup.ShowRecTime&&mysetup.ShowRecLength||mysetup.ShowRecLength&&mysetup.ShowRecDate)?"\t":"",
- (mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength)?"\t":"",
- name);
- }
- else
- {
- asprintf(&buffer,"%c\t%s%s%s%s%s%s",
- char(130),
- entries,
- (!mysetup.ShowRecDate&&!mysetup.ShowRecTime&&!mysetup.ShowRecLength)?"\t":"",
- (mysetup.ShowRecDate||mysetup.ShowRecTime||mysetup.ShowRecLength)?"\t":"",
- (mysetup.ShowRecDate&&mysetup.ShowRecTime||mysetup.ShowRecTime&&mysetup.ShowRecLength||mysetup.ShowRecLength&&mysetup.ShowRecDate)?"\t":"",
- (mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength)?"\t":"",
- name);
- }
- SetText(buffer,false);
+ if(mysetup.ShowNewRecs)
+ {
+ asprintf(&buffer,"%c\t%s (%d)%s%s%s%s%s",
+ char(130),
+ entries,
+ newentries,
+ (!mysetup.ShowRecDate&&!mysetup.ShowRecTime&&!mysetup.ShowRecLength)?"\t":"",
+ (mysetup.ShowRecDate||mysetup.ShowRecTime||mysetup.ShowRecLength)?"\t":"",
+ (mysetup.ShowRecDate&&mysetup.ShowRecTime||mysetup.ShowRecTime&&mysetup.ShowRecLength||mysetup.ShowRecLength&&mysetup.ShowRecDate)?"\t":"",
+ (mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength)?"\t":"",
+ name);
+ }
+ else
+ {
+ asprintf(&buffer,"%c\t%s%s%s%s%s%s",
+ char(130),
+ entries,
+ (!mysetup.ShowRecDate&&!mysetup.ShowRecTime&&!mysetup.ShowRecLength)?"\t":"",
+ (mysetup.ShowRecDate||mysetup.ShowRecTime||mysetup.ShowRecLength)?"\t":"",
+ (mysetup.ShowRecDate&&mysetup.ShowRecTime||mysetup.ShowRecTime&&mysetup.ShowRecLength||mysetup.ShowRecLength&&mysetup.ShowRecDate)?"\t":"",
+ (mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength)?"\t":"",
+ name);
+ }
+ SetText(buffer,false);
}
// --- myMenuRecordings -------------------------------------------------------
@@ -270,9 +333,9 @@ void myMenuRecordingsItem::IncrementCounter(bool IsNew)
bool myMenuRecordings::golastreplayed=false;
bool myMenuRecordings::wasdvd;
-myMenuRecordings::myMenuRecordings(const char *Base,int Level):cOsdMenu(Base?Base:"")
+myMenuRecordings::myMenuRecordings(const char *Base,int Level):cOsdMenu("")
{
- // only called if plugin menu is opened
+ // only called if plugin menu was opened
if(Level==0)
{
// patch font
@@ -283,23 +346,20 @@ myMenuRecordings::myMenuRecordings(const char *Base,int Level):cOsdMenu(Base?Bas
}
// set tabs
if(mysetup.ShowRecDate&&mysetup.ShowRecTime&&!mysetup.ShowRecLength) // recording date and time are shown, recording length not
- SetCols(2,8,6);
- else
- if(mysetup.ShowRecDate&&mysetup.ShowRecTime) // all details are shown
+ SetCols(2,8,6);
+ else if(mysetup.ShowRecDate&&mysetup.ShowRecTime) // all details are shown
SetCols(2,8,6,4);
- else
- if(mysetup.ShowRecDate&&!mysetup.ShowRecTime) // recording time is not shown
- SetCols(2,8,4);
+ else if(mysetup.ShowRecDate&&!mysetup.ShowRecTime) // recording time is not shown
+ SetCols(2,8,4);
+ else if(!mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength) // recording date is not shown
+ SetCols(2,6,4);
+ else // recording date and time are not shown; even if recording length should be not shown we must set two tabs because the details of the directories
+ {
+ if(mysetup.ShowNewRecs)
+ SetCols(2,8,3);
else
- if(!mysetup.ShowRecDate&&mysetup.ShowRecTime&&mysetup.ShowRecLength) // recording date is not shown
- SetCols(2,6,4);
- else // recording date and time are not shown; even if recording length should be not shown we must set two tabs because the details of the directories
- {
- if(mysetup.ShowNewRecs)
- SetCols(2,8,3);
- else
- SetCols(2,4,3);
- }
+ SetCols(2,4,3);
+ }
edit=false;
level=Level;
@@ -350,124 +410,149 @@ myMenuRecordings::~myMenuRecordings()
}
}
-void myMenuRecordings::SetFreeSpaceTitle()
+void myMenuRecordings::Title()
{
- int freemb;
- VideoDiskSpace(&freemb);
- int minutes=int(double(freemb)/MB_PER_MINUTE);
- char buffer[40];
- snprintf(buffer,sizeof(buffer),"%s - %2d:%02d %s",tr("Recordings"),minutes/60,minutes%60,tr("free"));
- SetTitle(buffer);
+ int freemb;
+ VideoDiskSpace(&freemb);
+ int minutes=int(double(freemb)/MB_PER_MINUTE);
+
+ stringstream buffer;
+ if(MoveThread.Active())
+ buffer << char(133);
+ if(cCutter::Active())
+ buffer << char(132);
+
+ if(MoveThread.Active() || cCutter::Active())
+ buffer << ' ';
+
+ if(base)
+ buffer << base;
+ else
+ buffer << tr("Recordings")<< " - "
+ << minutes/60 << ":"
+ << setw(2) << setfill('0') << minutes%60 << " "
+ << tr("free");
+
+ SetTitle(buffer.str().c_str());
}
void myMenuRecordings::SetHelpKeys()
{
- if(!HasSubMenu())
- {
- myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
- int newhelpkeys=0;
- if(item)
+ if(!HasSubMenu())
{
- if(item->IsDirectory())
- newhelpkeys=1;
- else
- {
- newhelpkeys=2;
- cRecording *recording=GetRecording(item);
- if(recording&&recording->Info()->Title())
- newhelpkeys=3;
- }
- if(newhelpkeys!=helpkeys)
- {
- switch(newhelpkeys)
+ myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
+ int newhelpkeys=0;
+ if(item)
{
- case 0: SetHelp(NULL);break;
- case 1: SetHelp(tr("Button$Open"),NULL,tr("Button$Edit"));break;
- case 2: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),tr("Button$Edit"),NULL);break;
- case 3: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),tr("Button$Edit"),tr("Button$Info"));break;
+ if(item->IsDirectory())
+ newhelpkeys=1;
+ else
+ {
+ newhelpkeys=2;
+ cRecording *recording=GetRecording(item);
+ if(mysetup.UseVDRsRecInfoMenu)
+ {
+ if(!recording->Info()->Title())
+ {
+ newhelpkeys=4;
+ if(MoveThread.IsMoving(recording->FileName()) || IsCutted())
+ newhelpkeys=5;
+ }
+ }
+ if(MoveThread.IsMoving(recording->FileName()) || IsCutted())
+ newhelpkeys=3;
+ }
+ if(newhelpkeys!=helpkeys)
+ {
+ switch(newhelpkeys)
+ {
+ case 0: SetHelp(NULL);break;
+ case 1: SetHelp(tr("Button$Open"),NULL,tr("Button$Edit"));break;
+ case 2: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),tr("Button$Edit"),tr("Button$Info"));break;
+ case 3: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),NULL,tr("Button$Info"));break;
+ case 4: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),tr("Button$Edit"),NULL);break;
+ case 5: SetHelp(RecordingCommands.Count()?tr("Button$Commands"):tr("Button$Play"),tr("Button$Rewind"),NULL,NULL);break;
+ }
+ }
+ helpkeys=newhelpkeys;
}
- }
- helpkeys=newhelpkeys;
}
- }
}
// create the menu list
void myMenuRecordings::Set(bool Refresh,char *current)
{
- const char *lastreplayed=current?current:myReplayControl::LastReplayed();
+ const char *lastreplayed=current?current:myReplayControl::LastReplayed();
- if(level==0)
- SetFreeSpaceTitle();
+ Title();
- cThreadLock RecordingsLock(&Recordings);
+ cThreadLock RecordingsLock(&Recordings);
- if(Refresh&&!current)
- {
- myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
- if(item)
+ if(Refresh&&!current)
{
- cRecording *recording=Recordings.GetByName(item->FileName());
- if(recording)
- lastreplayed=recording->FileName();
+ myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
+ if(item)
+ {
+ cRecording *recording=Recordings.GetByName(item->FileName());
+ if(recording)
+ lastreplayed=recording->FileName();
+ }
}
- }
- Clear();
+ Clear();
- // create my own recordings list from VDR's
- myRecList *list=new myRecList();
- for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
- list->Add(new myRecListItem(recording));
- // sort my recordings list
- char path[BUFSIZ];
- snprintf(path,sizeof(path),"%s/%s",VideoDirectory,base?base:"");
- list->Sort(mySortList->Find(path));
-
- // needed for move recording menu
- Recordings.Sort();
-
- char *lastitemtext=NULL;
- myMenuRecordingsItem *lastitem=NULL;
- for(myRecListItem *listitem=list->First();listitem;listitem=list->Next(listitem))
- {
- cRecording *recording=listitem->recording;
- if(!base||(strstr(listitem->recording->Name(),base)==listitem->recording->Name()&&listitem->recording->Name()[strlen(base)]=='~'))
+ // create my own recordings list from VDR's
+ myRecList *list=new myRecList();
+ for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
+ list->Add(new myRecListItem(recording));
+ // sort my recordings list
+ char path[BUFSIZ];
+ snprintf(path,sizeof(path),"%s/%s",VideoDirectory,base?base:"");
+ list->Sort(mySortList->Find(path));
+
+ // needed for move recording menu
+ Recordings.Sort();
+
+ char *lastitemtext=NULL;
+ myMenuRecordingsItem *lastitem=NULL;
+ for(myRecListItem *listitem=list->First();listitem;listitem=list->Next(listitem))
{
- myMenuRecordingsItem *recitem=new myMenuRecordingsItem(listitem->recording,level);
- if(*recitem->Text()&&((!lastitem||strcmp(recitem->Text(),lastitemtext))||!recitem->IsDirectory()))
- {
- Add(recitem);
- lastitem=recitem;
- free(lastitemtext);
- lastitemtext=strdup(lastitem->Text());
- }
- else
- delete recitem;
-
- if(lastitem)
- {
- if(lastitem->IsDirectory())
- lastitem->IncrementCounter(recording->IsNew());
- if(lastreplayed&&!strcmp(lastreplayed,recording->FileName()))
+ cRecording *recording=listitem->recording;
+ if(!base||(strstr(listitem->recording->Name(),base)==listitem->recording->Name()&&listitem->recording->Name()[strlen(base)]=='~'))
{
- if(golastreplayed||Refresh)
- {
- SetCurrent(lastitem);
- if(recitem&&!recitem->IsDirectory())
- if(!cControl::Control())
- golastreplayed=false;
- }
- if(recitem&&!recitem->IsDirectory()&&recitem->IsDVD()&&!cControl::Control())
- cReplayControl::ClearLastReplayed(cReplayControl::LastReplayed());
+ myMenuRecordingsItem *recitem=new myMenuRecordingsItem(listitem->recording,level);
+ if(*recitem->UniqID() && ((!lastitem || strcmp(recitem->UniqID(),lastitemtext))))
+ {
+ Add(recitem);
+ lastitem=recitem;
+ free(lastitemtext);
+ lastitemtext=strdup(lastitem->UniqID());
+ }
+ else
+ delete recitem;
+
+ if(lastitem)
+ {
+ if(lastitem->IsDirectory())
+ lastitem->IncrementCounter(recording->IsNew());
+ if(lastreplayed&&!strcmp(lastreplayed,recording->FileName()))
+ {
+ if(golastreplayed||Refresh)
+ {
+ SetCurrent(lastitem);
+ if(recitem && !recitem->IsDirectory() && !cControl::Control() && !mysetup.GoLastReplayed)
+ golastreplayed=false;
+ }
+ if(recitem&&!recitem->IsDirectory()&&recitem->IsDVD()&&!cControl::Control())
+ cReplayControl::ClearLastReplayed(cReplayControl::LastReplayed());
+ }
+ }
}
- }
}
- }
- free(lastitemtext);
- delete list;
- if(Refresh)
- Display();
+ free(lastitemtext);
+ delete list;
+ if(Refresh)
+ Display();
}
// returns the corresponding recording to an item
@@ -750,17 +835,19 @@ eOSState myMenuRecordings::MoveRec()
// opens an info screen to a recording
eOSState myMenuRecordings::Info(void)
{
- if(HasSubMenu()||Count()==0)
- return osContinue;
+ if(HasSubMenu()||Count()==0)
+ return osContinue;
- myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
- if(item&&!item->IsDirectory())
- {
- cRecording *recording=GetRecording(item);
- if(recording&&recording->Info()->Title())
- return AddSubMenu(new myMenuRecordingInfo(recording,true));
- }
- return osContinue;
+ myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
+ if(item&&!item->IsDirectory())
+ {
+ cRecording *recording=GetRecording(item);
+ if(mysetup.UseVDRsRecInfoMenu && (!recording || recording && !recording->Info()->Title()))
+ return osContinue;
+ else
+ return AddSubMenu(new myMenuRecordingInfo(recording,true));
+ }
+ return osContinue;
}
// execute a command for a recording
@@ -816,6 +903,30 @@ eOSState myMenuRecordings::ChangeSorting()
return osContinue;
}
+bool myMenuRecordings::IsCutted()
+{
+ if(cCutter::Active()) // cut in progress?
+ {
+ if(myReplayControl::Cut && myReplayControl::Cutted) // are there the paths to the cutted recording?
+ {
+ myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
+ if(item)
+ {
+ cRecording *recording=GetRecording(item);
+ if(recording)
+ {
+ if(!strcmp(recording->FileName(),myReplayControl::Cut) || !strcmp(recording->FileName(),myReplayControl::Cutted))
+ return true; // selected recording is cutted
+ else
+ return false; // seleted recording is not cutted
+ }
+ }
+ }
+ return true; // cut is in progress but i don't know for which recording, so editing for all recordings is prohibited
+ }
+ return false; // no cut in progress
+}
+
eOSState myMenuRecordings::ProcessKey(eKeys Key)
{
eOSState state;
@@ -854,23 +965,30 @@ eOSState myMenuRecordings::ProcessKey(eKeys Key)
case kOk: return Play();
case kRed: return (helpkeys>1&&RecordingCommands.Count())?Commands():Play();
case kGreen: return Rewind();
- case kYellow: if(cCutter::Active())
- Skins.Message(mtError,tr("Editing not allowed while cutting!"));
- else
+ case kYellow: if(!IsCutted())
{
- myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
+ myMenuRecordingsItem *item=(myMenuRecordingsItem*)Get(Current());
+ if(item)
+ {
+ cRecording *rec=GetRecording(item);
+ if(rec)
+ {
+ if(MoveThread.IsMoving(rec->FileName()))
+ break;
#ifdef WITHPINPLUGIN
- if(item&&cStatus::MsgReplayProtected(GetRecording(item),item->Name(),base,item->IsDirectory())==true)
- return osContinue;
-#endif
- if(!HasSubMenu()&&item)
- {
- edit=true;
- if(item->IsDirectory())
- SetHelp(tr("Button$Rename"),tr("Button$Move"));
- else
- SetHelp(tr("Button$Rename"),tr("Button$Move"),tr("Button$Delete"),(!item->IsDVD())?tr("Details"):NULL);
- }
+ if(cStatus::MsgReplayProtected(rec,item->Name(),base,item->IsDirectory())==true)
+ break;
+#endif
+ }
+ if(!HasSubMenu())
+ {
+ edit=true;
+ if(item->IsDirectory())
+ SetHelp(tr("Button$Rename"),tr("Button$Move"));
+ else
+ SetHelp(tr("Button$Rename"),tr("Button$Move"),tr("Button$Delete"),(!item->IsDVD())?tr("Details"):NULL);
+ }
+ }
}
break;
case kBlue: return Info();
@@ -886,6 +1004,21 @@ eOSState myMenuRecordings::ProcessKey(eKeys Key)
// update menu list after sub menu has closed
if(hadsubmenu&&!HasSubMenu()||Recordings.StateChanged(recordingsstate)||cCutter::Active())
Set(true);
+
+ if(!cCutter::Active())
+ {
+ // no cut in progress so delete the paths to the cutted recording
+ if(myReplayControl::Cut)
+ {
+ free(myReplayControl::Cut);
+ myReplayControl::Cut=NULL;
+ }
+ if(myReplayControl::Cutted)
+ {
+ free(myReplayControl::Cutted);
+ myReplayControl::Cutted=NULL;
+ }
+ }
if(!HasSubMenu()&&Key!=kNone);
SetHelpKeys();
diff --git a/mymenurecordings.h b/mymenurecordings.h
index ebaf588..c112be2 100644
--- a/mymenurecordings.h
+++ b/mymenurecordings.h
@@ -1,21 +1,23 @@
// --- myMenuRecordingsItem ---------------------------------------------------
class myMenuRecordingsItem:public cOsdItem
{
- private:
- bool isdvd;
- int level,isdirectory;
- int totalentries,newentries;
- char *title;
- char *name;
- const char *filename;
- public:
- myMenuRecordingsItem(cRecording *Recording,int Level);
- ~myMenuRecordingsItem();
- const char *FileName(){return filename;}
- const char *Name(){return name;}
- bool IsDirectory(){return name!=NULL;}
- void IncrementCounter(bool IsNew);
- bool IsDVD(){return isdvd;}
+ private:
+ bool isdvd;
+ int level,isdirectory;
+ int totalentries,newentries;
+ char *title;
+ char *name;
+ const char *filename;
+ std::string uniqid; // this is the unique name that identifies a recording
+ public:
+ myMenuRecordingsItem(cRecording *Recording,int Level);
+ ~myMenuRecordingsItem();
+ const char *FileName(){return filename;}
+ const char *Name(){return name;}
+ bool IsDirectory(){return name!=NULL;}
+ void IncrementCounter(bool IsNew);
+ bool IsDVD(){return isdvd;}
+ const char *UniqID(){return uniqid.length()?uniqid.c_str():"";}
};
// --- myMenuRecordings -------------------------------------------------------
@@ -30,7 +32,7 @@ class myMenuRecordings:public cOsdMenu
char *base;
bool Open();
void SetHelpKeys();
- void SetFreeSpaceTitle();
+ void Title();
cRecording *GetRecording(myMenuRecordingsItem *Item);
eOSState Play();
eOSState Rewind();
@@ -41,6 +43,7 @@ class myMenuRecordings:public cOsdMenu
eOSState Details();
eOSState Commands(eKeys Key=kNone);
eOSState ChangeSorting();
+ bool IsCutted();
public:
myMenuRecordings(const char *Base=NULL,int Level=0);
~myMenuRecordings();
diff --git a/mymenusetup.c b/mymenusetup.c
index f6cf128..40442e8 100644
--- a/mymenusetup.c
+++ b/mymenusetup.c
@@ -15,6 +15,10 @@ mySetup::mySetup()
mysetup.ShowRecLength=0;
mysetup.ShowNewRecs=1;
mysetup.DescendSorting=0;
+ mysetup.GoLastReplayed=0;
+ mysetup.ReturnToPlugin=1;
+ mysetup.LimitBandwidth=0;
+ mysetup.UseVDRsRecInfoMenu=0;
}
mySetup mysetup;
@@ -29,6 +33,10 @@ myMenuSetup::myMenuSetup()
showreclength=mysetup.ShowRecLength;
shownewrecs=mysetup.ShowNewRecs;
descendsorting=mysetup.DescendSorting;
+ golastreplayed=mysetup.GoLastReplayed;
+ returntoplugin=mysetup.ReturnToPlugin;
+ limitbandwidth=mysetup.LimitBandwidth;
+ usevdrsrecinfomenu=mysetup.UseVDRsRecInfoMenu;
sortingtypetexts[0]=tr("ascending");
sortingtypetexts[1]=tr("descending");
@@ -41,6 +49,10 @@ myMenuSetup::myMenuSetup()
Add(new cMenuEditBoolItem(tr("Show recording length"),&showreclength));
Add(new cMenuEditBoolItem(tr("Show nr. of new recordings in a directory"),&shownewrecs));
Add(new cMenuEditBoolItem(tr("Show alternative to new marker"),&patchnew));
+ Add(new cMenuEditBoolItem(tr("Jump to last replayed recording"),&golastreplayed));
+ Add(new cMenuEditBoolItem(tr("Call plugin after playback"),&returntoplugin));
+ Add(new cMenuEditBoolItem(tr("Limit bandwidth for move recordings"),&limitbandwidth));
+ Add(new cMenuEditBoolItem(tr("Use VDR's recording info menu"),&usevdrsrecinfomenu));
}
void myMenuSetup::Store()
@@ -53,4 +65,8 @@ void myMenuSetup::Store()
SetupStore("ShowRecLength",mysetup.ShowRecLength=showreclength);
SetupStore("ShowNewRecs",mysetup.ShowNewRecs=shownewrecs);
SetupStore("DescendSorting",mysetup.DescendSorting=descendsorting);
+ SetupStore("GoLastReplayed",mysetup.GoLastReplayed=golastreplayed);
+ SetupStore("ReturnToPlugin",mysetup.ReturnToPlugin=returntoplugin);
+ SetupStore("LimitBandwidth",mysetup.LimitBandwidth=limitbandwidth);
+ SetupStore("UseVDRsRecInfoMenu",mysetup.UseVDRsRecInfoMenu=usevdrsrecinfomenu);
}
diff --git a/mymenusetup.h b/mymenusetup.h
index ad0091b..740cd25 100644
--- a/mymenusetup.h
+++ b/mymenusetup.h
@@ -12,6 +12,10 @@ class mySetup
int PatchNew;
int ShowNewRecs;
int DescendSorting;
+ int GoLastReplayed;
+ int ReturnToPlugin;
+ int LimitBandwidth;
+ int UseVDRsRecInfoMenu;
};
extern mySetup mysetup;
@@ -28,6 +32,10 @@ class myMenuSetup:public cMenuSetupPage
int patchnew;
int shownewrecs;
int descendsorting;
+ int golastreplayed;
+ int returntoplugin;
+ int limitbandwidth;
+ int usevdrsrecinfomenu;
protected:
virtual void Store();
public:
diff --git a/myreplaycontrol.c b/myreplaycontrol.c
index bdfb123..5305746 100644
--- a/myreplaycontrol.c
+++ b/myreplaycontrol.c
@@ -4,18 +4,35 @@
#include <vdr/interface.h>
#include <vdr/status.h>
+#include <vdr/menu.h>
#include "myreplaycontrol.h"
#include "mymenusetup.h"
+using namespace std;
+
+char *myReplayControl::Cut=NULL;
+char *myReplayControl::Cutted=NULL;
+
myReplayControl::~myReplayControl()
{
- cRemote::CallPlugin("extrecmenu");
+ if(mysetup.ReturnToPlugin)
+ cRemote::CallPlugin("extrecmenu");
}
eOSState myReplayControl::ProcessKey(eKeys Key)
{
- if(Key==kBack)
- return osEnd;
+ if(Key==kBack)
+ return osEnd;
+
+ if(Key==kEditCut)
+ {
+ free(Cut);
+ Cut=strdup(LastReplayed());
- return cReplayControl::ProcessKey(Key);
+ cRecording recording(LastReplayed());
+ free(Cutted);
+ Cutted=strdup(recording.PrefixFileName('%'));
+ }
+
+ return cReplayControl::ProcessKey(Key);
}
diff --git a/myreplaycontrol.h b/myreplaycontrol.h
index 01980ac..2819dd1 100644
--- a/myreplaycontrol.h
+++ b/myreplaycontrol.h
@@ -1,8 +1,8 @@
-#include <vdr/menu.h>
-
class myReplayControl:public cReplayControl
{
public:
+ static char *Cut;
+ static char *Cutted;
eOSState ProcessKey(eKeys Key);
~myReplayControl();
};
diff --git a/patchfont.c b/patchfont.c
index d85bcd2..72c023b 100644
--- a/patchfont.c
+++ b/patchfont.c
@@ -28,7 +28,7 @@ void PatchFont(eDvbFont DvbFont)
font_data[i*num_rows+0] = (num_char>=127 && num_char<=129)?6:char_data->width;
font_data[i*num_rows+1] = char_data->height;
- // new marker
+ // alternative new marker
if(num_char==128&&mysetup.PatchNew)
{
if(DvbFont==fontOsd)
@@ -198,6 +198,102 @@ void PatchFont(eDvbFont DvbFont)
font_data[i*num_rows+ 1]=22;
}
}
+ // scissor
+ else if(num_char==132)
+ {
+ if(DvbFont==fontOsd)
+ {
+ font_data[i*num_rows+ 0]=22;
+ font_data[i*num_rows+ 1]=27;
+ font_data[i*num_rows+ 8]=0x018060; // .. ...# #... .... .##. ....
+ font_data[i*num_rows+ 9]=0x018060; // .. ...# #... .... .##. ....
+ font_data[i*num_rows+10]=0x00c0c0; // .. .... ##.. .... ##.. ....
+ font_data[i*num_rows+11]=0x00c0c0; // .. .... ##.. .... ##.. ....
+ font_data[i*num_rows+12]=0x006180; // .. .... .##. ...# #... ....
+ font_data[i*num_rows+13]=0x006180; // .. .... .##. ...# #... ....
+ font_data[i*num_rows+14]=0x003300; // .. .... ..## ..## .... ....
+ font_data[i*num_rows+15]=0x003300; // .. .... ..## ..## .... ....
+ font_data[i*num_rows+16]=0x001e00; // .. .... ...# ###. .... ....
+ font_data[i*num_rows+17]=0x001e00; // .. .... ...# ###. .... ....
+ font_data[i*num_rows+18]=0x003300; // .. .... ..## ..## #... ....
+ font_data[i*num_rows+19]=0x01f3e0; // .. ...# #### ..## ###. ....
+ font_data[i*num_rows+20]=0x033330; // .. ..## ..## ..## ..## ....
+ font_data[i*num_rows+21]=0x033330; // .. ..## ..## ..## ..## ....
+ font_data[i*num_rows+22]=0x033330; // .. ..## ..## ..## ..## ....
+ font_data[i*num_rows+23]=0x033330; // .. ..## ..## ..## ..## ....
+ font_data[i*num_rows+24]=0x01f3e0; // .. ...# #### ..## ###. ....
+ }
+ else
+ {
+ font_data[i*num_rows+ 0]=22;
+ font_data[i*num_rows+ 1]=22;
+ font_data[i*num_rows+ 5]=0x018060; // .. ...# #... .... .##. ....
+ font_data[i*num_rows+ 6]=0x018060; // .. ...# #... .... .##. ....
+ font_data[i*num_rows+ 7]=0x00c0c0; // .. .... ##.. .... ##.. ....
+ font_data[i*num_rows+ 8]=0x00c0c0; // .. .... ##.. .... ##.. ....
+ font_data[i*num_rows+ 9]=0x006180; // .. .... .##. ...# #... ....
+ font_data[i*num_rows+10]=0x006180; // .. .... .##. ...# #... ....
+ font_data[i*num_rows+11]=0x003300; // .. .... ..## ..## .... ....
+ font_data[i*num_rows+12]=0x003300; // .. .... ..## ..## .... ....
+ font_data[i*num_rows+13]=0x001e00; // .. .... ...# ###. .... ....
+ font_data[i*num_rows+14]=0x001e00; // .. .... ...# ###. .... ....
+ font_data[i*num_rows+15]=0x003300; // .. .... ..## ..## #... ....
+ font_data[i*num_rows+16]=0x01f3e0; // .. ...# #### ..## ###. ....
+ font_data[i*num_rows+17]=0x033330; // .. ..## ..## ..## ..## ....
+ font_data[i*num_rows+18]=0x033330; // .. ..## ..## ..## ..## ....
+ font_data[i*num_rows+19]=0x033330; // .. ..## ..## ..## ..## ....
+ font_data[i*num_rows+20]=0x033330; // .. ..## ..## ..## ..## ....
+ font_data[i*num_rows+21]=0x01f3e0; // .. ...# #### ..## ###. ....
+ }
+ }
+ // move symbol
+ else if(num_char==133)
+ {
+ if(DvbFont==fontOsd)
+ {
+ font_data[i*num_rows+ 0]=22;
+ font_data[i*num_rows+ 1]=27;
+ font_data[i*num_rows+ 8]=0x000000; // .. .... .... .... .... ....
+ font_data[i*num_rows+ 9]=0x0001fe; // .. .... .... .... .... ....
+ font_data[i*num_rows+10]=0x0001fe; // .. .... .... .... .... ....
+ font_data[i*num_rows+11]=0x000186; // .. .... .... .... .... ....
+ font_data[i*num_rows+12]=0x000006; // .. .... .... .... .... ....
+ font_data[i*num_rows+13]=0x0ff7e6; // .. .... .... .... .... ....
+ font_data[i*num_rows+14]=0x0fe3c6; // .. .... .... .... .... ....
+ font_data[i*num_rows+15]=0x0c07c6; // .. .... .... .... .... ....
+ font_data[i*num_rows+16]=0x0c1f86; // .. .... .... .... .... ....
+ font_data[i*num_rows+17]=0x0c7906; // .. .... .... .... .... ....
+ font_data[i*num_rows+18]=0x0de07e; // .. .... .... .... .... ....
+ font_data[i*num_rows+19]=0x0d80fe; // .. .... .... .... .... ....
+ font_data[i*num_rows+20]=0x0c3000; // .. .... .... .... .... ....
+ font_data[i*num_rows+21]=0x0c3000; // .. .... .... .... .... ....
+ font_data[i*num_rows+22]=0x0ff000; // .. .... .... .... .... ....
+ font_data[i*num_rows+23]=0x0ff000; // .. .... .... .... .... ....
+ font_data[i*num_rows+24]=0x000000; // .. .... .... .... .... ....
+ }
+ else
+ {
+ font_data[i*num_rows+ 0]=22;
+ font_data[i*num_rows+ 1]=22;
+ font_data[i*num_rows+ 5]=0x0001fe; // .. .... .... ...# #### ###.
+ font_data[i*num_rows+ 6]=0x0001fe; // .. .... .... ...# #### ###.
+ font_data[i*num_rows+ 7]=0x000186; // .. .... .... ...# #... .##.
+ font_data[i*num_rows+ 8]=0x000186; // .. .... .... ...#.#... .##.
+ font_data[i*num_rows+ 9]=0x000006; // .. .... .... .... .... .##.
+ font_data[i*num_rows+10]=0x1fe7e6; // .# #### ###. .### ###. .##.
+ font_data[i*num_rows+11]=0x1fe3c6; // .# #### ###. ..## ##.. .##.
+ font_data[i*num_rows+12]=0x1847c6; // .# #... .#.. .### ##.. .##.
+ font_data[i*num_rows+13]=0x181f86; // .# #... ...# #### #... .##.
+ font_data[i*num_rows+14]=0x187906; // .# #... .### #..# .... .##.
+ font_data[i*num_rows+15]=0x19e07e; // .# #..# ###. .... .### ###.
+ font_data[i*num_rows+16]=0x1981fe; // .# #..# #... ...# #### ###.
+ font_data[i*num_rows+17]=0x182000; // .# #... ..#. .... .... ....
+ font_data[i*num_rows+18]=0x186000; // .# #... .##. .... .... ....
+ font_data[i*num_rows+19]=0x186000; // .# #... .##. .... .... ....
+ font_data[i*num_rows+20]=0x1fe000; // .# #### ###. .... .... ....
+ font_data[i*num_rows+21]=0x1fe000; // .# #### ###. .... .... ....
+ }
+ }
else
{
for(j = 0; j<(int)char_data->height; j++)
diff --git a/tools.c b/tools.c
index d57bcb7..439051e 100644
--- a/tools.c
+++ b/tools.c
@@ -2,13 +2,48 @@
* See the README file for copyright information and how to reach the author.
*/
+#include <string>
+#include <fstream>
+#include <iostream>
#include <vdr/plugin.h>
#include <vdr/videodir.h>
#include <vdr/recording.h>
#include "tools.h"
#include "mymenusetup.h"
+using namespace std;
+
#define CONFIGFILE "/extrecmenu.sort.conf"
+#define BUFFERSIZE 20972 // (2*1024*1024)/100
+
+MoveBetweenFileSystems MoveThread;
+
+string myStrEscape(string S,const char *Chars)
+{
+ int i=0;
+ while(Chars[i]!=0)
+ {
+ string::size_type j=0;
+ while((j=S.find(Chars[i],j))!=string::npos)
+ {
+ S.insert(j,1,'\\');
+ j+=2;
+ }
+ i++;
+ }
+ return S;
+}
+
+string myStrReplace(string S,char C1,char C2)
+{
+ string::size_type i=0;
+ while((i=S.find(C1,i))!=string::npos)
+ {
+ S.replace(i,1,1,C2);
+ i++;
+ }
+ return S;
+}
// --- SortList ---------------------------------------------------------------
void SortList::ReadConfigFile()
@@ -50,84 +85,252 @@ bool SortList::Find(char *Path)
return false;
}
-// --- MoveRename -------------------------------------------------------------
-// creates the necassery directories and renames the given old name to the new name
-bool MoveRename(const char *OldName,const char *NewName,cRecording *Recording,bool Move)
+// --- MoveBetweenFileSystems -------------------------------------------------
+MoveBetweenFileSystems::MoveBetweenFileSystems():cThread("moving files between filesystems")
{
- char *buf=NULL;
+}
- // is OldName different to NewName
- if(!strcmp(OldName,NewName))
- return true;
+bool MoveBetweenFileSystems::Start(string OldName,string NewName,cRecording *Recording)
+{
+ oldname=OldName;
+ newname=NewName;
+ recording=Recording;
+
+ return cThread::Start();
+}
- // move/rename a recording
- if(Recording)
- {
- if(!MakeDirs(NewName,true))
+bool MoveBetweenFileSystems::IsMoving(string Path)
+{
+ if(Active())
{
- Skins.Message(mtError,tr("Creating directories failed!"));
- return false;
+ if(recording)
+ {
+ if(Path==oldname)
+ return true;
+ }
+ else
+ {
+ if(!strncmp(oldname.c_str(),Path.c_str(),oldname.length()))
+ return true;
+ }
}
- isyslog("[extrecmenu] moving %s to %s",OldName,NewName);
-
- if(rename(OldName,NewName)==-1)
+ return false;
+}
+
+bool MoveBetweenFileSystems::Move(string From,string To,cRecording *Recording)
+{
+ if(Recording)
{
- esyslog("[extrecmenu] %s",strerror(errno));
- Skins.Message(mtError,tr("Rename/Move failed!"));
- return false;
+ isyslog("[extrecmenu] moving %s to %s",From.c_str(),To.c_str());
+
+ DIR *dir;
+ struct dirent *entry;
+ dir=opendir(From.c_str());
+ while((entry=readdir(dir))!=NULL)
+ {
+ string from,to;
+ from=From+'/'+entry->d_name;
+ to=To+'/'+entry->d_name;
+
+ struct stat st;
+ stat(from.c_str(),&st);
+ if(S_ISREG(st.st_mode))
+ {
+ isyslog("[extrecmenu] moving %s",entry->d_name);
+
+ time_t copytime=time(NULL);
+
+ char buf[BUFFERSIZE];
+ int infile=-1,outfile=-1;
+ struct stat from_stat;
+ ssize_t sz,sz_read=1,sz_write;
+
+ if(stat(from.c_str(),&from_stat)!=0 ||
+ (infile=open(from.c_str(),O_RDONLY))<0 ||
+ (outfile=open(to.c_str(),O_WRONLY|O_CREAT|O_EXCL,from_stat.st_mode))<0)
+ {
+ if(infile>=0)
+ close(infile);
+ closedir(dir);
+
+ Skins.Message(mtError,strerror(errno));
+ return false;
+ }
+
+ while(sz_read>0 && (sz_read=read(infile,buf,BUFFERSIZE))>0)
+ {
+ sz_write=0;
+ do
+ {
+ if((sz=write(outfile,buf+sz_write,sz_read-sz_write))<0)
+ {
+ close(infile);
+ close(outfile);
+ closedir(dir);
+
+ Skins.Message(mtError,tr("Rename/Move failed!"));
+ esyslog("[extrecmenu] %s",strerror(errno));
+ return false;
+ }
+ sz_write+=sz;
+ }
+ while(sz_write<sz_read);
+
+ if(mysetup.LimitBandwidth)
+ usleep(10);
+ }
+ close(infile);
+ close(outfile);
+
+ copytime=time(NULL)-copytime;
+ isyslog("[extrecmenu] needed %d secs for %d bytes",(int)copytime,(int)st.st_size);
+ }
+ }
+ closedir(dir);
+
+ Recordings.AddByName(To.c_str());
+ Recording->Delete();
+ Recordings.DelByName(From.c_str());
+
+ string buf="move \"";
+ buf+=myStrEscape(From,"'\\\"$");
+ buf+="\"";
+ cRecordingUserCommand::InvokeCommand(buf.c_str(),To.c_str());
}
-
- // set user command for '-r'-option of VDR
- asprintf(&buf,"%s \"%s\"",Move?"move":"rename",*strescape(OldName,"'\\\"$"));
- cRecordingUserCommand::InvokeCommand(buf,NewName);
- free(buf);
-
- // update recordings list
- Recordings.AddByName(NewName);
- Recordings.Del(Recording);
- }
- // move/rename a directory
- else
- {
- // is the new path within the old?
- asprintf(&buf,"%s/",OldName); // we have to append a / to make sure that we search for a directory
- if(!strncmp(buf,NewName,strlen(buf)))
+ else
{
- Skins.Message(mtError,tr("Moving into own sub-directory not allowed!"));
- free(buf);
- return false;
+ string buf;
+ buf=From+'/';
+ if(!strncmp(buf.c_str(),To.c_str(),buf.length()))
+ {
+ Skins.Message(mtError,tr("Moving into own sub-directory not allowed!"));
+ return false;
+ }
+
+ myRecList *list=new myRecList();
+ for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
+ list->Add(new myRecListItem(recording));
+
+ myRecListItem *item=list->First();
+ while(item)
+ {
+ if(!strncmp(From.c_str(),item->recording->FileName(),From.length()))
+ {
+ char *buffer=NULL;
+ buffer=strdup(From.c_str()+strlen(VideoDirectory)+1);
+ buffer=ExchangeChars(buffer,false);
+
+ if(strcmp(item->recording->Name(),buffer))
+ {
+ buf=To+(item->recording->FileName()+From.length());
+ if(!MakeDirs(buf.c_str(),true))
+ {
+ Skins.Message(mtError,tr("Rename/Move failed!"));
+ esyslog("[extrecmenu] %s",strerror(errno));
+ free(buffer);
+ delete list;
+ return false;
+ }
+ if(Move(item->recording->FileName(),buf,item->recording)==false)
+ {
+ free(buffer);
+ delete list;
+ return false;
+ }
+ }
+ free(buffer);
+ }
+ item=list->Next(item);
+ }
+ delete list;
}
- free(buf);
-
- // build my own recordings list
- myRecList *list=new myRecList();
- for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
- list->Add(new myRecListItem(recording));
+ return true;
+}
+
+void MoveBetweenFileSystems::Action()
+{
+ Move(oldname,newname,recording);
+}
+
+// --- MoveRename -------------------------------------------------------------
+// creates the necassery directories and renames the given old name to the new name
+bool MoveRename(const char *OldName,const char *NewName,cRecording *Recording,bool Move)
+{
+ char *buf=NULL;
+
+ if(!strcmp(OldName,NewName))
+ return true;
- myRecListItem *item=list->First();
- while(item)
+ if(Recording)
{
- // find recordings within the path of OldName
- if(!strncmp(OldName,item->recording->FileName(),strlen(OldName)))
- {
- buf=strdup(OldName+strlen(VideoDirectory)+1);
- buf=ExchangeChars(buf,false);
-
- // exclude recordings with the same name as OldName
- if(strcmp(item->recording->Name(),buf))
+ isyslog("[extrecmenu] moving %s to %s",OldName,NewName);
+
+ if(rename(OldName,NewName)==-1)
{
- free(buf);
- asprintf(&buf,"%s%s",NewName,item->recording->FileName()+strlen(OldName));
- // move/rename the recording
- MoveRename(item->recording->FileName(),buf,item->recording,Move);
+ remove(NewName); // remove created directory
+ Skins.Message(mtError,tr("Rename/Move failed!"));
+ esyslog("[extrecmenu] %s",strerror(errno));
+ return false;
}
+
+ Recordings.AddByName(NewName);
+ Recordings.Del(Recording);
+
+ // set user command for '-r'-option of VDR
+ asprintf(&buf,"%s \"%s\"",Move?"move":"rename",*strescape(OldName,"'\\\"$"));
+ cRecordingUserCommand::InvokeCommand(buf,NewName);
free(buf);
- }
- item=list->Next(item);
}
- delete list;
- }
- return true;
+ else
+ {
+ // is the new path within the old?
+ asprintf(&buf,"%s/",OldName); // we have to append a / to make sure that we search for a directory
+ if(!strncmp(buf,NewName,strlen(buf)))
+ {
+ Skins.Message(mtError,tr("Moving into own sub-directory not allowed!"));
+ free(buf);
+ return false;
+ }
+ free(buf);
+
+ myRecList *list=new myRecList();
+ for(cRecording *recording=Recordings.First();recording;recording=Recordings.Next(recording))
+ list->Add(new myRecListItem(recording));
+
+ myRecListItem *item=list->First();
+ while(item)
+ {
+ if(!strncmp(OldName,item->recording->FileName(),strlen(OldName)))
+ {
+ buf=strdup(OldName+strlen(VideoDirectory)+1);
+ buf=ExchangeChars(buf,false);
+
+ if(strcmp(item->recording->Name(),buf))
+ {
+ free(buf);
+ asprintf(&buf,"%s%s",NewName,item->recording->FileName()+strlen(OldName));
+ if(!MakeDirs(buf,true))
+ {
+ Skins.Message(mtError,tr("Creating directories failed!"));
+ esyslog("[extrecmenu] %s",strerror(errno));
+ free(buf);
+ delete list;
+ return false;
+ }
+ if(MoveRename(item->recording->FileName(),buf,item->recording,Move)==false)
+ {
+ free(buf);
+ delete list;
+ return false;
+ }
+ }
+ free(buf);
+ }
+ item=list->Next(item);
+ }
+ delete list;
+ }
+ return true;
}
// --- myRecListItem ----------------------------------------------------------
diff --git a/tools.h b/tools.h
index 0090ed2..c12b070 100644
--- a/tools.h
+++ b/tools.h
@@ -1,44 +1,57 @@
-#include <string>
-#include <fstream>
-#include <iostream>
-
-using namespace std;
+std::string myStrReplace(std::string S,char C1,char C2);
class SortListItem:public cListObject
{
- private:
- string path;
- public:
- SortListItem(const char *Path){path=Path;};
- const char *Path(){return path.c_str();}
+ private:
+ std::string path;
+ public:
+ SortListItem(const char *Path){path=Path;};
+ const char *Path(){return path.c_str();}
};
class SortList:public cList<SortListItem>
{
- public:
- void ReadConfigFile();
- void WriteConfigFile();
- bool Find(char *Path);
+ public:
+ void ReadConfigFile();
+ void WriteConfigFile();
+ bool Find(char *Path);
};
+class MoveBetweenFileSystems:public cThread
+{
+ private:
+ std::string oldname;
+ std::string newname;
+ cRecording *recording;
+ bool Move(std::string From,std::string To,cRecording *Recording);
+ protected:
+ virtual void Action();
+ public:
+ MoveBetweenFileSystems();
+ bool Start(std::string OldName,std::string NewName,cRecording *Recording);
+ bool IsMoving(std::string Path);
+};
+
+extern MoveBetweenFileSystems MoveThread;
+
bool MoveRename(const char *OldName,const char *NewName,cRecording *Recording,bool Move);
class myRecListItem:public cListObject
{
- friend class myRecList;
- private:
- static bool SortByName;
- char *filename;
- static char *StripEpisodeName(char *s);
- public:
- myRecListItem(cRecording *Recording);
- ~myRecListItem();
- virtual int Compare(const cListObject &ListObject)const;
- cRecording *recording;
+ friend class myRecList;
+ private:
+ static bool SortByName;
+ char *filename;
+ static char *StripEpisodeName(char *s);
+ public:
+ myRecListItem(cRecording *Recording);
+ ~myRecListItem();
+ virtual int Compare(const cListObject &ListObject)const;
+ cRecording *recording;
};
class myRecList:public cList<myRecListItem>
{
- public:
- void Sort(bool SortByName);
+ public:
+ void Sort(bool SortByName);
};