Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
199 changes: 85 additions & 114 deletions FadCrypt.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

# Import shared core modules
from core.config_manager import ConfigManager
from core.application_manager import ApplicationManager


# Embedded configuration and state data
Expand Down Expand Up @@ -89,6 +90,9 @@ def __init__(self, master):
app_locker=None, # Will be set after app_locker is created
get_fadcrypt_folder_func=lambda: self.app_locker.get_fadcrypt_folder()
)

# Initialize shared ApplicationManager
self.app_manager = None # Will be initialized in create_widgets after tabs are created

self.set_app_icon() # Set the custom app icon
self.create_widgets()
Expand Down Expand Up @@ -124,15 +128,16 @@ def open_add_application_dialog(self):
# Center the dialog on the screen
screen_width = self.add_dialog.winfo_screenwidth()
screen_height = self.add_dialog.winfo_screenheight()
dialog_width = 400 # Adjust width as needed
dialog_height = 500 # Adjust height as needed
dialog_width = 420 # Increased width slightly
dialog_height = 580 # Increased height to accommodate all content
# position_x = (screen_width // 2) - (dialog_width // 2)
position_x = 50 # Position the dialog on the left edge of the screen
position_y = (screen_height // 2) - (dialog_height // 2)
self.add_dialog.geometry(f"{dialog_width}x{dialog_height}+{position_x}+{position_y}")

# Prevent resizing
self.add_dialog.resizable(False, False)
# Allow resizing so user can expand if needed
self.add_dialog.resizable(True, True)
self.add_dialog.minsize(400, 550) # Set minimum size

# Ensure the dialog is focused
self.add_dialog.attributes('-topmost', True)
Expand Down Expand Up @@ -181,12 +186,38 @@ def update_text_position():
browse_button = ttk.Button(manual_frame, text="Browse", command=self.browse_for_file, style="navy.TButton")
browse_button.pack(pady=5)

# Buttons frame
buttons_frame = ttk.Frame(self.add_dialog)
buttons_frame.pack(pady=10)

# Scan Apps Button (new feature!)
scan_button = ttk.Button(
buttons_frame,
text="🔍 Scan for Apps",
command=self.scan_for_apps,
width=15,
style="navy.TButton"
)
scan_button.pack(side=tk.LEFT, padx=5)

# Save Button
save_button = ttk.Button(self.add_dialog, text="Save", command=self.save_application, width=11, style="green.TButton")
save_button.pack(pady=10)
save_button = ttk.Button(
buttons_frame,
text="💾 Save",
command=self.save_application,
width=11,
style="green.TButton"
)
save_button.pack(side=tk.LEFT, padx=5)

# Bind the Enter key to the Save button
self.add_dialog.bind('<Return>', lambda event: save_button.invoke())

def scan_for_apps(self):
"""Open app scanner dialog"""
if hasattr(self, 'add_dialog'):
self.add_dialog.destroy() # Close add dialog
self.app_manager.show_app_scanner_dialog()


def on_drop(self, event):
Expand Down Expand Up @@ -354,69 +385,7 @@ def create_widgets(self):



# Applications Tab
self.apps_frame = ttk.Frame(self.notebook)
self.notebook.add(self.apps_frame, text="Applications")

# Create a frame to hold the listbox and scrollbar
list_frame = ttk.Frame(self.apps_frame)
list_frame.pack(pady=5, padx=5, fill=tk.BOTH, expand=True)

# Create the listbox with a scrollbar
self.apps_listbox = tk.Listbox(list_frame, width=50, font=("Helvetica", 10), selectmode=tk.SINGLE)
self.apps_listbox.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.apps_listbox.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

self.apps_listbox.config(yscrollcommand=scrollbar.set)



self.update_apps_listbox()

# Buttons frame
button_frame = ttk.Frame(self.apps_frame)
button_frame.pack(pady=10, padx=5, fill=tk.X)

# Modify the Add button to open the new dialog
ttk.Button(button_frame, text="Add", command=self.open_add_application_dialog, style="green.TButton").pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="Remove", command=self.remove_application, style="red.TButton").pack(side=tk.LEFT, padx=5)
ttk.Button(button_frame, text="Rename", command=self.rename_application).pack(side=tk.LEFT, padx=5)


# State Tab
# self.state_frame = ttk.Frame(self.notebook)
# self.notebook.add(self.state_frame, text="State")

# self.state_text = tk.Text(self.state_frame, width=60, height=10)
# self.state_text.pack(pady=5)
# self.update_state_display()
























# Config Tab
# Config Tab (moved before Applications tab to match Linux version)
# Config Tab with scrollable content
self.config_frame = ttk.Frame(self.notebook)
self.notebook.add(self.config_frame, text="Config")
Expand Down Expand Up @@ -448,6 +417,24 @@ def create_widgets(self):
self.config_text.pack(pady=5, padx=15, fill=tk.X, expand=False)
self.update_config_display()


# Applications Tab - Using shared ApplicationManager
self.app_manager = ApplicationManager(
app_locker=self.app_locker,
master=self.master,
notebook=self.notebook,
resource_path_func=self.resource_path,
show_message_func=self.show_message,
update_config_display_func=self.update_config_display,
is_linux=False
)

# Set callback for Add button
self.app_manager.add_application_callback = self.open_add_application_dialog

# Keep references to ApplicationManager's components
self.apps_frame = self.app_manager.apps_frame

# Description below the config text box
config_description = ttk.Label(scrollable_config_frame, text=(
"This is the list of applications currently locked by FadCrypt.\n"
Expand Down Expand Up @@ -1124,15 +1111,9 @@ def update_config_textbox(self):


def update_apps_listbox(self):
self.apps_listbox.delete(0, tk.END)
for index, app in enumerate(self.app_locker.config["applications"]):
item = f" {app['name']} - {app['path']}" # Added two spaces for left padding
self.apps_listbox.insert(tk.END, item)
# Apply alternating row colors
if index % 2 == 0:
self.apps_listbox.itemconfig(index, {'bg': '#f0f0f0'})
else:
self.apps_listbox.itemconfig(index, {'bg': '#ffffff'})
"""Delegate to ApplicationManager"""
if self.app_manager:
self.app_manager.update_apps_listbox()
self.update_config_display()

def update_config_display(self):
Expand Down Expand Up @@ -1164,11 +1145,6 @@ def export_state(self):



def update_apps_listbox(self):
self.apps_listbox.delete(0, tk.END)
for app in self.app_locker.config["applications"]:
self.apps_listbox.insert(tk.END, f"{app['name']} - {app['path']}")

def create_password(self):
if os.path.exists(self.app_locker.password_file):
self.show_message("Info", "Password already exists. Use 'Change Password' to modify.")
Expand All @@ -1192,42 +1168,20 @@ def change_password(self):
self.show_message("Oops!", "How do I change a password that doesn't exist? :(")

def add_application(self):
app_name = self.ask_password("Add Application", "Enter the name of the application:")
if app_name:
app_path = filedialog.askopenfilename(title="Select application executable")
if app_path:
self.app_locker.add_application(app_name, app_path)
self.update_apps_listbox()
self.update_config_display() # Update config tab
self.show_message("Success", f"Application {app_name}\nadded successfully.")
"""Keep old dialog - ApplicationManager doesn't have Windows .exe dialog"""
# The open_add_application_dialog method handles this
pass


def remove_application(self):
selection = self.apps_listbox.curselection()
if selection:
app_name = self.apps_listbox.get(selection[0]).split(" - ")[0].strip() # Remove leading spaces
self.app_locker.remove_application(app_name)
self.update_apps_listbox()
self.update_config_display()
self.show_message("Success", f"Application {app_name}\nremoved successfully.")
else:
self.show_message("Error", "Please select an application to remove.")
"""Delegate to ApplicationManager"""
if self.app_manager:
self.app_manager.remove_applications()

def rename_application(self):
selection = self.apps_listbox.curselection()
if selection:
old_name = self.apps_listbox.get(selection[0]).split(" - ")[0].strip() # Remove leading spaces
new_name = self.ask_password("Rename Application", f"Enter new name for {old_name}:")
if new_name:
for app in self.app_locker.config["applications"]:
if app["name"] == old_name:
app["name"] = new_name
break
self.update_apps_listbox()
self.update_config_display()
self.show_message("Success", f"Application renamed from {old_name} to {new_name}.")
else:
self.show_message("Error", "Please select an application to rename.")
"""Delegate to ApplicationManager's edit function"""
if self.app_manager:
self.app_manager.edit_application()

def start_monitoring(self, auto_start=False):
if os.path.exists(self.app_locker.password_file):
Expand Down Expand Up @@ -1493,8 +1447,17 @@ def ask_password(self, title, prompt):
def custom_dialog(self, title, prompt, fullscreen=False, input_required=True):
dialog = tk.Toplevel(self.master)
dialog.attributes('-alpha', 0.0) # Start fully transparent
dialog.attributes('-topmost', True) # Always on top
dialog.update_idletasks() # Update geometry-related information

# Set the FadCrypt icon for the dialog
try:
ico_path = self.resource_path('img/1.ico')
if os.path.exists(ico_path):
dialog.iconbitmap(ico_path)
except Exception as e:
print(f"Could not set dialog icon: {e}")

if fullscreen:
dialog.attributes('-fullscreen', True)
else:
Expand Down Expand Up @@ -1608,6 +1571,14 @@ def full_screen_password_dialog(self, title, prompt):
dialog.attributes('-fullscreen', True)
dialog.grab_set()

# Set the FadCrypt icon for the dialog
try:
ico_path = self.resource_path('img/1.ico')
if os.path.exists(ico_path):
dialog.iconbitmap(ico_path)
except Exception as e:
print(f"Could not set dialog icon: {e}")

# Load and display wallpaper
wallpaper_path = self.get_wallpaper_path()
wallpaper = Image.open(wallpaper_path)
Expand Down
Loading