huffman-py/huffman_py/gui/Ui_MainWindow.py

270 lines
9.6 KiB
Python
Raw Permalink Normal View History

2023-05-25 00:39:32 +02:00
#
# Sam Hadow - Huffman-py
# Copyright (C) 2023
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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, see <http://www.gnu.org/licenses/>.
#
from PyQt5 import QtCore, QtGui, QtWidgets, QtSvg
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import os, json, sys
from huffman_py.gui.generate_graph import *
2023-05-25 02:05:35 +02:00
from huffman_py.functions.decode import *
from huffman_py.functions.encode import *
2023-05-25 00:39:32 +02:00
from huffman_py.gui.InputDialog import *
2023-05-25 02:05:35 +02:00
from huffman_py.functions.ifFileGetContent import *
2023-05-25 00:39:32 +02:00
from huffman_py.gui.messageBox import *
class Ui_MainWindow(QWidget):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(800, 800)
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
2023-05-25 02:05:35 +02:00
# widget to attach graph/text
2023-05-25 00:39:32 +02:00
self.widget = QWidget(self.centralwidget)
self.widget.setObjectName(u"widget")
self.widget.setMinimumSize(QSize(10, 10))
self.gridLayout.addWidget(self.widget, 1, 0, 1, 1)
2023-05-25 02:05:35 +02:00
# widget_2 to attach buttons
2023-05-25 00:39:32 +02:00
self.widget_2 = QWidget(self.centralwidget)
self.widget_2.setObjectName(u"widget_2")
self.widget_2.setMaximumSize(QSize(4000, 50))
self.gridLayout.addWidget(self.widget_2, 0, 0, 1, 1)
##
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
2023-05-25 02:05:35 +02:00
# text/svg widget grid
2023-05-25 00:39:32 +02:00
self.gridLayout_main = QGridLayout(self.widget)
self.gridLayout_main.setObjectName(u"gridLayout_main")
2023-05-25 02:05:35 +02:00
# text/svg widgets
2023-05-25 00:39:32 +02:00
#####
2023-05-25 02:05:35 +02:00
# svg (tree graph)
2023-05-25 00:39:32 +02:00
self.viewer = QtSvg.QSvgWidget()
self.gridLayout_main.addWidget(self.viewer,0, 0, 1, 1)
#####
2023-05-25 02:05:35 +02:00
# text
self.text = QTextEdit()
self.text.setReadOnly(True)
self.gridLayout_main.addWidget(self.text,1, 0, 1, 1)
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# hide widgets for now
2023-05-25 00:39:32 +02:00
self.viewer.setVisible(False)
2023-05-25 02:05:35 +02:00
self.text.setVisible(False)
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# grid2
# buttons
2023-05-25 00:39:32 +02:00
######################
self.gridLayout_2 = QGridLayout(self.widget_2)
self.gridLayout_2.setObjectName(u"gridLayout_2")
#####
2023-05-25 02:05:35 +02:00
# push button encoding
2023-05-25 00:39:32 +02:00
self.pushButton_encode = QPushButton(self.widget_2)
self.pushButton_encode.setObjectName(u"pushButton")
self.gridLayout_2.addWidget(self.pushButton_encode, 1, 0, 1, 1)
2023-05-25 02:05:35 +02:00
self.pushButton_encode.setText(QCoreApplication.translate("MainWindow", u"encode", None))
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# button function
2023-05-25 00:39:32 +02:00
self.pushButton_encode.clicked.connect(self.showDialogEncoder)
#####
2023-05-25 02:05:35 +02:00
# push button decoding
2023-05-25 00:39:32 +02:00
self.pushButton_decode = QPushButton(self.widget_2)
self.pushButton_decode.setObjectName(u"pushButton_decode")
self.gridLayout_2.addWidget(self.pushButton_decode, 1, 1, 1, 1)
2023-05-25 02:05:35 +02:00
self.pushButton_decode.setText(QCoreApplication.translate("MainWindow", u"decode", None))
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# button function
self.pushButton_decode.clicked.connect(self.showDialogDecode)
2023-05-25 00:39:32 +02:00
#####
# push button encode to file
self.pushButton_encodeToFile = QPushButton(self.widget_2)
self.pushButton_encodeToFile.setObjectName(u"pushButton_encodeToFile")
self.gridLayout_2.addWidget(self.pushButton_encodeToFile, 1, 2, 1, 1)
2023-05-25 02:05:35 +02:00
self.pushButton_encodeToFile.setText(QCoreApplication.translate("MainWindow", u"encode to file", None))
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# button function
self.pushButton_encodeToFile.clicked.connect(self.showDialogEncodeToFile)
2023-05-25 00:39:32 +02:00
#####
#push button decode to file
self.pushButton_decodeToFile = QPushButton(self.widget_2)
self.pushButton_decodeToFile.setObjectName(u"pushButton_decodeToFile")
self.gridLayout_2.addWidget(self.pushButton_decodeToFile, 1, 3, 1, 1)
2023-05-25 02:05:35 +02:00
self.pushButton_decodeToFile.setText(QCoreApplication.translate("MainWindow", u"decode to file", None))
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# button function
self.pushButton_decodeToFile.clicked.connect(self.showDialogDecodeToFile)
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
##### end buttons
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# function on exit
2023-05-25 00:39:32 +02:00
qApp.aboutToQuit.connect(self.closeEvent)
######
2023-05-25 02:05:35 +02:00
# button functions
2023-05-25 00:39:32 +02:00
def showDialogEncoder(self):
2023-05-25 02:05:35 +02:00
'''dialog to encode a text, path to file allowed, will show a tree'''
text_input, ok = QInputDialog.getText(self, 'Input', 'Text to encode')
text = ifFileGetContent(text_input)
2023-05-25 00:39:32 +02:00
if ok and len(text) > 0:
the_data = (str(text))
print(the_data)
2023-05-25 02:05:35 +02:00
encoding, root, _ = huffman_encode(the_data)
2023-05-25 00:39:32 +02:00
print("Encoded output", encoding)
2023-05-25 02:05:35 +02:00
print("Decoded Output", huffman_decode(encoding, root))
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# generate tree svg
generate_graph(root)
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# refresh output
2023-05-25 00:39:32 +02:00
self.viewer.load('tree.svg')
self.viewer.update()
2023-05-25 02:05:35 +02:00
# show tree (and encoded text in a small box)
2023-05-25 00:39:32 +02:00
self.viewer.setVisible(True)
2023-05-25 02:05:35 +02:00
self.text.setText(encoding)
self.text.setMaximumSize(QSize(4000, 50))
self.text.setVisible(True)
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
def showDialogDecode(self):
'''dialog to decode a text with its dictionary, will show decoded text, path to files allowed'''
dialog = InputDialog("binary","Dict {char:code} JSON-formatted")
2023-05-25 00:39:32 +02:00
if dialog.exec():
data = dialog.getInputs()
2023-05-25 02:05:35 +02:00
binary = ifFileGetContent(data[0])
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
if len(binary)>0 and len(data[1])>0:
2023-05-25 00:39:32 +02:00
try:
2023-05-25 02:05:35 +02:00
dict = json.loads(ifFileGetContent(data[1]))
2023-05-25 00:39:32 +02:00
except ValueError:
2023-05-25 02:05:35 +02:00
create_msg_box("Can't read dictionary, is it JSON-formatted?","Invalid dictionary")
2023-05-25 00:39:32 +02:00
return 0
try:
2023-05-25 02:05:35 +02:00
text = decode_from_dict(binary, dict)
2023-05-25 00:39:32 +02:00
except ValueError:
2023-05-25 02:05:35 +02:00
create_msg_box("Can't decode text, is it the right dictionary?","decoding error")
2023-05-25 00:39:32 +02:00
return 0
except TypeError:
2023-05-25 02:05:35 +02:00
create_msg_box("Can't use text in input, is it a binary?","Input error")
2023-05-25 00:39:32 +02:00
return 0
2023-05-25 02:05:35 +02:00
# replace text widget content with decoded text
self.text.setText(text)
self.text.setMaximumSize(QSize(4000, 4000))
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
# show text widget (and hide tree)
2023-05-25 00:39:32 +02:00
self.viewer.setVisible(False)
2023-05-25 02:05:35 +02:00
self.text.setVisible(True)
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
def showDialogEncodeToFile(self):
'''Dialog to encode a text (path allowed), create a path.raw file with encoded text and a path.json file with corresponding dictionary'''
dialog = InputDialog("text","path to file")
2023-05-25 00:39:32 +02:00
if dialog.exec():
data = dialog.getInputs()
2023-05-25 02:05:35 +02:00
text = ifFileGetContent(data[0])
if len(data[1])>0 and len(text)>0:
2023-05-25 00:39:32 +02:00
try:
with open(data[1]+'.raw','w') as fd_bin, open(data[1]+'.json','w') as fd_dic:
2023-05-25 02:05:35 +02:00
encoding, _, dict = huffman_encode(text)
json.dump(dict,fd_dic)
2023-05-25 00:39:32 +02:00
fd_bin.write(encoding)
except FileNotFoundError:
2023-05-25 02:05:35 +02:00
create_msg_box("Invalid path, does this directory exist?","Input error")
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
def showDialogDecodeToFile(self):
'''Dialog to decode a binary (paths accepted for both dictionary and binary) and create a file with decoded text'''
dialog = InputDialog("text","Dict {lettre:code} JSON-formatted", text3 = "path to file", thirdBox = True)
2023-05-25 00:39:32 +02:00
if dialog.exec():
data = dialog.getInputs()
2023-05-25 02:05:35 +02:00
binary = ifFileGetContent(data[0])
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
if len(binary)>0 and len(data[1])>0:
2023-05-25 00:39:32 +02:00
try:
2023-05-25 02:05:35 +02:00
dict = json.loads(ifFileGetContent(data[1]))
2023-05-25 00:39:32 +02:00
except ValueError:
2023-05-25 02:05:35 +02:00
create_msg_box("Can't read dictionary, is it JSON-formatted?","Invalid dictionary")
2023-05-25 00:39:32 +02:00
return 0
try:
2023-05-25 02:05:35 +02:00
text = decode_from_dict(binary, dict)
2023-05-25 00:39:32 +02:00
except ValueError:
2023-05-25 02:05:35 +02:00
create_msg_box("Can't decode text, is it the right dictionary?","decoding error")
2023-05-25 00:39:32 +02:00
return 0
except TypeError:
2023-05-25 02:05:35 +02:00
create_msg_box("Can't use text in input, is it a binary?","Input error")
2023-05-25 00:39:32 +02:00
return 0
try:
with open(data[2],'w') as fd:
2023-05-25 02:05:35 +02:00
fd.write(text)
2023-05-25 00:39:32 +02:00
except FileNotFoundError:
2023-05-25 02:05:35 +02:00
create_msg_box("Invalid path, does this directory exist?","Input error")
2023-05-25 00:39:32 +02:00
2023-05-25 02:05:35 +02:00
##### end button functions
2023-05-25 00:39:32 +02:00
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("Huffman.py", u"Huffman.py", None))
def closeEvent(self):
2023-05-25 02:05:35 +02:00
# delete graph files before exiting
2023-05-25 00:39:32 +02:00
try:
os.unlink('./tree.gv')
os.unlink('./tree.svg')
except:
2023-05-25 02:05:35 +02:00
# if user didn't generate a tree
2023-05-25 00:39:32 +02:00
pass
print('exit')
sys.exit(0)