#!/usr/bin/python
# -*- coding: Utf-8 -*-

import sys, os
import Image, ExifTags
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from gui_modules_image.image_base import Base
from gui_modules_lecture.affichage_image.afficheurImage import VisionneurImagePourEKD

class FileImDialog(QFileDialog):
	"""Boite de fichier de dialogue préparant l'implémentation de l'aperçu image
	Dans l'idéal il faudrait mettre l'aperçu de l'image directement dans le QFileDialog.
	Mais je n'ai pas réussi à le faire"""
	
	def __init__(self, parent):
		
		formats = ["*.%s" % unicode(format).lower() \
			for format in QImageReader.supportedImageFormats()]
	
		format = "JPEG (*.jpg *.JPG *.jpeg *.JPEG);;PNG (*.png *.PNG);;GIF (*.gif *.GIF);;BMP (*.bmp *.BMP);;SGI (*.sgi *.SGI);;TIF (*.tif *.TIF);;TARGA (*.tga *.TGA);;PNM (*.pnm *.PNM);;PPM (*.ppm *.PPM);;Tous les fichiers (*.*)"
		
		txt = _(u"Fichiers Image")
		rep = parent.base.getRepSource(parent.chemin, parent.config)
		QFileDialog.__init__(self, None, _(u"Ouvrir"), rep,"%s (%s);;%s" %(txt, " ".join(formats), format))
		
		self.parent = parent # pour modifier le chemin du fichier-image
		self.dialogLabel = parent.dialogLabel # l'aperçu sera mis ici
		self.dialog = parent.dialog # pour fermer la meta-fenêtre de dialogue
		
		self.cheminProv = '' # chemin provisoire du fichier image
		
		self.connect(self,SIGNAL('currentChanged(const QString&)'),self.fileSelected)
		self.connect(self,SIGNAL('accepted()'),self.accepte)
		self.connect(self,SIGNAL('rejected()'),self.refuse)
	
	def fileSelected(self, chemin):
		"""On retient provisoirement le chemin sélectionné mais pas encore validé dans la boite de dialogue. On affiche également un aperçu de l'image. Tout serait beaucoup plus rapide si nous pouvions récupérer l'aperçu de ~/.thumbnails/ et l'enregistrer s'il n'y est pas.
		Comment identifie-t-on un aperçu thumbnail ?"""
		print 'chemin de fileSelected transformé:', str(chemin), type(str(chemin))
		self.cheminProv = str(chemin)
		objImg = QPixmap(self.cheminProv)
		self.nvObjImg = objImg.scaledToHeight(125) # appelé de l'extérieur
		self.dialogLabel.setPixmap(self.nvObjImg)
	
	def accepte(self):
		"""On enregistre vraiment le chemin du fichier-image"""
		print 'signal accepted()'
		self.parent.chemin = self.cheminProv
		print "chemin image d'entrée:", self.parent.chemin, type(self.parent.chemin)
		self.parent.base.setRepSource(self.parent.chemin, self.parent.config)
		self.dialog.close()
	
	def refuse(self):
		"""On n'enregistre rien et on quitte la boite de dialogue"""
		print 'signal refused()'
		self.parent.chemin = ''
		self.dialog.close()


class Image_Divers_Info(QWidget):
	# -----------------------------------
	# Cadre accueillant les widgets de :
	# Image >> Divers >> Information
	# -----------------------------------
	def __init__(self, parent):
        	QWidget.__init__(self)
		
		self.chemin = '' # chemin du fichier sélectionné
		
		# Boite d'alignement vertical
		vbox=QVBoxLayout(self)
		
		# Est-ce que l'image a déjà été affichée une fois ?
		# -> gain de temps au niveau de l'affichage
		self.drapeauImage = 0 # 0: non ; 1: oui
		# Dans une autre version: possibilité de lier le drapeau au 
		# redimensionnement de la fenêtre
		# -> redimensionnement de l'image
		
		# Titre de la page
		#txt1=_(u'Information')
		#titre_du_cadre=QLabel('<H2><CENTER>%s</CENTER></H2>' %txt1, self)
		
		# Aperçu image (vide pour le moment)
		self.tailleApercu=50
		objImg = QPixmap(self.tailleApercu,self.tailleApercu)
		objImg.fill(QColor(200,200,200))
		self.label = QLabel(self)
		self.label.setPixmap(objImg)
		
		# Fonctions communes à plusieurs cadres du module Image
		self.base = Base()
		# Paramètres de configuration
		self.config = parent.config
		
		hbox = QHBoxLayout()
		#hbox.addWidget(titre_du_cadre,1) # étirement: centré
		hbox.addWidget(self.label,0) # pas d'étirement: à droite
		
		# Ajout du titre de la page et de l'aperçu à la boite verticale
		vbox.addLayout(hbox, 0)

		# -------------------------------------------------------------------
		# Boîte de groupe : "Fichiers image source"
		# -------------------------------------------------------------------
		
		# widgets contenus dans la boite
		self.ligneCheminFichier=QLineEdit()
		self.ligneCheminFichier.setReadOnly(True)
		
		# Bouton parcourir (pour charger la video)
		boutOuvChargerImages=QPushButton(_(u'Parcourir...'))
		self.connect(boutOuvChargerImages, SIGNAL("clicked()"), self.ouvrirImages)
		
		# les boîtes de groupes seront placés dans des boîtes horizontales
		group=QGroupBox(_(u"Fichier image source"))
		hbox=QHBoxLayout(group)
		hbox.addWidget(self.ligneCheminFichier)
		hbox.addWidget(boutOuvChargerImages)
		vbox.addWidget(group)
		
		# -----------
		# Onglets
		# -----------
		
		# Onglets
		self.tab = QTabWidget()
		
		#== onglet d'information textuelle ===#
		
		self.zoneTexte = QTextEdit("")
		self.zoneTexte.setReadOnly(True)
		
		frame = QFrame()
		hboxTab = QHBoxLayout(frame)
		hboxTab.addWidget(self.zoneTexte)
		
		self.tabIndexText = self.tab.addTab(frame, _("Infos Texte"))
		
		#== onglet d'information exif ===#
		
		self.table = QTableWidget()
		self.tabIndexExif = self.tab.addTab(self.table, _("Infos Exif"))
		
		#=== onglet de visualisation de l'image ===#
		
		self.afficherImage = VisionneurImagePourEKD()
		self.tab.addTab(self.afficherImage, _("Image"))
		
		# [bidouillage] Comme on n'arrive pas à afficher les images centrées
		# de façon 'propre', en attendant on bidouille pour y arriver
		self.connect(self.tab, SIGNAL("currentChanged(int)"), self.afficherImgOnglet)
		
		self.tab.setEnabled(False)
		vbox.addWidget(self.tab)
		
		# -------------------------------------------------------------------
		# widgets du bas : ligne + boutons
		# -------------------------------------------------------------------
		
		# boutons
		boutAide=QPushButton(_(u" Aide"))
		boutAide.setIcon(QIcon("Icones/icone_aide_128.png"))
		self.connect(boutAide, SIGNAL("clicked()"), self.afficherAide)
	
		self.boutSauverInfos=QPushButton(_(u" Sauver infos (.txt)"))
		# Show infos (.txt) ==> Sauver infos (.txt)
		self.boutSauverInfos.setIcon(QIcon("Icones/icone_appliquer_128.png"))
		self.boutSauverInfos.setEnabled(False)
		self.connect(self.boutSauverInfos, SIGNAL("clicked()"), self.sauverInfos)
		
		self.boutSauverExif=QPushButton(_(u" Sauver Exif (.html)"))
		# Save Exif (.html) ==> Sauver Exif (.html)
		self.boutSauverExif.setIcon(QIcon("Icones/icone_appliquer_128.png"))
		self.boutSauverExif.setEnabled(False)
		self.connect(self.boutSauverExif, SIGNAL("clicked()"), self.sauverExif)

		# ligne de séparation juste au dessus des boutons
		ligne = QFrame()
		ligne.setFrameShape(QFrame.HLine)
		ligne.setFrameShadow(QFrame.Sunken)
		vbox.addWidget(ligne)
		vbox.addSpacing(-5)	# la ligne doit être plus près des boutons
		
		hbox=QHBoxLayout()
		hbox.addWidget(boutAide)
		hbox.addStretch()	# espace entre les 2 boutons
		#hbox.addWidget(self.boutApp)
		#hbox.addWidget(self.boutVoirInfos)
		hbox.addWidget(self.boutSauverInfos)
		#hbox.addWidget(self.boutVoirExif)
		hbox.addWidget(self.boutSauverExif)
		vbox.addLayout(hbox)
		
		# affichage de la boîte principale
		self.setLayout(vbox)
		
	
	def ouvrirImages(self):
		"""Récupération du chemin des images sélectionnées et éventuellement exécution d'une fonction"""
		
		# Boite de dialogue de fichier avec aperçu image
		self.dialog = QDialog()
		self.dialog.setMinimumSize(QSize(550,300))
		hbox = QHBoxLayout()
		
		self.dialogLabel = QLabel(self)
		
		# Chargement d'une seule image
		self.fileDialog = FileImDialog(self)
		
		hbox.addWidget(self.fileDialog,1)
		hbox.addWidget(self.dialogLabel,0)
		self.dialog.setLayout(hbox)
		self.dialog.exec_()
		
		if self.chemin!='':
			print "la fct est appelée"
			self.appliquer()
		else:
			print "la fct n'est pas appelée"
	
	
	def appliquer(self):
		"""Un chemin de fichier-image a été enregistré -> affichage des infos et possibilité de sauvegarder"""
		print '\nfonction imAccepte'
		print "chemin image d'entrée:", self.chemin, type(self.chemin)
		
		# Récupération du chemin + image chargée et de l'extension 
		fich, self.ext=os.path.splitext(self.chemin)
		
		# Affichage du chemin + nom de fichier dans la zone
		# de texte du widget QLineEdit (de l'init).
		self.ligneCheminFichier.setText(self.chemin)
		
		## Quand un fichier est sélectionné, les boutons deviennent cliquables
		#self.boutApp.setEnabled(True)
		#self.boutVoirInfos.setEnabled(True)
		#self.boutSauverInfos.setEnabled(True)
		#self.boutVoirExif.setEnabled(True)
		#self.boutSauverExif.setEnabled(True)
		
		# Affichage d'un apperçu dans le cadre. Apperçu contruit à partir 
		# de celui de la boite de dialogue de fichier -> gain de rapidité.
		nvObjImg = self.fileDialog.nvObjImg.scaledToHeight(self.tailleApercu)
		self.label.setPixmap(nvObjImg)
		
		#=== remplissage des onglets avec les infos disponibles ===#
		
		#||| infos texte |||#
		self.afficherInfos()
		# Activation du bouton pour sauvegarder les infos texte
		self.boutSauverInfos.setEnabled(True)
		
		#||| infos exif et infos texte ... avec conditions |||#
		imgExif=Image.open(self.chemin)
		# Seulement si l'extension sélectionnée est en JPEG (et que l'image chargée
		# contient des données EXIF), la fonction self.afficherExif est exécutée
		if self.ext in [".jpg", ".JPG", ".jpeg", ".JPEG"] and 'Profile-exif:' in self.InfosTxtImage:
			exifdata=imgExif._getexif()
			self.afficherExif()
			# La page infos exif est sélectionnée
			self.tab.setCurrentIndex(self.tabIndexExif)
			# Activation du bouton pour sauvegarder les infos exif
			self.boutSauverExif.setEnabled(True)
		# Seulement si l'extension sélectionnée est en JPEG (mais que l'image chargée ne 
		# contient pas de données EXIF), la fonction self.afficherInfos est exécutée,
		# et rien n'est affiché dans la page Infos Exif
		elif self.ext in [".jpg", ".JPG", ".jpeg", ".JPEG"] and 'Profile-exif:' not in self.InfosTxtImage:
			# La page infos exif se vide complètement (lignes et colonnes)
			self.table.setRowCount(0)
			self.table.setColumnCount(0)
			self.afficherInfos()
			# La page infos texte est sélectionnée
			self.tab.setCurrentIndex(self.tabIndexText)
			# Non activation du bouton pour sauvegarder les infos exif
			self.boutSauverExif.setEnabled(False)
		# Seulement si l'extension sélectionnée est tout autre que JPEG (c'est à 
		# dire/et que l'image chargée ne contient pas de données EXIF), la fonction
		# self.afficherInfos est exécutée, et rien n'est affiché dans la page Infos Exif
		elif self.ext not in [".jpg", ".JPG", ".jpeg", ".JPEG"]:
			self.table.setRowCount(0)
			self.table.setColumnCount(0)
			self.afficherInfos()
			self.tab.setCurrentIndex(self.tabIndexText)
			# Activation du bouton pour sauvegarder les infos exif
			self.boutSauverExif.setEnabled(False)
		
		# Dégriser les onglets
		self.tab.setEnabled(True)
		
		# L'image n'a jamais été affichée
		self.drapeauImage = 0
	
	
	def afficherImgOnglet(self, i):
		"""On redimensionne et centre l'image quand c'est nécessaire"""
		
		# L'image se trouve sur le 3ème onglet
		# et on ne veut pas la redimensionner
		# tant qu'une nouvelle n'a pas été sélectionnée (d'où le drapeau)
		if i==2 and not self.drapeauImage: # 2ème onglet
			# afficher l'image dans un onglet
			self.afficherImage.setImage(self.chemin)
			self.drapeauImage = 1
	
	
	def afficherInfos(self):
		"""afficher les infos venant d'ImageMagick"""
		
		if self.ext in [".jpg", ".JPG", ".jpeg", ".JPEG", ".tga", ".TGA", ".png", ".PNG", ".gif", ".GIF", ".tif", ".TIF", ".ppm", ".PPM", ".bmp", ".BMP", ".sgi", ".SGI", ".pnm", ".PNM"]:
			
			self.ImageInfos=os.popen('identify -verbose'+' '+"\""+self.chemin+"\"").readlines()
			
			# N'affichera que les infos humainement compréhensibles  
			# (dans le cas d'une image avec données EXIF)
			self.listeInfo=[]
			for parcInfo in self.ImageInfos:
				# Ignore les données commençant par ...
				if parcInfo.startswith("0x0") or parcInfo.startswith("    Components Configuration:") or parcInfo.startswith("    Components Configuration:") or parcInfo.startswith("    Maker Note:") or parcInfo.startswith("    CFA Pattern:") or parcInfo.startswith("    User Comment:") or parcInfo.startswith("    File Source:") or parcInfo.startswith("    unknown:") or parcInfo.startswith("    Scene Type:") or parcInfo.startswith("    Print Image Matching:"):
					pass

				else:
					self.listeInfo.append(parcInfo)
		
			a="You can't display the infos of several pictures (no possibility to select several pictures in a single dialog box).\n==========================================================\nThe pictures formats accepted are: .jpg, .jpeg, .tga, .png, .gif, .tif, .ppm, .bmp, .sgi and .pnm. If a picture with EXIF informations is shown, only .jpg (or .jpeg, .JPG, .JPEG) format is accepted.\n==========================================================\n"
		
			# Affichage dans zoneTexte
			self.InfosTxtImage=''.join(self.listeInfo)
			self.zoneTexte.setText(a+"\n"+self.InfosTxtImage)

		else:
			messageErreur=QMessageBox(self)
			messageErreur.setText(_(u"An error has occured !. This extension (%s) is not supported" % self.ext))
			messageErreur.setWindowTitle(_(u"Error"))
			messageErreur.setIcon(QMessageBox.Critical)
			messageErreur.exec_()
		
		
	def sauverInfos(self):
		"""Sauver les infos (sous forme de fichier texte)"""
		
		try:
			# Boîte de dialogue pour sauvegarder (nom du nouveau fichier)
			rep = self.base.getRepSource(self.chemin, self.config)
			sauver=str(QFileDialog.getSaveFileName(None, _(u"Sauver"), rep, _(u"Fichiers texte (*.txt)")))
			enrTxt=open(sauver+'.txt', 'wb')
			enrTxt.write(self.InfosTxtImage)
			enrTxt.flush()
			enrTxt.close()
			
		except:
			messageErreur=QMessageBox(self)
			messageErreur.setText(_(u"An error has occured !. You have canceled current operation or you have forgotten to load a picture with the 'Browse...' button."))
			messageErreur.setWindowTitle(_(u"Error"))
			messageErreur.setIcon(QMessageBox.Critical)
			messageErreur.exec_()
		
	
	def miseAJourTable(self, nbrCol, donnees):
		""" On met à jour la table exif """
		self.table.clear()
		self.table.setRowCount(len(donnees))
		self.table.setColumnCount(nbrCol)
		self.table.setHorizontalHeaderLabels([_(u"Paramètre"), _(u"Valeur")])
		self.table.setAlternatingRowColors(True)
		self.table.setEditTriggers(QTableWidget.NoEditTriggers)
		#self.table.setSelectionBehavior(QTableWidget.SelectRows)
		self.table.setSelectionMode(QTableWidget.ExtendedSelection)
		for indexL, ligne in enumerate(donnees):
			for indexC, element in enumerate(ligne):
				item = QTableWidgetItem(str(element))
				item.setTextAlignment(Qt.AlignCenter)
				#item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable)
				self.table.setItem(indexL, indexC, item)
				print indexL, indexC, element
        	self.table.resizeColumnsToContents()
	
	
	def afficherExif(self):
		"""Afficher les infos Exif"""
		
		try :
			# -----------------------------------------------------------------------
			# Extraction des donnees EXIF
			# -----------------------------------------------------------------------
			# Aide de Terry Carroll sur la liste de diffusion : 
			# image-sig at python.org .
			# Avec une petite adaptation personnelle. Merci à Terry Carroll.
			
			imgExif=Image.open(self.chemin)
			
			# Recupération des infos EXIF
			exifdata=imgExif._getexif()
			
			listeExif=[]
	
			for keyExif, valueExif in zip(exifdata.keys(), exifdata.values()):
	
				try:
					if ExifTags.TAGS[keyExif] in ['UserComment', 'ComponentsConfiguration', 'CFAPattern', 'FileSource', 'SceneType', 'MakerNote', '\x01\x02\x03CompressedBitPerPixel']:
                        			pass
					
					else :
						ImageExif=(str(ExifTags.TAGS[keyExif]), valueExif)
						listeExif.append(ImageExif)
						
				except KeyError:
					pass
			
			# Changement de l'affichage pour l'enregistrement, et ce pour une 
			# meilleure lecture des données EXIF.
			affExif=[]
			for exifAff in listeExif:
				if exifAff[0].startswith("ApertureValue"):
					exifAffnouveau='f/'+str(round(float(exifAff[1][0])/float(exifAff[1][1]), 1))
					affExif.append(('ApertureValue', exifAffnouveau))
				elif exifAff[0].startswith("CompressedBitsPerPixel"):
					exifAffnouveau=str(int(exifAff[1][0])/int(exifAff[1][1]))+' bit/pixel'
					affExif.append(('CompressedBitsPerPixel', exifAffnouveau))
				elif exifAff[0].startswith("ExposureTime"): 
					exifAffnouveau=str(round(float(exifAff[1][0])/float(exifAff[1][1]), 3))+' ('+str(exifAff[1][0]/exifAff[1][0])+'/'+str(exifAff[1][1]/exifAff[1][0])+' sec)'
					affExif.append(('ExposureTime',exifAffnouveau))
				elif exifAff[0].startswith("FNumber"):
					exifAffnouveau='f/'+str(round(float(exifAff[1][0])/float(exifAff[1][1]), 1))+' (diaphragm value)'
					affExif.append(('FNumber', exifAffnouveau))
				elif exifAff[0].startswith("FocalLength"):
					exifAffnouveau=str(round(float(exifAff[1][0])/float(exifAff[1][1]), 2))+' mm'
					affExif.append(('FocalLength', exifAffnouveau))
				elif exifAff[0].startswith("FocalPlaneXResolution"):
					exifAffnouveau=str(round(float(exifAff[1][0])/float(exifAff[1][1]), 1))
					affExif.append(('FocalPlaneXResolution', exifAffnouveau))
				elif exifAff[0].startswith("FocalPlaneYResolution"):
					exifAffnouveau=str(round(float(exifAff[1][0])/float(exifAff[1][1]), 1))
					affExif.append(('FocalPlaneYResolution', exifAffnouveau))
				elif exifAff[0].startswith("MaxApertureValue"):
					exifAffnouveau='f/'+str(round(float(exifAff[1][0])/float(exifAff[1][1]), 1))
					affExif.append(('MaxApertureValue', exifAffnouveau))
				elif exifAff[0].startswith("XResolution"):
					exifAffnouveau=str(int(exifAff[1][0])/int(exifAff[1][1]))+' dpi'
					affExif.append(('XResolution', exifAffnouveau))
				elif exifAff[0].startswith("YResolution"):
					exifAffnouveau=str(int(exifAff[1][0])/int(exifAff[1][1]))+' dpi'
					affExif.append(('YResolution', exifAffnouveau))
				else:
					affExif.append(exifAff)

			# Ttes les infos Exif (tags Exif) obtenu(es) avec
			# intégration du code html pour affichage ds tableau.
			# Si on utilisait unicode pour les traductions, val[0] et val[1]
			# seraient à remplacer par _(unicode(val[0])) et _(unicode(val[1]))
			ExifHtml=['<tr>\n<td bgcolor="9dc3d9">'+str(val[0])+'</td>\n<td>'+str(val[1])+'</td>\n</tr>\n' for val in affExif]
			ExifHtml.sort()
			
			# ----------------------------------------------------
			# Conditions de dimensions de l'image pour l'affichage
			# ----------------------------------------------------
			
			# Recuperation de la valeur du poids de l'image 
			poidsDebutImgExif=int(os.stat(self.chemin).st_size)
			# Calcul du poids en kilo-octet de l'image
			self.poidsFinImgExif=int(poidsDebutImgExif)/1000
		
			# Recuperation du chemin de chargement de la photo
			chemEnrExif=os.path.dirname(self.chemin)
			# Recuperation du nom de la photo
			self.nomImageExif=os.path.basename(self.chemin)
		
			# On recupere la taille de l'image
			self.widthImgExif, self.heightImgExif=imgExif.size
			
			# Si la dimension la + grde est inférieure ou égale à 640
			if max(self.widthImgExif, self.heightImgExif)<=640 : self.widthImgExif, self.heightImgExif
			# Si la dimension la + grde est supérieure à 640
			if max(self.widthImgExif, self.heightImgExif)>640 :
				# Calcul du ratio de l'image
				ratioWHexif=float(max(self.widthImgExif, self.heightImgExif))/float(min(self.widthImgExif, self.heightImgExif))
				# La dimension la + grde
				MaxWHexif=max(self.widthImgExif, self.heightImgExif)
				# On assigne automatiquement la dimension la +
				# grde à 640 pour affichage ds le fichier html
				MaxWHexif=float(640)
				# Calcul de la dimension la + petite
				MinWHexif=MaxWHexif/ratioWHexif
			
				# Si La dimension la + grde est supérieure à 640 et 
				# la largeur est supérieure ou égale à la hauteur
				if MaxWHexif==float(640) and self.widthImgExif>=self.heightImgExif :
					self.widthImgExif=640
					self.heightImgExif=int(round(MinWHexif))
			
				# Si la hauteur est supérieure à la largeur
				if self.heightImgExif>self.widthImgExif :
					self.heightImgExif=640
					self.widthImgExif=int(round(MinWHexif))
			
			#----------------------------------------------------------
			# mise en forme des données dans un tableau QTableWidget()
			#----------------------------------------------------------
			self.miseAJourTable(2, listeExif)
			
			# -----------------------------------------------------
			# Affichage de l'exif ds le code et ds un tableau . 
			# -----------------------------------------------------
			# --> Quelques traductions :
			# --------------------------
			# NAME OF THE IMAGE --> NOM DE L'IMAGE 
			# WEIGHT OF THE IMAGE --> POIDS DE L'IMAGE
			# kb --> ko (kilobytes --> kilo-octets)
			# EXIF INFORMATIONS ABOUT THE IMAGE --> INFORMATIONS EXIF SUR L'IMAGE 
			# ExifVersion --> Version Exif
			# DateTime --> Date et heure
			# DateTimeOriginal --> Date et heure (d'origine)
			# DateTimeDigitized --> Date et heure (numerisation)
			# ExifImageWidth --> Dimension X en pixels
			# ExifImageHeight --> Dimension Y en pixels
			# XResolution --> Resolution X
			# YResolution --> Resolution Y
			# Make --> Constructeur
			# Model --> Modele
			# READ ATTENTIVELY WHAT IS JUST DOWN --> LISEZ ATTENTIVEMENT CE QUI 
			# SE TROUVE EN DESSOUS
			# Your image has to be exactly in the same directory as your html file,
			# otherwise the image in question will not appear in this page . -->
			# Votre image doit se trouver exactement dans le même répertoire que
			# votre fichier html, autrement l'image en question n'apparaîtra pas
			# dans cette page . 
			# This page html was generated by 
			# <a href='http://ekd.tolosano.info'>EKD</a> (post-production 
			# software for videos and images) . --> Cette page html a été générée
			# par <a href='http://ekd.tolosano.info'>EKD</a> (logiciel de
			# post-production pour les vidéos et les images) .
			
			#----------------------------------------------
			# Construction du tableau html avant affichage
			#----------------------------------------------
			self.ListeExifPourHtml=['<table border=1 bgcolor="f6d79a" width=100% align=center bordercolor="black">\n<tr>\n<tr>\n<td colspan="2" bgcolor="black" align="center"><font color="white">'+_(u"NAME OF THE IMAGE")+'</td>\n</tr>\n<tr>\n<td colspan="2">'+str(self.nomImageExif)+'</td>\n</tr>\n<tr>\n<td colspan="2" bgcolor="black" align="center"><font color="white">'+_(u"WEIGHT OF THE IMAGE")+'</td>\n</tr>\n<tr>\n<td colspan="2">'+str(self.poidsFinImgExif)+_(' kb')+'</td>\n</tr>\n<tr>\n<td colspan="2" bgcolor="black" align="center"><font color="white">'+_(u"EXIF INFORMATIONS ABOUT THE IMAGE")+'</td>\n</tr>\n'+''.join(ExifHtml)+'</tr>\n<tr>\n<td colspan="2" bgcolor="black" align="center"><font color="white">'+_(u"READ ATTENTIVELY WHAT IS JUST DOWN")+'</td>\n</tr>\n<tr>\n<td colspan="2">'+_(u"Your image has to be exactly in the same directory as your html file, otherwise the image in question will not appear in this page .")+'</td>\n</tr>\n<tr>\n<td colspan="2" bgcolor="black" align="center"><font color="white">'+_(u"This page html was generated by <a href='http://ekd.tolosano.info'>EKD</a> (post-production software for videos and images) .")+'</td>\n</tr>\n</table>']
			
		except :
			messageErreur=QMessageBox(self) 
			messageErreur.setText(_(u"Il s'est produit un problème !. Certainement que les photos de cet appareil ne contiennent pas des données importantes (comme par exemple 'Date et heure').")) 
			messageErreur.setWindowTitle(_(u"Error")) 
			messageErreur.setIcon(QMessageBox.Critical) 
			messageErreur.exec_()


	def sauverExif(self):
		"""Sauver les infos Exif (sous forme de fichier html)"""
	
		try:
			# Boîte de dialogue pour sauvegarder (nom du nouveau fichier)
			rep = self.base.getRepSource(self.chemin, self.config)
			sauver=str(QFileDialog.getSaveFileName(None, _(u"Sauver"), rep, _(u"Fichiers HTML (*.html)")))
			enrHtml=open(sauver+'.html', 'wb')
			enrHtml.write('<!DOCTYPE html PUBLIC "-//IETF//DTD HTML 2.0//EN">\n<html>\n<head>\n<title>EXIF infos</title>\n</head>\n<body bgcolor="d0cfcd" text="#000000" link="lightblue" vlink="orange">\n<center><IMG src="'+str(self.nomImageExif)+'" '+ 'width="'+str(self.widthImgExif)+'" height="'+str(self.heightImgExif)+'" border="0"></center>\n<h4>'+"".join(self.ListeExifPourHtml)+'</h4>\n</body>\n</html>')
			enrHtml.flush()
			enrHtml.close()
			
		except:
			messageErreur=QMessageBox(self)
			messageErreur.setText(_(u"An error has occured !. You have canceled current operation or you have forgotten to load a picture with the 'Browse...' button."))
			messageErreur.setWindowTitle(_(u"Error"))
			messageErreur.setIcon(QMessageBox.Critical)
			messageErreur.exec_()
	

	def afficherAide(self):
		"""Boîte de dialogue de l'aide du cadre Image > Informations (txt ou Exif)"""
		
		messageAide=QMessageBox(self)
		messageAide.setText(_(u"Blabla ... blablabla ... blabla"))
		messageAide.setWindowTitle(_(u"Help"))
		messageAide.setIcon(QMessageBox.Information)
		messageAide.exec_()
		