From c62a8c7d16b617b1480f23af743c020e642dbf66 Mon Sep 17 00:00:00 2001 From: Emersonjsc Date: Sun, 6 Jul 2025 23:47:48 -0300 Subject: [PATCH] Campo de busca --- visao/componentes/dialogo_editar_adocao.py | 84 ++++++++++++++++++++++ visao/componentes/dialogo_nova_adocao.py | 9 ++- visao/frames/frame_adocao.py | 44 +++++++++++- visao/frames/frame_pessoa.py | 40 ++++++++++- visao/frames/frame_pet.py | 44 +++++++++++- 5 files changed, 211 insertions(+), 10 deletions(-) create mode 100644 visao/componentes/dialogo_editar_adocao.py diff --git a/visao/componentes/dialogo_editar_adocao.py b/visao/componentes/dialogo_editar_adocao.py new file mode 100644 index 0000000..257a95f --- /dev/null +++ b/visao/componentes/dialogo_editar_adocao.py @@ -0,0 +1,84 @@ +import tkinter as tk +from tkinter import ttk, messagebox +from datetime import datetime + +class DialogoEditarAdocao(tk.Toplevel): + def __init__(self, parent, bd, adocao_atual): + super().__init__(parent) + self.bd = bd + self.adocao_atual = adocao_atual + self.result = None + + self.title("Editar Adoção") + self.geometry("400x450") + self.configure(bg="#1e1e1e") + self.transient(parent) + self.grab_set() + + # 1. Obter os IDs de todos os pets que já foram adotados + ids_pets_adotados = set() + for adocao in self.bd.adocoes.listar_todos(): + for item in adocao.itens: + ids_pets_adotados.add(item.pet.id) + + # 2. Obter os IDs dos pets que pertencem a ESTA adoção específica + ids_pets_desta_adocao = {item.pet.id for item in self.adocao_atual.itens} + + # 3. A lista de pets para edição inclui os disponíveis E os que já estão nesta adoção + self.pessoas = self.bd.pessoas.listar_todos() + self.pets = [p for p in self.bd.pets.listar_todos() if p.id not in ids_pets_adotados or p.id in ids_pets_desta_adocao] + + self._criar_widgets() + self._preencher_dados() + + def _criar_widgets(self): + main_frame = tk.Frame(self, bg="#1e1e1e", padx=20, pady=20) + main_frame.pack(fill="both", expand=True) + + tk.Label(main_frame, text="Adotante:", bg="#1e1e1e", fg="white").pack(anchor="w") + self.combo_pessoas = ttk.Combobox(main_frame, values=[p.nome for p in self.pessoas], state="readonly") + self.combo_pessoas.pack(fill="x", pady=(0, 10)) + + tk.Label(main_frame, text="Selecione os Pets (use Ctrl ou Shift para múltiplos):", bg="#1e1e1e", fg="white").pack(anchor="w") + + pet_frame = tk.Frame(main_frame) + pet_frame.pack(fill="both", expand=True, pady=(0, 10)) + + self.listbox_pets = tk.Listbox(pet_frame, selectmode=tk.MULTIPLE, bg="#2c2c2c", fg="white", selectbackground="#1f6aa5") + for pet in self.pets: + self.listbox_pets.insert(tk.END, f"{pet.nome} ({pet.especie})") + + scrollbar = ttk.Scrollbar(pet_frame, orient="vertical", command=self.listbox_pets.yview) + self.listbox_pets.configure(yscrollcommand=scrollbar.set) + + self.listbox_pets.pack(side="left", fill="both", expand=True) + scrollbar.pack(side="right", fill="y") + + tk.Label(main_frame, text="Data da Adoção (DD-MM-AAAA):", bg="#1e1e1e", fg="white").pack(anchor="w") + self.entry_data = tk.Entry(main_frame, bg="#2c2c2c", fg="white", insertbackground="white") + self.entry_data.pack(fill="x", pady=(0, 20)) + + botoes_frame = tk.Frame(main_frame, bg="#1e1e1e") + botoes_frame.pack(fill="x") + + btn_ok = tk.Button(botoes_frame, text="Salvar", command=self._on_ok, bg="#4CAF50", fg="white", relief="flat") + btn_ok.pack(side="right", padx=(10, 0)) + + btn_cancelar = tk.Button(botoes_frame, text="Cancelar", command=self.destroy, bg="#f44336", fg="white", relief="flat") + btn_cancelar.pack(side="right") + + def _preencher_dados(self): + try: + idx_pessoa = [p.id for p in self.pessoas].index(self.adocao_atual.adotante.id) + self.combo_pessoas.current(idx_pessoa) + except (ValueError, AttributeError): + pass + + ids_pets_adotados = {item.pet.id for item in self.adocao_atual.itens} + for i, pet in enumerate(self.pets): + if pet.id in ids_pets_adotados: + self.listbox_pets.selection_set(i) + + if self.adocao_atual.itens: + # Corrigido: Pega a data do primeiro item como referência + self.entry_data.insert(0, self.adocao_atual.itens[0].data) \ No newline at end of file diff --git a/visao/componentes/dialogo_nova_adocao.py b/visao/componentes/dialogo_nova_adocao.py index d6b5718..b79c15c 100644 --- a/visao/componentes/dialogo_nova_adocao.py +++ b/visao/componentes/dialogo_nova_adocao.py @@ -14,8 +14,15 @@ class DialogoNovaAdocao(tk.Toplevel): self.transient(parent) self.grab_set() + # 1. Obter os IDs de todos os pets que já foram adotados + ids_pets_adotados = set() + for adocao in self.bd.adocoes.listar_todos(): + for item in adocao.itens: + ids_pets_adotados.add(item.pet.id) + + # 2. Filtrar a lista de pets para mostrar apenas os disponíveis self.pessoas = self.bd.pessoas.listar_todos() - self.pets = self.bd.pets.listar_todos() + self.pets = [p for p in self.bd.pets.listar_todos() if p.id not in ids_pets_adotados] self._criar_widgets() diff --git a/visao/frames/frame_adocao.py b/visao/frames/frame_adocao.py index 5caaf1c..c8e2193 100644 --- a/visao/frames/frame_adocao.py +++ b/visao/frames/frame_adocao.py @@ -24,6 +24,22 @@ class FrameAdocao(tk.Frame): ) titulo_label.pack(pady=20) + # Frame de busca + busca_frame = tk.Frame(self, bg="#1e1e1e") + busca_frame.pack(pady=5, padx=20, fill="x") + + tk.Label(busca_frame, text="Buscar por ID, Adotante ou Pet:", bg="#1e1e1e", fg="white").pack(side="left", padx=(0, 5)) + self.entry_busca = tk.Entry(busca_frame, bg="#2c2c2c", fg="white", insertbackground="white", width=40) + self.entry_busca.pack(side="left", fill="x", expand=True) + self.entry_busca.bind("", lambda event: self._realizar_busca()) + + btn_buscar = tk.Button(busca_frame, text="Buscar", command=self._realizar_busca, bg="#1f6aa5", fg="white", relief="flat") + btn_buscar.pack(side="left", padx=5) + + btn_limpar = tk.Button(busca_frame, text="Limpar", command=self._limpar_busca, bg="#555555", fg="white", relief="flat") + btn_limpar.pack(side="left", padx=5) + + # Estilo da Treeview style = ttk.Style() style.theme_use("default") style.configure("Treeview", @@ -81,13 +97,16 @@ class FrameAdocao(tk.Frame): ) btn_adicionar.pack(side="left", padx=5) - def popular_treeview(self): + def popular_treeview(self, lista_adocoes=None): # Limpa a árvore for i in self.tree.get_children(): self.tree.delete(i) + if lista_adocoes is None: + lista_adocoes = self.bd.adocoes.listar_todos() + # Popula com os dados de adoções do banco de dados - for adocao in self.bd.adocoes.listar_todos(): + for adocao in lista_adocoes: # Nó pai para a adoção adocao_node = self.tree.insert( "", "end", @@ -131,4 +150,23 @@ class FrameAdocao(tk.Frame): self.popular_treeview() messagebox.showinfo("Sucesso", "Adoção registrada com sucesso.") except Exception as e: - messagebox.showerror("Erro", f"Ocorreu um erro ao registrar a adoção:\n{e}") \ No newline at end of file + messagebox.showerror("Erro", f"Ocorreu um erro ao registrar a adoção:\n{e}") + + def _realizar_busca(self): + termo_busca = self.entry_busca.get().strip().lower() + if not termo_busca: + self.popular_treeview() + return + + todas_adocoes = self.bd.adocoes.listar_todos() + resultados = [ + adocao for adocao in todas_adocoes if + termo_busca in str(adocao.id) or + termo_busca in adocao.adotante.nome.lower() or + any(termo_busca in item.pet.nome.lower() or termo_busca in item.pet.especie.lower() for item in adocao.itens) + ] + self.popular_treeview(resultados) + + def _limpar_busca(self): + self.entry_busca.delete(0, tk.END) + self.popular_treeview() \ No newline at end of file diff --git a/visao/frames/frame_pessoa.py b/visao/frames/frame_pessoa.py index ade9916..528746a 100644 --- a/visao/frames/frame_pessoa.py +++ b/visao/frames/frame_pessoa.py @@ -19,6 +19,22 @@ class FramePessoas(tk.Frame): ) titulo_label.pack(pady=20) + # Frame de busca + busca_frame = tk.Frame(self, bg="#1e1e1e") + busca_frame.pack(pady=5, padx=20, fill="x") + + tk.Label(busca_frame, text="Buscar por ID ou Nome:", bg="#1e1e1e", fg="white").pack(side="left", padx=(0, 5)) + self.entry_busca = tk.Entry(busca_frame, bg="#2c2c2c", fg="white", insertbackground="white", width=40) + self.entry_busca.pack(side="left", fill="x", expand=True) + self.entry_busca.bind("", lambda event: self._realizar_busca()) + + btn_buscar = tk.Button(busca_frame, text="Buscar", command=self._realizar_busca, bg="#1f6aa5", fg="white", relief="flat") + btn_buscar.pack(side="left", padx=5) + + btn_limpar = tk.Button(busca_frame, text="Limpar", command=self._limpar_busca, bg="#555555", fg="white", relief="flat") + btn_limpar.pack(side="left", padx=5) + + # Estilo da Treeview style = ttk.Style() style.theme_use("default") style.configure("Treeview", @@ -100,10 +116,14 @@ class FramePessoas(tk.Frame): ) btn_apagar.pack(side="left", padx=5) - def popular_treeview(self): + def popular_treeview(self, lista_pessoas=None): for i in self.tree.get_children(): self.tree.delete(i) - for pessoa in self.bd.pessoas.listar_todos(): + + if lista_pessoas is None: + lista_pessoas = self.bd.pessoas.listar_todos() + + for pessoa in lista_pessoas: self.tree.insert("", "end", values=(pessoa.id, pessoa.nome)) def adicionar_pessoa(self): @@ -150,4 +170,18 @@ class FramePessoas(tk.Frame): if messagebox.askyesno("Confirmar", f"Tem certeza que deseja apagar '{nome_pessoa}'?"): self.bd.pessoas.remover(id_pessoa) self.popular_treeview() - messagebox.showinfo("Sucesso", "Pessoa apagada com sucesso.") \ No newline at end of file + messagebox.showinfo("Sucesso", "Pessoa apagada com sucesso.") + + def _realizar_busca(self): + termo_busca = self.entry_busca.get().strip().lower() + if not termo_busca: + self.popular_treeview() + return + + todas_pessoas = self.bd.pessoas.listar_todos() + resultados = [p for p in todas_pessoas if termo_busca in str(p.id) or termo_busca in p.nome.lower()] + self.popular_treeview(resultados) + + def _limpar_busca(self): + self.entry_busca.delete(0, tk.END) + self.popular_treeview() \ No newline at end of file diff --git a/visao/frames/frame_pet.py b/visao/frames/frame_pet.py index 55ef103..ac00c97 100644 --- a/visao/frames/frame_pet.py +++ b/visao/frames/frame_pet.py @@ -21,6 +21,21 @@ class FramePet(tk.Frame): ) titulo_label.pack(pady=20) + # Frame de busca + busca_frame = tk.Frame(self, bg="#1e1e1e") + busca_frame.pack(pady=5, padx=20, fill="x") + + tk.Label(busca_frame, text="Buscar por ID, Nome ou Espécie:", bg="#1e1e1e", fg="white").pack(side="left", padx=(0, 5)) + self.entry_busca = tk.Entry(busca_frame, bg="#2c2c2c", fg="white", insertbackground="white", width=40) + self.entry_busca.pack(side="left", fill="x", expand=True) + self.entry_busca.bind("", lambda event: self._realizar_busca()) + + btn_buscar = tk.Button(busca_frame, text="Buscar", command=self._realizar_busca, bg="#1f6aa5", fg="white", relief="flat") + btn_buscar.pack(side="left", padx=5) + + btn_limpar = tk.Button(busca_frame, text="Limpar", command=self._limpar_busca, bg="#555555", fg="white", relief="flat") + btn_limpar.pack(side="left", padx=5) + # Estilo para a Treeview style = ttk.Style() style.theme_use("default") @@ -108,10 +123,14 @@ class FramePet(tk.Frame): ) btn_apagar.pack(side="left", padx=5) - def popular_treeview(self): + def popular_treeview(self, lista_pets=None): for i in self.tree.get_children(): self.tree.delete(i) - for pet in self.bd.pets.listar_todos(): + + if lista_pets is None: + lista_pets = self.bd.pets.listar_todos() + + for pet in lista_pets: self.tree.insert("", "end", values=(pet.id, pet.nome, pet.especie)) def adicionar_pet(self): @@ -160,4 +179,23 @@ class FramePet(tk.Frame): if messagebox.askyesno("Confirmar", f"Tem certeza que deseja apagar '{nome_pet}'?"): self.bd.pets.remover(id_pet) self.popular_treeview() - messagebox.showinfo("Sucesso", "Pet apagada com sucesso.") \ No newline at end of file + messagebox.showinfo("Sucesso", "Pet apagada com sucesso.") + + def _realizar_busca(self): + termo_busca = self.entry_busca.get().strip().lower() + if not termo_busca: + self.popular_treeview() + return + + todos_pets = self.bd.pets.listar_todos() + resultados = [ + p for p in todos_pets if + termo_busca in str(p.id) or + termo_busca in p.nome.lower() or + termo_busca in p.especie.lower() + ] + self.popular_treeview(resultados) + + def _limpar_busca(self): + self.entry_busca.delete(0, tk.END) + self.popular_treeview() \ No newline at end of file