-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmagicmerge.py
More file actions
151 lines (116 loc) · 4.64 KB
/
magicmerge.py
File metadata and controls
151 lines (116 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#!/usr/bin/python3
#Magic Merge by Alayna Ferdarko - Created 21 February, 2025.
import os
import fitz # PyMuPDF
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from tkinterdnd2 import DND_FILES, TkinterDnD
def browse_files():
files = filedialog.askopenfilenames(filetypes=[("PDF Files", "*.pdf")])
add_files(files)
def add_files(files):
""" Adds files to the listbox and updates size estimate """
for file in files:
if file.endswith(".pdf") and file not in pdf_files:
pdf_files.append(file)
listbox.insert(tk.END, file)
update_size_estimate()
def remove_selected():
selected_indices = listbox.curselection()
for index in reversed(selected_indices):
pdf_files.pop(index)
listbox.delete(index)
update_size_estimate()
def move_up():
selected_indices = listbox.curselection()
for index in selected_indices:
if index > 0:
pdf_files[index], pdf_files[index - 1] = pdf_files[index - 1], pdf_files[index]
refresh_listbox()
listbox.selection_set(index - 1)
break
def move_down():
selected_indices = listbox.curselection()
for index in selected_indices:
if index < len(pdf_files) - 1:
pdf_files[index], pdf_files[index + 1] = pdf_files[index + 1], pdf_files[index]
refresh_listbox()
listbox.selection_set(index + 1)
break
def refresh_listbox():
listbox.delete(0, tk.END)
for file in pdf_files:
listbox.insert(tk.END, file)
def update_size_estimate():
total_size = sum(os.path.getsize(f) for f in pdf_files)
size_label.config(text=f"Estimated Size: {total_size / (1024 * 1024):.2f} MB")
def browse_save_location():
""" Let user choose where to save the merged PDF """
file_path = filedialog.asksaveasfilename(defaultextension=".pdf",
filetypes=[("PDF Files", "*.pdf")],
title="Choose Save Location")
if file_path:
save_location_entry.delete(0, tk.END)
save_location_entry.insert(0, file_path)
def merge_pdfs():
if not pdf_files:
messagebox.showerror("Error", "No PDFs selected.")
return
output_path = save_location_entry.get().strip()
if not output_path:
messagebox.showerror("Error", "Select a save location for the merged PDF.")
return
progress_bar.start()
merger = fitz.open()
for pdf in pdf_files:
with fitz.open(pdf) as doc:
merger.insert_pdf(doc)
merger.save(output_path)
merger.close()
progress_bar.stop()
messagebox.showinfo("Success", f"Merged PDF saved as:\n{output_path}")
def clear_list():
pdf_files.clear()
listbox.delete(0, tk.END)
update_size_estimate()
def on_drag(event):
""" Handles files dropped into the window """
files = app.tk.splitlist(event.data) # Get dropped files
add_files(files)
# Initialize TkinterDnD to enable drag-and-drop
app = TkinterDnD.Tk()
app.title("Magic Merge by Alayna Ferdarko")
pdf_files = []
pdf_viewer_frame = None # Initialize as None to avoid reference issues
frame = tk.Frame(app)
frame.pack(pady=10)
listbox = tk.Listbox(frame, width=50, height=10)
listbox.pack(side=tk.LEFT, padx=5)
scrollbar = tk.Scrollbar(frame, orient=tk.VERTICAL, command=listbox.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
listbox.config(yscrollcommand=scrollbar.set)
# Enable drag-and-drop for the listbox
listbox.drop_target_register(DND_FILES)
listbox.dnd_bind("<<Drop>>", on_drag)
btn_browse = tk.Button(app, text="Browse PDFs", command=browse_files)
btn_browse.pack(pady=5)
btn_remove = tk.Button(app, text="Remove Selected", command=remove_selected)
btn_remove.pack(pady=5)
btn_up = tk.Button(app, text="Move Up", command=move_up)
btn_up.pack(pady=5)
btn_down = tk.Button(app, text="Move Down", command=move_down)
btn_down.pack(pady=5)
size_label = tk.Label(app, text="Estimated Size: 0 MB")
size_label.pack()
# Save Location Entry & Browse Button
save_location_entry = tk.Entry(app, width=50)
save_location_entry.pack(pady=5)
btn_save_location = tk.Button(app, text="Browse Save Location", command=browse_save_location)
btn_save_location.pack(pady=5)
progress_bar = ttk.Progressbar(app, mode="indeterminate")
progress_bar.pack(pady=5)
btn_merge = tk.Button(app, text="Merge PDFs", command=merge_pdfs)
btn_merge.pack(pady=5)
btn_clear = tk.Button(app, text="Clear List", command=clear_list)
btn_clear.pack(pady=5)
app.mainloop()