Carregar ficheiros para "/"
This commit is contained in:
532
edc15_info_window.py
Normal file
532
edc15_info_window.py
Normal file
@ -0,0 +1,532 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox
|
||||
import psycopg2
|
||||
from datetime import datetime
|
||||
import logging
|
||||
import re
|
||||
import os
|
||||
|
||||
class EDC15InfoWindow(tk.Toplevel):
|
||||
def __init__(self, parent, filename, binary_data=None):
|
||||
logging.info("Initializing EDC15InfoWindow")
|
||||
try:
|
||||
super().__init__(parent)
|
||||
self.title("EDC15 File Information")
|
||||
self.filename = filename
|
||||
self.binary_data = binary_data
|
||||
|
||||
# Flag to track if project is created
|
||||
self.project_created = False
|
||||
|
||||
# Flag to track if window was closed by user
|
||||
self.window_closed = False
|
||||
|
||||
# Add protocol for window close
|
||||
self.protocol("WM_DELETE_WINDOW", self.on_closing)
|
||||
|
||||
# Load ECU types and car brands from files
|
||||
self.ecu_types = self.load_ecu_types()
|
||||
self.car_brands = self.load_car_brands()
|
||||
|
||||
# Load readout methods
|
||||
self.readout_methods = self.load_readout_methods()
|
||||
|
||||
# Hardware number prefixes
|
||||
self.hw_prefixes = ['0281', '0265', '0255', '0275', '0235', '0285']
|
||||
|
||||
# Software number prefix
|
||||
self.sw_prefix = '103'
|
||||
|
||||
# Lists to store all found numbers
|
||||
self.all_hw_numbers = []
|
||||
self.all_sw_numbers = []
|
||||
|
||||
# Configure window
|
||||
self.geometry("800x600")
|
||||
logging.info("EDC15InfoWindow geometry configured")
|
||||
|
||||
# Create main frame
|
||||
main_frame = ttk.Frame(self, padding="10")
|
||||
main_frame.pack(fill="both", expand=True)
|
||||
logging.info("EDC15InfoWindow main frame created")
|
||||
|
||||
# Customer Section
|
||||
customer_frame = ttk.LabelFrame(main_frame, text="Customer", padding="5")
|
||||
customer_frame.pack(fill="x", padx=5, pady=5)
|
||||
|
||||
ttk.Label(customer_frame, text="Name:").grid(row=0, column=0, sticky=tk.W)
|
||||
self.name_var = tk.StringVar()
|
||||
self.name_entry = ttk.Combobox(customer_frame, textvariable=self.name_var)
|
||||
self.name_entry.grid(row=0, column=1, sticky=(tk.W, tk.E))
|
||||
|
||||
ttk.Label(customer_frame, text="Phone:").grid(row=1, column=0, sticky=tk.W)
|
||||
self.phone_var = tk.StringVar()
|
||||
ttk.Entry(customer_frame, textvariable=self.phone_var).grid(row=1, column=1, sticky=(tk.W, tk.E))
|
||||
|
||||
ttk.Label(customer_frame, text="License Plate:").grid(row=2, column=0, sticky=tk.W)
|
||||
self.license_var = tk.StringVar()
|
||||
ttk.Entry(customer_frame, textvariable=self.license_var).grid(row=2, column=1, sticky=(tk.W, tk.E))
|
||||
|
||||
# Car Section with Comments
|
||||
car_frame = ttk.LabelFrame(main_frame, text="Car", padding="5")
|
||||
car_frame.pack(fill="x", padx=5, pady=5)
|
||||
|
||||
# Left side - Car details
|
||||
car_left_frame = ttk.Frame(car_frame)
|
||||
car_left_frame.pack(side="left", fill="x", expand=True, padx=5)
|
||||
|
||||
# Brand
|
||||
ttk.Label(car_left_frame, text="Brand:").grid(row=0, column=0, sticky="w", padx=5, pady=2)
|
||||
self.brand_var = tk.StringVar()
|
||||
self.brand_combo = ttk.Combobox(car_left_frame, textvariable=self.brand_var, values=self.car_brands)
|
||||
self.brand_combo.grid(row=0, column=1, sticky="ew", padx=5, pady=2)
|
||||
self.brand_combo.bind('<<ComboboxSelected>>', self.on_brand_selected)
|
||||
|
||||
# Model
|
||||
ttk.Label(car_left_frame, text="Model:").grid(row=1, column=0, sticky="w", padx=5, pady=2)
|
||||
self.model_var = tk.StringVar()
|
||||
self.model_combo = ttk.Combobox(car_left_frame, textvariable=self.model_var)
|
||||
self.model_combo.grid(row=1, column=1, sticky="ew", padx=5, pady=2)
|
||||
|
||||
# Engine
|
||||
ttk.Label(car_left_frame, text="Engine:").grid(row=2, column=0, sticky="w", padx=5, pady=2)
|
||||
self.engine_var = tk.StringVar()
|
||||
ttk.Entry(car_left_frame, textvariable=self.engine_var).grid(row=2, column=1, sticky="ew", padx=5, pady=2)
|
||||
|
||||
# HP
|
||||
ttk.Label(car_left_frame, text="HP:").grid(row=3, column=0, sticky="w", padx=5, pady=2)
|
||||
self.hp_var = tk.StringVar()
|
||||
ttk.Entry(car_left_frame, textvariable=self.hp_var).grid(row=3, column=1, sticky="ew", padx=5, pady=2)
|
||||
|
||||
# KW
|
||||
ttk.Label(car_left_frame, text="KW:").grid(row=4, column=0, sticky="w", padx=5, pady=2)
|
||||
self.kw_var = tk.StringVar()
|
||||
ttk.Entry(car_left_frame, textvariable=self.kw_var).grid(row=4, column=1, sticky="ew", padx=5, pady=2)
|
||||
|
||||
# Year
|
||||
year_label = tk.Label(car_left_frame, text="Year:")
|
||||
year_label.grid(row=5, column=0, sticky='w', padx=5, pady=2)
|
||||
self.year_var = tk.StringVar()
|
||||
self.year_combo = ttk.Combobox(car_left_frame, textvariable=self.year_var, state="readonly", width=20)
|
||||
self.year_combo['values'] = list(map(str, range(1993, 2009))) # Years from 1993 to 2008
|
||||
self.year_combo.grid(row=5, column=1, sticky='w', padx=5, pady=2)
|
||||
self.year_combo.set('') # Default empty selection
|
||||
|
||||
# VIN
|
||||
ttk.Label(car_left_frame, text="VIN:").grid(row=6, column=0, sticky="w", padx=5, pady=2)
|
||||
self.vin_var = tk.StringVar()
|
||||
ttk.Entry(car_left_frame, textvariable=self.vin_var).grid(row=6, column=1, sticky="ew", padx=5, pady=2)
|
||||
|
||||
# Transmission
|
||||
transmission_label = tk.Label(car_left_frame, text="Transmission:")
|
||||
transmission_label.grid(row=7, column=0, sticky='w', padx=5, pady=2)
|
||||
self.transmission_var = tk.StringVar()
|
||||
self.transmission_combo = ttk.Combobox(car_left_frame, textvariable=self.transmission_var, state="readonly", width=20)
|
||||
self.transmission_combo['values'] = ['Manual', 'Automatic']
|
||||
self.transmission_combo.grid(row=7, column=1, sticky='w', padx=5, pady=2)
|
||||
self.transmission_combo.set('') # Default empty selection
|
||||
|
||||
# Right side - Comments
|
||||
car_right_frame = ttk.LabelFrame(car_frame, text="Comments", padding="5")
|
||||
car_right_frame.pack(side="right", fill="both", expand=True, padx=5)
|
||||
|
||||
self.comment_text = tk.Text(car_right_frame, height=10, width=30, wrap=tk.WORD)
|
||||
comment_scrollbar = ttk.Scrollbar(car_right_frame, orient="vertical", command=self.comment_text.yview)
|
||||
self.comment_text.configure(yscrollcommand=comment_scrollbar.set)
|
||||
|
||||
self.comment_text.pack(side="left", fill="both", expand=True)
|
||||
comment_scrollbar.pack(side="right", fill="y")
|
||||
|
||||
# ECU and Project Section
|
||||
ecu_project_frame = ttk.LabelFrame(main_frame, text="ECU and Project", padding="5")
|
||||
ecu_project_frame.pack(fill="x", padx=5, pady=5)
|
||||
|
||||
# Create a frame to hold ECU and Project side by side
|
||||
ecu_project_inner_frame = ttk.Frame(ecu_project_frame)
|
||||
ecu_project_inner_frame.pack(fill="x", expand=True)
|
||||
|
||||
# Left side - ECU details
|
||||
ecu_left_frame = ttk.Frame(ecu_project_inner_frame)
|
||||
ecu_left_frame.pack(side="left", fill="x", expand=True, padx=5)
|
||||
|
||||
ttk.Label(ecu_left_frame, text="ECU Type:").grid(row=0, column=0, sticky="w", padx=5, pady=2)
|
||||
self.ecu_type_var = tk.StringVar()
|
||||
self.ecu_type_combo = ttk.Combobox(ecu_left_frame, textvariable=self.ecu_type_var, values=self.ecu_types)
|
||||
self.ecu_type_combo.grid(row=0, column=1, sticky="ew", padx=5, pady=2)
|
||||
|
||||
ttk.Label(ecu_left_frame, text="Hardware:").grid(row=1, column=0, sticky="w", padx=5, pady=2)
|
||||
self.hardware_var = tk.StringVar()
|
||||
ttk.Entry(ecu_left_frame, textvariable=self.hardware_var).grid(row=1, column=1, sticky="ew", padx=5, pady=2)
|
||||
|
||||
ttk.Label(ecu_left_frame, text="Software:").grid(row=2, column=0, sticky="w", padx=5, pady=2)
|
||||
self.software_var = tk.StringVar()
|
||||
ttk.Entry(ecu_left_frame, textvariable=self.software_var).grid(row=2, column=1, sticky="ew", padx=5, pady=2)
|
||||
|
||||
# Right side - Project details
|
||||
project_right_frame = ttk.Frame(ecu_project_inner_frame)
|
||||
project_right_frame.pack(side="right", fill="x", expand=True, padx=5)
|
||||
|
||||
ttk.Label(project_right_frame, text="Type:").grid(row=0, column=0, sticky="w", padx=5, pady=2)
|
||||
self.project_type_var = tk.StringVar()
|
||||
self.project_type_combo = ttk.Combobox(project_right_frame, textvariable=self.project_type_var)
|
||||
self.project_type_combo['values'] = [
|
||||
'BOOST CALIBRATION',
|
||||
'COLD START',
|
||||
'DPF REMOVAL',
|
||||
'DTC REMOVAL',
|
||||
'EGR REMOVAL',
|
||||
'EXHAUST FLAP',
|
||||
'FLAPS REMOVAL',
|
||||
'HOT START',
|
||||
'IMMO REMOVAL',
|
||||
'LAMBDA',
|
||||
'LAUNCH CONTROL',
|
||||
'MAF REMOVAL',
|
||||
'SPEED LIMITER REMOVAL',
|
||||
'TUNING',
|
||||
'TVA REMOVAL'
|
||||
]
|
||||
self.project_type_combo.grid(row=0, column=1, sticky="ew", padx=5, pady=2)
|
||||
self.project_type_combo.config(state="readonly")
|
||||
|
||||
ttk.Label(project_right_frame, text="State:").grid(row=1, column=0, sticky="w", padx=5, pady=2)
|
||||
self.state_var = tk.StringVar(value="NEW")
|
||||
self.state_combo = ttk.Combobox(project_right_frame, textvariable=self.state_var)
|
||||
self.state_combo['values'] = [
|
||||
'NEW',
|
||||
'DEVELOPING',
|
||||
'TESTING',
|
||||
'FINISH'
|
||||
]
|
||||
self.state_combo.grid(row=1, column=1, sticky="ew", padx=5, pady=2)
|
||||
self.state_combo.config(state="readonly")
|
||||
|
||||
ttk.Label(project_right_frame, text="Readout by:").grid(row=2, column=0, sticky="w", padx=5, pady=2)
|
||||
self.readout_var = tk.StringVar()
|
||||
self.readout_combo = ttk.Combobox(project_right_frame, textvariable=self.readout_var, values=self.readout_methods)
|
||||
self.readout_combo.grid(row=2, column=1, sticky="ew", padx=5, pady=2)
|
||||
self.readout_combo.config(state="readonly")
|
||||
|
||||
# Buttons at the bottom
|
||||
button_frame = ttk.Frame(main_frame)
|
||||
button_frame.pack(fill="x", padx=5, pady=10)
|
||||
|
||||
ttk.Button(button_frame, text="Create Project", command=self.create_project).pack(side=tk.LEFT, padx=5)
|
||||
ttk.Button(button_frame, text="Cancel", command=self.destroy).pack(side=tk.RIGHT, padx=5)
|
||||
|
||||
# Find hardware and software numbers if binary data is available
|
||||
if self.binary_data:
|
||||
self.find_all_numbers()
|
||||
self.update_comment_with_extra_numbers()
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error initializing EDC15InfoWindow: {str(e)}")
|
||||
|
||||
def load_ecu_types(self):
|
||||
"""Load ECU types from list_EDC15.txt file"""
|
||||
try:
|
||||
with open('list_EDC15.txt', 'r') as file:
|
||||
return [line.strip() for line in file if line.strip()]
|
||||
except Exception as e:
|
||||
logging.error(f"Error loading ECU types: {str(e)}")
|
||||
return []
|
||||
|
||||
def load_car_brands(self):
|
||||
"""Load car brands from car_brands.txt"""
|
||||
try:
|
||||
brands_file = os.path.join(os.path.dirname(__file__), 'car_brands.txt')
|
||||
if os.path.exists(brands_file):
|
||||
with open(brands_file, 'r') as f:
|
||||
brands = [line.strip() for line in f if line.strip()]
|
||||
logging.info(f"Loaded {len(brands)} car brands")
|
||||
return sorted(brands)
|
||||
else:
|
||||
logging.warning("car_brands.txt not found")
|
||||
return []
|
||||
except Exception as e:
|
||||
logging.error(f"Error loading car brands: {str(e)}")
|
||||
return []
|
||||
|
||||
def load_readout_methods(self):
|
||||
"""Load readout methods from readout.txt file"""
|
||||
try:
|
||||
with open(os.path.join(os.path.dirname(__file__), 'readout.txt'), 'r') as f:
|
||||
return [line.strip() for line in f if line.strip()]
|
||||
except FileNotFoundError:
|
||||
logging.warning("readout.txt file not found")
|
||||
return []
|
||||
except Exception as e:
|
||||
logging.error(f"Error reading readout.txt: {str(e)}")
|
||||
return []
|
||||
|
||||
def find_all_numbers(self):
|
||||
"""Find all hardware and software numbers in binary data"""
|
||||
try:
|
||||
if not self.binary_data:
|
||||
return
|
||||
|
||||
# Convert binary data to ASCII string
|
||||
ascii_data = self.binary_data.decode('ascii', errors='ignore')
|
||||
|
||||
# Find hardware numbers
|
||||
hw_pattern = '(' + '|'.join(self.hw_prefixes) + ')[0-9]{5}'
|
||||
hw_matches = re.finditer(hw_pattern, ascii_data)
|
||||
|
||||
# Store all hardware numbers found
|
||||
for match in hw_matches:
|
||||
number = match.group(0)
|
||||
if len(number) == 9 and number.isdigit():
|
||||
self.all_hw_numbers.append(number)
|
||||
|
||||
# Set first hardware number found to the hardware field
|
||||
if self.all_hw_numbers:
|
||||
self.hardware_var.set(self.all_hw_numbers[0])
|
||||
logging.info(f"Found primary hardware number: {self.all_hw_numbers[0]}")
|
||||
|
||||
# Find software numbers
|
||||
sw_pattern = f'{self.sw_prefix}[0-9]{{6}}'
|
||||
sw_matches = re.finditer(sw_pattern, ascii_data)
|
||||
|
||||
# Store all software numbers found
|
||||
for match in sw_matches:
|
||||
number = match.group(0)
|
||||
if len(number) == 9 and number.isdigit():
|
||||
self.all_sw_numbers.append(number)
|
||||
|
||||
# Set first software number found to the software field
|
||||
if self.all_sw_numbers:
|
||||
self.software_var.set(self.all_sw_numbers[0])
|
||||
logging.info(f"Found primary software number: {self.all_sw_numbers[0]}")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error finding numbers: {str(e)}")
|
||||
|
||||
def update_comment_with_extra_numbers(self):
|
||||
"""Update comment field with additional numbers found, excluding the ones already shown in hardware/software fields"""
|
||||
try:
|
||||
# Get the current hardware and software numbers from the fields
|
||||
current_hw = self.hardware_var.get()
|
||||
current_sw = self.software_var.get()
|
||||
|
||||
# Filter out numbers that are already shown in the fields
|
||||
extra_hw_numbers = [num for num in self.all_hw_numbers if num != current_hw]
|
||||
extra_sw_numbers = [num for num in self.all_sw_numbers if num != current_sw]
|
||||
|
||||
if extra_hw_numbers or extra_sw_numbers:
|
||||
comment = "Additional numbers found:\n"
|
||||
|
||||
if extra_hw_numbers:
|
||||
comment += "\nHardware numbers:\n"
|
||||
comment += "\n".join(extra_hw_numbers)
|
||||
|
||||
if extra_sw_numbers:
|
||||
comment += "\nSoftware numbers:\n"
|
||||
comment += "\n".join(extra_sw_numbers)
|
||||
|
||||
self.comment_text.delete('1.0', tk.END)
|
||||
self.comment_text.insert('1.0', comment)
|
||||
logging.info("Updated comment with extra numbers")
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error updating comment with extra numbers: {str(e)}")
|
||||
|
||||
def on_brand_selected(self, event=None):
|
||||
"""Update model list when brand is selected"""
|
||||
try:
|
||||
selected_brand = self.brand_var.get()
|
||||
if selected_brand:
|
||||
# Convert brand name to filename format
|
||||
filename_brand = selected_brand
|
||||
if selected_brand == "Citroen":
|
||||
filename_brand = "Citroen"
|
||||
elif selected_brand == "Mercedes-Benz":
|
||||
filename_brand = "Mercedes"
|
||||
|
||||
# Construct path to model file
|
||||
model_file = os.path.join(os.path.dirname(__file__), 'Model_car', f'{filename_brand}.txt')
|
||||
|
||||
if os.path.exists(model_file):
|
||||
# Load models from file
|
||||
with open(model_file, 'r') as f:
|
||||
models = [line.strip() for line in f if line.strip()]
|
||||
|
||||
# Update model combobox
|
||||
self.model_combo['values'] = sorted(models)
|
||||
logging.info(f"Loaded {len(models)} models for {selected_brand}")
|
||||
else:
|
||||
self.model_combo['values'] = []
|
||||
logging.warning(f"No model file found for {selected_brand}")
|
||||
|
||||
# Clear current model selection
|
||||
self.model_var.set('')
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error loading models for {selected_brand}: {str(e)}")
|
||||
self.model_combo['values'] = []
|
||||
|
||||
def save_data(self):
|
||||
try:
|
||||
conn = psycopg2.connect(
|
||||
dbname="hexaw",
|
||||
user="postgres",
|
||||
password="postgres",
|
||||
host="localhost"
|
||||
)
|
||||
cur = conn.cursor()
|
||||
|
||||
# Create table if it doesn't exist (removed producer field)
|
||||
cur.execute("""
|
||||
CREATE TABLE IF NOT EXISTS edc15_files (
|
||||
id SERIAL PRIMARY KEY,
|
||||
filename TEXT,
|
||||
customer_name TEXT,
|
||||
customer_phone TEXT,
|
||||
license_plate TEXT,
|
||||
car_brand TEXT,
|
||||
car_model TEXT,
|
||||
car_engine TEXT,
|
||||
car_hp TEXT,
|
||||
car_kw TEXT,
|
||||
car_year TEXT,
|
||||
car_vin TEXT,
|
||||
car_transmission TEXT,
|
||||
ecu_type TEXT,
|
||||
ecu_part TEXT,
|
||||
ecu_software TEXT,
|
||||
ecu_hardware TEXT,
|
||||
project_type TEXT,
|
||||
project_state TEXT,
|
||||
readout_by TEXT,
|
||||
comment TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)
|
||||
""")
|
||||
|
||||
# Insert data (removed producer field)
|
||||
cur.execute("""
|
||||
INSERT INTO edc15_files (
|
||||
filename, customer_name, customer_phone, license_plate,
|
||||
car_brand, car_model, car_engine, car_hp, car_kw,
|
||||
car_year, car_vin, car_transmission,
|
||||
ecu_type, ecu_part, ecu_software, ecu_hardware,
|
||||
project_type, project_state, readout_by,
|
||||
comment
|
||||
) VALUES (
|
||||
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
|
||||
%s, %s, %s, %s, %s, %s, %s,
|
||||
%s
|
||||
)
|
||||
""", (
|
||||
self.filename,
|
||||
self.name_var.get(),
|
||||
self.phone_var.get(),
|
||||
self.license_var.get(),
|
||||
self.brand_var.get(),
|
||||
self.model_var.get(),
|
||||
self.engine_var.get(),
|
||||
self.hp_var.get(),
|
||||
self.kw_var.get(),
|
||||
self.year_combo.get(),
|
||||
self.vin_var.get(),
|
||||
self.transmission_combo.get(),
|
||||
self.ecu_type_var.get(),
|
||||
'',
|
||||
self.software_var.get(),
|
||||
self.hardware_var.get(),
|
||||
self.project_type_var.get(),
|
||||
self.state_var.get(),
|
||||
self.readout_var.get(),
|
||||
self.comment_text.get("1.0", tk.END).strip()
|
||||
))
|
||||
|
||||
conn.commit()
|
||||
messagebox.showinfo("Success", "Data saved successfully!")
|
||||
self.destroy()
|
||||
|
||||
except Exception as e:
|
||||
messagebox.showerror("Error", f"Failed to save data: {str(e)}")
|
||||
logging.error(f"Database error: {str(e)}")
|
||||
finally:
|
||||
if 'cur' in locals():
|
||||
cur.close()
|
||||
if 'conn' in locals():
|
||||
conn.close()
|
||||
|
||||
def create_project(self):
|
||||
try:
|
||||
# Validate required fields before creating project
|
||||
if not all([
|
||||
self.name_var.get().strip(),
|
||||
self.brand_combo.get(),
|
||||
self.model_combo.get(),
|
||||
self.project_type_combo.get(),
|
||||
self.state_combo.get(),
|
||||
self.readout_combo.get()
|
||||
]):
|
||||
messagebox.showwarning("Incomplete Information", "Please fill in all required fields.")
|
||||
return
|
||||
|
||||
# Existing project creation logic
|
||||
conn = psycopg2.connect(
|
||||
dbname="hexawork",
|
||||
user="postgres",
|
||||
password="postgres",
|
||||
host="localhost"
|
||||
)
|
||||
cur = conn.cursor()
|
||||
|
||||
cur.execute("""
|
||||
INSERT INTO edc15_files (
|
||||
filename, customer_name, customer_phone, license_plate,
|
||||
car_brand, car_model, car_engine, car_hp, car_kw,
|
||||
car_year, car_vin, car_transmission,
|
||||
ecu_type, ecu_part, ecu_software, ecu_hardware,
|
||||
project_type, project_state, readout_by,
|
||||
comment
|
||||
) VALUES (
|
||||
%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s,
|
||||
%s, %s, %s, %s, %s, %s, %s, %s
|
||||
)
|
||||
""", (
|
||||
self.filename,
|
||||
self.name_var.get(),
|
||||
self.phone_var.get(),
|
||||
self.license_var.get(),
|
||||
self.brand_combo.get(),
|
||||
self.model_combo.get(),
|
||||
self.engine_var.get(),
|
||||
self.hp_var.get(),
|
||||
self.kw_var.get(),
|
||||
self.year_combo.get(),
|
||||
self.vin_var.get(),
|
||||
self.transmission_combo.get(),
|
||||
self.ecu_type_var.get(),
|
||||
'',
|
||||
self.software_var.get(),
|
||||
self.hardware_var.get(),
|
||||
self.project_type_var.get(),
|
||||
self.state_var.get(),
|
||||
self.readout_var.get(),
|
||||
self.comment_text.get("1.0", tk.END).strip()
|
||||
))
|
||||
|
||||
conn.commit()
|
||||
|
||||
# Set project created flag
|
||||
self.project_created = True
|
||||
|
||||
messagebox.showinfo("Success", "Project created successfully!")
|
||||
self.destroy()
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Error creating project: {str(e)}")
|
||||
messagebox.showerror("Error", f"Failed to create project: {str(e)}")
|
||||
finally:
|
||||
if 'conn' in locals():
|
||||
cur.close()
|
||||
conn.close()
|
||||
|
||||
def on_closing(self):
|
||||
"""Handle window closing event"""
|
||||
self.window_closed = True
|
||||
self.destroy()
|
||||
Reference in New Issue
Block a user