Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0af6aa05a0 | ||
|
|
1aaaefd08f |
@@ -1,377 +1,380 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import tkinter as tk
|
import tkinter as tk
|
||||||
from tkinter import filedialog, messagebox, scrolledtext
|
from tkinter import filedialog, messagebox, scrolledtext
|
||||||
import tkinter.font as tkfont
|
import tkinter.font as tkfont
|
||||||
import shutil
|
import shutil
|
||||||
import ctypes
|
import ctypes
|
||||||
import string
|
import string
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
|
|
||||||
# ============================================================
|
# ============================================================
|
||||||
# CONFIG:
|
# CONFIG:
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read(r"C:\ProgramData\Program-Search\config.ini")
|
config.read(r"C:\ProgramData\Program-Search\config.ini")
|
||||||
SEARCH_ROOT = config["Paths"]["SEARCH_ROOT"]
|
SEARCH_WINDOW_SIZE = config["General"]["SEARCH_WINDOW_SIZE"]
|
||||||
TRASH_DIR = config["Paths"]["TRASH_DIR"]
|
RESULTS_WINDOW_SIZE = config["General"]["RESULTS_WINDOW_SIZE"]
|
||||||
TRASH_ENABLED = config.getboolean("Features", "TRASH_ENABLED")
|
PREVIEW_WINDOW_SIZE = config["General"]["PREVIEW_WINDOW_SIZE"]
|
||||||
EDITOR_ENABLED = config.getboolean("Features", "EDITOR_ENABLED")
|
SEARCH_ROOT = config["Paths"]["SEARCH_ROOT"]
|
||||||
MANUEAL_REPLACE_ENABLED = config.getboolean("Features", "MANUEAL_REPLACE_ENABLED")
|
TRASH_DIR = config["Paths"]["TRASH_DIR"]
|
||||||
CLOSE_ALL_ENABLED = config.getboolean("Features", "CLOSE_ALL_ENABLED")
|
TRASH_ENABLED = config.getboolean("Features", "TRASH_ENABLED")
|
||||||
AUTO_CLOSE_SECONDS = config.getint("Features", "AUTO_CLOSE_SECONDS")
|
EDITOR_ENABLED = config.getboolean("Features", "EDITOR_ENABLED")
|
||||||
Extension = config["Copy"]["Extension"]
|
MANUEAL_REPLACE_ENABLED = config.getboolean("Features", "MANUEAL_REPLACE_ENABLED")
|
||||||
# ============================================================
|
CLOSE_ALL_ENABLED = config.getboolean("Features", "CLOSE_ALL_ENABLED")
|
||||||
|
AUTO_CLOSE_SECONDS = config.getint("Features", "AUTO_CLOSE_SECONDS")
|
||||||
|
Extension = config["Copy"]["Extension"]
|
||||||
os.makedirs(TRASH_DIR, exist_ok=True)
|
# ============================================================
|
||||||
|
|
||||||
|
|
||||||
def custom_messagebox(title, message, kind="info"):
|
os.makedirs(TRASH_DIR, exist_ok=True)
|
||||||
win = tk.Toplevel()
|
|
||||||
win.title(title)
|
|
||||||
win.geometry("600x300")
|
def custom_messagebox(title, message, kind="info"):
|
||||||
win.grab_set()
|
win = tk.Toplevel()
|
||||||
win.focus_force()
|
win.title(title)
|
||||||
frame = tk.Frame(win, padx=20, pady=20)
|
win.geometry(SEARCH_WINDOW_SIZE)
|
||||||
frame.pack(expand=True, fill="both")
|
win.grab_set()
|
||||||
center_window(win)
|
win.focus_force()
|
||||||
|
frame = tk.Frame(win, padx=20, pady=20)
|
||||||
tk.Label(frame, text=message, font=("Consolas", 24), wraplength=550).pack(pady=20)
|
frame.pack(expand=True, fill="both")
|
||||||
def close():
|
center_window(win)
|
||||||
win.destroy()
|
|
||||||
|
tk.Label(frame, text=message, font=("Consolas", 24), wraplength=550).pack(pady=20)
|
||||||
if kind == "yesno":
|
def close():
|
||||||
result = {"value": False}
|
win.destroy()
|
||||||
IsInfo = False
|
|
||||||
def yes():
|
if kind == "yesno":
|
||||||
result["value"] = True
|
result = {"value": False}
|
||||||
win.destroy()
|
IsInfo = False
|
||||||
|
def yes():
|
||||||
def no():
|
result["value"] = True
|
||||||
result["value"] = False
|
win.destroy()
|
||||||
win.destroy()
|
|
||||||
|
def no():
|
||||||
tk.Button(frame, text="Yes", font=("Consolas", 24), padx=10, pady=10, command=yes).pack(side="left", padx=16)
|
result["value"] = False
|
||||||
tk.Button(frame, text="No", font=("Consolas", 24), padx=10, pady=10, command=no).pack(side="right", padx=16)
|
win.destroy()
|
||||||
|
|
||||||
win.wait_window()
|
tk.Button(frame, text="Yes", font=("Consolas", 24), padx=10, pady=10, command=yes).pack(side="left", padx=16)
|
||||||
return result["value"]
|
tk.Button(frame, text="No", font=("Consolas", 24), padx=10, pady=10, command=no).pack(side="right", padx=16)
|
||||||
|
|
||||||
else:
|
win.wait_window()
|
||||||
tk.Button(frame, text="OK", font=("Consolas", 24), padx=10, pady=10, command=close).pack(pady=20)
|
return result["value"]
|
||||||
win.bind("<Return>", lambda event: close())
|
|
||||||
win.wait_window()
|
else:
|
||||||
|
tk.Button(frame, text="OK", font=("Consolas", 24), padx=10, pady=10, command=close).pack(pady=20)
|
||||||
|
win.bind("<Return>", lambda event: close())
|
||||||
def center_window(win):
|
win.wait_window()
|
||||||
win.update_idletasks()
|
|
||||||
w = win.winfo_width()
|
|
||||||
h = win.winfo_height()
|
def center_window(win):
|
||||||
sw = win.winfo_screenwidth()
|
win.update_idletasks()
|
||||||
sh = win.winfo_screenheight()
|
w = win.winfo_width()
|
||||||
x = (sw // 2) - (w // 2)
|
h = win.winfo_height()
|
||||||
y = (sh // 2) - (h // 2)
|
sw = win.winfo_screenwidth()
|
||||||
win.geometry(f"{w}x{h}+{x}+{y}")
|
sh = win.winfo_screenheight()
|
||||||
|
x = (sw // 2) - (w // 2)
|
||||||
|
y = (sh // 2) - (h // 2)
|
||||||
def find_external_drives():
|
win.geometry(f"{w}x{h}+{x}+{y}")
|
||||||
drives = []
|
|
||||||
DRIVE_REMOVABLE = 2
|
|
||||||
|
def find_external_drives():
|
||||||
for letter in string.ascii_uppercase:
|
drives = []
|
||||||
drive = f"{letter}:\\"
|
DRIVE_REMOVABLE = 2
|
||||||
if os.path.exists(drive):
|
|
||||||
dtype = ctypes.windll.kernel32.GetDriveTypeW(drive)
|
for letter in string.ascii_uppercase:
|
||||||
if dtype == DRIVE_REMOVABLE:
|
drive = f"{letter}:\\"
|
||||||
drives.append(drive)
|
if os.path.exists(drive):
|
||||||
|
dtype = ctypes.windll.kernel32.GetDriveTypeW(drive)
|
||||||
return drives
|
if dtype == DRIVE_REMOVABLE:
|
||||||
|
drives.append(drive)
|
||||||
|
|
||||||
def close_all(root):
|
return drives
|
||||||
for w in root.winfo_children():
|
|
||||||
try:
|
|
||||||
w.destroy()
|
def close_all(root):
|
||||||
except:
|
for w in root.winfo_children():
|
||||||
pass
|
try:
|
||||||
root.destroy()
|
w.destroy()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
def popup_search_input():
|
root.destroy()
|
||||||
win = tk.Toplevel()
|
|
||||||
win.title("Search")
|
|
||||||
win.geometry("600x300")
|
def popup_search_input():
|
||||||
center_window(win)
|
win = tk.Toplevel()
|
||||||
|
win.title("Search")
|
||||||
tk.Label(win, text="Enter program number, part number, or name:").pack(pady=10)
|
win.geometry(SEARCH_WINDOW_SIZE)
|
||||||
entry = tk.Entry(win)
|
center_window(win)
|
||||||
entry.pack(pady=5)
|
|
||||||
entry.focus_set()
|
tk.Label(win, text="Enter program number, part number, or name:").pack(pady=10)
|
||||||
entry.bind("<Return>", lambda event: submit())
|
entry = tk.Entry(win)
|
||||||
win.bind("<Return>", lambda event: submit())
|
entry.pack(pady=5)
|
||||||
|
entry.focus_set()
|
||||||
result = {"value": None}
|
entry.bind("<Return>", lambda event: submit())
|
||||||
|
win.bind("<Return>", lambda event: submit())
|
||||||
def submit():
|
|
||||||
result["value"] = entry.get().strip().lower()
|
result = {"value": None}
|
||||||
win.destroy()
|
|
||||||
|
def submit():
|
||||||
tk.Button(win, text="Search", command=submit, padx=20, pady=20).pack(pady=60)
|
result["value"] = entry.get().strip().lower()
|
||||||
|
win.destroy()
|
||||||
win.wait_window(); return result["value"]
|
|
||||||
|
tk.Button(win, text="Search", command=submit, padx=20, pady=20).pack(pady=60)
|
||||||
|
|
||||||
def search_files(term):
|
win.wait_window(); return result["value"]
|
||||||
matches = []
|
|
||||||
|
|
||||||
for root, dirs, files in os.walk(SEARCH_ROOT):
|
def search_files(term):
|
||||||
for fname in files:
|
matches = []
|
||||||
path = os.path.join(root, fname)
|
|
||||||
fname_lower = fname.lower()
|
for root, dirs, files in os.walk(SEARCH_ROOT):
|
||||||
|
for fname in files:
|
||||||
filename_match = term in fname_lower
|
path = os.path.join(root, fname)
|
||||||
contents_match = False
|
fname_lower = fname.lower()
|
||||||
|
|
||||||
try:
|
filename_match = term in fname_lower
|
||||||
with open(path, "r", errors="ignore") as f:
|
contents_match = False
|
||||||
if term in f.read().lower():
|
|
||||||
contents_match = True
|
try:
|
||||||
except:
|
with open(path, "r", errors="ignore") as f:
|
||||||
pass
|
if term in f.read().lower():
|
||||||
|
contents_match = True
|
||||||
if filename_match or contents_match:
|
except:
|
||||||
matches.append(path)
|
pass
|
||||||
|
|
||||||
return matches
|
if filename_match or contents_match:
|
||||||
|
matches.append(path)
|
||||||
|
|
||||||
def popup_results_list(matches):
|
return matches
|
||||||
win = tk.Toplevel()
|
|
||||||
win.title("Matches Found")
|
|
||||||
win.geometry("1200x1000")
|
def popup_results_list(matches):
|
||||||
center_window(win)
|
win = tk.Toplevel()
|
||||||
|
win.title("Matches Found")
|
||||||
tk.Label(win, text="Select files to preview:").pack(pady=10)
|
win.geometry(RESULTS_WINDOW_SIZE)
|
||||||
|
center_window(win)
|
||||||
lb = tk.Listbox(win, selectmode=tk.MULTIPLE)
|
|
||||||
lb.pack(expand=True, fill="both")
|
tk.Label(win, text="Select files to preview:").pack(pady=10)
|
||||||
|
|
||||||
for m in matches:
|
lb = tk.Listbox(win, selectmode=tk.MULTIPLE)
|
||||||
lb.insert(tk.END, m)
|
lb.pack(expand=True, fill="both")
|
||||||
|
|
||||||
result = {"selected": []}
|
for m in matches:
|
||||||
|
lb.insert(tk.END, m)
|
||||||
def select_all():
|
|
||||||
lb.select_set(0, tk.END)
|
result = {"selected": []}
|
||||||
def submit():
|
|
||||||
sel = lb.curselection()
|
def select_all():
|
||||||
result["selected"] = [matches[i] for i in sel]
|
lb.select_set(0, tk.END)
|
||||||
win.destroy()
|
def submit():
|
||||||
|
sel = lb.curselection()
|
||||||
tk.Button(win, text="Open Selected", command=submit, padx=20, pady=10).pack(side ="right", padx=20, pady=10)
|
result["selected"] = [matches[i] for i in sel]
|
||||||
tk.Button(win, text="Select All", command=select_all, padx=20, pady=10).pack(side ="left", padx=20, pady=10)
|
win.destroy()
|
||||||
|
|
||||||
lb.bind("<Return>", lambda event: submit())
|
tk.Button(win, text="Open Selected", command=submit, padx=20, pady=10).pack(side ="right", padx=20, pady=10)
|
||||||
win.bind("<Return>", lambda event: submit())
|
tk.Button(win, text="Select All", command=select_all, padx=20, pady=10).pack(side ="left", padx=20, pady=10)
|
||||||
|
|
||||||
win.wait_window(); return result["selected"]
|
lb.bind("<Return>", lambda event: submit())
|
||||||
|
win.bind("<Return>", lambda event: submit())
|
||||||
|
|
||||||
def popup_file_preview(path, on_close_callback):
|
win.wait_window(); return result["selected"]
|
||||||
win = tk.Toplevel()
|
|
||||||
win.title(path)
|
|
||||||
win.geometry("900x1000")
|
def popup_file_preview(path, on_close_callback):
|
||||||
|
win = tk.Toplevel()
|
||||||
box = scrolledtext.ScrolledText(win, wrap=tk.WORD)
|
win.title(path)
|
||||||
box.pack(expand=True, fill="both")
|
win.geometry(PREVIEW_WINDOW_SIZE)
|
||||||
|
|
||||||
try:
|
box = scrolledtext.ScrolledText(win, wrap=tk.WORD)
|
||||||
with open(path, "r", errors="ignore") as f:
|
box.pack(expand=True, fill="both")
|
||||||
original_text = f.read()
|
|
||||||
box.insert(tk.END, original_text)
|
try:
|
||||||
box.edit_modified(False)
|
with open(path, "r", errors="ignore") as f:
|
||||||
except Exception as e:
|
original_text = f.read()
|
||||||
original_text = ""
|
box.insert(tk.END, original_text)
|
||||||
box.insert(tk.END, f"Error reading file:\n{e}")
|
box.edit_modified(False)
|
||||||
|
except Exception as e:
|
||||||
modified = {"changed": False}
|
original_text = ""
|
||||||
|
box.insert(tk.END, f"Error reading file:\n{e}")
|
||||||
def mark_modified(event=None):
|
|
||||||
if box.edit_modified():
|
modified = {"changed": False}
|
||||||
modified["changed"] = True
|
|
||||||
box.edit_modified(False)
|
def mark_modified(event=None):
|
||||||
|
if box.edit_modified():
|
||||||
if EDITOR_ENABLED:
|
modified["changed"] = True
|
||||||
box.bind("<<Modified>>", mark_modified)
|
box.edit_modified(False)
|
||||||
else:
|
|
||||||
box.configure(state="disabled")
|
if EDITOR_ENABLED:
|
||||||
|
box.bind("<<Modified>>", mark_modified)
|
||||||
frame = tk.Frame(win)
|
else:
|
||||||
frame.pack(fill="x", pady=10)
|
box.configure(state="disabled")
|
||||||
|
|
||||||
|
frame = tk.Frame(win)
|
||||||
def save_file():
|
frame.pack(fill="x", pady=10)
|
||||||
try:
|
|
||||||
with open(path, "w", errors="ignore") as f:
|
|
||||||
f.write(box.get("1.0", tk.END))
|
def save_file():
|
||||||
modified["changed"] = False
|
try:
|
||||||
custom_messagebox("Saved", f"File saved:\n{path}")
|
with open(path, "w", errors="ignore") as f:
|
||||||
except Exception as e:
|
f.write(box.get("1.0", tk.END))
|
||||||
custom_messagebox("Save Error", str(e))
|
modified["changed"] = False
|
||||||
|
custom_messagebox("Saved", f"File saved:\n{path}")
|
||||||
def copy_to_external():
|
except Exception as e:
|
||||||
if EDITOR_ENABLED and modified["changed"]:
|
custom_messagebox("Save Error", str(e))
|
||||||
ask = custom_messagebox("Unsaved Changes", "You have unsaved changes.\nSave before copying?", kind = "yesno")
|
|
||||||
if ask:
|
def copy_to_external():
|
||||||
save_file()
|
if EDITOR_ENABLED and modified["changed"]:
|
||||||
|
ask = custom_messagebox("Unsaved Changes", "You have unsaved changes.\nSave before copying?", kind = "yesno")
|
||||||
drives = find_external_drives()
|
if ask:
|
||||||
if not drives:
|
save_file()
|
||||||
custom_messagebox("No External Drive Found", "No external drive detected."); return
|
|
||||||
|
drives = find_external_drives()
|
||||||
base_name = os.path.splitext(os.path.basename(path))[0]
|
if not drives:
|
||||||
new_name = base_name + Extension
|
custom_messagebox("No External Drive Found", "No external drive detected."); return
|
||||||
|
|
||||||
copied = []
|
base_name = os.path.splitext(os.path.basename(path))[0]
|
||||||
for d in drives:
|
new_name = base_name + Extension
|
||||||
try:
|
|
||||||
dest = os.path.join(d, new_name)
|
copied = []
|
||||||
shutil.copy2(path, dest)
|
for d in drives:
|
||||||
copied.append(dest)
|
try:
|
||||||
except Exception as e:
|
dest = os.path.join(d, new_name)
|
||||||
custom_messagebox("Copy Error", f"Could not copy to {d}:\n{e}")
|
shutil.copy2(path, dest)
|
||||||
|
copied.append(dest)
|
||||||
if copied:
|
except Exception as e:
|
||||||
custom_messagebox("Copied Successfully", "Copied to:\n\n" + "\n".join(copied))
|
custom_messagebox("Copy Error", f"Could not copy to {d}:\n{e}")
|
||||||
win.destroy()
|
|
||||||
on_close_callback()
|
if copied:
|
||||||
close_all(win.master)
|
custom_messagebox("Copied Successfully", "Copied to:\n\n" + "\n".join(copied))
|
||||||
|
win.destroy()
|
||||||
def move_to_trash():
|
on_close_callback()
|
||||||
confirm = custom_messagebox("Move to Trash",f"Are you sure you want to move this file to trash?\n\n{path}", kind = "yesno")
|
close_all(win.master)
|
||||||
if confirm:
|
|
||||||
try:
|
def move_to_trash():
|
||||||
rel_path = os.path.relpath(path, SEARCH_ROOT)
|
confirm = custom_messagebox("Move to Trash",f"Are you sure you want to move this file to trash?\n\n{path}", kind = "yesno")
|
||||||
dest_path = os.path.join(TRASH_DIR, rel_path)
|
if confirm:
|
||||||
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
|
try:
|
||||||
shutil.move(path, dest_path)
|
rel_path = os.path.relpath(path, SEARCH_ROOT)
|
||||||
custom_messagebox("Trashed", f"Moved to trash:\n{dest_path}")
|
dest_path = os.path.join(TRASH_DIR, rel_path)
|
||||||
win.destroy()
|
os.makedirs(os.path.dirname(dest_path), exist_ok=True)
|
||||||
on_close_callback()
|
shutil.move(path, dest_path)
|
||||||
|
custom_messagebox("Trashed", f"Moved to trash:\n{dest_path}")
|
||||||
except Exception as e:
|
win.destroy()
|
||||||
custom_messagebox("Trash Error", str(e))
|
on_close_callback()
|
||||||
|
|
||||||
def manual_replace():
|
except Exception as e:
|
||||||
drives = find_external_drives()
|
custom_messagebox("Trash Error", str(e))
|
||||||
if not drives: custom_messagebox("No External Drive Found","No external drive detected."); return
|
|
||||||
base_name = os.path.splitext(os.path.basename(path))[0]
|
def manual_replace():
|
||||||
new_name = base_name + Extension
|
drives = find_external_drives()
|
||||||
replacement_path = None
|
if not drives: custom_messagebox("No External Drive Found","No external drive detected."); return
|
||||||
for d in drives:
|
base_name = os.path.splitext(os.path.basename(path))[0]
|
||||||
candidate = os.path.join(d, new_name)
|
new_name = base_name + Extension
|
||||||
if os.path.exists(candidate): replacement_path = candidate;
|
replacement_path = None
|
||||||
break
|
for d in drives:
|
||||||
if not replacement_path: custom_messagebox("File Not Found",f"No replacement file named:\n\n{new_name}\n\nwas found on any external drive."); return
|
candidate = os.path.join(d, new_name)
|
||||||
try:
|
if os.path.exists(candidate): replacement_path = candidate;
|
||||||
with open(replacement_path,"r",errors="ignore") as f: new_contents = f.read()
|
break
|
||||||
except Exception as e: custom_messagebox("Read Error",f"Could not read replacement file:\n{e}"); return
|
if not replacement_path: custom_messagebox("File Not Found",f"No replacement file named:\n\n{new_name}\n\nwas found on any external drive."); return
|
||||||
try:
|
try:
|
||||||
with open(path,"w",errors="ignore") as f: f.write(new_contents)
|
with open(replacement_path,"r",errors="ignore") as f: new_contents = f.read()
|
||||||
except Exception as e: custom_messagebox("Write Error",f"Could not overwrite original file:\n{e}"); return
|
except Exception as e: custom_messagebox("Read Error",f"Could not read replacement file:\n{e}"); return
|
||||||
box.delete("1.0",tk.END); box.insert(tk.END,new_contents); box.edit_modified(False); modified["changed"] = False
|
try:
|
||||||
custom_messagebox("Replaced Successfully",f"File replaced using:\n{replacement_path}")
|
with open(path,"w",errors="ignore") as f: f.write(new_contents)
|
||||||
|
except Exception as e: custom_messagebox("Write Error",f"Could not overwrite original file:\n{e}"); return
|
||||||
def close():
|
box.delete("1.0",tk.END); box.insert(tk.END,new_contents); box.edit_modified(False); modified["changed"] = False
|
||||||
if EDITOR_ENABLED and modified["changed"]:
|
custom_messagebox("Replaced Successfully",f"File replaced using:\n{replacement_path}")
|
||||||
ask = custom_messagebox("Unsaved Changes", "You have unsaved changes.\nSave before closing?", kind = "yesno")
|
|
||||||
if ask:
|
def close():
|
||||||
save_file()
|
if EDITOR_ENABLED and modified["changed"]:
|
||||||
|
ask = custom_messagebox("Unsaved Changes", "You have unsaved changes.\nSave before closing?", kind = "yesno")
|
||||||
win.destroy()
|
if ask:
|
||||||
on_close_callback()
|
save_file()
|
||||||
|
|
||||||
def auto_close():
|
win.destroy()
|
||||||
if win.winfo_exists():
|
on_close_callback()
|
||||||
win.destroy()
|
|
||||||
on_close_callback()
|
def auto_close():
|
||||||
|
if win.winfo_exists():
|
||||||
def close_all_button():
|
win.destroy()
|
||||||
ask = custom_messagebox("WARNING!", "Are you sure you want to cloose all windows?", kind = "yesno")
|
on_close_callback()
|
||||||
if ask:
|
|
||||||
close_all(win.master)
|
def close_all_button():
|
||||||
|
ask = custom_messagebox("WARNING!", "Are you sure you want to cloose all windows?", kind = "yesno")
|
||||||
win.protocol("WM_DELETE_WINDOW", close)
|
if ask:
|
||||||
win.after(AUTO_CLOSE_SECONDS * 1000, auto_close)
|
close_all(win.master)
|
||||||
|
|
||||||
if EDITOR_ENABLED:
|
win.protocol("WM_DELETE_WINDOW", close)
|
||||||
tk.Button(win, text="Save", fg="green", command=save_file, padx=15, pady=8).pack(side ="left",padx=10, pady=10)
|
win.after(AUTO_CLOSE_SECONDS * 1000, auto_close)
|
||||||
|
|
||||||
if TRASH_ENABLED == True:
|
if EDITOR_ENABLED:
|
||||||
tk.Button(win, text="Move to Trash", fg="red", command=move_to_trash, padx=15, pady=8).pack(side ="left",padx=10, pady=10)
|
tk.Button(win, text="Save", fg="green", command=save_file, padx=15, pady=8).pack(side ="left",padx=10, pady=10)
|
||||||
|
|
||||||
tk.Button(win, text="Copy to External Drive", command=copy_to_external, padx=15, pady=8).pack(side ="left",padx=10, pady=10)
|
if TRASH_ENABLED == True:
|
||||||
|
tk.Button(win, text="Move to Trash", fg="red", command=move_to_trash, padx=15, pady=8).pack(side ="left",padx=10, pady=10)
|
||||||
tk.Button(win, text="Close", command=close, padx=15, pady=8).pack(side ="right",padx=10, pady=10)
|
|
||||||
|
tk.Button(win, text="Copy to External Drive", command=copy_to_external, padx=15, pady=8).pack(side ="left",padx=10, pady=10)
|
||||||
if CLOSE_ALL_ENABLED:
|
|
||||||
tk.Button(win, text="Close All", command=lambda: close_all_button(), padx=15, pady=8).pack(side ="right",padx=10, pady=10)
|
tk.Button(win, text="Close", command=close, padx=15, pady=8).pack(side ="right",padx=10, pady=10)
|
||||||
|
|
||||||
if MANUEAL_REPLACE_ENABLED == True:
|
if CLOSE_ALL_ENABLED:
|
||||||
tk.Button(win, text="Replace from External Drive", command=manual_replace, padx=15, pady=8).pack(side ="right",padx=10, pady=10)
|
tk.Button(win, text="Close All", command=lambda: close_all_button(), padx=15, pady=8).pack(side ="right",padx=10, pady=10)
|
||||||
|
|
||||||
|
if MANUEAL_REPLACE_ENABLED == True:
|
||||||
|
tk.Button(win, text="Replace from External Drive", command=manual_replace, padx=15, pady=8).pack(side ="right",padx=10, pady=10)
|
||||||
def main():
|
|
||||||
root = tk.Tk()
|
|
||||||
root.withdraw()
|
|
||||||
default_font = tkfont.nametofont("TkDefaultFont")
|
def main():
|
||||||
default_font.configure(family="Consolas", size=18)
|
root = tk.Tk()
|
||||||
|
root.withdraw()
|
||||||
text_font = tkfont.nametofont("TkTextFont")
|
default_font = tkfont.nametofont("TkDefaultFont")
|
||||||
text_font.configure(family="Consolas", size=18)
|
default_font.configure(family="Consolas", size=18)
|
||||||
|
|
||||||
fixed_font = tkfont.nametofont("TkFixedFont")
|
text_font = tkfont.nametofont("TkTextFont")
|
||||||
fixed_font.configure(family="Consolas", size=18)
|
text_font.configure(family="Consolas", size=18)
|
||||||
|
|
||||||
root.option_add("*Dialog.msg.font", "Consolas 18")
|
fixed_font = tkfont.nametofont("TkFixedFont")
|
||||||
root.option_add("*Dialog.msg.width", 60)
|
fixed_font.configure(family="Consolas", size=18)
|
||||||
root.option_add("*Dialog.msg.height", 10)
|
|
||||||
root.option_add("*Dialog.msg.wrapLength", 600)
|
root.option_add("*Dialog.msg.font", "Consolas 18")
|
||||||
|
root.option_add("*Dialog.msg.width", 60)
|
||||||
while True:
|
root.option_add("*Dialog.msg.height", 10)
|
||||||
search_term = popup_search_input()
|
root.option_add("*Dialog.msg.wrapLength", 600)
|
||||||
if not search_term:
|
|
||||||
root.destroy()
|
while True:
|
||||||
return
|
search_term = popup_search_input()
|
||||||
|
if not search_term:
|
||||||
matches = search_files(search_term)
|
root.destroy()
|
||||||
|
return
|
||||||
if matches:
|
|
||||||
break
|
matches = search_files(search_term)
|
||||||
|
|
||||||
custom_messagebox("No Results", "No matching files found.")
|
if matches:
|
||||||
|
break
|
||||||
selected = popup_results_list(matches)
|
|
||||||
if not selected:
|
custom_messagebox("No Results", "No matching files found.")
|
||||||
root.destroy()
|
|
||||||
return
|
selected = popup_results_list(matches)
|
||||||
|
if not selected:
|
||||||
|
root.destroy()
|
||||||
open_windows = {"count": len(selected)}
|
return
|
||||||
|
|
||||||
def window_closed():
|
|
||||||
open_windows["count"] -= 1
|
open_windows = {"count": len(selected)}
|
||||||
if open_windows["count"] == 0:
|
|
||||||
root.destroy()
|
def window_closed():
|
||||||
|
open_windows["count"] -= 1
|
||||||
|
if open_windows["count"] == 0:
|
||||||
for path in selected:
|
root.destroy()
|
||||||
popup_file_preview(path, window_closed)
|
|
||||||
|
|
||||||
root.mainloop()
|
for path in selected:
|
||||||
|
popup_file_preview(path, window_closed)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
root.mainloop()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
+17
-12
@@ -1,13 +1,18 @@
|
|||||||
[Paths]
|
[General]
|
||||||
SEARCH_ROOT = C:\CNCPrograms\Programs
|
SEARCH_WINDOW_SIZE = 600x300
|
||||||
TRASH_DIR = C:\CNCPrograms\Trash
|
RESULTS_WINDOW_SIZE = 1200x1000
|
||||||
|
PREVIEW_WINDOW_SIZE = 900x1000
|
||||||
[Features]
|
|
||||||
TRASH_ENABLED = False
|
[Paths]
|
||||||
EDITOR_ENABLED = False
|
SEARCH_ROOT = C:\CNCPrograms\Programs
|
||||||
MANUEAL_REPLACE_ENABLED = False
|
TRASH_DIR = C:\CNCPrograms\Trash
|
||||||
CLOSE_ALL_ENABLED = True
|
|
||||||
AUTO_CLOSE_SECONDS = 300
|
[Features]
|
||||||
|
TRASH_ENABLED = False
|
||||||
[Copy]
|
EDITOR_ENABLED = False
|
||||||
|
MANUEAL_REPLACE_ENABLED = False
|
||||||
|
CLOSE_ALL_ENABLED = True
|
||||||
|
AUTO_CLOSE_SECONDS = 300
|
||||||
|
|
||||||
|
[Copy]
|
||||||
Extension =
|
Extension =
|
||||||
Reference in New Issue
Block a user