Esempio n. 1
0
class MainWindow(QDialog):

	def __init__(self, parent=None):
		super(MainWindow, self).__init__(parent)
		self.stopSign = 0
		self.ws = 0
		self.comment = ''
		self.clipboard = QApplication.clipboard()
		self.setWindowTitle(u'勤務表')
		self.setWindowIcon(QIcon('./img/tray.png'))
		self.systemTrayIcon = QSystemTrayIcon(self)

		self.systemTrayIcon.setIcon(QIcon('./img/tray.png'))
		self.systemTrayIcon.setVisible(True)
		self.systemTrayIcon.show()

		self.systemTrayIcon.activated.connect(self.on_systemTrayIcon_activated)
		self.tableLabel = QLabel('select *.xls file')
		self.pathText   = QLineEdit()
		self.triggerBtn = QPushButton(u'檢查 / 開始')
		self.browseBtn  = QPushButton(u'   瀏覽   ')
		self.stopBtn	= QPushButton(u'停止')
		self.table      = QTableWidget(26,0,self)
		self.setUpTable()


		self.hbox1	  = QHBoxLayout()
		self.hbox2	  = QHBoxLayout()
		self.hbox3    = QHBoxLayout()
		self.hbox4	  = QHBoxLayout()

		self.hbox1.addWidget(self.pathText)
		self.hbox1.addWidget(self.browseBtn)
		self.hbox1.addWidget(self.triggerBtn)
		self.browseBtn.clicked.connect(self.OpenFile)
		self.triggerBtn.clicked.connect(self.setupTypeThread)
		self.stopBtn.clicked.connect(self.threadStop)

		self.status = QTreeWidget(self)
		
		self.status.setHeaderHidden(True)
		self.hbox2.addWidget(self.status)
		self.hbox3.addWidget(self.table)
		self.hbox4.addWidget(self.stopBtn)
		self.setGeometry(200, 200, 700, 400)
		self.status.setFixedHeight (80)
		self.layout = QVBoxLayout()
		self.layout.addWidget(self.tableLabel)
		self.layout.addLayout(self.hbox1)
		self.layout.addLayout(self.hbox2)
		self.layout.addLayout(self.hbox3)
		self.layout.addLayout(self.hbox4)
		self.setLayout(self.layout)
		self.stopBtn.setEnabled(False)

	def setUpTable(self):
		self.table.horizontalHeader().setVisible(False)
		for i in xrange(0, 26, 1):
			self.vhfont = QFont('Times', pointSize = 10, weight=QFont.Bold)
			timePos = i+6
			if   i == 0:
				item = QTableWidgetItem(u'[標題]')
			elif i == 1:
				item = QTableWidgetItem(u'[設定]')
			elif 2 < timePos < 24:
				item = QTableWidgetItem(('{0}~{1}').format(timePos, timePos+1))
			else:
				item = QTableWidgetItem(('{0}~{1}').format(timePos-24, timePos-23))
			item.setFont(self.vhfont)
			item.setTextAlignment(Qt.AlignCenter)
			self.table.setVerticalHeaderItem(i, item)

	def on_systemTrayIcon_activated(self, reason):
		if reason == QSystemTrayIcon.DoubleClick:
			if self.isHidden():
				try:
					self.typeThread
					self.threadStop()
				except:
					pass
				self.show()

			else:
				self.hide()

	def setupTypeThread(self): 
		self.clipboard.setText('')
		det = self.loadDetec()
		self.ws, vaild = self.checkTableValidation(det, self.table)
		ws = []
		for col in self.ws:
			ws.append(col[0])
		self.addStatus( u'  狀態:  檢查勤務表狀態....', 0)
		errStat = self.check(ws)
		

		if vaild != True and self.table.columnCount()!=0:
			self.addStatus( vaild, 1)
		elif self.table.columnCount() ==0:
			self.addStatus( u'  錯誤:  請載入勤務表', 1)
			
		self.typeThread = startType(self.ws)  
		self.typeThread.threadDone.connect(self.showDoneMsg, Qt.QueuedConnection)
		self.typeThread.toTray.connect(self.toTray, Qt.QueuedConnection)
		self.typeThread.toCilpboard.connect(self.toCilpboard, Qt.QueuedConnection) 
		self.typeThread.enableButtons.connect(self.enableButtons, Qt.QueuedConnection)
		self.typeThread.showErrMsg.connect(self.showErrMsg, Qt.QueuedConnection)  
		self.typeThread.addStatus.connect(self.addStatus, Qt.QueuedConnection) 

		if not self.typeThread.isRunning() and vaild == True and errStat == True:
			self.addStatus( u'  狀態:  檢查通過,開始進行登打作業....', -1)
			self.browseBtn.setEnabled(False)
			self.triggerBtn.setEnabled(False)
			self.stopBtn.setEnabled(True)
			self.typeThread.start()

	def toTray(self, state):
		if state:
			pass
			self.hide()
			self.systemTrayIcon.showMessage(u'輸入中',u'勤務表背景輸入中....\n\n雙擊圖示可暫停程序', msecs=1000000)
		else:
			self.show()			

	def toCilpboard(self, text):
		self.clipboard.setText(text)

	def threadStop(self):
		self.typeThread.stopSign = 1
		if self.typeThread.isRunning():
			self.browseBtn.setEnabled(True)
			self.triggerBtn.setEnabled(True)
			self.stopBtn.setEnabled(False)

	def addStatus(self, text, err):
		subTreeItem =  QTreeWidgetItem(self.status)
		subTreeItem.setText(0, text)
		self.activateWindow()

		if err == 1:
			font = QFont('Serif', 10, QFont.Bold)
			subTreeItem.setFont(0, font)
			subTreeItem.setForeground(0, QBrush(Qt.white))
			subTreeItem.setBackground(0, QBrush(QColor(150,0,0)))
		elif err == 0:
			font = QFont('Serif', 10, QFont.Bold)
			subTreeItem.setFont(0, font)
			subTreeItem.setForeground(0, QBrush(Qt.black))
			subTreeItem.setBackground(0, QBrush(Qt.white))
		else:
			font = QFont('Serif', 10, QFont.Bold)
			subTreeItem.setFont(0, font)
			subTreeItem.setForeground(0, QBrush(Qt.white))
			subTreeItem.setBackground(0, QBrush(QColor(0,150,0)))			
		self.status.scrollToItem(subTreeItem, QAbstractItemView.PositionAtCenter)
		
	def showErrMsg(self, title, msg):
		self.addStatus( u'錯誤:  ' + msg, 1)
		QMessageBox.warning(self, title, msg, QMessageBox.Ok)

	def showDoneMsg(self):
		self.addStatus( u'完成:  完成!', 1)
		QMessageBox.warning(self, u'完成!', u'完成!', QMessageBox.Ok)

	def enableButtons(self):
		self.clipboard.setText(self.comment)
		self.browseBtn.setEnabled(True)
		self.triggerBtn.setEnabled(True)
		self.stopBtn.setEnabled(False)
		self.show()
	
	def OpenFile(self):
		fileName	  = QFileDialog.getOpenFileName(self, "Open File.", "/home")
		self.comment  = ''
		ext = fileName[0].split('.')[-1]
		if ext == 'xls' or ext == 'xlsx':
			self.pathText.setText(fileName[0])
			sheet = open_workbook(fileName[0]).sheets()[0]
			self.setFixedHeight(550)
			self.addStatus(  u'  狀態:  載入勤務表: [' + fileName[0] + ']', -1)
			for col in xrange(self.table.columnCount()-1,-1,-1):
				self.table.removeColumn(col)
			ws, header, headerNum = self.loadWS(sheet)
			self.appendTable(header, ws)

			
			self.check(ws)
			self.comment += self.yieldcomment(sheet)
			self.ws = ws
		else:
			self.showErrMsg(u'錯誤',u'選取檔案不是EXCEL檔')
			self.ws = 0


	def checkTableValidation(self, detCol, table):
		#	.[ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9]
		ws = [[], [], [], [], [], [], [], [], [], []]
		errStat = True
		if len(detCol) == 0 or (0 in detCol):
			errStat =  u'  狀態:  勤務表標頭錯誤,點選 [ --請選擇-- ] 選取有效標頭'
		for i in xrange(len(detCol)-1):
			if sorted(detCol)[i] == sorted(detCol)[i+1]:
				errStat = u'  狀態:  勤務表標頭重複'
				
		print detCol
		for c in xrange(table.columnCount()):
			col = []
			colNum = detCol[c]
			for r in xrange(2, 26, 1):
				col.append(table.item(r,c).text())
			ws[colNum-1].append(col)
		for i in xrange(len(ws)):
			if len(ws[i]) == 0:
				ws[i].append(['','','','','','','','','','','','','','','','','','','','','','','',''])
		return (ws), errStat


	def loadWS(self, sheet):
		header, headerNum, ws= [],[],[]
		for c in xrange(3, 26 ,1):
			title  = (sheet.cell_value(3, c))
			if len(title) != 0 and len(header) <6:				
				header.append(title)
				col = []
				for m in xrange(7, 31, 1):
					try:
						col.append(str(sheet.cell_value(m, c)).strip('()').replace('.0', '').replace('.', ','))
					except:
						col.append(u'error')
				ws.append(col)
		return ws, header, headerNum

	def appendTable(self, header, ws):
		try:
			font  = QFont('TypeWriter', pointSize = 10, weight=QFont.Bold)
			for text in header:
				self.table.insertColumn(0)
			for c in xrange(len(header)):
				det = self.determine(header[c])
				item = QTableWidgetItem(header[c])
				if det == 0:
					item.setBackground(QBrush(QColor('#FF8D00')))
				else:
					item.setBackground(QBrush(QColor('#005588')))
				item.setFont(font)
				item.setTextAlignment(Qt.AlignCenter)
				self.table.setItem(0, c, item)	

				nComboBox = self.newCombo()
				nComboBox.setCurrentIndex(det)
				self.table.setCellWidget(1, c, (nComboBox))
				
				for r in xrange(2,26,1):
					item = QTableWidgetItem(ws[c][r-2])
					item.setFont(font)
					item.setTextAlignment(Qt.AlignCenter)
					self.table.setItem(r, c, item)
			self.addStatus(  u'  狀態:  勤務表預覽成功', -1)
			return 0
		except:
			self.addStatus(  u'  狀態:  勤務表預覽失敗', 1)
			return 'error'

	def loadDetec(self):
		det = []
		for col in xrange(self.table.columnCount()):
			det.append( self.table.cellWidget(1, col).currentIndex())
		return det

	def newCombo(self):
		taskList  = [u'--請選擇--', u'值班', u'救護勤務', u'備勤', u'待命服勤', u'水源查察', u'消防查察', u'宣導勤務', u'訓(演)練', u'專案勤務', u'南山救護站']
		nComboBox = QComboBox()
		nComboBox.addItems(taskList)
		for i in xrange(len(taskList)):
			if i == 0:
				nComboBox.setItemData(i, QColor('#550000'), Qt.BackgroundColorRole)
			nComboBox.setItemData(i, Qt.AlignCenter, Qt.TextAlignmentRole)
		nComboBox.setStyleSheet("text-align: right; font: bold 13px;")		
		return nComboBox

	def setTableErr(self, row, state):
		if   state == 'illegal'  : color = '#CC0033'
		elif state == 'repeated' : color = '#FF8D00'
		elif state == 'legal'    : color = '#201F1F'
		for col in xrange(self.table.columnCount()):
			self.table.item(row,col).setBackground(QBrush(QColor(color)))

	def check(self, ws):
		errStat = True
		for m in xrange(2,26):
			self.setTableErr(m, 'legal')
		for i in xrange(24):
			ary = []
			for j in xrange(len(ws)):
				for each in ws[j][i].replace(' ', '').split(','):
					try:
						if	each == "A": ary.append(-1)
						elif  each == '' : pass
						else: each == ary.append(int(each))

					except:
						errStat = False
						timePos = i+8
						rptErrMSG = u"  錯誤:  於 {0} ~ {1} 時   數字: {2}  --不合法,  請修正"
						self.setTableErr(i+2, 'illegal')
						print timePos
						if timePos < 23:
							print 'a'
							self.addStatus(rptErrMSG.format(timePos,   timePos+1,   each), 1)
						else:
							self.addStatus(rptErrMSG.format(timePos-24, timePos-23, each), 1)
									
			ary = sorted(ary)
			for idx in xrange(len(ary)-1):
				if ary[idx] == ary[idx+1]:
					errStat = False
					timePos = i+8
					rptErrMSG = u"  錯誤:  於 {0} ~ {1} 時   數字: {2}  --番號重複, 請修正"
					self.setTableErr(i+2, 'repeated')
					if timePos < 23:
						self.addStatus(rptErrMSG.format(timePos,   timePos+1,   str(ary[idx]).replace('-1', 'A')), 1)
					else:
						self.addStatus(rptErrMSG.format(timePos-24, timePos-23, str(ary[idx]).replace('-1', 'A')), 1)

		return errStat

	def determine(self, title):
		cmpfactor = 0

		smp = [u'值班', u'救護分隊務', u'備', u'待命服', u'水源', u'消防', u'宣導', u'訓演練', u'專案其它', u'南山站']
		for index, each in zip(xrange(len(smp)),smp):
			for text in each:
				for elem in title:
					cmpfactor += ( elem == text )
			if cmpfactor > 0:
				return index+1
		return 0

	def yieldcomment(self, sheet):
		comment0, comment1 = '', ''
		# for i,j in [[24,27], [27,27], [29,27], [29,35]]:
		# 	try:
		# 		comment0 += (smart_str(sheet.cell_value(i, j)) + '\n')
		# 	except:
		# 		pass
		for i,j in [[31,3], [32,3], [33,3], [34,3]]:
			try:
				comment1 += (sheet.cell_value(i, j) + '\n')
			except:
				pass
		return comment1
Esempio n. 2
0
class Ui_MainWindow(QMainWindow):
    """Cette classe contient tous les widgets de notre application."""
    
    defaultPalette = QPalette()
    defaultPalette.setColor(QPalette.Base, QColor("#151515"))
    defaultPalette.setColor(QPalette.Text, Qt.white)

    def __init__(self):
        super(Ui_MainWindow, self).__init__()
        # initialise la GUI avec un exemple
        self.text = "Ceci est un petit texte d'exemple."
        # les variables sont en place, initialise la GUI
        self.initUI()
        # exécute l'exemple
        self.orgText.setText(self.text)
        self.encode_text(False)
        self.logLab.setText(
            u"Saisir du texte ou importer un fichier, puis pousser \n"
            u"le bouton correspondant à l'opération souhaitée.")

    def initUI(self):
        """Met en place les éléments de l'interface."""
        # -+++++++------------------- main window -------------------+++++++- #
        self.setWindowTitle(u"Encodage / Décodage de Huffman")
        self.centerAndResize()
        centralwidget = QWidget(self)
        mainGrid = QGridLayout(centralwidget)
        mainGrid.setColumnMinimumWidth(0, 450)
        # -+++++++------------------ groupe analyse -----------------+++++++- #
        analysGroup = QGroupBox(u"Analyse", centralwidget)
        self.analysGrid = QGridLayout(analysGroup)
        #         ----------- groupe de la table des codes ----------         #
        codeTableGroup = QGroupBox(u"Table des codes", analysGroup)
        codeTableGrid = QGridLayout(codeTableGroup)
        # un tableau pour les codes
        self.codesTableModel = MyTableModel()
        self.codesTable = QTableView(codeTableGroup)
        self.codesTable.setModel(self.codesTableModel)
        self.codesTable.setFont(QFont("Mono", 8))
        self.codesTable.resizeColumnsToContents()
        self.codesTable.setSortingEnabled(True)
        codeTableGrid.addWidget(self.codesTable, 0, 0, 1, 1)
        self.analysGrid.addWidget(codeTableGroup, 1, 0, 1, 1)
        #        ----------- label du ratio de compression ----------         #
        self.ratioLab = QLabel(u"Ratio de compression: ", analysGroup)
        font = QFont()
        font.setBold(True)
        font.setWeight(75)
        font.setKerning(True)
        self.ratioLab.setFont(font)
        self.analysGrid.addWidget(self.ratioLab, 2, 0, 1, 1)
        # -+++++++-------- groupe de la table de comparaison --------+++++++- #
        self.compGroup = QGroupBox(analysGroup)
        self.compGroup.setTitle(u"Comparaisons")
        compGrid = QGridLayout(self.compGroup)
        # un tableau pour le ratio
        self.compTable = QTableWidget(self.compGroup)
        sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.compTable.sizePolicy().hasHeightForWidth())
        self.compTable.setSizePolicy(sizePolicy)
        self.compTable.setBaseSize(QSize(0, 0))
        font = QFont()
        font.setWeight(50)
        self.compTable.setFont(font)
        self.compTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        self.compTable.setShowGrid(True)
        self.compTable.setGridStyle(Qt.SolidLine)
        # lignes / colonnes
        self.compTable.setColumnCount(2)
        self.compTable.setRowCount(3)
        self.compTable.setVerticalHeaderItem(0, QTableWidgetItem("Taille (bits)"))
        self.compTable.setVerticalHeaderItem(1, QTableWidgetItem("Entropie"))
        self.compTable.setVerticalHeaderItem(2, QTableWidgetItem("Taille moy. (bits)"))
        for i in range(2):
            self.compTable.verticalHeaderItem(i).setTextAlignment(
                Qt.AlignRight)
        self.compTable.setHorizontalHeaderItem(0, QTableWidgetItem("ASCII"))
        self.compTable.setHorizontalHeaderItem(1, QTableWidgetItem("Huffman"))
        
        # nom des items
        self.compTabASCIIMem = QTableWidgetItem()
        self.compTable.setItem(0, 0, self.compTabASCIIMem)
        self.compTabASCIIEnt = QTableWidgetItem()
        self.compTable.setItem(1, 0, self.compTabASCIIEnt)
        self.compTabASCIIAvg = QTableWidgetItem()
        self.compTable.setItem(2, 0, self.compTabASCIIAvg)
        self.compTabHuffMem = QTableWidgetItem()
        self.compTable.setItem(0, 1, self.compTabHuffMem)
        self.compTabHuffEnt = QTableWidgetItem()
        self.compTable.setItem(1, 1, self.compTabHuffEnt)
        self.compTabHuffAvg = QTableWidgetItem()
        self.compTable.setItem(2, 1, self.compTabHuffAvg)
        # parem du tableau
        self.compTable.horizontalHeader().setCascadingSectionResizes(False)
        self.compTable.verticalHeader().setVisible(True)
        font = QFont("Mono", 8)
        self.compTable.setFont(font)
        compGrid.addWidget(self.compTable, 1, 0, 1, 1)
        self.analysGrid.addWidget(self.compGroup, 0, 0, 1, 1)
        mainGrid.addWidget(analysGroup, 0, 1, 1, 1)
        # -+++++++----------------- groupe du texte -----------------+++++++- #
        groupBox = QGroupBox(u"Texte", centralwidget)
        textGrid = QGridLayout(groupBox)
        # -+++++++------------- groupe du texte original ------------+++++++- #
        orgTextGroup = QGroupBox(u"Texte original (Ctrl+T)", groupBox)
        orgTextGrid = QGridLayout(orgTextGroup)
        self.orgText = QTextEdit(orgTextGroup)
        self.orgText.setPalette(self.defaultPalette)
        orgTextGrid.addWidget(self.orgText, 0, 0, 1, 1)
        textGrid.addWidget(orgTextGroup, 0, 0, 1, 2)
        # -+++++++------------ groupe du texte compressé ------------+++++++- #
        compressedTextGroup = QGroupBox(u"Texte compressé (Ctrl+H)", groupBox)
        compressedTextGrid = QGridLayout(compressedTextGroup)
        self.compressedText = QTextEdit(compressedTextGroup)
        self.compressedText.setPalette(self.defaultPalette)
        compressedTextGrid.addWidget(self.compressedText, 0, 0, 1, 1)
        textGrid.addWidget(compressedTextGroup, 1, 0, 1, 2)
        # -+++++++------------ groupe pour le texte ascii -----------+++++++- #
        asciiTextGroup = QGroupBox(u"Texte ASCII", groupBox)
        asciiTextGrid = QGridLayout(asciiTextGroup)
        self.asciiText = QTextBrowser(asciiTextGroup)
        self.asciiText.setPalette(self.defaultPalette)
        asciiTextGrid.addWidget(self.asciiText, 0, 0, 1, 1)
        textGrid.addWidget(asciiTextGroup, 2, 0, 1, 2)
        # -+++++++-------------------- label de log -----------------+++++++- #
        self.logLab = QLabel(analysGroup)
        textGrid.addWidget(self.logLab, 3, 0, 1, 2)
        # -+++++++----------- bouton pour encoder le texte ----------+++++++- #
        self.encodeBut = QPushButton(groupBox)
        self.encodeBut.setStatusTip(
            u"Cliquez sur ce bouton pour encoder le texte original.")
        self.encodeBut.setText(u"ENCODER")
        self.encodeBut.clicked.connect(self.encode_text)
        textGrid.addWidget(self.encodeBut, 4, 0, 1, 1)
        # -+++++++----------- bouton pour décoder le texte ----------+++++++- #
        self.decodeBut = QPushButton(groupBox)
        self.decodeBut.setStatusTip(
            u"Cliquez sur ce bouton pour décoder le texte compressé.")
        self.decodeBut.setText(u"DÉCODER")
        self.decodeBut.clicked.connect(self.decode_text)
        textGrid.addWidget(self.decodeBut, 4, 1, 1, 1)
        mainGrid.addWidget(groupBox, 0, 0, 1, 1)
        self.setCentralWidget(centralwidget)
        # -+++++++--------------- une barre de statut ---------------+++++++- #
        self.setStatusBar(QStatusBar(self))
        # -+++++++--------------------- le menu ---------------------+++++++- #
        self.fileMenu = QMenu(u"Fichier")
        self.fileMenu.addAction(u"Importer un texte...", self.open_text)
        self.fileMenu.addAction(
            u"Importer un texte encodé...", lambda: self.open_text(True))
        self.fileMenu.addAction(u"Importer un dictionnaire...", self.open_dict)
        self.fileMenu.addAction(u"Enregistrer le dictionnaire...", self.save_dict)
        self.fileMenu.addAction(u"Quitter", self.close)
        self.menuBar().addMenu(self.fileMenu)
        QMetaObject.connectSlotsByName(self)

    def open_text(self, compressed=False):
        """Ouvrir un fichier contenant un texte compressé ou non."""
        fname, _ = QFileDialog.getOpenFileName(self, u'Ouvrir')
        f = open(fname, 'r')
        with f:
            data = f.read()
            if compressed:
                self.compressedText.setText(data)
            else:
                self.orgText.setText(data)

    def open_dict(self):
        """Ouvrir un dictionnaire de codes Huffman."""
        fname, _ = QFileDialog.getOpenFileName(self, u'Ouvrir')
        self.occ = {}
        self.hCodes = {}
        self.aCodes = {}
        self.hCost = {}
        self.aCost = {}
        self.hCodes = create_dict_from_file(fname)
        self.update_codes_table()
        self.logLab.setText(u"Dictionnaire de Huffman importé.")
        return self.hCodes

    def save_dict(self):
        """Enregistrer le dictionnaire de codes Huffman."""
        fname, _ = QFileDialog.getSaveFileName(self, "Enregistrer sous")
        save_dict_to_file(fname, self.hCodes)

    def make_tab_rows(self):
        """Génère le remplissage des lignes du tableau des codes."""
        dictList = [self.occ, self.aCodes, self.hCodes, self.aCost, self.hCost]
        tabList = []
        charList = self.hCodes.keys() if self.hCodes else self.occ.keys()
        for char in charList:
            l = ["'" + char + "'"]
            for dic in dictList:
                try:
                    l.append(dic[char])
                except KeyError:
                    l.append('')
            tabList.append(l)
        return tabList

    def encode_text(self, wizard=True):
        """Encode le texte original."""
        self.text = self.orgText.toPlainText().encode('utf-8')
        if not self.text:
            self.compressedText.setText(u"")
            self.asciiText.setText(u"")
            self.logLab.setText(
                u"<font color=#A52A2A>Rien à compresser.</font>")
            return
        self.occ = {}
        self.tree = ()
        self.hCodes = {}
        self.aCodes = {}
        self.hCost = {}
        self.aCost = {}
        self.hSqueezed = []
        self.aSqueezed = []
        self.stringHSqueezed = ''
        self.stringASqueezed = ''
        if wizard:
            self.launch_wizard(
                EncodeWizard(self),
                u"<font color=#008000>Compression achevée.</font>")
        else:
            self.make_occ()
            self.make_tree()
            self.make_codes()
            self.make_cost()
            self.make_encoded_text()
            self.make_comp()

    def decode_text(self, wizard=True):
        """Décode le texte compressé."""
        self.codeString = str(
            self.compressedText.toPlainText().replace(' ', ''))
        if not self.codeString or not self.hCodes:
            self.orgText.setText(u"")
            self.asciiText.setText(u"")
            if not self.codeString:
                self.logLab.setText(
                    u"<font color=#A52A2A>Rien à décompresser.</font>")
            if not self.hCodes:
                self.logLab.setText(
                    u"<font color=#A52A2A>Dictionnaire indisponible pour la décompression.</font>")
            return
        self.text = ''
        self.stringASqueezed = ''
        if wizard:
            self.launch_wizard(
                DecodeWizard(self),
                u"<font color=#008000>Texte décompressé.</font>")
        else:
            self.make_code_map()
            self.make_decoded_text()

    def launch_wizard(self, wizard, finishString):
        """Lance l'assistant d'en/décodage pour guider l'utilisateur.
        Cache les options inaccessibles pendant l'assistant.
        """
        self.logLab.setText(
            u"<font color=#9E6A00>Opération en cours. "
            u"Suivre les indications.</font>")
        disItems = [self.orgText, self.compressedText, self.encodeBut,
                    self.decodeBut, self.fileMenu.actions()[1],
                    self.fileMenu.actions()[2], self.fileMenu.actions()[3]]
        for item in disItems:
            item.setEnabled(False)
        self.compGroup.setVisible(False)
        self.analysGrid.addWidget(wizard, 0, 0, 1, 1)
        res = wizard.exec_()
        if res:
            self.logLab.setText(finishString)
        else:
            self.logLab.setText(
                u"<font color=#A52A2A>Opération interrompue.</font>")
        for item in disItems:
            item.setEnabled(True)
        self.compGroup.setVisible(True)

    def update_ratio_lab(self):
        """Replace la valeur du label du ratio de compression."""
        if not self.stringASqueezed:
            val = '/'
        else:
            val = (len(self.stringHSqueezed.replace(' ', '')) /
                   float(len(self.stringASqueezed.replace(' ', ''))))
        self.ratioLab.setText(unicode('Taux de compression:  ' + str(val)))

    def update_comp_table(self):
        """Met à jour le tableau de comparaison ASCII VS Huffman."""
        self.compTabASCIIMem.setText(unicode(len(''.join(self.aSqueezed))))
        self.compTabHuffMem.setText(unicode(len(''.join(self.hSqueezed))))
        # entropie ?
        self.compTabASCIIEnt.setText('0')
        self.compTabHuffEnt.setText('0')
        self.compTabASCIIAvg.setText(unicode(8))
        self.compTabHuffAvg.setText(unicode(
            average_code_length(self.hSqueezed)))
        self.compTable.resizeColumnsToContents()

    def update_codes_table(self, hlRow=[]):
        """Met à jour le tableau des codes et surligne les lignes de hlRow."""
        self.codesTableModel.hlRow = hlRow
        self.codesTableModel.emptyTable()
        self.codesTableModel.fillTable(self.make_tab_rows())
        self.codesTable.resizeColumnsToContents()

    def centerAndResize(self):
        """Centre et redimmensionne le widget.""" 
        screen = QDesktopWidget().screenGeometry()
        self.resize(screen.width() / 1.6, screen.height() / 1.4)
        size = self.geometry()
        self.move(
            (screen.width() - size.width()) / 2,
            (screen.height() - size.height()) / 2)

    #===================== METHODS FOR EN/DECODE WIZARDS =====================#
    def make_encode_init(self):
        self.compressedText.setText(unicode(self.stringHSqueezed))
        self.asciiText.setText(unicode(self.stringASqueezed))
        self.orgText.setTextColor(QColor(Qt.darkGreen))
        self.orgText.setText(unicode(self.text.decode('utf-8')))
        self.update_codes_table()

    def make_occ(self):
        self.orgText.setTextColor(QColor(Qt.white))
        self.orgText.setText(unicode(self.text.decode('utf-8')))
        self.occ = occurences(self.text)
        self.update_codes_table([0, 1])

    def make_tree(self):
        self.tree = make_trie(self.occ)
        self.update_codes_table()

    def make_codes(self):
        self.hCodes = make_codes(self.tree, {})
        self.aCodes = make_ascii_codes(self.occ.keys(), {})
        self.update_codes_table([2, 3])

    def make_cost(self):
        self.hCost = tree_cost(self.hCodes, self.occ)
        self.aCost = tree_cost(self.aCodes, self.occ)
        self.update_codes_table([4, 5])

    def make_encoded_text(self):
        self.hSqueezed = squeeze(self.text, self.hCodes)
        self.aSqueezed = squeeze(self.text, self.aCodes)
        self.stringHSqueezed = ' '.join(self.hSqueezed)
        self.stringASqueezed = ' '.join(self.aSqueezed)
        self.compressedText.setTextColor(QColor(Qt.darkGreen))
        self.asciiText.setTextColor(QColor(Qt.darkYellow))
        self.compressedText.setText(unicode(self.stringHSqueezed))
        self.asciiText.setText(unicode(self.stringASqueezed))
        self.update_codes_table()

    def make_comp(self):
        self.compressedText.setTextColor(QColor(Qt.white))
        self.asciiText.setTextColor(QColor(Qt.white))
        self.compressedText.setText(unicode(self.stringHSqueezed))
        self.asciiText.setText(unicode(self.stringASqueezed))
        self.update_codes_table()
        self.update_comp_table()
        self.update_ratio_lab()

    def make_decode_init(self):
        self.orgText.setText(unicode(self.text))
        self.asciiText.setText(unicode(self.stringASqueezed))
        self.compressedText.setTextColor(QColor(Qt.darkGreen))
        self.compressedText.setText(self.compressedText.toPlainText())

    def make_code_map(self):
        self.compressedText.setTextColor(QColor(Qt.white))
        self.compressedText.setText(self.compressedText.toPlainText())
        self.orgText.setText(unicode(self.text))
        self.asciiText.setText(unicode(self.stringASqueezed))
        self.codeMap = dict(zip(self.hCodes.values(), self.hCodes.keys()))
        self.update_codes_table([0, 3])

    def make_decoded_text(self):
        self.unSqueezed = unsqueeze(self.codeString, self.codeMap)
        self.text = ''.join(self.unSqueezed)
        self.orgText.setTextColor(QColor(Qt.darkGreen))
        self.orgText.setText(unicode(self.text.decode('utf-8')))
        self.asciiText.setText(unicode(self.stringASqueezed))
        self.update_codes_table()

    def make_ascii_decode(self):
        self.orgText.setTextColor(QColor(Qt.white))
        self.orgText.setText(unicode(self.text.decode('utf-8')))
        self.aCodes = make_ascii_codes(self.codeMap.values(), {})
        self.aSqueezed = squeeze(self.text, self.aCodes)
        self.stringASqueezed = ' '.join(self.aSqueezed)
        self.occ = occurences(self.text)
        self.hCost = tree_cost(self.hCodes, self.occ)
        self.aCost = tree_cost(self.aCodes, self.occ)
        self.asciiText.setTextColor(QColor(Qt.darkGreen))
        self.asciiText.setText(unicode(self.stringASqueezed))
        self.update_codes_table([1, 2, 4, 5])