questo codice da diversi errori:
1) in modifica modulo, tentando di modificare il primo modulo nella maschera di modifica compaiono solo il campo del nome del modulo e quello del modulo ereditato, invece tantando di modificare il secondo modulo la maschera di modifica compare completa;
2) cliccando su genera modulo non genera niente, stessa cosa su salva configurazione.


import os
import json
import pandas as pd
import tkinter as tk
from tkinter import ttk, filedialog, messagebox

class ModuleGenerator:
    def __init__(self, module_name, module_path, models, options, actions, security_rules, manifest_data):
        self.module_name = module_name
        self.module_path = module_path
        self.models = models
        self.options = options
        self.actions = actions
        self.security_rules = security_rules
        self.manifest_data = manifest_data

    def validate_inputs(self):
        if not self.module_name or not isinstance(self.module_name, str):
            raise ValueError("Nome del modulo non valido")
        if not self.models or not isinstance(self.models, list):
            raise ValueError("I modelli devono essere una lista")

        for model in self.models:
            if not isinstance(model, dict):
                raise ValueError("Ogni modello deve essere un dizionario")
            if not model.get("name") or not isinstance(model.get("name"), str):
                raise ValueError(f"Ogni modello deve avere un nome valido")
            if not model.get("fields") or not isinstance(model.get("fields"), list) or not all(isinstance(f, tuple) and len(f) >= 7 for f in model.get("fields")):
                raise ValueError(f"I campi per il modello {model['name']} devono essere una lista di tuple con (nome, tipo, etichetta, obbligatorio, chiave primaria, [opzionale] modello_correlato, [opzionale] campo_relazione)")

        if not self.options or not isinstance(self.options, dict):
            raise ValueError("Le opzioni devono essere un dizionario")

    def get_dependencies(self):
        dependencies = set(self.manifest_data.get('depends', ['base']))
        for model in self.models:
            for field in model['fields']:
                ftype, related = field[1], field[5]
                if ftype in ['Many2one', 'Many2many'] and related and related.split('.')[0] != self.module_name:
                    dependencies.add(related.split('.')[0])
        return list(dependencies)

    def scaffold_module(self):
        base_dir = os.path.join(self.module_path, self.module_name)
        os.makedirs(base_dir, exist_ok=True)
        os.makedirs(os.path.join(base_dir, 'models'), exist_ok=True)
        os.makedirs(os.path.join(base_dir, 'views'), exist_ok=True)
        os.makedirs(os.path.join(base_dir, 'security'), exist_ok=True)

        with open(os.path.join(base_dir, '__init__.py'), 'w') as f:
            f.write("from . import models\n")

        models_init_content = "\n".join([f"from . import {model['name']}" for model in self.models])
        with open(os.path.join(base_dir, 'models', '__init__.py'), 'w') as f:
            f.write(models_init_content)

    def create_manifest(self):
        data_files = ['security/ir.model.access.csv']
        data_files.extend([f"views/{model['name']}_views.xml" for model in self.models])
        data_files.extend([f"views/{action['name']}_actions.xml" for action in self.actions])
        manifest = {
            'name': self.manifest_data.get('name', self.module_name),
            'version': self.manifest_data.get('version', '1.0'),
            'summary': self.manifest_data.get('summary', 'Modulo auto-generato'),
            'category': self.manifest_data.get('category', 'Custom'),
            'author': self.manifest_data.get('author', 'Tuo Nome'),
            'website': self.manifest_data.get('website', 'https://tuosito.com'),
            'depends': self.get_dependencies(),
            'data': data_files,
            'installable': True,
            'application': True,
        }
        manifest_file_path = os.path.join(self.module_path, self.module_name, '__manifest__.py')
        with open(manifest_file_path, 'w') as manifest_file:
            manifest_file.write(json.dumps(manifest, indent=4))

    def create_models(self):
        for model in self.models:
            fields_code = '\n    '.join([
                f"{name} = fields.{ftype}(comodel_name='{related}', string='{label}', required={mandatory}, primary_key={primary_key})" if ftype == 'Many2one'
                else f"{name} = fields.{ftype}(string='{label}', required={mandatory}, primary_key={primary_key})" if ftype not in ['One2many', 'Many2many']
                else f"{name} = fields.{ftype}('{related}', '{field[6]}', string='{label}')" if ftype == 'One2many'
                else f"{name} = fields.{ftype}(string='{label}')"
                for name, ftype, label, mandatory, primary_key, related in model.get("fields")
            ])
            inherit_code = f"_inherit = '{model.get('inherit')}'\n" if model.get('inherit') else ""
            model_template = f"""
from odoo import models, fields

class {model['name'].capitalize()}(models.Model):
    _name = '{self.module_name}.{model["name"]}'
    {inherit_code}_description = '{model["name"]}'

    {fields_code}
"""
            model_file_path = os.path.join(self.module_path, self.module_name, 'models', f'{model["name"]}.py')
            with open(model_file_path, 'w') as model_file:
                model_file.write(model_template)

    def create_views(self):
        for model in self.models:
            fields_lines = '\n'.join([f'                        <field name="{name}"/>' for name, _, _, _, _, _, _ in model.get("fields")])
            buttons_lines = '\n'.join([
                f'                    <button name="{button["name"]}" type="object" string="{button["string"]}" '
                f'icon="{button["icon"]}" class="{button.get("class", "")}"/>' for button in self.options.get('buttons', [])
            ])

            views = []

            if 'form' in self.options['views']:
                form_view = f"""
<odoo>
    <record id="{model['name']}_form" model="ir.ui.view">
        <field name="name">{model['name']}.form</field>
        <field name="model">{self.module_name}.{model["name"]}</field>
        <field name="arch" type="xml">
            <form string="{model['name'].capitalize()}">
                <header>
                    {buttons_lines}
                </header>
                <sheet>
                    <group>
{fields_lines}
                    </group>
                </sheet>
                <div>
                    <button string="Aggiungi" type="object" class="oe_highlight"/>
                    <button string="Cancella" type="object" class="oe_highlight"/>
                </div>
            </form>
        </field>
    </record>
"""
                views.append(form_view)

            if 'tree' in self.options['views']:
                tree_view = f"""
    <record id="{model['name']}_tree" model="ir.ui.view">
        <field name="name">{model['name']}.tree</field>
        <field name="model">{self.module_name}.{model['name']}</field>
        <field name="arch" type="xml">
            <tree string="{model['name'].capitalize()}">
{fields_lines}
            </tree>
        </field>
    </record>
"""
                views.append(tree_view)

            if 'search' in self.options['views']:
                search_view = f"""
    <record id="{model['name']}_search" model="ir.ui.view">
        <field name="name">{model['name']}.search</field>
        <field name="model">{self.module_name}.{model['name']}</field>
        <field name="arch" type="xml">
            <search string="Cerca {model['name'].capitalize()}">
{fields_lines}
            </search>
        </field>
    </record>
"""
                views.append(search_view)

            if 'kanban' in self.options['views']:
                kanban_view = f"""
    <record id="{model['name']}_kanban" model="ir.ui.view">
        <field name="name">{model['name']}.kanban</field>
        <field name="model">{self.module_name}.{model['name']}</field>
        <field name="arch" type="xml">
            <kanban string="{model['name'].capitalize()}">
                <templates>
                    <t t-name="kanban-box">
                        <div class="oe_kanban_global_click">
{fields_lines}
                        </div>
                    </t>
                </templates>
            </kanban>
        </field>
    </record>
"""
                views.append(kanban_view)

            if 'calendar' in self.options['views']:
                calendar_view = f"""
    <record id="{model['name']}_calendar" model="ir.ui.view">
        <field name="name">{model['name']}.calendar</field>
        <field name="model">{self.module_name}.{model['name']}</field>
        <field name="arch" type="xml">
            <calendar string="{model['name'].capitalize()}" date_start="start_date" date_stop="end_date">
{fields_lines}
            </calendar>
        </field>
    </record>
"""
                views.append(calendar_view)

            if 'graph' in self.options['views']:
                graph_view = f"""
    <record id="{model['name']}_graph" model="ir.ui.view">
        <field name="name">{model['name']}.graph</field>
        <field name="model">{self.module_name}.{model['name']}</field>
        <field name="arch" type="xml">
            <graph string="{model['name'].capitalize()}" type="bar">
{fields_lines}
            </graph>
        </field>
    </record>
"""
                views.append(graph_view)

            views_content = "\n".join(views)

            action_view = f"""
    <record id="action_{model['name']}" model="ir.actions.act_window">
        <field name="name">{model['name'].capitalize()} Action</field>
        <field name="res_model">{self.module_name}.{model['name']}</field>
        <field name="view_mode">{",".join(self.options["views"])}</field>
    </record>

    <menuitem id="menu_{model['name']}_root" name="{model['name'].capitalize()}"/>
    <menuitem id="menu_{model['name']}" parent="menu_{model['name']}_root" action="action_{model['name']}" name="{model['name'].capitalize()}"/>
</odoo>
"""
            view_template = views_content + action_view

            views_file_path = os.path.join(self.module_path, self.module_name, 'views', f'{model["name"]}_views.xml')
            with open(views_file_path, 'w') as views_file:
                views_file.write(view_template)

    def create_actions(self):
        for action in self.actions:
            action_template = f"""
<odoo>
    <record id="{action['name']}_server_action" model="ir.actions.server">
        <field name="name">{action['name']}</field>
        <field name="model_id" ref="model_{self.module_name}_{action['model']}"/>
        <field name="binding_model_id" ref="model_{self.module_name}_{action['model']}"/>
        <field name="state">code</field>
        <field name="code">{action['code']}</field>
    </record>
</odoo>
"""
            actions_file_path = os.path.join(self.module_path, self.module_name, 'views', f'{action["name"]}_actions.xml')
            with open(actions_file_path, 'w') as actions_file:
                actions_file.write(action_template)

    def create_security(self):
        for model in self.models:
            security_template = f"""
<odoo>
    <record model="ir.model.access" id="access_{model['name']}_user">
        <field name="name">{model['name'].capitalize()} user</field>
        <field name="model_id" ref="model_{self.module_name}_{model['name']}"/>
        <field name="group_id" ref="base.group_user"/>
        <field name="perm_read" eval="1"/>
        <field name="perm_write" eval="1"/>
        <field name="perm_create" eval="1"/>
        <field name="perm_unlink" eval="1"/>
    </record>
</odoo>
"""
            security_file_path = os.path.join(self.module_path, self.module_name, 'security', 'security.xml')
            with open(security_file_path, 'a') as security_file:
                security_file.write(security_template)

        access_template = f"""
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
"""
        for model in self.models:
            access_template += f"access_{model['name']},access_{model['name']},model_{self.module_name}_{model['name']},base.group_user,1,1,1,1\n"

        access_file_path = os.path.join(self.module_path, self.module_name, 'security', 'ir.model.access.csv')
        with open(access_file_path, 'w') as access_file:
            access_file.write(access_template.strip())

        # Additional Security Rules
        for rule in self.security_rules:
            security_rule_template = f"""
<odoo>
    <record id="{rule['id']}" model="ir.rule">
        <field name="name">{rule['name']}</field>
        <field name="model_id" ref="model_{self.module_name}_{rule['model']}"/>
        <field name="domain_force">{rule['domain']}</field>
        <field name="groups" eval="[(4, ref('base.group_user'))]"/>
    </record>
</odoo>
"""
            with open(security_file_path, 'a') as security_file:
                security_file.write(security_rule_template)

    def update_existing_views(self):
        for link in self.options.get('link_locations', []):
            form_xml_id = link.get('form')
            tab_name = link.get('tab')
            if form_xml_id and tab_name:
                views_file_path = os.path.join(self.module_path, self.module_name, f'extend_{form_xml_id}_views.xml')
                tabs_code_list = []
                for model in self.models:
                    fields = ", ".join([f"<field name='{field[0]}'/>" for field in model["fields"]])
                    tab_code = (
                        "<page string=\"{tab_name}\">\n"
                        "    <group>{fields}</group>\n"
                        "</page>".format(tab_name=tab_name, fields=fields)
                    )
                    tabs_code_list.append(tab_code)
                tabs_code = '\n'.join(tabs_code_list)
                view_template = """
<odoo>
    <record id="extend_{form_xml_id}" model="ir.ui.view">
        <field name="name">extend.form.{form_xml_id}</field>
        <field name="model">your.model</field>
        <field name="inherit_id" ref="{form_xml_id}"/>
        <field name="arch" type="xml">
            <xpath expr="//notebook" position="inside">
                {tabs_code}
            </xpath>
        </field>
    </record>
</odoo>
""".format(form_xml_id=form_xml_id, tabs_code=tabs_code)

                with open(views_file_path, 'w') as views_file:
                    views_file.write(view_template)

    def save_configuration(self, file_path):
        config = {
            'module_name': self.module_name,
            'module_path': self.module_path,
            'models': self.models,
            'options': self.options,
            'actions': self.actions,
            'security_rules': self.security_rules,
            'manifest_data': self.manifest_data
        }
        with open(file_path, 'w') as config_file:
            json.dump(config, config_file, indent=4)

    @classmethod
    def load_configuration(cls, file_path):
        with open(file_path, 'r') as config_file:
            config = json.load(config_file)
        return cls(
            config['module_name'],
            config['module_path'],
            config['models'],
            config['options'],
            config['actions'],
            config['security_rules'],
            config['manifest_data']
        )

    def generate_module(self):
        self.validate_inputs()
        self.scaffold_module()
        self.create_manifest()
        self.create_models()
        self.create_views()
        self.create_actions()
        self.create_security()
        self.update_existing_views()

class ModuleBuilderApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Odoo Module Builder")
        self.root.geometry("1000x800")

        self.models = []
        self.options = {
            'views': [],
            'buttons': [],
            'link_locations': []
        }
        self.actions = []
        self.security_rules = []
        self.manifest_data = {}

        self.init_ui()

    def init_ui(self):
        # Canvas and scrollbar setup
        self.canvas = tk.Canvas(self.root)
        self.scrollbar = ttk.Scrollbar(self.root, orient="vertical", command=self.canvas.yview)
        self.scrollable_frame = ttk.Frame(self.canvas)

        self.scrollable_frame.bind(
            "<Configure>",
            lambda e: self.canvas.configure(
                scrollregion=self.canvas.bbox("all")
            )
        )

        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        self.canvas.configure(yscrollcommand=self.scrollbar.set)

        self.canvas.grid(row=0, column=0, sticky="nsew")
        self.scrollbar.grid(row=0, column=1, sticky="ns")

        # Frame per il modulo e il percorso
        frame = ttk.Frame(self.scrollable_frame, padding="10")
        frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        # Nome del modulo
        ttk.Label(frame, text="Nome del modulo:").grid(column=0, row=0, sticky=tk.W)
        self.module_name = ttk.Entry(frame, width=40)
        self.module_name.grid(column=1, row=0, sticky=(tk.W, tk.E))
        self.module_name.bind("<FocusOut>", self.validate_field)

        # Tooltip e istruzioni
        ttk.Label(frame, text="Inserisci il nome del tuo modulo.", foreground="grey").grid(column=2, row=0, sticky=tk.W)

        # Percorso del modulo
        ttk.Label(frame, text="Percorso del modulo:").grid(column=0, row=1, sticky=tk.W)
        self.module_path = ttk.Entry(frame, width=40)
        self.module_path.grid(column=1, row=1, sticky=(tk.W, tk.E))
        self.module_path.bind("<FocusOut>", self.validate_field)
        
        # Bottone per sfogliare il percorso del modulo
        ttk.Button(frame, text="Sfoglia...", command=self.browse_path).grid(column=2, row=1, sticky=tk.E)
        
        # Tooltip e istruzioni
        ttk.Label(frame, text="Seleziona il percorso in cui il modulo sarà generato.", foreground="grey").grid(column=2, row=2, sticky=tk.W)

        # Import da Excel
        self.use_excel = tk.BooleanVar()
        ttk.Checkbutton(frame, text="Importa da Excel", variable=self.use_excel, command=self.toggle_excel).grid(column=0, row=3, sticky=tk.W)

        # Campo percorso file Excel
        self.excel_path = ttk.Entry(frame, width=40)
        self.excel_path.grid(column=1, row=3, sticky=(tk.W, tk.E))
        self.excel_browse_btn = ttk.Button(frame, text="Sfoglia...", command=self.browse_excel)
        self.excel_browse_btn.grid(column=2, row=3, sticky=tk.E)

        # Tooltip e istruzioni
        ttk.Label(frame, text="Seleziona un file Excel contenente le informazioni su tabelle e campi.", foreground="grey").grid(column=2, row=4, sticky=tk.W)

        # Sezione per definire le colonne Excel
        frame_excel_columns = ttk.Frame(self.scrollable_frame, padding="10")
        frame_excel_columns.grid(row=4, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Label(frame_excel_columns, text="Configurazione delle colonne del file Excel", foreground="grey").grid(column=0, row=0, columnspan=4, sticky=tk.W)

        ttk.Label(frame_excel_columns, text="Colonna Tabella/Modulo:").grid(column=0, row=1, sticky=tk.W)
        self.excel_col_table = ttk.Entry(frame_excel_columns, width=20)
        self.excel_col_table.grid(column=1, row=1, sticky=tk.W)

        ttk.Label(frame_excel_columns, text="Colonna Campo/Field:").grid(column=2, row=1, sticky=tk.W)
        self.excel_col_field = ttk.Entry(frame_excel_columns, width=20)
        self.excel_col_field.grid(column=3, row=1, sticky=tk.W)

        ttk.Button(frame_excel_columns, text="Importa", command=self.load_excel_data).grid(column=0, row=2, columnspan=4, sticky=tk.W)

        # Manifest Data
        manifest_frame = ttk.Labelframe(self.scrollable_frame, text="Dati Manifesto", padding="10")
        manifest_frame.grid(row=5, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Label(manifest_frame, text="Versione:").grid(column=0, row=0, sticky=tk.W)
        self.manifest_version = ttk.Entry(manifest_frame, width=20)
        self.manifest_version.grid(column=1, row=0, sticky=tk.W)

        ttk.Label(manifest_frame, text="Sommario:").grid(column=0, row=1, sticky=tk.W)
        self.manifest_summary = ttk.Entry(manifest_frame, width=20)
        self.manifest_summary.grid(column=1, row=1, sticky=tk.W)

        ttk.Label(manifest_frame, text="Categoria:").grid(column=0, row=2, sticky=tk.W)
        self.manifest_category = ttk.Entry(manifest_frame, width=20)
        self.manifest_category.grid(column=1, row=2, sticky=tk.W)

        ttk.Label(manifest_frame, text="Autore:").grid(column=0, row=3, sticky=tk.W)
        self.manifest_author = ttk.Entry(manifest_frame, width=20)
        self.manifest_author.grid(column=1, row=3, sticky=tk.W)

        ttk.Label(manifest_frame, text="Sito Web:").grid(column=0, row=4, sticky=tk.W)
        self.manifest_website = ttk.Entry(manifest_frame, width=20)
        self.manifest_website.grid(column=1, row=4, sticky=tk.W)

        ttk.Label(manifest_frame, text="Dipendenza:").grid(column=0, row=5, sticky=tk.W)
        self.manifest_depends = ttk.Entry(manifest_frame, width=20)
        self.manifest_depends.grid(column=1, row=5, sticky=tk.W)

        # Frame per i modelli
        models_frame = ttk.Labelframe(self.scrollable_frame, text="Modelli", padding="10")
        models_frame.grid(row=6, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Label(models_frame, text="Elenco dei modelli e gestione dei campi. Puoi aggiungere, modificare e cancellare modelli.", foreground="grey").grid(column=0, row=0, columnspan=3, sticky=tk.W)

        # Lista dei modelli
        self.models_listbox = tk.Listbox(models_frame, height=8)
        self.models_listbox.grid(column=0, row=1, columnspan=3, sticky=(tk.W, tk.E))

        ttk.Button(models_frame, text="Aggiungi Modello", command=self.add_model).grid(column=0, row=2, sticky=tk.W)
        ttk.Button(models_frame, text="Modifica Modello", command=self.edit_model).grid(column=1, row=2, sticky=tk.W)
        ttk.Button(models_frame, text="Cancella Modello", command=self.delete_model).grid(column=2, row=2, sticky=tk.W)

        # Frame per le opzioni
        options_frame = ttk.Labelframe(self.scrollable_frame, text="Opzioni", padding="10")
        options_frame.grid(row=7, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Label(options_frame, text="Seleziona i tipi di viste che vuoi includere nel modulo. Puoi anche aggiungere bottoni personalizzati.", foreground="grey").grid(column=0, row=0, columnspan=6, sticky=tk.W)

        self.view_types = ["form", "tree", "search", "kanban", "calendar", "graph"]
        self.view_vars = {view: tk.BooleanVar() for view in self.view_types}

        for i, view in enumerate(self.view_types):
            ttk.Checkbutton(options_frame, text=view.capitalize(), variable=self.view_vars[view]).grid(column=i, row=1, sticky=tk.W)

        # Bottoni
        buttons_frame = ttk.Labelframe(self.scrollable_frame, text="Bottoni", padding="10")
        buttons_frame.grid(row=8, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Label(buttons_frame, text="Gestisci i bottoni personalizzati per le viste.", foreground="grey").grid(column=0, row=0, columnspan=3, sticky=tk.W)

        ttk.Button(buttons_frame, text="Aggiungi Bottone", command=self.add_button).grid(column=0, row=1, sticky=tk.W)
        ttk.Button(buttons_frame, text="Modifica Bottone", command=self.edit_button).grid(column=1, row=1, sticky=tk.W)
        ttk.Button(buttons_frame, text="Cancella Bottone", command=self.delete_button).grid(column=2, row=1, sticky=tk.W)

        self.buttons_listbox = tk.Listbox(buttons_frame, height=4)
        self.buttons_listbox.grid(column=0, row=2, columnspan=3, sticky=(tk.W, tk.E))

        # Frame per il collegamento dei moduli
        link_frame = ttk.Labelframe(self.scrollable_frame, text="Collegamenti", padding="10")
        link_frame.grid(row=9, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Label(link_frame, text="Specifica dove collegare il nuovo modulo nelle viste esistenti.", foreground="grey").grid(column=0, row=0, columnspan=3, sticky=tk.W)

        ttk.Button(link_frame, text="Aggiungi Collegamento", command=self.add_link).grid(column=0, row=1, sticky=tk.W)
        ttk.Button(link_frame, text="Modifica Collegamento", command=self.edit_link).grid(column=1, row=1, sticky=tk.W)
        ttk.Button(link_frame, text="Cancella Collegamento", command=self.delete_link).grid(column=2, row=1, sticky=tk.W)

        self.links_listbox = tk.Listbox(link_frame, height=4)
        self.links_listbox.grid(column=0, row=2, columnspan=3, sticky=(tk.W, tk.E))

        # Frame per azioni personalizzate
        actions_frame = ttk.Labelframe(self.scrollable_frame, text="Azioni Personalizzate", padding="10")
        actions_frame.grid(row=10, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Label(actions_frame, text="Definisci azioni personalizzate per il modulo.", foreground="grey").grid(column=0, row=0, columnspan=3, sticky=tk.W)

        ttk.Button(actions_frame, text="Aggiungi Azione", command=self.add_action).grid(column=0, row=1, sticky=tk.W)
        ttk.Button(actions_frame, text="Modifica Azione", command=self.edit_action).grid(column=1, row=1, sticky=tk.W)
        ttk.Button(actions_frame, text="Cancella Azione", command=self.delete_action).grid(column=2, row=1, sticky=tk.W)

        self.actions_listbox = tk.Listbox(actions_frame, height=4)
        self.actions_listbox.grid(column=0, row=2, columnspan=3, sticky=(tk.W, tk.E))

        # Frame per le regole di sicurezza
        security_frame = ttk.Labelframe(self.scrollable_frame, text="Regole di Sicurezza", padding="10")
        security_frame.grid(row=11, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Label(security_frame, text="Gestisci le regole di sicurezza per il modulo.", foreground="grey").grid(column=0, row=0, columnspan=3, sticky=tk.W)

        ttk.Button(security_frame, text="Aggiungi Regola", command=self.add_security_rule).grid(column=0, row=1, sticky=tk.W)
        ttk.Button(security_frame, text="Modifica Regola", command=self.edit_security_rule).grid(column=1, row=1, sticky=tk.W)
        ttk.Button(security_frame, text="Cancella Regola", command=self.delete_security_rule).grid(column=2, row=1, sticky=tk.W)

        self.security_listbox = tk.Listbox(security_frame, height=4)
        self.security_listbox.grid(column=0, row=2, columnspan=3, sticky=(tk.W, tk.E))

        # Frame per i pulsanti di azione
        action_frame = ttk.Frame(self.scrollable_frame, padding="10")
        action_frame.grid(row=12, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

        ttk.Button(action_frame, text="Genera Modulo", command=self.generate_module).grid(column=0, row=0, sticky=tk.W)
        ttk.Button(action_frame, text="Salva Configurazione", command=self.save_config).grid(column=1, row=0, sticky=tk.W)
        ttk.Button(action_frame, text="Carica Configurazione", command=self.load_config).grid(column=2, row=0, sticky=tk.W)

    def browse_path(self):
        path = filedialog.askdirectory()
        if path:
            self.module_path.delete(0, tk.END)
            self.module_path.insert(0, path)

    def browse_excel(self):
        path = filedialog.askopenfilename(filetypes=[("Excel files", "*.xlsx *.xls")])
        if path:
            self.excel_path.delete(0, tk.END)
            self.excel_path.insert(0, path)
            self.load_excel_data()

    def toggle_excel(self):
        state = tk.NORMAL if self.use_excel.get() else tk.DISABLED
        self.excel_path.config(state=state)
        self.excel_browse_btn.config(state=state)
        self.excel_col_table.config(state=state)
        self.excel_col_field.config(state=state)

    def load_excel_data(self):
        if not self.excel_path.get() or not self.excel_col_table.get() or not self.excel_col_field.get():
            messagebox.showerror("Errore", "Per favore completa il percorso del file Excel e le colonne.")
            return

        try:
            df = pd.read_excel(self.excel_path.get())
            table_col = self.excel_col_table.get()
            field_col = self.excel_col_field.get()

            model_names = df[table_col].unique().tolist()
            self.models = []
            self.models_listbox.delete(0, tk.END)

            for model_name in model_names:
                model_fields = df[df[table_col] == model_name][field_col].tolist()
                model_fields_tuples = [(field, 'Char', 'Field Label', False, False, '') for field in model_fields]  # Default values for tuples
                self.models.append({"name": model_name, "fields": model_fields_tuples})
                self.models_listbox.insert(tk.END, f"{model_name} ({len(model_fields)} campi)")

        except Exception as e:
            messagebox.showerror("Errore", f"Errore durante l'importazione da Excel: {str(e)}")

    def add_model(self):
        add_model_dialog = tk.Toplevel(self.root)
        add_model_dialog.title("Aggiungi Modello")

        ttk.Label(add_model_dialog, text="Nome del modello:").grid(row=0, column=0, sticky=tk.W)
        model_name_entry = ttk.Entry(add_model_dialog, width=20)
        model_name_entry.grid(row=0, column=1, sticky=(tk.W, tk.E))

        ttk.Label(add_model_dialog, text="Ereditato da (opzionale):").grid(row=1, column=0, sticky=tk.W)
        model_inherit_entry = ttk.Entry(add_model_dialog, width=20)
        model_inherit_entry.grid(row=1, column=1, sticky=(tk.W, tk.E))

        columns = ["Nome Campo", "Tipo Campo", "Etichetta", "Obbligatorio", "Chiave Primaria", "Modello Correlato", "Campo Relazione"]
        frame_fields = ttk.Frame(add_model_dialog)
        frame_fields.grid(row=2, column=0, columnspan=2, sticky="nsew")

        for i, col in enumerate(columns):
            ttk.Label(frame_fields, text=col).grid(row=0, column=i, sticky=tk.W)

        fields_entries = []

        def add_field_row():
            row = len(fields_entries) + 1
            field_name = ttk.Entry(frame_fields)
            field_name.grid(row=row, column=0, sticky=tk.W)

            field_type = ttk.Combobox(frame_fields, values=["Binary", "Boolean", "Char", "Date", "Datetime", "Float", "HTML", "Integer", "JSON", "Many2many", "Many2one", "Many2one Reference", "Monetary", "One2many", "Properties", "Properties Definition", "Reference", "Selection", "Text"])
            field_type.grid(row=row, column=1, sticky=tk.W)

            field_label = ttk.Entry(frame_fields)
            field_label.grid(row=row, column=2, sticky=tk.W)

            mandatory_var = tk.BooleanVar()
            field_mandatory = ttk.Checkbutton(frame_fields, variable=mandatory_var)
            field_mandatory.grid(row=row, column=3, sticky=tk.W)

            primary_key_var = tk.BooleanVar()
            field_primary_key = ttk.Checkbutton(frame_fields, variable=primary_key_var)
            field_primary_key.grid(row=row, column=4, sticky=tk.W)

            def on_mandatory_change(*_):
                if not mandatory_var.get():
                    field_primary_key.state(['!selected'])

            def on_primary_key_change(*_):
                if primary_key_var.get():
                    mandatory_var.set(True)

            mandatory_var.trace_add('write', on_mandatory_change)
            primary_key_var.trace_add('write', on_primary_key_change)

            field_related = ttk.Entry(frame_fields)
            field_related.grid(row=row, column=5, sticky=tk.W)

            field_relation = ttk.Entry(frame_fields)
            field_relation.grid(row=row, column=6, sticky=tk.W)

            fields_entries.append((field_name, field_type, field_label, mandatory_var, primary_key_var, field_related, field_relation))

        ttk.Button(add_model_dialog, text="Aggiungi Campo", command=add_field_row).grid(row=3, column=0, columnspan=2, sticky=tk.W)

        def save_model():
            model_name = model_name_entry.get()
            model_inherit = model_inherit_entry.get().strip() or None
            if not model_name:
                messagebox.showerror("Errore", "Per favore inserisci un nome per il modello.")
                return

            model_fields = []
            for field_name, field_type, field_label, field_mandatory_var, field_primary_key_var, field_related, field_relation in fields_entries:
                name = field_name.get()
                ftype = field_type.get()
                label = field_label.get()
                mandatory = field_mandatory_var.get()
                primary_key = field_primary_key_var.get()
                related = field_related.get() if ftype in ['Many2one', 'One2many', 'Many2many'] else ''
                relation = field_relation.get() if ftype == 'One2many' else ''
                if not name or not ftype or not label:
                    messagebox.showerror("Errore", "Compila tutti i campi per ogni riga.")
                    return
                if primary_key and not mandatory:
                    messagebox.showerror("Errore", "Un campo chiave primaria deve essere obbligatorio.")
                    return
                model_fields.append((name, ftype, label, mandatory, primary_key, related, relation))

            self.models.append({"name": model_name, "inherit": model_inherit, "fields": model_fields})
            self.models_listbox.insert(tk.END, f"{model_name} ({len(model_fields)} campi)")
            add_model_dialog.destroy()

        ttk.Button(add_model_dialog, text="Salva Modello", command=save_model).grid(row=4, column=0, columnspan=2, sticky=(tk.W, tk.E))

    def edit_model(self):
        selection = self.models_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        model = self.models[index]

        edit_model_dialog = tk.Toplevel(self.root)
        edit_model_dialog.title("Modifica Modello")

        ttk.Label(edit_model_dialog, text="Nome del modello:").grid(row=0, column=0, sticky=tk.W)
        model_name_entry = ttk.Entry(edit_model_dialog, width=20)
        model_name_entry.grid(row=0, column=1, sticky=(tk.W, tk.E))
        model_name_entry.insert(0, model["name"])

        ttk.Label(edit_model_dialog, text="Ereditato da (opzionale):").grid(row=1, column=0, sticky=tk.W)
        model_inherit_entry = ttk.Entry(edit_model_dialog, width=20)
        model_inherit_entry.grid(row=1, column=1, sticky=(tk.W, tk.E))
        model_inherit_entry.insert(0, model.get("inherit", ""))

        columns = ["Nome Campo", "Tipo Campo", "Etichetta", "Obbligatorio", "Chiave Primaria", "Modello Correlato", "Campo Relazione"]
        frame_fields = ttk.Frame(edit_model_dialog)
        frame_fields.grid(row=2, column=0, columnspan=2, sticky="nsew")

        for i, col in enumerate(columns):
            ttk.Label(frame_fields, text=col).grid(row=0, column=i, sticky=tk.W)

        fields_entries = []
        for field_name, field_type, field_label, field_mandatory, field_primary_key, field_related, field_relation in model["fields"]:
            row = len(fields_entries) + 1
            field_name_entry = ttk.Entry(frame_fields)
            field_name_entry.grid(row=row, column=0, sticky=tk.W)
            field_name_entry.insert(0, field_name)

            field_type_entry = ttk.Combobox(frame_fields, values=["Binary", "Boolean", "Char", "Date", "Datetime", "Float", "HTML", "Integer", "JSON", "Many2many", "Many2one", "Many2one Reference", "Monetary", "One2many", "Properties", "Properties Definition", "Reference", "Selection", "Text"])
            field_type_entry.grid(row=row, column=1, sticky=tk.W)
            field_type_entry.set(field_type)

            field_label_entry = ttk.Entry(frame_fields)
            field_label_entry.grid(row=row, column=2, sticky=tk.W)
            field_label_entry.insert(0, field_label)

            field_mandatory_var = tk.BooleanVar(value=field_mandatory)
            field_mandatory_entry = ttk.Checkbutton(frame_fields, variable=field_mandatory_var)
            field_mandatory_entry.grid(row=row, column=3, sticky=tk.W)

            field_primary_key_var = tk.BooleanVar(value=field_primary_key)
            field_primary_key_entry = ttk.Checkbutton(frame_fields, variable=field_primary_key_var)
            field_primary_key_entry.grid(row=row, column=4, sticky=tk.W)

            def on_mandatory_change(*_):
                if not field_mandatory_var.get():
                    field_primary_key_entry.state(['!selected'])

            def on_primary_key_change(*_):
                if field_primary_key_var.get():
                    field_mandatory_var.set(True)

            field_mandatory_var.trace_add('write', on_mandatory_change)
            field_primary_key_var.trace_add('write', on_primary_key_change)

            field_related_entry = ttk.Entry(frame_fields)
            field_related_entry.grid(row=row, column=5, sticky=tk.W)
            field_related_entry.insert(0, field_related)

            field_relation_entry = ttk.Entry(frame_fields)
            field_relation_entry.grid(row=row, column=6, sticky=tk.W)
            field_relation_entry.insert(0, field_relation)

            fields_entries.append((field_name_entry, field_type_entry, field_label_entry, field_mandatory_var, field_primary_key_var, field_related_entry, field_relation_entry))

        def add_field_row():
            row = len(fields_entries) + 1
            field_name_entry = ttk.Entry(frame_fields)
            field_name_entry.grid(row=row, column=0, sticky=tk.W)

            field_type_entry = ttk.Combobox(frame_fields, values=["Binary", "Boolean", "Char", "Date", "Datetime", "Float", "HTML", "Integer", "JSON", "Many2many", "Many2one", "Many2one Reference", "Monetary", "One2many", "Properties", "Properties Definition", "Reference", "Selection", "Text"])
            field_type_entry.grid(row=row, column=1, sticky=tk.W)

            field_label_entry = ttk.Entry(frame_fields)
            field_label_entry.grid(row=row, column=2, sticky=tk.W)

            field_mandatory_var = tk.BooleanVar()
            field_mandatory_entry = ttk.Checkbutton(frame_fields, variable=field_mandatory_var)
            field_mandatory_entry.grid(row=row, column=3, sticky=tk.W)

            field_primary_key_var = tk.BooleanVar()
            field_primary_key_entry = ttk.Checkbutton(frame_fields, variable=field_primary_key_var)
            field_primary_key_entry.grid(row=row, column=4, sticky=tk.W)

            def on_mandatory_change(*_):
                if not field_mandatory_var.get():
                    field_primary_key_entry.state(['!selected'])

            def on_primary_key_change(*_):
                if field_primary_key_var.get():
                    field_mandatory_var.set(True)

            field_mandatory_var.trace_add('write', on_mandatory_change)
            field_primary_key_var.trace_add('write', on_primary_key_change)

            field_related_entry = ttk.Entry(frame_fields)
            field_related_entry.grid(row=row, column=5, sticky=tk.W)

            field_relation_entry = ttk.Entry(frame_fields)
            field_relation_entry.grid(row=row, column=6, sticky=tk.W)

            fields_entries.append((field_name_entry, field_type_entry, field_label_entry, field_mandatory_var, field_primary_key_var, field_related_entry, field_relation_entry))

        def delete_field_row():
            if fields_entries:
                entries = fields_entries.pop()
                for entry in entries:
                    entry.grid_forget()

        ttk.Button(edit_model_dialog, text="Aggiungi Campo", command=add_field_row).grid(row=3, column=0, sticky=tk.W)
        ttk.Button(edit_model_dialog, text="Elimina Campo", command=delete_field_row).grid(row=3, column=1, sticky=tk.W)

        def save_model():
            model_name = model_name_entry.get()
            model_inherit = model_inherit_entry.get().strip() or None
            if not model_name:
                messagebox.showerror("Errore", "Per favore inserisci un nome per il modello.")
                return

            model_fields = []
            for field_name_entry, field_type_entry, field_label_entry, field_mandatory_var, field_primary_key_var, field_related_entry, field_relation_entry in fields_entries:
                name = field_name_entry.get()
                ftype = field_type_entry.get()
                label = field_label_entry.get()
                mandatory = field_mandatory_var.get()
                primary_key = field_primary_key_var.get()
                related = field_related_entry.get() if ftype in ['Many2one', 'One2many', 'Many2many'] else ''
                relation = field_relation_entry.get() if ftype == 'One2many' else ''
                if not name or not ftype or not label:
                    messagebox.showerror("Errore", "Compila tutti i campi per ogni riga.")
                    return
                if primary_key and not mandatory:
                    messagebox.showerror("Errore", "Un campo chiave primaria deve essere obbligatorio.")
                    return
                model_fields.append((name, ftype, label, mandatory, primary_key, related, relation))

            self.models[index] = {"name": model_name, "inherit": model_inherit, "fields": model_fields}
            self.models_listbox.delete(index)
            self.models_listbox.insert(index, f"{model_name} ({len(model_fields)} campi)")
            edit_model_dialog.destroy()

        ttk.Button(edit_model_dialog, text="Salva Modello", command=save_model).grid(row=4, column=0, columnspan=2, sticky=(tk.W, tk.E))

    def delete_model(self):
        selection = self.models_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        self.models_listbox.delete(index)
        del self.models[index]

    def add_button(self):
        button_name = self.prompt_input("Inserisci il nome del bottone:")
        button_string = self.prompt_input("Inserisci la stringa del bottone:")
        button_icon = self.prompt_input("Inserisci l'icona del bottone (es. fa-check):")
        button_class = self.prompt_input("Inserisci la classe del bottone (es. btn-primary):")
        self.buttons_listbox.insert(tk.END, f"{button_name} ({button_string})")
        self.options['buttons'].append({
            "name": button_name,
            "string": button_string,
            "icon": button_icon,
            "class": button_class
        })

    def edit_button(self):
        selection = self.buttons_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        button = self.options['buttons'][index]
        self.buttons_listbox.delete(index)

        button_name = self.prompt_input("Inserisci il nome del bottone:", default_value=button["name"])
        button_string = self.prompt_input("Inserisci la stringa del bottone:", default_value=button["string"])
        button_icon = self.prompt_input("Inserisci l'icona del bottone (es. fa-check):", default_value=button["icon"])
        button_class = self.prompt_input("Inserisci la classe del bottone (es. btn-primary):", default_value=button["class"])

        self.buttons_listbox.insert(index, f"{button_name} ({button_string})")
        self.options['buttons'][index] = {
            "name": button_name,
            "string": button_string,
            "icon": button_icon,
            "class": button_class
        }

    def delete_button(self):
        selection = self.buttons_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        self.buttons_listbox.delete(index)
        del self.options['buttons'][index]

    def add_link(self):
        form_xml_id = self.prompt_input("Inserisci l'ID XML del form per collegare questo modulo:")
        if not form_xml_id:
            return
        tab_name = self.prompt_input("Inserisci il nome del tab o sezione in cui vuoi aggiungere questo modulo:")
        if not tab_name:
            return
        self.links_listbox.insert(tk.END, f"{form_xml_id} -> {tab_name}")
        self.options.get('link_locations', []).append({"form": form_xml_id, "tab": tab_name})

    def edit_link(self):
        selection = self.links_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        link = self.options.get('link_locations', [])[index]
        self.links_listbox.delete(index)

        form_xml_id = self.prompt_input("Inserisci l'ID XML del form per collegare questo modulo:", default_value=link["form"])
        tab_name = self.prompt_input("Inserisci il nome del tab o sezione in cui vuoi aggiungere questo modulo:", default_value=link["tab"])

        self.links_listbox.insert(index, f"{form_xml_id} -> {tab_name}")
        self.options.get('link_locations', [])[index] = {"form": form_xml_id, "tab": tab_name}

    def delete_link(self):
        selection = self.links_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        self.links_listbox.delete(index)
        del self.options.get('link_locations', [])[index]

    def add_action(self):
        action_name = self.prompt_input("Inserisci il nome dell'azione:")
        action_model = self.prompt_input("Inserisci il nome del modello per l'azione:")
        action_code = self.prompt_input("Inserisci il codice Python per l'azione:")
        self.actions_listbox.insert(tk.END, f"{action_name} ({action_model})")
        self.actions.append({"name": action_name, "model": action_model, "code": action_code})

    def edit_action(self):
        selection = self.actions_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        action = self.actions[index]
        self.actions_listbox.delete(index)

        action_name = self.prompt_input("Inserisci il nome dell'azione:", default_value=action["name"])
        action_model = self.prompt_input("Inserisci il nome del modello per l'azione:", default_value=action["model"])
        action_code = self.prompt_input("Inserisci il codice Python per l'azione:", default_value=action["code"])

        self.actions_listbox.insert(index, f"{action_name} ({action_model})")
        self.actions[index] = {"name": action_name, "model": action_model, "code": action_code}

    def delete_action(self):
        selection = self.actions_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        self.actions_listbox.delete(index)
        del self.actions[index]

    def add_security_rule(self):
        rule_id = self.prompt_input("Inserisci l'ID della regola di sicurezza:")
        rule_name = self.prompt_input("Inserisci il nome della regola:")
        rule_model = self.prompt_input("Inserisci il nome del modello per la regola:")
        rule_domain = self.prompt_input("Inserisci il dominio per la regola:")
        self.security_listbox.insert(tk.END, f"{rule_name} ({rule_model})")
        self.security_rules.append({"id": rule_id, "name": rule_name, "model": rule_model, "domain": rule_domain})

    def edit_security_rule(self):
        selection = self.security_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        rule = self.security_rules[index]
        self.security_listbox.delete(index)

        rule_id = self.prompt_input("Inserisci l'ID della regola di sicurezza:", default_value=rule["id"])
        rule_name = self.prompt_input("Inserisci il nome della regola:", default_value=rule["name"])
        rule_model = self.prompt_input("Inserisci il nome del modello per la regola:", default_value=rule["model"])
        rule_domain = self.prompt_input("Inserisci il dominio per la regola:", default_value=rule["domain"])

        self.security_listbox.insert(index, f"{rule_name} ({rule_model})")
        self.security_rules[index] = {"id": rule_id, "name": rule_name, "model": rule_model, "domain": rule_domain}

    def delete_security_rule(self):
        selection = self.security_listbox.curselection()
        if not selection:
            return
        index = selection[0]
        self.security_listbox.delete(index)
        del self.security_rules[index]

    def prompt_input(self, message, default_value=None):
        dialog = tk.Toplevel()
        dialog.grab_set()
        dialog.title("Input")
        ttk.Label(dialog, text=message).grid(column=0, row=0, sticky=tk.W)
        entry = ttk.Entry(dialog, width=20)
        entry.grid(column=1, row=0, sticky=(tk.W, tk.E))
        if default_value:
            entry.insert(0, default_value)

        def on_ok():
            self.input_value = entry.get()
            dialog.destroy()

        def on_cancel():
            self.input_value = None
            dialog.destroy()

        ttk.Button(dialog, text="OK", command=on_ok).grid(column=0, row=1, sticky=tk.E)
        ttk.Button(dialog, text="Cancel", command=on_cancel).grid(column=1, row=1, sticky=tk.W)

        dialog.wait_window()
        return self.input_value

    def validate_field(self, event):
        widget = event.widget
        if not widget.get():
            widget.config(background="pink")
        else:
            widget.config(background="white")

    def generate_module(self):
        if not self.module_name.get() or not self.module_path.get() or not self.models:
            messagebox.showerror("Errore", "Per favore compila tutti i campi richiesti.")
            return
        
        options = {
            "views": [view for view in self.view_types if self.view_vars[view].get()],
            "buttons": self.options.get('buttons', []),
            "link_locations": self.options.get('link_locations', [])
        }

        manifest_data = {
            'name': self.module_name.get(),
            'version': self.manifest_version.get(),
            'summary': self.manifest_summary.get(),
            'category': self.manifest_category.get(),
            'author': self.manifest_author.get(),
            'website': self.manifest_website.get(),
            'depends': self.get_dependencies()
        }
        
        generator = ModuleGenerator(self.module_name.get(), self.module_path.get(), self.models, options, self.actions, self.security_rules, manifest_data)
        try:
            generator.generate_module()
            messagebox.showinfo("Successo", "Modulo generato con successo.")
        except Exception as e:
            messagebox.showerror("Errore", str(e))

    def save_config(self):
        config_path = filedialog.asksaveasfilename(defaultextension=".json", filetypes=[("JSON files", "*.json")])
        if not config_path:
            return
        
        config = {
            'module_name': self.module_name.get(),
            'module_path': self.module_path.get(),
            'models': self.models,
            'options': {
                'views': [view for view in self.view_types if self.view_vars[view].get()],
                'buttons': self.options.get('buttons', []),
                'link_locations': self.options.get('link_locations', [])
            },
            'actions': self.actions,
            'security_rules': self.security_rules,
            'manifest_data': {
                'version': self.manifest_version.get(),
                'summary': self.manifest_summary.get(),
                'category': self.manifest_category.get(),
                'author': self.manifest_author.get(),
                'website': self.manifest_website.get(),
                'depends': self.get_dependencies()
            }
        }

        with open(config_path, 'w') as config_file:
            json.dump(config, config_file, indent=4)
        messagebox.showinfo("Successo", "Configurazione salvata con successo.")

    def load_config(self):
        config_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])
        if not config_path:
            return
        
        with open(config_path, 'r') as config_file:
            config = json.load(config_file)
        
        self.module_name.delete(0, tk.END)
        self.module_name.insert(0, config.get('module_name', ''))
        self.module_path.delete(0, tk.END)
        self.module_path.insert(0, config.get('module_path', ''))
        
        self.models_listbox.delete(0, tk.END)
        self.models = config.get('models', [])
        for model in self.models:
            self.models_listbox.insert(tk.END, f"{model['name']} ({len(model['fields'])} campi)")

        options = config.get('options', {})
        
        for view in self.view_types:
            self.view_vars[view].set(view in options.get('views', []))
        
        self.buttons_listbox.delete(0, tk.END)
        buttons = options.get('buttons', [])
        for button in buttons:
            self.buttons_listbox.insert(tk.END, f"{button['name']} ({button['string']})")
        self.options['buttons'] = buttons

        self.links_listbox.delete(0, tk.END)
        links = options.get('link_locations', [])
        for link in links:
            self.links_listbox.insert(tk.END, f"{link['form']} -> {link['tab']}")
        self.options['link_locations'] = links

        self.actions_listbox.delete(0, tk.END)
        self.actions = config.get('actions', [])
        for action in self.actions:
            self.actions_listbox.insert(tk.END, f"{action['name']} ({action['model']})")

        self.security_listbox.delete(0, tk.END)
        self.security_rules = config.get('security_rules', [])
        for rule in self.security_rules:
            self.security_listbox.insert(tk.END, f"{rule['name']} ({rule['model']})")

        manifest_data = config.get('manifest_data', {})
        self.manifest_version.delete(0, tk.END)
        self.manifest_version.insert(0, manifest_data.get('version', ''))
        self.manifest_summary.delete(0, tk.END)
        self.manifest_summary.insert(0, manifest_data.get('summary', ''))
        self.manifest_category.delete(0, tk.END)
        self.manifest_category.insert(0, manifest_data.get('category', ''))
        self.manifest_author.delete(0, tk.END)
        self.manifest_author.insert(0, manifest_data.get('author', ''))
        self.manifest_website.delete(0, tk.END)
        self.manifest_website.insert(0, manifest_data.get('website', ''))
        self.manifest_depends.delete(0, tk.END)
        self.manifest_depends.insert(0, ', '.join(manifest_data.get('depends', [])))

        messagebox.showinfo("Successo", "Configurazione caricata con successo.")

if __name__ == "__main__":
    root = tk.Tk()
    root.geometry("1000x800")
    root.grid_rowconfigure(0, weight=1)
    root.grid_columnconfigure(0, weight=1)
    app = ModuleBuilderApp(root)
    root.mainloop()


errori segnalati:
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Utente\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Utente\Desktop\odoo\odoo_17_costruttore\odoo_17_costruttore_v2.py", line 721, in edit_model
    model_inherit_entry.insert(0, model.get("inherit", ""))
  File "C:\Users\Utente\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 2686, in insert
    self.tk.call(self._w, 'insert', index, string)
_tkinter.TclError: wrong # args: should be ".!toplevel2.!entry2 insert index text"
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Utente\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Utente\Desktop\odoo\odoo_17_costruttore\odoo_17_costruttore_v2.py", line 1045, in generate_module
    'depends': self.get_dependencies()
AttributeError: 'ModuleBuilderApp' object has no attribute 'get_dependencies'
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Utente\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Utente\Desktop\odoo\odoo_17_costruttore\odoo_17_costruttore_v2.py", line 1045, in generate_module
    'depends': self.get_dependencies()
AttributeError: 'ModuleBuilderApp' object has no attribute 'get_dependencies'
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Utente\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Utente\Desktop\odoo\odoo_17_costruttore\odoo_17_costruttore_v2.py", line 1045, in generate_module
    'depends': self.get_dependencies()
AttributeError: 'ModuleBuilderApp' object has no attribute 'get_dependencies'
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Utente\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Utente\Desktop\odoo\odoo_17_costruttore\odoo_17_costruttore_v2.py", line 1045, in generate_module
    'depends': self.get_dependencies()
AttributeError: 'ModuleBuilderApp' object has no attribute 'get_dependencies'
Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\Utente\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1699, in __call__
    return self.func(*args)
  File "C:\Users\Utente\Desktop\odoo\odoo_17_costruttore\odoo_17_costruttore_v2.py", line 1077, in save_config
    'depends': self.get_dependencies()
AttributeError: 'ModuleBuilderApp' object has no attribute 'get_dependencies'