From pouchintv-dev at baysse.fr Fri Jan 8 10:42:07 2010
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: ven, 8 jan 2010 10:42:07 +0100
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r224 - / trunk
Message-ID: <20100108094208.2C5655F772@mail.baysse.fr>
Author: gingko
Date: 2010-01-08 10:42:07 +0100 (ven 08 jan 2010)
New Revision: 224
Added:
docs/
Removed:
trunk/docs/
Log:
Déplacement du répertoire "docs" du tronc à la racine du dépôt SVN.
En effet, ce répertoire étant supposé connaître une évolution nettement
distincte de celui des répertoires de code, il semble peu pertinent
qu'il se trouve dupliqué dans tous les tags présents et à venir.
From pouchintv-dev at baysse.fr Fri Jan 8 10:46:05 2010
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: ven, 8 jan 2010 10:46:05 +0100
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r225 -
tags/pouchintv_mod-0.6.0
Message-ID: <20100108094605.D35475F75B@mail.baysse.fr>
Author: gingko
Date: 2010-01-08 10:46:05 +0100 (ven 08 jan 2010)
New Revision: 225
Removed:
tags/pouchintv_mod-0.6.0/docs/
Log:
Suppression du répertoire "docs" du tag 0.6.0, concomitamment au
déplacement qui vient d'être effectué.
From pouchintv-dev at baysse.fr Fri Jan 8 10:59:36 2010
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: ven, 8 jan 2010 10:59:36 +0100
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r226 -
tags/pouchintv_mod-0.6.0 trunk
Message-ID: <20100108095937.4803F5F75B@mail.baysse.fr>
Author: gingko
Date: 2010-01-08 10:59:36 +0100 (ven 08 jan 2010)
New Revision: 226
Modified:
tags/pouchintv_mod-0.6.0/
tags/pouchintv_mod-0.6.0/Doxyfile
tags/pouchintv_mod-0.6.0/Pouchin TV_2005.vcproj
tags/pouchintv_mod-0.6.0/Pouchin TV_2008.vcproj
tags/pouchintv_mod-0.6.0/changelog.html
trunk/
trunk/Doxyfile
trunk/Pouchin TV_2005.vcproj
trunk/Pouchin TV_2008.vcproj
trunk/changelog.html
Log:
Ajustements mineurs :
* Le répertoire de génération des fichiers Doxygen est
renommé en Doxygen_files (plutôt que html) et relocalisé dans le
répertoire de la solution.
* Le numéro de version dans le fichier Doxyfile est ajusté (oubli).
* Petit correctif dans changelog.html.
* Ajout d'une définition préprocesseur manquante dans certaines
configuration des fichiers de projet.
* Les propriétés "svnignore" des répertoires "trunk" et
"pouchintv_mod-0.6.0" sont actualisées.
Property changes on: tags/pouchintv_mod-0.6.0
___________________________________________________________________
Modifié : svn:ignore
- Debug
Release
Vista Debug
Vista Release
x64
chaines.xml
config.ini
pouchin.log
Pouchin TV_*.suo
Pouchin TV_*.ncb
Pouchin TV_*.vcproj.*
programmes.xml
.*.swp
version.txt
res.aps
PouchinTVMod*.exe
vstudio_edition.h
Debug_x64
Release_x64
version.h
Release_SBCS
Debug_SBCS
Release_SBCS_x64
Debug_SBCS_x64
version.nsh
Setup_*.vcproj.*
+ Debug*
Diagnostic*
Release*
chaines.xml
config.ini
pouchin.log
*.suo
*.ncb
*.aps
*.vcproj.*
programmes.xml
version.txt
PouchinTVMod*.exe
vstudio_edition.h
version.h
version.nsh
Modifié: tags/pouchintv_mod-0.6.0/Doxyfile
===================================================================
--- tags/pouchintv_mod-0.6.0/Doxyfile 2010-01-08 09:46:05 UTC (rev 225)
+++ tags/pouchintv_mod-0.6.0/Doxyfile 2010-01-08 09:59:36 UTC (rev 226)
@@ -28,13 +28,13 @@
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 0.5~svn
+PROJECT_NUMBER = 0.6
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
-OUTPUT_DIRECTORY = docs
+OUTPUT_DIRECTORY =
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@@ -657,7 +657,7 @@
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
-HTML_OUTPUT = html
+HTML_OUTPUT = Doxygen_files
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
Modifié: tags/pouchintv_mod-0.6.0/Pouchin TV_2005.vcproj
===================================================================
--- tags/pouchintv_mod-0.6.0/Pouchin TV_2005.vcproj 2010-01-08 09:46:05 UTC (rev 225)
+++ tags/pouchintv_mod-0.6.0/Pouchin TV_2005.vcproj 2010-01-08 09:59:36 UTC (rev 226)
@@ -47,7 +47,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="BaseClasses"
- PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;USE_CONSOLE=1"
+ PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;_DIAGNOSTIC;USE_CONSOLE=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -411,7 +411,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="BaseClasses"
- PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;USE_CONSOLE=1"
+ PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;_DIAGNOSTIC;USE_CONSOLE=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
Modifié: tags/pouchintv_mod-0.6.0/Pouchin TV_2008.vcproj
===================================================================
--- tags/pouchintv_mod-0.6.0/Pouchin TV_2008.vcproj 2010-01-08 09:46:05 UTC (rev 225)
+++ tags/pouchintv_mod-0.6.0/Pouchin TV_2008.vcproj 2010-01-08 09:59:36 UTC (rev 226)
@@ -48,7 +48,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="BaseClasses"
- PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;USE_CONSOLE=1"
+ PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;_DIAGNOSTIC;USE_CONSOLE=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -408,7 +408,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="BaseClasses"
- PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;USE_CONSOLE=1"
+ PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;_DIAGNOSTIC;USE_CONSOLE=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
Modifié: tags/pouchintv_mod-0.6.0/changelog.html
===================================================================
--- tags/pouchintv_mod-0.6.0/changelog.html 2010-01-08 09:46:05 UTC (rev 225)
+++ tags/pouchintv_mod-0.6.0/changelog.html 2010-01-08 09:59:36 UTC (rev 226)
@@ -82,7 +82,7 @@
fond vert pour les émissions de la chaîne courante ;
fond jaune clair pour les émissions des chaînes diffusées sur le même multiplex
que la chaîne courante ;
- les émissions supposées être en cours de diffusion (selon leur horaire sont
+ les émissions supposées être en cours de diffusion (selon leur horaire) sont
affichées avec le texte en bleu ;
les émissions en cours d'enregistrement sont affichées en texte rouge ;
les autres émissions sont affichées en gris.
Property changes on: trunk
___________________________________________________________________
Modifié : svn:ignore
- Debug
Release
Vista Debug
Vista Release
x64
chaines.xml
config.ini
pouchin.log
Pouchin TV_*.suo
Pouchin TV_*.ncb
Pouchin TV_*.vcproj.*
programmes.xml
.*.swp
version.txt
res.aps
PouchinTVMod*.exe
vstudio_edition.h
Debug_x64
Release_x64
version.h
Release_SBCS
Debug_SBCS
Release_SBCS_x64
Debug_SBCS_x64
version.nsh
Setup_*.vcproj.*
+ Debug*
Diagnostic*
Release*
chaines.xml
config.ini
pouchin.log
*.suo
*.ncb
*.aps
*.vcproj.*
programmes.xml
version.txt
PouchinTVMod*.exe
vstudio_edition.h
version.h
version.nsh
Modifié: trunk/Doxyfile
===================================================================
--- trunk/Doxyfile 2010-01-08 09:46:05 UTC (rev 225)
+++ trunk/Doxyfile 2010-01-08 09:59:36 UTC (rev 226)
@@ -28,13 +28,13 @@
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = 0.5~svn
+PROJECT_NUMBER = 0.6
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
-OUTPUT_DIRECTORY = docs
+OUTPUT_DIRECTORY =
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@@ -657,7 +657,7 @@
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
-HTML_OUTPUT = html
+HTML_OUTPUT = Doxygen_files
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
Modifié: trunk/Pouchin TV_2005.vcproj
===================================================================
--- trunk/Pouchin TV_2005.vcproj 2010-01-08 09:46:05 UTC (rev 225)
+++ trunk/Pouchin TV_2005.vcproj 2010-01-08 09:59:36 UTC (rev 226)
@@ -47,7 +47,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="BaseClasses"
- PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;USE_CONSOLE=1"
+ PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;_DIAGNOSTIC;USE_CONSOLE=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -411,7 +411,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="BaseClasses"
- PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;USE_CONSOLE=1"
+ PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;_DIAGNOSTIC;USE_CONSOLE=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
Modifié: trunk/Pouchin TV_2008.vcproj
===================================================================
--- trunk/Pouchin TV_2008.vcproj 2010-01-08 09:46:05 UTC (rev 225)
+++ trunk/Pouchin TV_2008.vcproj 2010-01-08 09:59:36 UTC (rev 226)
@@ -48,7 +48,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="BaseClasses"
- PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;USE_CONSOLE=1"
+ PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;_DIAGNOSTIC;USE_CONSOLE=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
@@ -408,7 +408,7 @@
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="BaseClasses"
- PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;USE_CONSOLE=1"
+ PreprocessorDefinitions="NTDDI_VERSION=0x05010200;_WIN32_WINNT=0x0501;_CRT_SECURE_NO_DEPRECATE;_DIAGNOSTIC;USE_CONSOLE=1"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="1"
Modifié: trunk/changelog.html
===================================================================
--- trunk/changelog.html 2010-01-08 09:46:05 UTC (rev 225)
+++ trunk/changelog.html 2010-01-08 09:59:36 UTC (rev 226)
@@ -82,7 +82,7 @@
fond vert pour les émissions de la chaîne courante ;
fond jaune clair pour les émissions des chaînes diffusées sur le même multiplex
que la chaîne courante ;
- les émissions supposées être en cours de diffusion (selon leur horaire sont
+ les émissions supposées être en cours de diffusion (selon leur horaire) sont
affichées avec le texte en bleu ;
les émissions en cours d'enregistrement sont affichées en texte rouge ;
les autres émissions sont affichées en gris.
From pouchintv-dev at baysse.fr Sat Jan 9 15:43:50 2010
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: sam, 9 jan 2010 15:43:50 +0100
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r227 - in trunk: .
BaseClasses
Message-ID: <20100109144352.6E59A5F77D@mail.baysse.fr>
Author: gingko
Date: 2010-01-09 15:43:49 +0100 (sam 09 jan 2010)
New Revision: 227
Modified:
trunk/BaseClasses/Doxyfile
trunk/Doxyfile
trunk/canaux.ini
trunk/capture.cpp
trunk/capture.h
trunk/changelog.html
trunk/channels.cpp
trunk/channels.h
trunk/chanutils.cpp
trunk/chanutils.h
trunk/config.h
trunk/ini.cpp
trunk/ini.h
trunk/main.cpp
trunk/mpeg2defs.h
trunk/parse.cpp
trunk/pmtfilter.cpp
trunk/record.cpp
trunk/recprog.cpp
trunk/recprog.h
trunk/res.rc
trunk/utils.cpp
trunk/utils.h
Log:
Simplification de la représentation des données représentant les
flux TS des chaînes.
channels.h, channels.cpp, chanutils.h, chanutils.cpp, pmtfilter.cpp, parse.cpp,
main.cpp, record.cpp, recprog.cpp :
* La structure "ChainePMT" avec ses fonctions membres est déplacée
depuis "channels.h/.cpp" vers le fichier "chanutils.h/cpp".
* Le champ "pmt_pid" fait maintenant partie de cette structure,
ce qui permet de l'utiliser pour décrire entièrement les flux
TS à enregistrer dans un fichier du même type.
* Les deux listes de pistes ("son" et "autres") sont fusionnées
en une seule, organisée pour avoir les pistes "son" au début et
les pistes "autres" ensuite, successivement dans la même liste.
Dans cette nouvelle liste, la variable membre "nbr" indique le
nombre de pistes "son", la variable "nbr_tot" le nombre de pistes
total, le nombre de pistes "autres" se déduisant de la différence
entre les deux.
capture.h, capture.cpp, record.cpp :
* Utilisation effective de la structure "ChainePMT" dans les enregistrements
au format TS.
config.h, ini.h :
* La directive STREAMS_SAVE_ALL est déplacée dans le fichier "config.h".
res.rc :
* Correctif (oubli) dans le nom du dialogue d'arrêt temporisé des
enregistrements.
util.h, util.cpp :
* Ajout d'une macro CHAR2TCHAR en correspondance avec la macro WCHAR2TCHAR,
optimisation de la fonction WChar2Char existante, et ajout de la fonction
inverse Char2WChar.
recprog.h, recprog.cpp, ini.h, ini.cpp :
* La liste des jours de la semaine est maintenant une chaîne SBCS (plus pertinent
avec les fichiers XML et compatible avec l'UTF-8) destinée à être exploitée par
StringToEnum et EnumToString, et est un membre statique de la classe "Programme".
ini.h, ini.cpp :
* La structure NomFichierConf est maintenant un "template", permettant de l'utiliser
avec une combinaison quelconque de chaînes CHAR / WCHAR / TCHAR.
* Ajout de raccourcis modifiables pour le dialogue de configuration et le dialogue
de qualité du signal.
* Correctif : la présence d'un canal avec une valeur 0 dans le fichier canaux.ini n'a
plus pour effet d'interrompre la recherche.
* Les noms des fichiers "chaines.xml" et "programmes.xml" sont définis dans des macros.
* Ajout d'attributs "const" et retrait d'attributs "void".
* La valeur de retour de la fonction "lit_programmes" devient un HRESULT.
mpeg2defs.h :
* Commentaires ajoutés.
Modifié: trunk/BaseClasses/Doxyfile
===================================================================
--- trunk/BaseClasses/Doxyfile 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/BaseClasses/Doxyfile 2010-01-09 14:43:49 UTC (rev 227)
@@ -34,7 +34,7 @@
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
-OUTPUT_DIRECTORY = ..\docs\BaseClasses
+OUTPUT_DIRECTORY =
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@@ -115,6 +115,12 @@
# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
+# Note : si, à la génération, vous obtenez des erreurs multiples de type
+# "Error opening map file *.map for inclusion in the docs!", ne cherchez pas à
+# changer l'option SHORT_NAMES ainsi qu'il est parfois indiqué sur le Net.
+# Contentez-vous d'effacer le contenu du répertoire "Doxygen_files" et refaites
+# la génération de la documentation Doxyfile. Voir bug Doxygen 525273, ici :
+# http://bugzilla.gnome.org/show_bug.cgi?id=525273
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
@@ -651,7 +657,7 @@
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
-HTML_OUTPUT = html
+HTML_OUTPUT = Doxygen_files
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
@@ -1220,11 +1226,8 @@
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
-DOT_PATH = "C:/Program Files/Graphviz 2.21/bin"
+DOT_PATH =
-# Attention : sur un OS 64 bits, ce répertoire devrait être le suivant :
-# DOT_PATH = "C:/Program Files (x86)/Graphviz 2.21/bin"
-
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
Modifié: trunk/Doxyfile
===================================================================
--- trunk/Doxyfile 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/Doxyfile 2010-01-09 14:43:49 UTC (rev 227)
@@ -117,9 +117,9 @@
SHORT_NAMES = NO
# Note : si, à la génération, vous obtenez des erreurs multiples de type
# "Error opening map file *.map for inclusion in the docs!", ne cherchez pas à
-# changer l'option SHORT_NAMES ainsi qu'il est parfois ndiqué sur le Net.
-# Contentez-vous d'effacer le contenu du répertoire "docs/html" et refaites la
-# génération de la documentation Doxyfile. Voir bug Doxygen 525273, ici :
+# changer l'option SHORT_NAMES ainsi qu'il est parfois indiqué sur le Net.
+# Contentez-vous d'effacer le contenu du répertoire "Doxygen_files" et refaites
+# la génération de la documentation Doxyfile. Voir bug Doxygen 525273, ici :
# http://bugzilla.gnome.org/show_bug.cgi?id=525273
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
Modifié: trunk/canaux.ini
===================================================================
--- trunk/canaux.ini 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/canaux.ini 2010-01-09 14:43:49 UTC (rev 227)
@@ -2748,7 +2748,7 @@
[Mont-Revard - Le Revard]
R1=33
-R2=48
+R2=32
R3=39
R4=54
R5=0
Modifié: trunk/capture.cpp
===================================================================
--- trunk/capture.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/capture.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -69,15 +69,9 @@
CloseHandle(hFile);
}
-CCapture_TS::CCapture_TS(
- HANDLE hFil, UINT16 pmt, UINT16 video,
- const liste_pistes & lst_sons,
- const liste_pistes & lst_autr) :
+CCapture_TS::CCapture_TS(HANDLE hFil, const ChainePMT & lst_pistes) :
CCapture(hFil),
- video_pid(video),
- pmt_pid(pmt),
- sons(lst_sons),
- autr(lst_autr)
+ pistes(lst_pistes)
{
}
@@ -88,10 +82,9 @@
if (
pid == p_pid_PAT ||
- pid == pmt_pid ||
- pid == video_pid ||
- sons.cherche_pid(pid) ||
- autr.cherche_pid(pid)
+ pid == pistes.pmt_pid ||
+ pid == pistes.video_pid ||
+ pistes.cherche_pid(pid)
)
ecrit_fichier(p.bytes, TS_SIZE);
}
Modifié: trunk/capture.h
===================================================================
--- trunk/capture.h 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/capture.h 2010-01-09 14:43:49 UTC (rev 227)
@@ -57,16 +57,11 @@
class CCapture_TS : public CCapture
{
- UINT16 video_pid;
- UINT16 pmt_pid;
- liste_pistes sons;
- liste_pistes autr;
+ ChainePMT pistes;
public:
- CCapture_TS(HANDLE hFil, UINT16 pmt, UINT16 video,
- const liste_pistes & lst_sons,
- const liste_pistes & lst_autr);
+ CCapture_TS(HANDLE hFil, const ChainePMT & lst_pistes);
virtual void traite_paquet(const TS_packet & p);
};
Modifié: trunk/changelog.html
===================================================================
--- trunk/changelog.html 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/changelog.html 2010-01-09 14:43:49 UTC (rev 227)
@@ -57,6 +57,14 @@
Changements réalisés pour la version 0.6
+ SVN rév. 227 :
+
+ Ajout de raccourcis modifiables pour le dialogue de configuration et le dialogue
+ de qualité du signal.
+ Réorganisations internes.
+
+
+
0.6.0.223 (publiée le 27 décembre 2009) :
Correction d'un bug : un enregistrement programmé qui demande l'arrêt de l'application
Modifié: trunk/channels.cpp
===================================================================
--- trunk/channels.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/channels.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -90,40 +90,9 @@
return dwCle;
}
-ChainePMT::ChainePMT() :
- video_pid(0),
- video_type(vst_Unknown),
- pcr_pid(0)
-{
-}
-
-bool ChainePMT::operator == (const ChainePMT & cpmt) const
-{
- if (video_pid!=cpmt.video_pid || video_type!=cpmt.video_type || pcr_pid!=cpmt.pcr_pid)
- return false;
- return sons==cpmt.sons && autr==cpmt.autr;
-}
-
-LPCTSTR ChainePMT::norme(void) const
-{
- switch (video_type) {
- case vst_MPEG2:
- return TEXT("Mpeg2");
- case vst_H264:
- return TEXT("H264");
- case vst_MPEG2_encrypted:
- case vst_H264_encrypted:
- return TEXT("Crypté");
- }
- if (sons.nbr > 0)
- return TEXT("Audio");
- return TEXT("Inconnu");
-}
-
// Constructeur :
Chaine::Chaine() :
khz(-1),
- pmt_pid(0),
nNumeroNit(0),
nNumeroAuto(0),
emi_count(0),
@@ -207,7 +176,7 @@
};
char szLangue[32] = "";
- const une_piste & son_courant = sons.tbl[nTrack];
+ const une_piste & son_courant = tbl[nTrack];
for (int j=0; j < _countof(Tab_Lang); j++) {
const Langue & tlang = Tab_Lang[j];
@@ -314,9 +283,9 @@
myprintf(TEXT("Chaine::branche SID=%i, TSID=%i, ONID=%i, freq=%i") EOL, SID, TSID, ONID, khz);
if (reset_son)
- ixSonCourant = sons.selection_son(audio_pref);
+ ixSonCourant = selection_son(audio_pref);
- const une_piste son = sons.tbl[ixSonCourant];
+ const une_piste son = tbl[ixSonCourant];
if (!pGraph)
return E_FAIL;
@@ -532,8 +501,8 @@
if (ixChaine_ok(ixChaineCourante) && ixSon != ixSonCourant) {
const Chaine & canal = Canaux[ixChaineCourante];
- if (ixSon>=0 && ixSon=0 && ixSonchange_son(son.pid, son.type);
Modifié: trunk/channels.h
===================================================================
--- trunk/channels.h 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/channels.h 2010-01-09 14:43:49 UTC (rev 227)
@@ -57,24 +57,6 @@
return isOk() ? nom : TEXT("");}
};
-struct ChainePMT {
- UINT16 video_pid; //!< PID du flux vidéo
- VideoStreamType video_type; //!< Type du flux vidéo
- UINT16 pcr_pid; //!< PID contenant le "Program Clock Reference" (= en principe
- //!< au PID d'une autre piste existante, vidéo, audio ...)
- liste_pistes sons; //!< Liste des pistes son
- liste_pistes autr; //!< Liste des pistes "autres"
-
- ChainePMT();
- LPCTSTR norme(void) const;
- bool operator == (const ChainePMT & cpmt) const;
- bool operator != (const ChainePMT & cpmt) const {return ! operator == (cpmt);};
-
- /// Déterminer si une chaîne est cryptée ou pas
- bool isEncrypted() const {
- return video_type>=vst_MPEG2_encrypted;}
-};
-
// Définition de l'ensemble des identifiants d'une chaîne :
struct ChaineIDs {
UINT16 ONID; //!< Original Network ID (spécifique au réseau)
@@ -143,7 +125,6 @@
char nom[64];
char groupe[64];
INT32 khz; //!< Fréquence retenue pour le multiplex
- UINT16 pmt_pid; //!< PID de la table PMT
UINT16 nNumeroNit; //!< Numéro de chaîne original défini par le réseau
UINT16 nNumeroAuto; //!< Numéro de chaîne automatiquement attribué par l'application
//!< (mémorisé car il existe une commande de restauration)
@@ -237,7 +218,7 @@
/// Déterminer s'il s'agit d'une chaîne audio (radio numérique)
bool isAudio() const {
- return video_type == vst_Unknown && video_pid == 0 && sons.nbr > 0;}
+ return video_type == vst_Unknown && video_pid == 0 && nbr > 0;}
/// Déterminer si l'enregistrement en mode PS est disponible
bool isPsRecordAvailable() const {
Modifié: trunk/chanutils.cpp
===================================================================
--- trunk/chanutils.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/chanutils.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -65,9 +65,17 @@
int liste_pistes::ajoute(const une_piste & piste)
{
- if (nbr<_countof(tbl)) {
- tbl[nbr] = piste;
- return nbr++;
+ if (nbr_tot<_countof(tbl)) {
+ if (piste.type >= tst_Other_BEG) {
+ tbl[nbr_tot] = piste;
+ return nbr_tot++;
+ } else {
+ for (int nInx = nbr_tot; nInx > nbr; --nInx)
+ tbl[nInx] = tbl[nInx-1];
+ ++nbr_tot;
+ tbl[nbr] = piste;
+ return nbr++;
+ }
}
return -1;
}
@@ -150,3 +158,33 @@
}
}
+ChainePMT::ChainePMT() :
+ pmt_pid(0),
+ video_pid(0),
+ video_type(vst_Unknown),
+ pcr_pid(0)
+{
+}
+
+bool ChainePMT::operator == (const ChainePMT & cpmt) const
+{
+ if (video_pid!=cpmt.video_pid || video_type!=cpmt.video_type || pcr_pid!=cpmt.pcr_pid)
+ return false;
+ return liste_pistes::operator == (cpmt);
+}
+
+LPCTSTR ChainePMT::norme(void) const
+{
+ switch (video_type) {
+ case vst_MPEG2:
+ return TEXT("Mpeg2");
+ case vst_H264:
+ return TEXT("H264");
+ case vst_MPEG2_encrypted:
+ case vst_H264_encrypted:
+ return TEXT("Crypté");
+ }
+ if (nbr > 0)
+ return TEXT("Audio");
+ return TEXT("Inconnu");
+}
Modifié: trunk/chanutils.h
===================================================================
--- trunk/chanutils.h 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/chanutils.h 2010-01-09 14:43:49 UTC (rev 227)
@@ -107,12 +107,28 @@
return lang[0]!=0 && strcmp(lang, "fra")!=0 && strcmp(lang, "fre")!=0;}
};
+/**
+ * Table des pistes associées à une chaîne (son en premier, autres ensuite)
+ **/
struct liste_pistes {
- UINT16 nbr;
- une_piste tbl[NB_MAX_PISTES];
+ UINT16 nbr; //!< Nombre de pistes son
+ UINT16 nbr_tot; //!< Nombre de pistes total
+ une_piste tbl[NB_MAX_PISTES]; //!< Table des pistes
- liste_pistes() : nbr(0) {};
+ liste_pistes() :
+ nbr(0),
+ nbr_tot(0)
+ {};
+#if STREAMS_SAVE_ALL
+ LPCSTR getTagBase(bool bOther) const {
+ return bOther ? "Autre" : "Son";}
+ UINT16 getFirst(bool bOther) const {
+ return bOther ? nbr : 0;}
+ UINT16 getCount(bool bOther) const {
+ return bOther ? nbr_tot-nbr : nbr;}
+#endif // #if STREAMS_SAVE_ALL
+
bool cherche_pid(UINT16 pid) const;
int ajoute(const une_piste & piste);
@@ -124,3 +140,20 @@
bool operator == (const liste_pistes & lp) const;
bool operator != (const liste_pistes & lp) const {return ! operator == (lp);};
};
+
+struct ChainePMT : public liste_pistes {
+ UINT16 pmt_pid; //!< PID de la table PMT
+ UINT16 video_pid; //!< PID du flux vidéo
+ VideoStreamType video_type; //!< Type du flux vidéo
+ UINT16 pcr_pid; /*!< PID contenant le "Program Clock Reference" (= en principe
+ au PID d'une autre piste existante, vidéo, audio ...)
+ \todo Nécessaire ? */
+ ChainePMT();
+ LPCTSTR norme(void) const;
+ bool operator == (const ChainePMT & cpmt) const;
+ bool operator != (const ChainePMT & cpmt) const {return ! operator == (cpmt);};
+
+ /// Déterminer si une chaîne est cryptée ou pas
+ bool isEncrypted() const {
+ return video_type>=vst_MPEG2_encrypted;}
+};
Modifié: trunk/config.h
===================================================================
--- trunk/config.h 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/config.h 2010-01-09 14:43:49 UTC (rev 227)
@@ -52,6 +52,16 @@
#endif
#endif
+/**
+ * Activation (1) ou désactivation (0) de la sauvegarde des informations
+ * sur les flux vidéos, son et autre/
+ * \test La désactivation semble poser problème, notamment vis à vis des
+ * enregistrements programmés. Pour le moment, laisser activé et ne se
+ * servir de ceci que pour des tests d'évolutions progressives visant à
+ * permettre une désactivation sûre.
+ **/
+#define STREAMS_SAVE_ALL 1
+
// ====================================================================================
// Options liées au graphe
// ====================================================================================
Modifié: trunk/ini.cpp
===================================================================
--- trunk/ini.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/ini.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -92,6 +92,9 @@
{IDM_ALLWDT, TEXT("Utiliser toute la largeur"), TEXT("Aff Pleine largeur"), {false, false, false, TEXT('W')}},
{IDM_ALLHGT, TEXT("Utiliser toute la hauteur"), TEXT("Aff Pleine hauteur"), {false, false, false, TEXT('H')}},
{IDM_ETIRER, TEXT("Étirer la vidéo"), TEXT("Aff Étirer"), {false, false, false, TEXT('E')}},
+ // Divers
+ {IDM_CONFIG, TEXT("Configuration"), TEXT("Opt Config"), {false, false, false, TEXT('C')}},
+ {IDM_SIGNAL, TEXT("Qualité du signal"), TEXT("Info Signal"), {true, false, false, TEXT('S')}},
#ifdef _DIAGNOSTIC
{IDM_RUN_GRAPH, TEXT("Mettre le graphe en marche"), TEXT("Debug GrapheMarche"), {false, true, false, TEXT('R')}},
{IDM_PAUSE_GRAPH, TEXT("Mettre le graphe en pause"), TEXT("Debug GraphePause"), {false, true, true, TEXT('R')}},
@@ -223,11 +226,15 @@
// ====================================================================================
/// Nom de base du fichier définissant les villes et les canaux
-TCHAR scan_ini[]=TEXT("canaux.ini");
+TCHAR scan_ini[] = TEXT("canaux.ini");
+/// Nom du fichier de configuration
+TCHAR config_file[] = TEXT("config.ini");
+
/**
* Table des jours de la semaine pour sauvegarde et affichage.
**/
+/*
LPCTSTR Tbl_DoW[7] = {
TEXT("Dimanche"),
TEXT("Lundi"),
@@ -237,12 +244,9 @@
TEXT("Vendredi"),
TEXT("Samedi")
};
+*/
// ====================================================================================
-
-TCHAR config_file[] = TEXT("config.ini"); ///< Nom du fichier de configuration
-
-// ====================================================================================
// Fonctions
// ====================================================================================
@@ -277,7 +281,7 @@
/**
* Tableau associatif convertissant les valeurs booléennes pour sauvegarde
**/
-AssocElement aBoolTable[] =
+const AssocElement aBoolTable[] =
{
{TEXT("Faux"), 0},
{TEXT("Vrai"), 1},
@@ -287,7 +291,7 @@
/**
* Tableau associatif décrivant les prioritées de PTVM pour sauvegarde
**/
-AssocElement aPrioTable[] =
+const AssocElement aPrioTable[] =
{
{TEXT("Basse"), IDLE_PRIORITY_CLASS},
{TEXT("Inférieure"), BELOW_NORMAL_PRIORITY_CLASS},
@@ -301,7 +305,7 @@
/**
* Tableau associatif décrivant les différents affichages de la fenêtre pour sauvegarde
**/
-AssocElement aWStateTable[] =
+const AssocElement aWStateTable[] =
{ // EtatsFenetre
{TEXT("Normale"), etf_normal},
{TEXT("Sans menus"), etf_noborders},
@@ -311,7 +315,10 @@
{NULL, 0} // -> terminateur
};
-AssocElement aVideoTypeTable[] =
+/**
+ * Tableau associatif décrivant les différents types de flux vidéo reconnus
+ **/
+const AssocElement aVideoTypeTable[] =
{ // VideoStreamType
{TEXT("MPEG2"), vst_MPEG2},
{TEXT("H264"), vst_H264},
@@ -323,7 +330,7 @@
/**
* Tableau associatif décrivant le dernier type d'enregistrement dans la fenêtre de gestion de l'EPG pour la vidéo
**/
-AssocElement aEpgRecVideo[] =
+const AssocElement aEpgRecVideo[] =
{ // MethodeEnregistrement
{TEXT("TS"), meth_TS},
{TEXT("PS"), meth_PS},
@@ -334,7 +341,7 @@
/**
* Tableau associatif décrivant le dernier type d'enregistrement dans la fenêtre de gestion de l'EPG pour l'audio
**/
-AssocElement aEpgRecAudio[] =
+const AssocElement aEpgRecAudio[] =
{ // AudioMode
{TEXT("Aucune"), am_None},
{TEXT("Audio1"), am_Mpeg_1},
@@ -349,7 +356,7 @@
/**
* Tableau associatif décrivant les différentes configurations VMR disponibles
**/
-AssocElement aVMRModeTable[] =
+const AssocElement aVMRModeTable[] =
{ // VMRTypes
{TEXT("Aucun"), vmt_null},
{TEXT("VMR7 windowless"), vmt_VMR7_windowless},
@@ -363,7 +370,7 @@
/**
* Tableau associatif décrivant les différents modes panoramiques de la vidéo
**/
-AssocElement aPanModeTable[] =
+const AssocElement aPanModeTable[] =
{ // PanModes
{TEXT("Normal"), pm_Normal},
{TEXT("Étirer"), pm_Stretch},
@@ -375,7 +382,7 @@
/**
* Tableau associatif décrivant les méthodes de recherche des chaînes
**/
-AssocElement aSMethodTable[] =
+const AssocElement aSMethodTable[] =
{ // SearchMethod
{TEXT("Indéfinie"), sm_undef},
{TEXT("Incrémentale"), sm_incremental},
@@ -387,7 +394,7 @@
/**
* Tableau associatif décrivant les offsets de recherche des chaînes
**/
-AssocElement aOffsetsToUse[] =
+const AssocElement aOffsetsToUse[] =
{ // OffsetsToUse
{TEXT("0"), (DWORD)uo_0},
{TEXT("+167"), (DWORD)uo_167},
@@ -400,7 +407,7 @@
/**
* Tableau associatif décrivant les différents rôles possibles de la molette de la souris
**/
-AssocElement aMWheelTable[] =
+const AssocElement aMWheelTable[] =
{ // MouseWheelUsage
{TEXT("Aucun"), (DWORD)mwu_None},
{TEXT("Chaînes"), (DWORD)mwu_Channels},
@@ -862,10 +869,10 @@
class CIniFile
{
- NomFichierConf sIniFilePathName;
+ NomFichierConf<> sIniFilePathName;
protected:
- TCHAR szSectionName[128];
- DWORD dwError;
+ TCHAR szSectionName[128];
+ DWORD dwError;
public:
CIniFile(LPCTSTR pszFileName, bool bUsePrefix=true, LPCTSTR pszDir=pouchindir_conf) :
sIniFilePathName(pszFileName, bUsePrefix, pszDir),
@@ -1363,8 +1370,8 @@
return;
// Tout s'est bien passé : on peut utiliser les canaux.ini
- NomFichierConf fileName(scan_ini, false);
- TCHAR szBuffer[32] = {0};
+ NomFichierConf<> fileName(scan_ini, false);
+ TCHAR szBuffer[32] = {0};
// Lit pour voir si le fichier Canaux existe, et est plus ancien
GetPrivateProfileString(TEXT("Général"), TEXT("revision"), TEXT(""),
@@ -1551,11 +1558,11 @@
UINT nr_multiplex = 1;
do {
_stprintf_s(id_multiplex, _countof(id_multiplex), TEXT("R%d"), nr_multiplex);
- canal_no = (BYTE)cChanFile.load_int(id_multiplex, 0);
- if (canal_no != 0)
+ canal_no = (BYTE)cChanFile.load_int(id_multiplex, 0xff);
+ if (canal_no != 0 && canal_no != 0xff)
add(canal_no);
nr_multiplex++;
- } while (canal_no != 0 && nr_multiplex <= 99);
+ } while (canal_no != 0xff && nr_multiplex <= 99);
}
}
@@ -1599,7 +1606,7 @@
* recalcul du SID avec \p indexToSID ; attention cependant aux personnes qui migreraient
* tardivement depuis une très ancienne version du programme.
**/
-int lit_programmes(void)
+HRESULT lit_programmes()
{
// Noms des noeuds actuels
static const XMLSystemTimeNames Xstn_std = {
@@ -1639,10 +1646,10 @@
CXMLWrapper xml;
// Chargement du fichier décrivant les programmes (enregistrements)
- HRESULT hr = xml.charge(NomFichierConf(TEXT("programmes.xml")));
+ HRESULT hr = xml.charge(NomFichierConf<>(TEXT(FILENAME_PROGRAMS)));
if (FAILED(hr)) {
- return 1;
+ return E_FAIL;
}
CXMLElement root = xml.getDocElement();
@@ -1714,7 +1721,7 @@
// Au cas où on passe d'une ancienne version ne supportant pas les répétitions
if (repetitions) {
for (int j=0; j<7; j++) {
- if (repetitions->getInt(Tbl_DoW[j])!=0)
+ if (repetitions->getInt(EnumToString(j, prog.pszDoW))!=0)
prog.repetition |= 1<(TEXT(FILENAME_PROGRAMS)));
if (!oxml.opened())
return;
@@ -1801,7 +1808,7 @@
CXMLOpenChild oxmlc3(oxml, "Repetitions");
for (int j=0; j<7; j++)
- oxml.put(oxml.fmt("%" T2a, Tbl_DoW[j]), (programme.repetition & (1<(TEXT(FILENAME_CHANNELS)));
if (hr!=S_OK)
return hr;
@@ -1893,8 +1908,8 @@
canal.pmt_pid = (WORD)pNode->getInt(TEXT("PMT"));
canal.pcr_pid = (WORD)pNode->getInt(TEXT("PCR"));
-// Désactivation optionnelle des informations sur les flux vidéo, son et autre
-#if STREAMS_SAVE_ALL
+ // Désactivation optionnelle des informations sur les flux vidéo, son et autre
+ #if STREAMS_SAVE_ALL
// Détermine le type de flux vidéo
pNode->getStr(TEXT("Video_type"), var, _countof(var));
canal.video_type = (VideoStreamType)str2dword(aVideoTypeTable, var, vst_Unknown);
@@ -1909,10 +1924,10 @@
}
// Récupère les pistes son
- lit_pistes(*pNode, canal.sons, TEXT("Son"));
+ lit_pistes(*pNode, canal, false);
// Récupère les autres informations
- lit_pistes(*pNode, canal.autr, TEXT("Autre"));
-#endif
+ lit_pistes(*pNode, canal, true);
+ #endif // #if STREAMS_SAVE_ALL
// Mémorise le canal généré
Canaux.push_back(canal);
@@ -1928,34 +1943,37 @@
* Sauvegarde de la liste de pistes d'un type donné.
* \param[in] oxml Noeud XML
* \param[in] sPistes Liste de pistes
- * \param[in] pszTagStr Partie spécifique du tag XML à utiliser
+ * \param[in] bOther \p true si piste “Autre”
**/
-static void sauve_pistes(CXMLOutput & oxml, const liste_pistes & sPistes, LPCSTR pszTagStr)
+static void sauve_pistes(CXMLOutput & oxml, const liste_pistes & sPistes, bool bOther)
{
- oxml.put(oxml.fmt("Nb_%s", pszTagStr), sPistes.nbr);
+ LPCSTR pszTagStr = sPistes.getTagBase(bOther);
+ int nMax = sPistes.getCount(bOther);
+ int nOfs = sPistes.getFirst(bOther);
- // Mémorise toutes les pistes sons
- for (int j=0; j(TEXT(FILENAME_CHANNELS)));
if (!oxml.opened())
return;
@@ -1986,16 +2004,16 @@
oxml.put("PMT", canal.pmt_pid);
oxml.put("PCR", canal.pcr_pid);
-// Désactivation optionnelle des informations sur les flux vidéo, son et autre
-#if STREAMS_SAVE_ALL
+ // Désactivation optionnelle des informations sur les flux vidéo, son et autre
+ #if STREAMS_SAVE_ALL
oxml.put("Video", canal.video_pid);
oxml.put("Video_type", oxml.fmt("%" T2a, dword2str(aVideoTypeTable, canal.video_type)));
// Mémorise toutes les pistes sons
- sauve_pistes(oxml, canal.sons, "Son");
+ sauve_pistes(oxml, canal, false);
// Mémorise toutes les autres informations
- sauve_pistes(oxml, canal.autr, "Autre");
-#endif
+ sauve_pistes(oxml, canal, true);
+ #endif // #if STREAMS_SAVE_ALL
}
}
@@ -2200,7 +2218,7 @@
/**
* Sauvegarde les raccourcis
**/
-void save_config_raccourcis(void)
+void save_config_raccourcis()
{
CConfigFile().save_raccourcis();
}
@@ -2586,7 +2604,7 @@
/**
* Lecture de la configuration depuis le fichier de configuration
- * se trouvant dans \c "%appdata%\poutchin TV Mod", ou dans le dossier actuel
+ * se trouvant dans \c "%AppData%\Pouchin TV Mod", ou dans le dossier actuel
**/
void load_config()
{
@@ -2604,7 +2622,7 @@
swap(cConfig, cConfig2);
// ... et on décide que le répertoire de configuration sera celui du
// programme .
- /// \todo Faire en sorte que %AppData% devienne la seule option
+ /// \todo Faire en sorte que \c "%AppData%" devienne la seule option
strcpy_T(pouchindir_conf, pouchindir_prog);
}
}
@@ -2681,7 +2699,7 @@
* \retval true si le tuner configuré est valide
* \retval false si le tuner n'est pas valide
**/
-bool check_config(void)
+bool check_config()
{
#if ADVANCED_TUNER_SEARCH
if (!IsNullName(szPathTuner)) {
Modifié: trunk/ini.h
===================================================================
--- trunk/ini.h 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/ini.h 2010-01-09 14:43:49 UTC (rev 227)
@@ -31,16 +31,12 @@
#include "utils.h"
#include "channels.h"
-/**
- * Activation (1) ou désactivation (0) de la sauvegarde des informations
- * sur les flux vidéos, son et autre/
- * \test La désactivation semble poser problème, notamment vis à vis des
- * enregistrements programmés. Pour le moment, laisser activé et ne se
- * servir de ceci que pour des tests d'évolutions progressives visant à
- * permettre une désactivation sûre.
- **/
-#define STREAMS_SAVE_ALL 1
+/// Nom du fichier des chaines reçues
+#define FILENAME_CHANNELS "chaines.xml"
+/// Nom du fichier de sauvegarde des programmations
+#define FILENAME_PROGRAMS "programmes.xml"
+
/// Répertoire de Pouchin TV Mod
extern TCHAR pouchindir_prog[MAX_PATH];
@@ -295,17 +291,19 @@
FapfResult FindAppFile(LPCTSTR pszSubDir, LPCTSTR pszFile, tstring & strResult, DWORD dwFlags=FF_RECURSIVE);
/// Nom de fichier situé avec les données de l'application
-struct NomFichierConf
+template
+ struct NomFichierConf
{
- TCHAR str[MAX_PATH];
+ T str[MAX_PATH];
- NomFichierConf(LPCTSTR pszBaseName, bool bUsePrefix=true, LPCTSTR pszDir=pouchindir_conf) {
+ NomFichierConf(const U * pszBaseName, bool bUsePrefix=true, LPCTSTR pszDir=pouchindir_conf)
+ {
strcpy_T(str, pszDir);
if (bUsePrefix)
strcat_T(str, prefix_conf);
strcat_T(str, pszBaseName);
}
- operator LPCTSTR() const {
+ operator const T * () const {
return str;}
};
@@ -391,28 +389,28 @@
/**
* Sauvegarde de la liste des chaînes dans "chaines.xml".
**/
-void sauve_chaines(void);
+void sauve_chaines();
/**
* Lecture des programmations d'enregistrement depuis un fichier.
**/
-int lit_programmes(void);
+HRESULT lit_programmes();
/**
* Sauvegarde des programmations d'enregistrements dans un fichier.
**/
-void sauve_programmes(void);
+void sauve_programmes();
/**
* Sauvegarde tous les paramètres de configuration
**/
-void save_config(void);
+void save_config();
/**
* Lecture de la configuration depuis le fichier de configuration
- * se trouvant dans \c "%appdata%\poutchin TV Mod", ou dans le dossier actuel
+ * se trouvant dans \c "%AppData%\Pouchin TV Mod", ou dans le dossier actuel
**/
-void load_config(void);
+void load_config();
/**
* Chargement de la combo box 'hItm' à partir du fichier des noms de villes.
@@ -433,7 +431,7 @@
* \retval true si le tuner configuré est valide
* \retval false si le tuner n'est pas valide
**/
-bool check_config(void);
+bool check_config();
/**
* Sauvegarde la configuration spécifique au tuner
@@ -581,9 +579,9 @@
extern const AssocElement aChStateTable[];
/**
- * Table des jours de la semaine pour sauvegarde et affichage.
+ * Tableau associatif décrivant les différents types de flux vidéo reconnus
**/
-extern LPCTSTR Tbl_DoW[7];
+extern const AssocElement aVideoTypeTable[];
/**
* Variable à mettre à 'true' toutes les fois que quelque chose a été modifié
Modifié: trunk/main.cpp
===================================================================
--- trunk/main.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/main.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -523,7 +523,7 @@
while (DeleteMenu(hAudio, SMENU_PISTES_POSITION, MF_BYPOSITION));
// Insérer les nouveaux items de pistes audio
- for (int i=0; i 0) {
+ if (canal.nbr > 0) {
log(TEXT(" -- Audio seul") EOL);
} else {
//vire cette chaîne
@@ -481,16 +476,11 @@
}
} else {
TCHAR szWrk[128];
- int j;
- for (j=0; j 0)
+ if (canal.nbr > 0)
canal.etat = ec_active; // radio ...
else
canal.etat = ec_inactive;
@@ -1024,8 +1014,8 @@
raz_carte();
// Définition de l'emplacement du fichier de 'log' de la recherche, et ouverture.
- NomFichierConf sLogFileName(TEXT("scan.log"));
- FILE * fop;
+ NomFichierConf<> sLogFileName(TEXT("scan.log"));
+ FILE * fop;
if (_tfopen_s(&fop, sLogFileName, TEXT("a"))==0)
fLog = fop;
Modifié: trunk/pmtfilter.cpp
===================================================================
--- trunk/pmtfilter.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/pmtfilter.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -82,6 +82,7 @@
ChainePMT & chaine = Canaux[ixChaineCourante];
ChainePMT lpmt_e;
+ lpmt_e.pmt_pid = chaine.pmt_pid; // Récupération pid PMT
parse_pmt(*ppmt, false, lpmt_e);
if (lpmt_e != chaine) { // "operator !=" maintenant implémenté
Modifié: trunk/record.cpp
===================================================================
--- trunk/record.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/record.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -379,7 +379,6 @@
const Chaine & canal = Canaux[ixChaine];
NomFichierAvecDate nom_fichier(video_dir, getProgName(pProg), canal.nom, TEXT("ts"));
- UINT16 video = canal.video_pid ;
HANDLE hFile = nom_fichier.Create();
if (hFile == INVALID_HANDLE_VALUE) {
@@ -387,13 +386,12 @@
return -1;
}
- CCapture_TS * pCapture = new CCapture_TS(hFile, canal.pmt_pid,
- video, canal.sons, canal.autr);
+ CCapture_TS * pCapture = new CCapture_TS(hFile, canal);
if (pCapture==NULL)
return -1;
- myprintf(BOLD(TEXT("Enregistre TS")) TEXT(", video=%i, pmt=%i") EOL, video, canal.pmt_pid);
+ myprintf(BOLD(TEXT("Enregistre TS")) TEXT(", video=%i, pmt=%i") EOL, canal.video_pid, canal.pmt_pid);
cRecord[ixRecDescr].start(pCapture, ixChaine, pProg);
return ixRecDescr;
}
@@ -426,7 +424,7 @@
NomFichierAvecDate nom_fichier(video_dir, getProgName(pProg), canal.nom, TEXT("mpg"));
UINT16 video_pid = canal.video_pid;
- UINT16 audio_pid = canal.sons.tbl[ixSon].pid;
+ UINT16 audio_pid = canal.tbl[ixSon].pid;
HANDLE hFile = nom_fichier.Create();
if (hFile == INVALID_HANDLE_VALUE) {
Modifié: trunk/recprog.cpp
===================================================================
--- trunk/recprog.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/recprog.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -160,6 +160,16 @@
TEXT("Erreur")
};
+/// Liste des jours de la semaine pour affichage et sauvegarde
+LPCSTR Programme::pszDoW =
+ "Dimanche\0"
+ "Lundi\0"
+ "Mardi\0"
+ "Mercredi\0"
+ "Jeudi\0"
+ "Vendredi\0"
+ "Samedi\0";
+
/// Constructeur
Programme::Programme()
{
@@ -1920,7 +1930,7 @@
if (ixRecDescr < 0) {
// Si elle ne l'est pas, on démarre l'enregistrement :
- int ixSon = canal.sons.selection_son(prog.audio); // utilisé seulement en PS pour le moment
+ int ixSon = canal.selection_son(prog.audio);// utilisé seulement en PS pour le moment
switch(prog.methode) {
case meth_TS:
Modifié: trunk/recprog.h
===================================================================
--- trunk/recprog.h 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/recprog.h 2010-01-09 14:43:49 UTC (rev 227)
@@ -83,6 +83,8 @@
{
static const LPCTSTR t_states[];
public:
+ static LPCSTR pszDoW; //!< Liste des jours de la semaine pour affichage et sauvegarde
+
SYSTEMTIME debut; //!< Date & heure de début
/**
@@ -168,8 +170,8 @@
*
* \retval Pointeur sur une chaîne de caractère qui représente ce nom
**/
- LPCTSTR startDoW() const {
- return debut.wDayOfWeek<7 ? Tbl_DoW[debut.wDayOfWeek] : TEXT("?");}
+ LPCSTR startDoW() const {
+ return EnumToString(debut.wDayOfWeek, pszDoW);}
/// Retourne \p true si la programmation est couramment active
bool active() const {
@@ -197,7 +199,7 @@
* \retval Nombre de caractères écrits dans le tampon.
**/
UINT32 formate_heure_debut(LPTSTR pszBuf, UINT32 nCount) const {
- return _stprintf_s(pszBuf, nCount, TEXT("%s %i/%02i à %ih%02i"),
+ return _stprintf_s(pszBuf, nCount, TEXT("%") A2t TEXT(" %i/%02i à %ih%02i"),
startDoW(), debut.wDay, debut.wMonth, debut.wHour, debut.wMinute); }
/**
Modifié: trunk/res.rc
===================================================================
--- trunk/res.rc 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/res.rc 2010-01-09 14:43:49 UTC (rev 227)
@@ -376,7 +376,7 @@
IDD_DELAYED_STOP DIALOGEX 100, 100, 166, 148
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
-CAPTION "Stopper l'enregistrement dans…"
+CAPTION "Arrêter l'enregistrement dans…"
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
RTEXT "Chaîne enregistrée :",IDC_STATIC,7,9,70,8
Modifié: trunk/utils.cpp
===================================================================
--- trunk/utils.cpp 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/utils.cpp 2010-01-09 14:43:49 UTC (rev 227)
@@ -132,6 +132,28 @@
}
/**
+ * Conversion d'une chaîne de caractères WCHAR vers une chaîne std::string
+ * \param[in] pszStr Chaîne à convertir
+ **/
+std::string WChar2Char(LPCWSTR pszStr)
+{
+ COPY_STR_ON_STACK(CHAR, pszTmp, pszStr, nLen);
+
+ return pszTmp;
+}
+
+/**
+ * Conversion d'une chaîne de caractères CHAR vers une chaîne std::wstring
+ * \param[in] pszStr Chaîne à convertir
+ **/
+std::wstring Char2WChar(LPCSTR pszStr)
+{
+ COPY_STR_ON_STACK(WCHAR, pszTmp, pszStr, nLen);
+
+ return pszTmp;
+}
+
+/**
* Vérifie que les valeurs stockées sont dans la surface d'affichage actuelle
*
* \retval true si la zone est comprise dans l'affichage actuel
Modifié: trunk/utils.h
===================================================================
--- trunk/utils.h 2010-01-08 09:59:36 UTC (rev 226)
+++ trunk/utils.h 2010-01-09 14:43:49 UTC (rev 227)
@@ -402,30 +402,43 @@
// ----------------------------------------------------------------------------
+/**
+ * Conversion d'une chaîne de caractères WCHAR vers une chaîne std::string
+ * \param[in] pszStr Chaîne à convertir
+ **/
+std::string WChar2Char(LPCWSTR pszStr);
+
+/**
+ * Conversion d'une chaîne de caractères CHAR vers une chaîne std::wstring
+ * \param[in] pszStr Chaîne à convertir
+ **/
+std::wstring Char2WChar(LPCSTR pszStr);
+
+
/*! \def WCHAR2TCHAR
* Conversion "à la volée" d'une chaîne WCHAR vers une chaîne TCHAR.
- * Macro à utiliser lorsque la conversion doit impérativement se faire
- * au milieu d'une expression, et qu'on ne peut donc pas créer de variable
- * intermédiaire. Dans tous les autres cas, il vaut mieux passer par une
- * variable intermédiaire.
- * L'allocation mémoire intermédiaire est néanmoins
+ * Macro à utiliser de préférence lorsque la conversion doit se faire
+ * au milieu d'une expression. L'allocation mémoire intermédiaire est
* automatiquement libérée après évaluation de l'expression.
**/
#ifdef _UNICODE
#define WCHAR2TCHAR(str) str
#else
- inline std::string WChar2Char(LPCWSTR pszStr)
- {
- UINT nLen = strlen_T(pszStr);
- std::string strRes;
-
- strRes.resize(nLen);
- strcpy_T(&strRes[0], nLen+1, pszStr);
- return strRes;
- }
#define WCHAR2TCHAR(str) WChar2Char(str).c_str()
#endif
+/*! \def CHAR2TCHAR
+ * Conversion "à la volée" d'une chaîne CHAR vers une chaîne TCHAR.
+ * Macro à utiliser de préférence lorsque la conversion doit se faire
+ * au milieu d'une expression. L'allocation mémoire intermédiaire est
+ * automatiquement libérée après évaluation de l'expression.
+ **/
+#ifdef _UNICODE
+ #define CHAR2TCHAR(str) Char2WChar(str).c_str()
+#else
+ #define CHAR2TCHAR(str) str
+#endif
+
/**
* Macro d'allocation d'un tableau de \p taille éléments de type \p type sur la pile,
* en tirant parti des particularités de la fonction système \p _alloca.
From pouchintv-dev at baysse.fr Sat Jan 9 21:32:02 2010
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: sam, 9 jan 2010 21:32:02 +0100
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r228 - in trunk: . tinyxml
Message-ID: <20100109203204.548F75F784@mail.baysse.fr>
Author: gingko
Date: 2010-01-09 21:32:02 +0100 (sam 09 jan 2010)
New Revision: 228
Added:
trunk/tinyxml/readme.html
trunk/xmlutils.cpp
trunk/xmlutils.h
Removed:
trunk/tinyxml/tinyXmlTestSTL_2005.vcproj
trunk/tinyxml/tinyXmlTestSTL_2008.vcproj
trunk/tinyxml/tinyxmlSTL_2005.vcproj
trunk/tinyxml/tinyxmlSTL_2008.vcproj
Modified:
trunk/Pouchin TV_2005.vcproj
trunk/Pouchin TV_2008.vcproj
trunk/capture.cpp
trunk/channels.cpp
trunk/channels.h
trunk/chanutils.cpp
trunk/chanutils.h
trunk/config.h
trunk/ini.cpp
trunk/main.cpp
trunk/recprog.cpp
trunk/recprog.h
trunk/tinyxml/tinyXmlTest_2005.vcproj
trunk/tinyxml/tinyXmlTest_2008.vcproj
trunk/tinyxml/tinyxml_2005.sln
trunk/tinyxml/tinyxml_2008.sln
trunk/tinyxml/tinyxml_lib_2005.vcproj
trunk/tinyxml/tinyxml_lib_2008.vcproj
trunk/update.cpp
trunk/utils.h
trunk/xml.cpp
trunk/xml.h
Log:
Généralisation de l'usage de la bibliothèque TinyXML.
ini.cpp, channels.h, channels.cpp, chanutils.h, chanutils.cpp, recprog.h, recprog.cpp,
xml.h, xml.cpp, xmlutil.h, xmlutils.cpp, update.cpp, config.hn utils.h et fichiers projet :
* Le chargement et la sauvegarde des fichiers "chaines.xml" et "programmes.xml" est
maintenant assuré par les fonctions de la bibliothèque TintXML, qui était déjà utilisé
dans les fonctions de mise à jour dans "update.cpp".
* Les différences fonctions de chargement et de sauvegarde XML sont réparties dans les
classes concernées par les différents noeuds XML concernés, à l'aide de fonctions
membres le plus souvent nommées "SetFromXMLElement" et "GetAsXMLElement", leur donnant
une structure modulaire facilitant une éventuelle réutilisation ultérieure.
* Une macro de configuration "USE_TINYXML" permet (provisoirement) de basculer entre
l'ancien et le nouveau système, le temps que ce dernier soit clairement validé.
chanutils.h, chanutils.cpp, capture.cpp :
* La fonction "liste_pistes::cherche_pid" est déplacée dans la structure "ChainePMT" (qui
hérite de "liste_pistes", permettant ainsi de généraliser la fonction à tous les "pids"
de la chaîne.
chanutils.h, chanutils.cpp :
* Ajout de commentaires
Fichiers projet de TinyXML :
* Mise à niveau de tous les fichiers projet, en particulier pour la gestion du 64 bits
(seul les fichiers "tinyxml_lib_200x.vcproj" l'étaient précédemment).
* Suppression des fichiers projets dédiés à la compilation STL de TinyXML. Ces derniers
sont remplacés par l'ajout de configurations "Debug_STL" et "Release_STL" dans les
fichiers restants, produisant le même résultat.
* Noter que j'ai tenté d'utiliser ces configurations "_STL" dans Pouchin TV Mod, mais j'ai
finalement renoncé, constatant que cela générait davantage de code que la configuration
initiale.
Modifié: trunk/Pouchin TV_2005.vcproj
===================================================================
--- trunk/Pouchin TV_2005.vcproj 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/Pouchin TV_2005.vcproj 2010-01-09 20:32:02 UTC (rev 228)
@@ -1064,6 +1064,10 @@
RelativePath=".\xml.cpp"
>
+
+
+
+
+
+
+
+
Value();
+ LPCSTR pszTxt = pXmlChild->GetText();
+
+ if (pszTxt == NULL)
+ pszTxt = "0";
+
+ // Conversion en numérique pour les champs qui le requièrent.
+ long nVal = atol(pszTxt);
+
+ switch (StringToEnum(pszTagStrList, pszTag)) {
+
+ case tlc_Nom: strcpy_T(nom, ConvertUTF82Char(pszTxt).c_str()); break;
+ case tlc_Canal: canal_no = (UINT16)nVal; break;
+ case tlc_Groupe: strcpy_T(groupe, ConvertUTF82Char(pszTxt).c_str()); break;
+ case tlc_Frequence: khz = nVal; break;
+ case tlc_ONID: ONID = (UINT16)nVal; break;
+ case tlc_TSID: TSID = (UINT16)nVal; break;
+ case tlc_SID: SID = (UINT16)nVal; break;
+ case tlc_Numero_initial: nNumeroNit = (UINT16)nVal; break;
+ case tlc_Numero_auto: nNumeroAuto = (UINT16)nVal; break;
+ case tlc_Numero: nNumeroChaine = (UINT16)nVal; break;
+ case tlc_Etat: etat = (EtatChaine)str2dword(aChStateTable,
+ ConvertUTF82Char(pszTxt).c_str(), ec_preferee); break;
+ case tlc_PMT: pmt_pid = (UINT16)nVal; break;
+ case tlc_PCR: pcr_pid = (UINT16)nVal; break;
+
+ #if STREAMS_SAVE_ALL
+ case tlc_Video:
+ video_pid = (UINT16)nVal;
+ if (video_type == vst_Unknown)
+ video_type = vst_MPEG2; // pour compatibilité versions antérieures à SVN 175
+ break;
+
+ case tlc_Video_mpeg4:
+ // Tag pour compatibilité versions antérieures à SVN 175
+ video_pid = (UINT16)nVal;
+ if (video_type == vst_Unknown)
+ video_type = vst_H264;
+ break;
+
+ case tlc_Video_type:
+ video_type = (VideoStreamType)str2dword(aVideoTypeTable,
+ ConvertUTF82Char(pszTxt).c_str(), vst_Unknown);
+ #endif // #if STREAMS_SAVE_ALL
+ }
+ }
+
+ #if STREAMS_SAVE_ALL
+ // Récupère les pistes son
+ liste_pistes::FromXML(pXmlElm, false);
+ // Récupère les autres informations
+ liste_pistes::FromXML(pXmlElm, true);
+ #endif
+ return true;
+}
+
+/**
+ * Construction d'un noeud TinyXML représentant la définition de la chaîne
+ * \return Noeud XML construit
+ **/
+TiXmlElement * Chaine::GetAsXMLElement() const
+{
+ TiXmlElement * pXmlChan(new TiXmlElement("Chaine"));
+
+ if (pXmlChan) {
+ for (int eTag = tlc_Nom; eTag < tlc_END; ++eTag) {
+ CHAR szTmp[_countof(nom)] = "";
+
+ switch (eTag) {
+ case tlc_Nom: strcpy_T(szTmp, ConvertChar2UTF8(nom).c_str()); break;
+ case tlc_Canal: _itoa_s(canal_no, szTmp, 10); break;
+ case tlc_Groupe: strcpy_T(szTmp, ConvertChar2UTF8(groupe).c_str()); break;
+ case tlc_Frequence: _itoa_s(khz, szTmp, 10); break;
+ case tlc_ONID: _itoa_s(ONID, szTmp, 10); break;
+ case tlc_TSID: _itoa_s(TSID, szTmp, 10); break;
+ case tlc_SID: _itoa_s(SID, szTmp, 10); break;
+ case tlc_Numero_initial: _itoa_s(nNumeroNit, szTmp, 10); break;
+ case tlc_Numero_auto: _itoa_s(nNumeroAuto, szTmp, 10); break;
+ case tlc_Numero: _itoa_s(nNumeroChaine, szTmp, 10); break;
+ case tlc_Etat: strcpy_T(szTmp, ConvertChar2UTF8(dword2str(aChStateTable, etat)).c_str());
+ break;
+ case tlc_PMT: _itoa_s(pmt_pid, szTmp, 10); break;
+ case tlc_PCR: _itoa_s(pcr_pid, szTmp, 10); break;
+ #if STREAMS_SAVE_ALL
+ case tlc_Video: _itoa_s(video_pid, szTmp, 10); break;
+ case tlc_Video_mpeg4: continue;
+ case tlc_Video_type: strcpy_T(szTmp, ConvertChar2UTF8(dword2str(aVideoTypeTable, video_type)).c_str());
+ #endif
+ }
+
+ SetXmlContent(pXmlChan, EnumToString(eTag, pszTagStrList), szTmp);
+ }
+ }
+
+ #if STREAMS_SAVE_ALL
+ // Mémorise toutes les pistes sons
+ liste_pistes::ToXML(pXmlChan, false);
+ // Mémorise toutes les autres informations
+ liste_pistes::ToXML(pXmlChan, true);
+ #endif
+ return pXmlChan;
+}
+
+#endif // #if USE_TINYXML
+
HBITMAP Chaine::ChargeIcone()
{
if (hImage==INVALID_HANDLE_VALUE)
@@ -308,7 +445,50 @@
return -1;
}
+#if USE_TINYXML
+
/**
+ * Chargement de l'ensemble des chaînes à partir d'un noeud TinyXML construit
+ * \param[in] pXmlElm Noeud XML contenant les données à charger
+ * \return \p true ou \p false selon succès ou échec
+ **/
+bool Chaines::SetFromXMLElement(const TiXmlElement * pXmlElm)
+{
+ if (_stricmp(pXmlElm->Value(), "Chaines")!=0)
+ return false;
+ for (ITERATE_XML_ELEMENTS_NAMED(pXmlElm, pXmlChild, "Chaine")) {
+ Chaine canal;
+
+ if (canal.SetFromXMLElement(pXmlChild))
+ push_back(canal);
+ }
+
+ return true;
+}
+
+/**
+ * Construction d'un noeud TinyXML représentant la définition de l'ensemble des chaînes
+ * \return Noeud XML construit
+ **/
+TiXmlElement * Chaines::GetAsXMLElement() const
+{
+ TiXmlElement * pXmlChLst(new TiXmlElement("Chaines"));
+
+ if (pXmlChLst) {
+ for (ITERATE_CONST_VECTOR(*this, Chaine, it)) {
+ TiXmlElement * pXmlChan(it->GetAsXMLElement());
+
+ if (pXmlChan)
+ pXmlChLst->LinkEndChild(pXmlChan);
+ }
+ }
+
+ return pXmlChLst;
+}
+
+#endif // #if USE_TINYXML
+
+/**
* Recherche d'une chaîne en partant de son numéro
* \param[in] nNumChaine Numéro de la chaîne, tel que défini dans la configuration des
* chaînes et tel qu'affiché à l'utilisateur
Modifié: trunk/channels.h
===================================================================
--- trunk/channels.h 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/channels.h 2010-01-09 20:32:02 UTC (rev 228)
@@ -137,6 +137,48 @@
/// Constructeur
Chaine();
+#if USE_TINYXML
+
+ /// Énumération corresopondant aux tags XML utilisés pour la sauvegarde d'une chaîne
+ enum TagListChaine {
+ tlc_Nom,
+ tlc_Canal,
+ tlc_Groupe,
+ tlc_Frequence,
+ tlc_ONID,
+ tlc_TSID,
+ tlc_SID,
+ tlc_Numero_initial,
+ tlc_Numero_auto,
+ tlc_Numero,
+ tlc_Etat,
+ tlc_PMT,
+ tlc_PCR,
+ #if STREAMS_SAVE_ALL
+ tlc_Video,
+ tlc_Video_mpeg4,
+ tlc_Video_type,
+ #endif
+ tlc_END
+ };
+
+ /// Noms des tags XML utilisés pour la sauvegarde d'une chaîne
+ static LPCSTR pszTagStrList;
+
+ /**
+ * Chargement de la définition de la chaîne à partir d'un noeud TinyXML construit
+ * \param[in] pXmlElm Noeud XML contenant les données à charger
+ * \return \p true ou \p false selon succès ou échec
+ **/
+ bool SetFromXMLElement(const TiXmlElement * pXmlElm);
+
+ /**
+ * Construction d'un noeud TinyXML représentant la définition de la chaîne
+ * \return Noeud XML construit
+ **/
+ TiXmlElement * GetAsXMLElement() const;
+#endif
+
/// Chargement de l'icône associée à la chaîne
/// \todo Le chargement de l'icône (pourtant existante) dans le menu échoue
/// parfois, de façon apparemment aléatoire. Chercher pourquoi.
@@ -239,7 +281,22 @@
public:
Chaines() {};
+#if USE_TINYXML
/**
+ * Chargement de l'ensemble des chaînes à partir d'un noeud TinyXML construit
+ * \param[in] pXmlElm Noeud XML contenant les données à charger
+ * \return \p true ou \p false selon succès ou échec
+ **/
+ bool SetFromXMLElement(const TiXmlElement * pXmlElm);
+
+ /**
+ * Construction d'un noeud TinyXML représentant la définition de l'ensemble des chaînes
+ * \return Noeud XML construit
+ **/
+ TiXmlElement * GetAsXMLElement() const;
+#endif
+
+ /**
* Tri des chaînes par numéro.
* En cas d'identité de numéro (numéro pas attribué = 0, par exemple),
* les noms de chaînes sont comparés.
Modifié: trunk/chanutils.cpp
===================================================================
--- trunk/chanutils.cpp 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/chanutils.cpp 2010-01-09 20:32:02 UTC (rev 228)
@@ -39,10 +39,61 @@
#include "chanutils.h"
-une_piste::une_piste(const une_piste &piste) {
- pid = piste.pid; type=piste.type;
- strcpy_T(lang, piste.lang);
+#if USE_TINYXML && STREAMS_SAVE_ALL
+
+/**
+ * Chargement de la définition d'un groupe de pistes à partir d'un noeud TinyXML construit
+ * \param[in] pXmlElm Noeud XML parent de celui contenant les informations recherchées
+ * \param[in] bOther \p false pour pistes "son", \p true pour pistes "autre"
+ * \return \p true ou \p false selon succès ou échec
+ **/
+bool liste_pistes::FromXML(const TiXmlElement * pXmlElm, bool bOther)
+{
+ LPCSTR pszTagStr = getTagBase(bOther);
+ int nCount = (int)atol(GetXmlContentF(pXmlElm, "Nb_%s", pszTagStr));
+
+ for (int i=0; i
+#if USE_TINYXML
+ #include "xmlutils.h"
+#endif
+
+/// Énumération indiquant le types de la piste vidéo
enum VideoStreamType : UINT8
{
- vst_Unknown = 0xff,
- vst_MPEG2 = 0,
- vst_H264,
- vst_MPEG2_encrypted, // hypothétique, pour être exhaustif
- vst_H264_encrypted
+ vst_Unknown = 0xff, //!< Type vidéo inconnu
+ vst_MPEG2 = 0, //!< Vidéo MPEG2
+ vst_H264, //!< Vidéo H264 (SD ou HD)
+ vst_MPEG2_encrypted, //!< Vidéo MPEG2 cryptée (hypothétique, pour être exhaustif)
+ vst_H264_encrypted //!< Vidéo H264 cryptée (SD ou HD)
};
+/// Énumération indiquant les types des pistes "son" et "autres"
enum TrackStreamType : UINT8
{
- tst_Unknown = 0xff,
- tst_MPEG2 = 0, //!< 0 = MPEG2 Audio Layer II
- tst_AC3, //!< 1 = AC3
- tst_EAC3, //!< 2 = Enhanced AC3
- tst_AC3_hc, //!< 3 = AC3 Home Cinema (plus de 2 canaux, style 5.1)
- tst_EAC3_hc, //!< 4 = Enhanced AC3 Home Cinema
- tst_Audio_END, //!< (limite des codes audio)
+ tst_MPEG2, //!< 0 = MPEG2 Audio Layer II
+ tst_AC3, //!< 1 = AC3
+ tst_EAC3, //!< 2 = Enhanced AC3
+ tst_AC3_hc, //!< 3 = AC3 Home Cinema (plus de 2 canaux, style 5.1)
+ tst_EAC3_hc, //!< 4 = Enhanced AC3 Home Cinema
+ tst_Audio_END, //!< (limite supérieure des codes audio)
//
// Autres formats :
- tst_Other_BEG = 0x80,
- tst_Subtitling = tst_Other_BEG,
- tst_Teletext,
- tst_Other_END
+ tst_Subtitling = 0x80, //!< 128 = Sous-titrage
+ tst_Teletext, //!< 129 = Télétexte
+ tst_Other_END, //!< (limite supérieure des codes "autres")
+ //
+ tst_Other_BEG = tst_Subtitling, //!< (limite inférieure des codes "autres")
+ //
+ tst_Unknown = 0xff //!< 255 = Inconnu
};
-/// Indique quelle piste audio sera préférée
+/// Énumération indiquant les préférences audio de l'utilisateur
enum AudioMode {
am_None, //!< Aucune préférence
am_Mpeg_1, //!< Utilisation de la première piste MPEG2 disponible
@@ -76,71 +84,153 @@
am_VO //!< Utilisation de la première piste non francophone disponible
};
-// Nombre max de pistes son par chaîne
+/// Nombre maximal de pistes "son" + "autre" par chaîne
#define NB_MAX_PISTES 32
+/// Description d'une piste ("son" ou "autre")
struct une_piste {
UINT16 pid;
TrackStreamType type; // si son : voir TrackStreamType; tst_Unknown (réservé) si autres
char lang[8];
- // Efface le tableau de caractère, car pose des problèmes des fois si pas effacé
- une_piste() : pid(0), type(tst_Unknown) {
- ZeroMemory(lang, sizeof(lang)); };
- une_piste(const une_piste &piste);
+ /// Constructeur par défaut
+ une_piste() :
+ pid(0),
+ type(tst_Unknown)
+ {
+ // Mise à zéro du tableau de caractères
+ ZeroMemory(lang, sizeof(lang));
+ }
+ /// Constructeur copie
+ une_piste(const une_piste & piste) :
+ pid(piste.pid),
+ type(piste.type)
+ {
+ strcpy_T(lang, piste.lang);
+ }
+
+ /// Comparaison pour égalité
bool operator == (const une_piste & up) const;
+
+ /// Comparaison pour différence
bool operator != (const une_piste & up) const {
return ! operator == (up); }
+ /**
+ * Obtenir une chaîne représentant la définition de la fiche, pour affichage ou journalisation
+ * \param[in,out] pszBuf Pointeur sur une chaîne recevant le résultat
+ * \param[in] nBufSiz Longueur de cette chaîne
+ **/
void getAsLogString(LPTSTR pszBuf, UINT32 nBufSiz) const;
+ /// Tester s'il s'agit d'une piste MPEG2
bool isMPEG2() const {
return type == tst_MPEG2;}
+
+ /// Tester s'il s'agit d'une piste AC3
bool isAC3() const {
return type >= tst_AC3 && type <= tst_EAC3_hc;}
+
+ /// Tester s'il s'agit d'une piste AC3 HC (plus de deux canaux)
bool isAC3_HC() const {
return type == tst_AC3_hc || type == tst_EAC3_hc;}
+
+ /// Tester s'il s'agit d'une piste AC3 non HC (au plus deux canaux)
bool isAC3_non_HC() const {
return type == tst_AC3 || type == tst_EAC3;}
+
+ /// Tester s'il s'agit d'une piste en V.O. (langue différente de français)
bool isVO() const {
return lang[0]!=0 && strcmp(lang, "fra")!=0 && strcmp(lang, "fre")!=0;}
};
-/**
- * Table des pistes associées à une chaîne (son en premier, autres ensuite)
- **/
+/// Table des pistes associées à une chaîne (son en premier, autres ensuite)
struct liste_pistes {
UINT16 nbr; //!< Nombre de pistes son
UINT16 nbr_tot; //!< Nombre de pistes total
une_piste tbl[NB_MAX_PISTES]; //!< Table des pistes
+ /// Constructeur par défaut
liste_pistes() :
nbr(0),
nbr_tot(0)
{};
#if STREAMS_SAVE_ALL
+ /**
+ * Obtenir la base du tag XML requis, selon qu'on se réfère à une piste "son" ou "autre"
+ * \param[in] bOther \p false pour "son", \p true pour "autre"
+ **/
LPCSTR getTagBase(bool bOther) const {
return bOther ? "Autre" : "Son";}
+
+ /**
+ * Obtenir l'index de la première piste "son" ou "autre"
+ * \param[in] bOther \p false pour "son", \p true pour "autre"
+ **/
UINT16 getFirst(bool bOther) const {
return bOther ? nbr : 0;}
+
+ /**
+ * Obtenir le nombre de pistes de type "son" ou "autre"
+ * \param[in] bOther \p false pour "son", \p true pour "autre"
+ **/
UINT16 getCount(bool bOther) const {
return bOther ? nbr_tot-nbr : nbr;}
+
+ #if USE_TINYXML
+ /**
+ * Chargement de la définition d'un groupe de pistes à partir d'un noeud TinyXML construit
+ * \param[in] pXmlElm Noeud XML parent de celui contenant les informations recherchées
+ * \param[in] bOther \p false pour pistes "son", \p true pour pistes "autre"
+ * \return \p true ou \p false selon succès ou échec
+ **/
+ bool FromXML(const TiXmlElement * pXmlElm, bool bOther);
+
+ /**
+ * Ajout des éléments de ce groupe de pistes à un noeud TinyXML
+ * \param[in] pXmlElm Noeud XML auquel ajouter les informations
+ * \param[in] bOther \p false pour pistes "son", \p true pour pistes "autre"
+ **/
+ void ToXML(TiXmlElement * pXmlElm, bool bOther) const;
+ #endif // #if USE_TINYXML
#endif // #if STREAMS_SAVE_ALL
- bool cherche_pid(UINT16 pid) const;
+ /**
+ * Ajout d'une piste à la liste, avec détermination de la catétorie ("son" ou "autre")
+ * selon le type de la piste
+ * \param[in] piste Piste à ajouter
+ * \return Index de la piste qui vient d'être ajouté
+ * \note L'insertion d'une piste "son" va décaler les index des pistes "autre" qui
+ * pourraient exister préalablement
+ **/
int ajoute(const une_piste & piste);
- int cherche_piste(bool (une_piste::*fn)() const, int nCount = 1) const;
+ /**
+ * Recherche de la Nème piste audio correspondant à un critère donné
+ * \param[in] pfn Pointeur sur une fonction membre de test de critère
+ * \param[in] nCount Valeur de "N", numéro de piste recherché
+ * \return Index de la piste trouvée, ou -1 si aucune
+ **/
+ int cherche_piste(bool (une_piste::*pfn)() const, int nCount = 1) const;
- /// Trouver la piste audio la mieux adaptée au choix de l'utilisateur
+ /**
+ * Trouver la piste audio la mieux adaptée au choix de l'utilisateur
+ * \param[in] eAudio Code de préférence de l'utilisateur
+ * \return Index de la piste audio sélectionnée, ou bien -1 en cas d'échec
+ **/
int selection_son(AudioMode eAudio) const;
+ /// Comparaison pour égalité
bool operator == (const liste_pistes & lp) const;
- bool operator != (const liste_pistes & lp) const {return ! operator == (lp);};
+
+ /// Comparaison pour différence
+ bool operator != (const liste_pistes & lp) const {
+ return ! operator == (lp);};
};
+/// Structure de définition des pistes d'une chaîne
struct ChainePMT : public liste_pistes {
UINT16 pmt_pid; //!< PID de la table PMT
UINT16 video_pid; //!< PID du flux vidéo
@@ -148,11 +238,27 @@
UINT16 pcr_pid; /*!< PID contenant le "Program Clock Reference" (= en principe
au PID d'une autre piste existante, vidéo, audio ...)
\todo Nécessaire ? */
+ /// Constructeur par défaut
ChainePMT();
- LPCTSTR norme(void) const;
+
+ /**
+ * Rechercher si un "pid" donné fait partie de la définition des flux TS d'une chaîne
+ * \param[in] pid Numéro de "pid" recherché
+ * \return \p true si le "pid" est défini dans la chaîne
+ **/
+ bool cherche_pid(UINT16 pid) const;
+
+ /// Obtenir une chaîne de caractères représentant le codage vidéo utilisée
+ /// pour la chaîne, pour affichage
+ LPCTSTR norme() const;
+
+ /// Comparaison pour égalité
bool operator == (const ChainePMT & cpmt) const;
- bool operator != (const ChainePMT & cpmt) const {return ! operator == (cpmt);};
+ /// Comparaison pour différence
+ bool operator != (const ChainePMT & cpmt) const {
+ return ! operator == (cpmt);};
+
/// Déterminer si une chaîne est cryptée ou pas
bool isEncrypted() const {
return video_type>=vst_MPEG2_encrypted;}
Modifié: trunk/config.h
===================================================================
--- trunk/config.h 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/config.h 2010-01-09 20:32:02 UTC (rev 228)
@@ -43,12 +43,12 @@
**/
#ifdef USE_LOGITECH_LCD // (si défini par le projet)
#undef USE_LOGITECH_LCD
- #define USE_LOGITECH_LCD 1
+ #define USE_LOGITECH_LCD 1
#else
#ifdef _DEBUG
- #define USE_LOGITECH_LCD 1
+ #define USE_LOGITECH_LCD 1
#else
- #define USE_LOGITECH_LCD 0
+ #define USE_LOGITECH_LCD 0
#endif
#endif
@@ -62,6 +62,11 @@
**/
#define STREAMS_SAVE_ALL 1
+/**
+ * Utilisation de la bibliothèque TinyXML pour les fichiers XML
+ **/
+#define USE_TINYXML 1
+
// ====================================================================================
// Options liées au graphe
// ====================================================================================
Modifié: trunk/ini.cpp
===================================================================
--- trunk/ini.cpp 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/ini.cpp 2010-01-09 20:32:02 UTC (rev 228)
@@ -32,8 +32,13 @@
#include "search.h"
#include "graph.h"
#include "recprog.h"
-#include "xml.h"
+#if USE_TINYXML
+ #include "xmlutils.h"
+#else
+ #include "xml.h"
+#endif
+
#include
// ====================================================================================
@@ -231,21 +236,6 @@
/// Nom du fichier de configuration
TCHAR config_file[] = TEXT("config.ini");
-/**
- * Table des jours de la semaine pour sauvegarde et affichage.
- **/
-/*
-LPCTSTR Tbl_DoW[7] = {
- TEXT("Dimanche"),
- TEXT("Lundi"),
- TEXT("Mardi"),
- TEXT("Mercredi"),
- TEXT("Jeudi"),
- TEXT("Vendredi"),
- TEXT("Samedi")
-};
-*/
-
// ====================================================================================
// Fonctions
// ====================================================================================
@@ -1370,8 +1360,8 @@
return;
// Tout s'est bien passé : on peut utiliser les canaux.ini
- NomFichierConf<> fileName(scan_ini, false);
- TCHAR szBuffer[32] = {0};
+ NomFichierConf fileName(scan_ini, false);
+ TCHAR szBuffer[32] = {0};
// Lit pour voir si le fichier Canaux existe, et est plus ancien
GetPrivateProfileString(TEXT("Général"), TEXT("revision"), TEXT(""),
@@ -1570,6 +1560,7 @@
// Programmations d'enregistrements
// ====================================================================================
+#if ! USE_TINYXML
/// Noms des différents éléments consituant la date et l'heure dans \p programmes.xml.
struct XMLSystemTimeNames {
LPCTSTR name_wYear; ///< Année
@@ -1598,6 +1589,7 @@
stim.wMinute = (WORD)pNode->getInt(xstn.name_wMinute);
stim.wSecond = (WORD)pNode->getInt(xstn.name_wSecond);
}
+#endif // #if ! USE_TINYXML
/**
* Lecture des programmations d'enregistrement depuis un fichier.
@@ -1608,6 +1600,15 @@
**/
HRESULT lit_programmes()
{
+#if USE_TINYXML
+ TiXmlDocument cTiXmlDoc;
+
+ if (cTiXmlDoc.LoadFile(NomFichierConf(FILENAME_PROGRAMS), TIXML_ENCODING_UTF8)) {
+ if (Programmes.SetFromXMLElement(cTiXmlDoc.RootElement()))
+ return S_OK;
+ }
+ return E_FAIL;
+#else // #if USE_TINYXML
// Noms des noeuds actuels
static const XMLSystemTimeNames Xstn_std = {
TEXT("Annee"),
@@ -1742,8 +1743,10 @@
std::sort(Programmes.begin(), Programmes.end());
programmation_modifiee = false;
return S_OK;
+#endif // #if USE_TINYXML
}
+#if ! USE_TINYXML
/**
* Fonction permettant d'enregistrer dans un nouveau noeud XML la date passée
*
@@ -1763,12 +1766,27 @@
oxml.put("Minute", stim.wMinute);
oxml.put("Seconde", stim.wSecond);
}
+#endif // #if ! USE_TINYXML
/**
* Sauvegarde des programmations d'enregistrements dans un fichier.
**/
void sauve_programmes()
{
+#if USE_TINYXML
+ TiXmlDocument xmlDoc(NomFichierConf(FILENAME_PROGRAMS));
+ TiXmlDeclaration * pXmlDecl(new TiXmlDeclaration("1.0", "UTF-8", "yes"));
+
+ if (pXmlDecl) {
+ xmlDoc.LinkEndChild(pXmlDecl);
+
+ TiXmlElement * pXmlPrLst(Programmes.GetAsXMLElement());
+ if (pXmlPrLst) {
+ xmlDoc.LinkEndChild(pXmlPrLst);
+ xmlDoc.SaveFile();
+ }
+ }
+#else
int nbProgrammes = (int)Programmes.size();
CXMLOutput oxml(NomFichierConf<>(TEXT(FILENAME_PROGRAMS)));
@@ -1812,13 +1830,14 @@
}
programmation_modifiee = false;
+#endif // #if USE_TINYXML
}
// ====================================================================================
// Liste des chaînes définies
// ====================================================================================
-#if STREAMS_SAVE_ALL
+#if ! USE_TINYXML && STREAMS_SAVE_ALL
/**
* Lecture de la liste de pistes d'un type donné.
* \param[in] cNode Noeud XML
@@ -1852,7 +1871,7 @@
sPistes.ajoute(sPiste);
}
}
-#endif // #if STREAMS_SAVE_ALL
+#endif // #if ! USE_TINYXML && STREAMS_SAVE_ALL
/**
* Chargement du fichier des chaînes "chaines.xml".
@@ -1862,6 +1881,15 @@
**/
HRESULT lit_chaines()
{
+#if USE_TINYXML
+ TiXmlDocument cTiXmlDoc;
+
+ if (cTiXmlDoc.LoadFile(NomFichierConf(FILENAME_CHANNELS), TIXML_ENCODING_UTF8)) {
+ if (Canaux.SetFromXMLElement(cTiXmlDoc.RootElement()))
+ return S_OK;
+ }
+ return E_FAIL;
+#else // #if USE_TINYXML
// Fichier XML
CXMLWrapper xml;
@@ -1936,9 +1964,10 @@
}
return S_OK;
+#endif // #if USE_TINYXML
}
-#if STREAMS_SAVE_ALL
+#if ! USE_TINYXML && STREAMS_SAVE_ALL
/**
* Sauvegarde de la liste de pistes d'un type donné.
* \param[in] oxml Noeud XML
@@ -1962,13 +1991,28 @@
oxml.put(oxml.fmt("%s%i_Lang", pszTagStr, j), sPiste.lang);
}
}
-#endif // #if STREAMS_SAVE_ALL
+#endif // #if ! USE_TINYXML && STREAMS_SAVE_ALL
/**
* Sauvegarde de la liste des chaînes dans "chaines.xml".
**/
void sauve_chaines()
{
+#if USE_TINYXML
+ TiXmlDocument xmlDoc(NomFichierConf(FILENAME_CHANNELS));
+ TiXmlDeclaration * pXmlDecl(new TiXmlDeclaration("1.0", "UTF-8", "yes"));
+
+ if (pXmlDecl) {
+ xmlDoc.LinkEndChild(pXmlDecl);
+
+ TiXmlElement * pXmlChLst(Canaux.GetAsXMLElement());
+ if (pXmlChLst) {
+ xmlDoc.LinkEndChild(pXmlChLst);
+
+ xmlDoc.SaveFile();
+ }
+ }
+#else
// Nombre de chaines
int nbChaines = (int)Canaux.size();
@@ -2015,6 +2059,7 @@
sauve_pistes(oxml, canal, true);
#endif // #if STREAMS_SAVE_ALL
}
+#endif // #if USE_TINYXML
}
// ====================================================================================
Modifié: trunk/main.cpp
===================================================================
--- trunk/main.cpp 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/main.cpp 2010-01-09 20:32:02 UTC (rev 228)
@@ -40,7 +40,6 @@
#include "Hyperlinks.h"
-#include "xml.h"
#include "internet.h"
#include "update.h"
#include "version.h"
Modifié: trunk/recprog.cpp
===================================================================
--- trunk/recprog.cpp 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/recprog.cpp 2010-01-09 20:32:02 UTC (rev 228)
@@ -62,7 +62,7 @@
/**
* Liste des enregistrements programmés
**/
-std::vector Programmes;
+ProgramList Programmes;
static HWND hRecordDlg = NULL;
static WCHAR mdp[256] = L"";
@@ -179,6 +179,238 @@
}
+#if USE_TINYXML
+
+/**
+ * Extraire la date et l'heure d'un noeud XML
+ * \param[in] pXmlElm Élément (parent) des tags recherchés
+ * \param[in] pszTagList List de tags à utiliser
+ * \return Date et heure retournés
+ **/
+SYSTEMTIME Programme::XmlToTime(const TiXmlElement * pXmlElm, LPCSTR pszTagList)
+{
+ SYSTEMTIME sTime = {0};
+
+ for (ITERATE_XML_ELEMENTS(pXmlElm, pXmlChild)) {
+ LPCSTR pszTag = pXmlChild->Value();
+ LPCSTR pszTxt = pXmlChild->GetText();
+
+ if (pszTxt == NULL)
+ pszTxt = "0";
+
+ // Conversion en numérique pour les champs qui le requièrent.
+ TagListTime eTag = (TagListTime)StringToEnum(pszTagList, pszTag);
+
+ if (eTag >= tlt_Annee && eTag <= tlt_Seconde)
+ reinterpret_cast(&sTime)[eTag] = (WORD)atol(pszTxt);
+ }
+ return sTime;
+}
+
+/**
+ * Générer le noeud XML correspondant à une structure date et heure
+ * \param[in] sTime Date et heure à inclure
+ * \param[in] pszTag Tag du noeud parent
+ * \return Noeud XML généré
+ **/
+TiXmlElement * Programme::TimeToXml(SYSTEMTIME sTime, LPCSTR pszTag)
+{
+ TiXmlElement * pXmlTime(new TiXmlElement(pszTag));
+
+ if (pXmlTime) {
+ for (int eTag = tlt_Annee; eTag <= tlt_Seconde; ++eTag) {
+ LPCSTR pszTag = EnumToString(eTag, pszTimeTagStrList);
+ CHAR szTmp[16];
+
+ _itoa_s(reinterpret_cast(&sTime)[eTag], szTmp, 10);
+ SetXmlContent(pXmlTime, pszTag, szTmp);
+ }
+ }
+ return pXmlTime;
+}
+
+/**
+ * Extraire les informations de répétitions d'un noeud XML
+ * \param[in] pXmlElm Élément (parent) des tags recherchés
+ **/
+BYTE Programme::XmlToRepeat(const TiXmlElement * pXmlElm)
+{
+ BYTE nResult = 0;
+
+ for (ITERATE_XML_ELEMENTS(pXmlElm, pXmlChild)) {
+ LPCSTR pszTag = pXmlChild->Value();
+ LPCSTR pszTxt = pXmlChild->GetText();
+
+ if (pszTxt == NULL)
+ pszTxt = "0";
+
+ int nDoW = StringToEnum(pszDoW, pszTag);
+
+ if (nDoW>= 0 && atol(pszTxt))
+ nResult |= 1<Value();
+ LPCSTR pszTxt = pXmlChild->GetText();
+
+ if (pszTxt == NULL)
+ pszTxt = "0";
+
+ // Conversion en numérique pour les champs qui le requièrent.
+ UINT32 nVal = strtoul(pszTxt, NULL, 0); // Gère les valeurs en 0xNN
+
+ switch (StringToEnum(pszTagStrList, pszTag)) {
+ case tlp_Nom: strcpy_T(nom, ConvertUTF82Char(pszTxt).c_str()); break;
+ case tlp_NomAuto: nomAuto = nVal !=0; break;
+ case tlp_Chaine: nNumeroChaine = (WORD)nVal; break;
+ case tlp_ServiceID: sidChaine = (WORD)nVal; break;
+ case tlp_Cle: cleChaine = nVal; break;
+ case tlp_Debut: debut = XmlToTime(pXmlChild, pszTimeTagStrList); break;
+ case tlp_Fin: fin = XmlToTime(pXmlChild, pszTimeTagStrList); break;
+ case tlp_Methode: methode = (MethodeEnregistrement)nVal; break;
+ case tlp_Audio: audio = (AudioMode)nVal; break;
+ case tlp_After: apres = (ApresEnregistrement)nVal; break;
+ case tlp_Tache: tache = (PlanificateurTache)nVal; break;
+ case tlp_Etat: etat = (EtatProgramme)nVal; break;
+ case tlp_Repetitions: repetition = XmlToRepeat(pXmlChild); break;
+ // compatibilité anciennes versions :
+ case tlp_S_Annee: debut = XmlToTime(pXmlElm, pszOldSTimeTagStrList); break;
+ case tlp_E_Annee: fin = XmlToTime(pXmlElm, pszOldETimeTagStrList);
+ }
+ }
+
+ // Ajustement de compatibilité permettant de récupérer correctement les programmations
+ // faites avec les anciennes versions qui ne sauvegardaient pas le SID.
+ if (sidChaine==0)
+ sidChaine = indexToSID(Canaux.trouve_par_no(nNumeroChaine));
+
+ // Ajustement de compatibilité permettant de récupérer correctement les programmations
+ // faites avec les anciennes versions qui ne sauvegardaient pas la clé.
+ if (cleChaine==0)
+ cleChaine = indexToCle(Canaux.trouve_par_sid(sidChaine));
+
+ return true;
+}
+
+/**
+ * Construction d'un noeud TinyXML représentant la définition de la programmation
+ * \return Noeud XML construit
+ **/
+TiXmlElement * Programme::GetAsXMLElement() const
+{
+ TiXmlElement * pXmlProg(new TiXmlElement("Programme"));
+
+ if (pXmlProg) {
+ for (int eTag = tlp_Nom; eTag <= tlp_Repetitions; ++eTag) {
+ CHAR szTmp[_countof(nom)] = "0";
+ LPCSTR pszTag = EnumToString(eTag, pszTagStrList);
+ TiXmlElement * pXmlElm = NULL;
+
+ switch (eTag) {
+ case tlp_Nom: strcpy_T(szTmp, ConvertChar2UTF8(nom).c_str()); break;
+ case tlp_NomAuto: _itoa_s(nomAuto, szTmp, 10); break;
+ case tlp_Chaine: _itoa_s(nNumeroChaine, szTmp, 10); break;
+ case tlp_ServiceID: _itoa_s(sidChaine, szTmp, 10); break;
+ case tlp_Cle: sprintf_s(szTmp, "0x%08X", cleChaine); break;
+ case tlp_Debut: pXmlElm = TimeToXml(debut, pszTag); break;
+ case tlp_Fin: pXmlElm = TimeToXml(fin, pszTag); break;
+ case tlp_Methode: _itoa_s(methode, szTmp, 10); break;
+ case tlp_Audio: _itoa_s(audio, szTmp, 10); break;
+ case tlp_After: _itoa_s(apres, szTmp, 10); break;
+ case tlp_Tache: _itoa_s(tache, szTmp, 10); break;
+ case tlp_Etat: _itoa_s(etat, szTmp, 10); break;
+ case tlp_Repetitions: pXmlElm = RepeatToXml(repetition, pszTag);
+ }
+
+ if (pXmlElm)
+ pXmlProg->LinkEndChild(pXmlElm);
+ else
+ SetXmlContent(pXmlProg, pszTag, szTmp);
+ }
+ }
+ return pXmlProg;
+}
+
+#endif // #if USE_TINYXML
+
/// Retourne \p true si intersection temporelle avec la programmation \p p2
bool Programme::overlap(const Programme & p2) const
{
@@ -557,7 +789,54 @@
return true;
}
+#if USE_TINYXML
+
/**
+ * Chargement de la liste des programmations à partir d'un noeud TinyXML construit
+ * \param[in] pXmlElm Noeud XML contenant les données à charger
+ * \return \p true ou \p false selon succès ou échec
+ **/
+bool ProgramList::SetFromXMLElement(const TiXmlElement * pXmlElm)
+{
+ if (_stricmp(pXmlElm->Value(), "Programmes")!=0)
+ return false;
+ for (ITERATE_XML_ELEMENTS_NAMED(pXmlElm, pXmlChild, "Programme")) {
+ Programme prog;
+
+ if (prog.SetFromXMLElement(pXmlChild))
+ push_back(prog);
+ }
+
+ // Tri de la liste des programmations (en cas de chargement
+ // d'ancienne version, ou bien de modification extérieure) :
+ std::sort(begin(), end());
+ programmation_modifiee = false;
+ return true;
+}
+
+/**
+ * Construction d'un noeud TinyXML représentant la définition de la liste des programmations
+ * \return Noeud XML construit
+ **/
+TiXmlElement * ProgramList::GetAsXMLElement() const
+{
+ TiXmlElement * pXmlPrLst(new TiXmlElement("Programmes"));
+
+ if (pXmlPrLst) {
+ for (ITERATE_CONST_VECTOR(*this, Programme, it)) {
+ TiXmlElement * pXmlProg(it->GetAsXMLElement());
+
+ if (pXmlProg)
+ pXmlPrLst->LinkEndChild(pXmlProg);
+ }
+ }
+
+ return pXmlPrLst;
+}
+
+#endif // #if USE_TINYXML
+
+/**
* Traitement du chargement de la liste des programmes au démarrage, et purge
* des enregistrements périmés
**/
Modifié: trunk/recprog.h
===================================================================
--- trunk/recprog.h 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/recprog.h 2010-01-09 20:32:02 UTC (rev 228)
@@ -101,7 +101,89 @@
/// Constructeur
Programme();
+#if USE_TINYXML
+
+ /// Énumération corresopondant aux tags XML utilisés pour la sauvegarde d'une programmation
+ enum TagListProg {
+ tlp_Nom,
+ tlp_NomAuto,
+ tlp_Chaine,
+ tlp_ServiceID,
+ tlp_Cle,
+ tlp_Debut,
+ tlp_Fin,
+ tlp_Methode,
+ tlp_Audio,
+ tlp_After,
+ tlp_Tache,
+ tlp_Etat,
+ tlp_Repetitions,
+ tlp_S_Annee, // compatibilité anciennes versions
+ tlp_E_Annee // compatibilité anciennes versions
+ };
+
+ /// Énumération corresopondant aux tags XML utilisés pour la sauvegarde de l'heure et de la date
+ enum TagListTime {
+ tlt_Annee,
+ tlt_Mois,
+ tlt_Jour_Semaine,
+ tlt_Jour,
+ tlt_Heure,
+ tlt_Minute,
+ tlt_Seconde
+ };
+
+ /// Noms des tags XML utilisés pour la sauvegarde d'une programmation
+ static LPCSTR pszTagStrList;
+
+ /// Noms des tags XML utilisés pour la sauvegarde de l'heure et de la date
+ static LPCSTR pszTimeTagStrList;
+
/**
+ * Extraire la date et l'heure d'un noeud XML
+ * \param[in] pXmlElm Élément (parent) des tags recherchés
+ * \param[in] pszTagList List de tags à utiliser
+ * \return Date et heure retournés
+ **/
+ static SYSTEMTIME XmlToTime(const TiXmlElement * pXmlElm, LPCSTR pszTagList);
+
+ /**
+ * Générer le noeud XML correspondant à une structure date et heure
+ * \param[in] sTime Date et heure à inclure
+ * \param[in] pszTag Tag du noeud parent
+ * \return Noeud XML généré
+ **/
+ static TiXmlElement * TimeToXml(SYSTEMTIME sTime, LPCSTR pszTag);
+
+ /**
+ * Générer le noeud XML correspondant à variable de répétition hebdomadaire
+ * \param[in] nRep Flags contenant les jours de répétition
+ * \param[in] pszTag Tag du noeud parent
+ * \return Noeud XML généré
+ **/
+ static TiXmlElement * RepeatToXml(BYTE nRep, LPCSTR pszTag);
+
+ /**
+ * Extraire les informations de répétitions d'un noeud XML
+ * \param[in] pXmlElm Élément (parent) des tags recherchés
+ **/
+ static BYTE XmlToRepeat(const TiXmlElement * pXmlElm);
+
+ /**
+ * Chargement d'une programmation à partir d'un noeud TinyXML construit
+ * \param[in] pXmlElm Noeud XML contenant les données à charger
+ * \return \p true ou \p false selon succès ou échec
+ **/
+ bool SetFromXMLElement(const TiXmlElement * pXmlElm);
+
+ /**
+ * Construction d'un noeud TinyXML représentant la définition de la programmation
+ * \return Noeud XML construit
+ **/
+ TiXmlElement * GetAsXMLElement() const;
+#endif
+
+ /**
* \brief Vérification de la validité de la programmation
*
* \param[in] prog_modif Si non NULL, pointeur sur la programmation qu'on modifie (pour
@@ -222,9 +304,31 @@
};
/**
+ * Classe regroupant la liste des enregistrements programmés
+ **/
+class ProgramList : public std::vector
+{
+public:
+#if USE_TINYXML
+ /**
+ * Chargement de la liste des programmations à partir d'un noeud TinyXML construit
+ * \param[in] pXmlElm Noeud XML contenant les données à charger
+ * \return \p true ou \p false selon succès ou échec
+ **/
+ bool SetFromXMLElement(const TiXmlElement * pXmlElm);
+
+ /**
+ * Construction d'un noeud TinyXML représentant la définition de la liste des programmations
+ * \return Noeud XML construit
+ **/
+ TiXmlElement * GetAsXMLElement() const;
+#endif
+};
+
+/**
* Liste des enregistrements programmés
**/
-extern std::vector Programmes;
+extern ProgramList Programmes;
/**
* Traitement du chargement de la liste des programmes au démarrage, et purge
Ajouté: trunk/tinyxml/readme.html
===================================================================
--- trunk/tinyxml/readme.html (rev 0)
+++ trunk/tinyxml/readme.html 2010-01-09 20:32:02 UTC (rev 228)
@@ -0,0 +1,530 @@
+/** @mainpage
+
+ TinyXML
+
+TinyXML is a simple, small, C++ XML parser that can be easily
+integrated into other programs.
+
+ What it does.
+
+In brief, TinyXML parses an XML document, and builds from that a
+Document Object Model (DOM) that can be read, modified, and saved.
+
+XML stands for "eXtensible Markup Language." It allows you to create
+your own document markups. Where HTML does a very good job of marking
+documents for browsers, XML allows you to define any kind of document
+markup, for example a document that describes a "to do" list for an
+organizer application. XML is a very structured and convenient format.
+All those random file formats created to store application data can
+all be replaced with XML. One parser for everything.
+
+The best place for the complete, correct, and quite frankly hard to
+read spec is at
+http://www.w3.org/TR/2004/REC-xml-20040204/ . An intro to XML
+(that I really like) can be found at
+http://skew.org/xml/tutorial .
+
+There are different ways to access and interact with XML data.
+TinyXML uses a Document Object Model (DOM), meaning the XML data is parsed
+into a C++ objects that can be browsed and manipulated, and then
+written to disk or another output stream. You can also construct an XML document
+from scratch with C++ objects and write this to disk or another output
+stream.
+
+TinyXML is designed to be easy and fast to learn. It is two headers
+and four cpp files. Simply add these to your project and off you go.
+There is an example file - xmltest.cpp - to get you started.
+
+TinyXML is released under the ZLib license,
+so you can use it in open source or commercial code. The details
+of the license are at the top of every source file.
+
+TinyXML attempts to be a flexible parser, but with truly correct and
+compliant XML output. TinyXML should compile on any reasonably C++
+compliant system. It does not rely on exceptions or RTTI. It can be
+compiled with or without STL support. TinyXML fully supports
+the UTF-8 encoding, and the first 64k character entities.
+
+
+ What it doesn't do.
+
+TinyXML doesn't parse or use DTDs (Document Type Definitions) or XSLs
+(eXtensible Stylesheet Language.) There are other parsers out there
+(check out www.sourceforge.org, search for XML) that are much more fully
+featured. But they are also much bigger, take longer to set up in
+your project, have a higher learning curve, and often have a more
+restrictive license. If you are working with browsers or have more
+complete XML needs, TinyXML is not the parser for you.
+
+The following DTD syntax will not parse at this time in TinyXML:
+
+ at verbatim
+
+ ]>
+ at endverbatim
+
+because TinyXML sees this as a !DOCTYPE node with an illegally
+embedded !ELEMENT node. This may be addressed in the future.
+
+ Tutorials.
+
+For the impatient, here is a tutorial to get you going. A great way to get started,
+but it is worth your time to read this (very short) manual completely.
+
+- @subpage tutorial0
+
+ Code Status.
+
+TinyXML is mature, tested code. It is very stable. If you find
+bugs, please file a bug report on the sourceforge web site
+(www.sourceforge.net/projects/tinyxml). We'll get them straightened
+out as soon as possible.
+
+There are some areas of improvement; please check sourceforge if you are
+interested in working on TinyXML.
+
+ Related Projects
+
+TinyXML projects you may find useful! (Descriptions provided by the projects.)
+
+
+ TinyXPath (http://tinyxpath.sourceforge.net). TinyXPath is a small footprint
+ XPath syntax decoder, written in C++.
+ TinyXML++ (http://code.google.com/p/ticpp/). TinyXML++ is a completely new
+ interface to TinyXML that uses MANY of the C++ strengths. Templates,
+ exceptions, and much better error handling.
+
+
+ Features
+
+ Using STL
+
+TinyXML can be compiled to use or not use STL. When using STL, TinyXML
+uses the std::string class, and fully supports std::istream, std::ostream,
+operator<<, and operator>>. Many API methods have both 'const char*' and
+'const std::string&' forms.
+
+When STL support is compiled out, no STL files are included whatsoever. All
+the string classes are implemented by TinyXML itself. API methods
+all use the 'const char*' form for input.
+
+Use the compile time #define:
+
+ TIXML_USE_STL
+
+to compile one version or the other. This can be passed by the compiler,
+or set as the first line of "tinyxml.h".
+
+Note: If compiling the test code in Linux, setting the environment
+variable TINYXML_USE_STL=YES/NO will control STL compilation. In the
+Windows project file, STL and non STL targets are provided. In your project,
+It's probably easiest to add the line "#define TIXML_USE_STL" as the first
+line of tinyxml.h.
+
+ UTF-8
+
+TinyXML supports UTF-8 allowing to manipulate XML files in any language. TinyXML
+also supports "legacy mode" - the encoding used before UTF-8 support and
+probably best described as "extended ascii".
+
+Normally, TinyXML will try to detect the correct encoding and use it. However,
+by setting the value of TIXML_DEFAULT_ENCODING in the header file, TinyXML
+can be forced to always use one encoding.
+
+TinyXML will assume Legacy Mode until one of the following occurs:
+
+ If the non-standard but common "UTF-8 lead bytes" (0xef 0xbb 0xbf)
+ begin the file or data stream, TinyXML will read it as UTF-8.
+ If the declaration tag is read, and it has an encoding="UTF-8", then
+ TinyXML will read it as UTF-8.
+ If the declaration tag is read, and it has no encoding specified, then TinyXML will
+ read it as UTF-8.
+ If the declaration tag is read, and it has an encoding="something else", then TinyXML
+ will read it as Legacy Mode. In legacy mode, TinyXML will work as it did before. It's
+ not clear what that mode does exactly, but old content should keep working.
+ Until one of the above criteria is met, TinyXML runs in Legacy Mode.
+
+
+What happens if the encoding is incorrectly set or detected? TinyXML will try
+to read and pass through text seen as improperly encoded. You may get some strange results or
+mangled characters. You may want to force TinyXML to the correct mode.
+
+You may force TinyXML to Legacy Mode by using LoadFile( TIXML_ENCODING_LEGACY ) or
+LoadFile( filename, TIXML_ENCODING_LEGACY ). You may force it to use legacy mode all
+the time by setting TIXML_DEFAULT_ENCODING = TIXML_ENCODING_LEGACY. Likewise, you may
+force it to TIXML_ENCODING_UTF8 with the same technique.
+
+For English users, using English XML, UTF-8 is the same as low-ASCII. You
+don't need to be aware of UTF-8 or change your code in any way. You can think
+of UTF-8 as a "superset" of ASCII.
+
+UTF-8 is not a double byte format - but it is a standard encoding of Unicode!
+TinyXML does not use or directly support wchar, TCHAR, or Microsoft's _UNICODE at this time.
+It is common to see the term "Unicode" improperly refer to UTF-16, a wide byte encoding
+of unicode. This is a source of confusion.
+
+For "high-ascii" languages - everything not English, pretty much - TinyXML can
+handle all languages, at the same time, as long as the XML is encoded
+in UTF-8. That can be a little tricky, older programs and operating systems
+tend to use the "default" or "traditional" code page. Many apps (and almost all
+modern ones) can output UTF-8, but older or stubborn (or just broken) ones
+still output text in the default code page.
+
+For example, Japanese systems traditionally use SHIFT-JIS encoding.
+Text encoded as SHIFT-JIS can not be read by TinyXML.
+A good text editor can import SHIFT-JIS and then save as UTF-8.
+
+The Skew.org link does a great
+job covering the encoding issue.
+
+The test file "utf8test.xml" is an XML containing English, Spanish, Russian,
+and Simplified Chinese. (Hopefully they are translated correctly). The file
+"utf8test.gif" is a screen capture of the XML file, rendered in IE. Note that
+if you don't have the correct fonts (Simplified Chinese or Russian) on your
+system, you won't see output that matches the GIF file even if you can parse
+it correctly. Also note that (at least on my Windows machine) console output
+is in a Western code page, so that Print() or printf() cannot correctly display
+the file. This is not a bug in TinyXML - just an OS issue. No data is lost or
+destroyed by TinyXML. The console just doesn't render UTF-8.
+
+
+ Entities
+TinyXML recognizes the pre-defined "character entities", meaning special
+characters. Namely:
+
+ at verbatim
+ & &
+ < <
+ > >
+ " "
+ ' '
+ at endverbatim
+
+These are recognized when the XML document is read, and translated to there
+UTF-8 equivalents. For instance, text with the XML of:
+
+ at verbatim
+ Far & Away
+ at endverbatim
+
+will have the Value() of "Far & Away" when queried from the TiXmlText object,
+and will be written back to the XML stream/file as an ampersand. Older versions
+of TinyXML "preserved" character entities, but the newer versions will translate
+them into characters.
+
+Additionally, any character can be specified by its Unicode code point:
+The syntax " " or " " are both to the non-breaking space characher.
+
+ Printing
+TinyXML can print output in several different ways that all have strengths and limitations.
+
+- Print( FILE* ). Output to a std-C stream, which includes all C files as well as stdout.
+ - "Pretty prints", but you don't have control over printing options.
+ - The output is streamed directly to the FILE object, so there is no memory overhead
+ in the TinyXML code.
+ - used by Print() and SaveFile()
+
+- operator<<. Output to a c++ stream.
+ - Integrates with standart C++ iostreams.
+ - Outputs in "network printing" mode without line breaks. Good for network transmission
+ and moving XML between C++ objects, but hard for a human to read.
+
+- TiXmlPrinter. Output to a std::string or memory buffer.
+ - API is less concise
+ - Future printing options will be put here.
+ - Printing may change slightly in future versions as it is refined and expanded.
+
+ Streams
+With TIXML_USE_STL on TinyXML supports C++ streams (operator <<,>>) streams as well
+as C (FILE*) streams. There are some differences that you may need to be aware of.
+
+C style output:
+ - based on FILE*
+ - the Print() and SaveFile() methods
+
+ Generates formatted output, with plenty of white space, intended to be as
+ human-readable as possible. They are very fast, and tolerant of ill formed
+ XML documents. For example, an XML document that contains 2 root elements
+ and 2 declarations, will still print.
+
+C style input:
+ - based on FILE*
+ - the Parse() and LoadFile() methods
+
+ A fast, tolerant read. Use whenever you don't need the C++ streams.
+
+C++ style output:
+ - based on std::ostream
+ - operator<<
+
+ Generates condensed output, intended for network transmission rather than
+ readability. Depending on your system's implementation of the ostream class,
+ these may be somewhat slower. (Or may not.) Not tolerant of ill formed XML:
+ a document should contain the correct one root element. Additional root level
+ elements will not be streamed out.
+
+C++ style input:
+ - based on std::istream
+ - operator>>
+
+ Reads XML from a stream, making it useful for network transmission. The tricky
+ part is knowing when the XML document is complete, since there will almost
+ certainly be other data in the stream. TinyXML will assume the XML data is
+ complete after it reads the root element. Put another way, documents that
+ are ill-constructed with more than one root element will not read correctly.
+ Also note that operator>> is somewhat slower than Parse, due to both
+ implementation of the STL and limitations of TinyXML.
+
+ White space
+The world simply does not agree on whether white space should be kept, or condensed.
+For example, pretend the '_' is a space, and look at "Hello____world". HTML, and
+at least some XML parsers, will interpret this as "Hello_world". They condense white
+space. Some XML parsers do not, and will leave it as "Hello____world". (Remember
+to keep pretending the _ is a space.) Others suggest that __Hello___world__ should become
+Hello___world.
+
+It's an issue that hasn't been resolved to my satisfaction. TinyXML supports the
+first 2 approaches. Call TiXmlBase::SetCondenseWhiteSpace( bool ) to set the desired behavior.
+The default is to condense white space.
+
+If you change the default, you should call TiXmlBase::SetCondenseWhiteSpace( bool )
+before making any calls to Parse XML data, and I don't recommend changing it after
+it has been set.
+
+
+ Handles
+
+Where browsing an XML document in a robust way, it is important to check
+for null returns from method calls. An error safe implementation can
+generate a lot of code like:
+
+ at verbatim
+TiXmlElement* root = document.FirstChildElement( "Document" );
+if ( root )
+{
+ TiXmlElement* element = root->FirstChildElement( "Element" );
+ if ( element )
+ {
+ TiXmlElement* child = element->FirstChildElement( "Child" );
+ if ( child )
+ {
+ TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+ if ( child2 )
+ {
+ // Finally do something useful.
+ at endverbatim
+
+Handles have been introduced to clean this up. Using the TiXmlHandle class,
+the previous code reduces to:
+
+ at verbatim
+TiXmlHandle docHandle( &document );
+TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).ToElement();
+if ( child2 )
+{
+ // do something useful
+ at endverbatim
+
+Which is much easier to deal with. See TiXmlHandle for more information.
+
+
+ Row and Column tracking
+Being able to track nodes and attributes back to their origin location
+in source files can be very important for some applications. Additionally,
+knowing where parsing errors occured in the original source can be very
+time saving.
+
+TinyXML can tracks the row and column origin of all nodes and attributes
+in a text file. The TiXmlBase::Row() and TiXmlBase::Column() methods return
+the origin of the node in the source text. The correct tabs can be
+configured in TiXmlDocument::SetTabSize().
+
+
+ Using and Installing
+
+To Compile and Run xmltest:
+
+A Linux Makefile and a Windows Visual C++ .dsw file is provided.
+Simply compile and run. It will write the file demotest.xml to your
+disk and generate output on the screen. It also tests walking the
+DOM by printing out the number of nodes found using different
+techniques.
+
+The Linux makefile is very generic and runs on many systems - it
+is currently tested on mingw and
+MacOSX. You do not need to run 'make depend'. The dependecies have been
+hard coded.
+
+Windows project file for VC6
+
+tinyxml: tinyxml library, non-STL
+tinyxmlSTL: tinyxml library, STL
+tinyXmlTest: test app, non-STL
+tinyXmlTestSTL: test app, STL
+
+
+Makefile
+At the top of the makefile you can set:
+
+PROFILE, DEBUG, and TINYXML_USE_STL. Details (such that they are) are in
+the makefile.
+
+In the tinyxml directory, type "make clean" then "make". The executable
+file 'xmltest' will be created.
+
+
+
+To Use in an Application:
+
+Add tinyxml.cpp, tinyxml.h, tinyxmlerror.cpp, tinyxmlparser.cpp, tinystr.cpp, and tinystr.h to your
+project or make file. That's it! It should compile on any reasonably
+compliant C++ system. You do not need to enable exceptions or
+RTTI for TinyXML.
+
+
+ How TinyXML works.
+
+An example is probably the best way to go. Take:
+ at verbatim
+
+
+
+ - Go to the
Toy store!
+ - Do bills
+
+ at endverbatim
+
+Its not much of a To Do list, but it will do. To read this file
+(say "demo.xml") you would create a document, and parse it in:
+ at verbatim
+ TiXmlDocument doc( "demo.xml" );
+ doc.LoadFile();
+ at endverbatim
+
+And its ready to go. Now lets look at some lines and how they
+relate to the DOM.
+
+ at verbatim
+
+ at endverbatim
+
+ The first line is a declaration, and gets turned into the
+ TiXmlDeclaration class. It will be the first child of the
+ document node.
+
+ This is the only directive/special tag parsed by by TinyXML.
+ Generally directive tags are stored in TiXmlUnknown so the
+ commands wont be lost when it is saved back to disk.
+
+ at verbatim
+
+ at endverbatim
+
+ A comment. Will become a TiXmlComment object.
+
+ at verbatim
+
+ at endverbatim
+
+ The "ToDo" tag defines a TiXmlElement object. This one does not have
+ any attributes, but does contain 2 other elements.
+
+ at verbatim
+-
+ at endverbatim
+
+ Creates another TiXmlElement which is a child of the "ToDo" element.
+ This element has 1 attribute, with the name "priority" and the value
+ "1".
+
+ at verbatim
+Go to the
+ at endverbatim
+
+ A TiXmlText. This is a leaf node and cannot contain other nodes.
+ It is a child of the "Item" TiXmlElement.
+
+ at verbatim
+
+ at endverbatim
+
+
+ Another TiXmlElement, this one a child of the "Item" element.
+
+Etc.
+
+Looking at the entire object tree, you end up with:
+ at verbatim
+TiXmlDocument "demo.xml"
+ TiXmlDeclaration "version='1.0'" "standalone=no"
+ TiXmlComment " Our to do list data"
+ TiXmlElement "ToDo"
+ TiXmlElement "Item" Attribtutes: priority = 1
+ TiXmlText "Go to the "
+ TiXmlElement "bold"
+ TiXmlText "Toy store!"
+ TiXmlElement "Item" Attributes: priority=2
+ TiXmlText "Do bills"
+ at endverbatim
+
+ Documentation
+
+The documentation is build with Doxygen, using the 'dox'
+configuration file.
+
+ License
+
+TinyXML is released under the zlib license:
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+
+ References
+
+The World Wide Web Consortium is the definitive standard body for
+XML, and there web pages contain huge amounts of information.
+
+The definitive spec:
+http://www.w3.org/TR/2004/REC-xml-20040204/
+
+I also recommend "XML Pocket Reference" by Robert Eckstein and published by
+OReilly...the book that got the whole thing started.
+
+ Contributors, Contacts, and a Brief History
+
+Thanks very much to everyone who sends suggestions, bugs, ideas, and
+encouragement. It all helps, and makes this project fun. A special thanks
+to the contributors on the web pages that keep it lively.
+
+So many people have sent in bugs and ideas, that rather than list here
+we try to give credit due in the "changes.txt" file.
+
+TinyXML was originally written by Lee Thomason. (Often the "I" still
+in the documentation.) Lee reviews changes and releases new versions,
+with the help of Yves Berquin, Andrew Ellerton, and the tinyXml community.
+
+We appreciate your suggestions, and would love to know if you
+use TinyXML. Hopefully you will enjoy it and find it useful.
+Please post questions, comments, file bugs, or contact us at:
+
+www.sourceforge.net/projects/tinyxml
+
+Lee Thomason, Yves Berquin, Andrew Ellerton
+*/
Supprimé: trunk/tinyxml/tinyXmlTestSTL_2005.vcproj
===================================================================
--- trunk/tinyxml/tinyXmlTestSTL_2005.vcproj 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyXmlTestSTL_2005.vcproj 2010-01-09 20:32:02 UTC (rev 228)
@@ -1,225 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Supprimé: trunk/tinyxml/tinyXmlTestSTL_2008.vcproj
===================================================================
--- trunk/tinyxml/tinyXmlTestSTL_2008.vcproj 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyXmlTestSTL_2008.vcproj 2010-01-09 20:32:02 UTC (rev 228)
@@ -1,224 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Modifié: trunk/tinyxml/tinyXmlTest_2005.vcproj
===================================================================
--- trunk/tinyxml/tinyXmlTest_2005.vcproj 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyXmlTest_2005.vcproj 2010-01-09 20:32:02 UTC (rev 228)
@@ -1,226 +1,675 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Modifié: trunk/tinyxml/tinyXmlTest_2008.vcproj
===================================================================
--- trunk/tinyxml/tinyXmlTest_2008.vcproj 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyXmlTest_2008.vcproj 2010-01-09 20:32:02 UTC (rev 228)
@@ -4,22 +4,25 @@
Version="9,00"
Name="tinyXmlTest"
ProjectGUID="{34719950-09E8-457E-BE23-8F1CE3A1F1F6}"
+ RootNamespace="tinyXmlTest"
TargetFrameworkVersion="131072"
>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -161,11 +545,10 @@
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
Supprimé: trunk/tinyxml/tinyxmlSTL_2005.vcproj
===================================================================
--- trunk/tinyxml/tinyxmlSTL_2005.vcproj 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyxmlSTL_2005.vcproj 2010-01-09 20:32:02 UTC (rev 228)
@@ -1,277 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Supprimé: trunk/tinyxml/tinyxmlSTL_2008.vcproj
===================================================================
--- trunk/tinyxml/tinyxmlSTL_2008.vcproj 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyxmlSTL_2008.vcproj 2010-01-09 20:32:02 UTC (rev 228)
@@ -1,278 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Modifié: trunk/tinyxml/tinyxml_2005.sln
===================================================================
--- trunk/tinyxml/tinyxml_2005.sln 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyxml_2005.sln 2010-01-09 20:32:02 UTC (rev 228)
@@ -1,44 +1,59 @@
-
-Microsoft Visual Studio Solution File, Format Version 9.00
-# Visual C++ Express 2005
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyXmlTest", "tinyXmlTest_2005.vcproj", "{34719950-09E8-457E-BE23-8F1CE3A1F1F6}"
- ProjectSection(ProjectDependencies) = postProject
- {C406DAEC-0886-4771-8DEA-9D7329B46CC1} = {C406DAEC-0886-4771-8DEA-9D7329B46CC1}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyXmlTestSTL", "tinyXmlTestSTL_2005.vcproj", "{53ED5965-5BCA-47B5-9EB0-EDD20882F22F}"
- ProjectSection(ProjectDependencies) = postProject
- {A3A84737-5017-4577-B8A2-79429A25B8B6} = {A3A84737-5017-4577-B8A2-79429A25B8B6}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml", "tinyxml_lib_2005.vcproj", "{C406DAEC-0886-4771-8DEA-9D7329B46CC1}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxmlSTL", "tinyxmlSTL_2005.vcproj", "{A3A84737-5017-4577-B8A2-79429A25B8B6}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|Win32.ActiveCfg = Debug|Win32
- {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|Win32.Build.0 = Debug|Win32
- {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|Win32.ActiveCfg = Release|Win32
- {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|Win32.Build.0 = Release|Win32
- {53ED5965-5BCA-47B5-9EB0-EDD20882F22F}.Debug|Win32.ActiveCfg = Debug|Win32
- {53ED5965-5BCA-47B5-9EB0-EDD20882F22F}.Debug|Win32.Build.0 = Debug|Win32
- {53ED5965-5BCA-47B5-9EB0-EDD20882F22F}.Release|Win32.ActiveCfg = Release|Win32
- {53ED5965-5BCA-47B5-9EB0-EDD20882F22F}.Release|Win32.Build.0 = Release|Win32
- {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.ActiveCfg = Debug|Win32
- {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.Build.0 = Debug|Win32
- {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.ActiveCfg = Release|Win32
- {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.Build.0 = Release|Win32
- {A3A84737-5017-4577-B8A2-79429A25B8B6}.Debug|Win32.ActiveCfg = Debug|Win32
- {A3A84737-5017-4577-B8A2-79429A25B8B6}.Debug|Win32.Build.0 = Debug|Win32
- {A3A84737-5017-4577-B8A2-79429A25B8B6}.Release|Win32.ActiveCfg = Release|Win32
- {A3A84737-5017-4577-B8A2-79429A25B8B6}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyXmlTest", "tinyXmlTest_2005.vcproj", "{34719950-09E8-457E-BE23-8F1CE3A1F1F6}"
+ ProjectSection(ProjectDependencies) = postProject
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1} = {C406DAEC-0886-4771-8DEA-9D7329B46CC1}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml", "tinyxml_lib_2005.vcproj", "{C406DAEC-0886-4771-8DEA-9D7329B46CC1}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_STL|Win32 = Debug_STL|Win32
+ Debug_STL|x64 = Debug_STL|x64
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release_STL|Win32 = Release_STL|Win32
+ Release_STL|x64 = Release_STL|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug_STL|Win32.ActiveCfg = Debug_STL|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug_STL|Win32.Build.0 = Debug_STL|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug_STL|x64.ActiveCfg = Debug_STL|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug_STL|x64.Build.0 = Debug_STL|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|Win32.Build.0 = Debug|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|x64.ActiveCfg = Debug|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|x64.Build.0 = Debug|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release_STL|Win32.ActiveCfg = Release_STL|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release_STL|Win32.Build.0 = Release_STL|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release_STL|x64.ActiveCfg = Release_STL|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release_STL|x64.Build.0 = Release_STL|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|Win32.ActiveCfg = Release|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|Win32.Build.0 = Release|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|x64.ActiveCfg = Release|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|x64.Build.0 = Release|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug_STL|Win32.ActiveCfg = Debug_STL|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug_STL|Win32.Build.0 = Debug_STL|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug_STL|x64.ActiveCfg = Debug_STL|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug_STL|x64.Build.0 = Debug_STL|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.ActiveCfg = Debug|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.Build.0 = Debug|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|x64.ActiveCfg = Debug|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|x64.Build.0 = Debug|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release_STL|Win32.ActiveCfg = Release_STL|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release_STL|Win32.Build.0 = Release_STL|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release_STL|x64.ActiveCfg = Release_STL|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release_STL|x64.Build.0 = Release_STL|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.ActiveCfg = Release|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.Build.0 = Release|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|x64.ActiveCfg = Release|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
Modifié: trunk/tinyxml/tinyxml_2008.sln
===================================================================
--- trunk/tinyxml/tinyxml_2008.sln 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyxml_2008.sln 2010-01-09 20:32:02 UTC (rev 228)
@@ -6,37 +6,52 @@
{C406DAEC-0886-4771-8DEA-9D7329B46CC1} = {C406DAEC-0886-4771-8DEA-9D7329B46CC1}
EndProjectSection
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyXmlTestSTL", "tinyXmlTestSTL_2008.vcproj", "{53ED5965-5BCA-47B5-9EB0-EDD20882F22F}"
- ProjectSection(ProjectDependencies) = postProject
- {A3A84737-5017-4577-B8A2-79429A25B8B6} = {A3A84737-5017-4577-B8A2-79429A25B8B6}
- EndProjectSection
-EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxml", "tinyxml_lib_2008.vcproj", "{C406DAEC-0886-4771-8DEA-9D7329B46CC1}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tinyxmlSTL", "tinyxmlSTL_2008.vcproj", "{A3A84737-5017-4577-B8A2-79429A25B8B6}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug_STL|Win32 = Debug_STL|Win32
+ Debug_STL|x64 = Debug_STL|x64
Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release_STL|Win32 = Release_STL|Win32
+ Release_STL|x64 = Release_STL|x64
Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug_STL|Win32.ActiveCfg = Debug_STL|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug_STL|Win32.Build.0 = Debug_STL|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug_STL|x64.ActiveCfg = Debug_STL|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug_STL|x64.Build.0 = Debug_STL|x64
{34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|Win32.ActiveCfg = Debug|Win32
{34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|Win32.Build.0 = Debug|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|x64.ActiveCfg = Debug|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Debug|x64.Build.0 = Debug|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release_STL|Win32.ActiveCfg = Release_STL|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release_STL|Win32.Build.0 = Release_STL|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release_STL|x64.ActiveCfg = Release_STL|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release_STL|x64.Build.0 = Release_STL|x64
{34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|Win32.ActiveCfg = Release|Win32
{34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|Win32.Build.0 = Release|Win32
- {53ED5965-5BCA-47B5-9EB0-EDD20882F22F}.Debug|Win32.ActiveCfg = Debug|Win32
- {53ED5965-5BCA-47B5-9EB0-EDD20882F22F}.Debug|Win32.Build.0 = Debug|Win32
- {53ED5965-5BCA-47B5-9EB0-EDD20882F22F}.Release|Win32.ActiveCfg = Release|Win32
- {53ED5965-5BCA-47B5-9EB0-EDD20882F22F}.Release|Win32.Build.0 = Release|Win32
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|x64.ActiveCfg = Release|x64
+ {34719950-09E8-457E-BE23-8F1CE3A1F1F6}.Release|x64.Build.0 = Release|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug_STL|Win32.ActiveCfg = Debug_STL|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug_STL|Win32.Build.0 = Debug_STL|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug_STL|x64.ActiveCfg = Debug_STL|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug_STL|x64.Build.0 = Debug_STL|x64
{C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.ActiveCfg = Debug|Win32
{C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|Win32.Build.0 = Debug|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|x64.ActiveCfg = Debug|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Debug|x64.Build.0 = Debug|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release_STL|Win32.ActiveCfg = Release_STL|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release_STL|Win32.Build.0 = Release_STL|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release_STL|x64.ActiveCfg = Release_STL|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release_STL|x64.Build.0 = Release_STL|x64
{C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.ActiveCfg = Release|Win32
{C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|Win32.Build.0 = Release|Win32
- {A3A84737-5017-4577-B8A2-79429A25B8B6}.Debug|Win32.ActiveCfg = Debug|Win32
- {A3A84737-5017-4577-B8A2-79429A25B8B6}.Debug|Win32.Build.0 = Debug|Win32
- {A3A84737-5017-4577-B8A2-79429A25B8B6}.Release|Win32.ActiveCfg = Release|Win32
- {A3A84737-5017-4577-B8A2-79429A25B8B6}.Release|Win32.Build.0 = Release|Win32
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|x64.ActiveCfg = Release|x64
+ {C406DAEC-0886-4771-8DEA-9D7329B46CC1}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Modifié: trunk/tinyxml/tinyxml_lib_2005.vcproj
===================================================================
--- trunk/tinyxml/tinyxml_lib_2005.vcproj 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/tinyxml/tinyxml_lib_2005.vcproj 2010-01-09 20:32:02 UTC (rev 228)
@@ -289,6 +289,278 @@
Name="VCPostBuildEventTool"
/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -304,41 +576,14 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -305,41 +577,14 @@
-
-
-
-
-
-
-
-
-
FirstChild(); \
- child != NULL; \
- child = child->NextSibling()
-
-/// Macro d'assistance à l'énumération d'éléments enfants d'un nœud TiXML
-#define ITERATE_XML_ELEMENTS(parent, child) \
- const TiXmlElement * child = (parent)->FirstChildElement(); \
- child != NULL; \
- child = child->NextSiblingElement()
-
-/// Macro d'assistance à l'énumération d'éléments enfants nommés d'un nœud TiXML
-#define ITERATE_XML_ELEMENTS_NAMED(parent, child, name) \
- const TiXmlElement * child = (parent)->FirstChildElement(name); \
- child != NULL; \
- child = child->NextSiblingElement(name)
-
// ----------------------------------------------------------------------------
/// Structure d'assistance à la création de noms de fichiers situés dans le répertoire %TEMP%
Modifié: trunk/xml.cpp
===================================================================
--- trunk/xml.cpp 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/xml.cpp 2010-01-09 20:32:02 UTC (rev 228)
@@ -28,6 +28,8 @@
#include "base.h"
+#if ! USE_TINYXML
+
#include "xml.h"
/**
@@ -596,3 +598,5 @@
if (fop)
fclose(fop);
}
+
+#endif // #if ! USE_TINYXML
Modifié: trunk/xml.h
===================================================================
--- trunk/xml.h 2010-01-09 14:43:49 UTC (rev 227)
+++ trunk/xml.h 2010-01-09 20:32:02 UTC (rev 228)
@@ -28,6 +28,8 @@
#pragma once
+#if ! USE_TINYXML
+
#include
#include
@@ -154,3 +156,5 @@
CXMLOpenChild(CXMLOutput & rf, LPCSTR name);
~CXMLOpenChild(); // (le destructeur ferme l'enfant)
};
+
+#endif // #if ! USE_TINYXML
Ajouté: trunk/xmlutils.cpp
===================================================================
--- trunk/xmlutils.cpp (rev 0)
+++ trunk/xmlutils.cpp 2010-01-09 20:32:02 UTC (rev 228)
@@ -0,0 +1,109 @@
+/*
+ * xmlutils.cpp
+ * Copyright (C) 2010 gingko - http://gingko.homeip.net/
+ *
+ * This file is part of Pouchin TV Mod, a free DVB-T viewer.
+ * See http://pouchintv.baysse.fr/ for updates.
+ *
+ * Pouchin TV Mod is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Pouchin TV Mod is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *
+ * Most files of this project have been changed from the Pouchin TV
+ * project (Copyright (C) 2006 Pouchin ),
+ * to use with a modified version of this software.
+ * See http://pouchinteve.free.fr/ for the original project.
+ */
+
+#include "xmlutils.h"
+
+/**
+ * Obtenir le contenu d'un élément XML, ou bien une chaîne vide si
+ * cet élément n'existe pas ou s'il n'est pas du texte
+ * \param[in] pXmlElm Noeud XML parent
+ * \param[in] pszTag Élément recherché
+ * \return Le texte inclus dans l'élément, ou bien une chaîne vide si l'élément
+ * n'existe pas ou bien n'est pas une chaîne.
+ * \note Si plusieurs éléments de même nom existent, seul le premier est retourné
+ **/
+LPCSTR GetXmlContent(const TiXmlElement * pXmlElm, LPCSTR pszTag)
+{
+ const TiXmlElement * pXmlTmp = pXmlElm->FirstChildElement(pszTag);
+
+ if (pXmlTmp)
+ return pXmlTmp->GetText();
+ return "";
+}
+
+/**
+ * Obtenir le contenu d'un élément XML, ou bien une chaîne vide si
+ * cet élément n'existe pas ou s'il n'est pas du texte.
+ * Le nom de l'élément lui-même fait l'objet d'un formatage.
+ * \param[in] pXmlElm Noeud XML parent
+ * \param[in] pszFmt Chaîne de formatage
+ * \param ... Arguments de la chaîne de formatage
+ * \return Le texte inclus dans l'élément, ou bien une chaîne vide si l'élément
+ * n'existe pas ou bien n'est pas une chaîne.
+ * \note Si plusieurs éléments de même nom existent, seul le premier est retourné
+ **/
+LPCSTR GetXmlContentF(const TiXmlElement * pXmlElm, LPCSTR pszFmt, ...)
+{
+ CHAR szTmp[16];
+ va_list args;
+
+ va_start(args, pszFmt);
+ vsprintf_s(szTmp, pszFmt, args);
+ va_end(args);
+ return GetXmlContent(pXmlElm, szTmp);
+}
+
+/**
+ * Définir le contenu d'un élément XML
+ * \param[in] pXmlElm Noeud XML parent
+ * \param[in] pszTag Élément recherché
+ * \param[in] pszTxt Texte à y inclure
+ **/
+void SetXmlContent(TiXmlElement * pXmlElm, LPCSTR pszTag, LPCSTR pszTxt)
+{
+ TiXmlElement * pXmlChld(new TiXmlElement(pszTag));
+
+ if (pXmlChld) {
+ TiXmlText * pXmlTxt(new TiXmlText(pszTxt));
+
+ if (pXmlTxt) {
+ pXmlChld->LinkEndChild(pXmlTxt);
+ pXmlElm->LinkEndChild(pXmlChld);
+ } else
+ delete pXmlChld;
+ }
+}
+
+/**
+ * Définir le contenu d'un élément XML
+ * \param[in] pXmlElm Noeud XML parent
+ * \param[in] pszFmt Chaîne de formatage
+ * \param[in] pszTxt Texte à y inclure
+ * \param ... Arguments de la chaîne de formatage
+ **/
+void SetXmlContentF(TiXmlElement * pXmlElm, LPCSTR pszFmt, LPCSTR pszTxt, ...)
+{
+ CHAR szTmp[16];
+ va_list args;
+
+ va_start(args, pszTxt);
+ vsprintf_s(szTmp, pszFmt, args);
+ va_end(args);
+ SetXmlContent(pXmlElm, szTmp, pszTxt);
+}
+
Ajouté: trunk/xmlutils.h
===================================================================
--- trunk/xmlutils.h (rev 0)
+++ trunk/xmlutils.h 2010-01-09 20:32:02 UTC (rev 228)
@@ -0,0 +1,93 @@
+/*
+ * xmlutils.h
+ * Copyright (C) 2010 gingko - http://gingko.homeip.net/
+ *
+ * This file is part of Pouchin TV Mod, a free DVB-T viewer.
+ * See http://pouchintv.baysse.fr/ for updates.
+ *
+ * Pouchin TV Mod is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * Pouchin TV Mod is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *
+ * Most files of this project have been changed from the Pouchin TV
+ * project (Copyright (C) 2006 Pouchin ),
+ * to use with a modified version of this software.
+ * See http://pouchinteve.free.fr/ for the original project.
+ */
+
+#pragma once
+
+#include
+#include "tinyxml/tinyxml.h"
+
+/// Macro d'assistance à l'énumération de nœuds enfants d'un nœud TiXML
+#define ITERATE_XML_CHILDREN(parent, child) \
+ const TiXmlNode * child = (parent)->FirstChild(); \
+ child != NULL; \
+ child = child->NextSibling()
+
+/// Macro d'assistance à l'énumération d'éléments enfants d'un nœud TiXML
+#define ITERATE_XML_ELEMENTS(parent, child) \
+ const TiXmlElement * child = (parent)->FirstChildElement(); \
+ child != NULL; \
+ child = child->NextSiblingElement()
+
+/// Macro d'assistance à l'énumération d'éléments enfants nommés d'un nœud TiXML
+#define ITERATE_XML_ELEMENTS_NAMED(parent, child, name) \
+ const TiXmlElement * child = (parent)->FirstChildElement(name); \
+ child != NULL; \
+ child = child->NextSiblingElement(name)
+
+// ----------------------------------------------------------------------------
+
+/**
+ * Obtenir le contenu d'un élément XML, ou bien une chaîne vide si
+ * cet élément n'existe pas ou s'il n'est pas du texte
+ * \param[in] pXmlElm Noeud XML parent
+ * \param[in] pszTag Élément recherché
+ * \return Le texte inclus dans l'élément, ou bien une chaîne vide si l'élément
+ * n'existe pas ou bien n'est pas une chaîne.
+ * \note Si plusieurs éléments de même nom existent, seul le premier est retourné
+ **/
+LPCSTR GetXmlContent(const TiXmlElement * pXmlElm, LPCSTR pszTag);
+
+/**
+ * Obtenir le contenu d'un élément XML, ou bien une chaîne vide si
+ * cet élément n'existe pas ou s'il n'est pas du texte.
+ * Le nom de l'élément lui-même fait l'objet d'un formatage.
+ * \param[in] pXmlElm Noeud XML parent
+ * \param[in] pszFmt Chaîne de formatage
+ * \param ... Arguments de la chaîne de formatage
+ * \return Le texte inclus dans l'élément, ou bien une chaîne vide si l'élément
+ * n'existe pas ou bien n'est pas une chaîne.
+ * \note Si plusieurs éléments de même nom existent, seul le premier est retourné
+ **/
+LPCSTR GetXmlContentF(const TiXmlElement * pXmlElm, LPCSTR pszFmt, ...);
+
+/**
+ * Définir le contenu d'un élément XML
+ * \param[in] pXmlElm Noeud XML parent
+ * \param[in] pszTag Élément recherché
+ * \param[in] pszTxt Texte à y inclure
+ **/
+void SetXmlContent(TiXmlElement * pXmlElm, LPCSTR pszTag, LPCSTR pszTxt);
+
+/**
+ * Définir le contenu d'un élément XML
+ * \param[in] pXmlElm Noeud XML parent
+ * \param[in] pszFmt Chaîne de formatage
+ * \param[in] pszTxt Texte à y inclure
+ * \param ... Arguments de la chaîne de formatage
+ **/
+void SetXmlContentF(TiXmlElement * pXmlElm, LPCSTR pszFmt, LPCSTR pszTxt, ...);
From pouchintv-dev at baysse.fr Thu Jan 21 00:27:56 2010
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: jeu, 21 jan 2010 00:27:56 +0100
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r232 -
tags/pouchintv_mod-0.6.0 tags/pouchintv_mod-0.6.0/BaseClasses
trunk trunk/BaseClasses
Message-ID: <20100120232757.888B35F76D@mail.baysse.fr>
Author: gingko
Date: 2010-01-21 00:27:56 +0100 (jeu 21 jan 2010)
New Revision: 232
Modified:
tags/pouchintv_mod-0.6.0/BaseClasses/Doxyfile
tags/pouchintv_mod-0.6.0/Doxyfile
tags/pouchintv_mod-0.6.0/changelog.html
tags/pouchintv_mod-0.6.0/graph.cpp
tags/pouchintv_mod-0.6.0/ini.cpp
tags/pouchintv_mod-0.6.0/recprog.cpp
tags/pouchintv_mod-0.6.0/res.rc
trunk/BaseClasses/Doxyfile
trunk/changelog.html
trunk/console.h
trunk/grabber.h
trunk/graph.cpp
trunk/main.cpp
trunk/mpeg2defs.h
trunk/recprog.cpp
trunk/search.cpp
Log:
Correction de bugs pour la version 0.6.0 (Ã la fois dans le tag 0.6.0 et dans "trunk").
graph.cpp :
* Correctif pour certains tuners qui, bien que trouvés en mode normal, ne peuvent pas être
insérés dans le graphe.
recprog.cpp :
* Dans la programmation manuelle des enregistrements, certains intervalles de longueurs dans
le nom de l'enregistrement pouvaient provoquer un plantage de l'application.
Reports dans le tag 0.6.0 de correctifs déjà publiés dans le "trunk" à la révision 227, et
qui peuvent être publiés immédiatement :
ini.cpp :
* La présence d'un canal avec une valeur 0 dans le fichier canaux.ini n'a plus pour effet
d'interrompre la recherche.
res.rc :
* Correctif (oubli) dans le nom du dialogue d'arrêt temporisé des enregistrements.
Quelques oublis dans les commentaires globaux de fichiers et dans "main.cpp" (trunk).
Modifié: tags/pouchintv_mod-0.6.0/BaseClasses/Doxyfile
===================================================================
--- tags/pouchintv_mod-0.6.0/BaseClasses/Doxyfile 2010-01-20 22:46:09 UTC (rev 231)
+++ tags/pouchintv_mod-0.6.0/BaseClasses/Doxyfile 2010-01-20 23:27:56 UTC (rev 232)
@@ -1,4 +1,4 @@
-# Doxyfile 1.5.7.1
+# Doxyfile 1.6.2
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
@@ -34,7 +34,7 @@
# base path where the generated documentation will be put.
# If a relative path is entered, it will be relative to the location
# where doxygen was started. If left blank the current directory will be used.
-OUTPUT_DIRECTORY = ..\docs\BaseClasses
+OUTPUT_DIRECTORY =
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
# 4096 sub-directories (in 2 levels) under the output directory of each output
@@ -115,6 +115,12 @@
# (but less readable) file names. This can be useful is your file systems
# doesn't support long names like on DOS, Mac, or CD-ROM.
SHORT_NAMES = NO
+# Note : si, à la génération, vous obtenez des erreurs multiples de type
+# "Error opening map file *.map for inclusion in the docs!", ne cherchez pas à
+# changer l'option SHORT_NAMES ainsi qu'il est parfois indiqué sur le Net.
+# Contentez-vous d'effacer le contenu du répertoire "Doxygen_files" et refaites
+# la génération de la documentation Doxyfile. Voir bug Doxygen 525273, ici :
+# http://bugzilla.gnome.org/show_bug.cgi?id=525273
# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
# will interpret the first line (until the first dot) of a JavaDoc-style
@@ -651,7 +657,7 @@
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# put in front of it. If left blank `html' will be used as the default path.
-HTML_OUTPUT = html
+HTML_OUTPUT = Doxygen_files
# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
@@ -1220,11 +1226,8 @@
# The tag DOT_PATH can be used to specify the path where the dot tool can be
# found. If left blank, it is assumed the dot tool can be found in the path.
-DOT_PATH = "C:/Program Files/Graphviz 2.21/bin"
+DOT_PATH =
-# Attention : sur un OS 64 bits, ce répertoire devrait être le suivant :
-# DOT_PATH = "C:/Program Files (x86)/Graphviz 2.21/bin"
-
# The DOTFILE_DIRS tag can be used to specify one or more directories that
# contain dot files that are included in the documentation (see the
# \dotfile command).
Modifié: tags/pouchintv_mod-0.6.0/Doxyfile
===================================================================
--- tags/pouchintv_mod-0.6.0/Doxyfile 2010-01-20 22:46:09 UTC (rev 231)
+++ tags/pouchintv_mod-0.6.0/Doxyfile 2010-01-20 23:27:56 UTC (rev 232)
@@ -1,4 +1,4 @@
-# Doxyfile 1.5.7.1
+# Doxyfile 1.6.2
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
Modifié: tags/pouchintv_mod-0.6.0/changelog.html
===================================================================
--- tags/pouchintv_mod-0.6.0/changelog.html 2010-01-20 22:46:09 UTC (rev 231)
+++ tags/pouchintv_mod-0.6.0/changelog.html 2010-01-20 23:27:56 UTC (rev 232)
@@ -1,1029 +1,1043 @@
-
-
-
-
-
- Changements entre les versions
-
-
-
-
-
-
-
-
-
-
Changements entre les versions de Pouchin TV Mod
-
-
-
-
-
-
Cette page répertorie l'historique des différentes versions de Pouchin TV Mod
-depuis la création du logiciel Pouchin TV de base.
-
-
Les versions dont le numéro apparaît en bleu ont été publiées
-sur le site de Pouchin TV Mod , ou bien
-sur le site du créateur du Mod , ou bien
-sur le site du programme original Pouchin TV .
-
-
Les versions dont le numéro apparaît en noir (et en gras)
-ont été publiées à titre expérimental sur le
-forum de Pouchin TV Mod .
-
-
Les versions citées en italiques n'ont pas été publiées (ou bien ne sont plus disponibles).
-Certaines d'entre elles (indication SVN ) peuvent cependant être récupérées
-en tant que code source depuis le dépot SVN du projet ,
-et compilées en suivant les instructions de la
-page de compilation .
-
-
-
-
Changements réalisés pour la version 0.6
-
-
- 0.6.0.223 (publiée le 27 décembre 2009) :
-
- Correction d'un bug : un enregistrement programmé qui demande l'arrêt de l'application
- ou l'extinction de l'ordinateur pouvait interrompre un autre enregistrement en cours
- (contrairement à ce qui est affiché dans les boîtes de dialogue).
-
-
-
- SVN rév. 221 :
-
- Certaines colorisations de l'EPG sont rendues légèrement plus foncées.
- Correction de bugs :
- Certains tuners n'étaient plus trouvés dans la recherche.
- Duplicatas dans les noms de quatre codes de raccourcis.
- Un tuner débranché était toujours identifié comme présent, reportant l'erreur
- Ã la construction du graphe.
-
-
-
- 0.6.0.216 RC (publiée dans le forum le 19 décembre 2009) :
-
- Ajout de colorisations dans les rangées de la fenêtre EPG :
- fond vert pour les émissions de la chaîne courante ;
- fond jaune clair pour les émissions des chaînes diffusées sur le même multiplex
- que la chaîne courante ;
- les émissions supposées être en cours de diffusion (selon leur horaire) sont
- affichées avec le texte en bleu ;
- les émissions en cours d'enregistrement sont affichées en texte rouge ;
- les autres émissions sont affichées en gris.
- Dans cette même fenêtre EPG, toutes les colonnes peuvent être triées (alternativement
- en ordre ascendant et descendant) en cliquant sur l'en-tête de la colonne concernée.
-
-
-
- SVN rév. 215 :
-
- Les menus de l'application sont réorganisés, selon la nouvelle structure Fichiers ,
- Chaînes , Vidéo , Audio , Information , Enregistrer ,
- Options et Aide .
- Ajout de deux boutons -24h et +24h dans le dialogue des enregistrements
- programmés, pour permettre de décaler rapidement de 24h une programmation existante
- ou en construction.
- Ajout de couleurs dans la liste des enregistrements programmés, en correspondance avec
- l'état des programmations.
- Mise en place d'un nouveau système de numérotation des versions, selon lequel :
- Le 1er et le 2nd chiffre sont les numéros majeur et mineur.
- Le 3ème chiffre est le numéro de révision. Ce chiffre sera pair pour les
- versions publiées, et impair pour les versions intermédiaires, expérimentales ou beta.
- Le 4ème chiffre est le numéro de publications des sources dans le dépot SVN.
- Ce chiffre peut être suffixé d'un "+" dans le cas d'une compilation locale dont les sources
- ne sont pas (encore) publiés.
-
-
-
-
-
Retour
-
-
-
-
Changements réalisés pour la version 0.5
-
-
- SVN rév. 214 :
-
- Remplacement du paramètre de configuration Utiliser AC3 par défaut par une liste
- déroulante présentant sept choix possibles.
- Unification de ce choix de préférences avec celui présenté dans les enregistrements
- programmés, effectués directement ou bien via l'EPG.
- Les titres de menus Stopper l'enregistrement et dérivés sont remplacés par
- Arrêter l'enregistrement , etc.
- Ajout d'une détection des pistes AC3 et EAC3 Home Cinéma (c'est-à -dire celles qui
- définissent plus de deux canaux audio).
- La subdivision des items OSD du bas se fait maintenant dans la proportion 1/3 Ã gauche,
- 2/3 à droite, les noms des pistes audio pouvant ne pas tenir dans la moitié de l'écran.
- Corrections de bugs :
- Les tooltips de noms d'émissions en cours dans la zone de notification n'étaient
- pas toujours mis à jour correctement.
- La programmation d'un enregistrement depuis l'EPG pouvait faire planter l'application
- si le nom de l'émission était trop long.
- Les langues des pistes audio MPEG2 n'étaient plus récupérées, ni affichées dans le menu
- des pistes (régression remontant à la révision 175).
- Un enregistrement devenant supplanté pouvait ne pas être mis à jour en temps réel
- dans la boîte de dialogue de programmation.
- Ajout d'intitulés à certains contrôles de la boîte de dialogue EPG.
-
-
-
-
- SVN rév. 213 :
-
- Implémentation de la recherche de tuner avancée :
- Il n'y a plus besoin de spécifier de récepteur dans le dialogue de configuration.
- Cette disposition devrait permettre la compatibilité du logiciel avec un plus grand nombre
- de tuners différents.
-
-
-
- SVN rév. 212 :
-
- Si un filtre est manquant au moment de la configuration, son nom est préfixé des caractères
- <?> dans la liste déroulante, afin qu'il soit visible que cet élément n'est pas valide.
-
-
-
- SVN rév. 211 :
-
- Utilisation des interfaces tuning space pour sélectionner les chaînes, dans le graphe
- non alternatif .
-
-
-
- 0.5.208 (expérimentale, publiée dans le forum le 11 novembre 2009) :
-
- Ajout de la prise en charge des radios numériques DVB telles que celles qu'on peut avoir en Belgique.
- Ajout d'un raccourci clavier (backspace par défaut) permettant de revenir sur la chaîne précédemment
- regardée (s'il en existait une).
- En cas d'absence d'icône spécifique pour une chaîne donnée, une icône générique en niveaux de gris
- est maintenant affichée.
- En cas d'absence d'affichage vidéo (pas de codec ou bien chaîne radio), un rendu générique (avec une croix,
- bleue barrant l'écrant) est affiché, à la manière de ce qui existait déjà précédemment quand on désactivait le
- rendu vidéo.
- Correction d'un bug : l'option de désactivation de la prise en charge des touches multimédia
- ne fonctionnait pas correctement.
- Icône Clermont 1ère ajoutée.
-
-
-
- 0.5.205 (expérimentale, publiée via le service de mise à jour le 6 septembre 2009) :
-
- Correction d'un bug : en cas d'extinction de l'ordinateur sans quitter le logiciel,
- le programme se comportait comme s'il avait été quitté anormalement.
- Correction d'un bug : les enregistrements du multiplex entier étaient dupliqués
- toutes les 10 minutes, jusqu'à épuisement du nombre d'enregistrements simultanés disponibles.
- Icônes Fr3 Alpes et Fr3 Rhone ajoutées en doublon de France 3 .
-
-
-
- 0.5.204 (expérimentale, publiée dans le forum le 2 septembre 2009) :
-
- Correction d'un oubli : le paramètre de ligne de commande --prefix
- n'était pas répercuté dans les tâches programmées dans le gestionnaire des tâches,
- si on utilisait cette option dans les programmations d'enregistrements.
- Si Pouchin TV Mod est quitté irrégulièrement (plantage …), alors
- au démarrage suivant, un message avertit de cet état de fait et propose d'ouvrir le
- dialogue de configuration afin de laisser la possibilité de corriger le problème.
- Ajout de messages pour informer l'utilisateur de la nécessité, dans certaines
- versions et/ou configurations de Windows, de lancer l'application en mode
- administrateur si on veut pouvoir effectuer la mise à jour par Internet.
-
-
-
- 0.5.203 (expérimentale, publiée via le service de mise à jour le 30 août 2009) :
-
- Correction d'un bug dans la mise à jour des icônes
-
-
-
- SVN rév. 202 :
-
- Correction d'un bug introduit récemment, qui provoquait un plantage à l'issue
- d'unerecherche de chaînes en présence d'un tiner nouvellement installé (aucune
- chaîne préexistante).
- Correction d'un bug provoquant un plantage si la fenêtre de qualité du signal est
- ouverte pendant les redémarrages du graphe.
- Icônes Fr3 PaysLoire et Fr3 Poitiers ajoutées en doublon de France 3 .
-
-
-
- 0.5.201 (expérimentale, publiée dans le forum le 14 août 2009) :
-
- Optimisation du démarrage du graphe, qui devrait être un peu plus rapide.
- Correction d'une fuite mémoire introduite à la révision 198.
- Icône France3 (sans espace) ajoutée en doublon de France 3 (avec espace).
-
-
-
- SVN rév. 200 :
-
- Utilisation d'un filtre EAC3 dédié, sélectionnable dans la configuration,
- d'après un patch proposé par MatMaul .
- Un rebasculement en AC3 est prévu si aucun filtre EAC3 n'existe ou n'est choisi.
- Dans le menu des filtres, les filtres de rendu audio sont fusionnés sous une seule commande,
- affichant les propriétés du filtre effectivement utilisé.
-
-
-
- SVN rév. 199 :
-
- Mise à jour du système des … euh … mises à jour de Pouchin TV Mod,
- avec prise en charge correcte des versions 64 bits ainsi que des versions expérimentales.
-
-
-
- 0.5.198 (expérimentale, publiée dans le forum le 24 juillet 2009) :
-
- Dernière étape d'une importante réorganisation du code dans le graphe.
- En cas de plantage de l'Explorateur Windows, l'icône de la barre des tâches est restaurée.
- Ajout d'une commande clavier (Ctrl-Q par défaut) pour relancer le graphe en interne.
-
-
-
- SVN rév. 197 :
-
- Seconde étape d'une importante réorganisation du code dans le graphe.
- Quelques corrections mineures.
-
-
-
- SVN rév. 196 :
-
- Plus de déconnexion des filtres pendant la resyntonisation, afin d'éviter des plantages.
- Les listes de pilotes ou de codecs, dans la configuration, sont maintenant triées insensibles
- Ã la casse.
- Une erreur détectée pendant le changement de fréquence n'arrête plus la recherche
- des chaînes (cette détection avait été introduite à la révision 189, mais certains tuners semblent
- retourner une erreur alors qu'ils changent de fréquence correctement) .
- Première étape d'une importante réorganisation du code dans le graphe.
-
-
-
- SVN rév. 195 :
-
- La couleur de l'affichage OSD peut maintenant être changée.
- Possibilité de sélectionner les pistes audio par défilement, entre autres avec la molette de la souris.
- Affichage OSD au changement de piste audio.
-
-
-
- 0.5.194 (expérimentale, publiée dans le forum le 3 juillet 2009) :
-
- Réduction à un seul du nombre de filtres Grabber pour les enregistrements,
- et utilisation d'un thread pour réaliser ceux-ci, améliorant l'immunité
- des flux enregistrés aux influences d'autres programmes sur le même ordinateur.
- Quatre enregistrements simultanés possibles.
-
-
-
- SVN rév. 193 :
-
- Anticipation temporisée au changement de chaîne et de zoom.
- Davantage de choix pour la molette de la souris.
-
-
-
- SVN rév. 192 :
-
- Il est maintenant possible de passer outre
- Ã certains messages d'erreurs de conflits d'enregistrements.
-
-
-
- SVN rév. 190 :
-
- Deux tuners rigoureusement identiques (et donc affichant le même nom dans la configuration)
- devraient maintenant être accessibles séparément.
-
-
-
- SVN rév. 189 :
-
- Ajout d'options pour la molette de la souris et les commandes multimédia.
-
-
-
- 0.5.188 (expérimentale, publiée dans le forum le 13 juin 2009) :
-
- Ajout du support du rendu vidéo EVR (Enhanced Video Renderer),
- à partir d'un patch proposé par MatMaul .
-
-
-
- SVN rév. 187 :
-
- Plusieurs instances de l'application peuvent prendre en charge chacune un tuner différent,
- sur le même ordinateur, grâce à une option qui permet de leur attribuer à chacun des fichiers
- de configuration différents.
- Le titre de la fenêtre peut maintenant être modifié dans la configuration.
-
-
-
- 0.5.186 (expérimentale, publiée dans le forum le 28 mai 2009) :
-
- Prise en charge des filtres gérant l'audio au format E-AC3 .
- Implémentation d'une option permettant de revenir au graphe des versions antérieures
- à la révision 184 , car il apparaît que pour certains utilisateurs,
- le nouveau graphe ne marche pas alors que l'ancien fonctionnait.
- La recherche de chaînes peut maintenant essayer deux fréquences voisines pour chaque canal,
- avec décalage de 5 kHz (à cause de problèmes qu'ont certains tuners à gérer
- une fréquence trop proche de la fréquence effective).
- Ajout d'éléments de configuration supplémentaires à la recherche de chaînes.
- Certains messages affichés dans des dialogues d'informations
- sont assortis d'une option Ne plus afficher ce message .
- En cas d'échec d'initialisation du rendu vidéo, l'application n'est plus quittée.
- En lieu et place, l'affichage est désactivé avec un message d'avertissement.
-
-
-
- 0.5.184 (expérimentale, publiée dans le forum le 5 avril 2009) :
-
- Modification du graphe pour le rendre plus conforme à ce qui était recommandé par Microsoft
- (utilisation du filtre Microsoft DVB-T Network Provider ).
-
-
-
- SVN rév. 183 :
-
- Correction de bogues divers, concernant notamment l'affichage sur clavier
- LCD Logitech, l'EPG et le masquage de la souris en mode plein écran.
-
-
-
- SVN rév. 182 :
-
- L'affichage de qualité du signal gère correctement les tuners
- qui ne donnent pas certaines informations réclamées.
- Amélioration de la journalisation de la recherche de canaux et de l'affichage de versions.
-
-
-
- SVN rév. 181 :
-
- Amélioration du système qui affiche le nom de l'émission en cours.
-
-
-
- 0.5.179 (expérimentale, publiée dans le forum le 27 mars 2009) :
-
- Refonte complète du système de recherche de chaînes :
- La recherche de chaînes devient paramétrable,
- et se fait maintenant dans un thread distinct.
- L'attribution des numéros aux chaînes non numérotées,
- ou bien en cas de doublon, est maintenant configurable.
- Le cas de même chaînes reçues de plusieurs émetteurs différents
- est pris en charge plus proprement.
- Prise en charge améliorée des multiplex (vraisemblablement étrangers)
- qui ne contiennent pas de description des chaînes du réseau.
- La recherche peut se faire de manière incrémentale.
- Un fichier journal scan.log enregistre les résultats
- des recherches successives.
- Les indicateurs de force et de qualité du signal
- sont répliqués dans le dialogue de recherche de chaînes.
- On peut maintenant spécifier une liste de chaînes
- définie manuellement pour la recherche.
-
-
-
- SVN rév. 177 :
-
- Indicateurs visuels de niveau de force et de qualité dans le dialogue
- de qualité du signal.
- L'indicateur de force de signal est calibrable dans la configuration.
-
-
-
- SVN rév. 176 :
-
- En cas de présence de plusieurs tuners, les paramètres spécifiques à chacun
- d'eux sont sauvegardés séparément dans la configuration.
- Changer de tuner provoque automatiquement la sélection du récepteur associé au nouveau,
- s'il a déjà été utilisé auparavant.
- Représentation plus stricte des chaînes en interne.
- Les raccourcis clavier sont sauvegardés dans une sections distincte du fichier
- de configuration.
- Les tuners et codecs qui sont sélectionnés mais qui ont disparu du système restent
- néanmoins mémorisés et affichés dans les listes déroulantes.
- Un message d'alerte avertit alors de leur disparition.
-
-
-
- SVN rév. 175 :
-
- Le rafraîchissement, dans l'EPG, est limité à une fois par seconde.
- Correction d'un bug susceptible de corrompre les enregistrements dans le cas où
- le pilote du tuner utilisé enverrait des paquets incomplets à reconstituer
- (merci à virtualblue sur le forum).
- Une option de resyntonisation automatique remplace l'ancienne option
- va-et-vient de fréquences au démarrage .
- Correction d'un problème de relation entre certaines boîtes de dialogue et leurs fenêtres parentes.
-
-
-
- 0.5.174 (expérimentale, publiée dans le forum le 27 février 2009) :
-
- Le numéro de version devient 0.5 .
- La mise à jour de la liste des programmes dans l'EPG se fait maintenant en temps réel :
- plus besoin de presser de bouton Mettre à jour , lequel est donc, en conséquence, supprimé,
- et remplacé par un bouton Réinitialiser , qui provoque le rechargement intégral de l'EPG.
- Ajout de colonnes d'informations dans le dialogue de configuration des chaînes.
- La norme de réception est affichée en clair (MPEG2 ou H264 ).
- Ajout des icônes de chaînes belges dans l'installation.
-
-
-
-
-
Retour
-
-
-
-
Changements réalisés pour la version 0.4
-
(depuis la reprise du projet)
-
-
- 0.4.173 (expérimentale, publiée dans le forum le 22 février 2009,
- puis supprimée) :
-
- Ajout du support des chaînes haute définition .
- Les codecs peuvent être être désactivés en spécifiant le choix Aucun .
- Le va-et-vient de fréquence est remplacé par une détection de gels du graphe,
- provoquant une resyntonisation automatique.
- Nouveau système de numérotation des versions :
- numéro majeur
- numéro mineur
- numéro SVN
- indice (0 ou 1 ) de modification.
-
-
-
- SVN rév. 172 :
-
- Ajout du numéro TSID des chaînes devant leur numéro pour
- faire ressortir les chaînes appartenant au même multiplex.
- Informations supplémentaires dans le dialogue À propos
- pour mieux identifier la version compilée.
- Correctif visant à éviter qu'un flux TS corrompu
- puisse provoquer un plantage de l'application.
- Correction d'un bug susceptible d'introduire
- des corruptions du contenu de la liste des chaînes.
-
-
-
- SVN rév. 169 :
-
- La boîte de dialogue du Guide des Programmes est maintenant redimensionnable.
- Ajout d'une commande Ctrl-F pour resyntoniser sur la fréquence courante
- (permet parfois de débloquer un graphe figé).
- Dans les contrôles de dialogue présentant des listes, on peut maintenant
- réorganiser les colonnes (mais cette réorganisation n'est pas sauvegardée).
-
-
-
- SVN rév. 168 :
-
- Les changements de codecs ou de rendu vidéo
- peuvent maintenant se faire sans avoir à relancer l'application.
-
-
-
- SVN rév. 166 :
-
- Ajout des modes de rendu VMR7 windowless et Aucun rendu vidéo ,
- ce dernier mode permettant d'effectuer des enregistrements sur un ordinateur
- de performances insuffisantes pour afficher la vidéo.
- Ajout d'une option de configuration pour activer ou désactiver
- le va-et-vient de fréquence au démarrage.
-
-
-
- SVN rév. 165 :
-
- Ajout d'un raccourci (touche Suppr. )
- pour effacer une programmation de la liste des enregistrements programmés.
-
-
-
- SVN rév. 164 :
-
- Le réglage de volume a maintenant une variation logarithmique, par pas de 5 .
- Ajout de l'option de configuration --prefix ,
- permettant d'avoir des fichiers de configuration distincts.
-
-
-
- SVN rév. 163 :
-
- Le projet peut maintenant se compiler ASCII (8 bits) en plus du mode Unicode,
- à l'aide des configuration Debug_SBCS et Release_SBCS ajoutées.
- Correction d'un bug qui faisait disparaître les caractères accentués
- à la fin des noms d'enregistrement programmés.
-
-
-
- SVN rév. 160 :
-
- Ajout d'options de configuration pour augmenter la durée
- d'un enregistrement programmé depuis l'EPG, par le début et par la fin,
- de manière à se prémunir des incertitudes d'horaires.
- Suppression des configurations Vista debug et Vista release , qui
- n'avaient plus de raison d'être.
-
-
-
- SVN rév. 159 :
-
- Réécriture de la gestion du Video Mixing Renderer ,
- ainsi que de la fonction OSD .
- Ajout de la gestion du VMR9 .
- Activation de l'OSD en VMR9 sous Windows Vista.
- Ajout d'une commande Utiliser toute la hauteur ,
- contrepartie verticale de la commande Utiliser toute la largeur précédemment existante.
-
-
-
- SVN rév. 158 :
-
- Le fichier canaux.ini est dorénavant placé dans le répertoire Application Data .
-
-
-
- SVN rév. 157 :
-
- Mise à jour de la liste des canaux.
-
-
-
- SVN rév. 152 :
-
- Ajout d'une page de configuration de raccourcis clavier,
- permettant de modifier les commandes données par le clavier.
-
-
-
- SVN rév. 149 :
-
- Prise en charge des commandes multimédia
- (générées par certains périphériques de type clavier ou télécommande).
-
-
-
- SVN rév. 146 :
-
- Ajout d'une option pour spécifier le format du nom des fichiers enregistrés.
- Les options de ligne de commande prennent deux tirets au lieu d'un.
-
-
-
-
- SVN rév. 142 :
-
- Ajout d'icônes pour les chaînes belges.
-
-
-
- SVN rév. 141 :
-
- Un changement de chaîne en mode suspendu n'a plus pour effet
- de désuspendre l'audio et la vidéo.
- Correction d'un bug dans l'EPG qui faisait que le bouton Enregistrer
- ne fonctionnait qu'après modification de la sélection.
-
-
-
- SVN rév. 140 :
-
- Utilisation de classes ATL pour gérer les filtres,
- sécurisant ainsi l'application contre certains types de fuites de mémoire.
-
-
-
- SVN rév. 136 :
-
- Amélioration du système d'affichage des erreurs :
- les codes d'erreur numériques sont décodés pour affichage en clair,
- et les erreur successives se cumulent dans une seule fenêtre
- plutôt que de s'afficher successivement.
-
-
-
- SVN rév. 133 :
-
- Ajout de diverses options de ligne de commande : -fs , -maxi ,
- -noborders , -normal , -recps , -rects et -ch##X .
-
-
-
- 0.4~svn-r130 (publiée le 20 octobre 2008) :
-
- Correction d'un bug dans la gestion des caractères non latins.
- Ajout de diverses icônes pour des chaines locales ou frontalières.
-
-
-
- SVN rév. 123 :
-
- Affichage intelligible de la valeur des messages d'erreurs DirectX .
- Ajout d'icônes de chaines locales.
- Diverses réorganisations internes du code.
-
-
-
- SVN rév. 117 :
-
- Meilleur support de l'enregistrement en mode PS.
-
-
-
- 0.4~svn-r112 (publiée le 3 janvier 2008) :
-
- Plusieurs bugs corrigés.
- Réorganisation interne du code.
-
-
-
- SVN rév. 106 :
-
- Réactivation de l'enregistrement du multiplex,
- mais sous condition d'activer une option de configuration.
- Refonte de la gestion des enregistrements programmés.
- Correction d'un bug avec certains pilotes de cartes TNT.
-
-
-
- SVN rév. 102 :
-
- Implémentation du dialogue de réorganisation des chaînes :
- Les chaines peuvent maintenant être renumérotées facilement en cliquant sur le numéro
- et en en saisissant un nouveau, ou en déplaçant la chaine dans la liste.
- Les chaînes peuvent être déclarées Actives ,
- Inactives ou Préférées , grâce à un menu contextuel :
- les chaînes Préférées peuvent être sélectionnées par flèches haut et bas,
- molette de souris ou par menu, alors que les chaînes Actives
- ne peuvent être sélectionnées que par menu.
- En maintenant la touche SHIFT pressée au démarrage de l'application,
- on forcera l'ouverture du dialogue de configuration (utile dans le cas où
- la configuration courante fait planter l'application avant même d'avoir accès aux menus).
- Liste des canaux mis à jour au 5 octobre 2007.
- Modification de la gestion de l'offset.
-
-
-
- SVN rév. 98 :
-
- Plusieurs améliorations au niveau de la recherche de chaînes
- ainsi que des enregistrements programmés.
-
-
-
- SVN rév. 92 :
-
- Modification de la configuration, en utilisant des onglets,
- et rassemblement des options par cathégorie.
-
-
-
- 0.4~svn-r87 (publiée le 4 octobre 2007) :
-
- Correction pour le plantage qui se produisait à la fin d'un scan des chaînes
- lors d'une nouvelle installation et de l'utilisation de DScaler .
- Suppression de l'option multiplex dans le guide des programmes.
- Disparition du curseur de la souris en mode plein écran rétablie.
- Réactivation de l'arrêt programmé de Pouchin TV Mod à la fin d'un enregistrement.
- Réaffiche les icones des chaînes à la suite d'une nouvelle recherche.
- Retire la fenêtre du premier plan lorsque l'on supprime l'option.
- Correctif pour le démarrage minimisé qui ne marchait plus correctement.
- Réorganisation interne du code.
-
-
-
- 0.4~svn-r83 (publiée le 28 septembre 2007) :
-
- Correction de bogues pour l'enregistrement concurentiel.
-
-
-
- SVN rév. 78 :
-
- Supporte maintenant un nombre de multiplex variable : de R1 Ã R99 (max).
- Corrections pour la gestion des différentes modes de fenêtre de Pouchin TV Mod.
- Vérifie si les dossiers de sauvegarde des enregistrements et des captures
- existent au lancement, et demande quoi faire si non.
- Amélioration du support des systèmes Windows 64 bits.
-
-
-
- SVN rév. 72 :
-
- Support de la répétition des enregistrements
- (tous les Lundi , Mardi et Vendredi par exemple) .
- Le choix de la ville à utiliser se fait maintenant dans la fenêtre de scan.
- Réorganisation interne du code.
-
-
-
- SVN rév. 68 :
-
- Il n'est plus nécessaire d'effacer le fichier config.ini .
- Pouchin TV Mod repropose la configuration plutôt.
-
-
-
- SVN rév. 60 :
-
- Affichage des chiffres au fur et à mesure de la saisie.
-
-
-
- SVN rév. 58 :
-
- Ajout des icônes des chaines dans les menus.
-
-
-
- 0.4~svn-r57 (publiée le 15 septembre 2007) :
-
- Recherche de mise à jour sur internet.
- Ajout d'une fonction permettant de ré-actualiser la liste des chaînes depuis Pouchin TV Mod ,
- et ce, en choisissant ou non de conserver les modifications.
- Correction d'un bug de longue date (Pouchin TV original)
- empêchant de récupérer le numéro de la chaîne.
- Correction d'un bug conduisant à refaire une recherche des canaux à chaque démarrage,
- suite à l'ajout de France Ô aux chaines (caractères accentués).
- Diverses corrections de bugs.
-
-
-
- SVN rév. 49 :
-
- Les boites de dialogues Qualité du signal… , Guide des programmes… ,
- Enregistrements programmés… sont non modales.
- Ajout d'information sur le programme en cours dans le systray.
- Diverses corrections de bugs.
-
-
-
- SVN rév. 45 :
-
- Remplacement de la fonction permettant d'enregistrer un multiplex
- par la possibilité d'enregistrer plusieurs chaines (jusqu'à 3) du multiplex.
- Le fichier canaux.ini est maintenant extrait des ressources.
- Changement des répertoires par défaut pour les sauvegardes des images et des vidéos.
- Diverses corrections de bugs.
-
-
-
- 0.4~svn-r42 (publiée le 29 août 2007) :
-
- Correction de plusieurs bugs.
- Ajout de la liste des contributeurs à la fenêtre À propos… .
- les fichiers de configs sont maintenant stockés dans le profil de l'utilisateur,
- C:\Documents And Settings\Utilisateur\Application Data\Pouchin TV Mod
- par exemple, ce qui devrait résoudre tous les problèmes pour les
- télécommandes, de partage d'ordinateur, ou de droits d'accès.
-
-
-
- 0.4~svn-r38 (publiée le 28 août 2007) :
-
- Correction d'un bug sous Vista empêchant l'affichage correct des fenêtres.
- Changement de l'icône de Pouchin TV Mod lorsque l'on enregistre.
- Changement de place pour l'indication du volume.
- Suppression des dépendances.
- Maintenant, la seule chose indispensable à installer est Pouchin TV Mod .
-
-
-
- 0.4~svn-r25 (publiée le 18 août 2007) :
-
- Correction d'un bug lorsque l'on coupait le son.
- Fusion des version pour 2000/XP et la version de Vista en une seule.
-
-
-
- 0.4~svn-r23 (publiée le 17 août 2007) :
-
- Ajout des raccourcis claviers dans les menus.
- Ajout d'une fonction demandant confirmation si on quitte
- Pouchin TV Mod et qu'un enregistrement est en cours.
-
-
-
- 0.4~svn-r18 (publiée le 15 août 2007) :
-
- Fusion des modifs
- effectuées
- par radius pour Vista :
- Comme il n'y a plus d'OSD , affiche le volume dans la barre des
- status (barre du bas).
- Correction d'un bug lors de la gestion des bandes noires et commutation 4/3 <-> 16/9.
-
- ajout d'une option Programme / Muet si minimisé pour
- activer / désactiver le son de Pouchin TV quand on le minimise.
- modification de l'agencement des menus et des boites de
- dialogues.
-
-
-
- 0.4~svn-r16 (publiée le 15 août 2007) :
-
- correction d'un bug lors de la sauvegarde de l'enregistrement
- dans le planificateur des tâches, dont le nom contient des
- caractères invalide.
- ajout de la priorité Temps réel au programme.
- gestion de l'option arrêter le PC à la fin de
- l'enregistrement .
-
-
-
-
-
Retour
-
-
-
-
-
-
- 0.4 RC2 (publiée le 18 juin 2007) :
-
-
-
- 0.4 RC1 :
-
- Correction de bugs.
- Si pas de gros bugs, dernière version avant la stable.
-
-
-
- 0.4 beta3 :
-
- Correction de bugs.
- Possibilité de programmer la fin d'un enregistrment après l'avoir lancé
- (Stopper l'enregistrement dans … ).
- Option pour étirer la vidéo.
- Ajout d'une version compatible Vista (sans OSD).
- Nouvelle icône, merci à korse2a .
-
-
- 0.4 beta2a :
-
- Fix d'un bug qui faisait planter le programme dès qu'un enregistrement était programmé.
-
-
-
- 0.4 beta2 :
-
- Ajout d'une option pour arrêter le logiciel après un enregistrement programmé.
- Support des tâches planifiées de Windows.
-
-
-
- 0.4 beta1 :
-
- Correction de quelques bugs.
- Quelques modifications graphiques.
-
-
-
- 0.4 alpha2 :
-
- Correction du bug qui faisait que seul le premier enregistrement programmé fonctionnait.
-
-
-
- 0.4 alpha1 :
-
- Première version du Mod . Les nouveautés par rapport à la version 0.3a sont :
- Programmation des enregistrements,
- mon code étant largement inspiré du mod de jmblot , merci à lui.
- Minimiser dans le system tray : quand Pouchin est minimisé, il stoppe le son,
- la vidéo, et ne prend presque plus de processeur
- → on peut programmer des enregistrements et laisser Pouchin dans le system tray.
- Sauvegarde du volume.
- Refonte totale de la gestion des pistes :
- affichage de la langue de la piste, pistes dans un menu à part,
- gestion d'un nombre de pistes virtuellement illimité.
- Quand on enregistre en TS ca enregistre toutes les pistes de la chaîne et non pas que l'audio sélectionné
- (même les flux de sous-titres sont enregistrés bien qu'ils n'apparaissent pas dans Pouchin ).
- Fix de ef15c pour le support de la Nova T Stick (merci à lui).
-
-
-
-
-
-
Retour
-
-
-
-
Changements réalisés par le créateur de la version originale
-
(dénommée PouchinTV )
-
-
- 0.3a (publiée le 28 mai 2006) :
-
- Correction de la vidéo qui ne s'affiche que sur le 1er écran en dual screen.
-
-
-
- 0.3 (publiée le 5 mai 2006) :
-
- Possibilité d'enregistrer en MPEG2 PS .
- OSD simple : nom de la chaîne et du programme, sourdine, volume, zoom.
- PouchinTV a maintenant absolument besoin de l'overlay pour fonctionner (conséquence de l'OSD ).
- Plus besoin de scanner pendant les heures où Canal+ , TPS star et Paris Première
- diffusent en clair pour tout avoir, PouchinTV est capable de récupérer les PID en dynamique.
- Option pour switcher directement en AC3 sur les chaînes qui le proposent.
- Réglage du volume avec + et - .
- Zoom réglable avec Z /Maj-Z .
- Correction bug enregistrement sur Nova-t Usb2 .
- Fenêtre d'EPG : le programme en cours est choisi par défaut,
- double clic permet de zapper sur une chaîne.
- Correction plein écran sur systèmes dual screen.
- Version pour XP64 (non testée !).
- Option pour que l'image utilise toute la largeur de la fenêtre :
- utile pour les films 16/9 ou + diffusés sur une chaine en 4/3 avec un écran large.
- Sauve/restaure la taille et position de la fenêtre.
- Propose l'offset à 166 pour les Hauppauge , et 167 pour les Terratec …
- Option dans le .ini pour utliser le désentrelacement hardware du VMR :
- le codec vidéo doit supporter ce mode.
-
-
-
- 0.2b (publiée le 13 mars 2006) :
-
- L'offset passe à 167 par défaut, et est réglable dans canaux.ini .
- Devrait fixer le problème de la Terratec Cynergy T2 .
-
-
-
- 0.2a (publiée le 12 mars 2006) :
-
- Corrige scan complet sans préciser de ville,
- sauvegarde Always on top dans les préférences.
-
-
-
-
- 0.2 :
-
- Correction des problèmes de compatibilité avec les clés USB, et les cartes qui ont besoin de 166 en offset.
- Sélection de la carte TNT pour ceux qui en ont plusieurs installées.
- Affiche le nom du programme en cours et de celui qui suit, ainsi que leurs horaires.
- Fenêtre d'EPG avec les progammes en cours sur toutes les chaînes.
- Peut afficher le nom du programme regardé sur MSN Messenger .
- Dialogue affichant la qualité du signal.
- Fonction Always on top .
- Affichage minimum (pas de menu, juste la vidéo), en faisant un clic gauche sur la zone vidéo.
- Peut définir la priorité du programme.
- Menu contextuel sur la zone vidéo.
-
-
-
- 0.1 (publiée le 4 mars 2006) :
-
- Première version publiée de Pouchin TV .
-
-
-
-
-
Retour
-
-
-
- Dernière modification de cette page :
-
-
-
+
+
+
+
+
+ Changements entre les versions
+
+
+
+
+
+
+
+
+
+
Changements entre les versions de Pouchin TV Mod
+
+
+
+
+
+
Cette page répertorie l'historique des différentes versions de Pouchin TV Mod
+depuis la création du logiciel Pouchin TV de base.
+
+
Les versions dont le numéro apparaît en bleu ont été publiées
+sur le site de Pouchin TV Mod , ou bien
+sur le site du créateur du Mod , ou bien
+sur le site du programme original Pouchin TV .
+
+
Les versions dont le numéro apparaît en noir (et en gras)
+ont été publiées à titre expérimental sur le
+forum de Pouchin TV Mod .
+
+
Les versions citées en italiques n'ont pas été publiées (ou bien ne sont plus disponibles).
+Certaines d'entre elles (indication SVN ) peuvent cependant être récupérées
+en tant que code source depuis le dépot SVN du projet ,
+et compilées en suivant les instructions de la
+page de compilation .
+
+
+
+
Changements réalisés pour la version 0.6
+
+
+ 0.6.0.232 (publiée le 21 janvier 2010) :
+
+ Correction de bugs :
+ Correctif pour certains tuners qui, bien que trouvés en mode normal,
+ ne peuvent pas être insérés dans le graphe.
+ Dans la recherche de chaînes pour une ville, le fait d'avoir un multiplex R5 inexistant et
+ marqué à zéro empêchait la recherche des multiplex subséquents.
+ Dans la programmation manuelle des enregistrements, certains intervalles de longueurs dans
+ le nom de l'enregistrements pouvaient provoquer un plantage de l'application.
+ Le nom du dialogue d'arrêt des enregistrements programmés n'avait pas été changé en
+ "Arrêter l'enregistrement dans…", comme il se devait.
+
+
+
+ 0.6.0.223 (publiée le 27 décembre 2009, remplacée par 0.6.0.232) :
+
+ Correction d'un bug : un enregistrement programmé qui demande l'arrêt de l'application
+ ou l'extinction de l'ordinateur pouvait interrompre un autre enregistrement en cours
+ (contrairement à ce qui est affiché dans les boîtes de dialogue).
+
+
+
+ SVN rév. 221 :
+
+ Certaines colorisations de l'EPG sont rendues légèrement plus foncées.
+ Correction de bugs :
+ Certains tuners n'étaient plus trouvés dans la recherche.
+ Duplicatas dans les noms de quatre codes de raccourcis.
+ Un tuner débranché était toujours identifié comme présent, reportant l'erreur
+ Ã la construction du graphe.
+
+
+
+ 0.6.0.216 RC (publiée dans le forum le 19 décembre 2009) :
+
+ Ajout de colorisations dans les rangées de la fenêtre EPG :
+ fond vert pour les émissions de la chaîne courante ;
+ fond jaune clair pour les émissions des chaînes diffusées sur le même multiplex
+ que la chaîne courante ;
+ les émissions supposées être en cours de diffusion (selon leur horaire) sont
+ affichées avec le texte en bleu ;
+ les émissions en cours d'enregistrement sont affichées en texte rouge ;
+ les autres émissions sont affichées en gris.
+ Dans cette même fenêtre EPG, toutes les colonnes peuvent être triées (alternativement
+ en ordre ascendant et descendant) en cliquant sur l'en-tête de la colonne concernée.
+
+
+
+ SVN rév. 215 :
+
+ Les menus de l'application sont réorganisés, selon la nouvelle structure Fichiers ,
+ Chaînes , Vidéo , Audio , Information , Enregistrer ,
+ Options et Aide .
+ Ajout de deux boutons -24h et +24h dans le dialogue des enregistrements
+ programmés, pour permettre de décaler rapidement de 24h une programmation existante
+ ou en construction.
+ Ajout de couleurs dans la liste des enregistrements programmés, en correspondance avec
+ l'état des programmations.
+ Mise en place d'un nouveau système de numérotation des versions, selon lequel :
+ Le 1er et le 2nd chiffre sont les numéros majeur et mineur.
+ Le 3ème chiffre est le numéro de révision. Ce chiffre sera pair pour les
+ versions publiées, et impair pour les versions intermédiaires, expérimentales ou beta.
+ Le 4ème chiffre est le numéro de publications des sources dans le dépot SVN.
+ Ce chiffre peut être suffixé d'un "+" dans le cas d'une compilation locale dont les sources
+ ne sont pas (encore) publiés.
+
+
+
+
+
Retour
+
+
+
+
Changements réalisés pour la version 0.5
+
+
+ SVN rév. 214 :
+
+ Remplacement du paramètre de configuration Utiliser AC3 par défaut par une liste
+ déroulante présentant sept choix possibles.
+ Unification de ce choix de préférences avec celui présenté dans les enregistrements
+ programmés, effectués directement ou bien via l'EPG.
+ Les titres de menus Stopper l'enregistrement et dérivés sont remplacés par
+ Arrêter l'enregistrement , etc.
+ Ajout d'une détection des pistes AC3 et EAC3 Home Cinéma (c'est-à -dire celles qui
+ définissent plus de deux canaux audio).
+ La subdivision des items OSD du bas se fait maintenant dans la proportion 1/3 Ã gauche,
+ 2/3 à droite, les noms des pistes audio pouvant ne pas tenir dans la moitié de l'écran.
+ Corrections de bugs :
+ Les tooltips de noms d'émissions en cours dans la zone de notification n'étaient
+ pas toujours mis à jour correctement.
+ La programmation d'un enregistrement depuis l'EPG pouvait faire planter l'application
+ si le nom de l'émission était trop long.
+ Les langues des pistes audio MPEG2 n'étaient plus récupérées, ni affichées dans le menu
+ des pistes (régression remontant à la révision 175).
+ Un enregistrement devenant supplanté pouvait ne pas être mis à jour en temps réel
+ dans la boîte de dialogue de programmation.
+ Ajout d'intitulés à certains contrôles de la boîte de dialogue EPG.
+
+
+
+
+ SVN rév. 213 :
+
+ Implémentation de la recherche de tuner avancée :
+ Il n'y a plus besoin de spécifier de récepteur dans le dialogue de configuration.
+ Cette disposition devrait permettre la compatibilité du logiciel avec un plus grand nombre
+ de tuners différents.
+
+
+
+ SVN rév. 212 :
+
+ Si un filtre est manquant au moment de la configuration, son nom est préfixé des caractères
+ <?> dans la liste déroulante, afin qu'il soit visible que cet élément n'est pas valide.
+
+
+
+ SVN rév. 211 :
+
+ Utilisation des interfaces tuning space pour sélectionner les chaînes, dans le graphe
+ non alternatif .
+
+
+
+ 0.5.208 (expérimentale, publiée dans le forum le 11 novembre 2009) :
+
+ Ajout de la prise en charge des radios numériques DVB telles que celles qu'on peut avoir en Belgique.
+ Ajout d'un raccourci clavier (backspace par défaut) permettant de revenir sur la chaîne précédemment
+ regardée (s'il en existait une).
+ En cas d'absence d'icône spécifique pour une chaîne donnée, une icône générique en niveaux de gris
+ est maintenant affichée.
+ En cas d'absence d'affichage vidéo (pas de codec ou bien chaîne radio), un rendu générique (avec une croix,
+ bleue barrant l'écrant) est affiché, à la manière de ce qui existait déjà précédemment quand on désactivait le
+ rendu vidéo.
+ Correction d'un bug : l'option de désactivation de la prise en charge des touches multimédia
+ ne fonctionnait pas correctement.
+ Icône Clermont 1ère ajoutée.
+
+
+
+ 0.5.205 (expérimentale, publiée via le service de mise à jour le 6 septembre 2009) :
+
+ Correction d'un bug : en cas d'extinction de l'ordinateur sans quitter le logiciel,
+ le programme se comportait comme s'il avait été quitté anormalement.
+ Correction d'un bug : les enregistrements du multiplex entier étaient dupliqués
+ toutes les 10 minutes, jusqu'à épuisement du nombre d'enregistrements simultanés disponibles.
+ Icônes Fr3 Alpes et Fr3 Rhone ajoutées en doublon de France 3 .
+
+
+
+ 0.5.204 (expérimentale, publiée dans le forum le 2 septembre 2009) :
+
+ Correction d'un oubli : le paramètre de ligne de commande --prefix
+ n'était pas répercuté dans les tâches programmées dans le gestionnaire des tâches,
+ si on utilisait cette option dans les programmations d'enregistrements.
+ Si Pouchin TV Mod est quitté irrégulièrement (plantage …), alors
+ au démarrage suivant, un message avertit de cet état de fait et propose d'ouvrir le
+ dialogue de configuration afin de laisser la possibilité de corriger le problème.
+ Ajout de messages pour informer l'utilisateur de la nécessité, dans certaines
+ versions et/ou configurations de Windows, de lancer l'application en mode
+ administrateur si on veut pouvoir effectuer la mise à jour par Internet.
+
+
+
+ 0.5.203 (expérimentale, publiée via le service de mise à jour le 30 août 2009) :
+
+ Correction d'un bug dans la mise à jour des icônes
+
+
+
+ SVN rév. 202 :
+
+ Correction d'un bug introduit récemment, qui provoquait un plantage à l'issue
+ d'unerecherche de chaînes en présence d'un tiner nouvellement installé (aucune
+ chaîne préexistante).
+ Correction d'un bug provoquant un plantage si la fenêtre de qualité du signal est
+ ouverte pendant les redémarrages du graphe.
+ Icônes Fr3 PaysLoire et Fr3 Poitiers ajoutées en doublon de France 3 .
+
+
+
+ 0.5.201 (expérimentale, publiée dans le forum le 14 août 2009) :
+
+ Optimisation du démarrage du graphe, qui devrait être un peu plus rapide.
+ Correction d'une fuite mémoire introduite à la révision 198.
+ Icône France3 (sans espace) ajoutée en doublon de France 3 (avec espace).
+
+
+
+ SVN rév. 200 :
+
+ Utilisation d'un filtre EAC3 dédié, sélectionnable dans la configuration,
+ d'après un patch proposé par MatMaul .
+ Un rebasculement en AC3 est prévu si aucun filtre EAC3 n'existe ou n'est choisi.
+ Dans le menu des filtres, les filtres de rendu audio sont fusionnés sous une seule commande,
+ affichant les propriétés du filtre effectivement utilisé.
+
+
+
+ SVN rév. 199 :
+
+ Mise à jour du système des … euh … mises à jour de Pouchin TV Mod,
+ avec prise en charge correcte des versions 64 bits ainsi que des versions expérimentales.
+
+
+
+ 0.5.198 (expérimentale, publiée dans le forum le 24 juillet 2009) :
+
+ Dernière étape d'une importante réorganisation du code dans le graphe.
+ En cas de plantage de l'Explorateur Windows, l'icône de la barre des tâches est restaurée.
+ Ajout d'une commande clavier (Ctrl-Q par défaut) pour relancer le graphe en interne.
+
+
+
+ SVN rév. 197 :
+
+ Seconde étape d'une importante réorganisation du code dans le graphe.
+ Quelques corrections mineures.
+
+
+
+ SVN rév. 196 :
+
+ Plus de déconnexion des filtres pendant la resyntonisation, afin d'éviter des plantages.
+ Les listes de pilotes ou de codecs, dans la configuration, sont maintenant triées insensibles
+ Ã la casse.
+ Une erreur détectée pendant le changement de fréquence n'arrête plus la recherche
+ des chaînes (cette détection avait été introduite à la révision 189, mais certains tuners semblent
+ retourner une erreur alors qu'ils changent de fréquence correctement) .
+ Première étape d'une importante réorganisation du code dans le graphe.
+
+
+
+ SVN rév. 195 :
+
+ La couleur de l'affichage OSD peut maintenant être changée.
+ Possibilité de sélectionner les pistes audio par défilement, entre autres avec la molette de la souris.
+ Affichage OSD au changement de piste audio.
+
+
+
+ 0.5.194 (expérimentale, publiée dans le forum le 3 juillet 2009) :
+
+ Réduction à un seul du nombre de filtres Grabber pour les enregistrements,
+ et utilisation d'un thread pour réaliser ceux-ci, améliorant l'immunité
+ des flux enregistrés aux influences d'autres programmes sur le même ordinateur.
+ Quatre enregistrements simultanés possibles.
+
+
+
+ SVN rév. 193 :
+
+ Anticipation temporisée au changement de chaîne et de zoom.
+ Davantage de choix pour la molette de la souris.
+
+
+
+ SVN rév. 192 :
+
+ Il est maintenant possible de passer outre
+ Ã certains messages d'erreurs de conflits d'enregistrements.
+
+
+
+ SVN rév. 190 :
+
+ Deux tuners rigoureusement identiques (et donc affichant le même nom dans la configuration)
+ devraient maintenant être accessibles séparément.
+
+
+
+ SVN rév. 189 :
+
+ Ajout d'options pour la molette de la souris et les commandes multimédia.
+
+
+
+ 0.5.188 (expérimentale, publiée dans le forum le 13 juin 2009) :
+
+ Ajout du support du rendu vidéo EVR (Enhanced Video Renderer),
+ à partir d'un patch proposé par MatMaul .
+
+
+
+ SVN rév. 187 :
+
+ Plusieurs instances de l'application peuvent prendre en charge chacune un tuner différent,
+ sur le même ordinateur, grâce à une option qui permet de leur attribuer à chacun des fichiers
+ de configuration différents.
+ Le titre de la fenêtre peut maintenant être modifié dans la configuration.
+
+
+
+ 0.5.186 (expérimentale, publiée dans le forum le 28 mai 2009) :
+
+ Prise en charge des filtres gérant l'audio au format E-AC3 .
+ Implémentation d'une option permettant de revenir au graphe des versions antérieures
+ à la révision 184 , car il apparaît que pour certains utilisateurs,
+ le nouveau graphe ne marche pas alors que l'ancien fonctionnait.
+ La recherche de chaînes peut maintenant essayer deux fréquences voisines pour chaque canal,
+ avec décalage de 5 kHz (à cause de problèmes qu'ont certains tuners à gérer
+ une fréquence trop proche de la fréquence effective).
+ Ajout d'éléments de configuration supplémentaires à la recherche de chaînes.
+ Certains messages affichés dans des dialogues d'informations
+ sont assortis d'une option Ne plus afficher ce message .
+ En cas d'échec d'initialisation du rendu vidéo, l'application n'est plus quittée.
+ En lieu et place, l'affichage est désactivé avec un message d'avertissement.
+
+
+
+ 0.5.184 (expérimentale, publiée dans le forum le 5 avril 2009) :
+
+ Modification du graphe pour le rendre plus conforme à ce qui était recommandé par Microsoft
+ (utilisation du filtre Microsoft DVB-T Network Provider ).
+
+
+
+ SVN rév. 183 :
+
+ Correction de bogues divers, concernant notamment l'affichage sur clavier
+ LCD Logitech, l'EPG et le masquage de la souris en mode plein écran.
+
+
+
+ SVN rév. 182 :
+
+ L'affichage de qualité du signal gère correctement les tuners
+ qui ne donnent pas certaines informations réclamées.
+ Amélioration de la journalisation de la recherche de canaux et de l'affichage de versions.
+
+
+
+ SVN rév. 181 :
+
+ Amélioration du système qui affiche le nom de l'émission en cours.
+
+
+
+ 0.5.179 (expérimentale, publiée dans le forum le 27 mars 2009) :
+
+ Refonte complète du système de recherche de chaînes :
+ La recherche de chaînes devient paramétrable,
+ et se fait maintenant dans un thread distinct.
+ L'attribution des numéros aux chaînes non numérotées,
+ ou bien en cas de doublon, est maintenant configurable.
+ Le cas de même chaînes reçues de plusieurs émetteurs différents
+ est pris en charge plus proprement.
+ Prise en charge améliorée des multiplex (vraisemblablement étrangers)
+ qui ne contiennent pas de description des chaînes du réseau.
+ La recherche peut se faire de manière incrémentale.
+ Un fichier journal scan.log enregistre les résultats
+ des recherches successives.
+ Les indicateurs de force et de qualité du signal
+ sont répliqués dans le dialogue de recherche de chaînes.
+ On peut maintenant spécifier une liste de chaînes
+ définie manuellement pour la recherche.
+
+
+
+ SVN rév. 177 :
+
+ Indicateurs visuels de niveau de force et de qualité dans le dialogue
+ de qualité du signal.
+ L'indicateur de force de signal est calibrable dans la configuration.
+
+
+
+ SVN rév. 176 :
+
+ En cas de présence de plusieurs tuners, les paramètres spécifiques à chacun
+ d'eux sont sauvegardés séparément dans la configuration.
+ Changer de tuner provoque automatiquement la sélection du récepteur associé au nouveau,
+ s'il a déjà été utilisé auparavant.
+ Représentation plus stricte des chaînes en interne.
+ Les raccourcis clavier sont sauvegardés dans une sections distincte du fichier
+ de configuration.
+ Les tuners et codecs qui sont sélectionnés mais qui ont disparu du système restent
+ néanmoins mémorisés et affichés dans les listes déroulantes.
+ Un message d'alerte avertit alors de leur disparition.
+
+
+
+ SVN rév. 175 :
+
+ Le rafraîchissement, dans l'EPG, est limité à une fois par seconde.
+ Correction d'un bug susceptible de corrompre les enregistrements dans le cas où
+ le pilote du tuner utilisé enverrait des paquets incomplets à reconstituer
+ (merci à virtualblue sur le forum).
+ Une option de resyntonisation automatique remplace l'ancienne option
+ va-et-vient de fréquences au démarrage .
+ Correction d'un problème de relation entre certaines boîtes de dialogue et leurs fenêtres parentes.
+
+
+
+ 0.5.174 (expérimentale, publiée dans le forum le 27 février 2009) :
+
+ Le numéro de version devient 0.5 .
+ La mise à jour de la liste des programmes dans l'EPG se fait maintenant en temps réel :
+ plus besoin de presser de bouton Mettre à jour , lequel est donc, en conséquence, supprimé,
+ et remplacé par un bouton Réinitialiser , qui provoque le rechargement intégral de l'EPG.
+ Ajout de colonnes d'informations dans le dialogue de configuration des chaînes.
+ La norme de réception est affichée en clair (MPEG2 ou H264 ).
+ Ajout des icônes de chaînes belges dans l'installation.
+
+
+
+
+
Retour
+
+
+
+
Changements réalisés pour la version 0.4
+
(depuis la reprise du projet)
+
+
+ 0.4.173 (expérimentale, publiée dans le forum le 22 février 2009,
+ puis supprimée) :
+
+ Ajout du support des chaînes haute définition .
+ Les codecs peuvent être être désactivés en spécifiant le choix Aucun .
+ Le va-et-vient de fréquence est remplacé par une détection de gels du graphe,
+ provoquant une resyntonisation automatique.
+ Nouveau système de numérotation des versions :
+ numéro majeur
+ numéro mineur
+ numéro SVN
+ indice (0 ou 1 ) de modification.
+
+
+
+ SVN rév. 172 :
+
+ Ajout du numéro TSID des chaînes devant leur numéro pour
+ faire ressortir les chaînes appartenant au même multiplex.
+ Informations supplémentaires dans le dialogue À propos
+ pour mieux identifier la version compilée.
+ Correctif visant à éviter qu'un flux TS corrompu
+ puisse provoquer un plantage de l'application.
+ Correction d'un bug susceptible d'introduire
+ des corruptions du contenu de la liste des chaînes.
+
+
+
+ SVN rév. 169 :
+
+ La boîte de dialogue du Guide des Programmes est maintenant redimensionnable.
+ Ajout d'une commande Ctrl-F pour resyntoniser sur la fréquence courante
+ (permet parfois de débloquer un graphe figé).
+ Dans les contrôles de dialogue présentant des listes, on peut maintenant
+ réorganiser les colonnes (mais cette réorganisation n'est pas sauvegardée).
+
+
+
+ SVN rév. 168 :
+
+ Les changements de codecs ou de rendu vidéo
+ peuvent maintenant se faire sans avoir à relancer l'application.
+
+
+
+ SVN rév. 166 :
+
+ Ajout des modes de rendu VMR7 windowless et Aucun rendu vidéo ,
+ ce dernier mode permettant d'effectuer des enregistrements sur un ordinateur
+ de performances insuffisantes pour afficher la vidéo.
+ Ajout d'une option de configuration pour activer ou désactiver
+ le va-et-vient de fréquence au démarrage.
+
+
+
+ SVN rév. 165 :
+
+ Ajout d'un raccourci (touche Suppr. )
+ pour effacer une programmation de la liste des enregistrements programmés.
+
+
+
+ SVN rév. 164 :
+
+ Le réglage de volume a maintenant une variation logarithmique, par pas de 5 .
+ Ajout de l'option de configuration --prefix ,
+ permettant d'avoir des fichiers de configuration distincts.
+
+
+
+ SVN rév. 163 :
+
+ Le projet peut maintenant se compiler ASCII (8 bits) en plus du mode Unicode,
+ à l'aide des configuration Debug_SBCS et Release_SBCS ajoutées.
+ Correction d'un bug qui faisait disparaître les caractères accentués
+ à la fin des noms d'enregistrement programmés.
+
+
+
+ SVN rév. 160 :
+
+ Ajout d'options de configuration pour augmenter la durée
+ d'un enregistrement programmé depuis l'EPG, par le début et par la fin,
+ de manière à se prémunir des incertitudes d'horaires.
+ Suppression des configurations Vista debug et Vista release , qui
+ n'avaient plus de raison d'être.
+
+
+
+ SVN rév. 159 :
+
+ Réécriture de la gestion du Video Mixing Renderer ,
+ ainsi que de la fonction OSD .
+ Ajout de la gestion du VMR9 .
+ Activation de l'OSD en VMR9 sous Windows Vista.
+ Ajout d'une commande Utiliser toute la hauteur ,
+ contrepartie verticale de la commande Utiliser toute la largeur précédemment existante.
+
+
+
+ SVN rév. 158 :
+
+ Le fichier canaux.ini est dorénavant placé dans le répertoire Application Data .
+
+
+
+ SVN rév. 157 :
+
+ Mise à jour de la liste des canaux.
+
+
+
+ SVN rév. 152 :
+
+ Ajout d'une page de configuration de raccourcis clavier,
+ permettant de modifier les commandes données par le clavier.
+
+
+
+ SVN rév. 149 :
+
+ Prise en charge des commandes multimédia
+ (générées par certains périphériques de type clavier ou télécommande).
+
+
+
+ SVN rév. 146 :
+
+ Ajout d'une option pour spécifier le format du nom des fichiers enregistrés.
+ Les options de ligne de commande prennent deux tirets au lieu d'un.
+
+
+
+
+ SVN rév. 142 :
+
+ Ajout d'icônes pour les chaînes belges.
+
+
+
+ SVN rév. 141 :
+
+ Un changement de chaîne en mode suspendu n'a plus pour effet
+ de désuspendre l'audio et la vidéo.
+ Correction d'un bug dans l'EPG qui faisait que le bouton Enregistrer
+ ne fonctionnait qu'après modification de la sélection.
+
+
+
+ SVN rév. 140 :
+
+ Utilisation de classes ATL pour gérer les filtres,
+ sécurisant ainsi l'application contre certains types de fuites de mémoire.
+
+
+
+ SVN rév. 136 :
+
+ Amélioration du système d'affichage des erreurs :
+ les codes d'erreur numériques sont décodés pour affichage en clair,
+ et les erreur successives se cumulent dans une seule fenêtre
+ plutôt que de s'afficher successivement.
+
+
+
+ SVN rév. 133 :
+
+ Ajout de diverses options de ligne de commande : -fs , -maxi ,
+ -noborders , -normal , -recps , -rects et -ch##X .
+
+
+
+ 0.4~svn-r130 (publiée le 20 octobre 2008) :
+
+ Correction d'un bug dans la gestion des caractères non latins.
+ Ajout de diverses icônes pour des chaines locales ou frontalières.
+
+
+
+ SVN rév. 123 :
+
+ Affichage intelligible de la valeur des messages d'erreurs DirectX .
+ Ajout d'icônes de chaines locales.
+ Diverses réorganisations internes du code.
+
+
+
+ SVN rév. 117 :
+
+ Meilleur support de l'enregistrement en mode PS.
+
+
+
+ 0.4~svn-r112 (publiée le 3 janvier 2008) :
+
+ Plusieurs bugs corrigés.
+ Réorganisation interne du code.
+
+
+
+ SVN rév. 106 :
+
+ Réactivation de l'enregistrement du multiplex,
+ mais sous condition d'activer une option de configuration.
+ Refonte de la gestion des enregistrements programmés.
+ Correction d'un bug avec certains pilotes de cartes TNT.
+
+
+
+ SVN rév. 102 :
+
+ Implémentation du dialogue de réorganisation des chaînes :
+ Les chaines peuvent maintenant être renumérotées facilement en cliquant sur le numéro
+ et en en saisissant un nouveau, ou en déplaçant la chaine dans la liste.
+ Les chaînes peuvent être déclarées Actives ,
+ Inactives ou Préférées , grâce à un menu contextuel :
+ les chaînes Préférées peuvent être sélectionnées par flèches haut et bas,
+ molette de souris ou par menu, alors que les chaînes Actives
+ ne peuvent être sélectionnées que par menu.
+ En maintenant la touche SHIFT pressée au démarrage de l'application,
+ on forcera l'ouverture du dialogue de configuration (utile dans le cas où
+ la configuration courante fait planter l'application avant même d'avoir accès aux menus).
+ Liste des canaux mis à jour au 5 octobre 2007.
+ Modification de la gestion de l'offset.
+
+
+
+ SVN rév. 98 :
+
+ Plusieurs améliorations au niveau de la recherche de chaînes
+ ainsi que des enregistrements programmés.
+
+
+
+ SVN rév. 92 :
+
+ Modification de la configuration, en utilisant des onglets,
+ et rassemblement des options par cathégorie.
+
+
+
+ 0.4~svn-r87 (publiée le 4 octobre 2007) :
+
+ Correction pour le plantage qui se produisait à la fin d'un scan des chaînes
+ lors d'une nouvelle installation et de l'utilisation de DScaler .
+ Suppression de l'option multiplex dans le guide des programmes.
+ Disparition du curseur de la souris en mode plein écran rétablie.
+ Réactivation de l'arrêt programmé de Pouchin TV Mod à la fin d'un enregistrement.
+ Réaffiche les icones des chaînes à la suite d'une nouvelle recherche.
+ Retire la fenêtre du premier plan lorsque l'on supprime l'option.
+ Correctif pour le démarrage minimisé qui ne marchait plus correctement.
+ Réorganisation interne du code.
+
+
+
+ 0.4~svn-r83 (publiée le 28 septembre 2007) :
+
+ Correction de bogues pour l'enregistrement concurentiel.
+
+
+
+ SVN rév. 78 :
+
+ Supporte maintenant un nombre de multiplex variable : de R1 Ã R99 (max).
+ Corrections pour la gestion des différentes modes de fenêtre de Pouchin TV Mod.
+ Vérifie si les dossiers de sauvegarde des enregistrements et des captures
+ existent au lancement, et demande quoi faire si non.
+ Amélioration du support des systèmes Windows 64 bits.
+
+
+
+ SVN rév. 72 :
+
+ Support de la répétition des enregistrements
+ (tous les Lundi , Mardi et Vendredi par exemple) .
+ Le choix de la ville à utiliser se fait maintenant dans la fenêtre de scan.
+ Réorganisation interne du code.
+
+
+
+ SVN rév. 68 :
+
+ Il n'est plus nécessaire d'effacer le fichier config.ini .
+ Pouchin TV Mod repropose la configuration plutôt.
+
+
+
+ SVN rév. 60 :
+
+ Affichage des chiffres au fur et à mesure de la saisie.
+
+
+
+ SVN rév. 58 :
+
+ Ajout des icônes des chaines dans les menus.
+
+
+
+ 0.4~svn-r57 (publiée le 15 septembre 2007) :
+
+ Recherche de mise à jour sur internet.
+ Ajout d'une fonction permettant de ré-actualiser la liste des chaînes depuis Pouchin TV Mod ,
+ et ce, en choisissant ou non de conserver les modifications.
+ Correction d'un bug de longue date (Pouchin TV original)
+ empêchant de récupérer le numéro de la chaîne.
+ Correction d'un bug conduisant à refaire une recherche des canaux à chaque démarrage,
+ suite à l'ajout de France Ô aux chaines (caractères accentués).
+ Diverses corrections de bugs.
+
+
+
+ SVN rév. 49 :
+
+ Les boites de dialogues Qualité du signal… , Guide des programmes… ,
+ Enregistrements programmés… sont non modales.
+ Ajout d'information sur le programme en cours dans le systray.
+ Diverses corrections de bugs.
+
+
+
+ SVN rév. 45 :
+
+ Remplacement de la fonction permettant d'enregistrer un multiplex
+ par la possibilité d'enregistrer plusieurs chaines (jusqu'à 3) du multiplex.
+ Le fichier canaux.ini est maintenant extrait des ressources.
+ Changement des répertoires par défaut pour les sauvegardes des images et des vidéos.
+ Diverses corrections de bugs.
+
+
+
+ 0.4~svn-r42 (publiée le 29 août 2007) :
+
+ Correction de plusieurs bugs.
+ Ajout de la liste des contributeurs à la fenêtre À propos… .
+ les fichiers de configs sont maintenant stockés dans le profil de l'utilisateur,
+ C:\Documents And Settings\Utilisateur\Application Data\Pouchin TV Mod
+ par exemple, ce qui devrait résoudre tous les problèmes pour les
+ télécommandes, de partage d'ordinateur, ou de droits d'accès.
+
+
+
+ 0.4~svn-r38 (publiée le 28 août 2007) :
+
+ Correction d'un bug sous Vista empêchant l'affichage correct des fenêtres.
+ Changement de l'icône de Pouchin TV Mod lorsque l'on enregistre.
+ Changement de place pour l'indication du volume.
+ Suppression des dépendances.
+ Maintenant, la seule chose indispensable à installer est Pouchin TV Mod .
+
+
+
+ 0.4~svn-r25 (publiée le 18 août 2007) :
+
+ Correction d'un bug lorsque l'on coupait le son.
+ Fusion des version pour 2000/XP et la version de Vista en une seule.
+
+
+
+ 0.4~svn-r23 (publiée le 17 août 2007) :
+
+ Ajout des raccourcis claviers dans les menus.
+ Ajout d'une fonction demandant confirmation si on quitte
+ Pouchin TV Mod et qu'un enregistrement est en cours.
+
+
+
+ 0.4~svn-r18 (publiée le 15 août 2007) :
+
+ Fusion des modifs
+ effectuées
+ par radius pour Vista :
+ Comme il n'y a plus d'OSD , affiche le volume dans la barre des
+ status (barre du bas).
+ Correction d'un bug lors de la gestion des bandes noires et commutation 4/3 <-> 16/9.
+
+ ajout d'une option Programme / Muet si minimisé pour
+ activer / désactiver le son de Pouchin TV quand on le minimise.
+ modification de l'agencement des menus et des boites de
+ dialogues.
+
+
+
+ 0.4~svn-r16 (publiée le 15 août 2007) :
+
+ correction d'un bug lors de la sauvegarde de l'enregistrement
+ dans le planificateur des tâches, dont le nom contient des
+ caractères invalide.
+ ajout de la priorité Temps réel au programme.
+ gestion de l'option arrêter le PC à la fin de
+ l'enregistrement .
+
+
+
+
+
Retour
+
+
+
+
+
+
+ 0.4 RC2 (publiée le 18 juin 2007) :
+
+
+
+ 0.4 RC1 :
+
+ Correction de bugs.
+ Si pas de gros bugs, dernière version avant la stable.
+
+
+
+ 0.4 beta3 :
+
+ Correction de bugs.
+ Possibilité de programmer la fin d'un enregistrment après l'avoir lancé
+ (Stopper l'enregistrement dans … ).
+ Option pour étirer la vidéo.
+ Ajout d'une version compatible Vista (sans OSD).
+ Nouvelle icône, merci à korse2a .
+
+
+ 0.4 beta2a :
+
+ Fix d'un bug qui faisait planter le programme dès qu'un enregistrement était programmé.
+
+
+
+ 0.4 beta2 :
+
+ Ajout d'une option pour arrêter le logiciel après un enregistrement programmé.
+ Support des tâches planifiées de Windows.
+
+
+
+ 0.4 beta1 :
+
+ Correction de quelques bugs.
+ Quelques modifications graphiques.
+
+
+
+ 0.4 alpha2 :
+
+ Correction du bug qui faisait que seul le premier enregistrement programmé fonctionnait.
+
+
+
+ 0.4 alpha1 :
+
+ Première version du Mod . Les nouveautés par rapport à la version 0.3a sont :
+ Programmation des enregistrements,
+ mon code étant largement inspiré du mod de jmblot , merci à lui.
+ Minimiser dans le system tray : quand Pouchin est minimisé, il stoppe le son,
+ la vidéo, et ne prend presque plus de processeur
+ → on peut programmer des enregistrements et laisser Pouchin dans le system tray.
+ Sauvegarde du volume.
+ Refonte totale de la gestion des pistes :
+ affichage de la langue de la piste, pistes dans un menu à part,
+ gestion d'un nombre de pistes virtuellement illimité.
+ Quand on enregistre en TS ca enregistre toutes les pistes de la chaîne et non pas que l'audio sélectionné
+ (même les flux de sous-titres sont enregistrés bien qu'ils n'apparaissent pas dans Pouchin ).
+ Fix de ef15c pour le support de la Nova T Stick (merci à lui).
+
+
+
+
+
+
Retour
+
+
+
+
Changements réalisés par le créateur de la version originale
+
(dénommée PouchinTV )
+
+
+ 0.3a (publiée le 28 mai 2006) :
+
+ Correction de la vidéo qui ne s'affiche que sur le 1er écran en dual screen.
+
+
+
+ 0.3 (publiée le 5 mai 2006) :
+
+ Possibilité d'enregistrer en MPEG2 PS .
+ OSD simple : nom de la chaîne et du programme, sourdine, volume, zoom.
+ PouchinTV a maintenant absolument besoin de l'overlay pour fonctionner (conséquence de l'OSD ).
+ Plus besoin de scanner pendant les heures où Canal+ , TPS star et Paris Première
+ diffusent en clair pour tout avoir, PouchinTV est capable de récupérer les PID en dynamique.
+ Option pour switcher directement en AC3 sur les chaînes qui le proposent.
+ Réglage du volume avec + et - .
+ Zoom réglable avec Z /Maj-Z .
+ Correction bug enregistrement sur Nova-t Usb2 .
+ Fenêtre d'EPG : le programme en cours est choisi par défaut,
+ double clic permet de zapper sur une chaîne.
+ Correction plein écran sur systèmes dual screen.
+ Version pour XP64 (non testée !).
+ Option pour que l'image utilise toute la largeur de la fenêtre :
+ utile pour les films 16/9 ou + diffusés sur une chaine en 4/3 avec un écran large.
+ Sauve/restaure la taille et position de la fenêtre.
+ Propose l'offset à 166 pour les Hauppauge , et 167 pour les Terratec …
+ Option dans le .ini pour utliser le désentrelacement hardware du VMR :
+ le codec vidéo doit supporter ce mode.
+
+
+
+ 0.2b (publiée le 13 mars 2006) :
+
+ L'offset passe à 167 par défaut, et est réglable dans canaux.ini .
+ Devrait fixer le problème de la Terratec Cynergy T2 .
+
+
+
+ 0.2a (publiée le 12 mars 2006) :
+
+ Corrige scan complet sans préciser de ville,
+ sauvegarde Always on top dans les préférences.
+
+
+
+
+ 0.2 :
+
+ Correction des problèmes de compatibilité avec les clés USB, et les cartes qui ont besoin de 166 en offset.
+ Sélection de la carte TNT pour ceux qui en ont plusieurs installées.
+ Affiche le nom du programme en cours et de celui qui suit, ainsi que leurs horaires.
+ Fenêtre d'EPG avec les progammes en cours sur toutes les chaînes.
+ Peut afficher le nom du programme regardé sur MSN Messenger .
+ Dialogue affichant la qualité du signal.
+ Fonction Always on top .
+ Affichage minimum (pas de menu, juste la vidéo), en faisant un clic gauche sur la zone vidéo.
+ Peut définir la priorité du programme.
+ Menu contextuel sur la zone vidéo.
+
+
+
+ 0.1 (publiée le 4 mars 2006) :
+
+ Première version publiée de Pouchin TV .
+
+
+
+
+
Retour
+
+
+
+ Dernière modification de cette page :
+
+
+
Property changes on: tags/pouchintv_mod-0.6.0/changelog.html
___________________________________________________________________
Ajouté : svn:eol-style
+ native
Modifié: tags/pouchintv_mod-0.6.0/graph.cpp
===================================================================
--- tags/pouchintv_mod-0.6.0/graph.cpp 2010-01-20 22:46:09 UTC (rev 231)
+++ tags/pouchintv_mod-0.6.0/graph.cpp 2010-01-20 23:27:56 UTC (rev 232)
@@ -1252,6 +1252,12 @@
pTailFilter = sNetworkProvider.pFilter;
+ if (SUCCEEDED(hr)) {
+ // Nécessaire à certains tuners
+ HRESULT hr2 = change_frequence(-1, -1);
+
+ myprintf(CMyP ERRX(TEXT("Erreur : sélection fréquence impossible, hr=0x%x")), FAILED(hr2), hr2);
+ }
return hr;
}
@@ -1278,7 +1284,9 @@
HRESULT CMicrosoftTunerGraph::change_frequence(LONG nFreq, LONG nBandwidth, const ChaineIDs * pChIDs, tstring * pstrErr)
{
HRESULT hr;
- CDVBTTuneRequest cTuneRequest(cTuningSpace, nFreq+offset_tuner, nBandwidth,
+ CDVBTTuneRequest cTuneRequest(cTuningSpace,
+ nFreq >= 0 ? nFreq+offset_tuner : nFreq,
+ nBandwidth,
pChIDs ? pChIDs->ONID : -1,
pChIDs ? pChIDs->TSID : -1,
pChIDs ? pChIDs->SID : -1,
Modifié: tags/pouchintv_mod-0.6.0/ini.cpp
===================================================================
--- tags/pouchintv_mod-0.6.0/ini.cpp 2010-01-20 22:46:09 UTC (rev 231)
+++ tags/pouchintv_mod-0.6.0/ini.cpp 2010-01-20 23:27:56 UTC (rev 232)
@@ -311,6 +311,9 @@
{NULL, 0} // -> terminateur
};
+/**
+ * Tableau associatif décrivant les différents types de flux vidéo reconnus
+ **/
AssocElement aVideoTypeTable[] =
{ // VideoStreamType
{TEXT("MPEG2"), vst_MPEG2},
@@ -1551,11 +1554,11 @@
UINT nr_multiplex = 1;
do {
_stprintf_s(id_multiplex, _countof(id_multiplex), TEXT("R%d"), nr_multiplex);
- canal_no = (BYTE)cChanFile.load_int(id_multiplex, 0);
- if (canal_no != 0)
+ canal_no = (BYTE)cChanFile.load_int(id_multiplex, 0xff);
+ if (canal_no != 0 && canal_no != 0xff)
add(canal_no);
nr_multiplex++;
- } while (canal_no != 0 && nr_multiplex <= 99);
+ } while (canal_no != 0xff && nr_multiplex <= 99);
}
}
@@ -1893,8 +1896,8 @@
canal.pmt_pid = (WORD)pNode->getInt(TEXT("PMT"));
canal.pcr_pid = (WORD)pNode->getInt(TEXT("PCR"));
-// Désactivation optionnelle des informations sur les flux vidéo, son et autre
-#if STREAMS_SAVE_ALL
+ // Désactivation optionnelle des informations sur les flux vidéo, son et autre
+ #if STREAMS_SAVE_ALL
// Détermine le type de flux vidéo
pNode->getStr(TEXT("Video_type"), var, _countof(var));
canal.video_type = (VideoStreamType)str2dword(aVideoTypeTable, var, vst_Unknown);
@@ -1912,7 +1915,7 @@
lit_pistes(*pNode, canal.sons, TEXT("Son"));
// Récupère les autres informations
lit_pistes(*pNode, canal.autr, TEXT("Autre"));
-#endif
+ #endif // #if STREAMS_SAVE_ALL
// Mémorise le canal généré
Canaux.push_back(canal);
@@ -1944,7 +1947,7 @@
oxml.put(oxml.fmt("%s%i_Lang", pszTagStr, j), sPiste.lang);
}
}
-#endif
+#endif // #if STREAMS_SAVE_ALL
/**
* Sauvegarde de la liste des chaînes dans "chaines.xml".
@@ -1995,7 +1998,7 @@
sauve_pistes(oxml, canal.sons, "Son");
// Mémorise toutes les autres informations
sauve_pistes(oxml, canal.autr, "Autre");
-#endif
+#endif // #if STREAMS_SAVE_ALL
}
}
Modifié: tags/pouchintv_mod-0.6.0/recprog.cpp
===================================================================
--- tags/pouchintv_mod-0.6.0/recprog.cpp 2010-01-20 22:46:09 UTC (rev 231)
+++ tags/pouchintv_mod-0.6.0/recprog.cpp 2010-01-20 23:27:56 UTC (rev 232)
@@ -1,2022 +1,2024 @@
-/*
- * recprog.cpp
- * Copyright (C) 2007 gingko - http://gingko.homeip.net/
- *
- * This file is part of Pouchin TV Mod, a free DVB-T viewer.
- * See http://pouchintv.baysse.fr/ for updates.
- *
- * Pouchin TV Mod is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Pouchin TV Mod is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- *
- * Most files of this project have been changed from the Pouchin TV
- * project (Copyright (C) 2006 Pouchin ),
- * to use with a modified version of this software.
- * See http://pouchinteve.free.fr/ for the original project.
- */
-
-#include "recprog.h"
-#include "base.h"
-#include "channels.h"
-#include "record.h"
-#include "main.h"
-#include "utils.h"
-//
-#include
-#include
-#include // pour 'sort'
-
-/**
- * Délai de grâce pour l'arrêt après enregistrement : si, à l'arrêt d'un enregistrement, un
- * autre enregistrement est programmé dans un délai plus court que le délai spécifié, alors
- * les options d'arrêt du programme ou d'extinction de l'ordinateur sont ignorées.
- * \todo Rendre ceci configurable par l'utilisateur.
- **/
-#define DUREE_GRACE_QUIT 30 // Valeur en minutes
-
-/**
- * En cas d'arrêt programmé de l'application et/ou de l'ordinateur à l'issue d'un enregistrement,
- * le délai suivant est appliqué avant l'exécution effective de l'arrêt, afin de garantir une
- * terminaison propre de l'enregistrement.
- **/
-#define DUREE_QUIT 2000 // Valeur en millisecondes
-
-/**
- * Marge pour le calcul des recouvrements de programmations :
- * Deux programmations doivent être séparées par au moins ce temps
- * (en millisecondes) pourqu'il soit considéré qu'elles ne se superposent pas.
- **/
-#define DUREE_MARGE_RECOUVREMENT 2500 // Valeur en millisecondes
-
-/**
- * Liste des enregistrements programmés
- **/
-std::vector Programmes;
-
-static HWND hRecordDlg = NULL;
-static WCHAR mdp[256] = L"";
-
-// Variables utilisées pendant les modifications des contrôles date et heure pour tester la
-// différence entre le début et la fin ainsi que la différence avec la valeur avant changement :
-static SYSTEMTIME dtc_debut = {0};
-static SYSTEMTIME dtc_fin = {0};
-
-/**
- * On passe une clé de chaîne en paramètre,
- * et on retourne la fréquence du multiplex correspondant
- **/
-static INT32 getFrequence_par_cle(UINT32 cleChaine)
-{
- int ixChaine = Canaux.trouve_par_cle(cleChaine);
-
- if (ixChaine >= 0)
- return Canaux[ixChaine].khz;
-
- return -1;
-}
-
-/**
- * Fonction “callback” de traitement de la saisie du mot de passe requis lors de l'ajout d'une
- * tâche dans le planificateur de tâches
- **/
-static INT_PTR CALLBACK PaswdDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
- switch (uMsg) {
- case WM_INITDIALOG:
- return TRUE;
-
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
-
- case IDOK: {
- TCHAR buffer[128];
-
- *reinterpret_cast(&buffer[0]) = _countof(buffer);
-
- UINT nLen = (UINT)SendDlgItemMessage(hwndDlg, IDC_PASWD, EM_GETLINE, 0, (LPARAM)buffer);
-
- buffer[nLen] = 0; // (selon la doc, EM_GETLINE n'ajouterait pas toujours le zéro terminateur)
- strcpy_T(mdp, buffer);
- EndDialog(hwndDlg, 0);
- return TRUE; }
-
- case IDCANCEL:
- EndDialog(hwndDlg, 1);
- return TRUE;
- }
- return FALSE;
-
- default:
- return FALSE;
- }
-}
-
-/**
- * Saisie du mot de passe requis lors de l'ajout d'une tâche dans le planificateur de tâches
- **/
-static bool taskLogon(HWND hDlg, LPCWSTR username)
-{
- // Vérifie le login, et demande le mot de passe si besoin est
- bool identifie = false;
-
- HANDLE session;
- do {
- identifie = LogonUserW(username, NULL, mdp,
- LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &session)==TRUE;
- if (identifie)
- break;
-
- // Saisie du mot de passe, et reboucler si pas d'annulation :
- mdp[0] = 0; // (vider la saisie précédente)
- } while (DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_PASWD), hDlg, PaswdDialogProc)==0);
-
- CloseHandle(session);
-
- return identifie;
-}
-
-/**
- * Tableau de chaînes affichables correspondant aux différents états possibles
- * d'un enregistrement programmé
- **/
-const LPCTSTR Programme::t_states[] =
-{
- TEXT("Attente"),
- TEXT("En cours"),
- TEXT("Désactivé"),
- TEXT("Interrompu"),
- TEXT("Supplanté"),
- TEXT("Terminé"),
- TEXT("Erreur")
-};
-
-/// Constructeur
-Programme::Programme()
-{
- apres = apr_rien;
- memset(&debut, 0, LPBYTE(this)+sizeof(*this)-LPBYTE(&debut));
- etat = epr_inactif;
-}
-
-
-/// Retourne \p true si intersection temporelle avec la programmation \p p2
-bool Programme::overlap(const Programme & p2) const
-{
- // avec 1000 millisecondes de marge
- return
- DiffTime(fin, p2.debut) >= DUREE_MARGE_RECOUVREMENT &&
- DiffTime(p2.fin, debut) >= DUREE_MARGE_RECOUVREMENT;
-}
-
-/**
- * \brief Comparaison en vue de tri sur l'heure de début
- *
- * Utilisé par la fonction std::sort
- * \retval \p true si cette programmation se classe avant la programmation \p p2 dans le temps.
- **/
-bool Programme::operator < (const Programme & p2) const
-{
- return DiffTime(debut, p2.debut)<0;
-}
-
-/**
- * \brief Calcul du temps restant avant début enregistrement en millisecondes.
- *
- * \param[in] localtime Heure de référence (en principe l'heure système)
- **/
-long Programme::temps_restant(const SYSTEMTIME & localtime) const
-{
- if (!active() || DiffTime(localtime, fin)>=0)
- return DUREE_INFINIE; // La programmation est inactive ou l'heure de fin est dépassée
-
- long reste = DiffTime(debut, localtime);
-
- return max(reste, 0);
-}
-
-/**
- * \brief Ajustement des données si répétitions programmées et horaire de fin dépassé
- *
- * \param[in] localtime Heure de référence (en principe l'heure système)
- * \retval \p true si un ajustement a eu lieu
- **/
-bool Programme::ajustementDesRepetitions(const SYSTEMTIME & localtime)
-{
- bool res = false;
-
- if (repetition != 0 && etat != epr_inactif) {
- // En cas de répétition, tous les enregistrements non explicitement marqués comme
- // "inactifs" sont reconduits et réactivés dès lors que l'heure de fin est dépassée
-
- while (DiffTime(localtime, fin) >= 0) { // Tant que l'heure de fin est dépassée
- int nbJours;
-
- // Trouver le nombre de jours avant la répétition suivante :
- for (nbJours=1; (repetition & (1<<((debut.wDayOfWeek + nbJours) % 7)))==0; nbJours++);
-
- long to_add = nbJours * 24 * 60 * 60 * 1000; // Conversion en millisecondes
-
- AddTime(debut, to_add);
- AddTime(fin, to_add);
-
- /// \todo Il faudrait vérifier d'une façon ou d'une autre qu'une transition
- /// heure d'été <-> heure d'hiver intempestive ne risque pas d'introduire un
- /// décalage d'une heure dans la programmation à cet endroit.
-
- etat = epr_actif; // réactivation
- programmation_modifiee = true;
- res = true;
-
- // Note : on revérifie en bouclant sur le test de différence de temps pour parer au cas
- // où celui-ci serait effectué alors que le programme n'a pas été exécuté pendant un délai
- // excédant plusieurs répétitions consécutives.
- }
- }
- return res;
-}
-
-/**
- * Affichage du message d'avertissement en cas de conflit dans une programmation
- * \param[in] pszMessage Texte du message à afficher
- * \return \p true ou \p false selon que l'utilisateur souhaite néanmoins poursuive ou pas
- **/
-bool Programme::warn_prog(LPCTSTR pszMessage)
-{
- tstring strMsg(pszMessage);
-
- strMsg += EOL TEXT("Voulez-vous quand même effectuer cette programmation ?");
-
- if (MessageBox(hMainWnd, strMsg.c_str(), TEXT("Avertissement"), MB_YESNO|MB_ICONWARNING)==IDNO)
- return false;
- return true;
-}
-
-/**
- * \brief Vérification de la validité de la programmation
- *
- * \param[in] prog_modif Si non NULL, pointeur sur la programmation qu'on modifie (pour
- * éviter de la comparer à elle-même lors des tests de recouvrement)
- * \retval \p true ou \p false selon succès ou échec, respectivement
- **/
-bool Programme::verifie(const Programme * prog_modif) const
-{
- int ixChaine = Canaux.trouve_par_cle(cleChaine);
- SYSTEMTIME localtime;
-
- if (ixChaine<0) {
- affiche_erreurs(TEXT("La chaîne est incorrecte"));
- return false;
- }
-
- GetLocalTime(&localtime);
-
- long duree = DiffTime(fin, debut);
-
- if (duree < 0) {
- affiche_erreurs(TEXT("Le programme commence après avoir fini !"));
- return false;
- }
-
- if (duree == 0) {
- affiche_erreurs(TEXT("La durée de l'enregistrement est nulle !"));
- return false;
- }
-
- if (duree > 12*60*60*1000) {
- affiche_erreurs(TEXT("La durée de l'enregistrement dépasse 12 heures !"));
- return false;
- }
-
- if (DiffTime(fin, localtime) < 0 &&
- !warn_prog(TEXT("L'heure de fin du programme est dépassée !")) )
- return false;
-
- if (nom[0] == 0) {
- affiche_erreurs(TEXT("Veuillez donner un nom à ce programme"));
- return false;
- }
-
- const Chaine & canal = Canaux[ixChaine];
-
- if (methode==meth_PS && canal.video_type!=vst_MPEG2) {
- affiche_erreurs(
- TEXT("L'enregistrement d'une chaîne H264 (cas de la haute définition) ")
- TEXT("en mode PS n'est pas encore implémenté"));
- return false;
- }
-
- int nbProgrammes = (int)Programmes.size();
-
- for(int i = 0; i < nbProgrammes; i++) {
- const Programme & prog_verif = Programmes[i];
-
- if (&prog_verif ==prog_modif)
- continue; // Ne pas comparer la programmation à celle en cours de modification
-
- if (_tcscmp(prog_verif.nom, nom) == 0) {
- affiche_erreurs(TEXT("Ce nom est déjà utilisé"));
- return false;
- }
-
- if (prog_verif.active() && overlap(prog_verif)) {
- // Chevauchement des horaires :
-
- // Vérifier qu'on n'a pas programmé plusieurs fois la même chaîne au même moment :
- if (cleChaine==prog_verif.cleChaine &&
- isMultiplex()==prog_verif.isMultiplex() &&
- !warn_prog(
- tstr_printf(
- TEXT("Chevauchement des horaires avec \"%s\", qui concerne la même chaîne !"),
- prog_verif.nom).c_str()) )
- return false;
-
- // Vérifie que le programme chevauchant est sur le même multiplex :
- if (getFrequence_par_cle(prog_verif.cleChaine) != canal.khz) {
- int ixChaine2 = Canaux.trouve_par_cle(prog_verif.cleChaine);
-
- if (ixChaine_ok(ixChaine2) &&
- !warn_prog(
- tstr_printf(
- TEXT("Chevauchement des horaires avec \"%s\" sur %") A2t
- TEXT(", qui ne partage pas le même multiplex !"),
- prog_verif.nom,
- Canaux[ixChaine2].nom).c_str()) )
- return false;
- }
- }
- }
-
- return true; // pas d'erreur
-}
-
-/**
- * \brief Génération du nom de tâche programmée correspondant
- *
- * \param[in] pstr Pointeur sur le tampon qui va recevoir le nom
- * \param[in] bufSize Taille de ce tampon
- **/
-void Programme::genereNomTache(LPWSTR pstr, UINT bufSize) const
-{
- TCHAR szTmp[256];
-
- if (*prefix_conf)
- _stprintf_s(szTmp, TEXT("PTV[%s]-%s") , prefix_conf, nom);
- else
- _stprintf_s(szTmp, TEXT("PTV-%s"), nom);
-
- // Remplace les caractères incorrects :
- NomProtege nom_tache(szTmp, TCHAR('_'));
-
- // On convertit le nom de la tâche en Unicode (s'il ne l'est pas déjà) :
- nom_tache.Extract(pstr, bufSize);
-}
-
-/**
- * \brief Ajout de cette programmation aux tâches programmées
- *
- * \param[in] username Nom d'utilisateur
- * \param[in] motdepasse Mot de passe
- * \retval \p true ou \p false selon succès ou échec, respectivement
- **/
-bool Programme::ajouterTacheProgrammee(LPCWSTR username, LPCWSTR motdepasse) const
-{
- WCHAR taskName[_countof(nom)+4];
- SYSTEMTIME date = debut;
- CComPtr pTask;
- HRESULT hr;
-
- AddTime(date, -60*1000); // Soustraire 60 secondes
-
- // On génère le nom de la tâche :
- genereNomTache(taskName, _countof(taskName));
-
- // Accède au planificateur pour supprimer la tâche si elle existe
- {
- CComPtr pITS;
-
- hr = pITS.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER);
- if (FAILED(hr)) {
- myprintf(TEXT("Erreur init task scheduler") EOL);
- return false;
- }
- // Supprime la tâche
- pITS->Delete(taskName);
-
- // Crée la nouvelle tâche
- hr = pITS->NewWorkItem(taskName, CLSID_CTask, IID_ITask, (IUnknown**)&pTask);
- }
-
- if (FAILED(hr)) {
- myprintf(TEXT("Erreur création tâche %s") EOL, taskName);
- return false;
- }
-
- wchar_t szTmp[MAX_PATH];
-
- // Définition de la tâche
- GetModuleFileNameW(NULL, szTmp, _countof(szTmp));
- pTask->SetApplicationName(szTmp);
-
- swprintf_s(szTmp, L"--minimize%" T2w, GetInstancePrefix().c_str());
- pTask->SetParameters(szTmp);
-
- GetCurrentDirectoryW(_countof(szTmp), szTmp);
- pTask->SetWorkingDirectory(szTmp);
-
- hr = pTask->SetAccountInformation(username, motdepasse);
- if (SUCCEEDED(hr)) {
- WORD piNewTrigger;
- CComPtr pTaskTrigger;
-
- pTask->SetFlags(TASK_FLAG_DELETE_WHEN_DONE | TASK_FLAG_SYSTEM_REQUIRED);
- pTask->SetMaxRunTime(INFINITE);
- pTask->CreateTrigger(&piNewTrigger, &pTaskTrigger);
-
- TASK_TRIGGER Trig = {
- sizeof(Trig), // cbTriggerSize
- 0, // Reserved1
- date.wYear, // wBeginYear
- date.wMonth, // wBeginMonth
- date.wDay, // wBeginDay
- 0, // wEndYear
- 0, // wEndMonth
- 0, // wEndDay
- date.wHour, // wStartHour
- date.wMinute, // wStartMinute
- 0, // rgFlags
- TASK_TIME_TRIGGER_ONCE // TriggerType (Pas de répétition de la tâche, par défaut)
- // le reste à zéro (implicite)
- };
-
- if (repetition!=0) {
- // On a demandé à ce que la tâche soit répétée
- Trig.TriggerType = TASK_TIME_TRIGGER_WEEKLY;
-
- WEEKLY & jours = Trig.Type.Weekly;
-
- jours.WeeksInterval = 1; // Répète toutes les semaines
- jours.rgfDaysOfTheWeek = 0;
-
- static const BYTE repFlgs[7] =
- {TASK_SUNDAY, TASK_MONDAY, TASK_TUESDAY, TASK_WEDNESDAY,
- TASK_THURSDAY, TASK_FRIDAY, TASK_SATURDAY};
-
- for (int i=0; i<7; i++) {
- if ((repetition & (1<SetTrigger(&Trig);
-
- CComQIPtr pPersistFile(pTask);
-
- if (pPersistFile)
- pPersistFile->Save(NULL, TRUE);
- }
-
- return true;
-}
-
-/**
- * \brief Ajout de la programmation si nécessaire, incluant identification
- *
- * \param[in] hDlg Handle du dialogue parent
- * \retval \p true ou \p false selon succès ou échec, respectivement
- **/
-bool Programme::ajoutTacheAvecLogon(HWND hDlg)
-{
- // Par précaution, détruire d'abord toute tâche antérieurement existante portant
- // le nom demandé :
- supprimerTacheProgrammee();
-
- if (etat==epr_actif && tache == planif_ajout) {
- WCHAR username[256];
- DWORD iLen = _countof(username);
-
- GetUserNameW(username, &iLen); // Obtenir le nom de l'utilisateur courant
-
- if (taskLogon(hDlg, username)) {
- if (ajouterTacheProgrammee(username, mdp)) {
- tache = planif_avec;
- return true;
- }
- } else {
- tache = planif_sans;
- CheckDlgButton(hDlg, IDC_TACHE, BST_UNCHECKED);
- MessageBox(hDlg, TEXT("Vous n'avez pas saisi de mot de passe valide :") EOL
- TEXT("Cet enregistrement va être programmé sans ajout au gestionnaire des tâches."),
- TEXT("Saisie de mot de passe annulée"), MB_ICONINFORMATION | MB_OK);
- }
- }
- return false;
-}
-
-/**
- * \brief Suppression de cette programmation de la liste des tâches programmées
- *
- * \retval \p true ou \p false selon succès ou échec, respectivement
- **/
-bool Programme::supprimerTacheProgrammee() const
-{
- WCHAR taskName[_countof(nom)+4];
-
- // On génère le nom de la tâche :
- genereNomTache(taskName, _countof(taskName));
-
- CComPtr pITS;
-
- HRESULT hr = pITS.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER);
- if (FAILED(hr)) {
- myprintf(TEXT("Erreur init task scheduler") EOL);
- return false;
- }
-
- // Supprime la tâche
- pITS->Delete(taskName);
- return true;
-}
-
-/**
- * Traitement du chargement de la liste des programmes au démarrage, et purge
- * des enregistrements périmés
- **/
-void init_programmation()
-{
- // Charge la liste des programmes
- lit_programmes();
-
- SYSTEMTIME localtime;
- GetLocalTime(&localtime);
- int i = 0;
- while (i < (int)Programmes.size()) {
- Programme & prog = Programmes[i];
- long diff = DiffTime(prog.fin, localtime);
-
- if (diff <= 0) {
- // On efface les programmes sans répétitions dont l'heure de fin est passée
- if (prog.repetition==0) {
- Programmes.erase(Programmes.begin()+i);
- programmation_modifiee = true;
- continue; // L'enregistrement courant ayant été supprimé, on n'incrémente pas 'i'
- }
-
- // Le cas échéant, on calcule la répétition suivante
- // (mais ça a probablement déjà été fait ailleurs)
- prog.ajustementDesRepetitions(localtime);
- }
- i++;
- }
-
- // Mises à jour éventuelles au cas où les opérations
- // précédentes auraient modifié la programmation
- record_list_updated();
-}
-
-/**
- * Trouver l'index d'un enregistrement programmé à partir de son nom.
- *
- * \param[in] nom Nom de l'enregistrement recherché
- * \retval Index numérique de l'enregistrement
- * \retval -1 si nom vide ou rien trouvé.
- **/
-int trouve_prog_par_nom(LPCTSTR nom)
-{
- if (nom && nom[0] != 0) {
- int nbProgrammes = (int)Programmes.size();
-
- for (int i=0; i= -(60-1) && diff <= -(60-20)) {
- // On a incrémenté les secondes mais reculé de (60-20) à (60-1) secondes
- if (tempres.wSecond < 20)
- toAdd = 60;
- } else if (diff >= -(60-1)*60 && diff <= -(60-20)*60) {
- // On a incrémenté les minutes mais reculé de (60-20) à (60-1) minutes
- if (tempres.wMinute < 20)
- toAdd = 60*60;
- } else if (diff == -(24-1)*60*60) {
- // On a incrémenté les heures mais reculé de (24-1) heures
- if (tempres.wHour < 1)
- toAdd = 24*60*60;
- }
- }
- } else {
- // On a avancé dans le temps
-
- if (GetAsyncKeyState(VK_LBUTTON)<0 || GetAsyncKeyState(VK_SUBTRACT)<0 || GetAsyncKeyState(VK_DOWN)<0) {
- // Traitement seulement si le bouton gauche de la souris ou une des touches
- // '-' ou fleche en bas est couramment pressé :
- if (diff >= (60-20) && diff <= (60-1)) {
- // On a décrémenté les secondes mais avancé de (60-20) à (60-1) secondes
- if (tempres.wSecond >= 60-20)
- toAdd = -60;
- } else if (diff >= (60-20)*60 && diff <= (60-1)*60) {
- // On a décrémenté les minutes mais avancé de (60-20) à (60-1) minutes
- if (tempres.wMinute >= 60-20)
- toAdd = -60*60;
- } else if (diff == (24-1)*60*60) {
- // On a décrémenté les heures mais avancé de (24-1) heures
- if (tempres.wHour >= 24-1)
- toAdd = -24*60*60;
- }
- }
- }
-
- if (toAdd != 0) {
- AddTime(tempres, toAdd*1000);
- SetCtlTimeDate(hDlg, dateID, timeID, tempres);
- }
-
- result = tempres;
-}
-
-/**
- * Chargement de la liste des enregistrements programmés.
- * \param[in] hListItem “Handle” du contrôle de liste
- **/
-static void remplit_liste_programmes(HWND hListItem)
-{
- TCHAR buffer[64];
-
- LVITEM item = {
- LVIF_TEXT, // mask
- 0, 0, 0, 0, // iItem, iSubItem, state, stateMask
- buffer, // buffer
- _countof(buffer) // cchTextMax
- // le reste à zéro (implicite)
- };
-
- int nbProgrammes = (int)Programmes.size();
-
- for(; item.iItem=apr_eteindrePC);
- CheckDlgButton(hDlg, quitID, after>=apr_quitter);
-}
-
-/**
- * Coche ou décoche les cases liées aux répétitions :
- **/
-static void SetCtlRepeat(HWND hDlg, int repeatBaseID, BYTE repetition)
-{
- for (int i=0; i<7; i++)
- CheckDlgButton(hDlg, repeatBaseID+i, (repetition & (1<0 && *pwrk<=' ') // attention, type CHAR signé !!
- pwrk++;
- if (pwrk>pnom)
- strcpy_T(pnom, bufSize, pwrk);
-
- // Supprimer les espaces de fin :
- UINT strSize = strlen_T(pnom);
- while (strSize>0 && pnom[strSize-1]>0 && pnom[strSize-1]<=' ')
- pnom[--strSize] = 0;
-}
-
-/**
- * Récupère les données de l'enregistrement dans la fenêtre.
- * Retourne 'true' si ces données sont valides, 'false' sinon.
- **/
-static bool dlgToProg(HWND hDlg, Programme & prog, bool modif)
-{
- UINT32 cleChaine;
- int ixChaine;
-
- // Récupérer la chaîne :
- if ((ixChaine = (int)SendDlgItemMessage(hDlg, IDC_CHANNEL, CB_GETCURSEL, 0, 0))==CB_ERR) // index combo
- return false;
- if ((cleChaine = (UINT32)SendDlgItemMessage(hDlg, IDC_CHANNEL, CB_GETITEMDATA, ixChaine, 0))==0)// Clé
- return false;
- if (!ixChaine_ok(ixChaine = Canaux.trouve_par_cle(UINT32(cleChaine)))) // index chaîne
- return false;
-
- // Récupérer d'abord les dates, car un éventuel nom généré automatiquement se sert
- // de la date de début :
- GetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, prog.debut);
- GetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, prog.fin);
-
- // Ces deux valeurs ont été extraites de la boîte de dialogue au moment de leur sélection :
- prog.methode = epg_typerecvideo;
- prog.audio = epg_typerecaudio;
-
- const Chaine & canal = Canaux[ixChaine];
- NomProg nom;
-
- // Récupérer le nom :
- getDlgProgName(hDlg, nom, _countof(nom));
-
- if (nom[0]==0) {
- // le nom de la programmation est vide :
- if (prog.nom[0]==0 || prog.nomAuto) {
- // En générer un s'il n'y avait pas d'ancien nom,
- // ou bien si celui-ci avait déjà été généré automatiquement :
- unsigned ixSuffNom = 0;
- //
- do {
- ixSuffNom++;
- _stprintf_s(nom, _countof(nom),
- ixSuffNom>1 ? TEXT("%") A2t TEXT("-%i-%02i_%u") : TEXT("%") A2t TEXT("-%i-%02i"),
- prog.isMultiplex() ? "Multiplex" : canal.nom,
- prog.debut.wDay, prog.debut.wMonth, ixSuffNom);
- } while (_tcscmp(nom, prog.nom)!=0 && trouve_prog_par_nom(nom)>=0);
- strcpy_T(prog.nom, nom);
- prog.nomAuto = true;
- }
- } else {
- strcpy_T(prog.nom, nom);
- prog.nomAuto = false;
- }
-
- prog.nNumeroChaine = canal.nNumeroChaine;
- prog.cleChaine = canal.cle();
- prog.sidChaine = canal.SID; /// \deprecated \p sidChaine remplacé par \p cleChaine
-
- prog.apres = GetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER);
- prog.etat = IsDlgButtonChecked(hDlg, IDC_INACTIVE) == BST_CHECKED ? epr_inactif : epr_actif;
-
- // Ajoute l'indicatif pour la répétition
- prog.repetition = 0;
- for (int i=0; i<7; i++) {
- if (IsDlgButtonChecked(hDlg, IDC_REP_BASE+i) == BST_CHECKED)
- prog.repetition |= 1<=_countof(canal.emis))
- return false;
-
- const Emission & emis = canal.emis[noEmis];
-
- _tcsncpy_s(prog.nom, emis.nom, _countof(prog.nom)-1); // Tronquer si la longueur dépasse
- prog.nom[_countof(prog.nom)-1] = 0;
- prog.cleChaine = canal.cle();
- prog.sidChaine = canal.SID; /// \deprecated \p sidChaine remplacé par \p cleChaine
- prog.nNumeroChaine = canal.nNumeroChaine;
- prog.apres = apr_rien;
- prog.methode = meth_TS;
- prog.audio = am_Mpeg_1;
-
- // Ajout de l'heure de début et de l'heure de fin, avec leurs décalages respectifs :
- prog.fin = emis.fin;
- AddTime(prog.fin, retard_enreg * 60000);
- prog.debut = emis.debut;
- AddTime(prog.debut, avance_enreg * -60000);
-
- prog.repetition = 0;
- prog.tache = planif_sans;
- prog.etat = epr_actif;
-
- return true;
-}
-
-// Chargement des données de démarrage initialisant une nouvelle programmation :
-static void InitNewRecord(HWND hDlg)
-{
- SYSTEMTIME localtime;
-
- GetLocalTime(&localtime);
-
- localtime.wSecond = 0;
- localtime.wMilliseconds = 0;
- SetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut = localtime);
- SetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin = localtime);
- CtlSelChannel(GetDlgItem(hDlg, IDC_CHANNEL), ixChaineCourante);
- SendDlgItemMessage(hDlg, IDC_NAME, WM_SETTEXT, 0, (LPARAM)TEXT(""));
-
- SetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER, apr_rien);
- CheckDlgButton(hDlg, IDC_TACHE, BST_UNCHECKED);
- CheckDlgButton(hDlg, IDC_INACTIVE, BST_UNCHECKED);
-
- SetCtlRepeat(hDlg, IDC_REP_BASE, 0); // Répétitions
-}
-
-/**
- * Remplissage d'une combo box de liste de chaînes actives.
- **/
-static void remplit_liste_chaines(HWND hCtl)
-{
- int nbChaines = (int)Canaux.size();
-
- for (int i=0; i=0) {
- // On ajoute le SID de la chaîne en tant que donnée associée :
- // ceci servira à identifier la sélection, étant donné que l'index
- // dans la combo box ne correspondra pas nécessairement à celui de la liste
- // des chaînes, du fait des chaînes inactives possibles.
- SendMessage(hCtl, CB_SETITEMDATA, res, canal.cle());
- }
- }
- }
-}
-
-/**
- * Remplissage d'une combo-box de méthodes d'enregistement
- * \param[in] hCtl "Handle" de la combo-box
- * \param[in] eSel Item sélectionné
- **/
-void remplit_liste_methodes(HWND hCtl, MethodeEnregistrement eSel)
-{
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("TS"));
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("PS"));
- if (allow_stream_record)
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("Multiplex"));
- SendMessage(hCtl, CB_SETCURSEL, eSel, 0);
-}
-
-/**
- * Remplissage d'une combo-box d'items audio
- * \param[in] hCtl "Handle" de la combo-box
- * \param[in] eSel Item sélectionné
- **/
-void remplit_liste_audio(HWND hCtl, AudioMode eSel)
-{
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("1ère piste"));
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("Mpeg (1ère)"));
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("Mpeg (2ème)"));
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("(E)AC3"));
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("(E)AC3 2.0"));
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("(E)AC3 HC"));
- SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("V.O."));
- SendMessage(hCtl, CB_SETCURSEL, eSel, 0);
-}
-
-/**
- * Initialisation des items de méthodes d'enregistrement d'un dialogue d'enregistrements programmés
- * \param[in] hDlg "Handle" de la boîte de dialogue
- **/
-void init_methodes(HWND hDlg)
-{
- HWND hCtlMtd = GetDlgItem(hDlg, IDC_METHOD);
- HWND hCtlAud = GetDlgItem(hDlg, IDC_AUDIO);
-
- remplit_liste_methodes(hCtlMtd, epg_typerecvideo);
- remplit_liste_audio(hCtlAud, epg_typerecaudio);
-
- EnableWindow(hCtlAud, epg_typerecvideo == meth_PS);
-}
-
-/**
- * Mise à jour des méthodes d'enregistrement après changement d'un des items de dialogue
- * qui les contrôlent
- * \param[in] hDlg "Handle" de la boîte de dialogue
- **/
-void update_methodes(HWND hDlg)
-{
- HWND hCtlMtd = GetDlgItem(hDlg, IDC_METHOD);
- HWND hCtlAud = GetDlgItem(hDlg, IDC_AUDIO);
-
- epg_typerecvideo = (MethodeEnregistrement)SendMessage(hCtlMtd, CB_GETCURSEL, 0, NULL);
- epg_typerecaudio = (AudioMode)SendMessage(hCtlAud, CB_GETCURSEL, 0, NULL);
-
- EnableWindow(hCtlAud, epg_typerecvideo == meth_PS);
-}
-
-static void update_edit_state(HWND hDlg, int selection)
-{
- NomProg nom;
- bool edit = selection>=0 && Programmes[selection].etat!=epr_encours;
-
- EnableWindow(GetDlgItem(hDlg, IDC_MODIFY), edit);
- EnableWindow(GetDlgItem(hDlg, IDC_REMOVE), edit);
-
- // Activation ou désactivation du bouton "Ajouter" selon le contenu de l'item
- // d'édition de nom (ne doit pas être vide et ne doit pas déjà exister) :
- getDlgProgName(hDlg, nom, _countof(nom));
- EnableWindow(GetDlgItem(hDlg, IDC_ADD), trouve_prog_par_nom(nom)<0);
-}
-
-static INT_PTR CALLBACK RecordDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static HWND hListItem = NULL;
- static int selection = -1; // Index de l'item couramment sélectionné si >= 0
- static NomProg selProgNom = TEXT(""); // Nom de la sélection courante (pour pouvoir reconstituer celle-ci
- // après modification ou tri de la liste)
-
- switch (uMsg) {
-
- case WM_INITDIALOG: {
-
- selProgNom[0] = 0;
- hListItem = GetDlgItem(hDlg, IDC_LIST_PROGRAMMES);
-
- static const struct Tab_cols t_cols[] = {
- {TEXT("Nom"), 160},
- {TEXT("Chaîne"), 86},
- {TEXT("Début"), 140},
- {TEXT("Fin"), 48},
- {TEXT("État"), 78},
- {NULL, 0} // Terminateur
- };
-
- ListView_AjouteColonnes(hListItem, t_cols);
- remplit_liste_programmes(hListItem);
- remplit_liste_chaines(GetDlgItem(hDlg, IDC_CHANNEL)); // Chargement du combo de choix des chaînes
- init_methodes(hDlg);
- InitNewRecord(hDlg);
- update_edit_state(hDlg, selection);
- ShowCursor(TRUE); // Suspend la disparition temporisée du curseur
- return TRUE; }
-
- case WM_NOTIFY:
- switch (wParam) {
-
- case IDC_LIST_PROGRAMMES:
- if (_ncode_(lParam)==NM_CLICK) {
- selection = ListView_GetSelectionMark(hListItem);
- if (selection>=0) {
- // Clic dans la liste des programmations
- const Programme & prog = Programmes[selection];
-
- progToDlg(hDlg, prog);
- dtc_debut = prog.debut;
- dtc_fin = prog.fin;
-
- SendDlgItemMessage(hDlg, IDC_METHOD, CB_SETCURSEL, epg_typerecvideo = prog.methode, NULL);
- SendDlgItemMessage(hDlg, IDC_AUDIO, CB_SETCURSEL, epg_typerecaudio = prog.audio, NULL);
- EnableWindow(GetDlgItem(hDlg, IDC_AUDIO), epg_typerecvideo == meth_PS);
-
- SetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER, prog.apres);
-
- CheckDlgButton(hDlg, IDC_TACHE,
- prog.tache!=planif_sans ? BST_CHECKED : BST_UNCHECKED);
-
- // Coche les cases pour les répétitions :
- SetCtlRepeat(hDlg, IDC_REP_BASE, prog.repetition);
-
- strcpy_T(selProgNom, prog.nom);
- return TRUE;
- }
- update_edit_state(hDlg, selection);
- } else if (_ncode_(lParam)==LVN_KEYDOWN) {
- LPNMLVKEYDOWN pnkd = (LPNMLVKEYDOWN) lParam;
- if (pnkd->wVKey == VK_DELETE)
- SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDC_REMOVE, 0), 0);
- } else if (_ncode_(lParam)==NM_CUSTOMDRAW) {
- NMLVCUSTOMDRAW & sNlcd = *reinterpret_cast(lParam);
-
- switch(sNlcd.nmcd.dwDrawStage) {
-
- case CDDS_PREPAINT:
- SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW);
- return TRUE;
-
- case CDDS_ITEMPREPAINT: {
- const Programme & prog = Programmes[sNlcd.nmcd.dwItemSpec];
-
- switch (prog.etat) {
-
- case epr_actif:
- sNlcd.clrText = RGB(0,128,255);
- break;
-
- case epr_encours:
- sNlcd.clrText = RGB(255,0,0);
- break;
-
- case epr_interrompu:
- case epr_termine:
- case epr_inactif:
- sNlcd.clrText = RGB(128,128,128);
- break;
-
- case epr_supplante:
- case epr_erreur:
- sNlcd.clrText = RGB(128,0,128);
- }
- return TRUE; }
- }
- }
- break;
-
- case IDC_DATE_START:
- case IDC_TIME_START:
- if (_ncode_(lParam)==DTN_DATETIMECHANGE) {
- GetCtlTimeDateChg(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
- GetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
- if (DiffTime(dtc_debut, dtc_fin) > 0)
- SetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin = dtc_debut);
- }
- break;
-
- case IDC_DATE_END:
- case IDC_TIME_END:
- if (_ncode_(lParam)==DTN_DATETIMECHANGE) {
- GetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
- GetCtlTimeDateChg(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
- if (DiffTime(dtc_debut, dtc_fin) > 0)
- SetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut = dtc_fin);
- }
- }
- return FALSE;
-
- case WM_COMMAND:
- switch(LOWORD(wParam)) {
-
- case IDC_ADD_24: // Ajouter 24h des deux côtés
- GetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
- AddTime(dtc_debut, 24 * 60 * 60 * 1000);
- SetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
- GetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
- AddTime(dtc_fin, 24 * 60 * 60 * 1000);
- SetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
- break;
-
- case IDC_SUB_24: // Soustraire 24h des deux côtés
- GetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
- AddTime(dtc_debut, -24 * 60 * 60 * 1000);
- SetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
- GetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
- AddTime(dtc_fin, -24 * 60 * 60 * 1000);
- SetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
- break;
-
- case IDC_METHOD:
- case IDC_AUDIO:
- if (HIWORD(wParam) == CBN_SELCHANGE) {
- update_methodes(hDlg);
- return TRUE;
- }
- break;
-
- case IDC_NAME:
- if (HIWORD(wParam) == EN_CHANGE) {
- update_edit_state(hDlg, selection);
- return TRUE;
- }
- break;
-
- case IDC_REMOVE:
- if (selection >= 0 && Programmes[selection].etat!=epr_encours) {
- ListView_DeleteItem(hListItem, selection);
-
- // Suppression éventuelle tâche antérieure portant ce nom :
- Programmes[selection].supprimerTacheProgrammee();
-
- Programmes.erase(Programmes.begin() + selection);
- finalize_prog_change();
- }
- return TRUE;
-
- case IDC_MODIFY:
- if (selection >= 0) {
- Programme & prog = Programmes[selection];
- Programme newprog = prog;
-
- if (dlgToProg(hDlg, newprog, true) && prog.verifie(&prog)) {
- // Récupération et vérification données du dialogue
-
- if (prog.etat == epr_encours)
- MessageBox(hDlg, TEXT("Cet enregistrement est actuellement en cours.") EOL
- TEXT("Utilisez la commande \"Arrêter l'enregistrement dans...\"")
- TEXT(" pour y apporter des modifications maintenant."),
- TEXT("Erreur lors de la modification"), MB_ICONERROR);
- else {
- // Suppression éventuelle tâche antérieure portant l'ancien nom :
- prog.supprimerTacheProgrammee();
-
- prog = newprog;
-
- strcpy_T(selProgNom, prog.nom);
- prog.ajoutTacheAvecLogon(hDlg);
-
- finalize_prog_change();
- }
- }
- }
- return TRUE;
-
- case IDC_ADD: {
- Programme prog;
-
- // Récupération des données de l'enregistrement depuis la boîte de dialogue
- if (!dlgToProg(hDlg, prog, false) || !prog.verifie())
- return FALSE;
-
- strcpy_T(selProgNom, prog.nom);
- prog.ajoutTacheAvecLogon(hDlg);
- Programmes.push_back(prog);
-
- finalize_prog_change();
- return TRUE; }
-
- case IDC_NEW:
- // Réinitialiser les données de programmation
- InitNewRecord(hDlg);
- selection = -1;
- selProgNom[0] = 0;
- update_edit_state(hDlg, selection);
- return TRUE;
-
- case IDC_CURRENT_PROGRAM: {
- // Charger les données de l'émission en cours
- Programme prog;
-
- if (chaineToProg(ixChaineCourante, 0, prog)) {
- progToDlg(hDlg, prog);
- dtc_debut = prog.debut;
- dtc_fin = prog.fin;
- selection = -1;
- selProgNom[0] = 0;
- update_edit_state(hDlg, selection);
- }
- return TRUE; }
-
- case IDC_AFTER_POWEROFF:
- // Coche le bouton arrêtant PouchinTV si on a demandé l'arrêt de l'ordinateur
- if (IsDlgButtonChecked(hDlg, IDC_AFTER_POWEROFF) == BST_CHECKED)
- CheckDlgButton(hDlg, IDC_AFTER, BST_CHECKED);
- return TRUE;
-
- case IDC_AFTER:
- // Décoche le bouton arrêtant le PC si on ne souhaite pas arrêter PouchinTV
- if (IsDlgButtonChecked(hDlg, IDC_AFTER) == BST_UNCHECKED)
- CheckDlgButton(hDlg, IDC_AFTER_POWEROFF, BST_UNCHECKED);
- return TRUE;
-
- case IDOK:
- DestroyWindow(hDlg);
- return TRUE;
- }
- break;
-
- case WM_CLOSE:
- DestroyWindow(hDlg);
- return TRUE;
-
- case WM_NCDESTROY:
- // Fermeture de la boîte de dialogue : on efface le mot de passe
- SecureZeroMemory(mdp, sizeof(mdp));
-
- hRecordDlg = NULL;
- ShowCursor(FALSE); // Rétablit la disparition temporisée du curseur
- return TRUE;
-
- case WM_APP_PROG_CHANGED:
- // Reconstruction de la liste des enregistrements programmés après changement :
- ListView_DeleteAllItems(hListItem);
- remplit_liste_programmes(hListItem);
- selection = trouve_prog_par_nom(selProgNom);
- if (selection>=0)
- ListView_SetItemState(hListItem, selection, LVIS_SELECTED, LVIS_SELECTED);
- update_edit_state(hDlg, selection);
- return TRUE;
-
- }
-
- return FALSE;
-}
-
-/**
- * Ouverture du dialogue des enregistrements programmés
- **/
-void open_record_dialog()
-{
- if (hRecordDlg)
- BringWindowToTop(hRecordDlg);
- else {
- hRecordDlg = CreateDialog(hAppInstance,
- MAKEINTRESOURCE(IDD_DELAYED_RECORD), hMainWnd, RecordDialogProc);
- ShowWindow(hRecordDlg, SW_SHOW);
- }
-}
-
-/**
- * Traitement des événements liés au dialogue d'enregistrement.
- * Retourne \p true si le message \p msg a été traité, auquel cas il ne faut pas le
- * passer à \p TranslateMessage et \p DispatchMessage.
- * À placer dans la boucle de gestion générale des messages.
- **/
-bool is_record_dialog_message(MSG & msg) {
- if (hRecordDlg!=NULL && IsDialogMessage(hRecordDlg, &msg))
- return true;
- return false;
-}
-
-/**
- * Transformation d'un horaire de fin en temps restant
- **/
-static SYSTEMTIME EndTimeToRemTime(SYSTEMTIME time)
-{
- SYSTEMTIME localtime;
- LONG wMillisec;
-
- GetLocalTime(&localtime);
- wMillisec = DiffTime(time, localtime);
-
- // S'assurer que l'heure de fin tombe bien dans les 24 heures qui suivent :
- #define ONEDAY (24*60*60*1000)
- while (wMillisec<0)
- wMillisec += ONEDAY;
- while (wMillisec>=ONEDAY)
- wMillisec -= ONEDAY;
- #undef ONEDAY
-
- time.wMilliseconds = WORD(wMillisec % 1000);
- wMillisec /= 1000;
- time.wSecond = WORD(wMillisec % 60);
- wMillisec /= 60;
- time.wMinute = WORD(wMillisec % 60);
- wMillisec /= 60;
- time.wHour = WORD(wMillisec);
- return time;
-}
-
-/**
- * Transformation d'un temps restant en horaire de fin
- **/
-static SYSTEMTIME RemTimeToEndTime(SYSTEMTIME time)
-{
- LONG wMillisec = ((time.wHour*60 + time.wMinute)*60 + time.wSecond)*1000 + time.wMilliseconds;
-
- GetLocalTime(&time);
- AddTime(time, wMillisec);
- return time;
-}
-
-enum DlgEditState {
- des_notModified, // Aucun changement à appliquer
- des_noConfirmNeed, // Un changement peut-être appliqué mais son annulation n'a pas
- // besoin d'être explicite
- des_needConfirm // Un changement a été effectué mais son annulation doit être explicite
-};
-
-struct DelayEditData {
- HWND hDlg;
- HWND hEnrCombo;
- HWND hTimeCtl;
- int ixRecDescr; // index du descripteur d'enregistrement
- int comboSel; // item couramment sélectionné dans la combo box
- Enregistrement * penreg; // pointeur enregistrement à modifier
- SYSTEMTIME refTime; // Contenu du contrôle de temps, soit en tant qu'heure de fin,
- // soit en tant que temps restant, selon le contenu de
- // 'useEndTime' (définit le temps de référence)
- bool useEndTime; // vrai si le temps mémorisé (refTime) est l'heure de fin
- bool dispEndTime; // vrai si le contrôle affiche l'heure de fin
- bool delayActive; // vrai si la temporisation sera activée
- DlgEditState dlgEditState; // niveau de modifications effectuées
-
- void remplitCombo();
- void load(bool initActive); // charger les données de l'enregistrement N° 'ixRecDescr'
- void setCtlTime(); // Transférer le temps de référence dans le contrôle, selon le mode courant
- bool needTimer() const {return delayActive && dispEndTime != useEndTime;}
- void toEndTime(void); // convertir en mode "heure de fin"
- void apply(void); // appliquer les changements
- void setChangedState(DlgEditState newState); // Indique comment le contenu du dialogue a été modifié ou pas
- void setActiveState(bool active); // Modifie l'état "actif" de la fin d'enregistrement programmée
- void recordEnded(void);
-};
-
-// Chargement du combo des chaînes en cours d'enregistrement :
-void DelayEditData::remplitCombo()
-{
- TCHAR buf[64];
- LPCSTR nom;
- int res, i, sel=0;
-
- comboSel = 0;
- for (i = 0; i < enregistrements_actuels.count(); i++) {
- const Enregistrement & enreg = enregistrements_actuels[i];
-
- if (!enreg.recording())
- continue;
- nom = enreg.channelName();
- if (*nom == '*')
- strcpy_T(buf, "[ multiplex ]");
- else
- strcpy_T(buf, nom);
- res = (int)SendMessage(hEnrCombo, CB_ADDSTRING, 0, LPARAM(buf));
- SendMessage(hEnrCombo, CB_SETITEMDATA, res, i);
- if (i==ixRecDescr)
- sel = res;
- }
-
- comboSel = (int)SendMessage(hEnrCombo, CB_SETCURSEL, sel, 0);
-}
-
-// Chargement des données de l'enregistrement 'ixRecDescr'.
-// Si 'initActive' = true, le dialogue sera préparé pour activation si aucune
-// temporisation n'existait auparavant pour cet enregistrement
-// (afin d'éviter à l'utilisateur d'avoir à cliquer sur la case d'activation
-// lors de l'ouverture du dialogue). Il restera néanmoins nécessaire de valider
-// ce changement.
-void DelayEditData::load(bool initActive)
-{
- if (ixRecDescr<0)
- ixRecDescr = 0;
- penreg = &enregistrements_actuels[ixRecDescr];
-
- CheckDlgButton(hDlg, IDC_DELAY_BY_REMTIME, BST_CHECKED);
- dispEndTime = false;
- if (!penreg->recording()) {
- recordEnded();
- } else {
- EnableWindow(GetDlgItem(hDlg, IDC_DELAY_ACTIVE), TRUE);
- if (penreg->apres != apr_null) {
- setActiveState(true);
- SetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER, penreg->apres);
- refTime = penreg->fin;
- useEndTime = true;
- setChangedState(des_notModified);
- } else {
- setActiveState(initActive);
- GetLocalTime(&refTime);
- // Indiquer temps restant = 1/2 heure par défaut.
- refTime.wHour = refTime.wSecond = refTime.wMilliseconds = 0;
- refTime.wMinute = 30;
- useEndTime = false;
- setChangedState(initActive ? des_noConfirmNeed : des_notModified);
- }
- }
- CheckDlgButton(hDlg, IDC_DELAY_ACTIVE, delayActive);
- setCtlTime();
-}
-
-// Modifie l'état "actif" de la fin d'enregistrement programmée
-void DelayEditData::setActiveState(bool active)
-{
- static const int t_id[] =
- {IDC_DELAYED_STOP, IDC_DELAY_LABEL, IDC_DELAY_BY_REMTIME, IDC_DELAY_BY_ENDTIME,
- IDC_AFTER_RECORD, IDC_AFTER, IDC_AFTER_POWEROFF, IDC_AFTER_NOTE};
-
- delayActive = active;
- for (int i=0; i<_countof(t_id); i++)
- EnableWindow(GetDlgItem(hDlg, t_id[i]), delayActive);
-}
-
-// Fonction appelée si l'enregistrement se termine pendant que le dialogue
-// est ouvert :
-void DelayEditData::recordEnded(void)
-{
- setActiveState(false);
- EnableWindow(GetDlgItem(hDlg, IDC_DELAY_ACTIVE), FALSE);
-}
-
-// Indique si le contenu du dialogue a été modifié ou pas
-void DelayEditData::setChangedState(DlgEditState newState)
-{
- bool modified = newState!=des_notModified;
- bool oldActive = penreg && penreg->apres!=apr_null;
- bool activeChanged = delayActive != oldActive;
-
- dlgEditState = newState;
- EnableWindow(GetDlgItem(hDlg, IDC_APPLY), modified && (delayActive || activeChanged));
-}
-
-void DelayEditData::toEndTime(void)
-{
- if (useEndTime) {
- // Si on utilise déjà l'heure de fin, on effectue une double conversion
- // pour s'assurer que celle-ci se trouve bien dans le futur, et non pas
- // plus tôt dans la journée (étant donné que le dialogue ne peut pas
- // définir la date).
- refTime = EndTimeToRemTime(refTime);
- useEndTime = false;
- }
- if (!useEndTime) {
- refTime = RemTimeToEndTime(refTime);
- useEndTime = true;
- }
-}
-
-void DelayEditData::setCtlTime()
-{
- if (dispEndTime==useEndTime)
- DateTime_SetSystemtime(hTimeCtl, GDT_VALID, &refTime);
- else {
- SYSTEMTIME tmptime = (dispEndTime ? RemTimeToEndTime : EndTimeToRemTime)(refTime);
-
- DateTime_SetSystemtime(hTimeCtl, GDT_VALID, &tmptime);
- }
-};
-
-// Application des modifications :
-void DelayEditData::apply(void)
-{
- if (penreg->recording() && dlgEditState!=des_notModified) { // Toujours en train d'enregistrer ?
- ApresEnregistrement apres = delayActive ?
- GetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER) :
- apr_null;
-
- toEndTime();
- penreg->fin = refTime;
- penreg->apres = apres;
-
- // Rechercher si l'arrêt retardé résultait d'une programmation,
- // afin de mettre à jour celle-ci en même temps, le cas échéant :
- int ixProg = trouve_prog_par_nom(penreg->nom);
-
- if (ixProg>=0) {
- Programme & prog = Programmes[ixProg];
-
- programmation_modifiee = true;
- if (prog.repetition != 0) {
- // La programmation comporte des répétitions :
- // on se contente de la "déconnecter" de l'enregistrement, lui permettant
- // ainsi d'être reportée intégralement à son occurrence suivante.
- prog.etat = epr_supplante;
- } else {
- if (apres == apr_null) {
- // On a annulé l'arrêt d'enregistrement (celui-ci
- // peut donc se poursuivre indéfiniment)
- prog.etat = epr_supplante;
- } else {
- // On a modifié l'heure ou l'action de fin : on reporte les
- // modifications dans la programmation, de sorte qu'un arrêt
- // impromptu éventuel du programme suivi d'une relance
- // (plantage ?) reprennne le reliquat ainsi.
- prog.fin = refTime;
- prog.apres = apres;
- }
- }
- record_list_updated();
- }
-
- setChangedState(des_notModified);
- PostMessage(hMainWnd, WM_TIMECHANGE, 0, 0);
- }
-}
-
-// Gestion du dialogue des arrêts d'enregistrement temporisés :
-static INT_PTR CALLBACK DelayedStopDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
-{
- static DelayEditData edat = {0}; // tout à zéro, false ou NULL à l'initialisation
-
- switch (uMsg) {
-
- case WM_INITDIALOG:
- edat.hDlg = hDlg;
- edat.hEnrCombo = GetDlgItem(hDlg, IDC_CHANNEL);
- edat.hTimeCtl = GetDlgItem(hDlg, IDC_DELAYED_STOP);
- edat.ixRecDescr = enregistrements_actuels.getRecordingDescr(ixChaineCourante);
- edat.load(false /*true*/);
- edat.remplitCombo(); // Chargement du combo des enregistrements
-
- // Création d'un timer battant à la seconde pour la mise à jour du contrôle de saisie
- // de l'heure (selon son mode d'affichage), ainsi que la détection des
- // enregistrements terminés.
- SetTimer(hDlg, TIMER_DELAYED_STOP, 1000, NULL);
- return TRUE;
-
- case WM_TIMER:
- if (!edat.penreg->recording()) // Tester si l'enregistrement se termine à ce moment
- edat.recordEnded();
- if (edat.needTimer())
- edat.setCtlTime();
- return TRUE;
-
- case WM_COMMAND: {
- switch(wParam) {
-
- case _cmd_(IDC_CHANNEL, CBN_SELCHANGE): {
- int newSel = (int)SendMessage(edat.hEnrCombo, CB_GETCURSEL, 0, 0);
-
- if (newSel!=CB_ERR && newSel!=edat.comboSel) {
- if (edat.dlgEditState==des_needConfirm) {
- switch (MessageBox(hDlg,
- TEXT("Vous avez apporté des modifications à la programmation de la chaîne en cours.") EOL
- TEXT("Désirez-vous valider ces modifications ?"),
- TEXT("Changement de chaîne"),
- MB_YESNOCANCEL)) {
-
- case IDCANCEL:
- SendMessage(edat.hEnrCombo, CB_SETCURSEL, WPARAM(edat.comboSel), 0);
- return TRUE;
-
- case IDYES:
- edat.apply();
- case IDNO: ;
- }
- }
- edat.comboSel = newSel;
- edat.ixRecDescr = (int)SendMessage(edat.hEnrCombo, CB_GETITEMDATA, WPARAM(newSel), 0);
- edat.load(false /*true*/);
- }
- return TRUE; }
-
- case _cmd_(IDC_DELAY_BY_REMTIME, BN_CLICKED):
- case _cmd_(IDC_DELAY_BY_ENDTIME, BN_CLICKED):
- edat.dispEndTime = IsDlgButtonChecked(hDlg, IDC_DELAY_BY_ENDTIME)==BST_CHECKED;
- edat.setCtlTime();
- return TRUE;
-
- case _cmd_(IDC_DELAY_ACTIVE, BN_CLICKED):
- edat.setActiveState(IsDlgButtonChecked(hDlg, IDC_DELAY_ACTIVE)==BST_CHECKED);
- edat.setChangedState(des_needConfirm);
- return TRUE;
-
- case _cmd_(IDC_AFTER, BN_CLICKED):
- // Décoche le bouton arrêtant le PC si on ne souhaite pas arrêter PouchinTV
- if (IsDlgButtonChecked(hDlg, IDC_AFTER) == BST_UNCHECKED)
- CheckDlgButton(hDlg, IDC_AFTER_POWEROFF, BST_UNCHECKED);
- edat.setChangedState(des_needConfirm);
- return TRUE;
-
- case _cmd_(IDC_AFTER_POWEROFF, BN_CLICKED):
- // Coche le bouton arrêtant PouchinTV si on a demandé l'arrêt de l'ordinateur
- if (IsDlgButtonChecked(hDlg, IDC_AFTER_POWEROFF) == BST_CHECKED)
- CheckDlgButton(hDlg, IDC_AFTER, BST_CHECKED);
- edat.setChangedState(des_needConfirm);
- return TRUE;
-
- case _cmd_(IDC_APPLY, BN_CLICKED):
- edat.apply();
- return TRUE;
-
- case _cmd_(IDOK, BN_CLICKED):
- edat.apply();
- // ...
- case _cmd_(IDCANCEL, BN_CLICKED):
- KillTimer(hDlg, TIMER_DELAYED_STOP);
- EndDialog(hDlg, 0);
- return TRUE;
- }
- break; }
-
- case WM_NOTIFY:
- if (_ncode_(lParam)==DTN_DATETIMECHANGE) {
- DateTime_GetSystemtime(edat.hTimeCtl, &edat.refTime);
- // Le mode d'affichage utilisé sert maintenant de référence :
- edat.useEndTime = edat.dispEndTime;
- edat.setChangedState(des_needConfirm);
- }
- return TRUE;
- }
-
- return FALSE;
-}
-
-/**
- * Appel du dialogue de fin d'enregistrement retardée.
- **/
-void delayed_stop_dialog()
-{
- ShowCursor(TRUE);
- DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_DELAYED_STOP), hMainWnd, DelayedStopDialogProc);
- ShowCursor(FALSE);
-}
-
-/**
- * Fonction à appeler en cas de changement externe possible de la liste des enregistrements programmés.
- * Assure la sauvegarde des modification et la mise à jour de la liste dans la fenêtre de dialogue
- * si celle-ci est ouverte.
- **/
-void record_list_updated()
-{
- if (programmation_modifiee) {
- // Tri de la liste :
- std::sort(Programmes.begin(), Programmes.end());
-
- if (hRecordDlg)
- PostMessage(hRecordDlg, WM_APP_PROG_CHANGED, 0, 0); // Reconstruction de la liste si couramment affichée
-
- // Sauvegarde de la liste des programmes
- sauve_programmes();
- }
-}
-
-/**
- * Finalisation d'un changement dans les enregistrements programmés.
- **/
-void finalize_prog_change()
-{
- programmation_modifiee = true;
-
- // Mise à jour du timer des enregistrements :
- set_timer_record();
-
- // Mise à jour de l'affichage, et sauvegarde dans le fichier :
- record_list_updated();
-}
-
-/**
- * Démarre tous les enregistrements qui devraient l'être à cet instant précis.
- * Retourne 'true' si au moins un changement de nature à affecter les menus
- * ou la programmation d'enregistrement a eu lieu
- **/
-static bool do_record_start(const SYSTEMTIME & localtime)
-{
- long frequence_courante = 0;
- int ixChaine = -1;
- bool changement = false;
-
- // Déterminer si on enregistre quelque chose actuellement, et si oui, quelle est la
- // fréquence utilisée.
- UINT32 cleChaine = enregistrements_actuels.recording();
-
- if (cleChaine != 0) {
- ixChaine = cleChaine != STREAM_PSEUDO_CLE ? Canaux.trouve_par_cle(cleChaine) : ixChaineCourante;
-
- if (ixChaine_ok(ixChaine))
- frequence_courante = Canaux[ixChaine].khz;
- }
-
- int nbProgrammes = (int)Programmes.size();
-
- // Passer en revue les programmations définies afin de démarrer TOUS les enregistrements qui
- // devraient être en cours et qui peuvent être démarrés.
- for (int i=0; i),
+ * to use with a modified version of this software.
+ * See http://pouchinteve.free.fr/ for the original project.
+ */
+
+#include "recprog.h"
+#include "base.h"
+#include "channels.h"
+#include "record.h"
+#include "main.h"
+#include "utils.h"
+//
+#include
+#include
+#include // pour 'sort'
+
+/**
+ * Délai de grâce pour l'arrêt après enregistrement : si, à l'arrêt d'un enregistrement, un
+ * autre enregistrement est programmé dans un délai plus court que le délai spécifié, alors
+ * les options d'arrêt du programme ou d'extinction de l'ordinateur sont ignorées.
+ * \todo Rendre ceci configurable par l'utilisateur.
+ **/
+#define DUREE_GRACE_QUIT 30 // Valeur en minutes
+
+/**
+ * En cas d'arrêt programmé de l'application et/ou de l'ordinateur à l'issue d'un enregistrement,
+ * le délai suivant est appliqué avant l'exécution effective de l'arrêt, afin de garantir une
+ * terminaison propre de l'enregistrement.
+ **/
+#define DUREE_QUIT 2000 // Valeur en millisecondes
+
+/**
+ * Marge pour le calcul des recouvrements de programmations :
+ * Deux programmations doivent être séparées par au moins ce temps
+ * (en millisecondes) pourqu'il soit considéré qu'elles ne se superposent pas.
+ **/
+#define DUREE_MARGE_RECOUVREMENT 2500 // Valeur en millisecondes
+
+/**
+ * Liste des enregistrements programmés
+ **/
+std::vector Programmes;
+
+static HWND hRecordDlg = NULL;
+static WCHAR mdp[256] = L"";
+
+// Variables utilisées pendant les modifications des contrôles date et heure pour tester la
+// différence entre le début et la fin ainsi que la différence avec la valeur avant changement :
+static SYSTEMTIME dtc_debut = {0};
+static SYSTEMTIME dtc_fin = {0};
+
+/**
+ * On passe une clé de chaîne en paramètre,
+ * et on retourne la fréquence du multiplex correspondant
+ **/
+static INT32 getFrequence_par_cle(UINT32 cleChaine)
+{
+ int ixChaine = Canaux.trouve_par_cle(cleChaine);
+
+ if (ixChaine >= 0)
+ return Canaux[ixChaine].khz;
+
+ return -1;
+}
+
+/**
+ * Fonction “callback” de traitement de la saisie du mot de passe requis lors de l'ajout d'une
+ * tâche dans le planificateur de tâches
+ **/
+static INT_PTR CALLBACK PaswdDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
+ switch (uMsg) {
+ case WM_INITDIALOG:
+ return TRUE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+
+ case IDOK: {
+ TCHAR buffer[128];
+
+ *reinterpret_cast(&buffer[0]) = _countof(buffer);
+
+ UINT nLen = (UINT)SendDlgItemMessage(hwndDlg, IDC_PASWD, EM_GETLINE, 0, (LPARAM)buffer);
+
+ buffer[nLen] = 0; // (selon la doc, EM_GETLINE n'ajouterait pas toujours le zéro terminateur)
+ strcpy_T(mdp, buffer);
+ EndDialog(hwndDlg, 0);
+ return TRUE; }
+
+ case IDCANCEL:
+ EndDialog(hwndDlg, 1);
+ return TRUE;
+ }
+ return FALSE;
+
+ default:
+ return FALSE;
+ }
+}
+
+/**
+ * Saisie du mot de passe requis lors de l'ajout d'une tâche dans le planificateur de tâches
+ **/
+static bool taskLogon(HWND hDlg, LPCWSTR username)
+{
+ // Vérifie le login, et demande le mot de passe si besoin est
+ bool identifie = false;
+
+ HANDLE session;
+ do {
+ identifie = LogonUserW(username, NULL, mdp,
+ LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &session)==TRUE;
+ if (identifie)
+ break;
+
+ // Saisie du mot de passe, et reboucler si pas d'annulation :
+ mdp[0] = 0; // (vider la saisie précédente)
+ } while (DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_PASWD), hDlg, PaswdDialogProc)==0);
+
+ CloseHandle(session);
+
+ return identifie;
+}
+
+/**
+ * Tableau de chaînes affichables correspondant aux différents états possibles
+ * d'un enregistrement programmé
+ **/
+const LPCTSTR Programme::t_states[] =
+{
+ TEXT("Attente"),
+ TEXT("En cours"),
+ TEXT("Désactivé"),
+ TEXT("Interrompu"),
+ TEXT("Supplanté"),
+ TEXT("Terminé"),
+ TEXT("Erreur")
+};
+
+/// Constructeur
+Programme::Programme()
+{
+ apres = apr_rien;
+ memset(&debut, 0, LPBYTE(this)+sizeof(*this)-LPBYTE(&debut));
+ etat = epr_inactif;
+}
+
+
+/// Retourne \p true si intersection temporelle avec la programmation \p p2
+bool Programme::overlap(const Programme & p2) const
+{
+ // avec 1000 millisecondes de marge
+ return
+ DiffTime(fin, p2.debut) >= DUREE_MARGE_RECOUVREMENT &&
+ DiffTime(p2.fin, debut) >= DUREE_MARGE_RECOUVREMENT;
+}
+
+/**
+ * \brief Comparaison en vue de tri sur l'heure de début
+ *
+ * Utilisé par la fonction std::sort
+ * \retval \p true si cette programmation se classe avant la programmation \p p2 dans le temps.
+ **/
+bool Programme::operator < (const Programme & p2) const
+{
+ return DiffTime(debut, p2.debut)<0;
+}
+
+/**
+ * \brief Calcul du temps restant avant début enregistrement en millisecondes.
+ *
+ * \param[in] localtime Heure de référence (en principe l'heure système)
+ **/
+long Programme::temps_restant(const SYSTEMTIME & localtime) const
+{
+ if (!active() || DiffTime(localtime, fin)>=0)
+ return DUREE_INFINIE; // La programmation est inactive ou l'heure de fin est dépassée
+
+ long reste = DiffTime(debut, localtime);
+
+ return max(reste, 0);
+}
+
+/**
+ * \brief Ajustement des données si répétitions programmées et horaire de fin dépassé
+ *
+ * \param[in] localtime Heure de référence (en principe l'heure système)
+ * \retval \p true si un ajustement a eu lieu
+ **/
+bool Programme::ajustementDesRepetitions(const SYSTEMTIME & localtime)
+{
+ bool res = false;
+
+ if (repetition != 0 && etat != epr_inactif) {
+ // En cas de répétition, tous les enregistrements non explicitement marqués comme
+ // "inactifs" sont reconduits et réactivés dès lors que l'heure de fin est dépassée
+
+ while (DiffTime(localtime, fin) >= 0) { // Tant que l'heure de fin est dépassée
+ int nbJours;
+
+ // Trouver le nombre de jours avant la répétition suivante :
+ for (nbJours=1; (repetition & (1<<((debut.wDayOfWeek + nbJours) % 7)))==0; nbJours++);
+
+ long to_add = nbJours * 24 * 60 * 60 * 1000; // Conversion en millisecondes
+
+ AddTime(debut, to_add);
+ AddTime(fin, to_add);
+
+ /// \todo Il faudrait vérifier d'une façon ou d'une autre qu'une transition
+ /// heure d'été <-> heure d'hiver intempestive ne risque pas d'introduire un
+ /// décalage d'une heure dans la programmation à cet endroit.
+
+ etat = epr_actif; // réactivation
+ programmation_modifiee = true;
+ res = true;
+
+ // Note : on revérifie en bouclant sur le test de différence de temps pour parer au cas
+ // où celui-ci serait effectué alors que le programme n'a pas été exécuté pendant un délai
+ // excédant plusieurs répétitions consécutives.
+ }
+ }
+ return res;
+}
+
+/**
+ * Affichage du message d'avertissement en cas de conflit dans une programmation
+ * \param[in] pszMessage Texte du message à afficher
+ * \return \p true ou \p false selon que l'utilisateur souhaite néanmoins poursuive ou pas
+ **/
+bool Programme::warn_prog(LPCTSTR pszMessage)
+{
+ tstring strMsg(pszMessage);
+
+ strMsg += EOL TEXT("Voulez-vous quand même effectuer cette programmation ?");
+
+ if (MessageBox(hMainWnd, strMsg.c_str(), TEXT("Avertissement"), MB_YESNO|MB_ICONWARNING)==IDNO)
+ return false;
+ return true;
+}
+
+/**
+ * \brief Vérification de la validité de la programmation
+ *
+ * \param[in] prog_modif Si non NULL, pointeur sur la programmation qu'on modifie (pour
+ * éviter de la comparer à elle-même lors des tests de recouvrement)
+ * \retval \p true ou \p false selon succès ou échec, respectivement
+ **/
+bool Programme::verifie(const Programme * prog_modif) const
+{
+ int ixChaine = Canaux.trouve_par_cle(cleChaine);
+ SYSTEMTIME localtime;
+
+ if (ixChaine<0) {
+ affiche_erreurs(TEXT("La chaîne est incorrecte"));
+ return false;
+ }
+
+ GetLocalTime(&localtime);
+
+ long duree = DiffTime(fin, debut);
+
+ if (duree < 0) {
+ affiche_erreurs(TEXT("Le programme commence après avoir fini !"));
+ return false;
+ }
+
+ if (duree == 0) {
+ affiche_erreurs(TEXT("La durée de l'enregistrement est nulle !"));
+ return false;
+ }
+
+ if (duree > 12*60*60*1000) {
+ affiche_erreurs(TEXT("La durée de l'enregistrement dépasse 12 heures !"));
+ return false;
+ }
+
+ if (DiffTime(fin, localtime) < 0 &&
+ !warn_prog(TEXT("L'heure de fin du programme est dépassée !")) )
+ return false;
+
+ if (nom[0] == 0) {
+ affiche_erreurs(TEXT("Veuillez donner un nom à ce programme"));
+ return false;
+ }
+
+ const Chaine & canal = Canaux[ixChaine];
+
+ if (methode==meth_PS && canal.video_type!=vst_MPEG2) {
+ affiche_erreurs(
+ TEXT("L'enregistrement d'une chaîne H264 (cas de la haute définition) ")
+ TEXT("en mode PS n'est pas encore implémenté"));
+ return false;
+ }
+
+ int nbProgrammes = (int)Programmes.size();
+
+ for(int i = 0; i < nbProgrammes; i++) {
+ const Programme & prog_verif = Programmes[i];
+
+ if (&prog_verif ==prog_modif)
+ continue; // Ne pas comparer la programmation à celle en cours de modification
+
+ if (_tcscmp(prog_verif.nom, nom) == 0) {
+ affiche_erreurs(TEXT("Ce nom est déjà utilisé"));
+ return false;
+ }
+
+ if (prog_verif.active() && overlap(prog_verif)) {
+ // Chevauchement des horaires :
+
+ // Vérifier qu'on n'a pas programmé plusieurs fois la même chaîne au même moment :
+ if (cleChaine==prog_verif.cleChaine &&
+ isMultiplex()==prog_verif.isMultiplex() &&
+ !warn_prog(
+ tstr_printf(
+ TEXT("Chevauchement des horaires avec \"%s\", qui concerne la même chaîne !"),
+ prog_verif.nom).c_str()) )
+ return false;
+
+ // Vérifie que le programme chevauchant est sur le même multiplex :
+ if (getFrequence_par_cle(prog_verif.cleChaine) != canal.khz) {
+ int ixChaine2 = Canaux.trouve_par_cle(prog_verif.cleChaine);
+
+ if (ixChaine_ok(ixChaine2) &&
+ !warn_prog(
+ tstr_printf(
+ TEXT("Chevauchement des horaires avec \"%s\" sur %") A2t
+ TEXT(", qui ne partage pas le même multiplex !"),
+ prog_verif.nom,
+ Canaux[ixChaine2].nom).c_str()) )
+ return false;
+ }
+ }
+ }
+
+ return true; // pas d'erreur
+}
+
+/**
+ * \brief Génération du nom de tâche programmée correspondant
+ *
+ * \param[in] pstr Pointeur sur le tampon qui va recevoir le nom
+ * \param[in] bufSize Taille de ce tampon
+ **/
+void Programme::genereNomTache(LPWSTR pstr, UINT bufSize) const
+{
+ TCHAR szTmp[256];
+
+ if (*prefix_conf)
+ _stprintf_s(szTmp, TEXT("PTV[%s]-%s") , prefix_conf, nom);
+ else
+ _stprintf_s(szTmp, TEXT("PTV-%s"), nom);
+
+ // Remplace les caractères incorrects :
+ NomProtege nom_tache(szTmp, TCHAR('_'));
+
+ // On convertit le nom de la tâche en Unicode (s'il ne l'est pas déjà) :
+ nom_tache.Extract(pstr, bufSize);
+}
+
+/**
+ * \brief Ajout de cette programmation aux tâches programmées
+ *
+ * \param[in] username Nom d'utilisateur
+ * \param[in] motdepasse Mot de passe
+ * \retval \p true ou \p false selon succès ou échec, respectivement
+ **/
+bool Programme::ajouterTacheProgrammee(LPCWSTR username, LPCWSTR motdepasse) const
+{
+ WCHAR taskName[_countof(nom)+4];
+ SYSTEMTIME date = debut;
+ CComPtr pTask;
+ HRESULT hr;
+
+ AddTime(date, -60*1000); // Soustraire 60 secondes
+
+ // On génère le nom de la tâche :
+ genereNomTache(taskName, _countof(taskName));
+
+ // Accède au planificateur pour supprimer la tâche si elle existe
+ {
+ CComPtr pITS;
+
+ hr = pITS.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER);
+ if (FAILED(hr)) {
+ myprintf(TEXT("Erreur init task scheduler") EOL);
+ return false;
+ }
+ // Supprime la tâche
+ pITS->Delete(taskName);
+
+ // Crée la nouvelle tâche
+ hr = pITS->NewWorkItem(taskName, CLSID_CTask, IID_ITask, (IUnknown**)&pTask);
+ }
+
+ if (FAILED(hr)) {
+ myprintf(TEXT("Erreur création tâche %s") EOL, taskName);
+ return false;
+ }
+
+ wchar_t szTmp[MAX_PATH];
+
+ // Définition de la tâche
+ GetModuleFileNameW(NULL, szTmp, _countof(szTmp));
+ pTask->SetApplicationName(szTmp);
+
+ swprintf_s(szTmp, L"--minimize%" T2w, GetInstancePrefix().c_str());
+ pTask->SetParameters(szTmp);
+
+ GetCurrentDirectoryW(_countof(szTmp), szTmp);
+ pTask->SetWorkingDirectory(szTmp);
+
+ hr = pTask->SetAccountInformation(username, motdepasse);
+ if (SUCCEEDED(hr)) {
+ WORD piNewTrigger;
+ CComPtr pTaskTrigger;
+
+ pTask->SetFlags(TASK_FLAG_DELETE_WHEN_DONE | TASK_FLAG_SYSTEM_REQUIRED);
+ pTask->SetMaxRunTime(INFINITE);
+ pTask->CreateTrigger(&piNewTrigger, &pTaskTrigger);
+
+ TASK_TRIGGER Trig = {
+ sizeof(Trig), // cbTriggerSize
+ 0, // Reserved1
+ date.wYear, // wBeginYear
+ date.wMonth, // wBeginMonth
+ date.wDay, // wBeginDay
+ 0, // wEndYear
+ 0, // wEndMonth
+ 0, // wEndDay
+ date.wHour, // wStartHour
+ date.wMinute, // wStartMinute
+ 0, // rgFlags
+ TASK_TIME_TRIGGER_ONCE // TriggerType (Pas de répétition de la tâche, par défaut)
+ // le reste à zéro (implicite)
+ };
+
+ if (repetition!=0) {
+ // On a demandé à ce que la tâche soit répétée
+ Trig.TriggerType = TASK_TIME_TRIGGER_WEEKLY;
+
+ WEEKLY & jours = Trig.Type.Weekly;
+
+ jours.WeeksInterval = 1; // Répète toutes les semaines
+ jours.rgfDaysOfTheWeek = 0;
+
+ static const BYTE repFlgs[7] =
+ {TASK_SUNDAY, TASK_MONDAY, TASK_TUESDAY, TASK_WEDNESDAY,
+ TASK_THURSDAY, TASK_FRIDAY, TASK_SATURDAY};
+
+ for (int i=0; i<7; i++) {
+ if ((repetition & (1<SetTrigger(&Trig);
+
+ CComQIPtr pPersistFile(pTask);
+
+ if (pPersistFile)
+ pPersistFile->Save(NULL, TRUE);
+ }
+
+ return true;
+}
+
+/**
+ * \brief Ajout de la programmation si nécessaire, incluant identification
+ *
+ * \param[in] hDlg Handle du dialogue parent
+ * \retval \p true ou \p false selon succès ou échec, respectivement
+ **/
+bool Programme::ajoutTacheAvecLogon(HWND hDlg)
+{
+ // Par précaution, détruire d'abord toute tâche antérieurement existante portant
+ // le nom demandé :
+ supprimerTacheProgrammee();
+
+ if (etat==epr_actif && tache == planif_ajout) {
+ WCHAR username[256];
+ DWORD iLen = _countof(username);
+
+ GetUserNameW(username, &iLen); // Obtenir le nom de l'utilisateur courant
+
+ if (taskLogon(hDlg, username)) {
+ if (ajouterTacheProgrammee(username, mdp)) {
+ tache = planif_avec;
+ return true;
+ }
+ } else {
+ tache = planif_sans;
+ CheckDlgButton(hDlg, IDC_TACHE, BST_UNCHECKED);
+ MessageBox(hDlg, TEXT("Vous n'avez pas saisi de mot de passe valide :") EOL
+ TEXT("Cet enregistrement va être programmé sans ajout au gestionnaire des tâches."),
+ TEXT("Saisie de mot de passe annulée"), MB_ICONINFORMATION | MB_OK);
+ }
+ }
+ return false;
+}
+
+/**
+ * \brief Suppression de cette programmation de la liste des tâches programmées
+ *
+ * \retval \p true ou \p false selon succès ou échec, respectivement
+ **/
+bool Programme::supprimerTacheProgrammee() const
+{
+ // Nom de la tâche (réserver la taille du nom de l'émission plus une marge à cause de la taille
+ // du préfixe, lequel peut être assez long si un nom d'instance de PTVM y est inclus).
+ WCHAR taskName[_countof(nom)+32];
+
+ // On génère le nom de la tâche :
+ genereNomTache(taskName, _countof(taskName));
+
+ CComPtr pITS;
+
+ HRESULT hr = pITS.CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER);
+ if (FAILED(hr)) {
+ myprintf(TEXT("Erreur init task scheduler") EOL);
+ return false;
+ }
+
+ // Supprime la tâche
+ pITS->Delete(taskName);
+ return true;
+}
+
+/**
+ * Traitement du chargement de la liste des programmes au démarrage, et purge
+ * des enregistrements périmés
+ **/
+void init_programmation()
+{
+ // Charge la liste des programmes
+ lit_programmes();
+
+ SYSTEMTIME localtime;
+ GetLocalTime(&localtime);
+ int i = 0;
+ while (i < (int)Programmes.size()) {
+ Programme & prog = Programmes[i];
+ long diff = DiffTime(prog.fin, localtime);
+
+ if (diff <= 0) {
+ // On efface les programmes sans répétitions dont l'heure de fin est passée
+ if (prog.repetition==0) {
+ Programmes.erase(Programmes.begin()+i);
+ programmation_modifiee = true;
+ continue; // L'enregistrement courant ayant été supprimé, on n'incrémente pas 'i'
+ }
+
+ // Le cas échéant, on calcule la répétition suivante
+ // (mais ça a probablement déjà été fait ailleurs)
+ prog.ajustementDesRepetitions(localtime);
+ }
+ i++;
+ }
+
+ // Mises à jour éventuelles au cas où les opérations
+ // précédentes auraient modifié la programmation
+ record_list_updated();
+}
+
+/**
+ * Trouver l'index d'un enregistrement programmé à partir de son nom.
+ *
+ * \param[in] nom Nom de l'enregistrement recherché
+ * \retval Index numérique de l'enregistrement
+ * \retval -1 si nom vide ou rien trouvé.
+ **/
+int trouve_prog_par_nom(LPCTSTR nom)
+{
+ if (nom && nom[0] != 0) {
+ int nbProgrammes = (int)Programmes.size();
+
+ for (int i=0; i= -(60-1) && diff <= -(60-20)) {
+ // On a incrémenté les secondes mais reculé de (60-20) à (60-1) secondes
+ if (tempres.wSecond < 20)
+ toAdd = 60;
+ } else if (diff >= -(60-1)*60 && diff <= -(60-20)*60) {
+ // On a incrémenté les minutes mais reculé de (60-20) à (60-1) minutes
+ if (tempres.wMinute < 20)
+ toAdd = 60*60;
+ } else if (diff == -(24-1)*60*60) {
+ // On a incrémenté les heures mais reculé de (24-1) heures
+ if (tempres.wHour < 1)
+ toAdd = 24*60*60;
+ }
+ }
+ } else {
+ // On a avancé dans le temps
+
+ if (GetAsyncKeyState(VK_LBUTTON)<0 || GetAsyncKeyState(VK_SUBTRACT)<0 || GetAsyncKeyState(VK_DOWN)<0) {
+ // Traitement seulement si le bouton gauche de la souris ou une des touches
+ // '-' ou fleche en bas est couramment pressé :
+ if (diff >= (60-20) && diff <= (60-1)) {
+ // On a décrémenté les secondes mais avancé de (60-20) à (60-1) secondes
+ if (tempres.wSecond >= 60-20)
+ toAdd = -60;
+ } else if (diff >= (60-20)*60 && diff <= (60-1)*60) {
+ // On a décrémenté les minutes mais avancé de (60-20) à (60-1) minutes
+ if (tempres.wMinute >= 60-20)
+ toAdd = -60*60;
+ } else if (diff == (24-1)*60*60) {
+ // On a décrémenté les heures mais avancé de (24-1) heures
+ if (tempres.wHour >= 24-1)
+ toAdd = -24*60*60;
+ }
+ }
+ }
+
+ if (toAdd != 0) {
+ AddTime(tempres, toAdd*1000);
+ SetCtlTimeDate(hDlg, dateID, timeID, tempres);
+ }
+
+ result = tempres;
+}
+
+/**
+ * Chargement de la liste des enregistrements programmés.
+ * \param[in] hListItem “Handle” du contrôle de liste
+ **/
+static void remplit_liste_programmes(HWND hListItem)
+{
+ TCHAR buffer[64];
+
+ LVITEM item = {
+ LVIF_TEXT, // mask
+ 0, 0, 0, 0, // iItem, iSubItem, state, stateMask
+ buffer, // buffer
+ _countof(buffer) // cchTextMax
+ // le reste à zéro (implicite)
+ };
+
+ int nbProgrammes = (int)Programmes.size();
+
+ for(; item.iItem=apr_eteindrePC);
+ CheckDlgButton(hDlg, quitID, after>=apr_quitter);
+}
+
+/**
+ * Coche ou décoche les cases liées aux répétitions :
+ **/
+static void SetCtlRepeat(HWND hDlg, int repeatBaseID, BYTE repetition)
+{
+ for (int i=0; i<7; i++)
+ CheckDlgButton(hDlg, repeatBaseID+i, (repetition & (1<0 && *pwrk<=' ') // attention, type CHAR signé !!
+ pwrk++;
+ if (pwrk>pnom)
+ strcpy_T(pnom, bufSize, pwrk);
+
+ // Supprimer les espaces de fin :
+ UINT strSize = strlen_T(pnom);
+ while (strSize>0 && pnom[strSize-1]>0 && pnom[strSize-1]<=' ')
+ pnom[--strSize] = 0;
+}
+
+/**
+ * Récupère les données de l'enregistrement dans la fenêtre.
+ * Retourne 'true' si ces données sont valides, 'false' sinon.
+ **/
+static bool dlgToProg(HWND hDlg, Programme & prog, bool modif)
+{
+ UINT32 cleChaine;
+ int ixChaine;
+
+ // Récupérer la chaîne :
+ if ((ixChaine = (int)SendDlgItemMessage(hDlg, IDC_CHANNEL, CB_GETCURSEL, 0, 0))==CB_ERR) // index combo
+ return false;
+ if ((cleChaine = (UINT32)SendDlgItemMessage(hDlg, IDC_CHANNEL, CB_GETITEMDATA, ixChaine, 0))==0)// Clé
+ return false;
+ if (!ixChaine_ok(ixChaine = Canaux.trouve_par_cle(UINT32(cleChaine)))) // index chaîne
+ return false;
+
+ // Récupérer d'abord les dates, car un éventuel nom généré automatiquement se sert
+ // de la date de début :
+ GetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, prog.debut);
+ GetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, prog.fin);
+
+ // Ces deux valeurs ont été extraites de la boîte de dialogue au moment de leur sélection :
+ prog.methode = epg_typerecvideo;
+ prog.audio = epg_typerecaudio;
+
+ const Chaine & canal = Canaux[ixChaine];
+ NomProg nom;
+
+ // Récupérer le nom :
+ getDlgProgName(hDlg, nom, _countof(nom));
+
+ if (nom[0]==0) {
+ // le nom de la programmation est vide :
+ if (prog.nom[0]==0 || prog.nomAuto) {
+ // En générer un s'il n'y avait pas d'ancien nom,
+ // ou bien si celui-ci avait déjà été généré automatiquement :
+ unsigned ixSuffNom = 0;
+ //
+ do {
+ ixSuffNom++;
+ _stprintf_s(nom, _countof(nom),
+ ixSuffNom>1 ? TEXT("%") A2t TEXT("-%i-%02i_%u") : TEXT("%") A2t TEXT("-%i-%02i"),
+ prog.isMultiplex() ? "Multiplex" : canal.nom,
+ prog.debut.wDay, prog.debut.wMonth, ixSuffNom);
+ } while (_tcscmp(nom, prog.nom)!=0 && trouve_prog_par_nom(nom)>=0);
+ strcpy_T(prog.nom, nom);
+ prog.nomAuto = true;
+ }
+ } else {
+ strcpy_T(prog.nom, nom);
+ prog.nomAuto = false;
+ }
+
+ prog.nNumeroChaine = canal.nNumeroChaine;
+ prog.cleChaine = canal.cle();
+ prog.sidChaine = canal.SID; /// \deprecated \p sidChaine remplacé par \p cleChaine
+
+ prog.apres = GetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER);
+ prog.etat = IsDlgButtonChecked(hDlg, IDC_INACTIVE) == BST_CHECKED ? epr_inactif : epr_actif;
+
+ // Ajoute l'indicatif pour la répétition
+ prog.repetition = 0;
+ for (int i=0; i<7; i++) {
+ if (IsDlgButtonChecked(hDlg, IDC_REP_BASE+i) == BST_CHECKED)
+ prog.repetition |= 1<=_countof(canal.emis))
+ return false;
+
+ const Emission & emis = canal.emis[noEmis];
+
+ _tcsncpy_s(prog.nom, emis.nom, _countof(prog.nom)-1); // Tronquer si la longueur dépasse
+ prog.nom[_countof(prog.nom)-1] = 0;
+ prog.cleChaine = canal.cle();
+ prog.sidChaine = canal.SID; /// \deprecated \p sidChaine remplacé par \p cleChaine
+ prog.nNumeroChaine = canal.nNumeroChaine;
+ prog.apres = apr_rien;
+ prog.methode = meth_TS;
+ prog.audio = am_Mpeg_1;
+
+ // Ajout de l'heure de début et de l'heure de fin, avec leurs décalages respectifs :
+ prog.fin = emis.fin;
+ AddTime(prog.fin, retard_enreg * 60000);
+ prog.debut = emis.debut;
+ AddTime(prog.debut, avance_enreg * -60000);
+
+ prog.repetition = 0;
+ prog.tache = planif_sans;
+ prog.etat = epr_actif;
+
+ return true;
+}
+
+// Chargement des données de démarrage initialisant une nouvelle programmation :
+static void InitNewRecord(HWND hDlg)
+{
+ SYSTEMTIME localtime;
+
+ GetLocalTime(&localtime);
+
+ localtime.wSecond = 0;
+ localtime.wMilliseconds = 0;
+ SetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut = localtime);
+ SetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin = localtime);
+ CtlSelChannel(GetDlgItem(hDlg, IDC_CHANNEL), ixChaineCourante);
+ SendDlgItemMessage(hDlg, IDC_NAME, WM_SETTEXT, 0, (LPARAM)TEXT(""));
+
+ SetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER, apr_rien);
+ CheckDlgButton(hDlg, IDC_TACHE, BST_UNCHECKED);
+ CheckDlgButton(hDlg, IDC_INACTIVE, BST_UNCHECKED);
+
+ SetCtlRepeat(hDlg, IDC_REP_BASE, 0); // Répétitions
+}
+
+/**
+ * Remplissage d'une combo box de liste de chaînes actives.
+ **/
+static void remplit_liste_chaines(HWND hCtl)
+{
+ int nbChaines = (int)Canaux.size();
+
+ for (int i=0; i=0) {
+ // On ajoute le SID de la chaîne en tant que donnée associée :
+ // ceci servira à identifier la sélection, étant donné que l'index
+ // dans la combo box ne correspondra pas nécessairement à celui de la liste
+ // des chaînes, du fait des chaînes inactives possibles.
+ SendMessage(hCtl, CB_SETITEMDATA, res, canal.cle());
+ }
+ }
+ }
+}
+
+/**
+ * Remplissage d'une combo-box de méthodes d'enregistement
+ * \param[in] hCtl "Handle" de la combo-box
+ * \param[in] eSel Item sélectionné
+ **/
+void remplit_liste_methodes(HWND hCtl, MethodeEnregistrement eSel)
+{
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("TS"));
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("PS"));
+ if (allow_stream_record)
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("Multiplex"));
+ SendMessage(hCtl, CB_SETCURSEL, eSel, 0);
+}
+
+/**
+ * Remplissage d'une combo-box d'items audio
+ * \param[in] hCtl "Handle" de la combo-box
+ * \param[in] eSel Item sélectionné
+ **/
+void remplit_liste_audio(HWND hCtl, AudioMode eSel)
+{
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("1ère piste"));
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("Mpeg (1ère)"));
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("Mpeg (2ème)"));
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("(E)AC3"));
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("(E)AC3 2.0"));
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("(E)AC3 HC"));
+ SendMessage(hCtl, CB_ADDSTRING, 0, (LPARAM)TEXT("V.O."));
+ SendMessage(hCtl, CB_SETCURSEL, eSel, 0);
+}
+
+/**
+ * Initialisation des items de méthodes d'enregistrement d'un dialogue d'enregistrements programmés
+ * \param[in] hDlg "Handle" de la boîte de dialogue
+ **/
+void init_methodes(HWND hDlg)
+{
+ HWND hCtlMtd = GetDlgItem(hDlg, IDC_METHOD);
+ HWND hCtlAud = GetDlgItem(hDlg, IDC_AUDIO);
+
+ remplit_liste_methodes(hCtlMtd, epg_typerecvideo);
+ remplit_liste_audio(hCtlAud, epg_typerecaudio);
+
+ EnableWindow(hCtlAud, epg_typerecvideo == meth_PS);
+}
+
+/**
+ * Mise à jour des méthodes d'enregistrement après changement d'un des items de dialogue
+ * qui les contrôlent
+ * \param[in] hDlg "Handle" de la boîte de dialogue
+ **/
+void update_methodes(HWND hDlg)
+{
+ HWND hCtlMtd = GetDlgItem(hDlg, IDC_METHOD);
+ HWND hCtlAud = GetDlgItem(hDlg, IDC_AUDIO);
+
+ epg_typerecvideo = (MethodeEnregistrement)SendMessage(hCtlMtd, CB_GETCURSEL, 0, NULL);
+ epg_typerecaudio = (AudioMode)SendMessage(hCtlAud, CB_GETCURSEL, 0, NULL);
+
+ EnableWindow(hCtlAud, epg_typerecvideo == meth_PS);
+}
+
+static void update_edit_state(HWND hDlg, int selection)
+{
+ NomProg nom;
+ bool edit = selection>=0 && Programmes[selection].etat!=epr_encours;
+
+ EnableWindow(GetDlgItem(hDlg, IDC_MODIFY), edit);
+ EnableWindow(GetDlgItem(hDlg, IDC_REMOVE), edit);
+
+ // Activation ou désactivation du bouton "Ajouter" selon le contenu de l'item
+ // d'édition de nom (ne doit pas être vide et ne doit pas déjà exister) :
+ getDlgProgName(hDlg, nom, _countof(nom));
+ EnableWindow(GetDlgItem(hDlg, IDC_ADD), trouve_prog_par_nom(nom)<0);
+}
+
+static INT_PTR CALLBACK RecordDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static HWND hListItem = NULL;
+ static int selection = -1; // Index de l'item couramment sélectionné si >= 0
+ static NomProg selProgNom = TEXT(""); // Nom de la sélection courante (pour pouvoir reconstituer celle-ci
+ // après modification ou tri de la liste)
+
+ switch (uMsg) {
+
+ case WM_INITDIALOG: {
+
+ selProgNom[0] = 0;
+ hListItem = GetDlgItem(hDlg, IDC_LIST_PROGRAMMES);
+
+ static const struct Tab_cols t_cols[] = {
+ {TEXT("Nom"), 160},
+ {TEXT("Chaîne"), 86},
+ {TEXT("Début"), 140},
+ {TEXT("Fin"), 48},
+ {TEXT("État"), 78},
+ {NULL, 0} // Terminateur
+ };
+
+ ListView_AjouteColonnes(hListItem, t_cols);
+ remplit_liste_programmes(hListItem);
+ remplit_liste_chaines(GetDlgItem(hDlg, IDC_CHANNEL)); // Chargement du combo de choix des chaînes
+ init_methodes(hDlg);
+ InitNewRecord(hDlg);
+ update_edit_state(hDlg, selection);
+ ShowCursor(TRUE); // Suspend la disparition temporisée du curseur
+ return TRUE; }
+
+ case WM_NOTIFY:
+ switch (wParam) {
+
+ case IDC_LIST_PROGRAMMES:
+ if (_ncode_(lParam)==NM_CLICK) {
+ selection = ListView_GetSelectionMark(hListItem);
+ if (selection>=0) {
+ // Clic dans la liste des programmations
+ const Programme & prog = Programmes[selection];
+
+ progToDlg(hDlg, prog);
+ dtc_debut = prog.debut;
+ dtc_fin = prog.fin;
+
+ SendDlgItemMessage(hDlg, IDC_METHOD, CB_SETCURSEL, epg_typerecvideo = prog.methode, NULL);
+ SendDlgItemMessage(hDlg, IDC_AUDIO, CB_SETCURSEL, epg_typerecaudio = prog.audio, NULL);
+ EnableWindow(GetDlgItem(hDlg, IDC_AUDIO), epg_typerecvideo == meth_PS);
+
+ SetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER, prog.apres);
+
+ CheckDlgButton(hDlg, IDC_TACHE,
+ prog.tache!=planif_sans ? BST_CHECKED : BST_UNCHECKED);
+
+ // Coche les cases pour les répétitions :
+ SetCtlRepeat(hDlg, IDC_REP_BASE, prog.repetition);
+
+ strcpy_T(selProgNom, prog.nom);
+ return TRUE;
+ }
+ update_edit_state(hDlg, selection);
+ } else if (_ncode_(lParam)==LVN_KEYDOWN) {
+ LPNMLVKEYDOWN pnkd = (LPNMLVKEYDOWN) lParam;
+ if (pnkd->wVKey == VK_DELETE)
+ SendMessage(hDlg, WM_COMMAND, MAKEWPARAM(IDC_REMOVE, 0), 0);
+ } else if (_ncode_(lParam)==NM_CUSTOMDRAW) {
+ NMLVCUSTOMDRAW & sNlcd = *reinterpret_cast(lParam);
+
+ switch(sNlcd.nmcd.dwDrawStage) {
+
+ case CDDS_PREPAINT:
+ SetWindowLongPtr(hDlg, DWLP_MSGRESULT, CDRF_NOTIFYITEMDRAW);
+ return TRUE;
+
+ case CDDS_ITEMPREPAINT: {
+ const Programme & prog = Programmes[sNlcd.nmcd.dwItemSpec];
+
+ switch (prog.etat) {
+
+ case epr_actif:
+ sNlcd.clrText = RGB(0,128,255);
+ break;
+
+ case epr_encours:
+ sNlcd.clrText = RGB(255,0,0);
+ break;
+
+ case epr_interrompu:
+ case epr_termine:
+ case epr_inactif:
+ sNlcd.clrText = RGB(128,128,128);
+ break;
+
+ case epr_supplante:
+ case epr_erreur:
+ sNlcd.clrText = RGB(128,0,128);
+ }
+ return TRUE; }
+ }
+ }
+ break;
+
+ case IDC_DATE_START:
+ case IDC_TIME_START:
+ if (_ncode_(lParam)==DTN_DATETIMECHANGE) {
+ GetCtlTimeDateChg(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
+ GetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
+ if (DiffTime(dtc_debut, dtc_fin) > 0)
+ SetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin = dtc_debut);
+ }
+ break;
+
+ case IDC_DATE_END:
+ case IDC_TIME_END:
+ if (_ncode_(lParam)==DTN_DATETIMECHANGE) {
+ GetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
+ GetCtlTimeDateChg(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
+ if (DiffTime(dtc_debut, dtc_fin) > 0)
+ SetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut = dtc_fin);
+ }
+ }
+ return FALSE;
+
+ case WM_COMMAND:
+ switch(LOWORD(wParam)) {
+
+ case IDC_ADD_24: // Ajouter 24h des deux côtés
+ GetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
+ AddTime(dtc_debut, 24 * 60 * 60 * 1000);
+ SetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
+ GetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
+ AddTime(dtc_fin, 24 * 60 * 60 * 1000);
+ SetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
+ break;
+
+ case IDC_SUB_24: // Soustraire 24h des deux côtés
+ GetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
+ AddTime(dtc_debut, -24 * 60 * 60 * 1000);
+ SetCtlTimeDate(hDlg, IDC_DATE_START, IDC_TIME_START, dtc_debut);
+ GetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
+ AddTime(dtc_fin, -24 * 60 * 60 * 1000);
+ SetCtlTimeDate(hDlg, IDC_DATE_END, IDC_TIME_END, dtc_fin);
+ break;
+
+ case IDC_METHOD:
+ case IDC_AUDIO:
+ if (HIWORD(wParam) == CBN_SELCHANGE) {
+ update_methodes(hDlg);
+ return TRUE;
+ }
+ break;
+
+ case IDC_NAME:
+ if (HIWORD(wParam) == EN_CHANGE) {
+ update_edit_state(hDlg, selection);
+ return TRUE;
+ }
+ break;
+
+ case IDC_REMOVE:
+ if (selection >= 0 && Programmes[selection].etat!=epr_encours) {
+ ListView_DeleteItem(hListItem, selection);
+
+ // Suppression éventuelle tâche antérieure portant ce nom :
+ Programmes[selection].supprimerTacheProgrammee();
+
+ Programmes.erase(Programmes.begin() + selection);
+ finalize_prog_change();
+ }
+ return TRUE;
+
+ case IDC_MODIFY:
+ if (selection >= 0) {
+ Programme & prog = Programmes[selection];
+ Programme newprog = prog;
+
+ if (dlgToProg(hDlg, newprog, true) && prog.verifie(&prog)) {
+ // Récupération et vérification données du dialogue
+
+ if (prog.etat == epr_encours)
+ MessageBox(hDlg, TEXT("Cet enregistrement est actuellement en cours.") EOL
+ TEXT("Utilisez la commande \"Arrêter l'enregistrement dans...\"")
+ TEXT(" pour y apporter des modifications maintenant."),
+ TEXT("Erreur lors de la modification"), MB_ICONERROR);
+ else {
+ // Suppression éventuelle tâche antérieure portant l'ancien nom :
+ prog.supprimerTacheProgrammee();
+
+ prog = newprog;
+
+ strcpy_T(selProgNom, prog.nom);
+ prog.ajoutTacheAvecLogon(hDlg);
+
+ finalize_prog_change();
+ }
+ }
+ }
+ return TRUE;
+
+ case IDC_ADD: {
+ Programme prog;
+
+ // Récupération des données de l'enregistrement depuis la boîte de dialogue
+ if (!dlgToProg(hDlg, prog, false) || !prog.verifie())
+ return FALSE;
+
+ strcpy_T(selProgNom, prog.nom);
+ prog.ajoutTacheAvecLogon(hDlg);
+ Programmes.push_back(prog);
+
+ finalize_prog_change();
+ return TRUE; }
+
+ case IDC_NEW:
+ // Réinitialiser les données de programmation
+ InitNewRecord(hDlg);
+ selection = -1;
+ selProgNom[0] = 0;
+ update_edit_state(hDlg, selection);
+ return TRUE;
+
+ case IDC_CURRENT_PROGRAM: {
+ // Charger les données de l'émission en cours
+ Programme prog;
+
+ if (chaineToProg(ixChaineCourante, 0, prog)) {
+ progToDlg(hDlg, prog);
+ dtc_debut = prog.debut;
+ dtc_fin = prog.fin;
+ selection = -1;
+ selProgNom[0] = 0;
+ update_edit_state(hDlg, selection);
+ }
+ return TRUE; }
+
+ case IDC_AFTER_POWEROFF:
+ // Coche le bouton arrêtant PouchinTV si on a demandé l'arrêt de l'ordinateur
+ if (IsDlgButtonChecked(hDlg, IDC_AFTER_POWEROFF) == BST_CHECKED)
+ CheckDlgButton(hDlg, IDC_AFTER, BST_CHECKED);
+ return TRUE;
+
+ case IDC_AFTER:
+ // Décoche le bouton arrêtant le PC si on ne souhaite pas arrêter PouchinTV
+ if (IsDlgButtonChecked(hDlg, IDC_AFTER) == BST_UNCHECKED)
+ CheckDlgButton(hDlg, IDC_AFTER_POWEROFF, BST_UNCHECKED);
+ return TRUE;
+
+ case IDOK:
+ DestroyWindow(hDlg);
+ return TRUE;
+ }
+ break;
+
+ case WM_CLOSE:
+ DestroyWindow(hDlg);
+ return TRUE;
+
+ case WM_NCDESTROY:
+ // Fermeture de la boîte de dialogue : on efface le mot de passe
+ SecureZeroMemory(mdp, sizeof(mdp));
+
+ hRecordDlg = NULL;
+ ShowCursor(FALSE); // Rétablit la disparition temporisée du curseur
+ return TRUE;
+
+ case WM_APP_PROG_CHANGED:
+ // Reconstruction de la liste des enregistrements programmés après changement :
+ ListView_DeleteAllItems(hListItem);
+ remplit_liste_programmes(hListItem);
+ selection = trouve_prog_par_nom(selProgNom);
+ if (selection>=0)
+ ListView_SetItemState(hListItem, selection, LVIS_SELECTED, LVIS_SELECTED);
+ update_edit_state(hDlg, selection);
+ return TRUE;
+
+ }
+
+ return FALSE;
+}
+
+/**
+ * Ouverture du dialogue des enregistrements programmés
+ **/
+void open_record_dialog()
+{
+ if (hRecordDlg)
+ BringWindowToTop(hRecordDlg);
+ else {
+ hRecordDlg = CreateDialog(hAppInstance,
+ MAKEINTRESOURCE(IDD_DELAYED_RECORD), hMainWnd, RecordDialogProc);
+ ShowWindow(hRecordDlg, SW_SHOW);
+ }
+}
+
+/**
+ * Traitement des événements liés au dialogue d'enregistrement.
+ * Retourne \p true si le message \p msg a été traité, auquel cas il ne faut pas le
+ * passer à \p TranslateMessage et \p DispatchMessage.
+ * À placer dans la boucle de gestion générale des messages.
+ **/
+bool is_record_dialog_message(MSG & msg) {
+ if (hRecordDlg!=NULL && IsDialogMessage(hRecordDlg, &msg))
+ return true;
+ return false;
+}
+
+/**
+ * Transformation d'un horaire de fin en temps restant
+ **/
+static SYSTEMTIME EndTimeToRemTime(SYSTEMTIME time)
+{
+ SYSTEMTIME localtime;
+ LONG wMillisec;
+
+ GetLocalTime(&localtime);
+ wMillisec = DiffTime(time, localtime);
+
+ // S'assurer que l'heure de fin tombe bien dans les 24 heures qui suivent :
+ #define ONEDAY (24*60*60*1000)
+ while (wMillisec<0)
+ wMillisec += ONEDAY;
+ while (wMillisec>=ONEDAY)
+ wMillisec -= ONEDAY;
+ #undef ONEDAY
+
+ time.wMilliseconds = WORD(wMillisec % 1000);
+ wMillisec /= 1000;
+ time.wSecond = WORD(wMillisec % 60);
+ wMillisec /= 60;
+ time.wMinute = WORD(wMillisec % 60);
+ wMillisec /= 60;
+ time.wHour = WORD(wMillisec);
+ return time;
+}
+
+/**
+ * Transformation d'un temps restant en horaire de fin
+ **/
+static SYSTEMTIME RemTimeToEndTime(SYSTEMTIME time)
+{
+ LONG wMillisec = ((time.wHour*60 + time.wMinute)*60 + time.wSecond)*1000 + time.wMilliseconds;
+
+ GetLocalTime(&time);
+ AddTime(time, wMillisec);
+ return time;
+}
+
+enum DlgEditState {
+ des_notModified, // Aucun changement à appliquer
+ des_noConfirmNeed, // Un changement peut-être appliqué mais son annulation n'a pas
+ // besoin d'être explicite
+ des_needConfirm // Un changement a été effectué mais son annulation doit être explicite
+};
+
+struct DelayEditData {
+ HWND hDlg;
+ HWND hEnrCombo;
+ HWND hTimeCtl;
+ int ixRecDescr; // index du descripteur d'enregistrement
+ int comboSel; // item couramment sélectionné dans la combo box
+ Enregistrement * penreg; // pointeur enregistrement à modifier
+ SYSTEMTIME refTime; // Contenu du contrôle de temps, soit en tant qu'heure de fin,
+ // soit en tant que temps restant, selon le contenu de
+ // 'useEndTime' (définit le temps de référence)
+ bool useEndTime; // vrai si le temps mémorisé (refTime) est l'heure de fin
+ bool dispEndTime; // vrai si le contrôle affiche l'heure de fin
+ bool delayActive; // vrai si la temporisation sera activée
+ DlgEditState dlgEditState; // niveau de modifications effectuées
+
+ void remplitCombo();
+ void load(bool initActive); // charger les données de l'enregistrement N° 'ixRecDescr'
+ void setCtlTime(); // Transférer le temps de référence dans le contrôle, selon le mode courant
+ bool needTimer() const {return delayActive && dispEndTime != useEndTime;}
+ void toEndTime(void); // convertir en mode "heure de fin"
+ void apply(void); // appliquer les changements
+ void setChangedState(DlgEditState newState); // Indique comment le contenu du dialogue a été modifié ou pas
+ void setActiveState(bool active); // Modifie l'état "actif" de la fin d'enregistrement programmée
+ void recordEnded(void);
+};
+
+// Chargement du combo des chaînes en cours d'enregistrement :
+void DelayEditData::remplitCombo()
+{
+ TCHAR buf[64];
+ LPCSTR nom;
+ int res, i, sel=0;
+
+ comboSel = 0;
+ for (i = 0; i < enregistrements_actuels.count(); i++) {
+ const Enregistrement & enreg = enregistrements_actuels[i];
+
+ if (!enreg.recording())
+ continue;
+ nom = enreg.channelName();
+ if (*nom == '*')
+ strcpy_T(buf, "[ multiplex ]");
+ else
+ strcpy_T(buf, nom);
+ res = (int)SendMessage(hEnrCombo, CB_ADDSTRING, 0, LPARAM(buf));
+ SendMessage(hEnrCombo, CB_SETITEMDATA, res, i);
+ if (i==ixRecDescr)
+ sel = res;
+ }
+
+ comboSel = (int)SendMessage(hEnrCombo, CB_SETCURSEL, sel, 0);
+}
+
+// Chargement des données de l'enregistrement 'ixRecDescr'.
+// Si 'initActive' = true, le dialogue sera préparé pour activation si aucune
+// temporisation n'existait auparavant pour cet enregistrement
+// (afin d'éviter à l'utilisateur d'avoir à cliquer sur la case d'activation
+// lors de l'ouverture du dialogue). Il restera néanmoins nécessaire de valider
+// ce changement.
+void DelayEditData::load(bool initActive)
+{
+ if (ixRecDescr<0)
+ ixRecDescr = 0;
+ penreg = &enregistrements_actuels[ixRecDescr];
+
+ CheckDlgButton(hDlg, IDC_DELAY_BY_REMTIME, BST_CHECKED);
+ dispEndTime = false;
+ if (!penreg->recording()) {
+ recordEnded();
+ } else {
+ EnableWindow(GetDlgItem(hDlg, IDC_DELAY_ACTIVE), TRUE);
+ if (penreg->apres != apr_null) {
+ setActiveState(true);
+ SetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER, penreg->apres);
+ refTime = penreg->fin;
+ useEndTime = true;
+ setChangedState(des_notModified);
+ } else {
+ setActiveState(initActive);
+ GetLocalTime(&refTime);
+ // Indiquer temps restant = 1/2 heure par défaut.
+ refTime.wHour = refTime.wSecond = refTime.wMilliseconds = 0;
+ refTime.wMinute = 30;
+ useEndTime = false;
+ setChangedState(initActive ? des_noConfirmNeed : des_notModified);
+ }
+ }
+ CheckDlgButton(hDlg, IDC_DELAY_ACTIVE, delayActive);
+ setCtlTime();
+}
+
+// Modifie l'état "actif" de la fin d'enregistrement programmée
+void DelayEditData::setActiveState(bool active)
+{
+ static const int t_id[] =
+ {IDC_DELAYED_STOP, IDC_DELAY_LABEL, IDC_DELAY_BY_REMTIME, IDC_DELAY_BY_ENDTIME,
+ IDC_AFTER_RECORD, IDC_AFTER, IDC_AFTER_POWEROFF, IDC_AFTER_NOTE};
+
+ delayActive = active;
+ for (int i=0; i<_countof(t_id); i++)
+ EnableWindow(GetDlgItem(hDlg, t_id[i]), delayActive);
+}
+
+// Fonction appelée si l'enregistrement se termine pendant que le dialogue
+// est ouvert :
+void DelayEditData::recordEnded(void)
+{
+ setActiveState(false);
+ EnableWindow(GetDlgItem(hDlg, IDC_DELAY_ACTIVE), FALSE);
+}
+
+// Indique si le contenu du dialogue a été modifié ou pas
+void DelayEditData::setChangedState(DlgEditState newState)
+{
+ bool modified = newState!=des_notModified;
+ bool oldActive = penreg && penreg->apres!=apr_null;
+ bool activeChanged = delayActive != oldActive;
+
+ dlgEditState = newState;
+ EnableWindow(GetDlgItem(hDlg, IDC_APPLY), modified && (delayActive || activeChanged));
+}
+
+void DelayEditData::toEndTime(void)
+{
+ if (useEndTime) {
+ // Si on utilise déjà l'heure de fin, on effectue une double conversion
+ // pour s'assurer que celle-ci se trouve bien dans le futur, et non pas
+ // plus tôt dans la journée (étant donné que le dialogue ne peut pas
+ // définir la date).
+ refTime = EndTimeToRemTime(refTime);
+ useEndTime = false;
+ }
+ if (!useEndTime) {
+ refTime = RemTimeToEndTime(refTime);
+ useEndTime = true;
+ }
+}
+
+void DelayEditData::setCtlTime()
+{
+ if (dispEndTime==useEndTime)
+ DateTime_SetSystemtime(hTimeCtl, GDT_VALID, &refTime);
+ else {
+ SYSTEMTIME tmptime = (dispEndTime ? RemTimeToEndTime : EndTimeToRemTime)(refTime);
+
+ DateTime_SetSystemtime(hTimeCtl, GDT_VALID, &tmptime);
+ }
+};
+
+// Application des modifications :
+void DelayEditData::apply(void)
+{
+ if (penreg->recording() && dlgEditState!=des_notModified) { // Toujours en train d'enregistrer ?
+ ApresEnregistrement apres = delayActive ?
+ GetCtlAfter(hDlg, IDC_AFTER_POWEROFF, IDC_AFTER) :
+ apr_null;
+
+ toEndTime();
+ penreg->fin = refTime;
+ penreg->apres = apres;
+
+ // Rechercher si l'arrêt retardé résultait d'une programmation,
+ // afin de mettre à jour celle-ci en même temps, le cas échéant :
+ int ixProg = trouve_prog_par_nom(penreg->nom);
+
+ if (ixProg>=0) {
+ Programme & prog = Programmes[ixProg];
+
+ programmation_modifiee = true;
+ if (prog.repetition != 0) {
+ // La programmation comporte des répétitions :
+ // on se contente de la "déconnecter" de l'enregistrement, lui permettant
+ // ainsi d'être reportée intégralement à son occurrence suivante.
+ prog.etat = epr_supplante;
+ } else {
+ if (apres == apr_null) {
+ // On a annulé l'arrêt d'enregistrement (celui-ci
+ // peut donc se poursuivre indéfiniment)
+ prog.etat = epr_supplante;
+ } else {
+ // On a modifié l'heure ou l'action de fin : on reporte les
+ // modifications dans la programmation, de sorte qu'un arrêt
+ // impromptu éventuel du programme suivi d'une relance
+ // (plantage ?) reprennne le reliquat ainsi.
+ prog.fin = refTime;
+ prog.apres = apres;
+ }
+ }
+ record_list_updated();
+ }
+
+ setChangedState(des_notModified);
+ PostMessage(hMainWnd, WM_TIMECHANGE, 0, 0);
+ }
+}
+
+// Gestion du dialogue des arrêts d'enregistrement temporisés :
+static INT_PTR CALLBACK DelayedStopDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ static DelayEditData edat = {0}; // tout à zéro, false ou NULL à l'initialisation
+
+ switch (uMsg) {
+
+ case WM_INITDIALOG:
+ edat.hDlg = hDlg;
+ edat.hEnrCombo = GetDlgItem(hDlg, IDC_CHANNEL);
+ edat.hTimeCtl = GetDlgItem(hDlg, IDC_DELAYED_STOP);
+ edat.ixRecDescr = enregistrements_actuels.getRecordingDescr(ixChaineCourante);
+ edat.load(false /*true*/);
+ edat.remplitCombo(); // Chargement du combo des enregistrements
+
+ // Création d'un timer battant à la seconde pour la mise à jour du contrôle de saisie
+ // de l'heure (selon son mode d'affichage), ainsi que la détection des
+ // enregistrements terminés.
+ SetTimer(hDlg, TIMER_DELAYED_STOP, 1000, NULL);
+ return TRUE;
+
+ case WM_TIMER:
+ if (!edat.penreg->recording()) // Tester si l'enregistrement se termine à ce moment
+ edat.recordEnded();
+ if (edat.needTimer())
+ edat.setCtlTime();
+ return TRUE;
+
+ case WM_COMMAND: {
+ switch(wParam) {
+
+ case _cmd_(IDC_CHANNEL, CBN_SELCHANGE): {
+ int newSel = (int)SendMessage(edat.hEnrCombo, CB_GETCURSEL, 0, 0);
+
+ if (newSel!=CB_ERR && newSel!=edat.comboSel) {
+ if (edat.dlgEditState==des_needConfirm) {
+ switch (MessageBox(hDlg,
+ TEXT("Vous avez apporté des modifications à la programmation de la chaîne en cours.") EOL
+ TEXT("Désirez-vous valider ces modifications ?"),
+ TEXT("Changement de chaîne"),
+ MB_YESNOCANCEL)) {
+
+ case IDCANCEL:
+ SendMessage(edat.hEnrCombo, CB_SETCURSEL, WPARAM(edat.comboSel), 0);
+ return TRUE;
+
+ case IDYES:
+ edat.apply();
+ case IDNO: ;
+ }
+ }
+ edat.comboSel = newSel;
+ edat.ixRecDescr = (int)SendMessage(edat.hEnrCombo, CB_GETITEMDATA, WPARAM(newSel), 0);
+ edat.load(false /*true*/);
+ }
+ return TRUE; }
+
+ case _cmd_(IDC_DELAY_BY_REMTIME, BN_CLICKED):
+ case _cmd_(IDC_DELAY_BY_ENDTIME, BN_CLICKED):
+ edat.dispEndTime = IsDlgButtonChecked(hDlg, IDC_DELAY_BY_ENDTIME)==BST_CHECKED;
+ edat.setCtlTime();
+ return TRUE;
+
+ case _cmd_(IDC_DELAY_ACTIVE, BN_CLICKED):
+ edat.setActiveState(IsDlgButtonChecked(hDlg, IDC_DELAY_ACTIVE)==BST_CHECKED);
+ edat.setChangedState(des_needConfirm);
+ return TRUE;
+
+ case _cmd_(IDC_AFTER, BN_CLICKED):
+ // Décoche le bouton arrêtant le PC si on ne souhaite pas arrêter PouchinTV
+ if (IsDlgButtonChecked(hDlg, IDC_AFTER) == BST_UNCHECKED)
+ CheckDlgButton(hDlg, IDC_AFTER_POWEROFF, BST_UNCHECKED);
+ edat.setChangedState(des_needConfirm);
+ return TRUE;
+
+ case _cmd_(IDC_AFTER_POWEROFF, BN_CLICKED):
+ // Coche le bouton arrêtant PouchinTV si on a demandé l'arrêt de l'ordinateur
+ if (IsDlgButtonChecked(hDlg, IDC_AFTER_POWEROFF) == BST_CHECKED)
+ CheckDlgButton(hDlg, IDC_AFTER, BST_CHECKED);
+ edat.setChangedState(des_needConfirm);
+ return TRUE;
+
+ case _cmd_(IDC_APPLY, BN_CLICKED):
+ edat.apply();
+ return TRUE;
+
+ case _cmd_(IDOK, BN_CLICKED):
+ edat.apply();
+ // ...
+ case _cmd_(IDCANCEL, BN_CLICKED):
+ KillTimer(hDlg, TIMER_DELAYED_STOP);
+ EndDialog(hDlg, 0);
+ return TRUE;
+ }
+ break; }
+
+ case WM_NOTIFY:
+ if (_ncode_(lParam)==DTN_DATETIMECHANGE) {
+ DateTime_GetSystemtime(edat.hTimeCtl, &edat.refTime);
+ // Le mode d'affichage utilisé sert maintenant de référence :
+ edat.useEndTime = edat.dispEndTime;
+ edat.setChangedState(des_needConfirm);
+ }
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Appel du dialogue de fin d'enregistrement retardée.
+ **/
+void delayed_stop_dialog()
+{
+ ShowCursor(TRUE);
+ DialogBox(hAppInstance, MAKEINTRESOURCE(IDD_DELAYED_STOP), hMainWnd, DelayedStopDialogProc);
+ ShowCursor(FALSE);
+}
+
+/**
+ * Fonction à appeler en cas de changement externe possible de la liste des enregistrements programmés.
+ * Assure la sauvegarde des modification et la mise à jour de la liste dans la fenêtre de dialogue
+ * si celle-ci est ouverte.
+ **/
+void record_list_updated()
+{
+ if (programmation_modifiee) {
+ // Tri de la liste :
+ std::sort(Programmes.begin(), Programmes.end());
+
+ if (hRecordDlg)
+ PostMessage(hRecordDlg, WM_APP_PROG_CHANGED, 0, 0); // Reconstruction de la liste si couramment affichée
+
+ // Sauvegarde de la liste des programmes
+ sauve_programmes();
+ }
+}
+
+/**
+ * Finalisation d'un changement dans les enregistrements programmés.
+ **/
+void finalize_prog_change()
+{
+ programmation_modifiee = true;
+
+ // Mise à jour du timer des enregistrements :
+ set_timer_record();
+
+ // Mise à jour de l'affichage, et sauvegarde dans le fichier :
+ record_list_updated();
+}
+
+/**
+ * Démarre tous les enregistrements qui devraient l'être à cet instant précis.
+ * Retourne 'true' si au moins un changement de nature à affecter les menus
+ * ou la programmation d'enregistrement a eu lieu
+ **/
+static bool do_record_start(const SYSTEMTIME & localtime)
+{
+ long frequence_courante = 0;
+ int ixChaine = -1;
+ bool changement = false;
+
+ // Déterminer si on enregistre quelque chose actuellement, et si oui, quelle est la
+ // fréquence utilisée.
+ UINT32 cleChaine = enregistrements_actuels.recording();
+
+ if (cleChaine != 0) {
+ ixChaine = cleChaine != STREAM_PSEUDO_CLE ? Canaux.trouve_par_cle(cleChaine) : ixChaineCourante;
+
+ if (ixChaine_ok(ixChaine))
+ frequence_courante = Canaux[ixChaine].khz;
+ }
+
+ int nbProgrammes = (int)Programmes.size();
+
+ // Passer en revue les programmations définies afin de démarrer TOUS les enregistrements qui
+ // devraient être en cours et qui peuvent être démarrés.
+ for (int i=0; i
Changements entre les versions
-
valeur binaire.
* Cette structure est destinée à faire partie d'une table dont le dernier élément
* doit avoir ses deux valeurs à NULL et 0 respectivement.
From pouchintv-dev at baysse.fr Wed Jan 20 22:49:20 2010
From: pouchintv-dev at baysse.fr (=?iso-8859-1?q?Liste_utilis=E9e_par_les_d=E9veloppeurs?=)
Date: mer, 20 jan 2010 22:49:20 +0100
Subject: [Pouchintv-dev] [PouchinTVMod] gingko | r230 - in trunk: .
BaseClasses LCD_Logitech lzma lzma/LzmaUtil tinyxml tools
tools/ConditionalHeaderGenerator tools/GeneRealVersion
Message-ID: <20100120214929.203255F774@mail.baysse.fr>
Author: gingko
Date: 2010-01-20 22:49:20 +0100 (mer 20 jan 2010)
New Revision: 230
Modified:
trunk/AUTHORS
trunk/BaseClasses/Doxyfile
trunk/BaseClasses/amextra.cpp
trunk/BaseClasses/amextra.h
trunk/BaseClasses/amfilter.cpp
trunk/BaseClasses/amfilter.h
trunk/BaseClasses/amvideo.cpp
trunk/BaseClasses/arithutil.cpp
trunk/BaseClasses/baseclasses_2005.sln
trunk/BaseClasses/baseclasses_2005.vcproj
trunk/BaseClasses/baseclasses_2008.sln
trunk/BaseClasses/baseclasses_2008.vcproj
trunk/BaseClasses/cache.h
trunk/BaseClasses/checkbmi.h
trunk/BaseClasses/combase.cpp
trunk/BaseClasses/combase.h
trunk/BaseClasses/cprop.cpp
trunk/BaseClasses/cprop.h
trunk/BaseClasses/ctlutil.cpp
trunk/BaseClasses/ctlutil.h
trunk/BaseClasses/ddmm.cpp
trunk/BaseClasses/ddmm.h
trunk/BaseClasses/dllentry.cpp
trunk/BaseClasses/dllsetup.cpp
trunk/BaseClasses/dllsetup.h
trunk/BaseClasses/dxmperf.h
trunk/BaseClasses/fourcc.h
trunk/BaseClasses/measure.h
trunk/BaseClasses/msgthrd.h
trunk/BaseClasses/mtype.cpp
trunk/BaseClasses/mtype.h
trunk/BaseClasses/outputq.cpp
trunk/BaseClasses/outputq.h
trunk/BaseClasses/perflog.cpp
trunk/BaseClasses/perflog.h
trunk/BaseClasses/perfstruct.h
trunk/BaseClasses/pstream.cpp
trunk/BaseClasses/pstream.h
trunk/BaseClasses/pullpin.cpp
trunk/BaseClasses/pullpin.h
trunk/BaseClasses/refclock.cpp
trunk/BaseClasses/refclock.h
trunk/BaseClasses/reftime.h
trunk/BaseClasses/renbase.cpp
trunk/BaseClasses/renbase.h
trunk/BaseClasses/schedule.cpp
trunk/BaseClasses/schedule.h
trunk/BaseClasses/seekpt.cpp
trunk/BaseClasses/seekpt.h
trunk/BaseClasses/source.cpp
trunk/BaseClasses/source.h
trunk/BaseClasses/streams.h
trunk/BaseClasses/strmctl.cpp
trunk/BaseClasses/strmctl.h
trunk/BaseClasses/sysclock.cpp
trunk/BaseClasses/sysclock.h
trunk/BaseClasses/transfrm.cpp
trunk/BaseClasses/transfrm.h
trunk/BaseClasses/transip.cpp
trunk/BaseClasses/transip.h
trunk/BaseClasses/videoctl.cpp
trunk/BaseClasses/videoctl.h
trunk/BaseClasses/vtrans.cpp
trunk/BaseClasses/vtrans.h
trunk/BaseClasses/winctrl.cpp
trunk/BaseClasses/winctrl.h
trunk/BaseClasses/winutil.cpp
trunk/BaseClasses/winutil.h
trunk/BaseClasses/wxdebug.cpp
trunk/BaseClasses/wxdebug.h
trunk/BaseClasses/wxlist.cpp
trunk/BaseClasses/wxlist.h
trunk/BaseClasses/wxutil.cpp
trunk/BaseClasses/wxutil.h
trunk/LCD_Logitech/lglcd.h
trunk/Lisez-moi (setup).txt
trunk/Pouchin TV_2005.sln
trunk/REFERENCES
trunk/Setup_2005.vcproj
trunk/Setup_2008.vcproj
trunk/changelog.html
trunk/lzma/7zC.txt
trunk/lzma/7zFile.c
trunk/lzma/7zFile.h
trunk/lzma/7zFormat.txt
trunk/lzma/7zStream.c
trunk/lzma/7zVersion.h
trunk/lzma/Alloc.c
trunk/lzma/Alloc.h
trunk/lzma/CpuArch.h
trunk/lzma/LzFind.c
trunk/lzma/LzFind.h
trunk/lzma/LzFindMt.c
trunk/lzma/LzFindMt.h
trunk/lzma/LzHash.h
trunk/lzma/LzmaDec.c
trunk/lzma/LzmaDec.h
trunk/lzma/LzmaEnc.c
trunk/lzma/LzmaEnc.h
trunk/lzma/LzmaUtil/LzmaUtil.c
trunk/lzma/LzmaUtil/LzmaUtil.dsp
trunk/lzma/LzmaUtil/LzmaUtil.dsw
trunk/lzma/LzmaUtil/LzmaUtil_2005.sln
trunk/lzma/LzmaUtil/LzmaUtil_2005.vcproj
trunk/lzma/LzmaUtil/LzmaUtil_2008.sln
trunk/lzma/LzmaUtil/LzmaUtil_2008.vcproj
trunk/lzma/LzmaUtil/makefile
trunk/lzma/LzmaUtil/makefile.gcc
trunk/lzma/Methods.txt
trunk/lzma/Threads.c
trunk/lzma/Threads.h
trunk/lzma/Types.h
trunk/lzma/history.txt
trunk/lzma/lzma.txt
trunk/style.css
trunk/tinyxml/Makefile
trunk/tinyxml/changes.txt
trunk/tinyxml/dox
trunk/tinyxml/echo.dsp
trunk/tinyxml/readme.html
trunk/tinyxml/readme.txt
trunk/tinyxml/tinyXmlTest.dsp
trunk/tinyxml/tinyXmlTestSTL.dsp
trunk/tinyxml/tinyXmlTest_2005.vcproj
trunk/tinyxml/tinyXmlTest_2008.vcproj
trunk/tinyxml/tinystr.cpp
trunk/tinyxml/tinystr.h
trunk/tinyxml/tinyxml.cpp
trunk/tinyxml/tinyxml.dsw
trunk/tinyxml/tinyxml.h
trunk/tinyxml/tinyxmlSTL.dsp
trunk/tinyxml/tinyxml_2005.sln
trunk/tinyxml/tinyxml_2008.sln
trunk/tinyxml/tinyxml_lib.dsp
trunk/tinyxml/tinyxml_lib_2005.vcproj
trunk/tinyxml/tinyxml_lib_2008.vcproj
trunk/tinyxml/tinyxmlerror.cpp
trunk/tinyxml/tinyxmlparser.cpp
trunk/tinyxml/tutorial_gettingStarted.txt
trunk/tinyxml/utf8test.xml
trunk/tinyxml/utf8testverify.xml
trunk/tinyxml/xmltest.cpp
trunk/tools/ConditionalHeaderGenerator/ConditionalHeaderGenerator_2005.sln
trunk/tools/ConditionalHeaderGenerator/ConditionalHeaderGenerator_2005.vcproj
trunk/tools/ConditionalHeaderGenerator/ConditionalHeaderGenerator_2008.sln
trunk/tools/ConditionalHeaderGenerator/ConditionalHeaderGenerator_2008.vcproj
trunk/tools/GeneRealVersion/GeneRealVersion_2005.sln
trunk/tools/GeneRealVersion/GeneRealVersion_2005.vcproj
trunk/tools/GeneRealVersion/GeneRealVersion_2008.sln
trunk/tools/GeneRealVersion/GeneRealVersion_2008.vcproj
trunk/tools/gen_canaux.ini.pl
trunk/version
trunk/version.rc2
Log:
Ajustement des propriétés "svn:eol-style" (dans trunk) pour tous les fichiers restants non
modifiés du point de vue de leur contenu.
Modifié: trunk/AUTHORS
===================================================================
--- trunk/AUTHORS 2010-01-20 21:36:17 UTC (rev 229)
+++ trunk/AUTHORS 2010-01-20 21:49:20 UTC (rev 230)
@@ -1,19 +1,19 @@
-Original author
-Auteur du logiciel original
- Pouchin http://pouchinteve.free.fr/
-
-Mod's creator
-Créateur du Mod
- MatMaul (Mathieu Velten)
- http://www.etud.insa-toulouse.fr/~mvelten/pouchintvmod/
-
-
-Contributers sorted alphabetically by last name
-Contributeurs classés alphabétiquement par nom de famille
-
-Name/Nom Identifiant
-Laurent Baysse lolo_32
-Gilles Reeves gingko
-Christian Schoffit ef15c
-Mathieu Velten matmaul
-? radius
+Original author
+Auteur du logiciel original
+ Pouchin http://pouchinteve.free.fr/
+
+Mod's creator
+Créateur du Mod
+ MatMaul (Mathieu Velten)
+ http://www.etud.insa-toulouse.fr/~mvelten/pouchintvmod/
+
+
+Contributers sorted alphabetically by last name
+Contributeurs classés alphabétiquement par nom de famille
+
+Name/Nom Identifiant
+Laurent Baysse lolo_32
+Gilles Reeves gingko
+Christian Schoffit ef15c
+Mathieu Velten matmaul
+? radius
Property changes on: trunk/AUTHORS
___________________________________________________________________
Ajouté : svn:eol-style
+ native
Modifié: trunk/BaseClasses/Doxyfile
===================================================================
--- trunk/BaseClasses/Doxyfile 2010-01-20 21:36:17 UTC (rev 229)
+++ trunk/BaseClasses/Doxyfile 2010-01-20 21:49:20 UTC (rev 230)
@@ -1,1283 +1,1283 @@
-# Doxyfile 1.5.7.1
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# Project related configuration options
-#---------------------------------------------------------------------------
-
-# This tag specifies the encoding used for all characters in the config file
-# that follow. The default is UTF-8 which is also the encoding used for all
-# text before the first occurrence of this tag. Doxygen uses libiconv (or the
-# iconv built into libc) for the transcoding. See
-# http://www.gnu.org/software/libiconv for the list of possible encodings.
-DOXYFILE_ENCODING = UTF-8
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-PROJECT_NAME = BaseClasses
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-PROJECT_NUMBER = 6.0
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-OUTPUT_DIRECTORY =
-
-# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
-# 4096 sub-directories (in 2 levels) under the output directory of each output
-# format and will distribute the generated files over these directories.
-# Enabling this option can be useful when feeding doxygen a huge amount of
-# source files, where putting all generated files in the same directory would
-# otherwise cause performance problems for the file system.
-CREATE_SUBDIRS = NO
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
-# Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek,
-# Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages),
-# Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish,
-# Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, Slovene,
-# Spanish, Swedish, and Ukrainian.
-OUTPUT_LANGUAGE = French
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-REPEAT_BRIEF = YES
-
-# This tag implements a quasi-intelligent brief description abbreviator
-# that is used to form the text in various listings. Each string
-# in this list, if found as the leading text of the brief description, will be
-# stripped from the text and the result after processing the whole list, is
-# used as the annotated text. Otherwise, the brief description is used as-is.
-# If left blank, the following values are used ("$name" is automatically
-# replaced with the name of the entity): "The $name class" "The $name widget"
-# "The $name file" "is" "provides" "specifies" "contains"
-# "represents" "a" "an" "the"
-ABBREVIATE_BRIEF =
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-ALWAYS_DETAILED_SEC = NO
-
-# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
-# inherited members of a class in the documentation of that class as if those
-# members were ordinary class members. Constructors, destructors and assignment
-# operators of the base classes will not be shown.
-INLINE_INHERITED_MEMB = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-FULL_PATH_NAMES = YES
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user-defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. The tag can be used to show relative paths in the file list.
-# If left blank the directory from which doxygen is run is used as the
-# path to strip.
-STRIP_FROM_PATH = .
-
-# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
-# the path mentioned in the documentation of a class, which tells
-# the reader which header file to include in order to use a class.
-# If left blank only the name of the header file containing the class
-# definition is used. Otherwise one should specify the include paths that
-# are normally passed to the compiler using the -I flag.
-STRIP_FROM_INC_PATH =
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-SHORT_NAMES = NO
-# Note : si, à la génération, vous obtenez des erreurs multiples de type
-# "Error opening map file *.map for inclusion in the docs!", ne cherchez pas à
-# changer l'option SHORT_NAMES ainsi qu'il est parfois indiqué sur le Net.
-# Contentez-vous d'effacer le contenu du répertoire "Doxygen_files" et refaites
-# la génération de la documentation Doxyfile. Voir bug Doxygen 525273, ici :
-# http://bugzilla.gnome.org/sh