import db def duplicate_element(slug, element_id): """Duplique un élément et tout son sous-arbre DANS SON CONTENEUR ACTUEL (même écran, même parent_id que l'original) — le clic droit "Dupliquer" de l'arborescence n'a pas à faire choisir où poser la copie, elle apparaît juste à côté de l'original. Renvoie l'id de la copie (celui à sélectionner ensuite), ou None si l'élément n'existe pas.""" conn = db.connect(slug) root_row = conn.execute("SELECT * FROM _screen_elements WHERE id = ?", (element_id,)).fetchone() if not root_row: conn.close() return None root = dict(root_row) source = [ dict(r) for r in conn.execute( "SELECT * FROM _screen_elements WHERE screen_id = ?", (root["screen_id"],) ).fetchall() ] conn.close() def copy_one(src, new_parent_id, is_root): conn = db.connect(slug) max_z = conn.execute( "SELECT MAX(z_index) AS m FROM _screen_elements WHERE screen_id = ?", (src["screen_id"],) ).fetchone()["m"] x, y = src["x"], src["y"] if is_root and not new_parent_id: # Petit décalage pour que la copie ne recouvre pas exactement # l'original (qui serait alors invisible en dessous). x = min(100, (x or 0) + 4) y = min(100, (y or 0) + 4) name = src.get("name") if is_root and name: name = f"{name} (copie)" conn.execute( """INSERT INTO _screen_elements (screen_id, parent_id, widget, element_type_id, name, content, attributes, x, y, width, height, z_index, style) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""", ( src["screen_id"], new_parent_id, src["widget"], src.get("element_type_id"), name, src["content"], src["attributes"], x, y, src["width"], src["height"], (max_z or 0) + 1, src["style"], ), ) new_id = conn.execute("SELECT last_insert_rowid() AS id").fetchone()["id"] conn.commit() conn.close() return new_id def walk(src_parent_id, new_parent_id): for child in [s for s in source if s.get("parent_id") == src_parent_id]: new_child_id = copy_one(child, new_parent_id, is_root=False) walk(child["id"], new_child_id) new_root_id = copy_one(root, root.get("parent_id"), is_root=True) walk(root["id"], new_root_id) return new_root_id