Skip to content

Commit 1a2dae5

Browse files
committed
made the installer. and finnished the first phase
1 parent 4da1a03 commit 1a2dae5

File tree

3 files changed

+97
-26
lines changed

3 files changed

+97
-26
lines changed

setup.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from cx_Freeze import setup, Executable
2+
3+
build_exe_options = {
4+
"packages": [],
5+
"include_files": ["xdelta3.exe"], # <- include it
6+
}
7+
8+
setup(
9+
name="XdeltaUIPython",
10+
version="1.0",
11+
description="Xdelta Patch GUI",
12+
options={"build_exe": build_exe_options},
13+
executables=[Executable("xdeltapatcherpython.py")],
14+
icons=["icon.ico"],
15+
)

xdelta3.exe

603 KB
Binary file not shown.

xdeltapatcherpython.py

Lines changed: 82 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,36 @@
11
import customtkinter
22
from tkinter import filedialog
33
from CTkMenuBar import *
4-
import github
5-
from github import *
6-
4+
import os
5+
import subprocess
6+
import logging
7+
8+
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
9+
10+
def run_executable(source, patch, output):
11+
try:
12+
result = subprocess.run(
13+
["xdelta3.exe", "-d", "-s", source, patch, output],
14+
capture_output=True,
15+
text=True
16+
)
17+
logging.info(result.stdout)
18+
logging.error(result.stderr)
19+
return result.returncode == 0
20+
except Exception as e:
21+
logging.error(f"Error running xdelta3: {e}")
22+
return False
723

824

925
class ToplevelWindow(customtkinter.CTkToplevel):
1026
def __init__(self, *args, **kwargs):
1127
super().__init__(*args, **kwargs)
1228
self.geometry("255x250")
13-
self.label = customtkinter.CTkLabel(self, text="About Xdelta Py UI")
14-
self.label.pack(padx=20, pady=20)
15-
self.label2 = customtkinter.CTkLabel(self, text="This is a simple UI for Xdelta patching.")
16-
self.label2.pack(padx=20, pady=20)
17-
self.label3 = customtkinter.CTkLabel(self, text="version 1.0", font=("Arial", 10, "italic"))
18-
self.label3.pack(padx=20, pady=20)
29+
self.title("About")
30+
customtkinter.CTkLabel(self, text="About Xdelta Py UI").pack(padx=20, pady=10)
31+
customtkinter.CTkLabel(self, text="This is a simple UI for Xdelta patching.").pack(padx=20, pady=10)
32+
customtkinter.CTkLabel(self, text="Version 1.0", font=("Arial", 10, "italic")).pack(padx=20, pady=10)
33+
1934

2035
class App(customtkinter.CTk):
2136
def __init__(self, *args, **kwargs):
@@ -25,38 +40,79 @@ def __init__(self, *args, **kwargs):
2540
self.title("Xdelta Py UI")
2641
self._set_appearance_mode("System")
2742

28-
43+
self.sourcefile = None
44+
self.patchfile = None
45+
2946
menu = CTkTitleMenu(master=self)
30-
button_1 = menu.add_cascade("File")
31-
button_2 = menu.add_cascade("About")
47+
file_button = menu.add_cascade("File")
48+
about_button = menu.add_cascade("About")
3249

33-
34-
50+
file_menu = CustomDropdownMenu(widget=file_button)
51+
file_menu.add_option("Open Source File", command=self.open_source_file)
52+
file_menu.add_option("Open Patch File", command=self.open_patch_file)
53+
file_menu.add_separator()
54+
file_menu.add_option("Exit", command=self.quit)
3555

56+
about_menu = CustomDropdownMenu(widget=about_button)
57+
about_menu.add_option("Open About Window", command=self.open_toplevel)
3658

37-
dropdown1 = CustomDropdownMenu(widget=button_1)
38-
dropdown1.add_option(option="Open Source File", command=lambda: filedialog.askopenfilename(filetypes=[("GM Data Files", "*data.win")]))
39-
dropdown1.add_option(option="Open Patch File", command=lambda: filedialog.askopenfilename(filetypes=[("Xdelta Patch Files", "*.xdelta")]))
40-
dropdown1.add_separator()
59+
self.toplevel_window = None
4160

42-
dropdown1.add_option(option="Exit", command=self.quit)
61+
self.file_entry = customtkinter.CTkEntry(self, placeholder_text="No source file selected")
62+
self.file_entry.pack(pady=10, padx=20, fill="x")
63+
self.file_entry.configure(state="disabled")
4364

65+
self.source_button = customtkinter.CTkButton(self, text="Change Source File", command=self.open_source_file)
66+
self.source_button.pack(pady=10, padx=20, fill="x")
4467

45-
dropdown2 = CustomDropdownMenu(widget=button_2)
46-
dropdown2.add_option("Open About Window", command=self.open_toplevel)
68+
self.patch_entry = customtkinter.CTkEntry(self, placeholder_text="No patch file selected")
69+
self.patch_entry.pack(pady=10, padx=20, fill="x")
70+
self.patch_entry.configure(state="disabled")
4771

48-
self.toplevel_window = None
72+
self.patch_button = customtkinter.CTkButton(self, text="Change Patch File", command=self.open_patch_file)
73+
self.patch_button.pack(pady=10, padx=20, fill="x")
74+
75+
self.output_entry = customtkinter.CTkEntry(self, placeholder_text="Output file name (e.g., patched.win)")
76+
self.output_entry.pack(pady=10, padx=20, fill="x")
77+
78+
self.run_button = customtkinter.CTkButton(self, text="Apply Patch", command=self.run_patch)
79+
self.run_button.pack(pady=20, padx=20, fill="x")
80+
81+
def open_source_file(self):
82+
self.sourcefile = filedialog.askopenfilename(filetypes=[("GM Data Files", "*data.win")])
83+
if self.sourcefile:
84+
self.file_entry.configure(state="normal")
85+
self.file_entry.delete(0, 'end')
86+
self.file_entry.insert(0, self.sourcefile)
87+
self.file_entry.configure(state="disabled")
88+
89+
def open_patch_file(self):
90+
self.patchfile = filedialog.askopenfilename(filetypes=[("Xdelta Patch Files", "*.xdelta")])
91+
if self.patchfile:
92+
self.patch_entry.configure(state="normal")
93+
self.patch_entry.delete(0, 'end')
94+
self.patch_entry.insert(0, self.patchfile)
95+
self.patch_entry.configure(state="disabled")
4996

5097
def open_toplevel(self):
5198
if self.toplevel_window is None or not self.toplevel_window.winfo_exists():
5299
self.toplevel_window = ToplevelWindow(self)
53100
else:
54101
self.toplevel_window.focus()
55102

103+
def run_patch(self):
104+
output_path = self.output_entry.get()
105+
if not self.sourcefile or not self.patchfile or not output_path:
106+
logging.error("Missing source, patch, or output path.")
107+
return
56108

109+
success = run_executable(self.sourcefile, self.patchfile, output_path)
110+
if success:
111+
logging.info("Patch applied successfully.")
112+
else:
113+
logging.error("Failed to apply patch.")
57114

58115

59-
60-
61-
app = App()
62-
app.mainloop()
116+
if __name__ == "__main__":
117+
app = App()
118+
app.mainloop()

0 commit comments

Comments
 (0)