diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..88537a9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +## Ignoring PyCharm settings +/.idea + +## Ignoring Python complied files +/__pycache__ +/main/__pycache__ +/main/form.py + +## Ignoring build from cx_Freeze +/prog_build + +## Ignoring build files from PyInstaller +/build +/dist diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..fb967b8 --- /dev/null +++ b/__init__.py @@ -0,0 +1,12 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +from sys import argv, exit +from PyQt5.QtWidgets import QApplication +from main.script import MainWindow + +if __name__ == '__main__': + app = QApplication(argv) + win = MainWindow() + win.show() + exit(app.exec()) diff --git a/compile_cx-freeze.bat b/compile_cx-freeze.bat new file mode 100644 index 0000000..3d7f60b --- /dev/null +++ b/compile_cx-freeze.bat @@ -0,0 +1 @@ +python setup.py build diff --git a/convert_ui_to_py.bat b/convert_ui_to_py.bat new file mode 100644 index 0000000..a6d28b5 --- /dev/null +++ b/convert_ui_to_py.bat @@ -0,0 +1,13 @@ +cls +@echo off +title Form converter + +:SETUP +echo Enter form name to convert into .py (without .ui): +echo Type 'exit' to exit +set/p "name=> " +if %name%==exit goto EXIT +pyuic5 %name%.ui -o %name%.py +goto SETUP + +:EXIT \ No newline at end of file diff --git a/dlls/imageformats/qgif.dll b/dlls/imageformats/qgif.dll new file mode 100644 index 0000000..c507af0 Binary files /dev/null and b/dlls/imageformats/qgif.dll differ diff --git a/dlls/imageformats/qicns.dll b/dlls/imageformats/qicns.dll new file mode 100644 index 0000000..3d427d7 Binary files /dev/null and b/dlls/imageformats/qicns.dll differ diff --git a/dlls/imageformats/qico.dll b/dlls/imageformats/qico.dll new file mode 100644 index 0000000..820d268 Binary files /dev/null and b/dlls/imageformats/qico.dll differ diff --git a/dlls/imageformats/qjpeg.dll b/dlls/imageformats/qjpeg.dll new file mode 100644 index 0000000..59ca503 Binary files /dev/null and b/dlls/imageformats/qjpeg.dll differ diff --git a/dlls/imageformats/qsvg.dll b/dlls/imageformats/qsvg.dll new file mode 100644 index 0000000..c302700 Binary files /dev/null and b/dlls/imageformats/qsvg.dll differ diff --git a/dlls/imageformats/qtga.dll b/dlls/imageformats/qtga.dll new file mode 100644 index 0000000..a31f068 Binary files /dev/null and b/dlls/imageformats/qtga.dll differ diff --git a/dlls/imageformats/qtiff.dll b/dlls/imageformats/qtiff.dll new file mode 100644 index 0000000..4ed799d Binary files /dev/null and b/dlls/imageformats/qtiff.dll differ diff --git a/dlls/imageformats/qwbmp.dll b/dlls/imageformats/qwbmp.dll new file mode 100644 index 0000000..1cff95f Binary files /dev/null and b/dlls/imageformats/qwbmp.dll differ diff --git a/dlls/imageformats/qwebp.dll b/dlls/imageformats/qwebp.dll new file mode 100644 index 0000000..68bd1c1 Binary files /dev/null and b/dlls/imageformats/qwebp.dll differ diff --git a/dlls/platforms/qminimal.dll b/dlls/platforms/qminimal.dll new file mode 100644 index 0000000..79e5afa Binary files /dev/null and b/dlls/platforms/qminimal.dll differ diff --git a/dlls/platforms/qoffscreen.dll b/dlls/platforms/qoffscreen.dll new file mode 100644 index 0000000..1c42fc0 Binary files /dev/null and b/dlls/platforms/qoffscreen.dll differ diff --git a/dlls/platforms/qwebgl.dll b/dlls/platforms/qwebgl.dll new file mode 100644 index 0000000..404e92f Binary files /dev/null and b/dlls/platforms/qwebgl.dll differ diff --git a/dlls/platforms/qwindows.dll b/dlls/platforms/qwindows.dll new file mode 100644 index 0000000..baccb9b Binary files /dev/null and b/dlls/platforms/qwindows.dll differ diff --git a/dlls/styles/qwindowsvistastyle.dll b/dlls/styles/qwindowsvistastyle.dll new file mode 100644 index 0000000..809fa5b Binary files /dev/null and b/dlls/styles/qwindowsvistastyle.dll differ diff --git a/main/__init__.py b/main/__init__.py new file mode 100644 index 0000000..a2e8df5 --- /dev/null +++ b/main/__init__.py @@ -0,0 +1 @@ +# initializing module 'main' diff --git a/main/form.ui b/main/form.ui new file mode 100644 index 0000000..d3a8759 --- /dev/null +++ b/main/form.ui @@ -0,0 +1,128 @@ + + + JDM170 + MainWindow + + + + 0 + 0 + 504 + 374 + + + + + Times New Roman + 12 + + + + SaveWizard config editor + + + QMainWindow::AllowTabbedDocks + + + + + + 0 + 0 + 501 + 351 + + + + + 0 + 0 + + + + QFrame::NoFrame + + + QFrame::Plain + + + + + + + 0 + 0 + 504 + 21 + + + + true + + + false + + + + Options + + + + + + + + + + + + + + + Open + + + Ctrl+O + + + + + Save + + + Ctrl+S + + + + + Save As + + + Ctrl+Shift+S + + + + + Close file + + + Closing current file + + + Ctrl+W + + + + + Exit + + + + + Generate and copy MD5 + + + + + + diff --git a/main/script.py b/main/script.py new file mode 100644 index 0000000..d9182e6 --- /dev/null +++ b/main/script.py @@ -0,0 +1,134 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +from PyQt5.QtCore import Qt +from PyQt5.QtGui import QResizeEvent, QCloseEvent, QClipboard +from PyQt5.QtWidgets import QMainWindow, QFileDialog, QMessageBox, QApplication +from ast import literal_eval +from json import dump, load, decoder +from hashlib import md5 +from .form import Ui_MainWindow + + +class MainWindow(QMainWindow, Ui_MainWindow): + def __init__(self, parent=None): + QMainWindow.__init__(self, parent, flags=Qt.Window) + Ui_MainWindow.__init__(self) + self.ui = Ui_MainWindow() + self.ui.setupUi(self) + + self.file_path = "" + self.win_title = self.tr("{}".format(self.windowTitle())) + + self.ui.textEdit.document().contentsChanged.connect(self.content_changed) + + for action, method in { + self.ui.actionOpen: self.open_file, + self.ui.actionSave: self.save_file, + self.ui.actionSave_As: self.save_as, + self.ui.actionMD5: self.copy_hash, + self.ui.actionCloseFile: self.close_file, + self.ui.actionExit: self.exit + }.items(): + action.triggered.connect(method) + + def resizeEvent(self, event: QResizeEvent): + window = self.ui.centralwidget.geometry().getCoords() + edit = self.ui.textEdit.geometry().getCoords() + self.ui.textEdit.setGeometry(edit[0], edit[1], window[2], window[3]-25) + + def closeEvent(self, event: QCloseEvent): + if self.maybe_save(): + event.accept() + else: + event.ignore() + + @staticmethod + def save_handler(path, data): + with open(path, encoding="utf-8", mode="w") as f: + dump(data, f, indent=4, sort_keys=True, separators=(",", " : ")) + try: + with open(path, encoding="utf-8") as f: + load(f) + except decoder.JSONDecodeError: + return False + return True + + @staticmethod + def generate_md5(fn): + hash_md5 = md5() + try: + with open(fn, "rb") as f: + for chunk in iter(lambda: f.read(4096), b""): + hash_md5.update(chunk) + return hash_md5.hexdigest() + except FileNotFoundError: + return False + + def content_changed(self): + self.setWindowModified(self.ui.textEdit.document().isModified()) + + def open_file(self): + file_path, file_name = QFileDialog.getOpenFileName(parent=self, + caption=self.tr("Choose config..."), + filter=self.tr("*.json")) + if file_path != "": + self.file_path = file_path + with open(file_path) as f: + self.ui.textEdit.setPlainText(f.read()) + self.setWindowTitle(self.tr("[*]{} - {}".format(file_path, self.win_title))) + self.ui.textEdit.document().setModified(False) + self.setWindowModified(False) + + def save_file(self): + if self.file_path != "": + data = literal_eval(self.ui.textEdit.toPlainText()) + ret = self.save_handler(self.file_path, data) + if ret: + self.ui.textEdit.document().setModified(False) + self.setWindowModified(False) + return ret + + def save_as(self): + file_path, file_name = QFileDialog.getSaveFileName(parent=self, + caption=self.tr("Select position"), + filter=self.tr("*.json")) + file_data = literal_eval(self.ui.textEdit.toPlainText()) + ret = self.save_handler(file_path, file_data) + if ret: + self.file_path = file_path + self.setWindowTitle(self.tr("[*]{} - {}".format(file_path, self.win_title))) + self.ui.textEdit.document().setModified(False) + self.setWindowModified(False) + + def copy_hash(self): + if self.maybe_save(): + result = self.generate_md5(self.file_path) + clip = QApplication.clipboard() + QClipboard.setText(clip, result) + box = QMessageBox(QMessageBox.Information, "Information", "Hash successfully copied into your clipboard.") + box.exec() + + def close_file(self): + if self.maybe_save(): + self.setWindowTitle(self.win_title) + self.ui.textEdit.clear() + self.file_path = "" + + def exit(self): + self.close() + + def maybe_save(self): + if not self.ui.textEdit.document().isModified(): + return True + box = QMessageBox.warning(self, + self.tr("App"), + self.tr("The document has been modified.\nDo you want to save your changes?"), + QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) + if box == QMessageBox.Save: + return self.save_file() + elif box == QMessageBox.Discard: + return True + elif box == QMessageBox.Cancel: + return False + return True diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..266b786 --- /dev/null +++ b/setup.py @@ -0,0 +1,42 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- + +from sys import platform +from cx_Freeze import setup, Executable + +base = None +if platform == 'win32': + base = 'Win32GUI' + +executables = [Executable('__init__.py', targetName='config_editor.exe', base=base)] + +excludes = ['html', 'pydoc_data', 'unittest', 'xml', 'pwd', 'shlex', 'platform', 'webbrowser', 'pydoc', 'tty', + 'inspect', 'doctest', 'plistlib', 'subprocess', 'bz2', '_strptime', 'dummy_threading', 'selectors', + 'select', 'http', 'email', 'datetime', 'calendar', 'urllib', 'posixpath', 'tempfile', 'shutil', 'copy', + 'stringprep', 'socket'] + +includes = ['pkgutil', 'PyQt5.sip'] + +zip_include_packages = ['collections', 'encodings', 'importlib', 'json', 'hashlib', 'ast', 'PyQt5', 'main'] + +include_files = ['dlls/imageformats', 'dlls/platforms', 'dlls/styles'] + +options = { + 'build_exe': { + 'excludes': excludes, + 'includes': includes, + 'include_msvcr': True, + 'build_exe': 'prog_build', + 'include_files': include_files, + 'zip_include_packages': zip_include_packages, + } +} + +setup( + name='SaveWizard Config Editor', + version='1.0', + description='For editing configs from SaveWizard', + executables=executables, + options=options, + requires=['PyQt5'], +)