# "Autocompleta DOCX" por ADG, alias Ingenierio Solitario (https://autarquiapersonal.com/)

import tkinter as tk
from tkinter import ttk
from tkinter import filedialog as fd
from tkinter.messagebox import showinfo

import docx
from docx2pdf import convert
import os
import sys

# Variables:

rutas_de_archivos = []
ruta_de_destino = ""

numero_de_campos = 3000
campos_a_cumplimentar = {}
datos_a_insertar = []
for i in range(3000):
    llave = "{$ID"+str(i)+"}"
    campos_a_cumplimentar[llave] = ""

# Inicio GUI:

root = tk.Tk()
root.title('Autocompleta DOCX por Ingeniero Solitario (ADG)')
root.geometry('450x210')

#  Funciones para pegar datos, seleccionar documento y seleccionar destino:

def pegar_datos():

    global datos_a_insertar

    try:

        datos_copiados_texto = root.clipboard_get()

        datos_a_insertar = datos_copiados_texto.split("_#_")

    except tk.TclError:

        pass

    if len(datos_a_insertar) == numero_de_campos:
        boton_de_seleccionar_varios.state(["!disabled"])

def seleccionar_varios_archivos():

    global rutas_de_archivos

    tipos_de_archivos = (
        ('Documento de word', '*.docx'),
    )

    rutas_de_archivos = fd.askopenfilenames(
        title='Elegir documentos',
        initialdir='/',
        filetypes=tipos_de_archivos)

    if rutas_de_archivos != 0:
        boton_de_destino.state(["!disabled"])

def seleccionar_destino():

    global ruta_de_destino

    tipos_de_archivos = (
        ('Documento de word', '*.docx'),
    )

    ruta_de_destino = fd.askdirectory(
        title='Elegir un destino',
        initialdir='/'
    )

    if ruta_de_destino != 0:
        boton_de_guardados.state(["!disabled"])

# Función para controlar la barra de progreso:

def control_progreso_impresion():

    progreso_impresion["value"] += 100 / len(rutas_de_archivos)

    estado_progreso.config(text=str(round(progreso_impresion["value"], 0)) +"%")


# Edición y guardado del documento word:

def editar_varios_documentos():

    for j in range(len(rutas_de_archivos)):

        documento = docx.Document(rutas_de_archivos[int(j)])

        for i in campos_a_cumplimentar:
            campos_a_cumplimentar[i] = datos_a_insertar[list(campos_a_cumplimentar).index(i)]

        for paragraph in documento.paragraphs:
            for i in campos_a_cumplimentar:
                if i in paragraph.text:
                    paragraph.text = paragraph.text.replace(i, campos_a_cumplimentar[i])

        for table in documento.tables:
            for row in table.rows:
                for cell in row.cells:
                    for paragraph in cell.paragraphs:
                        for i in campos_a_cumplimentar:
                            if i in paragraph.text:
                                paragraph.text = paragraph.text.replace(i, campos_a_cumplimentar[i])

        for k in range(len(documento.sections)):
            section = documento.sections[k]
            header = section.header

            for paragraph in header.paragraphs:
                for i in campos_a_cumplimentar:
                    if i in paragraph.text:
                        paragraph.text = paragraph.text.replace(i, campos_a_cumplimentar[i])

            for table in header.tables:
                for row in table.rows:
                    for cell in row.cells:
                        for paragraph in cell.paragraphs:
                            for i in campos_a_cumplimentar:
                                if i in paragraph.text:
                                    paragraph.text = paragraph.text.replace(i, campos_a_cumplimentar[i])

        documento.save(ruta_de_destino + "/" + os.path.basename(rutas_de_archivos[int(j)]))

        control_progreso_impresion()

    boton_de_pdf.state(["!disabled"])

# Imprimir DOCX en PDF, se atrapa "convert" para evitar impresión que evita el funcionamiento de dcox2pdf al pasar a EXE:

def convertir_a_pdf():

    sys.stderr = open("consoleoutput.log", "w")

    convert(ruta_de_destino)

    sys.stderr.close()

    os.remove("consoleoutput.log")

# Definición de botones:

boton_de_pegado = ttk.Button(
    root,
    text='Pegar datos',
    command=pegar_datos
)

boton_de_pegado.grid(row=0, column=0, sticky="WE", ipadx=2.5, ipady=5, padx=2.5, pady=2.5)

boton_de_seleccionar_varios = ttk.Button(
    root,
    text='Seleccionar documentos',
    state="disabled",
    command=seleccionar_varios_archivos
)

boton_de_seleccionar_varios.grid(row=1, column=0, sticky="WE", ipadx=2.5, ipady=5, padx=2.5, pady=2.5)

boton_de_destino = ttk.Button(
    root,
    text="Seleccionar destino",
    state="disabled",
    command=seleccionar_destino
)

boton_de_destino.grid(row=2, column=0, sticky="WE", ipadx=2.5, ipady=5, padx=2.5, pady=2.5)

boton_de_guardados = ttk.Button(
    root,
    text='Guardar documentos',
    state="disabled",
    command=editar_varios_documentos
)

boton_de_guardados.grid(row=3, column=0, sticky="WE", ipadx=2.5, ipady=5, padx=2.5, pady=2.5)

boton_de_pdf = ttk.Button(
    root,
    text="Generar PDF",
    state="disabled",
    command=convertir_a_pdf
)

boton_de_pdf.grid(row=4, column=0, sticky="WE", ipadx=2.5, ipady=5, padx=2.5, pady=2.5)

# Barra de progreso:

progreso_impresion = ttk.Progressbar(
    root,
    orient="vertical",
    mode="determinate"
)

progreso_impresion.grid(row=0, column=1, sticky="NS", ipadx=2.5, ipady=5, padx=2.5, pady=2.5, rowspan=3)

estado_progreso = ttk.Label(
    root,
    text="0%",
)

estado_progreso.grid(row=3, column=1, sticky="NS", ipadx=2.5, ipady=5, padx=2.5, pady=2.5)

# Final GUI:

root.mainloop()