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

import sys, os, glob, string, Image, ImageDraw, ImageFont
# Le module itertools (voir à partir de la ligne 397)
from itertools import cycle, islice, izip
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 Image_Divers_PlContact(QWidget):
	"""# -----------------------------------
	# Cadre accueillant les widgets de :
	# Image >> Divers >> Planche-contact
	# -----------------------------------"""
	def __init__(self, parent):
        	QWidget.__init__(self)
		
		# -------------------------------
		# Parametres généraux du widget
		# -------------------------------
		#=== tout sera mis dans une boîte verticale ===#
		vbox=QVBoxLayout(self)
		
		#=== Création des répertoires temporaires ===#
		self.repTampon = '/tmp/ekd/tampon/image_divers_planche_contact/'
		if os.path.isdir(self.repTampon) is False:
        		os.makedirs(self.repTampon)
		if os.path.isdir(self.repTampon+'redim/') is False:
        		os.makedirs(self.repTampon+'redim/')
		
		# Au cas où le répertoire existait déjà et qu'il n'était pas vide 
		# -> purge (simple précausion)
		for toutRepCompo in glob.glob(self.repTampon+'*.*'):
			os.remove(toutRepCompo)
		
		# Délai avant conversion
		self.timer = QTimer()
		self.connect(self.timer, SIGNAL('timeout()'), self.sonderTempsActuel)
		
		# Fonctions communes à plusieurs cadres du module Image
		self.base = Base()
		# Paramètres de configuration
		self.config = parent.config
		self.listeChemin = []
		
		#-------------------------------------------------
		# Sélection images, type de méthode et de masque
		#-------------------------------------------------
		
		boutCharger=QPushButton(_(u'Ouvrir images'))
		self.connect(boutCharger, SIGNAL("clicked()"), self.ouvrirSource)
		vbox.addWidget(boutCharger)
		
		#------------------------
		# Onglets et stacked
		#------------------------
		self.tabwidget=QTabWidget()
		
		#=== 1er onglet ===#
		self.framReglage=QFrame()
		vboxReglage=QVBoxLayout(self.framReglage)
		
		# boite de combo
		self.comboReglage=QComboBox()
		self.listeComboReglage=[(_(u'JPEG (.jpg)'), '.jpg'),\
					(_(u'PNG (.png)'), '.png'),\
					(_(u'GIF (.gif)'), '.gif'),\
					(_(u'BMP (.bmp)'), '.bmp'),\
					(_(u'PDF (.pdf)'), '.pdf')]
		# Insertion des formats dans la combo box
		for i in self.listeComboReglage:
                	self.comboReglage.addItem(i[0],QVariant(i[1]))
		self.connect(self.comboReglage, SIGNAL("activated(int)"), self.changerComboReglage)
		
		# boite de combo
		self.comboPorPay=QComboBox()
		self.listeComboPorPay=[(_(u'Format portrait'), 'form_port'),\
					(_(u'Format paysage'), 'form_pay')]
		# Insertion des formats portrait ou paysage dans la combo box
		for i in self.listeComboPorPay:
                	self.comboPorPay.addItem(i[0],QVariant(i[1]))
		self.connect(self.comboPorPay, SIGNAL("activated(int)"), self.changerComboPorPay)
		
		# boite de combo
		self.comboVal=QComboBox()
		self.listeComboVal=[(_(u'Blanc'), 'blanc'),\
				    (_(u'Noir'),  'noir'),\
				    (_(u'Gris'),  'gris')]
		# Insertion des valeurs (ce ne sont pas des couleurs) dans la combo box
		for i in self.listeComboVal:
                	self.comboVal.addItem(i[0],QVariant(i[1]))
		self.connect(self.comboVal, SIGNAL("activated(int)"), self.changerComboVal)
		
		grid = QGridLayout()
		grid.addWidget(QLabel(_(u"Passage d'une image à l'autre")), 0, 0)
		self.spin1=QSpinBox()
		self.spin1.setRange(1, 1000)
		self.spin1.setValue(1)
		grid.addWidget(self.spin1, 0, 1)
		grid.addWidget(QLabel(_(u'Orientation de la page de fond')), 1, 0)
		grid.addWidget(self.comboPorPay, 1, 1)
		grid.addWidget(QLabel(_(u'Valeur du fond')), 2, 0)
		grid.addWidget(self.comboVal, 2, 1)
		grid.addWidget(QLabel(_(u"Nombre d'images par ligne")), 3, 0)
		self.spin2=QSpinBox()
		self.spin2.setRange(1, 12)
		self.spin2.setValue(4)
		grid.addWidget(self.spin2, 3, 1)
		grid.addWidget(QLabel(_(u"Nombre d'images par colonne")), 4, 0)
		self.spin3=QSpinBox()
		self.spin3.setRange(1, 14)
		self.spin3.setValue(6)
		grid.addWidget(self.spin3, 4, 1)
		grid.addWidget(QLabel(_(u"Largeur de la marge en pixels (entre les images)")), 5, 0)
		self.spin4=QSpinBox()
		self.spin4.setRange(1, 100)
		self.spin4.setValue(10)
		grid.addWidget(self.spin4, 5, 1)
		grid.addWidget(QLabel(_(u'Format de sortie de la planche-contact')), 6, 0)
		grid.addWidget(self.comboReglage, 6, 1)
		
		grid.setAlignment(Qt.AlignHCenter)
		
		vboxReglage.addSpacing(10)
		vboxReglage.addLayout(grid)
		vboxReglage.addStretch()
		
		# Mise par défaut de la résolution de l'image de fond ------
		# Résolution en largeur de l'image de base (le fond)
		self.resLarg=595
		# Résolution en hauteur de l'image de base (le fond)
		self.resHaut=842
		# Mise par défaut de la valeur de l'image de fond ----------
		# Par défaut le fond est blanc
		self.val=(255, 255, 255)
		# Couleur de la police de numérotation des pages
		self.coulPolice=(0, 0, 0)
		# ----------------------------------------------------------
		
		#=== 2ème onglet ===#
		# infos - logs
		self.zoneAffichInfosImg = QTextEdit("")
		self.zoneAffichInfosImg.setReadOnly(True)
		self.framImg=QFrame()
		vboxReglage=QVBoxLayout(self.framImg)
		vboxReglage.addWidget(self.zoneAffichInfosImg)
		self.framImg.setEnabled(False)
		
		#=== 3ème onglet ===#
		self.afficheurImg_1=VisionneurImagePourEKD()
		self.afficheurImg_2=VisionneurImagePourEKD()
		
		self.indexTabReglage=self.tabwidget.addTab(self.framReglage, _(u'Réglages'))
		self.indexImagechargee=self.tabwidget.addTab(self.afficheurImg_1, _(u'Image chargée'))
		self.indexImageResultat=self.tabwidget.addTab(self.afficheurImg_2, _(u'Image Résultat'))
		self.indexTabInfo=self.tabwidget.addTab(self.framImg, _(u'Infos'))
		
		# [bidouillage] Comme on n'arrive pas à afficher les images centrées
		# de façon 'propre', en attendant on bidouille pour y
		# arriver (le prbl concerne surtout les images d'acceuil)
		self.connect(self.tabwidget, SIGNAL("currentChanged(int)"), self.protheseCentrageImg) 
		
		vbox.addWidget(self.tabwidget)
		
		#------------------
		# Widgets du bas
		#------------------
		
		# boutons
		boutAide=QPushButton(_(u" Aide"))
		boutAide.setIcon(QIcon("Icones/icone_aide_128.png"))
		boutAide.setFocusPolicy(Qt.NoFocus)
		self.connect(boutAide, SIGNAL("clicked()"), self.afficherAide)
		self.info=QPushButton(_(u" Information"))
		self.info.setIcon(QIcon("Icones/icone_info_128.png"))
		self.info.setFocusPolicy(Qt.NoFocus)
		self.connect(self.info, SIGNAL("clicked()"), self.information)
		self.boutApp=QPushButton(_(u" Appliquer"))
		self.boutApp.setIcon(QIcon("Icones/icone_appliquer_128.png"))
		self.boutApp.setFocusPolicy(Qt.NoFocus)
		self.boutApp.setEnabled(False)
		self.connect(self.boutApp, SIGNAL("clicked()"), self.appliquer0)
		
		# 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.info)
		hbox.addStretch()
		hbox.addWidget(self.boutApp)
		vbox.addLayout(hbox)
		
		self.setLayout(vbox)
		
		#------------------------------------------------
		# Barre de progression dans une fenêtre séparée
		#------------------------------------------------
		
		self.progress=QProgressDialog(_(u"Progression ..."), _(u"Arrêter le processus"), 0, 100)
		self.progress.setWindowTitle(_(u'EnKoDeur-Mixeur. Fenêtre de progression'))
		# Attribution des nouvelles dimensions
		self.progress.setMinimumWidth(500)
		self.progress.setMinimumHeight(100)
		
		
	def changerComboReglage(self, i):
		"""Récup/affichage ds le terminal de l'index de self.comboReglage"""
		#print self.comboReglage.currentIndex()
		print self.comboReglage.currentText()
		
		
	def changerComboPorPay(self, i):
		"""Récup/affichage ds le terminal de l'index de self.comboPorPay"""
		#print self.comboPorPay.currentText()
		idCombo=str(self.comboPorPay.itemData(i).toStringList()[0])
		# Si l'orientation est en format portrait ...
		if idCombo=='form_port':
			print "L'orientation choisie est en format portrait"
			# Résolution en largeur de l'image de base (le fond)
			self.resLarg=595
			# Résolution en hauteur de l'image de base (le fond)
			self.resHaut=842
		# Si l'orientation est en format paysage ...
		elif idCombo=='form_pay':
			print "L'orientation choisie est en format paysage"
			# Résolution en largeur de l'image de base (le fond)
			self.resLarg=842
			# Résolution en hauteur de l'image de base (le fond)
			self.resHaut=595
			# Changement automatique du nbre d'images par ligne,
			# de même changement du nombre d'images par colonne
			self.spin2.setValue(6)
			self.spin3.setValue(4)
			
			
	def changerComboVal(self, i):
		"""Récup/affichage ds le terminal de l'index de self.comboVal"""
		#print self.comboVal.currentText()
		idCombo=str(self.comboVal.itemData(i).toStringList()[0])
		if idCombo=='blanc':
			print "L'image de fond est blanche"
			self.val=(255, 255, 255)
			self.coulPolice=(0, 0, 0)
		elif idCombo=='noir':
			print "L'image de fond est noire"
			self.val=(0, 0, 0)
			self.coulPolice=(255, 255, 255)
		elif idCombo=='gris':
			print "L'image de fond est grise"
			self.val=(127, 127, 127)
			self.coulPolice=(255, 255, 255)

	
	def protheseCentrageImg(self, i):
		"""Rafraichissemnt pour affichage de l'image au
		# milieu de la fenêtre. La fonction setTailleFenetre()
		# vient de la classe VisionneurImagePourEKD du fichier
		# gui_modules_lecture/affichage_image/afficheurImage.py"""
		if i==1: # 2ème onglet
			self.afficheurImg_1.setTailleFenetre()
		elif i==2: # 3ème onglet
			self.afficheurImg_2.setTailleFenetre()
	
	
	def ouvrirSource(self):
		txt = _(u"Fichier images")
		rep = self.base.getRepSource(self.listeChemin, self.config)
		listeChemin=QFileDialog.getOpenFileNames(None, _(u"Ouvrir"), rep, ("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);; *"))
		
		print "Chemin de chargement des images:", listeChemin, type(listeChemin)
		
		self.listeChemin = [str(listeChemin[i]) for i in range(len(listeChemin))]
		
		if self.listeChemin==[]: return
		
		self.listeChemin.sort()
		
		self.base.setRepSource(self.listeChemin, self.config)
		
		# Le bouton devient actif
		self.boutApp.setEnabled(True)

		
	def stat_dim_img(self):
		"""Calcul statistique des dimensions des images les plus présentes dans le lot"""
		
		# Ouverture et mise ds une liste des dimensions des images
		listePrepaRedim=[Image.open(aA).size for aA in self.listeChemin]
		
		# Merci beaucoup à Marc Keller de la liste: python at aful.org de m'avoir
		# aidé pour cette partie (les 4 lignes en dessous)
		dictSeq={}.fromkeys(listePrepaRedim, 0)
		for cle in listePrepaRedim: dictSeq[cle]+=1
		self.lStatDimSeq=sorted(zip(dictSeq.itervalues(), dictSeq.iterkeys()), reverse=1)
		self.dimStatImg=self.lStatDimSeq[0][1]
		
		print "Toutes les dimensions des images (avec le nbre d'images):", self.lStatDimSeq
		print 'Dimension des images la plus presente dans la sequence:', self.dimStatImg
		print "Nombre de tailles d'images différentes dans le lot :", len(self.lStatDimSeq)
		
		if len(self.lStatDimSeq)>1:
			return 0
		else:
			return 1
	
	
	def redim_img(self):
		"""Si l'utilisateur charge des images avec des tailles complètement différentes --> les images de la séquence  peuvent être redimensionnées"""
		
		if not self.stat_dim_img():
			reply = QMessageBox.warning(self, 'Message',
			_(u"Vos images ne sont pas toutes de la même taille. Voulez-vous redimensionner les images de sortie à la taille la plus répandue dans la séquence?"), QMessageBox.Yes, QMessageBox.No)
			if reply == QMessageBox.No:
				return
			
			# Les images de tailles différentes à la plus répandue sont redimensionnées
			# dans un répertoire temporaire.
			# Les images redimensionnées voient leur chemin modifié dans la liste des
			# chemins des images sources. Les autres chemins ne changent pas.
			index=0
			for chemImg in self.listeChemin:
				obImg=Image.open(chemImg)
				if obImg.size!=self.dimStatImg:
					pass
				sRedim=obImg.resize(self.dimStatImg)
				chemSortie = self.repTampon+'redim/'+os.path.basename(chemImg)
				sRedim.save(chemSortie)
				self.listeChemin[index] = chemSortie
				index += 1
		
	
	def information(self):
		""" Information(s) concernant la planche-contact """
		
		# Calcul du nombre d'images sur la page
		nb=(self.spin2.value()*self.spin3.value())*20
		
		info=QMessageBox(self)
		info.setText(_(u"Le nombre maximum d'images (miniatures) pouvant être affichées dans les différentes pages de la planche-contact est de <b>%s</b>, en fait le nombre d'images par ligne multiplié par le nombre d'images par colonne, tout ceci multiplé par 20 (il s'agit du nombre de pages possibles pour la planche-contact).") % nb)
		info.setWindowTitle(_(u"Information"))
		info.setIcon(QMessageBox.Information)
		info.exec_()
			
			
	def planche_contact(self):
		""" Planche-contact """
		
		# Calcul du nombre maximum d'images autorisées sur une page planche-contact
		# En fait le nombre max d'images autorisées correspond au nbre d'images par
		# ligne mutiplié par le nbre d'images par colonne
		nbMax=self.spin2.value()*self.spin3.value()
		
		# Redimensionner les images de tailles différentes?
		self.redim_img()
		
		# Calcul de la résolution (la largeur) des images miniatures sur la planche-contact
		largMiniature=(self.resLarg-(self.spin2.value()+1)*self.spin4.value())/self.spin2.value()
		
		# Calcul du ratio de l'image de base
		ratio=float(self.resLarg)/float(self.resHaut)
		
		# Si la résolution de l'image est en format portrait (comme par défaut)
		if self.resLarg<=self.resHaut:
			# Calcul de la résolution (la hauteur) des images
			hautMiniature=int(float(largMiniature)*ratio)
		# Si la résolution de l'image est en format paysage
		elif self.resLarg>self.resHaut:
			# Calcul de la résolution (la hauteur) des images
			hautMiniature=int(float(largMiniature)/ratio)
			# Information pour l'utilisateur
			if self.spin3.value()>self.spin2.value():
				warning=QMessageBox(self)
				warning.setText(_(u"Vous avez effectué les réglages afin que le nombre d'images par colonne soit plus important que nombre d'images par ligne. Vous allez en conséquence obtenir d'assez mauvais résultats (chevauchement d'images). Pour un format paysage, le nombre d'images par ligne doit être supérieur au nombre d'images par colonne."))
				warning.setWindowTitle(_(u"Attention !"))
				warning.setIcon(QMessageBox.Warning)
				warning.exec_()
		
		# Calcul de la taille de la marge haute
		hautMarge=(self.resHaut-(self.spin3.value()*hautMiniature))/(self.spin3.value()+1)
		
		# Comprehension-list pour calculer l'emplacement exact des images sur la planche
		# La taille de la marge haute est automatiquement adaptée (par le calcul de hautMarge)
		# Affiche (par exemple):
		# [(10, 38), (156, 38), (302, 38), ...]
		lCoordPlanche=[(((totoX+1)*self.spin4.value())+(totoX*largMiniature), ((totoY+1)*hautMarge)+(totoY*hautMiniature)) for totoY in range(self.spin3.value()) for totoX in range(self.spin2.value())]
		
		# Récup du format sélectionné par l'utilisateur
		format=self.comboReglage.currentText()
		# Définition de l'extension pour la conversion
		if format=='JPEG (.jpg)': ext='.jpg'
		elif format=='PNG (.png)': ext='.png'
		elif format=='GIF (.gif)': ext='.gif'
		elif format=='BMP (.bmp)': ext='.bmp'
		elif format=='PDF (.pdf)': ext='.pdf'
		
		nbreImg=len(self.listeChemin)
		
		# Comprehension-list pour sélection des images
		listeImCo=[self.listeChemin[parc_1] for parc_1 in range(0, len(self.listeChemin), self.spin1.value())]
		
		# Mise en relation des images sélectionnées par la liste listeImCo et
		# les coordonnées calculées dans la liste lCoordPlanche. Un très très 
		# grand merci à Kent Johnson de la liste tutor at python.org pour avoir
		# trouvé cette solution. Les messages sont consultables ici:
		# http://mail.python.org/pipermail/tutor/2008-March/060701.html
		# http://mail.python.org/pipermail/tutor/2008-March/060702.html
		# http://mail.python.org/pipermail/tutor/2008-March/060703.html
		# Par exemple cette liste affiche:
		# [('/chemin/image_000001.png', (10, 38)), 
		#  ('/chemin/image_000002.png', (156, 38)), 
		#  ('/chemin/image_000003.png', (302, 38)),
		# ...]
		lImCoordFinal=list(islice(izip(cycle(listeImCo), cycle(lCoordPlanche)), max(len(lCoordPlanche[0:len(listeImCo)]), len(listeImCo))))
		
		# Coordonnées d'affichage de la police (numérotation des pages)
		posXFonte=lCoordPlanche[len(lCoordPlanche)-1][0]
		posYFonte=lCoordPlanche[len(lCoordPlanche)-1][1]+hautMiniature+10
		
		# Conditions d'affichage de la police ...
		if posYFonte<(self.resHaut-10):
			posYFonte=posYFonte
		elif posYFonte>=(self.resHaut-10):
			posYFonte=lCoordPlanche[len(lCoordPlanche)-1][1]+hautMiniature+1
		
		# Fonte truetype utilisée (celle par défaut)
		fonte=ImageFont.load_default()
		
		# Création de l'image de fond (1ère page) sur laquelle viendront 
		# se greffer les miniatures
		img2=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		# Ecriture du numéro de page
		ImageDraw.Draw(img2).text((posXFonte, posYFonte), '-- 1 --', font=fonte, fill=self.coulPolice)
		# Création des autres pages (20 en tout)
		img3=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img3).text((posXFonte, posYFonte), '-- 2 --', font=fonte, fill=self.coulPolice)
		img4=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img4).text((posXFonte, posYFonte), '-- 3 --', font=fonte, fill=self.coulPolice)
		img5=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img5).text((posXFonte, posYFonte), '-- 4 --', font=fonte, fill=self.coulPolice)
		img6=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img6).text((posXFonte, posYFonte), '-- 5 --', font=fonte, fill=self.coulPolice)
		img7=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img7).text((posXFonte, posYFonte), '-- 6 --', font=fonte, fill=self.coulPolice)
		img8=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img8).text((posXFonte, posYFonte), '-- 7 --', font=fonte, fill=self.coulPolice)
		img9=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img9).text((posXFonte, posYFonte), '-- 8 --', font=fonte, fill=self.coulPolice)
		img10=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img10).text((posXFonte, posYFonte), '-- 9 --', font=fonte, fill=self.coulPolice)
		img11=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img11).text((posXFonte, posYFonte), '-- 10 --', font=fonte, fill=self.coulPolice)
		img12=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img12).text((posXFonte, posYFonte), '-- 11 --', font=fonte, fill=self.coulPolice)
		img13=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img13).text((posXFonte, posYFonte), '-- 12 --', font=fonte, fill=self.coulPolice)
		img14=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img14).text((posXFonte, posYFonte), '-- 13 --', font=fonte, fill=self.coulPolice)
		img15=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img15).text((posXFonte, posYFonte), '-- 14 --', font=fonte, fill=self.coulPolice)
		img16=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img16).text((posXFonte, posYFonte), '-- 15 --', font=fonte, fill=self.coulPolice)
		img17=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img17).text((posXFonte, posYFonte), '-- 16 --', font=fonte, fill=self.coulPolice)
		img18=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img18).text((posXFonte, posYFonte), '-- 17 --', font=fonte, fill=self.coulPolice)
		img19=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img19).text((posXFonte, posYFonte), '-- 18 --', font=fonte, fill=self.coulPolice)
		img20=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img20).text((posXFonte, posYFonte), '-- 19 --', font=fonte, fill=self.coulPolice)
		img21=Image.new('RGB', (self.resLarg, self.resHaut), self.val)
		ImageDraw.Draw(img21).text((posXFonte, posYFonte), '-- 20 --', font=fonte, fill=self.coulPolice)
		
		# Liste pour affichage des images chargées (ds le tabwidget)
		listeAff_1=[]
		# Liste pour affichage des pages sauvegardées (ds le tabwidget)
		listeAff_2=[]
		
		listeOcc=[]
		# Boucle principale
		for images, coorXY in lImCoordFinal:
		
			# Remplissage de la liste pour le calcul du pourcentage
			listeOcc.append(images)
			# Ouverture images
			img1=Image.open(images)
			# Redimensionnement des futures miniatures pour affichage ds la planche
			redim=img1.resize((largMiniature, hautMiniature))
			
			# Conditions d'affichage sur la 1ère page, sauvegarde et affichage
			if (len(listeOcc)*100/nbMax)<=100:
				# Copie des miniatures dans l'image de fond
				img2.paste(redim, coorXY)
				# Sauvegarde pour l'utilisateur
				img2.save(self.chemDossierSauv+'_'+string.zfill(1, 3)+ext)
				# Remplissage de la liste des pages sauvegardées (Info)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(1, 3)+ext)
				# Sauv ds rep. tampon et affichage de la planche-contact ------
				# Si le format de sortie est .pdf (format non géré par PIL ni PyQt4) 
				# la page est d'abord sauvegardée dans le rep.
				# /tmp/ekd/tampon/image_divers_planche_contact/ sous forme d'image 
				# .jpg, ainsi elle peut être affichée dans l'interface
				if format=='PDF (.pdf)':
					img2.save(self.repTampon+'plp2_'+string.zfill(1, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(1, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(1, 3)+ext)
			# -------------------------------------------------------------
			# Conditions d'affichage sur la 2ème page, sauvegarde et affichage
			elif 101<=(len(listeOcc)*100/nbMax)<=200:
				img3.paste(redim, coorXY)
				img3.save(self.chemDossierSauv+'_'+string.zfill(2, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(2, 3)+ext)
				if format=='PDF (.pdf)':
					img3.save(self.repTampon+'plp2_'+string.zfill(2, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(2, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(2, 3)+ext)
			# Conditions d'affichage sur la 3ème page, sauvegarde et affichage
			elif 201<=(len(listeOcc)*100/nbMax)<=300:
				img4.paste(redim, coorXY)
				img4.save(self.chemDossierSauv+'_'+string.zfill(3, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(3, 3)+ext)
				if format=='PDF (.pdf)':
					img4.save(self.repTampon+'plp2_'+string.zfill(3, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(3, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(3, 3)+ext)
			# ...
			elif 301<=(len(listeOcc)*100/nbMax)<=400:
				img5.paste(redim, coorXY)
				img5.save(self.chemDossierSauv+'_'+string.zfill(4, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(4, 3)+ext)
				if format=='PDF (.pdf)':
					img5.save(self.repTampon+'plp2_'+string.zfill(4, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(4, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(4, 3)+ext)
			elif 401<=(len(listeOcc)*100/nbMax)<=500:
				img6.paste(redim, coorXY)
				img6.save(self.chemDossierSauv+'_'+string.zfill(5, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(5, 3)+ext)
				if format=='PDF (.pdf)':
					img6.save(self.repTampon+'plp2_'+string.zfill(5, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(5, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(5, 3)+ext)
			elif 501<=(len(listeOcc)*100/nbMax)<=600:
				img7.paste(redim, coorXY)
				img7.save(self.chemDossierSauv+'_'+string.zfill(6, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(6, 3)+ext)
				if format=='PDF (.pdf)':
					img7.save(self.repTampon+'plp2_'+string.zfill(6, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(6, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(6, 3)+ext)
			elif 601<=(len(listeOcc)*100/nbMax)<=700:
				img8.paste(redim, coorXY)
				img8.save(self.chemDossierSauv+'_'+string.zfill(7, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(7, 3)+ext)
				if format=='PDF (.pdf)':
					img8.save(self.repTampon+'plp2_'+string.zfill(7, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(7, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(7, 3)+ext)
			elif 701<=(len(listeOcc)*100/nbMax)<=800:
				img9.paste(redim, coorXY)
				img9.save(self.chemDossierSauv+'_'+string.zfill(8, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(8, 3)+ext)
				if format=='PDF (.pdf)':
					img9.save(self.repTampon+'plp2_'+string.zfill(8, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(8, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(8, 3)+ext)
			elif 801<=(len(listeOcc)*100/nbMax)<=900:
				img10.paste(redim, coorXY)
				img10.save(self.chemDossierSauv+'_'+string.zfill(9, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(9, 3)+ext)
				if format=='PDF (.pdf)':
					img10.save(self.repTampon+'plp2_'+string.zfill(9, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(9, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(9, 3)+ext)
			elif 901<=(len(listeOcc)*100/nbMax)<=1000:
				img11.paste(redim, coorXY)
				img11.save(self.chemDossierSauv+'_'+string.zfill(10, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(10, 3)+ext)
				if format=='PDF (.pdf)':
					img11.save(self.repTampon+'plp2_'+string.zfill(10, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(10, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(10, 3)+ext)
			elif 1001<=(len(listeOcc)*100/nbMax)<=1100:
				img12.paste(redim, coorXY)
				img12.save(self.chemDossierSauv+'_'+string.zfill(11, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(11, 3)+ext)
				if format=='PDF (.pdf)':
					img12.save(self.repTampon+'plp2_'+string.zfill(11, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(11, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(11, 3)+ext)
			elif 1101<=(len(listeOcc)*100/nbMax)<=1200:
				img13.paste(redim, coorXY)
				img13.save(self.chemDossierSauv+'_'+string.zfill(12, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(12, 3)+ext)
				if format=='PDF (.pdf)':
					img13.save(self.repTampon+'plp2_'+string.zfill(12, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(12, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(12, 3)+ext)
			elif 1201<=(len(listeOcc)*100/nbMax)<=1300:
				img14.paste(redim, coorXY)
				img14.save(self.chemDossierSauv+'_'+string.zfill(13, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(13, 3)+ext)
				if format=='PDF (.pdf)':
					img14.save(self.repTampon+'plp2_'+string.zfill(13, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(13, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(13, 3)+ext)
			elif 1301<=(len(listeOcc)*100/nbMax)<=1400:
				img15.paste(redim, coorXY)
				img15.save(self.chemDossierSauv+'_'+string.zfill(14, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(14, 3)+ext)
				if format=='PDF (.pdf)':
					img15.save(self.repTampon+'plp2_'+string.zfill(14, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(14, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(14, 3)+ext)
			elif 1401<=(len(listeOcc)*100/nbMax)<=1500:
				img16.paste(redim, coorXY)
				img16.save(self.chemDossierSauv+'_'+string.zfill(15, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(15, 3)+ext)
				if format=='PDF (.pdf)':
					img16.save(self.repTampon+'plp2_'+string.zfill(15, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(15, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(15, 3)+ext)
			elif 1501<=(len(listeOcc)*100/nbMax)<=1600:
				img17.paste(redim, coorXY)
				img17.save(self.chemDossierSauv+'_'+string.zfill(16, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(16, 3)+ext)
				if format=='PDF (.pdf)':
					img17.save(self.repTampon+'plp2_'+string.zfill(16, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(16, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(16, 3)+ext)
			elif 1601<=(len(listeOcc)*100/nbMax)<=1700:
				img18.paste(redim, coorXY)
				img18.save(self.chemDossierSauv+'_'+string.zfill(17, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(17, 3)+ext)
				if format=='PDF (.pdf)':
					img18.save(self.repTampon+'plp2_'+string.zfill(17, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(17, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(17, 3)+ext)
			elif 1701<=(len(listeOcc)*100/nbMax)<=1800:
				img19.paste(redim, coorXY)
				img19.save(self.chemDossierSauv+'_'+string.zfill(18, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(18, 3)+ext)
				if format=='PDF (.pdf)':
					img19.save(self.repTampon+'plp2_'+string.zfill(18, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(18, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(18, 3)+ext)
			elif 1801<=(len(listeOcc)*100/nbMax)<=1900:
				img20.paste(redim, coorXY)
				img20.save(self.chemDossierSauv+'_'+string.zfill(19, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(19, 3)+ext)
				if format=='PDF (.pdf)':
					img20.save(self.repTampon+'plp2_'+string.zfill(19, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(19, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(19, 3)+ext)
			elif 1901<=(len(listeOcc)*100/nbMax)<=2000:
				img21.paste(redim, coorXY)
				img21.save(self.chemDossierSauv+'_'+string.zfill(20, 3)+ext)
				listeAff_2.append(self.chemDossierSauv+'_'+string.zfill(20, 3)+ext)
				if format=='PDF (.pdf)':
					img21.save(self.repTampon+'plp2_'+string.zfill(20, 3)+'.jpg')
					self.afficheurImg_2.setImage(self.repTampon+'plp2_'+string.zfill(20, 3)+'.jpg')
				else: self.afficheurImg_2.setImage(self.chemDossierSauv+'_'+string.zfill(20, 3)+ext)
			
			# La page Image résultat devient visible à la fin des conversions
			self.tabwidget.setCurrentIndex(self.indexImageResultat)
			
			# Affichage de la dernière image du lot chargée par l'utilisateur---
			self.afficheurImg_1.setImage(self.listeChemin[len(self.listeChemin)-1])
			# ------------------------------------------------------------------
			
			# Remplissage de la liste pour les statistiques de rendu
			listeAff_1.append(images)
			
			# ================================================================== #
			# Calcule le pourcentage effectue a chaque passage et ce pour la 
			# barre de progression .
			# ---------------------------------------------
			val_pourc=((len(listeOcc)*100)/(nbreImg/self.spin1.value()))
			# Si le pourcentage dépasse les 100% il est remis à 100
			if val_pourc>=100: val_pourc=100
			
			# --------------------------------------------
			# Affichage de la progression (avec
			# QProgressDialog) ds une fenêtre séparée
			self.progress.setValue(val_pourc)
			QApplication.processEvents()
			# Bouton Cancel pour arrêter la progression donc le process
			if (self.progress.wasCanceled()): break
			# --------------------------------------------
		
		# Récupération du chemin + nom des fichiers
		# sauvegardés en ayant éliminé les doublons
		import sets
		listeAff_2=list(set(listeAff_2))
		listeAff_2.sort()
			
		# Affichage des infos sur l'image -------------------------	
		# On implémente les chemins des fichiers dans une variable
		# pour préparer l'affichage des infos
		texte1=_(u" Image(s) chargée(s)")
		texte2=_(u" Pages des planches-contact sauvegardées")
		a='#'*36
			
		self.infosImgProv_1=a+'\n#'+texte1+'\n'+a
		self.infosImgProv_2=a+'\n#'+texte2+'\n'+a
		
		# Images chargées
		for parcStatRendu_1 in listeAff_1:
			self.infosImgProv_1=self.infosImgProv_1+'\n'+parcStatRendu_1
			
		# Pages sauvegardées
		for parcStatRendu_2 in listeAff_2:
			self.infosImgProv_2=self.infosImgProv_2+'\n'+parcStatRendu_2
		
		# affichage des infos dans l'onglet
		self.zoneAffichInfosImg.setText(self.infosImgProv_1+'\n\n'+self.infosImgProv_2+'\n\n')
		self.framImg.setEnabled(True)
			
		# remise à 0 de la variable provisoire de log
		self.infosImgProv=''
		# ---------------------------------------------------------

		# Epuration/elimination des fichiers tampon
		for toutRepTemp in glob.glob(self.repTampon+'*.*'):
			os.remove(toutRepTemp)
		# Si les images viennent d'être redimensionnées ...	
		if len(glob.glob(self.repTampon+'redim/*.*'))>0:
			# Epuration/elimination des fichiers tampon dans le rep redim
			for repTemp in glob.glob(self.repTampon+'redim/*.*'):
				os.remove(repTemp)
		
	
	def sonderTempsActuel(self):
		"""x ms après l'apparition de la boite de dialogue, on lance la conversion. But: faire en sorte que la boite de dialogue ait le temps de s'afficher correctement"""
		self.timer.stop()
		self.appliquer()
	
	
	def appliquer(self):
		"""On lance le type de conversion correspondant aux items sélectionnés des 2 boites de combo """
		# Si on a sélectionné masque alpha et la méthode 1 
		
		self.planche_contact()
		
	
	def appliquer0(self):
		"""Préparation de la conversion"""
		
		# Si la valeur de Passage d'une image à l'autre est supérieure au nbre d'images
		# chargées par l'utilisateur ...
		if self.spin1.value()>len(self.listeChemin):
			warn=QMessageBox(self)
			warn.setText(_(u"La valeur de 'Passage d'une image à l'autre' est supérieure au nombre d'images que vous avez chargé, cela ne convient pas (la valeur de 'Passage ...' doit obligatoirement être inférieure au nombre d'images chargées pour que l'opération puisse se poursuivre)"))
			warn.setWindowTitle(_(u"Attention !"))
			warn.setIcon(QMessageBox.Warning)
			warn.exec_()
   			return
		
		# Autrement si tout va bien ...
			
		# Boîte de dialogue pour sauvegarder (nom du nouveau fichier)
		rep = self.base.getRepSource(self.listeChemin, self.config)
		self.chemDossierSauv=str(QFileDialog.getSaveFileName(None, _(u"Sauver"), rep, _(u"Tous les fichiers *.*")))
		
		if self.chemDossierSauv=='': return
		
		self.progress.reset()
		self.progress.show()
		self.progress.setValue(0)
		QApplication.processEvents()
		
		# Lancement de la conversion dans 250 ms (seule solution trouvée pour éviter 
		# le grisage au début)
		self.timer.start(250)

		
	def afficherAide(self):
		"""Boîte de dialogue de l'aide"""
		messageAide=QMessageBox(self)
		messageAide.setText(_(u"Blablablabla ... blabla."))
		messageAide.setWindowTitle(_(u"Aide"))
		messageAide.setIcon(QMessageBox.Information)
		messageAide.exec_()
		