diff --git a/obs.txt b/obs.txt new file mode 100644 index 0000000..e1fc4f4 --- /dev/null +++ b/obs.txt @@ -0,0 +1,13 @@ +- fazer desinstalador +- fazer modulo para help q consulta a docstring + +- verificar o tipo do retorno do select no store na hr de converter +- transformar classe Tipo global +- criar container Main das janelas direto no MJanela +- criar variaveis globais no __init__ do src +- mover definir_incone de dentro da classe TKUtils para classe MJanela como cnf +- criar schema para model, uma classe com todos os metodos e atributos padroes +- desativar botão de cadastro de algo quando ja tiver uma janela aberta +- fazer obter do modelo retornar apenas o valor achado e nao uma lista +- levar validar data para Utils +- remover redundancia de nomes como "data_apresentacao" para "data" diff --git a/run.py b/run.py index d2cefb1..e14bd11 100644 --- a/run.py +++ b/run.py @@ -1,4 +1,4 @@ -from src.utils import Utils +from src.utils.env import Env from src.view import View from src.model import Model @@ -8,16 +8,16 @@ if __name__ == '__main__': - if Utils.verificar_modo_teste(): - tests = Tests() - tests.iniciar() - else: - controller = Controller() - view = View(controller=controller) - model = Model(controller=controller) + if Env.modo_teste(): + Tests().iniciar() + exit() - controller.segundo_init(model=model, view=view) - view.segundo_init() - model.segundo_init() + view = View() + model = Model() + controller = Controller() - controller.iniciar() + view.iniciar() + model.iniciar() + controller.iniciar(view=view, model=model) + + view.mainloop() diff --git a/src/__init__.py b/src/__init__.py index e69de29..6ff06d1 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -0,0 +1,9 @@ +""".""" + +from src.utils.caminho import Caminho + + +ARQUIVO_CSV = Caminho.ate('src/store/file/alunos.csv') +BANCO_DE_DADOS = Caminho.ate('src/store/file/bd.sqlite') + +ICONE_MAIN = Caminho.ate('src/assets/icone_main.png') diff --git a/src/assets/icone.png b/src/assets/icone_main.png similarity index 100% rename from src/assets/icone.png rename to src/assets/icone_main.png diff --git a/src/controller/__init__.py b/src/controller/__init__.py index 1e90b6d..6b5c3ce 100644 --- a/src/controller/__init__.py +++ b/src/controller/__init__.py @@ -1,58 +1,45 @@ """Controller Root.""" from src.controller.navbar import Navbar + from src.controller.home import Home from src.controller.aluno import Aluno from src.controller.grupo import Grupo -from src.controller.atividade import Atividade from src.controller.sobre import Sobre +from src.controller.tarefa import Tarefa +from src.controller.atividade import Atividade +from src.controller.apresentacao import Apresentacao class Controller(object): - """Classe responsavel por gerenciar o fluxo de execucao da aplicacao. - - Attributes: - view (View:obj): Objeto root View. - model (Model:obj): Objeto root Model. - - navbar (Controller:Navbar:obj): Padrao None. - home (Controller:Home:obj): Padrao None. - aluno (Controller:Aluno:obj): Padrao None. - grupo (Controller:Grupo:obj): Padrao None. - atividade (Controller:Atividade:obj): Padrao None. - sobre (Controller:Sobre:obj): Padrao None. - """ + """Classe responsavel por gerenciar o fluxo de execucao da aplicacao.""" def __init__(self) -> None: """Contrutor padrao, declara os atributos da classe.""" self.view = None self.model = None - self.navbar = None - self.home = None - self.aluno = None - self.grupo = None - self.atividade = None - self.sobre = None + self.navbar = Navbar() - def segundo_init(self, model: object, view: object) -> None: - """Segundo contrutor, recebe os objetos Model e View instanciados. + self.home = Home() + self.aluno = Aluno() + self.grupo = Grupo() + self.sobre = Sobre() + self.tarefa = Tarefa() + self.atividade = Atividade() + self.apresentacao = Apresentacao() - Args: - model (Model:obj): Objeto root Model - view (View:obj): Objeto root View - """ + def iniciar(self, view, model) -> None: + """Instancia/cria os sub-objetos e inicializa Model root e View root.""" self.view = view self.model = model - def iniciar(self) -> None: - """Instancia/cria os sub-objetos e inicializa Model root e View root.""" - self.navbar = Navbar(controller=self) - self.home = Home(controller=self) - self.aluno = Aluno(controller=self) - self.atividade = Atividade(controller=self) - self.grupo = Grupo(controller=self) - self.sobre = Sobre(controller=self) - - self.model.iniciar() - self.view.iniciar() + self.navbar.iniciar(controller=self) + + self.home.iniciar(controller=self) + self.aluno.iniciar(controller=self) + self.grupo.iniciar(controller=self) + self.sobre.iniciar(controller=self) + self.tarefa.iniciar(controller=self) + self.atividade.iniciar(controller=self) + self.apresentacao.iniciar(controller=self) diff --git a/src/controller/aluno/__init__.py b/src/controller/aluno/__init__.py index 301d379..2e85294 100644 --- a/src/controller/aluno/__init__.py +++ b/src/controller/aluno/__init__.py @@ -1,38 +1,22 @@ """Controller do Aluno.""" -from src.controller.aluno.eventos import Eventos +from src.controller.aluno.actions import Actions +from src.controller.aluno.listagem import Listagem -class Aluno(object): - """Classe responsavel por controlar componentes relacionados ao aluno. - Attributes: - view (View:obj): Objeto root View - model (Model:obj): Objeto root Model - """ +class Aluno(Actions, Listagem): + """Classe responsavel por controlar componentes relacionados ao aluno.""" - def __init__(self, controller: object) -> None: - """Construtor padrao, define define os atributos view e model. + def __init__(self) -> None: + """Construtor padrao, define define os atributos view e model.""" + Actions.__init__(self) + Listagem.__init__(self) - Args: - controller (Controller:obj): Objeto root Controller - """ + def iniciar(self, controller: object): self.view = controller.view self.model = controller.model - self.eventos = Eventos(controller=self) + self.cadastrar_tarefa = controller.tarefa.cadastrar - def carregar_lista_de_alunos(self) -> None: - """Busca os alunos no model e cria os componentes visuais.""" - for aluno in self.model.aluno.alunos: - self.view.aluno.lista.adicionar(nome_do_aluno=aluno) - - def elemento_montado(self) -> None: - """Disparado quando o container Aluno for criado. - - - Inicia o componente Aluno - - Carrega a lista de alunos na View - """ - self.view.aluno.iniciar() - self.carregar_lista_de_alunos() - - self.view.aluno.desativar() + Actions.configurar(self) + Listagem.configurar(self) diff --git a/src/controller/aluno/actions.py b/src/controller/aluno/actions.py new file mode 100644 index 0000000..36d6665 --- /dev/null +++ b/src/controller/aluno/actions.py @@ -0,0 +1,22 @@ +class Actions(object): + + def __init__(self): + pass + + def sortear(self, evt): + self.view.ocultar_container_ativo() + self.view.mostrar_container('home') + + self.cadastrar_tarefa(evt=None) + + def arquivo(self, evt) -> None: + """Evento click do botao para carregar arquivo csv.""" + pass + + def configurar(self): + actions = self.view.aluno.actions.subelemento + + actions.arquivo.evento[''] = self.arquivo + actions.sortear.evento[''] = self.sortear + + self.view.aluno.actions.carregar_eventos() diff --git a/src/controller/aluno/eventos.py b/src/controller/aluno/eventos.py deleted file mode 100644 index 27d9377..0000000 --- a/src/controller/aluno/eventos.py +++ /dev/null @@ -1,36 +0,0 @@ -class Eventos(object): - - def __init__(self, controller): - self.view = controller.view - self.model = controller.model - - def sortear(self, valor=''): - aluno = valor - - if not self.model.aluno.alunos: - erro = 'Lista de Alunos vazia' - self.view.criar_janela_de_erro(erro=erro) - return - - if not self.model.atividade.atividades: - erro = 'Lista de Atividades vazia' - self.view.criar_janela_de_erro(erro=erro) - return - - if not aluno: - aluno = self.model.aluno.sortear() - - atividade = self.model.atividade.sortear() - if not atividade: - erro = 'Todas as Atividades já estão em uso' - self.view.criar_janela_de_erro(erro=erro) - return - - self.view.criar_janela_de_sorteio(atividade=atividade, aluno=aluno) - - def carregar_arquivo(self) -> None: - """Evento click do botao para carregar arquivo csv.""" - pass - - def expandir_label(self, evento, elemento): - pass diff --git a/src/controller/aluno/listagem.py b/src/controller/aluno/listagem.py new file mode 100644 index 0000000..765e7b0 --- /dev/null +++ b/src/controller/aluno/listagem.py @@ -0,0 +1,26 @@ +class Listagem(object): + + def __init__(self): + pass + + def sortear_(self, evt, aluno): + self.model.aluno.aluno = aluno + + self.view.ocultar_container_ativo() + self.view.mostrar_container('home') + + self.cadastrar_tarefa(evt=None) + + def expandir_label(self, evt, elemento): + pass + + def configurar_(self, elemento): + elemento.subelemento.sortear.evento[''] =\ + lambda evt: self.sortear_(evt, aluno=elemento.dados) + + elemento.carregar_eventos() + + def configurar(self): + for aluno in self.model.aluno.alunos: + elemento = self.view.aluno.listagem.adicionar(nome_do_aluno=aluno) + self.configurar_(elemento) diff --git a/src/controller/apresentacao/__init__.py b/src/controller/apresentacao/__init__.py new file mode 100644 index 0000000..66b1716 --- /dev/null +++ b/src/controller/apresentacao/__init__.py @@ -0,0 +1,24 @@ +"""Controller da Home e da Apresentacao.""" + +from src.controller.apresentacao.listagem import Listagem +from src.controller.apresentacao.cadastro import Cadastro + + +class Apresentacao(Listagem, Cadastro): + """Classe responsavel por gerenciar Home de View e Apresentacao de Model.""" + + def __init__(self) -> None: + """Construtor padrao, define os atributos view e model.""" + Listagem.__init__(self) + Cadastro.__init__(self) + + def iniciar(self, controller: object): + self.view = controller.view + self.model = controller.model + + Listagem.configurar(self) + + def cadastrar(self, evt) -> None: + """Evento click do botao cadastrar na actions.""" + self.view.home.cadastro_apresentacao.iniciar() + Cadastro.configurar(self) diff --git a/src/controller/apresentacao/cadastro.py b/src/controller/apresentacao/cadastro.py new file mode 100644 index 0000000..df25b1e --- /dev/null +++ b/src/controller/apresentacao/cadastro.py @@ -0,0 +1,57 @@ +class Cadastro(object): + + def __init__(self): + pass + + def confirmar(self, evt=None) -> None: + """Evento click do botao confirmar no formulario de cadastro.""" + formulario = self.view.home.cadastro_apresentacao.obter_campos() + + erro = self.model.apresentacao.validar(formulario) + if erro: + return self.view.janela_erro.iniciar(erro) + + erro = 'Todos os Grupos estão em uso' + grupo = self.model.grupo.sortear() + if not grupo: + return self.view.janela_erro.iniciar(erro) + + id_grupo = grupo['id_grupo'] + formulario['id_grupo'] = id_grupo + + erro = 'Todas as Atividades estão em uso' + atividade = self.model.atividade.sortear() + if not atividade: + self.view.janela_erro.iniciar(erro) + return + + id_atividade = atividade['id_atividade'] + formulario['id_atividade'] = id_atividade + + apresentacao = self.model.apresentacao.cadastrar(formulario) + + self.model.grupo.atualizar(id_grupo, campos={'em_uso': 1}) + self.model.atividade.atualizar(id_atividade, campos={'em_uso': 1}) + + self.view.home.cadastro_apresentacao.fechar() + + elemento = self.view.home.listagem.adicionar(apresentacao) + self.configurar_(elemento) + + self.view.grupo.listagem.desativar(id_grupo) + self.view.atividade.listagem.desativar(id_atividade) + + def cancelar(self, evt=None) -> None: + """Evento click do botao cancelar no formulario de cadastro.""" + self.view.home.cadastro_apresentacao.fechar() + + def configurar(self) -> None: + cadastro = self.view.home.cadastro_apresentacao.subelemento + + cadastro.data.input.evento[''] = self.confirmar + cadastro.duracao.input.evento[''] = self.confirmar + + cadastro.cancelar.defs.mcnf['command'] = self.cancelar + cadastro.confirmar.defs.mcnf['command'] = self.confirmar + + self.view.home.cadastro_apresentacao.carregar_eventos() diff --git a/src/controller/apresentacao/listagem.py b/src/controller/apresentacao/listagem.py new file mode 100644 index 0000000..7028548 --- /dev/null +++ b/src/controller/apresentacao/listagem.py @@ -0,0 +1,45 @@ +class Listagem(object): + + def __init__(self): + pass + + def remover(self, evt, id_apresentacao: str) -> None: + """Evento click do botao remover na lista de apresentacoes.""" + ids = self.model.apresentacao.remover(id_apresentacao) + self.view.home.listagem.remover(id_apresentacao, 'id_apresentacao') + + self.model.grupo.atualizar(ids['grupo'], campos={'em_uso': 0}) + self.model.atividade.atualizar(ids['atividade'], campos={'em_uso': 0}) + + self.view.grupo.listagem.ativar(ids['grupo']) + self.view.atividade.listagem.ativar(ids['atividade']) + + def expandir_recolher(self, evt, elemento): + if elemento.subelemento.secundario.defs.visivel: + elemento.subelemento.secundario.ocultar() + else: + elemento.subelemento.secundario.mostrar() + + def configurar_(self, elemento): + primario = elemento.subelemento.primario + secundario = elemento.subelemento.secundario + + primario.subelemento.label.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + + primario.subelemento.remover.evento[''] =\ + lambda evt: self.remover(evt, elemento.dados['id_apresentacao']) + + secundario.subelemento.cadastro.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + + secundario.subelemento.apresentacao.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + + elemento.carregar_eventos() + + def configurar(self) -> None: + """Carrega as apresentacoes na lista de eventos da Home na View.""" + for apresentacao in self.model.apresentacao.apresentacoes: + elemento = self.view.home.listagem.adicionar(apresentacao) + self.configurar_(elemento) diff --git a/src/controller/atividade/__init__.py b/src/controller/atividade/__init__.py index 84fc776..f3b2f36 100644 --- a/src/controller/atividade/__init__.py +++ b/src/controller/atividade/__init__.py @@ -1,38 +1,28 @@ """Controller da Atividade.""" -from src.controller.atividade.eventos import Eventos +from src.controller.atividade.actions import Actions +from src.controller.atividade.listagem import Listagem +from src.controller.atividade.cadastro import Cadastro -class Atividade(object): - """Classe responsavel por gerenciar os componentes de Atividade. - Attributes: - view (View:obj): Objeto root View - model (Mode:obj): Objeto root Model - """ +class Atividade(Actions, Listagem, Cadastro): + """Classe responsavel por gerenciar os componentes de Atividade.""" - def __init__(self, controller: object) -> None: - """Classe responsavel por gerenciar os componentes de Atividade. + def __init__(self) -> None: + """Classe responsavel por gerenciar os componentes de Atividade.""" + Actions.__init__(self) + Listagem.__init__(self) + Cadastro.__init__(self) - Args: - controller (Controller:obj): Objeto Pai - """ + def iniciar(self, controller: object): self.view = controller.view self.model = controller.model + self.cadastrar_apresentacao = controller.apresentacao.cadastrar - self.eventos = Eventos(controller=self) + Actions.configurar(self) + Listagem.configurar(self) - def carregar_atividades(self) -> None: - """Busca as atividades no Model e cria os componentes visuais.""" - for atv in self.model.atividade.atividades: - self.view.atividade.lista.adicionar(atividade=atv) - - def elemento_montado(self) -> None: - """Disparado quando o componente Atividade da View e montado. - - - Inicia o componente/container visual da Atividade - - Carrega a listagem das atividades na view - """ - self.view.atividade.iniciar() - self.carregar_atividades() - - self.view.atividade.desativar() + def cadastrar(self, evt) -> None: + """Evento click do botao cadastrar.""" + self.view.atividade.cadastro.iniciar() + Cadastro.configurar(self) diff --git a/src/controller/atividade/actions.py b/src/controller/atividade/actions.py new file mode 100644 index 0000000..3c0daf2 --- /dev/null +++ b/src/controller/atividade/actions.py @@ -0,0 +1,19 @@ +class Actions(object): + + def __init__(self): + pass + + def sortear(self, evt): + self.view.ocultar_container_ativo() + self.view.mostrar_container('home') + + self.cadastrar_apresentacao(evt=None) + + def configurar(self) -> None: + """Disparado quando o componente Atividade da View e montado.""" + actions = self.view.atividade.actions + + actions.subelemento.sortear.evento[''] = self.sortear + actions.subelemento.cadastrar.evento[''] = self.cadastrar + + actions.carregar_eventos() diff --git a/src/controller/atividade/cadastro.py b/src/controller/atividade/cadastro.py new file mode 100644 index 0000000..eb3b91b --- /dev/null +++ b/src/controller/atividade/cadastro.py @@ -0,0 +1,33 @@ +class Cadastro(object): + + def __init__(self): + pass + + def confirmar(self, evt=None) -> None: + """Evento click do botao confirmar cadastro.""" + formulario = self.view.atividade.cadastro.obter_campos() + + erro = self.model.atividade.validar(formulario) + if erro: + return self.view.janela_erro.iniciar(erro) + + atividade = self.model.atividade.cadastrar(atividade=formulario) + self.view.atividade.cadastro.fechar() + + elemento = self.view.atividade.listagem.adicionar(atividade) + self.configurar_(elemento) + + def cancelar(self, evt=None) -> None: + """Evento click do botao cancelar do formulario.""" + self.view.atividade.cadastro.fechar() + + def configurar(self): + cadastro = self.view.atividade.cadastro.subelemento + + cadastro.titulo.input.evento[''] = self.confirmar + cadastro.descricao.input.evento[''] = self.confirmar + + cadastro.cancelar.defs.mcnf['command'] = self.cancelar + cadastro.confirmar.defs.mcnf['command'] = self.confirmar + + self.view.atividade.cadastro.carregar_eventos() diff --git a/src/controller/atividade/eventos.py b/src/controller/atividade/eventos.py deleted file mode 100644 index 1b4e6ce..0000000 --- a/src/controller/atividade/eventos.py +++ /dev/null @@ -1,70 +0,0 @@ -class Eventos(object): - - def __init__(self, controller): - self.view = controller.view - self.model = controller.model - - def sortear(self, valor): - self.model.atividade.atividade = valor - - self.view.desativar_container_ativo() - - self.view.home.ativar() - self.view.container_ativo = 'home' - - self.view.home.criar_janela_de_cadastro() - - def cadastrar(self) -> None: - """Evento click do botao cadastrar. - - - Cria a janela cadastro. - """ - self.view.atividade.criar_janela_de_cadastro() - - def confirmar_cadastro(self) -> None: - """Evento click do botao confirmar cadastro. - - - Obtem os valores dos campos do formulario - - Verifica se os campos sao validos - - sim -> continua - - nao -> cria janela de erro e para o evento - - Salva atividade - - Destroi janela de cadastro - - Destroi listagem de atividades - - Carrega nova listade de atividades - """ - form = self.view.atividade.janela_de_cadastro.obter_campos() - - erro = self.model.atividade.validar_campos(formulario=form) - if erro: - self.view.criar_janela_de_erro(erro=erro) - return - - self.model.atividade.cadastrar_atividade(atividade=form) - self.view.atividade.destruir_janela_de_cadastro() - - atividade = self.model.atividade.atividades[-1] - self.view.atividade.lista.adicionar(atividade=atividade) - - def cancelar_cadastro(self) -> None: - """Evento click do botao cancelar do formulario. - - - Destroi a janela de cadastro - """ - self.view.atividade.destruir_janela_de_cadastro() - - def remover_atividade(self, id_atividade: str) -> None: - """Evento click do botao remover atividade no label da listagem. - - Args: - id_atividade (str): id da atividade que sera removida do bd - - - Remove atividade do id passado como parametro - - Destroi a listagem de atividades na view - - Carrega a nova lista de atividades na view - """ - self.model.atividade.remover_atividade(id_atividade=id_atividade) - self.view.atividade.lista.remover_elemento(id_atividade, 'id_atividade') - - def expandir_label(self, evento, elemento): - self.view.atividade.lista.expandir(elemento=elemento) diff --git a/src/controller/atividade/listagem.py b/src/controller/atividade/listagem.py new file mode 100644 index 0000000..5b4ef65 --- /dev/null +++ b/src/controller/atividade/listagem.py @@ -0,0 +1,47 @@ +class Listagem(object): + + def __init__(self): + pass + + def sortear_(self, evt, atividade): + self.model.atividade.atividade = atividade + + self.view.ocultar_container_ativo() + self.view.mostrar_container('home') + + self.cadastrar_apresentacao(evt=None) + + def remover(self, evt, id_atividade: str) -> None: + """Evento click do botao remover atividade no label da listagem.""" + self.model.atividade.remover(id_atividade) + self.view.atividade.listagem.remover(id_atividade, 'id_atividade') + + def expandir_recolher(self, evt, elemento): + if elemento.subelemento.secundario.defs.visivel: + elemento.subelemento.secundario.ocultar() + else: + elemento.subelemento.secundario.mostrar() + + def configurar_(self, elemento): + primario = elemento.subelemento.primario + secundario = elemento.subelemento.secundario + + primario.subelemento.label.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + primario.subelemento.sortear.evento[''] =\ + lambda evt: self.sortear_(evt, elemento.dados) + primario.subelemento.remover.evento[''] =\ + lambda evt: self.remover(evt, elemento.dados['id_atividade']) + + secundario.subelemento.cadastro.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + secundario.subelemento.descricao.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + + elemento.carregar_eventos() + + def configurar(self) -> None: + """Busca as atividades no Model e cria os componentes visuais.""" + for atividade in self.model.atividade.atividades: + elemento = self.view.atividade.listagem.adicionar(atividade) + self.configurar_(elemento) diff --git a/src/controller/grupo/__init__.py b/src/controller/grupo/__init__.py index 2f8f1e3..3afcf0b 100644 --- a/src/controller/grupo/__init__.py +++ b/src/controller/grupo/__init__.py @@ -1,34 +1,28 @@ """Controller do Grupo.""" -from src.controller.grupo.eventos import Eventos +from src.controller.grupo.actions import Actions +from src.controller.grupo.listagem import Listagem +from src.controller.grupo.cadastro import Cadastro -class Grupo(object): - """Classe responsavel por gerenciar a View e Model relacionados a Grupo. - Attributes: - view (View:obj): Objeto root View - model (Model:obj): Objeto root Model - """ +class Grupo(Actions, Listagem, Cadastro): + """Classe responsavel por gerenciar a View e Model relacionados a Grupo.""" - def __init__(self, controller: object) -> None: - """Construtor padrao, define os atributos view e model.""" + def __init__(self) -> None: + """Classe responsavel por gerenciar os componentes de Atividade.""" + Actions.__init__(self) + Listagem.__init__(self) + Cadastro.__init__(self) + + def iniciar(self, controller: object): self.view = controller.view self.model = controller.model + self.cadastrar_apresentacao = controller.apresentacao.cadastrar - self.eventos = Eventos(controller=self) - - def carregar_grupos(self) -> None: - """Busca os grupos no Model e carrega a listagem dos grupos na View.""" - for grupo in self.model.grupo.grupos: - self.view.grupo.lista.adicionar(grupo=grupo) - - def elemento_montado(self) -> None: - """Disparado quando o componente/container Grupo e montado. - - - Inicia o componente/container Grupo - - Carrea a lista de grupos - """ - self.view.grupo.iniciar() - self.carregar_grupos() + Actions.configurar(self) + Listagem.configurar(self) - self.view.grupo.desativar() + def cadastrar(self, evt) -> None: + """Evento click do botao cadastrar.""" + self.view.grupo.cadastro.iniciar() + Cadastro.configurar(self) diff --git a/src/controller/grupo/actions.py b/src/controller/grupo/actions.py new file mode 100644 index 0000000..1ddce1d --- /dev/null +++ b/src/controller/grupo/actions.py @@ -0,0 +1,18 @@ +class Actions(object): + + def __init__(self): + pass + + def sortear(self, evt) -> None: + self.view.ocultar_container_ativo() + self.view.mostrar_container('home') + + self.cadastrar_apresentacao(evt=None) + + def configurar(self): + actions = self.view.grupo.actions.subelemento + + actions.sortear.evento[''] = self.sortear + actions.cadastrar.evento[''] = self.cadastrar + + self.view.grupo.actions.carregar_eventos() diff --git a/src/controller/grupo/cadastro.py b/src/controller/grupo/cadastro.py new file mode 100644 index 0000000..3507435 --- /dev/null +++ b/src/controller/grupo/cadastro.py @@ -0,0 +1,38 @@ +class Cadastro(object): + + def __init__(self): + pass + + def confirmar(self, evt=None) -> None: + """Evento click do botao confirmar do formulario de cadastro.""" + formulario = self.view.grupo.cadastro.obter_campos() + + erro = self.model.grupo.validar(formulario) + if erro: + return self.view.janela_erro.iniciar(erro) + + grupos = self.model.grupo.gerar(formulario) + for grupo in grupos: + self.model.grupo.cadastrar(grupo) + + index = len(self.model.grupo.grupos) - len(grupos) + for grupo in self.model.grupo.grupos[index:]: + elemento = self.view.grupo.listagem.adicionar(grupo) + self.configurar_(elemento) + + self.view.grupo.cadastro.fechar() + + def cancelar(self, evt=None) -> None: + """Evento click do botao cancelar no formulario.""" + self.view.grupo.cadastro.fechar() + + def configurar(self): + cadastro = self.view.grupo.cadastro.subelemento + + cadastro.nome.input.evento[''] = self.confirmar + cadastro.quantidade.input.evento[''] = self.confirmar + + cadastro.cancelar.defs.mcnf['command'] = self.cancelar + cadastro.confirmar.defs.mcnf['command'] = self.confirmar + + self.view.grupo.cadastro.carregar_eventos() diff --git a/src/controller/grupo/eventos.py b/src/controller/grupo/eventos.py deleted file mode 100644 index a51f72c..0000000 --- a/src/controller/grupo/eventos.py +++ /dev/null @@ -1,76 +0,0 @@ -class Eventos(object): - - def __init__(self, controller): - self.view = controller.view - self.model = controller.model - - def sortear(self, valor: dict) -> None: - self.model.grupo.grupo = valor - - self.view.desativar_container_ativo() - - self.view.home.ativar() - self.view.container_ativo = 'home' - - self.view.home.criar_janela_de_cadastro() - - def cadastrar(self) -> None: - """Evento click do botao cadastrar. - - - Cria a janela de cadastro - """ - self.view.grupo.criar_janela_de_cadastro() - - def confirmar_cadastro(self) -> None: - """Evento click do botao confirmar do formulario de cadastro. - - - Obtem os campos do formulario - - Valida os campos a procura de erros - - se tudo ok -> continua - - se ouver erro -> cria uma janela de erro - - Gera os grupos de acordo com os dados do formulario - - Salva cada grupo gerado - - Destroi janela de cadastro - - Destroi a lista de grupos - - Carrega a lista de grupos - """ - form = self.view.grupo.janela_de_cadastro.obter_campos() - - erro = self.model.grupo.validar_campos(formulario=form) - if erro: - self.view.criar_janela_de_erro(erro=erro) - return - - grupos = self.model.grupo.gerar_grupos(formulario=form) - - for grupo in grupos: - self.model.grupo.cadastrar_grupo(grupo=grupo) - - self.view.grupo.destruir_janela_de_cadastro() - - index = len(self.model.grupo.grupos) - len(grupos) - for grupo in self.model.grupo.grupos[index:]: - self.view.grupo.lista.adicionar(grupo=grupo) - - def cancelar_cadastro(self) -> None: - """Evento click do botao cancelar no formulario. - - - Destroi a janela de cadastro - """ - self.view.grupo.destruir_janela_de_cadastro() - - def remover_grupo(self, id_grupo: str) -> None: - """Evento click do botao remover da lista de grupos. - - Args: - id_grupo (str): ID do grupo que sera removido - - - Remove o grupo do bd - - Destroi a lista de grupos - - Carrega a lista de grupos - """ - self.model.grupo.remover_grupo(id_grupo=id_grupo) - self.view.grupo.lista.remover_elemento(id_grupo, 'id_grupo') - - def expandir_label(self, evento, elemento): - self.view.grupo.lista.expandir(elemento=elemento) diff --git a/src/controller/grupo/listagem.py b/src/controller/grupo/listagem.py new file mode 100644 index 0000000..653d26b --- /dev/null +++ b/src/controller/grupo/listagem.py @@ -0,0 +1,52 @@ +class Listagem(object): + + def __init__(self): + pass + + def sortear_(self, evt, grupo: dict) -> None: + self.model.grupo.grupo = grupo + + self.view.ocultar_container_ativo() + self.view.mostrar_container('home') + + self.cadastrar_apresentacao(evt=None) + + def remover(self, evt, id_grupo: str) -> None: + """Evento click do botao remover da lista de grupos.""" + self.model.grupo.remover(id_grupo) + self.view.grupo.listagem.remover(id_grupo) + + def expandir_recolher(self, evt, elemento): + if not elemento.subelemento.integrantes.lista: + self.view.grupo.listagem.inicializar_integrantes(elemento) + + if elemento.subelemento.secundario.defs.visivel: + elemento.subelemento.secundario.ocultar() + elemento.subelemento.integrantes.ocultar() + else: + elemento.subelemento.secundario.mostrar() + elemento.subelemento.integrantes.mostrar() + + def configurar_(self, elemento): + primario = elemento.subelemento.primario + secundario = elemento.subelemento.secundario + + primario.subelemento.label.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + primario.subelemento.sortear.evento[''] =\ + lambda evt: self.sortear_(evt, elemento.dados) + primario.subelemento.remover.evento[''] =\ + lambda evt: self.remover(evt, elemento.dados['id_grupo']) + + secundario.subelemento.cadastro.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + secundario.subelemento.total.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + + elemento.carregar_eventos() + + def configurar(self) -> None: + """Busca os grupos no Model e carrega a listagem dos grupos na View.""" + for grupo in self.model.grupo.grupos: + elemento = self.view.grupo.listagem.adicionar(grupo) + self.configurar_(elemento) diff --git a/src/controller/home.py b/src/controller/home.py new file mode 100644 index 0000000..900f522 --- /dev/null +++ b/src/controller/home.py @@ -0,0 +1,21 @@ +class Home(object): + + def __init__(self): + pass + + def iniciar(self, controller: object): + self.view = controller.view + self.model = controller.model + + self.cadastrar_tarefa = controller.tarefa.cadastrar + self.cadastrar_apresentacao = controller.apresentacao.cadastrar + + self.configurar() + + def configurar(self) -> None: + actions = self.view.home.actions.subelemento + + actions.tarefa.evento[''] = self.cadastrar_tarefa + actions.cadastrar.evento[''] = self.cadastrar_apresentacao + + self.view.home.actions.carregar_eventos() diff --git a/src/controller/home/__init__.py b/src/controller/home/__init__.py deleted file mode 100644 index bfc42c6..0000000 --- a/src/controller/home/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -"""Controller da Home e da Apresentacao.""" -from src.controller.home.eventos import Eventos - - -class Home(object): - """Classe responsavel por gerenciar Home de View e Apresentacao de Model. - - Attributes: - view (View:obj): Objeto root View - model (Model:obj): Objeto root Model - """ - - def __init__(self, controller: object) -> None: - """Construtor padrao, define os atributos view e model.""" - self.view = controller.view - self.model = controller.model - - self.eventos = Eventos(controller=self) - - def carregar_apresentacoes(self) -> None: - """Carrega as apresentacoes na lista de eventos da Home na View.""" - for apresentacao in self.model.apresentacao.apresentacoes: - self.view.home.lista.adicionar(apresentacao=apresentacao) - - def elemento_montado(self) -> None: - """Disparado quando o componente Home na View e montado. - - - Inicia o container Home - - Carrega a lista de apresentacoes - """ - self.view.home.iniciar() - self.carregar_apresentacoes() - - self.view.home.desativar() diff --git a/src/controller/home/eventos.py b/src/controller/home/eventos.py deleted file mode 100644 index 2612d47..0000000 --- a/src/controller/home/eventos.py +++ /dev/null @@ -1,75 +0,0 @@ -class Eventos(object): - - def __init__(self, controller): - self.view = controller.view - self.model = controller.model - - def cadastrar_apresentacao(self) -> None: - """Evento click do botao cadastrar na actions. - - - Cria a janela de cadastro - """ - self.view.home.criar_janela_de_cadastro() - - def confirmar_cadastro(self) -> None: - """Evento click do botao confirmar no formulario de cadastro.""" - formulario = self.view.home.janela_de_cadastro.obter_campos() - - erro = self.model.apresentacao.validar_cadastro(formulario=formulario) - if erro: - self.view.criar_janela_de_erro(erro=erro) - return - - grupo = self.model.grupo.sortear() - if not grupo: - erro = 'Todos os Grupos estão em uso' - self.view.criar_janela_de_erro(erro=erro) - return - - id_grupo = grupo['id_grupo'] - formulario['id_grupo'] = id_grupo - - atividade = self.model.atividade.sortear() - if not atividade: - erro = 'Todas as Atividades estão em uso' - self.view.criar_janela_de_erro(erro=erro) - return - - id_atividade = atividade['id_atividade'] - formulario['id_atividade'] = id_atividade - - self.model.apresentacao.cadastrar_apresentacao(apresentacao=formulario) - elemento = self.model.apresentacao.apresentacoes[-1] - - self.model.apresentacao.ordenar() - - self.model.grupo.atualizar_uso(id_grupo=id_grupo) - self.model.atividade.atualizar_uso(id_atividade=id_atividade) - - self.view.home.destruir_janela_de_cadastro() - - self.view.home.lista.adicionar(elemento) - - self.view.atividade.lista.mudar_estado(id_atividade, 'id_atividade') - self.view.grupo.lista.mudar_estado(id_grupo, 'id_grupo') - - def cancelar_cadastro(self) -> None: - """Evento click do botao cancelar no formulario de cadastro.""" - self.view.home.destruir_janela_de_cadastro() - - def remover_apresentacao(self, id_apr: str) -> None: - """Evento click do botao remover na lista de apresentacoes.""" - id_atv, id_grupo =\ - self.model.apresentacao.remover_apresentacao(id_apr=id_apr) - - self.view.home.lista.remover_elemento(id_apr, 'id_apresentacao') - - self.view.atividade.lista.mudar_estado(id_atv, 'id_atividade', False) - self.view.grupo.lista.mudar_estado(id_grupo, 'id_grupo', False) - - def ordenar_lista(self) -> None: - """Evento click do botao ordenar na actions.""" - pass - - def expandir_label(self, evento, elemento): - self.view.home.lista.expandir(elemento=elemento) diff --git a/src/controller/navbar.py b/src/controller/navbar.py index 717b299..cf4ddf2 100644 --- a/src/controller/navbar.py +++ b/src/controller/navbar.py @@ -2,108 +2,65 @@ class Navbar(object): - """Classe responsavle por gerenciar View e Model relacionados com Navbar. + """Classe responsavle por gerenciar View e Model relacionados com Navbar.""" - Attributes: - view (View:obj): Objeto root View - """ + def __init__(self) -> None: + """Construtor padrao, define o atributo view.""" + pass - def __init__(self, controller: object) -> None: - """Construtor padrao, define o atributo view. - - Args: - controller (Controller:obj): Objeto root Controller - """ + def iniciar(self, controller: object): self.view = controller.view + self.model = controller.model - def tela_home(self) -> None: - """Evento click do botao home. + self.configurar() - - Verifica se o container Home ja esta ativo - - sim -> para o evento - - nao -> continua - - Destroi container ativo - - Cria container Home - """ + def tela_home(self, evt: object or None=None) -> None: + """Evento click do botao home.""" if self.view.container_ativo == 'home': return - self.view.desativar_container_ativo() - - self.view.home.ativar() - self.view.container_ativo = 'home' - - def tela_aluno(self) -> None: - """Evento click do botao aluno. + self.view.ocultar_container_ativo() + self.view.mostrar_container('home') - - Verifica se o container Aluno ja esta ativo - - sim -> para o evento - - nao -> continua - - Destroi container ativo - - Cria container Aluno - """ + def tela_aluno(self, evt: object or None=None) -> None: + """Evento click do botao aluno.""" if self.view.container_ativo == 'aluno': return - self.view.desativar_container_ativo() - - self.view.aluno.ativar() - self.view.container_ativo = 'aluno' - - def tela_atividade(self) -> None: - """Evento click do botao atividade. + self.view.ocultar_container_ativo() + self.view.mostrar_container('aluno') - - Verifica se o container Atividade ja esta ativo - - sim -> para o evento - - nao -> continua - - Destroi container ativo - - Cria container Atividade - """ + def tela_atividade(self, evt: object or None=None) -> None: + """Evento click do botao atividade.""" if self.view.container_ativo == 'atividade': return - self.view.desativar_container_ativo() + self.view.ocultar_container_ativo() + self.view.mostrar_container('atividade') - self.view.atividade.ativar() - self.view.container_ativo = 'atividade' - - def tela_grupo(self) -> None: - """Evento click do botao grupo. - - - Verifica se o container Grupo ja esta ativo - - sim -> para o evento - - nao -> continua - - Destroi container ativo - - Cria container Grupo - """ + def tela_grupo(self, evt: object or None=None) -> None: + """Evento click do botao grupo.""" if self.view.container_ativo == 'grupo': return - self.view.desativar_container_ativo() - - self.view.grupo.ativar() - self.view.container_ativo = 'grupo' - - def tela_sobre(self) -> None: - """Evento click do botao sobre. + self.view.ocultar_container_ativo() + self.view.mostrar_container('grupo') - - Verifica se o container Sobre ja esta ativo - - sim -> para o evento - - nao -> continua - - Destroi container ativo - - Cria container Sobre - """ + def tela_sobre(self, evt: object or None=None) -> None: + """Evento click do botao sobre.""" if self.view.container_ativo == 'sobre': return - self.view.desativar_container_ativo() + self.view.ocultar_container_ativo() + self.view.mostrar_container('sobre') - self.view.sobre.ativar() - self.view.container_ativo = 'sober' + def configurar(self) -> None: + navbar = self.view.navbar - def elemento_montado(self) -> None: - """Evento disparado quando o componente Navbar e montado. + navbar.subelemento.home.evento[''] = self.tela_home + navbar.subelemento.aluno.evento[''] = self.tela_aluno + navbar.subelemento.grupo.evento[''] = self.tela_grupo + navbar.subelemento.sobre.evento[''] = self.tela_sobre + navbar.subelemento.atividade.evento[''] = self.tela_atividade - - Inicia o componente Navbar - """ - self.view.navbar.iniciar() + navbar.carregar_eventos() diff --git a/src/controller/sobre.py b/src/controller/sobre.py index fa15aa8..beefe41 100644 --- a/src/controller/sobre.py +++ b/src/controller/sobre.py @@ -2,26 +2,18 @@ class Sobre(object): - """Classe responsavel por gerenciar View e Model relacionados a Sobre. + """Classe responsavel por gerenciar View e Model relacionados a Sobre.""" - Attributes: - view (View:obj): Objeto root View - model (Model:obj): Objeto root Model - """ + def __init__(self) -> None: + """Construtor padrao, define view e model.""" + pass - def __init__(self, controller: object) -> None: - """Construtor padrao, define view e model. - - Args: - controller (Controller:obj): Objeto root Controller - """ + def iniciar(self, controller: object): self.view = controller.view self.model = controller.model - def elemento_montado(self) -> None: - """Evento disparado quando o componente Sobre e montado. + self.configurar() - - Inicia o container Sobre - """ - self.view.sobre.iniciar() - self.view.sobre.desativar() + def configurar(self) -> None: + """Evento disparado quando o componente Sobre e montado.""" + pass diff --git a/src/controller/tarefa/__init__.py b/src/controller/tarefa/__init__.py new file mode 100644 index 0000000..0e87210 --- /dev/null +++ b/src/controller/tarefa/__init__.py @@ -0,0 +1,24 @@ +"""Controller da Home e da Apresentacao.""" + +from src.controller.tarefa.listagem import Listagem +from src.controller.tarefa.cadastro import Cadastro + + +class Tarefa(Listagem, Cadastro): + """Classe responsavel por gerenciar Home de View e Apresentacao de Model.""" + + def __init__(self) -> None: + """Construtor padrao, define os atributos view e model.""" + Listagem.__init__(self) + Cadastro.__init__(self) + + def iniciar(self, controller: object): + self.view = controller.view + self.model = controller.model + + Listagem.configurar(self) + + def cadastrar(self, evt) -> None: + """Evento click do botao cadastrar na actions.""" + self.view.home.cadastro_tarefa.iniciar() + Cadastro.configurar(self) diff --git a/src/controller/tarefa/cadastro.py b/src/controller/tarefa/cadastro.py new file mode 100644 index 0000000..b01d425 --- /dev/null +++ b/src/controller/tarefa/cadastro.py @@ -0,0 +1,50 @@ +class Cadastro(object): + + def __init__(self): + pass + + def confirmar(self, evt=None): + formulario = self.view.home.cadastro_tarefa.obter_campos() + + erro = self.model.tarefa.validar(formulario) + if erro: + return self.view.janela_erro.iniciar(erro) + + erro = 'Todas as atividades já estão em uso' + atividade = self.model.atividade.sortear() + if not atividade: + return self.view.janela_erro.iniciar(erro) + + erro = 'Lista de alunos vazia' + aluno = self.model.aluno.sortear() + if not aluno: + return self.view.janela_erro.iniciar(erro) + + id_atividade = atividade['id_atividade'] + + formulario['aluno'] = aluno + formulario['id_atividade'] = id_atividade + + tarefa = self.model.tarefa.cadastrar(formulario) + + elemento = self.view.home.listagem.adicionar(tarefa=tarefa) + self.configurar_(elemento) + + self.model.atividade.atualizar(id_atividade, campos={'em_uso': 1}) + self.view.atividade.listagem.desativar(id_atividade) + + self.view.home.cadastro_tarefa.fechar() + + def cancelar(self, evt=None): + self.view.home.cadastro_tarefa.fechar() + + def configurar(self): + tarefa = self.view.home.cadastro_tarefa.subelemento + + tarefa.data.input.evento[''] = self.confirmar + tarefa.duracao.input.evento[''] = self.confirmar + + tarefa.cancelar.defs.mcnf['command'] = self.cancelar + tarefa.confirmar.defs.mcnf['command'] = self.confirmar + + self.view.home.cadastro_tarefa.carregar_eventos() diff --git a/src/controller/tarefa/listagem.py b/src/controller/tarefa/listagem.py new file mode 100644 index 0000000..fd5c5db --- /dev/null +++ b/src/controller/tarefa/listagem.py @@ -0,0 +1,42 @@ +class Listagem(object): + + def __init__(self): + pass + + def remover(self, evt, id_tarefa: str) -> None: + """Evento click do botao remover na lista de apresentacoes.""" + ids = self.model.tarefa.remover(id_tarefa) + self.view.home.listagem.remover(id_tarefa, chave='id_tarefa') + + self.model.atividade.atualizar(ids['atividade'], campos={'em_uso': 0}) + self.view.atividade.listagem.ativar(ids['atividade']) + + def expandir_recolher(self, evt, elemento): + if elemento.subelemento.secundario.defs.visivel: + elemento.subelemento.secundario.ocultar() + else: + elemento.subelemento.secundario.mostrar() + + def configurar_(self, elemento): + primario = elemento.subelemento.primario + secundario = elemento.subelemento.secundario + + primario.subelemento.label.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + + primario.subelemento.remover.evento[''] =\ + lambda evt: self.remover(evt, elemento.dados['id_tarefa']) + + secundario.subelemento.cadastro.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + + secundario.subelemento.apresentacao.evento[''] =\ + lambda evt: self.expandir_recolher(evt, elemento) + + elemento.carregar_eventos() + + def configurar(self) -> None: + """Carrega as apresentacoes na lista de eventos da Home na View.""" + for tarefa in self.model.tarefa.tarefas: + elemento = self.view.home.listagem.adicionar(tarefa=tarefa) + self.configurar_(elemento) diff --git a/src/model/__init__.py b/src/model/__init__.py index 703f5a1..66fcf33 100644 --- a/src/model/__init__.py +++ b/src/model/__init__.py @@ -10,37 +10,24 @@ from src.model.apresentacao import Apresentacao -class Model: +class Model(object): - def __init__(self, controller): - self.controller = controller - - self.store = None - - self.aluno = None - self.grupo = None - self.sobre = None - self.atividade = None - - self.tarefa = None - self.apresentacao = None - - def segundo_init(self): + def __init__(self): self.store = Store() - self.aluno = Aluno(model=self) - self.grupo = Grupo(model=self) - self.sobre = Sobre(model=self) - self.atividade = Atividade(model=self) + self.aluno = Aluno() + self.grupo = Grupo() + self.sobre = Sobre() + self.atividade = Atividade() - self.tarefa = Tarefa(model=self) - self.apresentacao = Apresentacao(model=self) + self.tarefa = Tarefa() + self.apresentacao = Apresentacao() def iniciar(self): - self.aluno.iniciar() - self.grupo.iniciar() - self.sobre.iniciar() - self.atividade.iniciar() + self.aluno.iniciar(model=self) + self.grupo.iniciar(model=self) + self.sobre.iniciar(model=self) + self.atividade.iniciar(model=self) - self.tarefa.iniciar() - self.apresentacao.iniciar() + self.tarefa.iniciar(model=self) + self.apresentacao.iniciar(model=self) diff --git a/src/model/aluno.py b/src/model/aluno.py index 87f4dce..16ca46e 100644 --- a/src/model/aluno.py +++ b/src/model/aluno.py @@ -1,32 +1,43 @@ -from src.utils import Utils +"""Model de Aluno.""" +from src import ARQUIVO_CSV +from src.model.modelo import Modelo -class Aluno: - def __init__(self, model): - self.model = model - self.store = self.model.store - self.controller = self.model.controller.aluno +class Aluno(Modelo): + """Cuida de todas as operacoes envolvendo Alunos e dados.""" + def __init__(self): + """Inicializa a classe Modelo e configura os atributos.""" + super().__init__() + + self.aluno = None self.alunos = [] - def iniciar(self): - self.ler_arquivo() + def iniciar(self, model): + """Inicializa os metodos das classes Aluno e Modelo.""" + super().iniciar(model) + + self.ler_arquivo_csv() def sortear(self): - fim = len(self.alunos) - 1 - index = Utils.obter_inteiro_aleatorio(inicio=0, fim=fim) + """.""" + if self.aluno: + aluno, self.aluno = self.aluno, None + + return aluno - return self.alunos[index] + return super().sortear(lista=self.alunos) - def ler_arquivo(self): - caminho = 'src/store/alunos.csv' - arquivo = self.store.obter_arquivo(caminho=caminho, modo='r') + def ler_arquivo_csv(self): + """.""" + csv = self.store.arquivo(ARQUIVO_CSV, modo='r') - for linha in arquivo: - self.alunos.append(self.limpar_linha(linha=linha)) + for linha in csv: + self.alunos.append(self.formatar(linha)) - arquivo.close() + csv.close() - def limpar_linha(self, linha): + def formatar(self, linha): + """.""" return linha.replace('\n', '').title() diff --git a/src/model/apresentacao.py b/src/model/apresentacao.py index 3d94286..abceb29 100644 --- a/src/model/apresentacao.py +++ b/src/model/apresentacao.py @@ -1,48 +1,37 @@ from src.utils import Utils +from src.model.modelo import Modelo -class Apresentacao: +class Apresentacao(Modelo): - def __init__(self, model): - self.model = model - self.store = self.model.store - self.controller = self.model.controller + def __init__(self): + super().__init__() self.tabela = 'apresentacao' - self.colunas = ['id_apresentacao', 'id_atividade', 'id_grupo', - 'duracao', 'data_apresentacao', 'data_cadastro'] - self.apresentacoes = [] - def iniciar(self): - self.obter_apresentacoes() - self.ordenar() - - def obter_apresentacao(self, id_apresentacao): - tab, cols = self.tabela, self.colunas - con = f'id_apresentacao == "{id_apresentacao}"' - - sql = self.store.select(tabela=tab, colunas=cols, condicao=con) + def iniciar(self, model): + super().iniciar(model) - return self.store.executar(codigo_sql=sql, colunas=cols) + self.carregar() + self.ordenar() - def obter_apresentacoes(self): - tab, cols = self.tabela, self.colunas + def obter(self, id_apresentacao): + return super().obter(_id=id_apresentacao) - sql = self.store.select(tabela=tab, colunas=cols) - self.apresentacoes = self.store.executar(codigo_sql=sql, colunas=cols) + def carregar(self): + self.apresentacoes = super().carregar() for apresentacao in self.apresentacoes: id_grupo = apresentacao['id_grupo'] - grupo = self.model.grupo.obter_grupo(id_grupo=id_grupo) - id_atividade = apresentacao['id_atividade'] - atividade =\ - self.model.atividade.obter_atividade(id_atividade=id_atividade) - if grupo == []: + grupo = self.model.grupo.obter(id_grupo) + atividade = self.model.atividade.obter(id_atividade) + + if not grupo: grupo = [{'nome': 'GRUPO DELETADO'}] - if atividade == []: + if not atividade: atividade = [{'titulo': 'ATIVIDADE DELETADA'}] apresentacao['grupo'] = grupo[0] @@ -50,50 +39,47 @@ def obter_apresentacoes(self): nome_do_grupo = apresentacao['grupo']['nome'] titulo_da_atividade = apresentacao['atividade']['titulo'] - apresentacao['titulo'] = f'{nome_do_grupo} - {titulo_da_atividade}' - - def cadastrar_apresentacao(self, apresentacao): - tab, cols, vals = self.tabela, self.colunas[1:], [] + apresentacao['titulo'] = f'{nome_do_grupo} | {titulo_da_atividade}' + def cadastrar(self, apresentacao): + vals = [] vals.append(apresentacao['id_atividade']) vals.append(apresentacao['id_grupo']) vals.append(apresentacao['duracao']) vals.append(apresentacao['data_apresentacao']) - vals.append(Utils.obter_data_e_hora_atual()) + vals.append(Utils.data_e_hora_atual()) - sql = self.store.insert(tabela=tab, colunas=cols, valores=vals) - self.store.executar(codigo_sql=sql) + super().cadastrar(vals) + self.carregar() - self.obter_apresentacoes() + apresentacao = self.apresentacoes[-1] + self.ordenar() - def remover_apresentacao(self, id_apr): - tab, cols = self.tabela, self.colunas - con = f'id_apresentacao = {id_apr}' + return apresentacao - apresentacao = self.obter_apresentacao(id_apresentacao=id_apr)[0] + def remover(self, id_apresentacao): + apresentacao = self.obter(id_apresentacao)[0] + id_grupo = apresentacao['id_grupo'] id_atividade = apresentacao['id_atividade'] - self.model.atividade.atualizar_uso(id_atividade=id_atividade, valor=0) - id_grupo = apresentacao['id_grupo'] - self.model.grupo.atualizar_uso(id_grupo=id_grupo, valor=0) + self.model.grupo.atualizar(id_grupo, campos={'em_uso': 0}) + self.model.atividade.atualizar(id_atividade, campos={'em_uso': 0}) - sql = self.store.delete(tabela=tab, condicao=con) - self.store.executar(codigo_sql=sql) + super().remover(_id=id_apresentacao) for i, apresentacao in enumerate(self.apresentacoes): - if apresentacao['id_apresentacao'] == id_apr: + if apresentacao['id_apresentacao'] == id_apresentacao: del self.apresentacoes[i] - return id_atividade, id_grupo + return {'atividade': id_atividade, 'grupo': id_grupo} def ordenar(self): - self.apresentacoes.sort( - key=lambda a: a['data_apresentacao'].split('/')[::-1]) + dp = 'data_apresentacao' + self.apresentacoes.sort(key=lambda a: a[dp].split('/')[::-1]) - def validar_cadastro(self, formulario): - data = formulario['data_apresentacao'] - duracao = formulario['duracao'] + def validar(self, formulario): + data, duracao = formulario['data_apresentacao'], formulario['duracao'] if not self.model.atividade.atividades: return 'Lista de Atividades vazia' @@ -103,7 +89,6 @@ def validar_cadastro(self, formulario): if not data: return 'O campo "Apresentação" não pode estar vazio!' - if not duracao: return 'O campo "Duração" não pode estar vazio!' @@ -111,16 +96,7 @@ def validar_cadastro(self, formulario): return 'Formato invalido! Entre com o formato dd/mm/aaaa' dia, mes, ano = data.split('/') - - data_atual = Utils.obter_data_e_hora_atual().split(' ')[0].split('/') - - erro = 'Data INVALIDA' - if data_atual[2] > ano: - return erro - elif data_atual[2] == ano and data_atual[1] > mes: - return erro - elif data_atual[2] == ano and data_atual[1] == mes and data_atual[0] > dia: - return erro + data_atual = Utils.data_e_hora_atual().split(' ')[0].split('/') try: dia, mes, ano = int(dia), int(mes), int(ano) @@ -129,6 +105,9 @@ def validar_cadastro(self, formulario): data_valida = False + if data_atual[::-1] > data.split('/')[::-1]: + return 'Data INVALIDA' + meses_com_ate_31_dias = [1, 3, 5, 7, 8, 10, 12] if mes in meses_com_ate_31_dias: if dia <= 31: diff --git a/src/model/atividade.py b/src/model/atividade.py index 1a7ba20..8639d03 100644 --- a/src/model/atividade.py +++ b/src/model/atividade.py @@ -1,91 +1,65 @@ from src.utils import Utils +from src.model.modelo import Modelo -class Atividade: +class Atividade(Modelo): - def __init__(self, model): - self.model = model - self.store = self.model.store - self.controller = self.model.controller.atividade + def __init__(self): + super().__init__() self.tabela = 'atividade' - self.colunas = ['id_atividade', 'titulo', 'descricao', 'em_uso', - 'data_cadastro'] - self.atividades = [] self.atividade = None + self.atividades = [] - def iniciar(self): - self.obter_atividades() - - def sortear(self): - atividades_disponiveis = [] + def iniciar(self, model): + super().iniciar(model) + self.carregar() - atividade = self.atividade - if atividade: - self.atividade = None + def sortear(self) -> dict or None: + if self.atividade: + atividade, self.atividade = self.atividade, None return atividade - for atividade in self.atividades: - if not atividade['em_uso']: - atividades_disponiveis.append(atividade) + if not self.atividades: + return None - if atividades_disponiveis: - fim = len(atividades_disponiveis) - 1 - index = Utils.obter_inteiro_aleatorio(inicio=0, fim=fim) - - return atividades_disponiveis[index] - - return None + return super().sortear(lista=self.atividades) - def obter_atividade(self, id_atividade): - tab, cols = self.tabela, self.colunas - con = f'id_atividade == "{id_atividade}"' + def obter(self, id_atividade): + return super().obter(_id=id_atividade) - sql = self.store.select(tabela=tab, colunas=cols, condicao=con) - - return self.store.executar(codigo_sql=sql, colunas=cols) - - def obter_atividades(self): - tab, cols = self.tabela, self.colunas - - sql = self.store.select(tabela=tab, colunas=cols) - self.atividades = self.store.executar(codigo_sql=sql, colunas=cols) - - def cadastrar_atividade(self, atividade): - tab, cols, vals = self.tabela, self.colunas[1:], [] + def carregar(self): + self.atividades = super().carregar() + def cadastrar(self, atividade): + vals = [] vals.append(atividade['titulo'].capitalize()) vals.append(atividade['descricao'].capitalize()) vals.append(0) - vals.append(Utils.obter_data_e_hora_atual()) - - sql = self.store.insert(tabela=tab, colunas=cols, valores=vals) - self.store.executar(codigo_sql=sql) + vals.append(Utils.data_e_hora_atual()) - self.obter_atividades() + super().cadastrar(vals) - def atualizar_uso(self, id_atividade, valor=1): - tab = self.tabela - cam = f'em_uso = {valor}' - con = f'id_atividade = {id_atividade}' + self.carregar() - sql = self.store.update(tabela=tab, campos=cam, condicao=con) - self.store.executar(codigo_sql=sql) + return self.atividades[-1] - self.obter_atividades() + def atualizar(self, id_atividade, campos: dict): + super().atualizar(_id=id_atividade, campos=campos) - def remover_atividade(self, id_atividade): - tab, cols = self.tabela, self.colunas - con = f'id_atividade = {id_atividade}' + self.carregar() - sql = self.store.delete(tabela=tab, condicao=con) - self.store.executar(codigo_sql=sql) + def remover(self, id_atividade): + super().remover(_id=id_atividade) - self.obter_atividades() + for i, atividade in enumerate(self.atividades): + if atividade['id_atividade'] == id_atividade: + del self.atividades[i] + break - def validar_campos(self, formulario): + def validar(self, formulario): if formulario['titulo'] == '': return 'O campo "Titulo" não pode estar vazio' @@ -94,6 +68,6 @@ def validar_campos(self, formulario): return None - def limpar_formulario(self, formulario): + def limpar(self, formulario): formulario['titulo'] = '' formulario['descricao'] = '' diff --git a/src/model/grupo.py b/src/model/grupo.py index 240cd5b..df3fe85 100644 --- a/src/model/grupo.py +++ b/src/model/grupo.py @@ -1,104 +1,66 @@ from src.utils import Utils +from src.model.modelo import Modelo -class Grupo: +class Grupo(Modelo): - def __init__(self, model): - self.model = model - self.store = self.model.store - self.controller = self.model.controller.grupo + def __init__(self): + super().__init__() self.tabela = 'grupo' - self.colunas = ['id_grupo', 'nome', 'integrantes', 'em_uso', - 'data_cadastro'] - self.grupos = [] self.grupo = None + self.grupos = [] - def iniciar(self): - self.obter_grupos() - - def sortear(self): - grupos_disponiveis = [] + def iniciar(self, model): + super().iniciar(model) + self.carregar() - grupo = self.grupo - if grupo: - self.grupo = None + def sortear(self) -> dict or None: + if self.grupo: + grupo, self.grupo = self.grupo, None return grupo - for grupo in self.grupos: - if not grupo['em_uso']: - grupos_disponiveis.append(grupo) - - if grupos_disponiveis: - fim = len(grupos_disponiveis) - 1 - index = Utils.obter_inteiro_aleatorio(inicio=0, fim=fim) - - return grupos_disponiveis[index] - - return None - - def obter_grupo(self, id_grupo): - tab, cols = self.tabela, self.colunas - con = f'id_grupo == "{id_grupo}"' + return super().sortear(lista=self.grupos) - sql = self.store.select(tabela=tab, colunas=cols, condicao=con) + def obter(self, id_grupo): + return super().obter(_id=id_grupo) - return self.store.executar(codigo_sql=sql, colunas=cols) - - def obter_grupos(self): - tab, cols = self.tabela, self.colunas - - sql = self.store.select(tabela=tab, colunas=cols) - self.grupos = self.store.executar(codigo_sql=sql, colunas=cols) + def carregar(self): + self.grupos = super().carregar() for grupo in self.grupos: grupo['integrantes'] =\ grupo['integrantes'][1:-2].replace("'", '').split(', ') - def cadastrar_grupo(self, grupo): - tab, cols, vals = self.tabela, self.colunas[1:], [] - + def cadastrar(self, grupo): + vals = [] vals.append(grupo['nome'].capitalize()) vals.append(grupo['integrantes']) vals.append(0) - vals.append(Utils.obter_data_e_hora_atual()) - - sql = self.store.insert(tabela=tab, colunas=cols, valores=vals) - self.store.executar(codigo_sql=sql) - - self.obter_grupos() - - def atualizar_uso(self, id_grupo, valor=1): - tab = self.tabela - cam = f'em_uso = {valor}' - con = f'id_grupo = {id_grupo}' - - sql = self.store.update(tabela=tab, campos=cam, condicao=con) - self.store.executar(codigo_sql=sql) - - self.obter_grupos() + vals.append(Utils.data_e_hora_atual()) - def remover_grupo(self, id_grupo): - tab = self.tabela - con = f'id_grupo = {id_grupo}' + super().cadastrar(vals) + self.carregar() - sql = self.store.delete(tabela=tab, condicao=con) - self.store.executar(codigo_sql=sql) + def atualizar(self, id_grupo, campos): + super().atualizar(_id=id_grupo, campos=campos) + self.carregar() - self.obter_grupos() + def remover(self, id_grupo): + super().remover(_id=id_grupo) + self.carregar() - def gerar_grupos(self, formulario): - nome_base = formulario['nome'] - alunos_por_grupo = int(formulario['quantidade']) + def gerar(self, formulario): + nome, quantidade = formulario['nome'], int(formulario['quantidade']) alunos = self.model.aluno.alunos.copy() grupos_gerados = [] - quantidade_de_grupos = len(alunos) // alunos_por_grupo + quantidade_grupos = len(alunos) // quantidade - for i in range(quantidade_de_grupos): + for i in range(quantidade_grupos): grupo = {} grupo['nome'] = '' grupo['integrantes'] = [] @@ -106,51 +68,51 @@ def gerar_grupos(self, formulario): grupos_gerados.append(grupo) for i, grupo in enumerate(grupos_gerados): - grupo['nome'] = f'{nome_base}-{i + 1}' + grupo['nome'] = f'{nome}-{i + 1}' - for j in range(alunos_por_grupo): + for j in range(quantidade): fim = len(alunos) - 1 - index = Utils.obter_inteiro_aleatorio(inicio=0, fim=fim) + index = Utils.inteiro_aleatorio(inicio=0, fim=fim) grupo['integrantes'].append(alunos[index]) del alunos[index] # alunos sem grupo - fim = quantidade_de_grupos - 1 + fim = quantidade_grupos - 1 for aluno in alunos: - index = Utils.obter_inteiro_aleatorio(inicio=0, fim=fim) + index = Utils.inteiro_aleatorio(inicio=0, fim=fim) grupos_gerados[index]['integrantes'].append(aluno) return grupos_gerados - def validar_campos(self, formulario): + def validar(self, formulario): alunos = self.model.aluno.alunos.copy() if formulario['nome'] == '': - return 'O campo "Nome" não pode estar vazio!' + return 'O campo "Nome" não pode estar vazio' if formulario['quantidade'] == '': - return 'O campo "Nome Base" não pode estar vazio!' + return 'O campo "Nome Base" não pode estar vazio' try: quantidade = int(formulario['quantidade']) except: - return 'O campo "Quantidade" só aceita valor inteiro!' + return 'O campo "Quantidade" só aceita valor inteiro' if quantidade < 2: return 'A quantidade mínima de integrantes é 2' if quantidade > len(alunos): - return 'Quantidade de integrantes maior que a quantidade de alunos!' + return 'Quantidade de integrantes maior que a quantidade de alunos' - if (len(alunos) / quantidade) < 2: - return 'Numero de integrantes insuficientes para gerar grupos!' + if len(alunos) / quantidade < 2: + return 'Numero de integrantes insuficientes para gerar grupos' return None - def limpar_formulario(self, formulario): + def limpar(self, formulario): formulario['nome'] = '' formulario['quantidade'] = '' diff --git a/src/model/modelo.py b/src/model/modelo.py new file mode 100644 index 0000000..fdbb2b9 --- /dev/null +++ b/src/model/modelo.py @@ -0,0 +1,44 @@ +from src.utils import Utils + + +class Modelo(object): + + def __init__(self): + pass + + def iniciar(self, model): + self.model = model + self.store = self.model.store + + def sortear(self, lista: list) -> dict or str or None: + if isinstance(lista[0], dict): + lista = list(filter(lambda valor: not valor['em_uso'], lista)) + + if not lista: + return None + + index = Utils.inteiro_aleatorio(inicio=0, fim=len(lista) - 1) + + return lista[index] + + def obter(self, _id): + sql = self.store.sql.select(self.tabela, _id) + + return self.store.executar(sql) + + def carregar(self): + sql = self.store.sql.select(self.tabela) + + return self.store.executar(sql) + + def cadastrar(self, vals): + sql = self.store.sql.insert(self.tabela, valores=vals) + self.store.executar(sql) + + def atualizar(self, _id, campos): + sql = self.store.sql.update(self.tabela, _id, campos) + self.store.executar(sql) + + def remover(self, _id): + sql = self.store.sql.delete(self.tabela, _id) + self.store.executar(sql) diff --git a/src/model/sobre.py b/src/model/sobre.py index 1fc91ac..2f79268 100644 --- a/src/model/sobre.py +++ b/src/model/sobre.py @@ -1,16 +1,17 @@ -class Sobre: +from src.model.modelo import Modelo - def __init__(self, model): - self.model = model - self.store = self.model.store - self.controller = self.model.controller.sobre +class Sobre(Modelo): - self.tabela = 'sobre' - self.colunas = ['id_do_cartao', 'titulo', 'conteudo'] + def __init__(self): + super().__init__() + self.tabela = 'sobre' self.cartoes = [] - def iniciar(self): + def iniciar(self, model): + self.model = model + self.store = self.model.store + self.obter_cartoes() def obter_cartoes(self): diff --git a/src/model/tarefa.py b/src/model/tarefa.py index 5588574..43b7871 100644 --- a/src/model/tarefa.py +++ b/src/model/tarefa.py @@ -1,89 +1,65 @@ from src.utils import Utils +from src.model.modelo import Modelo -class Tarefa: - - def __init__(self, model): - self.model = model - self.store = self.model.store - self.controller = self.model.controller +class Tarefa(Modelo): + def __init__(self): + super().__init__() self.tabela = 'tarefa' - self.colunas = ['id_tarefa', 'id_atividade', 'aluno', 'data_tarefa', - 'data_cadastro'] self.tarefas = [] - def iniciar(self): - self.obter_tarefas() - - def obter_tarefa(self, id_grupo_atividade): - tab, cols = self.tabela, self.colunas - con = f'id_grupo_atividade == "{id_grupo_atividade}"' - - sql = self.store.select(tabela=tab, colunas=cols, condicao=con) + def iniciar(self, model): + self.model = model + self.store = self.model.store - return self.store.executar(codigo_sql=sql, colunas=cols) + self.carregar() - def obter_tarefas(self): - tab, cols = self.tabela, self.colunas + def obter(self, id_tarefa): + return super().obter(_id=id_tarefa) - sql = self.store.select(tabela=tab, colunas=cols) - self.tarefas = self.store.executar(codigo_sql=sql, colunas=cols) + def carregar(self): + self.tarefas = super().carregar() for tarefa in self.tarefas: - aluno = tarefa['aluno'] - grupo = self.model.grupo.obter_grupo(aluno=aluno) - - id_atividade = tarefa['id_atividade'] - atividade =\ - self.model.atividade.obter_atividade(id_atividade=id_atividade) + atividade = self.model.atividade.obter(tarefa['id_atividade']) - if grupo == []: - grupo = [{'nome': 'GRUPO DELETADO'}] if atividade == []: atividade = [{'titulo': 'ATIVIDADE DELETADA'}] - tarefa['grupo'] = grupo[0] tarefa['atividade'] = atividade[0] - nome_do_grupo = tarefa['grupo']['nome'] - titulo_da_atividade = tarefa['atividade']['titulo'] - tarefa['titulo'] = f'{nome_do_grupo} - {titulo_da_atividade}' - - def cadastrar_apresentacao(self, tarefa): - tab, cols, vals = self.tabela, self.colunas[1:], [] + nome_aluno = tarefa['aluno'] + titulo_atividade = tarefa['atividade']['titulo'] + tarefa['titulo'] = f'{nome_aluno} - {titulo_atividade}' + def cadastrar(self, tarefa): + vals = [] vals.append(tarefa['id_atividade']) vals.append(tarefa['aluno']) vals.append(tarefa['duracao']) vals.append(tarefa['data_tarefa']) - vals.append(Utils.obter_data_e_hora_atual()) + vals.append(Utils.data_e_hora_atual()) - sql = self.store.insert(tabela=tab, colunas=cols, valores=vals) - self.store.executar(codigo_sql=sql) + super().cadastrar(vals) + self.carregar() - self.obter_tarefas() + tarefa = self.tarefas[-1] - def remover_apresentacao(self, id_grupo_atividade): - tab, cols = self.tabela, self.colunas - con = f'id_grupo_atividade = {id_grupo_atividade}' + return tarefa - tarefa =\ - self.obter_tarefa(id_grupo_atividade=id_grupo_atividade)[0] + def remover(self, id_tarefa): + tarefa = self.obter(id_tarefa)[0] id_atividade = tarefa['id_atividade'] - self.model.atividade.atualizar_uso(id_atividade=id_atividade, valor=0) - - aluno = tarefa['aluno'] - self.model.grupo.atualizar_uso(aluno=aluno, valor=0) + self.model.atividade.atualizar(id_atividade, campos={'em_uso': 0}) - sql = self.store.delete(tabela=tab, condicao=con) - self.store.executar(codigo_sql=sql) + super().remover(_id=id_tarefa) - self.obter_tarefas() + return {'atividade': id_atividade} - def validar_campos(self, formulario): + def validar(self, formulario): data = formulario['data_tarefa'] duracao = formulario['duracao'] diff --git a/src/store/__init__.py b/src/store/__init__.py index 9103ac5..bac756e 100644 --- a/src/store/__init__.py +++ b/src/store/__init__.py @@ -1,84 +1,41 @@ -import sqlite3 -from src.utils import Utils +""".""" +from src.store.sqlite import MSqLite -class Store: +from src.utils.tipo import Tipo +from src.utils.caminho import Caminho - def __init__(self): - self.conexao = None - self.conectado = False - self.caminho = Utils.obter_caminho('src/store/banco_de_dados.sqlite') - def obter_arquivo(self, caminho, modo): - return open(Utils.obter_caminho(caminho), mode=modo) +class Store(MSqLite): + """.""" - def executar(self, codigo_sql, converter=True, colunas=[]): - if self.conectado: - self.fechar_conexao() + def __init__(self) -> None: + """.""" + super().__init__() - self.conexao = self.conectar() + def arquivo(self, arquivo: str, modo: str='r') -> Tipo.arquivo: + """.""" + return open(arquivo, mode=modo) - resultado = self.conexao.cursor().execute(codigo_sql) + def executar(self, codigo_sql: str) -> list or None: + """.""" + resultado = super().executar(codigo_sql) - if 'SELECT' in codigo_sql and converter: - resultado = self.converter(tabela=resultado, colunas=colunas) + if 'SELECT' in codigo_sql: + return self.converter(cursor=resultado) - self.salvar() + def converter(self, cursor: Tipo.exc_sqlite) -> list: + """.""" + tabela = cursor.fetchall() + colunas = [linha[0] for linha in cursor.description] - return resultado - - def salvar(self, fechar_conexao=True): - if not self.conectado: - return - - self.conexao.commit() - - if fechar_conexao: - self.fechar_conexao() - - def fechar_conexao(self): - if not self.conectado: - return - - self.conexao.close() - self.conectado = False - - def conectar(self): - self.conectado = True - - return sqlite3.connect(self.caminho) - - def converter(self, tabela, colunas): - resultado, resultado_parcial = [], {} + nova_tabela, nova_linha = [], {} for linha in tabela: for i, valor in enumerate(linha): - resultado_parcial[colunas[i]] = valor - - resultado.append(resultado_parcial) - resultado_parcial = {} - - return resultado - - def select(self, tabela, colunas, condicao=None): - colunas = ', '.join(colunas) - - codigo = f'SELECT {colunas} FROM {tabela}' - - if condicao: - codigo = f'{codigo} WHERE {condicao}' - - return codigo - - def insert(self, tabela, colunas, valores): - valores = map(lambda valor: f'"{valor}"', valores) - valores = ', '.join(valores) - colunas = ', '.join(colunas) - - return f'INSERT INTO {tabela}({colunas}) VALUES({valores})' + nova_linha[colunas[i]] = valor - def update(self, tabela, campos, condicao): - return f'UPDATE {tabela} SET {campos} WHERE {condicao}' + nova_tabela.append(nova_linha) + nova_linha = {} - def delete(self, tabela, condicao): - return f'DELETE FROM {tabela} WHERE {condicao}' + return nova_tabela diff --git a/src/store/codigo_sql.py b/src/store/codigo_sql.py new file mode 100644 index 0000000..e693e93 --- /dev/null +++ b/src/store/codigo_sql.py @@ -0,0 +1,41 @@ +""".""" + +from src.store.infos import Infos + + +class CodigoSql(object): + """.""" + + @staticmethod + def select(tabela: str, _id: str='') -> str: + """.""" + colunas = ', '.join(Infos.colunas_da(tabela)) + condicao = f'{Infos.colunas_da(tabela)[0]} == "{_id}"' + + codigo_sql = f'SELECT {colunas} FROM {tabela}' + + return f'{codigo_sql} WHERE {condicao}' if _id else codigo_sql + + @staticmethod + def insert(tabela: str, valores: list) -> str: + """.""" + colunas = ', '.join(Infos.colunas_da(tabela)[1:]) + valores = ', '.join(map(lambda valor: f'"{valor}"', valores)) + + return f'INSERT INTO {tabela}({colunas}) VALUES({valores})' + + @staticmethod + def update(tabela: str, _id: str, campos: dict) -> str: + """.""" + condicao = f'{Infos.colunas_da(tabela)[0]} == "{_id}"' + campos = ', '.join(map( + lambda chave: f'{chave} = "{campos[chave]}"', campos)) + + return f'UPDATE {tabela} SET {campos} WHERE {condicao}' + + @staticmethod + def delete(tabela: str, _id: str) -> str: + """.""" + condicao = f'{Infos.colunas_da(tabela)[0]} == "{_id}"' + + return f'DELETE FROM {tabela} WHERE {condicao}' diff --git a/src/store/alunos.csv b/src/store/file/alunos.csv similarity index 100% rename from src/store/alunos.csv rename to src/store/file/alunos.csv diff --git a/src/store/banco_de_dados.sqlite b/src/store/file/bd.sqlite similarity index 95% rename from src/store/banco_de_dados.sqlite rename to src/store/file/bd.sqlite index ef0f1d8..bf2ef3a 100644 Binary files a/src/store/banco_de_dados.sqlite and b/src/store/file/bd.sqlite differ diff --git a/src/store/infos.py b/src/store/infos.py new file mode 100644 index 0000000..0f2e937 --- /dev/null +++ b/src/store/infos.py @@ -0,0 +1,48 @@ +""".""" + + +class Infos(object): + """.""" + + @staticmethod + def tabelas() -> list: + """.""" + return ['atividade', 'grupo', 'apresentacao', 'tarefa', 'evento'] + + @staticmethod + def colunas_da(tabela: str) -> list: + """.""" + return getattr(Infos, f'colunas_{tabela}')() + + @staticmethod + def colunas_atividade() -> list: + """.""" + return ['id_atividade', 'titulo', 'descricao', 'em_uso', + 'data_cadastro'] + + @staticmethod + def colunas_grupo() -> list: + """.""" + return ['id_grupo', 'nome', 'integrantes', 'em_uso', 'data_cadastro'] + + @staticmethod + def colunas_tarefa() -> list: + """.""" + return ['id_tarefa', 'id_atividade', 'aluno', 'duracao', 'data_tarefa', + 'data_cadastro'] + + @staticmethod + def colunas_apresentacao() -> list: + """.""" + return ['id_apresentacao', 'id_atividade', 'id_grupo', 'duracao', + 'data_apresentacao', 'data_cadastro'] + + @staticmethod + def colunas_evento() -> list: + """.""" + return [] + + @staticmethod + def colunas_sobre() -> list: + """.""" + return [] diff --git a/src/store/sqlite.py b/src/store/sqlite.py new file mode 100644 index 0000000..b4563a7 --- /dev/null +++ b/src/store/sqlite.py @@ -0,0 +1,54 @@ +""".""" +from src import BANCO_DE_DADOS +import sqlite3 + +from src.store.infos import Infos +from src.store.codigo_sql import CodigoSql + +from src.utils.tipo import Tipo + + +class MSqLite(object): + """.""" + + def __init__(self) -> None: + """.""" + self.sql = CodigoSql + + self.conexao = None + self.conectado = False + + def executar(self, codigo_sql: str) -> Tipo.exc_sqlite: + """.""" + if self.conectado: + self.fechar_conexao() + + self.conectar() + resultado = self.conexao.cursor().execute(codigo_sql) + + self.salvar(fechar_conexao=False) + + return resultado + + def salvar(self, fechar_conexao: bool=True) -> None: + """.""" + if not self.conectado: + return + + self.conexao.commit() + + if fechar_conexao: + self.fechar_conexao() + + def fechar_conexao(self) -> None: + """.""" + if not self.conectado: + return + + self.conexao.close() + self.conectado = False + + def conectar(self) -> None: + """.""" + self.conexao = sqlite3.connect(BANCO_DE_DADOS) + self.conectado = True diff --git a/src/utils/__init__.py b/src/utils/__init__.py index 31405d6..c510a28 100644 --- a/src/utils/__init__.py +++ b/src/utils/__init__.py @@ -1,65 +1,18 @@ -from sys import argv -from os import getcwd +"""Conjunto de codigo reaproveitavel.""" + from random import randint from datetime import datetime -class Utils: +class Utils(object): + """Conjunto de “atalhos” para funcionalidades uteis.""" @staticmethod - def obter_inteiro_aleatorio(inicio, fim): + def inteiro_aleatorio(inicio: int, fim: int) -> int: + """Devolve um inteiro aleatorio: inicio=1 e fim=3 saida=1 ou 2 ou 3.""" return randint(inicio, fim) @staticmethod - def obter_data_e_hora_atual(): + def data_e_hora_atual() -> str: + """Devolve uma data em string no formato: dd/mm/aaaa hh:mm.""" return datetime.now().strftime('%d/%m/%Y %H:%M') - - @staticmethod - def obter_caminho_atual(): - caminho = '' - caminho_absoluto = getcwd() - caminho_de_execucao = Utils.obter_caminho_de_execucao() - - if caminho_de_execucao == '' or caminho_de_execucao[0] != '/': - caminho = f'{caminho_absoluto}/{caminho_de_execucao}' - else: - caminho = caminho_de_execucao - - return caminho - - @staticmethod - def obter_caminho(caminho_do_arquivo): - caminho = Utils.obter_caminho_atual() - - if Utils.verificar_modo_producao(): - caminho = f'{caminho}/lib' - - caminho = f'{caminho}/{caminho_do_arquivo}' - - return caminho - - @staticmethod - def obter_parametros(): - return argv - - @staticmethod - def obter_caminho_de_execucao(): - return '/'.join(argv[0].split('/')[:-1]) - - @staticmethod - def verificar_modo_dev(): - if '--dev' in argv: - return True - return False - - @staticmethod - def verificar_modo_teste(): - if '--test' in argv: - return True - return False - - @staticmethod - def verificar_modo_producao(): - if not Utils.verificar_modo_dev() and not Utils.verificar_modo_teste(): - return True - return False diff --git a/src/utils/atributo.py b/src/utils/atributo.py new file mode 100644 index 0000000..f432c27 --- /dev/null +++ b/src/utils/atributo.py @@ -0,0 +1,9 @@ +"""Submodulo de Utils.""" + + +class Atributo(object): + """Guarda os subelementos de uma classe como atributos.""" + + def __init__(self) -> None: + """.""" + pass diff --git a/src/utils/caminho.py b/src/utils/caminho.py new file mode 100644 index 0000000..362f204 --- /dev/null +++ b/src/utils/caminho.py @@ -0,0 +1,38 @@ +"""Submodulo de Utils.""" + +from os import getcwd +from src.utils.env import Env + + +class Caminho(object): + """Conjunto caminhos relacionados a execucao e resolvedor de caminhos.""" + + @staticmethod + def ate(arquivo: str) -> str: + """Resolve o caminho ate um arquivo de acordo com diversos fatores.""" + final = f'{Caminho.atual()}/{arquivo}' + + if Env.modo_producao(): + final = f'{final}/lib/{arquivo}' + + return final + + @staticmethod + def atual() -> str: + """Caminho atual levando em conta o caminho do comando de execucao.""" + caminho = '' + + absoluto = getcwd() + execucao = Caminho.execucao() + + if execucao and execucao[0] != '/': + caminho = f'{absoluto}/{execucao}' + else: + caminho = absoluto + + return caminho + + @staticmethod + def execucao() -> str: + """Caminho em que o comando de exeucao foi executado.""" + return '/'.join(Env.parametros()[0].split('/')[:-1]) diff --git a/src/utils/env.py b/src/utils/env.py new file mode 100644 index 0000000..cfa9a04 --- /dev/null +++ b/src/utils/env.py @@ -0,0 +1,27 @@ +"""Submodulo de Utils.""" + +from sys import argv + + +class Env(object): + """Conjunto de informacoes relacionadas a execucao.""" + + @staticmethod + def parametros() -> list: + """Retorna os parametros recebidos no momento da execucao.""" + return argv + + @staticmethod + def modo_dev() -> bool: + """Verifica se o app foi executado em modo de desenvolvimento.""" + return True if '--dev' in Env.parametros() else False + + @staticmethod + def modo_teste() -> bool: + """Verifica se o app foi executado em modo de testes.""" + return True if '--test' in Env.parametros() else False + + @staticmethod + def modo_producao() -> bool: + """Verifica se o app foi executado em modo de producao.""" + return True if not Env.modo_dev() and not Env.modo_teste() else False diff --git a/src/utils/tipo.py b/src/utils/tipo.py new file mode 100644 index 0000000..0cda118 --- /dev/null +++ b/src/utils/tipo.py @@ -0,0 +1,18 @@ +"""Submodulo de Utils.""" + +from sqlite3 import Cursor +from _io import TextIOWrapper + + +class Tipo(object): + """Conjunto de tipos para ajudar com a tipagem estatica.""" + + @staticmethod + def arquivo() -> TextIOWrapper: + """Tipo arquivo padrao do python: tipo=open('arquivo.txt').""" + return TextIOWrapper + + @staticmethod + def exc_sqlite() -> Cursor: + """Tipo de objeto retornado apos operacoes no banco de dados.""" + return Cursor diff --git a/src/utils/tk.py b/src/utils/tk.py deleted file mode 100644 index 754729d..0000000 --- a/src/utils/tk.py +++ /dev/null @@ -1,155 +0,0 @@ -import tkinter as tk -from src.utils import Utils - - -class TKUtils: - - @staticmethod - def definir_icone(master, nome_do_icone): - arquivo = Utils.obter_caminho(f'src/assets/{nome_do_icone}.png') - imagem = tk.PhotoImage(file=arquivo) - master.wm_iconphoto(True, imagem) - - @staticmethod - def obter_label(master, cnf={}, pack={}, grid={}): - cnf_padrao = {} - - cnf_padrao['text'] = '...' - cnf_padrao['font'] = ('times new roman', 14, 'bold') - - label = tk.Label(master=master, cnf=cnf_padrao) - label.configure(cnf=cnf) - - if grid: - label.grid(grid) - else: - label.pack(pack) - - label.style_cnf = cnf - label.default_style_cnf = cnf_padrao - - return label - - @staticmethod - def obter_botao(master, cnf={}, pack={}, grid={}): - cnf_padrao = {} - - cnf_padrao['text'] = '...' - cnf_padrao['width'] = 10 - cnf_padrao['height'] = 1 - cnf_padrao['bd'] = 2 - cnf_padrao['pady'] = 6 - cnf_padrao['padx'] = 6 - cnf_padrao['fg'] = 'white' - cnf_padrao['font'] = ('times new roman', 14, 'bold') - - botao = tk.Button(master=master, cnf=cnf_padrao) - botao.configure(cnf=cnf) - - if grid: - botao.grid(grid) - else: - botao.pack(pack) - - botao.style_cnf = cnf - botao.default_style_cnf = cnf_padrao - - return botao - - @staticmethod - def obter_input(master, cnf={}, pack={}, grid={}): - cnf_padrao = {} - - cnf_padrao['width'] = 20 - cnf_padrao['bg'] = 'white' - cnf_padrao['fg'] = 'black' - cnf_padrao['bd'] = 0 - cnf_padrao['justify'] = 'left' - cnf_padrao['font'] = ('times new roman', 14, 'italic') - - _input = tk.Entry(master=master, cnf=cnf_padrao) - - if 'placeholder' in cnf: - _input.insert(0, cnf['placeholder']) - cnf.pop('placeholder') - - _input.configure(cnf=cnf) - - if grid: - _input.grid(grid) - else: - _input.pack(pack) - - _input.style_cnf = cnf - _input.default_style_cnf = cnf_padrao - - return _input - - @staticmethod - def obter_container(master, cnf={}, pack={}, grid={}): - container = tk.Frame(master=master, cnf=cnf) - - if grid: - container.grid(grid) - else: - container.pack(pack) - - container.style_cnf = cnf - - return container - - @staticmethod - def obter_janela(titulo='Nova Janela', tamanho='200x100'): - janela = tk.Tk() - - janela.title(titulo) - janela.geometry(tamanho) - - janela.style_cnf = cnf - janela.default_style_cnf = cnf_padrao - - return janela - - @staticmethod - def Janela(): - return tk.Tk - - @staticmethod - def Container(): - return tk.Frame - - @staticmethod - def ScrollContainer(): - return ScrollContainer - - -class ScrollContainer(tk.Frame): - - def __init__(self, master, cnf={}, cs_cnf={}, vt_cnf={}, sr_cnf={}): - super().__init__(master=master, cnf=cnf) - self.pack(expand=True) - - self.canvas = tk.Canvas(master=self, cnf=cs_cnf) - self.viewport = tk.Frame(master=self.canvas, cnf=vt_cnf) - self.scrollbar = tk.Scrollbar( - master=self, cnf=sr_cnf, command=self.canvas.yview) - - self.canvas.configure(yscrollcommand=self.scrollbar.set) - - self.scrollbar.pack(side='right', fill='y') - self.canvas.pack(side='left', fill='both', expand=True) - self.canvas_window =\ - self.canvas.create_window( - (4, 4), window=self.viewport, anchor='nw', tags='self.viewport') - - self.viewport.bind('', self.on_frame_configure) - self.canvas.bind('', self.on_canvas_configure) - - self.on_frame_configure(None) - - def on_frame_configure(self, event): - self.canvas.configure(scrollregion=self.canvas.bbox('all')) - - def on_canvas_configure(self, event): - canvas_width = event.width - self.canvas.itemconfig(self.canvas_window, width=canvas_width) diff --git a/src/utils/tk/__init__.py b/src/utils/tk/__init__.py new file mode 100644 index 0000000..bf945b9 --- /dev/null +++ b/src/utils/tk/__init__.py @@ -0,0 +1,48 @@ +"""Intermediador entre o Tkinter e a camada View do App.""" + +from src.utils.tk.botao import MBotao +from src.utils.tk.label import MLabel +from src.utils.tk.input import MInput +from src.utils.tk.janela import MJanela +from src.utils.tk.mensagem import MMensagem +from src.utils.tk.container import MContainer +from src.utils.tk.scrollview import MScrollView + + +class TKUtils(object): + """Serve instancias customizadas de classes TK.""" + + @staticmethod + def obter_label() -> MLabel: + """Devolve uma instancia de MLabel.""" + return MLabel() + + @staticmethod + def obter_mensagem() -> MMensagem: + """Devolve uma instancia de MMensagem.""" + return MMensagem() + + @staticmethod + def obter_botao() -> MBotao: + """Devolve uma instancia de MBotao.""" + return MBotao() + + @staticmethod + def obter_input() -> MInput: + """Devolve uma instancia de MInput.""" + return MInput() + + @staticmethod + def obter_container(instanciar: bool=False) -> MContainer: + """Devolve uma instancia de MContainer.""" + return MContainer() if instanciar else MContainer + + @staticmethod + def obter_scrollview(instanciar: bool=False) -> MScrollView: + """Devolve uma instancia de MScrollView.""" + return MScrollView() if instanciar else MScrollView + + @staticmethod + def obter_janela(instanciar: bool=False) -> MJanela: + """Devolve uma instancia de MJanela.""" + return MJanela() if instanciar else MJanela diff --git a/src/utils/tk/botao.py b/src/utils/tk/botao.py new file mode 100644 index 0000000..0a4be77 --- /dev/null +++ b/src/utils/tk/botao.py @@ -0,0 +1,59 @@ +"""Button de TK personalizado.""" + +from tkinter import Button +from src.utils.tk.elemento import Elemento + + +class MBotao(Button, Elemento): + """Estende a classe Button de TK abstraindo algumas configuracoes.""" + + def __init__(self) -> None: + """Define as configuracoes padroes.""" + Elemento.__init__(self) + + self.defs.cnf['text'] = 'BOTAO' + self.defs.cnf['width'] = 10 + self.defs.cnf['height'] = 1 + self.defs.cnf['bd'] = 2 + self.defs.cnf['pady'] = 6 + self.defs.cnf['padx'] = 6 + self.defs.cnf['bg'] = 'grey' + self.defs.cnf['fg'] = 'white' + self.defs.cnf['font'] = ('times new roman', 14, 'bold') + + self.ativo = True + + def iniciar(self, master: object) -> None: + """Inicializa e configura.""" + if 'fz' in self.defs.mcnf: + fonte = self.defs.cnf['font'] + self.defs.cnf['font'] = (fonte[0], self.defs.mcnf['fz'], fonte[2]) + + Button.__init__(self, master=master, cnf=self.defs.cnf) + self.mostrar() + + def ativar(self) -> None: + """Ativa o botao: volta com a cor e eventos que tinha antes.""" + self.configure(state='normal', bg=self.defs.cnf['bg']) + self.ativo = True + + self.carregar_eventos() + + def desativar(self) -> None: + """Desativa o botao: remove os eventos e muda a cor para sinza.""" + self.configure(state='disabled', bg='grey', command=None) + + for key in self.evento: + self.unbind(key) + + self.ativo = False + + def carregar_eventos(self) -> None: + """Sobescreve o metodo de Elemento tratando 'command' como um evento.""" + if not self.ativo: + return + + if 'command' in self.defs.mcnf: + self.configure(command=self.defs.mcnf['command']) + + Elemento.carregar_eventos(self) diff --git a/src/utils/tk/container.py b/src/utils/tk/container.py new file mode 100644 index 0000000..43f76fe --- /dev/null +++ b/src/utils/tk/container.py @@ -0,0 +1,19 @@ +"""Frame de TK personalizado.""" + +from tkinter import Frame +from src.utils.tk.elemento import Elemento + + +class MContainer(Frame, Elemento): + """Estende a classe Frame de TK abstraindo algumas configuracoes.""" + + def __init__(self) -> None: + """Define as configuracoes padroes.""" + Elemento.__init__(self) + + self.defs.cnf['bd'] = 2 + + def iniciar(self, master: object) -> None: + """Inicializa e configura.""" + Frame.__init__(self, master=master, cnf=self.defs.cnf) + self.mostrar() diff --git a/src/utils/tk/elemento.py b/src/utils/tk/elemento.py new file mode 100644 index 0000000..cae1dab --- /dev/null +++ b/src/utils/tk/elemento.py @@ -0,0 +1,57 @@ +"""Subelemento de Utils.""" + +from src.utils.atributo import Atributo + + +class Elemento(object): + """Salva os dados de cada elemento TK de forma padronizada e organizada.""" + + def __init__(self) -> None: + """Define os atributos customizados que podem ser usados.""" + self.evento = {} + self.dados = None + + self.defs = Atributo() + self.subelemento = Atributo() + + self.defs.cnf = {} + self.defs.mcnf = {} + self.defs.pack = {} + self.defs.grid = {} + + self.defs.visivel = False + + def mostrar(self) -> None: + """Deixa o componente visivel com as regras geometricas predefinidas.""" + if self.defs.grid: + self.grid(self.defs.grid) + else: + self.pack(self.defs.pack) + + self.defs.visivel = True + + def ocultar(self) -> None: + """Oculta o elemento.""" + if self.defs.grid: + self.grid_forget() + else: + self.pack_forget() + + self.defs.visivel = False + + def carregar_eventos(self) -> None: + """Carrega/ativa os eventos predefinidos do elemento e subelementos.""" + for key in self.evento: + self.bind(key, self.evento[key]) + + subelementos = filter(lambda v: not '__' in v, dir(self.subelemento)) + for subelemento in list(subelementos): + elemento = getattr(self.subelemento, subelemento) + + if 'carregar_eventos' in dir(elemento): + elemento.carregar_eventos() + continue + + subelementos = filter(lambda v: not '__' in v, dir(elemento)) + for subelemento in list(subelementos): + getattr(elemento, subelemento).carregar_eventos() diff --git a/src/utils/tk/input.py b/src/utils/tk/input.py new file mode 100644 index 0000000..3a7cd8a --- /dev/null +++ b/src/utils/tk/input.py @@ -0,0 +1,32 @@ +"""Entry de TK personalizado.""" + +from tkinter import Entry +from src.utils.tk.elemento import Elemento + + +class MInput(Entry, Elemento): + """Estende a classe Entry de TK abstraindo algumas configuracoes.""" + + def __init__(self) -> None: + """Define as configuracoes padroes.""" + Elemento.__init__(self) + + self.defs.cnf['bd'] = 0 + self.defs.cnf['width'] = 20 + self.defs.cnf['bg'] = 'white' + self.defs.cnf['fg'] = 'black' + self.defs.cnf['justify'] = 'left' + self.defs.cnf['font'] = ('times new roman', 14, 'italic') + + self.defs.mcnf['focus'] = False + self.defs.mcnf['placeholder'] = 'Digite algo...' + + def iniciar(self, master: object) -> None: + """Inicializa e configura.""" + Entry.__init__(self, master=master, cnf=self.defs.cnf) + + self.insert(0, self.defs.mcnf['placeholder']) + if self.defs.mcnf['focus']: + self.focus() + + self.mostrar() diff --git a/src/utils/tk/janela.py b/src/utils/tk/janela.py new file mode 100644 index 0000000..7e20ab3 --- /dev/null +++ b/src/utils/tk/janela.py @@ -0,0 +1,33 @@ +"""Tk de TK personalizado.""" + +from tkinter import Tk, PhotoImage +from src.utils.tk.elemento import Elemento + + +class MJanela(Tk, Elemento): + """Estende a classe Tk de TK abstraindo algumas configuracoes.""" + + def __init__(self) -> None: + """Define as configuracoes padroes.""" + Elemento.__init__(self) + + self.defs.cnf['title'] = 'JANELA SEM TITULO' + self.defs.cnf['geometry'] = '400x400' + self.defs.cnf['resizable'] = False + + def iniciar(self) -> None: + """Inicializa e configura.""" + Tk.__init__(self) + + if 'icon' in self.defs.cnf: + self.wm_iconphoto(True, PhotoImage(file=self.defs.cnf['icon'])) + + self.title(self.defs.cnf['title']) + self.geometry(self.defs.cnf['geometry']) + + if not self.defs.cnf['resizable']: + self.resizable(0, 0) + + def fechar(self) -> None: + """Destroi a janela""" + self.destroy() diff --git a/src/utils/tk/label.py b/src/utils/tk/label.py new file mode 100644 index 0000000..66debd0 --- /dev/null +++ b/src/utils/tk/label.py @@ -0,0 +1,24 @@ +"""Label TK personalizado.""" + +from tkinter import Label +from src.utils.tk.elemento import Elemento + + +class MLabel(Label, Elemento): + """Estende a classe Label de TK abstraindo algumas configuracoes.""" + + def __init__(self) -> None: + """Define as configuracoes padroes.""" + Elemento.__init__(self) + + self.defs.cnf['text'] = 'LABEL' + self.defs.cnf['font'] = ('times new roman', 14, 'bold') + + def iniciar(self, master: object) -> None: + """Inicializa e configura.""" + if 'fz' in self.defs.mcnf: + fonte = self.defs.cnf['font'] + self.defs.cnf['font'] = (fonte[0], self.defs.mcnf['fz'], fonte[2]) + + Label.__init__(self, master=master, cnf=self.defs.cnf) + self.mostrar() diff --git a/src/utils/tk/mensagem.py b/src/utils/tk/mensagem.py new file mode 100644 index 0000000..07c0f02 --- /dev/null +++ b/src/utils/tk/mensagem.py @@ -0,0 +1,24 @@ +"""Message TK personalizado.""" + +from tkinter import Message +from src.utils.tk.elemento import Elemento + + +class MMensagem(Message, Elemento): + """Estende a classe Message de TK abstraindo algumas configuracoes.""" + + def __init__(self) -> None: + """Define as configuracoes padroes.""" + Elemento.__init__(self) + + self.defs.cnf['text'] = 'MENSAGEM' + self.defs.cnf['font'] = ('times new roman', 14, 'italic') + + def iniciar(self, master: object) -> None: + """Inicializa e configura.""" + if 'fz' in self.defs.mcnf: + fonte = self.defs.cnf['font'] + self.defs.cnf['font'] = (fonte[0], self.defs.mcnf['fz'], fonte[2]) + + Message.__init__(self, master=master, cnf=self.defs.cnf) + self.mostrar() diff --git a/src/utils/tk/scrollview.py b/src/utils/tk/scrollview.py new file mode 100644 index 0000000..c4cb18f --- /dev/null +++ b/src/utils/tk/scrollview.py @@ -0,0 +1,55 @@ +"""ScrollView com classes TK puras.""" + +from tkinter import Frame, Canvas, Scrollbar +from src.utils.tk.elemento import Elemento + + +class MScrollView(Frame, Elemento): + """Conjunto de classes TK para listagem de elementos. + + obs: canvas, viewport e scrollbar nao sao subelementos pq o objetivo e criar + um novo tipo de objeto que ate entao nao existe por padrao no TK. + """ + + def __init__(self) -> None: + """Define algumas configuracoes extras relacionadas ao Elemento.""" + Elemento.__init__(self) + + self.defs.pack['expand'] = True + + self.defs.canvas = {} + self.defs.viewport = {} + self.defs.scrollbar = {} + + def iniciar(self, master: object) -> None: + """Inicializa e configura.""" + Frame.__init__(self, master=master, cnf=self.defs.cnf) + + self.canvas = Canvas(master=self, cnf=self.defs.canvas) + self.viewport = Frame(master=self.canvas, cnf=self.defs.viewport) + self.scrollbar = Scrollbar(master=self, cnf=self.defs.scrollbar) + + self.scrollbar.configure(command=self.canvas.yview) + self.canvas.configure(yscrollcommand=self.scrollbar.set) + + self.scrollbar.pack(side='right', fill='y') + self.canvas.pack(side='left', fill='both', expand=True) + + jnl, ar, tags = self.viewport, 'nw', 'self.viewport' + self.canvas_window =\ + self.canvas.create_window((4, 4), window=jnl, anchor=ar, tags=tags) + + self.canvas.bind('', self.evento_configurar_canvas) + self.viewport.bind('', self.evento_configurar_viewport) + + self.evento_configurar_viewport(None) + + self.mostrar() + + def evento_configurar_viewport(self, evt) -> None: + """.""" + self.canvas.configure(scrollregion=self.canvas.bbox('all')) + + def evento_configurar_canvas(self, evt) -> None: + """.""" + self.canvas.itemconfig(self.canvas_window, width=evt.width) diff --git a/src/view/__init__.py b/src/view/__init__.py index db91458..a099c5d 100644 --- a/src/view/__init__.py +++ b/src/view/__init__.py @@ -1,113 +1,59 @@ +from src import ICONE_MAIN from src.utils.tk import TKUtils from src.view.navbar import Navbar + from src.view.home import Home from src.view.aluno import Aluno from src.view.grupo import Grupo -from src.view.atividade import Atividade from src.view.sobre import Sobre +from src.view.atividade import Atividade -from src.view.janela_de_erro import JanelaDeErro -from src.view.janela_de_sorteio import JanelaDeSorteio +from src.view.janela_erro import JanelaDeErro +from src.view.janela_sorteio import JanelaDeSorteio -class View(TKUtils.Janela()): +class View(TKUtils.obter_janela()): - def __init__(self, controller): + def __init__(self): super().__init__() - self.controller = controller + self.defs.cnf['icon'] = ICONE_MAIN + self.defs.cnf['title'] = 'StuKi®' + self.defs.cnf['geometry'] = '960x490' - self.navbar = None - self.home = None - self.aluno = None - self.grupo = None - self.atividade = None - self.sobre = None + self.navbar = Navbar() - self.janela_de_erro = None - self.janela_de_sorteio = None - - self.container_ativo = '' + self.home = Home() + self.aluno = Aluno() + self.grupo = Grupo() + self.sobre = Sobre() + self.atividade = Atividade() - def segundo_init(self): - self.title('StuKi®') - self.geometry('960x490') - self.resizable(0, 0) + self.janela_erro = JanelaDeErro() + self.janela_sorteio = JanelaDeSorteio() - TKUtils.definir_icone(master=self, nome_do_icone='icone') + self.container_ativo = '' def iniciar(self): - self.criar_navbar() - - self.criar_container_home() - self.criar_container_aluno() - self.criar_container_atividade() - self.criar_container_grupo() - self.criar_container_sobre() - - self.home.ativar() - self.container_ativo = 'home' - - self.mainloop() - - def criar_navbar(self): - controller = self.controller.navbar - self.navbar = Navbar(master=self, controller=controller) + super().iniciar() - self.controller.navbar.elemento_montado() + self.navbar.iniciar(master=self) - def criar_container_home(self): - controller = self.controller.home - self.home = Home(master=self, controller=controller) + self.home.iniciar(master=self) + self.aluno.iniciar(master=self) + self.grupo.iniciar(master=self) + self.sobre.iniciar(master=self) + self.atividade.iniciar(master=self) - self.controller.home.elemento_montado() + self.mostrar_container('home') - def criar_container_aluno(self): - controller = self.controller.aluno - self.aluno = Aluno(master=self, controller=controller) + def mostrar_container(self, container): + getattr(self, container).mostrar() - self.controller.aluno.elemento_montado() + self.container_ativo = container - def criar_container_atividade(self): - controller = self.controller.atividade - self.atividade = Atividade(master=self, controller=controller) - - self.controller.atividade.elemento_montado() - - def criar_container_grupo(self): - controller = self.controller.grupo - self.grupo = Grupo(master=self, controller=controller) - - self.controller.grupo.elemento_montado() - - def criar_container_sobre(self): - controller = self.controller.sobre - self.sobre = Sobre(master=self, controller=controller) - - self.controller.sobre.elemento_montado() - - def desativar_container_ativo(self): - if self.container_ativo == 'home': - self.home.desativar() - elif self.container_ativo == 'aluno': - self.aluno.desativar() - elif self.container_ativo == 'atividade': - self.atividade.desativar() - elif self.container_ativo == 'grupo': - self.grupo.desativar() - elif self.container_ativo == 'sobre': - self.sobre.desativar() + def ocultar_container_ativo(self): + getattr(self, self.container_ativo).ocultar() self.container_ativo = '' - - def criar_janela_de_erro(self, erro): - self.janela_de_erro = JanelaDeErro(erro=erro) - - def criar_janela_de_sorteio(self, atividade, aluno='', grupo=''): - elemento = aluno if aluno else grupo['nome'] - - self.janela_de_sorteio =\ - JanelaDeSorteio(elemento=elemento, atividade=atividade) - - self.janela_de_sorteio.iniciar() diff --git a/src/view/aluno/__init__.py b/src/view/aluno/__init__.py index e560d00..7fa4ee2 100644 --- a/src/view/aluno/__init__.py +++ b/src/view/aluno/__init__.py @@ -1,46 +1,23 @@ from src.utils.tk import TKUtils from src.view.aluno.actions import Actions -from src.view.aluno.lista import ListaDeAlunos +from src.view.aluno.listagem import ListaDeAlunos -class Aluno(TKUtils.Container()): +class Aluno(TKUtils.obter_container()): - def __init__(self, master, controller): - super().__init__(master=master) + def __init__(self): + super().__init__() - self.controller = controller + self.defs.pack['side'] = 'bottom' - self.lista = None - self.actions = None + self.actions = Actions() + self.listagem = ListaDeAlunos() - def iniciar(self): - self.criar_actions() - self.criar_listagem_de_alunos() + def iniciar(self, master): + super().iniciar(master=master) - self.lista.iniciar() - self.actions.iniciar() + self.actions.iniciar(master=self) + self.listagem.iniciar(master=self) - self.pack(side='bottom') - - def criar_listagem_de_alunos(self): - eventos = {} - - eventos['sortear'] = self.controller.eventos.sortear - eventos['expandir'] = self.controller.eventos.expandir_label - - self.lista = ListaDeAlunos(master=self, eventos=eventos) - - def criar_actions(self): - eventos = {} - - eventos['sortear'] = self.controller.eventos.sortear - eventos['arquivo'] = self.controller.eventos.carregar_arquivo - - self.actions = Actions(master=self, eventos=eventos) - - def ativar(self): - self.pack_configure(side='bottom') - - def desativar(self): - self.pack_forget() + self.ocultar() diff --git a/src/view/aluno/actions.py b/src/view/aluno/actions.py index 7e7df13..450172e 100644 --- a/src/view/aluno/actions.py +++ b/src/view/aluno/actions.py @@ -1,44 +1,38 @@ from src.utils.tk import TKUtils -class Actions(TKUtils.Container()): +class Actions(TKUtils.obter_container()): - def __init__(self, master, eventos): - super().__init__(master=master, bd=10) + def __init__(self): + super().__init__() - self.eventos = eventos + self.defs.cnf['bd'] = 10 + self.defs.pack['expand'] = True + self.defs.pack['side'] = 'bottom' - self.botao_de_sorteio = None - self.botao_de_carregar_arquivo = None + self.subelemento.sortear = TKUtils.obter_botao() + self.subelemento.arquivo = TKUtils.obter_botao() - def iniciar(self): - self.criar_botao_de_sorteio() - self.criar_botao_de_carregar_arquivo() + def iniciar(self, master): + super().iniciar(master=master) - self.pack(expand=True) + self.inicializar_botao_sorteio() + self.inicializar_botao_carregar_arquivo() - def criar_botao_de_sorteio(self): - cnf, pack = {}, {} + def inicializar_botao_sorteio(self): + self.subelemento.sortear.defs.cnf['text'] = 'Sortear Aluno' + self.subelemento.sortear.defs.cnf['bg'] = 'blue' + self.subelemento.sortear.defs.cnf['width'] = 20 - cnf['text'] = 'Sortear Aluno' - cnf['bg'] = 'blue' - cnf['width'] = 20 - cnf['command'] = lambda evt=None: self.eventos['sortear']({}) + self.subelemento.sortear.defs.pack['side'] = 'left' - pack['side'] = 'left' + self.subelemento.sortear.iniciar(master=self) - self.botao_de_sorteio =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + def inicializar_botao_carregar_arquivo(self): + self.subelemento.arquivo.defs.cnf['text'] = 'Procurar CSV' + self.subelemento.arquivo.defs.cnf['bg'] = 'green' + self.subelemento.arquivo.defs.cnf['width'] = 20 - def criar_botao_de_carregar_arquivo(self): - cnf, pack = {}, {} + self.subelemento.arquivo.defs.pack['side'] = 'right' - cnf['text'] = 'Procurar CSV' - cnf['bg'] = 'green' - cnf['width'] = 20 - cnf['command'] = self.eventos['arquivo'] - - pack['side'] = 'right' - - self.botao_de_carregar_arquivo =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + self.subelemento.arquivo.iniciar(master=self) diff --git a/src/view/aluno/lista.py b/src/view/aluno/lista.py deleted file mode 100644 index 98e33a2..0000000 --- a/src/view/aluno/lista.py +++ /dev/null @@ -1,23 +0,0 @@ -from src.utils.tk import TKUtils -from src.view.listagem import Listagem - - -class ListaDeAlunos(Listagem): - - def __init__(self, master, eventos): - super().__init__(master=master) - - self.eventos = eventos - - def adicionar(self, nome_do_aluno): - elemento = self.criar_elemento(dados=nome_do_aluno) - - cnf, pack = {}, {} - cnf['text'] = nome_do_aluno - cnf['bg'] = 'red' - cnf['width'] = 97 - - elemento.label = self.criar_label(master=elemento, cnf=cnf, pack=pack) - elemento.botao_sortear = self.criar_botao_sortear(master=elemento) - - self.elementos.append(elemento) diff --git a/src/view/aluno/listagem.py b/src/view/aluno/listagem.py new file mode 100644 index 0000000..de497f0 --- /dev/null +++ b/src/view/aluno/listagem.py @@ -0,0 +1,29 @@ +from src.view.listagem import Listagem + + +class ListaDeAlunos(Listagem): + + def __init__(self): + super().__init__() + + def iniciar(self, master): + super().iniciar(master=master) + + def adicionar(self, nome_do_aluno): + elemento = self.criar_elemento(dados=nome_do_aluno) + + elemento.subelemento.label = self.criar_label() + elemento.subelemento.sortear = self.criar_botao_sortear() + + elemento.subelemento.label.defs.cnf['text'] = nome_do_aluno + elemento.subelemento.label.defs.cnf['bg'] = 'red' + elemento.subelemento.label.defs.cnf['width'] = 97 + + elemento.iniciar(master=self.viewport) + + elemento.subelemento.label.iniciar(master=elemento) + elemento.subelemento.sortear.iniciar(master=elemento) + + self.elementos.append(elemento) + + return elemento diff --git a/src/view/atividade/__init__.py b/src/view/atividade/__init__.py index 3af9a49..0dea73a 100644 --- a/src/view/atividade/__init__.py +++ b/src/view/atividade/__init__.py @@ -1,62 +1,25 @@ from src.utils.tk import TKUtils from src.view.atividade.actions import Actions -from src.view.atividade.lista import ListaDeAtividades from src.view.atividade.cadastro import Formulario +from src.view.atividade.listagem import ListaDeAtividades -class Atividade(TKUtils.Container()): +class Atividade(TKUtils.obter_container()): - def __init__(self, master, controller): - super().__init__(master=master) + def __init__(self): + super().__init__() - self.controller = controller + self.defs.pack['side'] = 'bottom' - self.actions = None - self.lista = None - self.janela_de_cadastro = None + self.actions = Actions() + self.cadastro = Formulario() + self.listagem = ListaDeAtividades() - def iniciar(self): - self.criar_actions() - self.criar_listagem_de_atividades() + def iniciar(self, master): + super().iniciar(master=master) - self.lista.iniciar() - self.actions.iniciar() + self.actions.iniciar(master=self) + self.listagem.iniciar(master=self) - self.pack(side='bottom') - - def criar_actions(self): - eventos = {} - - eventos['sortear'] = self.controller.eventos.sortear - eventos['cadastrar'] = self.controller.eventos.cadastrar - - self.actions = Actions(master=self, eventos=eventos) - - def criar_listagem_de_atividades(self): - eventos = {} - - eventos['sortear'] = self.controller.eventos.sortear - eventos['remover'] = self.controller.eventos.remover_atividade - eventos['expandir'] = self.controller.eventos.expandir_label - - self.lista = ListaDeAtividades(master=self, eventos=eventos) - - def criar_janela_de_cadastro(self): - eventos = {} - - eventos['cancelar'] = self.controller.eventos.cancelar_cadastro - eventos['confirmar'] = self.controller.eventos.confirmar_cadastro - - self.janela_de_cadastro = Formulario(eventos=eventos) - self.janela_de_cadastro.iniciar() - - def destruir_janela_de_cadastro(self): - self.janela_de_cadastro.destroy() - self.janela_de_cadastro = None - - def ativar(self): - self.pack_configure(side='bottom') - - def desativar(self): - self.pack_forget() + self.ocultar() diff --git a/src/view/atividade/actions.py b/src/view/atividade/actions.py index 424ee91..5770f0a 100644 --- a/src/view/atividade/actions.py +++ b/src/view/atividade/actions.py @@ -1,43 +1,38 @@ from src.utils.tk import TKUtils -class Actions(TKUtils.Container()): +class Actions(TKUtils.obter_container()): - def __init__(self, master, eventos): - super().__init__(master=master, bd=10) + def __init__(self): + super().__init__() - self.eventos = eventos + self.defs.cnf['bd'] = 10 + self.defs.pack['expand'] = True + self.defs.pack['side'] = 'bottom' - self.botao_de_sorteio = None - self.botao_de_cadastro = None + self.subelemento.sortear = TKUtils.obter_botao() + self.subelemento.cadastrar = TKUtils.obter_botao() - def iniciar(self): - self.criar_botao_de_sorteio() - self.criar_botao_de_cadastro() + def iniciar(self, master): + super().iniciar(master=master) - self.pack(expand=True) + self.inicializar_botao_sorteio() + self.inicializar_botao_cadastro() - def criar_botao_de_sorteio(self): - cnf, pack = {}, {} + def inicializar_botao_sorteio(self): + self.subelemento.sortear.defs.cnf['text'] = 'Sortear Atividade' + self.subelemento.sortear.defs.cnf['bg'] = 'blue' + self.subelemento.sortear.defs.cnf['width'] = 20 - cnf['text'] = 'Sortear Atividade' - cnf['bg'] = 'blue' - cnf['width'] = 20 - cnf['command'] = lambda evt=None: self.eventos['sortear']({}) + self.subelemento.sortear.defs.pack['side'] = 'left' - pack['side'] = 'left' + self.subelemento.sortear.iniciar(master=self) - self.botao_de_sorteio =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + def inicializar_botao_cadastro(self): + self.subelemento.cadastrar.defs.cnf['text'] = 'Cadastrar Atividade' + self.subelemento.cadastrar.defs.cnf['bg'] = 'green' + self.subelemento.cadastrar.defs.cnf['width'] = 20 - def criar_botao_de_cadastro(self): - cnf, pack = {}, {} + self.subelemento.cadastrar.defs.pack['side'] = 'right' - cnf['text'] = 'Cadastrar Atividade' - cnf['bg'] = 'green' - cnf['width'] = 20 - cnf['command'] = self.eventos['cadastrar'] - - pack['side'] = 'right' - - self.botao_de_cadastro = TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + self.subelemento.cadastrar.iniciar(master=self) diff --git a/src/view/atividade/cadastro.py b/src/view/atividade/cadastro.py index 1a1ec53..fd31fdb 100644 --- a/src/view/atividade/cadastro.py +++ b/src/view/atividade/cadastro.py @@ -1,73 +1,70 @@ from src.utils.tk import TKUtils -from src.view.janela_de_cadastro import JanelaDeCadastro +from src.utils.atributo import Atributo + +from src.view.janela_cadastro import JanelaDeCadastro class Formulario(JanelaDeCadastro): - def __init__(self, eventos): - super().__init__(titulo='Cadastrar Atividade') + def __init__(self): + super().__init__() + + self.defs.cnf['title'] = 'Cadastrar Atividade' - self.eventos = eventos + self.subelemento.titulo = Atributo() + self.subelemento.titulo.label = TKUtils.obter_label() + self.subelemento.titulo.input = TKUtils.obter_input() - self.campo_descricao = {} - self.campo_titulo = {} + self.subelemento.descricao = Atributo() + self.subelemento.descricao.label = TKUtils.obter_label() + self.subelemento.descricao.input = TKUtils.obter_input() def iniciar(self): - super().iniciar(texto='Cadastrar', campos=2) + super().iniciar() - self.criar_campo_titulo() - self.criar_campo_descricao() + self.inicializar_campo_titulo() + self.inicializar_campo_descricao() def obter_campos(self): campos = {} - campos['titulo'] = self.campo_titulo['input'].get() - campos['descricao'] = self.campo_descricao['input'].get() + campos['titulo'] = self.subelemento.titulo.input.get() + campos['descricao'] = self.subelemento.descricao.input.get() return campos - def criar_campo_titulo(self): - cnf, grid = {}, {} - - cnf['text'] = 'Titulo' - cnf['pady'] = 4 - - grid['row'] = 0 - grid['column'] = 0 - grid['sticky'] = 'W' - - self.campo_titulo['label'] =\ - TKUtils.obter_label(master=self.corpo, cnf=cnf, grid=grid) - - cnf, grid = {}, {} - - cnf['placeholder'] = 'Capinar um lote' - - grid['row'] = 0 - grid['column'] = 1 + def inicializar_campo_titulo(self): + self.subelemento.titulo.label.defs.cnf['pady'] = 4 + self.subelemento.titulo.label.defs.cnf['text'] = 'Titulo' - self.campo_titulo['input'] =\ - TKUtils.obter_input(master=self.corpo, cnf=cnf, grid=grid) + self.subelemento.titulo.label.defs.grid['row'] = 0 + self.subelemento.titulo.label.defs.grid['column'] = 0 + self.subelemento.titulo.label.defs.grid['sticky'] = 'W' - def criar_campo_descricao(self): - cnf, grid = {}, {} + self.subelemento.titulo.input.defs.cnf['width'] = 30 + self.subelemento.titulo.input.defs.mcnf['focus'] = True + self.subelemento.titulo.input.defs.mcnf['placeholder'] = 'Capinar lote' - cnf['text'] = 'Descrição' - cnf['pady'] = 4 + self.subelemento.titulo.input.defs.grid['row'] = 0 + self.subelemento.titulo.input.defs.grid['column'] = 1 - grid['row'] = 1 - grid['column'] = 0 - grid['sticky'] = 'W' + self.subelemento.titulo.label.iniciar(master=self.subelemento.main) + self.subelemento.titulo.input.iniciar(master=self.subelemento.main) - self.campo_descricao['label'] =\ - TKUtils.obter_label(master=self.corpo, cnf=cnf, grid=grid) + def inicializar_campo_descricao(self): + self.subelemento.descricao.label.defs.cnf['pady'] = 4 + self.subelemento.descricao.label.defs.cnf['text'] = 'Descrição' - cnf, grid = {}, {} + self.subelemento.descricao.label.defs.grid['row'] = 1 + self.subelemento.descricao.label.defs.grid['column'] = 0 + self.subelemento.descricao.label.defs.grid['sticky'] = 'W' - cnf['placeholder'] = 'Programar um drone para capinar um lote' + self.subelemento.descricao.input.defs.cnf['width'] = 30 + self.subelemento.descricao.input.defs.mcnf['placeholder'] =\ + 'Programar um drone para capinar um lote' - grid['row'] = 1 - grid['column'] = 1 + self.subelemento.descricao.input.defs.grid['row'] = 1 + self.subelemento.descricao.input.defs.grid['column'] = 1 - self.campo_descricao['input'] =\ - TKUtils.obter_input(master=self.corpo, cnf=cnf, grid=grid) + self.subelemento.descricao.label.iniciar(master=self.subelemento.main) + self.subelemento.descricao.input.iniciar(master=self.subelemento.main) diff --git a/src/view/atividade/lista.py b/src/view/atividade/lista.py deleted file mode 100644 index f794b92..0000000 --- a/src/view/atividade/lista.py +++ /dev/null @@ -1,91 +0,0 @@ -from src.utils.tk import TKUtils -from src.view.listagem import Listagem - - -class ListaDeAtividades(Listagem): - - def __init__(self, master, eventos): - super().__init__(master=master) - - self.eventos = eventos - - def adicionar(self, atividade): - id_elemento = atividade['id_atividade'] - - elemento = self.criar_elemento(dados=atividade) - - header = TKUtils.obter_container(master=elemento) - body = TKUtils.obter_container(master=elemento) - - elemento.header = self.criar_header(header) - elemento.body = self.criar_body(body) - - self.elementos.append(elemento) - - self.mudar_estado(id_elemento, 'id_atividade', atividade['em_uso']) - - def expandir(self, elemento): - header = elemento.header - body = elemento.body - - if elemento.selecionado: - header.label.configure(width=header.label.cnf['width'], height=2) - - header.botao_sortear.pack_configure(side='left') - header.botao_remover.pack_configure(side='left') - - body.pack_forget() - - elemento.selecionado = False - else: - header.label.configure(width=110, height=3) - - header.botao_remover.pack_forget() - header.botao_sortear.pack_forget() - - body.pack_configure() - - elemento.selecionado = True - - def criar_header(self, header): - id_elemento = header.master.dados['id_atividade'] - - cnf, pack = {}, {} - - cnf['text'] = header.master.dados['titulo'] - cnf['bg'] = 'blue' - cnf['width'] = 92 - pack['side'] = 'left' - - header.label = self.criar_label(master=header, cnf=cnf, pack=pack) - header.botao_sortear = self.criar_botao_sortear(master=header) - header.botao_remover =\ - self.criar_botao_remover(master=header, id_elemento=id_elemento) - - return header - - def criar_body(self, body): - cnf, pack = {}, {} - - cnf['bg'] = 'blue' - cnf['fg'] = 'white' - cnf['height'] = 2 - pack['side'] = 'left' - - cnf['text'] = body.master.dados['descricao'] - cnf['width'] = 82 - - body.label_descricao =\ - TKUtils.obter_label(master=body, cnf=cnf, pack=pack) - body.label_descricao.cnf = cnf - - cnf['text'] = body.master.dados['data_cadastro'].replace(' ', ' as ') - cnf['width'] = 20 - - body.label_data_cadastro =\ - TKUtils.obter_label(master=body, cnf=cnf, pack=pack) - body.label_data_cadastro.cnf = cnf - - body.pack_forget() - - return body diff --git a/src/view/atividade/listagem.py b/src/view/atividade/listagem.py new file mode 100644 index 0000000..758b6b6 --- /dev/null +++ b/src/view/atividade/listagem.py @@ -0,0 +1,85 @@ +from src.utils.tk import TKUtils +from src.view.listagem import Listagem + + +class ListaDeAtividades(Listagem): + + def __init__(self): + super().__init__() + + self.elemento = None + self.elementos = [] + + def iniciar(self, master): + super().iniciar(master=master) + + def adicionar(self, atividade): + self.elemento = self.criar_elemento(dados=atividade) + + self.inicializar_primario() + self.inicializar_secundario() + + self.elemento.subelemento.secundario.ocultar() + + if self.elemento.dados['em_uso']: + self.desativar(elemento=self.elemento) + + self.elementos.append(self.elemento) + self.elemento = None + + return self.elementos[-1] + + def ativar(self, id_atividade='', elemento=None): + if not elemento: + elemento = super().obter(_id=id_atividade)['elemento'] + + elemento.subelemento.primario.subelemento.remover.ativar() + elemento.subelemento.primario.subelemento.sortear.ativar() + + def desativar(self, id_atividade='', elemento=None): + if not elemento: + elemento = super().obter(_id=id_atividade)['elemento'] + + elemento.subelemento.primario.subelemento.remover.desativar() + elemento.subelemento.primario.subelemento.sortear.desativar() + + def inicializar_primario(self): + primario = self.elemento.subelemento.primario + + primario.subelemento.label = self.criar_label() + primario.subelemento.sortear = self.criar_botao_sortear() + primario.subelemento.remover = self.criar_botao_remover() + + primario.subelemento.label.defs.cnf['text'] =\ + self.elemento.dados['titulo'] + primario.subelemento.label.defs.cnf['bg'] = 'blue' + primario.subelemento.label.defs.cnf['width'] = 92 + + primario.subelemento.label.defs.pack['side'] = 'left' + + primario.iniciar(master=self.elemento) + primario.subelemento.label.iniciar(master=primario) + primario.subelemento.sortear.iniciar(master=primario) + primario.subelemento.remover.iniciar(master=primario) + + def inicializar_secundario(self): + secundario = self.elemento.subelemento.secundario + + secundario.subelemento.cadastro = self.criar_label() + secundario.subelemento.descricao = self.criar_label() + + secundario.subelemento.descricao.defs.cnf['text'] =\ + self.elemento.dados['descricao'] + secundario.subelemento.descricao.defs.cnf['width'] = 80 + secundario.subelemento.descricao.defs.cnf['bg'] = 'blue' + + secundario.subelemento.descricao.defs.pack['side'] = 'left' + + secundario.subelemento.cadastro.defs.cnf['text'] =\ + self.elemento.dados['data_cadastro'].replace(' ', ' as ') + secundario.subelemento.cadastro.defs.cnf['width'] = 21 + secundario.subelemento.cadastro.defs.cnf['bg'] = 'blue' + + secundario.iniciar(master=self.elemento) + secundario.subelemento.descricao.iniciar(master=secundario) + secundario.subelemento.cadastro.iniciar(master=secundario) diff --git a/src/view/grupo/__init__.py b/src/view/grupo/__init__.py index 4c11d5d..13fbbd7 100644 --- a/src/view/grupo/__init__.py +++ b/src/view/grupo/__init__.py @@ -2,61 +2,24 @@ from src.view.grupo.actions import Actions from src.view.grupo.cadastro import Formulario -from src.view.grupo.lista import ListaDeGrupos +from src.view.grupo.listagem import ListaDeGrupos -class Grupo(TKUtils.Container()): +class Grupo(TKUtils.obter_container()): - def __init__(self, master, controller): - super().__init__(master=master) + def __init__(self): + super().__init__() - self.controller = controller + self.defs.pack['side'] = 'bottom' - self.actions = None - self.lista = None - self.janela_de_cadastro = None + self.actions = Actions() + self.cadastro = Formulario() + self.listagem = ListaDeGrupos() - def iniciar(self): - self.criar_actions() - self.criar_listagem_de_grupos() + def iniciar(self, master): + super().iniciar(master=master) - self.lista.iniciar() - self.actions.iniciar() + self.actions.iniciar(master=self) + self.listagem.iniciar(master=self) - self.pack(side='bottom') - - def criar_listagem_de_grupos(self): - eventos = {} - - eventos['sortear'] = self.controller.eventos.sortear - eventos['remover'] = self.controller.eventos.remover_grupo - eventos['expandir'] = self.controller.eventos.expandir_label - - self.lista = ListaDeGrupos(master=self, eventos=eventos) - - def criar_actions(self): - eventos = {} - - eventos['sortear'] = self.controller.eventos.sortear - eventos['cadastrar'] = self.controller.eventos.cadastrar - - self.actions = Actions(master=self, eventos=eventos) - - def criar_janela_de_cadastro(self): - eventos = {} - - eventos['cancelar'] = self.controller.eventos.cancelar_cadastro - eventos['confirmar'] = self.controller.eventos.confirmar_cadastro - - self.janela_de_cadastro = Formulario(eventos=eventos) - self.janela_de_cadastro.iniciar() - - def destruir_janela_de_cadastro(self): - self.janela_de_cadastro.destroy() - self.janela_de_cadastro = None - - def ativar(self): - self.pack_configure(side='bottom') - - def desativar(self): - self.pack_forget() + self.ocultar() diff --git a/src/view/grupo/actions.py b/src/view/grupo/actions.py index dc96f7c..33e0cf7 100644 --- a/src/view/grupo/actions.py +++ b/src/view/grupo/actions.py @@ -1,44 +1,38 @@ from src.utils.tk import TKUtils -class Actions(TKUtils.Container()): +class Actions(TKUtils.obter_container()): - def __init__(self, master, eventos): - super().__init__(master=master, bd=10) + def __init__(self): + super().__init__() - self.eventos = eventos + self.defs.cnf['bd'] = 10 + self.defs.pack['expand'] = True + self.defs.pack['side'] = 'bottom' - self.botao_de_sorteio = None - self.botao_de_cadastro = None + self.subelemento.sortear = TKUtils.obter_botao() + self.subelemento.cadastrar = TKUtils.obter_botao() - def iniciar(self): - self.criar_botao_de_sorteio() - self.criar_botao_de_cadastro() + def iniciar(self, master): + super().iniciar(master=master) - self.pack(expand=True) + self.inicializar_botao_sorteio() + self.inicializar_botao_cadastro() - def criar_botao_de_sorteio(self): - cnf, pack = {}, {} + def inicializar_botao_sorteio(self): + self.subelemento.sortear.defs.cnf['text'] = 'Sortear Grupo' + self.subelemento.sortear.defs.cnf['bg'] = 'blue' + self.subelemento.sortear.defs.cnf['width'] = 20 - cnf['text'] = 'Sortear Grupo' - cnf['bg'] = 'blue' - cnf['width'] = 20 - cnf['command'] = lambda evt=None: self.eventos['sortear']({}) + self.subelemento.sortear.defs.pack['side'] = 'left' - pack['side'] = 'left' + self.subelemento.sortear.iniciar(master=self) - self.botao_de_sorteio =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + def inicializar_botao_cadastro(self): + self.subelemento.cadastrar.defs.cnf['text'] = 'Gerar Grupos' + self.subelemento.cadastrar.defs.cnf['bg'] = 'green' + self.subelemento.cadastrar.defs.cnf['width'] = 20 - def criar_botao_de_cadastro(self): - cnf, pack = {}, {} + self.subelemento.cadastrar.defs.pack['side'] = 'right' - cnf['text'] = 'Gerar Grupos' - cnf['bg'] = 'green' - cnf['width'] = 20 - cnf['command'] = self.eventos['cadastrar'] - - pack['side'] = 'right' - - self.botao_de_cadastro =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + self.subelemento.cadastrar.iniciar(master=self) diff --git a/src/view/grupo/cadastro.py b/src/view/grupo/cadastro.py index 695f504..7e5dea4 100644 --- a/src/view/grupo/cadastro.py +++ b/src/view/grupo/cadastro.py @@ -1,73 +1,69 @@ from src.utils.tk import TKUtils -from src.view.janela_de_cadastro import JanelaDeCadastro +from src.utils.atributo import Atributo + +from src.view.janela_cadastro import JanelaDeCadastro class Formulario(JanelaDeCadastro): - def __init__(self, eventos): - super().__init__(titulo='Gerar Grupos') + def __init__(self): + super().__init__() + + self.defs.cnf['title'] = 'Gerar Grupos' - self.eventos = eventos + self.subelemento.nome = Atributo() + self.subelemento.nome.label = TKUtils.obter_label() + self.subelemento.nome.input = TKUtils.obter_input() - self.campo_nome = {} - self.campo_quantidade = {} + self.subelemento.quantidade = Atributo() + self.subelemento.quantidade.label = TKUtils.obter_label() + self.subelemento.quantidade.input = TKUtils.obter_input() def iniciar(self): - super().iniciar(texto='Gerar', campos=2) + super().iniciar() - self.criar_campo_nome() - self.criar_campo_quantidade() + self.inicializar_campo_nome() + self.inicializar_campo_quantidade() def obter_campos(self): campos = {} - campos['nome'] = self.campo_nome['input'].get() - campos['quantidade'] = self.campo_quantidade['input'].get() + campos['nome'] = self.subelemento.nome.input.get() + campos['quantidade'] = self.subelemento.quantidade.input.get() return campos - def criar_campo_nome(self): - cnf, grid = {}, {} - - cnf['text'] = 'Nome' - cnf['pady'] = 4 - - grid['row'] = 0 - grid['column'] = 0 - grid['sticky'] = 'W' - - self.campo_nome['label'] =\ - TKUtils.obter_label(master=self.corpo, cnf=cnf, grid=grid) - - cnf, grid = {}, {} - - cnf['placeholder'] = 'Segundo Periodo' - - grid['row'] = 0 - grid['column'] = 1 + def inicializar_campo_nome(self): + self.subelemento.nome.label.defs.cnf['text'] = 'Nome' + self.subelemento.nome.label.defs.cnf['pady'] = 4 - self.campo_nome['input'] =\ - TKUtils.obter_input(master=self.corpo, cnf=cnf, grid=grid) + self.subelemento.nome.label.defs.grid['row'] = 0 + self.subelemento.nome.label.defs.grid['column'] = 0 + self.subelemento.nome.label.defs.grid['sticky'] = 'W' - def criar_campo_quantidade(self): - cnf, grid = {}, {} + self.subelemento.nome.input.defs.cnf['width'] = 30 + self.subelemento.nome.input.defs.mcnf['focus'] = True + self.subelemento.nome.input.defs.mcnf['placeholder'] = 'Segundo Periodo' - cnf['text'] = 'Quantidade' - cnf['pady'] = 4 + self.subelemento.nome.input.defs.grid['row'] = 0 + self.subelemento.nome.input.defs.grid['column'] = 1 - grid['row'] = 1 - grid['column'] = 0 - grid['sticky'] = 'W' + self.subelemento.nome.input.iniciar(master=self.subelemento.main) + self.subelemento.nome.label.iniciar(master=self.subelemento.main) - self.campo_quantidade['label'] =\ - TKUtils.obter_label(master=self.corpo, cnf=cnf, grid=grid) + def inicializar_campo_quantidade(self): + self.subelemento.quantidade.label.defs.cnf['text'] = 'Quantidade' + self.subelemento.quantidade.label.defs.cnf['pady'] = 4 - cnf, grid = {}, {} + self.subelemento.quantidade.label.defs.grid['row'] = 1 + self.subelemento.quantidade.label.defs.grid['column'] = 0 + self.subelemento.quantidade.label.defs.grid['sticky'] = 'W' - cnf['placeholder'] = '6' + self.subelemento.quantidade.input.defs.cnf['width'] = 30 + self.subelemento.quantidade.input.defs.mcnf['placeholder'] = '6' - grid['row'] = 1 - grid['column'] = 1 + self.subelemento.quantidade.input.defs.grid['row'] = 1 + self.subelemento.quantidade.input.defs.grid['column'] = 1 - self.campo_quantidade['input'] =\ - TKUtils.obter_input(master=self.corpo, cnf=cnf, grid=grid) + self.subelemento.quantidade.input.iniciar(master=self.subelemento.main) + self.subelemento.quantidade.label.iniciar(master=self.subelemento.main) diff --git a/src/view/grupo/lista.py b/src/view/grupo/lista.py deleted file mode 100644 index af7e883..0000000 --- a/src/view/grupo/lista.py +++ /dev/null @@ -1,113 +0,0 @@ -from src.utils.tk import TKUtils -from src.view.listagem import Listagem - - -class ListaDeGrupos(Listagem): - - def __init__(self, master, eventos): - super().__init__(master=master) - - self.eventos = eventos - - def adicionar(self, grupo): - id_elemento = grupo['id_grupo'] - - elemento = self.criar_elemento(dados=grupo) - - header = TKUtils.obter_container(master=elemento) - lista = TKUtils.obter_container(master=elemento) - body = TKUtils.obter_container(master=elemento) - - elemento.header = self.criar_header(header) - elemento.lista = self.criar_lista(lista) - elemento.body = self.criar_body(body) - - self.elementos.append(elemento) - - self.mudar_estado(id_elemento, 'id_grupo', grupo['em_uso']) - - def expandir(self, elemento): - header = elemento.header - lista = elemento.lista - body = elemento.body - - if elemento.selecionado: - header.label.configure(width=header.label.cnf['width'], height=2) - - header.botao_sortear.pack_configure(side='left') - header.botao_remover.pack_configure(side='left') - - lista.pack_forget() - body.pack_forget() - - elemento.selecionado = False - else: - header.label.configure(width=110, height=3) - - header.botao_remover.pack_forget() - header.botao_sortear.pack_forget() - - lista.pack_configure() - body.pack_configure() - - elemento.selecionado = True - - def criar_header(self, header): - id_elemento = header.master.dados['id_grupo'] - - cnf, pack = {}, {} - - cnf['text'] = header.master.dados['nome'] - cnf['bg'] = 'green' - cnf['width'] = 92 - - header.label = self.criar_label(master=header, cnf=cnf, pack=pack) - header.botao_sortear = self.criar_botao_sortear(master=header) - header.botao_remover =\ - self.criar_botao_remover(master=header, id_elemento=id_elemento) - - return header - - def criar_body(self, body): - cnf, pack = {}, {} - - cnf['bg'] = 'green' - cnf['fg'] = 'white' - cnf['height'] = 3 - pack['side'] = 'left' - - cnf['text'] =\ - f'Total de {len(body.master.dados["integrantes"])} integrantes' - cnf['width'] = 82 - - body.integrantes =\ - TKUtils.obter_label(master=body, cnf=cnf, pack=pack) - body.integrantes.cnf = cnf - - cnf['text'] = body.master.dados['data_cadastro'].replace(' ', ' as ') - cnf['width'] = 20 - - body.label_data_cadastro =\ - TKUtils.obter_label(master=body, cnf=cnf, pack=pack) - body.label_data_cadastro.cnf = cnf - - body.pack_forget() - - return body - - def criar_lista(self, lista): - cnf, pack = {}, {} - - cnf['bg'] = 'green' - cnf['fg'] = 'white' - cnf['height'] = 1 - cnf['width'] = 110 - - for integrante in lista.master.dados['integrantes']: - cnf['text'] = integrante - - TKUtils.obter_label(master=lista, cnf=cnf, pack=pack) - - lista.pack_forget() - - return lista diff --git a/src/view/grupo/listagem.py b/src/view/grupo/listagem.py new file mode 100644 index 0000000..267fe1b --- /dev/null +++ b/src/view/grupo/listagem.py @@ -0,0 +1,99 @@ +from src.utils.tk import TKUtils +from src.view.listagem import Listagem + + +class ListaDeGrupos(Listagem): + + def __init__(self): + super().__init__() + + self.elemento = None + self.elementos = [] + + def iniciar(self, master): + super().iniciar(master=master) + + def adicionar(self, grupo): + self.elemento = self.criar_elemento(dados=grupo) + + self.inicializar_primario() + self.inicializar_secundario() + + if self.elemento.dados['em_uso']: + self.desativar(elemento=self.elemento) + + self.elementos.append(self.elemento) + self.elemento = None + + return self.elementos[-1] + + def inicializar_primario(self): + primario = self.elemento.subelemento.primario + + primario.subelemento.label = self.criar_label() + primario.subelemento.sortear = self.criar_botao_sortear() + primario.subelemento.remover = self.criar_botao_remover() + + primario.subelemento.label.defs.cnf['text'] =\ + self.elemento.dados['nome'] + primario.subelemento.label.defs.cnf['width'] = 92 + primario.subelemento.label.defs.cnf['bg'] = 'green' + + primario.iniciar(master=self.elemento) + primario.subelemento.label.iniciar(master=primario) + primario.subelemento.sortear.iniciar(master=primario) + primario.subelemento.remover.iniciar(master=primario) + + def ativar(self, id_atividade='', elemento=None): + if not elemento: + elemento = super().obter(_id=id_atividade)['elemento'] + + elemento.subelemento.primario.subelemento.remover.ativar() + elemento.subelemento.primario.subelemento.sortear.ativar() + + def desativar(self, id_atividade='', elemento=None): + if not elemento: + elemento = super().obter(_id=id_atividade)['elemento'] + + elemento.subelemento.primario.subelemento.remover.desativar() + elemento.subelemento.primario.subelemento.sortear.desativar() + + def inicializar_secundario(self): + secundario = self.elemento.subelemento.secundario + + secundario.subelemento.total = self.criar_label() + secundario.subelemento.cadastro = self.criar_label() + + secundario.subelemento.total.defs.cnf['text'] =\ + f'Total de {len(self.elemento.dados["integrantes"])} integrantes' + secundario.subelemento.total.defs.cnf['width'] = 80 + secundario.subelemento.total.defs.cnf['bg'] = 'green' + + secundario.subelemento.total.defs.pack['side'] = 'left' + + secundario.subelemento.cadastro.defs.cnf['text'] =\ + self.elemento.dados['data_cadastro'].replace(' ', ' as ') + secundario.subelemento.cadastro.defs.cnf['width'] = 21 + secundario.subelemento.cadastro.defs.cnf['bg'] = 'green' + + secundario.iniciar(master=self.elemento) + secundario.subelemento.total.iniciar(master=secundario) + secundario.subelemento.cadastro.iniciar(master=secundario) + + secundario.ocultar() + + def inicializar_integrantes(self, elemento): + elemento.subelemento.integrantes.iniciar(master=elemento) + + for nome in elemento.dados['integrantes']: + integrante = self.criar_label() + + integrante.defs.cnf['text'] = nome + integrante.defs.cnf['width'] = 102 + integrante.defs.cnf['height'] = 1 + integrante.defs.cnf['bg'] = 'green' + + integrante.defs.pack['side'] = 'top' + + integrante.iniciar(master=elemento.subelemento.integrantes) + elemento.subelemento.integrantes.lista.append(integrante) diff --git a/src/view/home/__init__.py b/src/view/home/__init__.py index 77d199c..c016793 100644 --- a/src/view/home/__init__.py +++ b/src/view/home/__init__.py @@ -1,67 +1,26 @@ from src.utils.tk import TKUtils from src.view.home.actions import Actions -from src.view.home.lista import ListaDeElementos -from src.view.home.cadastro import Formulario +from src.view.home.listagem import ListaDeElementos +from src.view.home.cadastro import FormularioApresentacao, FormularioTarefa -class Home(TKUtils.Container()): +class Home(TKUtils.obter_container()): - def __init__(self, master, controller): - super().__init__(master=master) + def __init__(self): + super().__init__() - self.controller = controller + self.defs.pack['side'] = 'bottom' - self.actions = None - self.lista = None - self.janela_de_cadastro = None + self.actions = Actions() + self.listagem = ListaDeElementos() + self.cadastro_tarefa = FormularioTarefa() + self.cadastro_apresentacao = FormularioApresentacao() - def iniciar(self): - self.criar_listagem_de_elementos() - self.criar_actions() + def iniciar(self, master): + super().iniciar(master=master) - self.lista.iniciar() - self.actions.iniciar() + self.actions.iniciar(master=self) + self.listagem.iniciar(master=self) - self.pack(side='bottom') - - def criar_listagem_de_elementos(self): - eventos = {} - - eventos['expandir'] = self.controller.eventos.expandir_label - eventos['remover'] = self.controller.eventos.remover_apresentacao - - self.lista = ListaDeElementos(master=self, eventos=eventos) - - def destruir_lista_de_elementos(self): - for elemento in self.lista.elementos: - elemento.destroy() - - self.lista.elementos = [] - - def criar_actions(self): - eventos = {} - - eventos['ordenar'] = self.controller.eventos.ordenar_lista - eventos['cadastrar'] = self.controller.eventos.cadastrar_apresentacao - - self.actions = Actions(master=self, eventos=eventos) - - def criar_janela_de_cadastro(self): - eventos = {} - - eventos['cancelar'] = self.controller.eventos.cancelar_cadastro - eventos['confirmar'] = self.controller.eventos.confirmar_cadastro - - self.janela_de_cadastro = Formulario(eventos=eventos) - self.janela_de_cadastro.iniciar() - - def destruir_janela_de_cadastro(self): - self.janela_de_cadastro.destroy() - self.janela_de_cadastro = None - - def ativar(self): - self.pack_configure(side='bottom') - - def desativar(self): - self.pack_forget() + self.ocultar() diff --git a/src/view/home/actions.py b/src/view/home/actions.py index b212ba7..64d3226 100644 --- a/src/view/home/actions.py +++ b/src/view/home/actions.py @@ -1,44 +1,38 @@ from src.utils.tk import TKUtils -class Actions(TKUtils.Container()): +class Actions(TKUtils.obter_container()): - def __init__(self, master, eventos): - super().__init__(master=master, bd=10) + def __init__(self): + super().__init__() - self.eventos = eventos + self.defs.cnf['bd'] = 10 + self.defs.pack['expand'] = True + self.defs.pack['side'] = 'bottom' - self.botao_ordenar = None - self.botao_cadastrar = None + self.subelemento.tarefa = TKUtils.obter_botao() + self.subelemento.cadastrar = TKUtils.obter_botao() - def iniciar(self): - self.criar_botao_ordenar() - self.criar_botao_cadastrar() + def iniciar(self, master): + super().iniciar(master=master) - self.pack(expand=True) + self.inicializar_botao_cadastro() + self.inicializar_botao_cadastro_tarefa() - def criar_botao_ordenar(self): - cnf, pack = {}, {} + def inicializar_botao_cadastro(self): + self.subelemento.cadastrar.defs.cnf['text'] = 'Cadastrar Apresentação' + self.subelemento.cadastrar.defs.cnf['bg'] = 'green' + self.subelemento.cadastrar.defs.cnf['width'] = 30 - cnf['text'] = 'Ordenar Apresentações' - cnf['bg'] = 'blue' - cnf['width'] = 30 - cnf['command'] = self.eventos['ordenar'] + self.subelemento.cadastrar.defs.pack['side'] = 'right' - pack['side'] = 'left' + self.subelemento.cadastrar.iniciar(master=self) - self.botao_ordenar =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + def inicializar_botao_cadastro_tarefa(self): + self.subelemento.tarefa.defs.cnf['text'] = 'Cadastrar Tarefa' + self.subelemento.tarefa.defs.cnf['bg'] = 'blue' + self.subelemento.tarefa.defs.cnf['width'] = 30 - def criar_botao_cadastrar(self): - cnf, pack = {}, {} + self.subelemento.tarefa.defs.pack['side'] = 'left' - cnf['text'] = 'Cadastrar Apresentação' - cnf['bg'] = 'green' - cnf['width'] = 30 - cnf['command'] = self.eventos['cadastrar'] - - pack['side'] = 'left' - - self.botao_cadastrar =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + self.subelemento.tarefa.iniciar(master=self) diff --git a/src/view/home/cadastro.py b/src/view/home/cadastro.py index ed23d48..95cd9ac 100644 --- a/src/view/home/cadastro.py +++ b/src/view/home/cadastro.py @@ -1,73 +1,89 @@ -from src.utils.tk import TKUtils from src.utils import Utils -from src.view.janela_de_cadastro import JanelaDeCadastro +from src.utils.tk import TKUtils +from src.utils.atributo import Atributo + +from src.view.janela_cadastro import JanelaDeCadastro -class Formulario(JanelaDeCadastro): +class FormularioApresentacao(JanelaDeCadastro): - def __init__(self, eventos): - super().__init__(titulo='Cadastrar Apresentação') + def __init__(self): + super().__init__() - self.eventos = eventos + self.defs.cnf['title'] = 'Cadastrar Apresentação' - self.campo_data = {} - self.campo_duracao = {} + self.subelemento.data = Atributo() + self.subelemento.data.label = TKUtils.obter_label() + self.subelemento.data.input = TKUtils.obter_input() + + self.subelemento.duracao = Atributo() + self.subelemento.duracao.label = TKUtils.obter_label() + self.subelemento.duracao.input = TKUtils.obter_input() def iniciar(self): - super().iniciar(texto='Criar', campos=2) + super().iniciar() - self.criar_campo_duracao(linha=0) - self.criar_campo_data(linha=1) + self.inicializar_campo_data() + self.inicializar_campo_duracao() def obter_campos(self): campos = {} - campos['duracao'] = self.campo_duracao['input'].get() - campos['data_apresentacao'] = self.campo_data['input'].get() + campos['duracao'] = self.subelemento.duracao.input.get() + campos['data_apresentacao'] = self.subelemento.data.input.get() return campos - def criar_campo_data(self, linha): - cnf, grid = {}, {} + def inicializar_campo_data(self): + self.subelemento.data.label.defs.cnf['text'] = 'Data' + self.subelemento.data.label.defs.cnf['pady'] = 4 + + self.subelemento.data.label.defs.grid['row'] = 0 + self.subelemento.data.label.defs.grid['column'] = 0 + self.subelemento.data.label.defs.grid['sticky'] = 'W' - cnf['text'] = 'Apresentação' - cnf['pady'] = 4 - cnf['padx'] = 8 + self.subelemento.data.input.defs.cnf['width'] = 30 + self.subelemento.data.input.defs.mcnf['focus'] = True + self.subelemento.data.input.defs.mcnf['placeholder'] =\ + Utils.data_e_hora_atual().split(' ')[0] - grid['row'] = linha - grid['column'] = 0 - grid['sticky'] = 'W' + self.subelemento.data.input.defs.grid['row'] = 0 + self.subelemento.data.input.defs.grid['column'] = 1 - self.campo_data['label'] =\ - TKUtils.obter_label(master=self.corpo, cnf=cnf, grid=grid) + self.subelemento.data.input.iniciar(master=self.subelemento.main) + self.subelemento.data.label.iniciar(master=self.subelemento.main) - cnf, grid = {}, {} - cnf['placeholder'] = Utils.obter_data_e_hora_atual().split(' ')[0] + def inicializar_campo_duracao(self): + self.subelemento.duracao.label.defs.cnf['text'] = 'Duração' + self.subelemento.duracao.label.defs.cnf['pady'] = 4 - grid['row'] = linha - grid['column'] = 1 + self.subelemento.duracao.label.defs.grid['row'] = 1 + self.subelemento.duracao.label.defs.grid['column'] = 0 + self.subelemento.duracao.label.defs.grid['sticky'] = 'W' - self.campo_data['input'] =\ - TKUtils.obter_input(master=self.corpo, cnf=cnf, grid=grid) + self.subelemento.duracao.input.defs.cnf['width'] = 30 + self.subelemento.duracao.input.defs.mcnf['placeholder'] = '20' - def criar_campo_duracao(self, linha): - cnf, grid = {}, {} + self.subelemento.duracao.input.defs.grid['row'] = 1 + self.subelemento.duracao.input.defs.grid['column'] = 1 - cnf['text'] = 'Duração' - cnf['pady'] = 4 - cnf['padx'] = 8 + self.subelemento.duracao.input.iniciar(master=self.subelemento.main) + self.subelemento.duracao.label.iniciar(master=self.subelemento.main) - grid['row'] = linha - grid['column'] = 0 - grid['sticky'] = 'W' - self.campo_duracao['label'] =\ - TKUtils.obter_label(master=self.corpo, cnf=cnf, grid=grid) +class FormularioTarefa(FormularioApresentacao): - cnf, grid = {}, {} - cnf['placeholder'] = '20' + def __init__(self): + super().__init__() - grid['row'] = linha - grid['column'] = 1 + self.defs.cnf['title'] = 'Cadastrar Tarefa' - self.campo_duracao['input'] =\ - TKUtils.obter_input(master=self.corpo, cnf=cnf, grid=grid) + def iniciar(self): + super().iniciar() + + def obter_campos(self): + campos = super().obter_campos() + + campos['data_tarefa'] = campos['data_apresentacao'] + del campos['data_apresentacao'] + + return campos diff --git a/src/view/home/lista.py b/src/view/home/lista.py deleted file mode 100644 index e241384..0000000 --- a/src/view/home/lista.py +++ /dev/null @@ -1,87 +0,0 @@ -from src.utils.tk import TKUtils -from src.view.listagem import Listagem - - -class ListaDeElementos(Listagem): - - def __init__(self, master, eventos): - super().__init__(master=master) - - self.eventos = eventos - - def adicionar(self, apresentacao): - elemento = self.criar_elemento(dados=apresentacao) - - header = TKUtils.obter_container(master=elemento) - body = TKUtils.obter_container(master=elemento) - - elemento.header = self.criar_header(header) - elemento.body = self.criar_body(body) - - self.elementos.append(elemento) - - def expandir(self, elemento): - header = elemento.header - body = elemento.body - - if elemento.selecionado: - header.label.configure(width=header.label.cnf['width'], height=2) - - header.botao_remover.pack_configure(side='left') - - body.pack_forget() - - elemento.selecionado = False - else: - header.label.configure(width=110, height=3) - - header.botao_remover.pack_forget() - - body.pack_configure() - - elemento.selecionado = True - - def criar_header(self, header): - id_elemento = header.master.dados['id_apresentacao'] - - cnf, pack = {}, {} - - cnf['text'] = header.master.dados['titulo'] - cnf['bg'] = 'orange' - cnf['width'] = 97 - pack['side'] = 'left' - - header.label = self.criar_label(master=header, cnf=cnf, pack=pack) - header.botao_remover =\ - self.criar_botao_remover(master=header, id_elemento=id_elemento) - - return header - - def criar_body(self, body): - cnf, pack = {}, {} - - cnf['bg'] = 'orange' - cnf['fg'] = 'white' - cnf['height'] = 2 - pack['side'] = 'left' - - data_apresentacao = body.master.dados['data_apresentacao'] - duracao = body.master.dados['duracao'] - cnf['text'] = f'Apresentação marcada para {data_apresentacao}' - cnf['text'] += f' com duração prevista de {duracao} minutos' - cnf['width'] = 82 - - body.label_data_apresentacao =\ - TKUtils.obter_label(master=body, cnf=cnf, pack=pack) - body.label_data_apresentacao.cnf = cnf - - cnf['text'] = body.master.dados['data_cadastro'].replace(' ', ' as ') - cnf['width'] = 20 - - body.label_data_cadastro =\ - TKUtils.obter_label(master=body, cnf=cnf, pack=pack) - body.label_data_cadastro.cnf = cnf - - body.pack_forget() - - return body diff --git a/src/view/home/listagem.py b/src/view/home/listagem.py new file mode 100644 index 0000000..03ab505 --- /dev/null +++ b/src/view/home/listagem.py @@ -0,0 +1,74 @@ +from src.utils.tk import TKUtils +from src.view.listagem import Listagem + + +class ListaDeElementos(Listagem): + + def __init__(self): + super().__init__() + + self.elemento = None + self.elementos = [] + + def iniciar(self, master): + super().iniciar(master=master) + + def adicionar(self, apresentacao=None, tarefa=None): + dados = tarefa if tarefa else apresentacao + self.elemento = self.criar_elemento(dados) + + self.inicializar_primario() + self.inicializar_secundario() + + self.elementos.append(self.elemento) + self.elemento = None + + return self.elementos[-1] + + def inicializar_primario(self): + primario = self.elemento.subelemento.primario + + primario.subelemento.label = self.criar_label() + primario.subelemento.remover = self.criar_botao_remover() + + primario.subelemento.label.defs.cnf['text'] =\ + self.elemento.dados['titulo'] + primario.subelemento.label.defs.cnf['width'] = 97 + primario.subelemento.label.defs.cnf['bg'] = 'orange' + + primario.iniciar(master=self.elemento) + primario.subelemento.label.iniciar(master=primario) + primario.subelemento.remover.iniciar(master=primario) + + def inicializar_secundario(self): + secundario = self.elemento.subelemento.secundario + + secundario.subelemento.cadastro = self.criar_label() + secundario.subelemento.apresentacao = self.criar_label() + + if 'data_tarefa' in self.elemento.dados: + data = self.elemento.dados['data_tarefa'] + else: + data = self.elemento.dados['data_apresentacao'] + + secundario.subelemento.apresentacao.defs.cnf['text'] = ( + 'Apresentação marcada para ' + data + ' com duração prevista de ' + + str(self.elemento.dados['duracao']) + ' minutos' + ) + secundario.subelemento.apresentacao.defs.cnf['width'] = 82 + secundario.subelemento.apresentacao.defs.cnf['bg'] = 'orange' + + secundario.subelemento.apresentacao.defs.pack['side'] = 'left' + + secundario.subelemento.cadastro.defs.cnf['text'] =\ + self.elemento.dados['data_cadastro'].replace(' ', ' as ') + secundario.subelemento.cadastro.defs.cnf['width'] = 20 + secundario.subelemento.cadastro.defs.cnf['bg'] = 'orange' + + secundario.subelemento.cadastro.defs.pack['side'] = 'right' + + secundario.iniciar(master=self.elemento) + secundario.subelemento.cadastro.iniciar(master=secundario) + secundario.subelemento.apresentacao.iniciar(master=secundario) + + secundario.ocultar() diff --git a/src/view/janela_cadastro.py b/src/view/janela_cadastro.py new file mode 100644 index 0000000..fe28920 --- /dev/null +++ b/src/view/janela_cadastro.py @@ -0,0 +1,59 @@ +""".""" + +from src.utils.tk import TKUtils + + +class JanelaDeCadastro(TKUtils.obter_janela()): + """.""" + + def __init__(self, campos: int=2) -> None: + """.""" + super().__init__() + + self.defs.qtd_campos = campos + self.defs.cnf['geometry'] = f'420x{campos * 120}' + + self.subelemento.main = TKUtils.obter_container(instanciar=True) + self.subelemento.cancelar = TKUtils.obter_botao() + self.subelemento.confirmar = TKUtils.obter_botao() + + def iniciar(self) -> None: + """.""" + super().iniciar() + + self.criar_container_main() + self.criar_botao_cancelar() + self.criar_botao_confirmar() + + def criar_container_main(self) -> None: + """.""" + self.subelemento.main.defs.cnf['bd'] = 10 + self.subelemento.main.defs.cnf['padx'] = 8 + + self.subelemento.main.defs.grid['sticky'] = 'WE' + + self.subelemento.main.iniciar(master=self) + + def criar_botao_cancelar(self) -> None: + """.""" + self.subelemento.cancelar.defs.cnf['text'] = 'Cancelar' + self.subelemento.cancelar.defs.cnf['bg'] = 'red' + + self.subelemento.cancelar.defs.grid['row'] = self.defs.qtd_campos + self.subelemento.cancelar.defs.grid['column'] = 0 + self.subelemento.cancelar.defs.grid['pady'] = 100 + self.subelemento.cancelar.defs.grid['sticky'] = 'W' + + self.subelemento.cancelar.iniciar(master=self.subelemento.main) + + def criar_botao_confirmar(self) -> None: + """.""" + self.subelemento.confirmar.defs.cnf['text'] = 'Confirmar' + self.subelemento.confirmar.defs.cnf['bg'] = 'green' + + self.subelemento.confirmar.defs.grid['row'] = self.defs.qtd_campos + self.subelemento.confirmar.defs.grid['column'] = 1 + self.subelemento.confirmar.defs.grid['pady'] = 100 + self.subelemento.confirmar.defs.grid['sticky'] = 'E' + + self.subelemento.confirmar.iniciar(master=self.subelemento.main) diff --git a/src/view/janela_de_cadastro.py b/src/view/janela_de_cadastro.py deleted file mode 100644 index 00faec3..0000000 --- a/src/view/janela_de_cadastro.py +++ /dev/null @@ -1,59 +0,0 @@ -from src.utils.tk import TKUtils - - -class JanelaDeCadastro(TKUtils.Janela()): - - def __init__(self, titulo): - super().__init__() - - self.eventos = None - self.titulo = titulo - - self.corpo = None - self.botao_cancelar = None - self.botao_confirmar = None - - def iniciar(self, texto, campos): - self.texto = texto - self.quantidade_de_campos = campos - - self.title(self.titulo) - self.geometry('360x280') - self.resizable(0, 0) - - self.criar_corpo() - - self.criar_botao_cancelar() - self.criar_botao_confirmar() - - def criar_corpo(self): - self.corpo = TKUtils.obter_container(master=self, cnf={'bd': 10}) - - def criar_botao_cancelar(self): - cnf, grid = {}, {} - - cnf['text'] = 'Cancelar' - cnf['bg'] = 'red' - cnf['command'] = self.eventos['cancelar'] - - grid['row'] = self.quantidade_de_campos - grid['column'] = 0 - grid['sticky'] = 'W' - - self.botao_cancelar =\ - TKUtils.obter_botao(master=self.corpo, cnf=cnf, grid=grid) - - def criar_botao_confirmar(self): - cnf, grid = {}, {} - - cnf['text'] = self.texto - cnf['bg'] = 'green' - cnf['command'] = self.eventos['confirmar'] - - grid['row'] = self.quantidade_de_campos - grid['column'] = 1 - grid['sticky'] = 'E' - grid['pady'] = 200 - self.quantidade_de_campos * 24 - - self.botao_confirmar =\ - TKUtils.obter_botao(master=self.corpo, cnf=cnf, grid=grid) diff --git a/src/view/janela_de_erro.py b/src/view/janela_de_erro.py deleted file mode 100644 index 108e9df..0000000 --- a/src/view/janela_de_erro.py +++ /dev/null @@ -1,53 +0,0 @@ -from src.utils.tk import TKUtils - - -class JanelaDeErro(TKUtils.Janela()): - - def __init__(self, erro): - super().__init__() - - self.title('Janela de Erro') - self.geometry(f'{len(erro) * 16}x140') - self.resizable(0, 0) - - self.msg_de_erro = erro - - self.container = None - self.label_de_erro = None - self.botao_confirmar = None - - self.criar_container() - - def criar_container(self): - cnf = {} - cnf['bd'] = 10 - - self.container = TKUtils.obter_container(master=self, cnf=cnf) - - self.criar_label_de_erro() - self.criar_botao_confirmar() - - def criar_label_de_erro(self): - cnf, pack = {}, {} - - cnf['text'] = self.msg_de_erro - cnf['fg'] = 'red' - cnf['font'] = ('arial', 16, 'bold') - - pack['pady'] = 10 - - self.label_de_erro =\ - TKUtils.obter_label(master=self, cnf=cnf, pack=pack) - - def criar_botao_confirmar(self): - cnf, pack = {}, {} - - cnf['text'] = 'OK' - cnf['bg'] = 'green' - cnf['command'] = self.destroy - - pack['pady'] = 25 - pack['side'] = 'bottom' - - self.botao_confirmar =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) diff --git a/src/view/janela_de_sorteio.py b/src/view/janela_de_sorteio.py deleted file mode 100644 index 055d350..0000000 --- a/src/view/janela_de_sorteio.py +++ /dev/null @@ -1,40 +0,0 @@ -from src.utils.tk import TKUtils - - -class JanelaDeSorteio(TKUtils.Janela()): - - def __init__(self, elemento, atividade): - super().__init__() - - self.elemento = elemento - self.atividade = atividade - - self.container = None - self.label_do_elemento = None - self.label_da_atividade = None - - def iniciar(self): - self.title('Grande Felizardo(a)') - self.geometry(f'{len(self.elemento) * 18 + 100}x100') - self.resizable(0, 0) - - self.container = self.criar_container() - - texto = f'Aluno: {self.elemento}' - self.label_do_elemento = self.criar_label(texto=texto, cor='red') - - texto = f'Atividade: {self.atividade["titulo"]}' - self.label_do_elemento = self.criar_label(texto=texto, cor='green') - - def criar_container(self): - return TKUtils.obter_container(master=self) - - def criar_label(self, texto, cor): - cnf, pack = {}, {} - - cnf['text'] = texto - cnf['bd'] = 4 - cnf['fg'] = cor - cnf['font'] = ('times new roman', 22, 'bold') - - return TKUtils.obter_label(master=self.container, cnf=cnf, pack=pack) diff --git a/src/view/janela_erro.py b/src/view/janela_erro.py new file mode 100644 index 0000000..a1df86a --- /dev/null +++ b/src/view/janela_erro.py @@ -0,0 +1,57 @@ +""".""" + +from src.utils.tk import TKUtils + + +class JanelaDeErro(TKUtils.obter_janela()): + """.""" + + def __init__(self) -> None: + """.""" + super().__init__() + + self.defs.cnf['title'] = 'Janela de Erro' + self.defs.cnf['geometry'] = '340x200' + + self.subelemento.main = TKUtils.obter_container(instanciar=True) + self.subelemento.mensagem = TKUtils.obter_mensagem() + self.subelemento.confirmar = TKUtils.obter_botao() + + def iniciar(self, erro: str) -> None: + """.""" + super().iniciar() + + self.msg_erro = erro + + self.inicializar_container_main() + self.inicializar_mensagem_erro() + self.inicializar_botao_confirmar() + + def inicializar_container_main(self) -> None: + """.""" + self.subelemento.main.defs.cnf['bd'] = 10 + self.subelemento.main.defs.pack['expand'] = True + + self.subelemento.main.iniciar(master=self) + + def inicializar_mensagem_erro(self) -> None: + """.""" + self.subelemento.mensagem.defs.cnf['text'] = self.msg_erro + self.subelemento.mensagem.defs.cnf['fg'] = 'red' + self.subelemento.mensagem.defs.cnf['width'] = 320 + self.subelemento.mensagem.defs.mcnf['fz'] = 20 + + self.subelemento.mensagem.defs.pack['pady'] = 10 + + self.subelemento.mensagem.iniciar(master=self.subelemento.main) + + def inicializar_botao_confirmar(self) -> None: + """.""" + self.subelemento.confirmar.defs.cnf['text'] = 'OK' + self.subelemento.confirmar.defs.cnf['bg'] = 'green' + self.subelemento.confirmar.defs.cnf['command'] = self.destroy + + self.subelemento.confirmar.defs.pack['pady'] = 25 + self.subelemento.confirmar.defs.pack['side'] = 'bottom' + + self.subelemento.confirmar.iniciar(master=self.subelemento.main) diff --git a/src/view/janela_sorteio.py b/src/view/janela_sorteio.py new file mode 100644 index 0000000..583c026 --- /dev/null +++ b/src/view/janela_sorteio.py @@ -0,0 +1,80 @@ +""".""" + +from src.utils.tk import TKUtils + + +class JanelaDeSorteio(TKUtils.obter_janela()): + """.""" + + def __init__(self) -> None: + """.""" + super().__init__() + + self.defs.cnf['title'] = 'Grande Felizardo(a)' + self.defs.cnf['geometry'] = f'600x180' + + self.subelemento.main = TKUtils.obter_container(instanciar=True) + self.subelemento.sorteado = TKUtils.obter_label() + self.subelemento.atividade = TKUtils.obter_label() + self.subelemento.confirmar = TKUtils.obter_botao() + self.subelemento.cancelar = TKUtils.obter_botao() + + def iniciar(self, atividade: str, evento, grupo='', aluno='') -> None: + """.""" + super().iniciar() + + self.evento = evento + self.sorteado = grupo if grupo else aluno + self.atividade = atividade + + self.criar_container_main() + self.criar_label_sorteado() + self.criar_label_atividade() + self.criar_botao_cancelar() + self.criar_botao_confirmar() + + def criar_container_main(self) -> None: + """.""" + self.subelemento.main.defs.cnf['bd'] = 10 + self.subelemento.main.iniciar(master=self) + + def criar_label_sorteado(self) -> None: + """.""" + self.subelemento.sorteado.defs.cnf['text'] = self.sorteado + self.subelemento.sorteado.defs.cnf['bd'] = 4 + self.subelemento.sorteado.defs.mcnf['fz'] = 22 + self.subelemento.sorteado.defs.cnf['fg'] =\ + 'red' if 'Aluno' in self.sorteado else 'green' + + self.subelemento.sorteado.iniciar(master=self.subelemento.main) + + def criar_label_atividade(self) -> None: + """.""" + self.subelemento.atividade.defs.cnf['text'] = self.atividade['titulo'] + self.subelemento.atividade.defs.cnf['bd'] = 4 + self.subelemento.atividade.defs.mcnf['fz'] = 22 + self.subelemento.atividade.defs.cnf['fg'] = 'blue' + + self.subelemento.atividade.iniciar(master=self.subelemento.main) + + def criar_botao_confirmar(self) -> None: + """.""" + self.subelemento.confirmar.defs.cnf['text'] = 'Confirmar' + self.subelemento.confirmar.defs.cnf['bg'] = 'green' + self.subelemento.confirmar.defs.cnf['command'] = self.evento + + self.subelemento.confirmar.defs.pack['pady'] = 15 + self.subelemento.confirmar.defs.pack['side'] = 'right' + + self.subelemento.confirmar.iniciar(master=self.subelemento.main) + + def criar_botao_cancelar(self) -> None: + """.""" + self.subelemento.cancelar.defs.cnf['text'] = 'Cancelar' + self.subelemento.cancelar.defs.cnf['bg'] = 'red' + self.subelemento.cancelar.defs.cnf['command'] = self.destroy + + self.subelemento.cancelar.defs.pack['pady'] = 15 + self.subelemento.cancelar.defs.pack['side'] = 'left' + + self.subelemento.cancelar.iniciar(master=self.subelemento.main) diff --git a/src/view/listagem.py b/src/view/listagem.py index 0661af2..b612dfc 100644 --- a/src/view/listagem.py +++ b/src/view/listagem.py @@ -1,128 +1,114 @@ from src.utils.tk import TKUtils -class Listagem(TKUtils.ScrollContainer()): +class Listagem(TKUtils.obter_scrollview()): - def __init__(self, master): - cnf, canvas_cnf, viewport_cnf, scrollbar_cnf = {}, {}, {}, {} + def __init__(self): + super().__init__() - cnf['bd'] = 2 - cnf['bg'] = 'grey' - cnf['relief'] = 'flat' + self.defs.cnf['bd'] = 2 + self.defs.cnf['bg'] = 'grey' + self.defs.cnf['relief'] = 'flat' - canvas_cnf['width'] = 920 - canvas_cnf['height'] = 360 + self.defs.pack['expand'] = True + self.defs.pack['side'] = 'bottom' - scrollbar_cnf['bd'] = 4 - scrollbar_cnf['bg'] = 'grey' - scrollbar_cnf['relief'] = 'flat' + self.defs.canvas['width'] = 920 + self.defs.canvas['height'] = 360 - super().__init__(master=master, cnf=cnf, cs_cnf=canvas_cnf, - vt_cnf=viewport_cnf, sr_cnf=scrollbar_cnf) + self.defs.scrollbar['bd'] = 4 + self.defs.scrollbar['bg'] = 'grey' + self.defs.scrollbar['relief'] = 'flat' + self.elemento = None self.elementos = [] + self.classe_pai = '' - def iniciar(self): - self.pack(expand=True) + def iniciar(self, master): + super().iniciar(master=master) + self.classe_pai = master.__str__().replace('.!', '') - def mudar_estado(self, id_elemento, chave, desativar=True): - for elemento in self.elementos: - if elemento.dados[chave] == id_elemento: - if desativar: - self.desativar_elemento(elemento=elemento) - else: - self.ativar_elemento(elemento=elemento) - return + def obter(self, _id, chave=''): + if not chave: + chave = f'id_{self.classe_pai}' - def remover_elemento(self, id_elemento, chave): for i, elemento in enumerate(self.elementos): - if elemento.dados[chave] == id_elemento: - elemento.destroy() - del self.elementos[i] + if chave in elemento.dados and elemento.dados[chave] == _id: + return {'elemento': elemento, 'index': i} - def ativar_elemento(self, elemento): - header = elemento.header + def remover(self, _id, chave=''): + resultado = self.obter(_id, chave) - header.label.configure(bg=header.label.cnf['bg']) + resultado['elemento'].destroy() + del self.elementos[resultado['index']] - if 'botao_remover' in dir(header): - header.botao_remover.configure(state='normal', bg='red') - if 'botao_sortear' in dir(header): - header.botao_sortear.configure(state='normal', bg='orange') - - elemento.desativado = False + def criar_elemento(self, dados): + instanciar = True - def desativar_elemento(self, elemento): - header = elemento.header + elemento = TKUtils.obter_container(instanciar) + elemento.subelemento.primario = TKUtils.obter_container(instanciar) + elemento.subelemento.secundario = TKUtils.obter_container(instanciar) - header.label.configure(bg='grey') + elemento.defs.cnf['bd'] = 2 + elemento.defs.cnf['bg'] = 'grey' + elemento.defs.cnf['relief'] = 'ridge' - if 'botao_remover' in dir(header): - header.botao_remover.configure(state='disabled', bg='grey') - if 'botao_sortear' in dir(header): - header.botao_sortear.configure(state='disabled', bg='grey') + elemento.dados = dados - elemento.desativado = True + elemento.subelemento.primario.defs.cnf['bd'] = 1 + elemento.subelemento.primario.defs.cnf['bg'] = 'grey' + elemento.subelemento.primario.defs.cnf['relief'] = 'ridge' - def criar_elemento(self, dados): - cnf = {} + elemento.subelemento.primario.defs.pack['side'] = 'top' - cnf['bd'] = 2 - cnf['bg'] = 'grey' - cnf['relief'] = 'ridge' + elemento.subelemento.secundario.defs.cnf['bd'] = 1 + elemento.subelemento.secundario.defs.cnf['bg'] = 'grey' + elemento.subelemento.secundario.defs.cnf['relief'] = 'ridge' - container = TKUtils.obter_container(master=self.viewport, cnf=cnf) + elemento.subelemento.secundario.defs.pack['side'] = 'bottom' - container.desativado = False - container.selecionado = False + if self.classe_pai == 'grupo': + elemento.subelemento.integrantes =\ + TKUtils.obter_container(instanciar) + elemento.subelemento.integrantes.defs.cnf['bd'] = 1 + elemento.subelemento.integrantes.defs.cnf['bg'] = 'grey' + elemento.subelemento.integrantes.defs.cnf['relief'] = 'ridge' + elemento.subelemento.integrantes.lista = [] - container.dados = dados + elemento.iniciar(master=self.viewport) - return container + return elemento - def criar_label(self, master, cnf={}, pack={}): - cnf['fg'] = 'white' - cnf['height'] = 2 + def criar_label(self): + label = TKUtils.obter_label() - pack['side'] = 'left' + label.defs.cnf['fg'] = 'white' + label.defs.cnf['height'] = 2 - label = TKUtils.obter_label(master=master, cnf=cnf, pack=pack) - label.cnf = cnf - - comando = self.eventos['expandir'] - label.bind('', lambda evt=None: comando(evt, master.master)) + label.defs.pack['side'] = 'left' return label - def criar_botao_sortear(self, master, cnf={}, pack={}): - if 'dados' in dir(master.master): - dados = master.master.dados - else: - dados = master.dados - - cnf['text'] = 'O' - cnf['bg'] = 'orange' - cnf['bd'] = 4 - cnf['width'] = 2 - cnf['command'] = lambda evt=None: self.eventos['sortear'](valor=dados) + def criar_botao_sortear(self): + botao = TKUtils.obter_botao() - pack['side'] = 'left' + botao.defs.cnf['text'] = 'O' + botao.defs.cnf['bg'] = 'orange' + botao.defs.cnf['bd'] = 4 + botao.defs.cnf['width'] = 2 - botao = TKUtils.obter_botao(master=master, cnf=cnf, pack=pack) - botao.cnf = cnf + botao.defs.pack['side'] = 'left' return botao - def criar_botao_remover(self, master, id_elemento, cnf={}, pack={}): - cnf['text'] = 'X' - cnf['bg'] = 'red' - cnf['bd'] = 4 - cnf['width'] = 2 - cnf['command'] = lambda evt=None: self.eventos['remover'](id_elemento) + def criar_botao_remover(self): + botao = TKUtils.obter_botao() - pack['side'] = 'left' + botao.defs.cnf['text'] = 'X' + botao.defs.cnf['bg'] = 'red' + botao.defs.cnf['bd'] = 4 + botao.defs.cnf['width'] = 2 - botao = TKUtils.obter_botao(master=master, cnf=cnf, pack=pack) - botao.cnf = cnf + botao.defs.pack['side'] = 'right' return botao diff --git a/src/view/navbar.py b/src/view/navbar.py index 5551cff..3cfa255 100644 --- a/src/view/navbar.py +++ b/src/view/navbar.py @@ -1,95 +1,79 @@ from src.utils.tk import TKUtils -class Navbar(TKUtils.Container()): +class Navbar(TKUtils.obter_container()): - def __init__(self, master, controller): - super().__init__(master=master) + def __init__(self): + super().__init__() - self.controller = controller + self.defs.pack['side'] = 'top' - self.botao_home = None - self.botao_aluno = None - self.botao_grupo = None - self.botao_atividade = None - self.botao_sobre = None + self.subelemento.home = TKUtils.obter_botao() + self.subelemento.aluno = TKUtils.obter_botao() + self.subelemento.grupo = TKUtils.obter_botao() + self.subelemento.atividade = TKUtils.obter_botao() + self.subelemento.sobre = TKUtils.obter_botao() - def iniciar(self): - self.criar_botao_aluno() - self.criar_botao_grupo() - self.criar_botao_home() - self.criar_botao_atividade() - self.criar_botao_sobre() + def iniciar(self, master): + super().iniciar(master=master) - self.pack(side='top') + self.inicializar_botao_aluno() + self.inicializar_botao_grupo() + self.inicializar_botao_home() + self.inicializar_botao_atividade() + self.inicializar_botao_sobre() - def criar_botao_home(self): - cnf, pack = {}, {} + def inicializar_botao_home(self): + self.subelemento.home.defs.cnf['text'] = 'Home' + self.subelemento.home.defs.cnf['bg'] = 'orange' + self.subelemento.home.defs.cnf['width'] = 28 + self.subelemento.home.defs.cnf['pady'] = 9 + self.subelemento.home.defs.mcnf['fz'] = 15 - cnf['text'] = 'Home' - cnf['bg'] = 'orange' - cnf['width'] = 28 - cnf['pady'] = 9 - cnf['font'] = ('times new roman', 15, 'bold') - cnf['command'] = self.controller.tela_home + self.subelemento.home.defs.pack['side'] = 'left' - pack['side'] = 'left' + self.subelemento.home.iniciar(master=self) - self.botao_home = TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + def inicializar_botao_aluno(self): + self.subelemento.aluno.defs.cnf['text'] = 'Alunos' + self.subelemento.aluno.defs.cnf['bg'] = 'red' + self.subelemento.aluno.defs.cnf['width'] = 14 + self.subelemento.aluno.defs.cnf['pady'] = 9 + self.subelemento.aluno.defs.mcnf['fz'] = 15 - def criar_botao_aluno(self): - cnf, pack = {}, {} + self.subelemento.aluno.defs.pack['side'] = 'left' - cnf['text'] = 'Alunos' - cnf['bg'] = 'red' - cnf['width'] = 14 - cnf['pady'] = 9 - cnf['font'] = ('times new roman', 15, 'bold') - cnf['command'] = self.controller.tela_aluno + self.subelemento.aluno.iniciar(master=self) - pack['side'] = 'left' + def inicializar_botao_atividade(self): + self.subelemento.atividade.defs.cnf['text'] = 'Atividades' + self.subelemento.atividade.defs.cnf['bg'] = 'blue' + self.subelemento.atividade.defs.cnf['width'] = 14 + self.subelemento.atividade.defs.cnf['pady'] = 9 + self.subelemento.atividade.defs.mcnf['fz'] = 15 - self.botao_aluno = TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + self.subelemento.atividade.defs.pack['side'] = 'left' - def criar_botao_atividade(self): - cnf, pack = {}, {} + self.subelemento.atividade.iniciar(master=self) - cnf['text'] = 'Atividades' - cnf['bg'] = 'blue' - cnf['width'] = 14 - cnf['pady'] = 9 - cnf['font'] = ('times new roman', 15, 'bold') - cnf['command'] = self.controller.tela_atividade + def inicializar_botao_grupo(self): + self.subelemento.grupo.defs.cnf['text'] = 'Grupos' + self.subelemento.grupo.defs.cnf['bg'] = 'green' + self.subelemento.grupo.defs.cnf['width'] = 14 + self.subelemento.grupo.defs.cnf['pady'] = 9 + self.subelemento.grupo.defs.mcnf['fz'] = 15 - pack['side'] = 'left' + self.subelemento.grupo.defs.pack['side'] = 'left' - self.botao_atividade =\ - TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + self.subelemento.grupo.iniciar(master=self) - def criar_botao_grupo(self): - cnf, pack = {}, {} + def inicializar_botao_sobre(self): + self.subelemento.sobre.defs.cnf['text'] = 'Sobre' + self.subelemento.sobre.defs.cnf['bg'] = 'grey' + self.subelemento.sobre.defs.cnf['width'] = 14 + self.subelemento.sobre.defs.cnf['pady'] = 9 + self.subelemento.sobre.defs.mcnf['fz'] = 15 - cnf['text'] = 'Grupos' - cnf['bg'] = 'green' - cnf['width'] = 14 - cnf['pady'] = 9 - cnf['font'] = ('times new roman', 15, 'bold') - cnf['command'] = self.controller.tela_grupo + self.subelemento.sobre.defs.pack['side'] = 'left' - pack['side'] = 'left' - - self.botao_grupo = TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) - - def criar_botao_sobre(self): - cnf, pack = {}, {} - - cnf['text'] = 'Sobre' - cnf['bg'] = 'grey' - cnf['width'] = 14 - cnf['pady'] = 9 - cnf['font'] = ('times new roman', 15, 'bold') - cnf['command'] = self.controller.tela_sobre - - pack['side'] = 'left' - - self.botao_sobre = TKUtils.obter_botao(master=self, cnf=cnf, pack=pack) + self.subelemento.sobre.iniciar(master=self) diff --git a/src/view/sobre/__init__.py b/src/view/sobre/__init__.py index 493a2ad..a0e14a8 100644 --- a/src/view/sobre/__init__.py +++ b/src/view/sobre/__init__.py @@ -1,16 +1,14 @@ from src.utils.tk import TKUtils -class Sobre(TKUtils.Container()): +class Sobre(TKUtils.obter_container()): - def __init__(self, master, controller): - super().__init__(master=master) + def __init__(self): + super().__init__() - def iniciar(self): - self.pack(side='bottom') + self.defs.pack['side'] = 'bottom' - def ativar(self): - self.pack_configure(side='bottom') + def iniciar(self, master): + super().iniciar(master=master) - def desativar(self): - self.pack_forget() + self.ocultar() diff --git a/tests/__init__.py b/tests/__init__.py index cd2a4a7..0d82b11 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -2,72 +2,71 @@ from tests.view import TesteDaView from tests.model import TesteDoModel -from tests.controller import TesteDoController -from tests.utils import TesteDoUtils +from tests.utils import TUtils from tests.store import TesteDoStore +from tests.controller import TesteDoController -class Tests: +class Tests(object): def __init__(self): - self.numero_de_testes = 10 + self.qtd_testes = 10 def iniciar(self): - print('\n') - try: - print('Testando View...', end='') - self.testar_view() - - print('Testando Model...', end='') - self.testar_model() - - print('Testando Controller...', end='') - self.testar_controller() - - print('Testando Utils...', end='') - self.testar_utils() - - print('Testando Store...', end='') - self.testar_store() + self.view() + self.model() + self.utils() + self.store() + self.controller() except Exception as erro: - if 'erro_msg' in dir(erro): - self.mostrar_erro(erro_msg=erro) - else: - self.mostrar_erro(erro_msg='Erro inesperado...') + if not isinstance(erro, ExceptionNoTeste): + print('\n\n\t Erro inesperado... \n\n') raise + print(erro) + + exit(1) + exit(0) - print('\n') + def view(self): + print('Testando View...', end='') - def testar_view(self): - for i in range(self.numero_de_testes): + for i in range(self.qtd_testes): TesteDaView(loop=i).iniciar() - print('\b\b\b ->\033[1;32m OK', end='\033[0;0m\n') + self.mostrar_ok(qtd_espacos=7) + + def model(self): + print('Testando Model...', end='') - def testar_model(self): - for i in range(self.numero_de_testes): + for i in range(self.qtd_testes): TesteDoModel(loop=i).iniciar() - print('\b\b\b ->\033[1;32m OK', end='\033[0;0m\n') + self.mostrar_ok(qtd_espacos=6) - def testar_controller(self): - for i in range(self.numero_de_testes): + def controller(self): + print('Testando Controller...', end='') + + for i in range(self.qtd_testes): TesteDoController(loop=i).iniciar() - print('\b\b\b ->\033[1;32m OK', end='\033[0;0m\n') + self.mostrar_ok(qtd_espacos=1) + + def utils(self): + print('Testando Utils...', end='') + + for i in range(self.qtd_testes): + TUtils(loop=i).iniciar() - def testar_utils(self): - for i in range(self.numero_de_testes): - TesteDoUtils(loop=i).iniciar() + self.mostrar_ok(qtd_espacos=6) - print('\b\b\b ->\033[1;32m OK', end='\033[0;0m\n') + def store(self): + print('Testando Store...', end='') - def testar_store(self): - for i in range(self.numero_de_testes): + for i in range(self.qtd_testes): TesteDoStore(loop=i).iniciar() - print('\b\b\b ->\033[1;32m OK', end='\033[0;0m\n') + self.mostrar_ok(qtd_espacos=6) - def mostrar_erro(self, erro_msg): - print(f'\n\t\033[1;33m {erro_msg}', end='\033[0;0m\n') + def mostrar_ok(self, qtd_espacos): + print(f'\b\b\b{" " * qtd_espacos}->\033[1;32m OK', end='\033[0;0m\n') diff --git a/tests/controller.py b/tests/controller/__init__.py similarity index 51% rename from tests/controller.py rename to tests/controller/__init__.py index ddaa463..22f73d0 100644 --- a/tests/controller.py +++ b/tests/controller/__init__.py @@ -8,10 +8,12 @@ class TesteDoController: def __init__(self, loop): self.loop = loop - self.controller = Controller() - model = Model(controller=self.controller) - view = View(controller=self.controller) - self.controller.segundo_init(model=model, view=view) - def iniciar(self): pass + + def inicializacao(self): + view = View() + model = Model() + controller = Controller() + + view.iniciar() diff --git a/tests/exception.py b/tests/exception.py index 32b75aa..875a111 100644 --- a/tests/exception.py +++ b/tests/exception.py @@ -1,7 +1,9 @@ class ExceptionNoTeste(Exception): def __init__(self, local, erro): - self.erro_msg = f'{local}: {erro}' + self.msg_erro = f'{local}: {erro}' def __str__(self): - return self.erro_msg + print(f'\n\t\033[1;33m {self.msg_erro}') + + return '\033[0;0m' diff --git a/tests/model.py b/tests/model.py deleted file mode 100644 index 87cdf53..0000000 --- a/tests/model.py +++ /dev/null @@ -1,48 +0,0 @@ -from src.view import View -from src.model import Model -from src.controller import Controller - -from tests.exception import ExceptionNoTeste - - -class TesteDoModel: - - def __init__(self, loop): - self.loop = loop - - controller = Controller() - self.model = Model(controller=controller) - view = View(controller=controller) - controller.segundo_init(model=self.model, view=view) - self.model.segundo_init() - - def iniciar(self): - self.teste_do_init_do_aluno() - self.teste_do_ler_arquivo_do_aluno() - self.teste_do_limpar_linha_do_aluno() - self.teste_geral_do_aluno() - - def teste_do_init_do_aluno(self): - local = 'model.aluno.__init__' - - self.model.aluno.iniciar() - - if self.model.aluno.alunos == []: - erro = 'arquivo nao foi carregado' - raise ExceptionNoTeste(local=local, erro=erro) - - def teste_do_ler_arquivo_do_aluno(self): - local = 'model.aluno.ler_arquivo' - - self.model.aluno.alunos = [] - self.model.aluno.ler_arquivo() - - if self.model.aluno.alunos == []: - erro = 'conteudo do arquivo nao foi carregado' - raise ExceptionNoTeste(local=local, erro=erro) - - def teste_do_limpar_linha_do_aluno(self): - pass - - def teste_geral_do_aluno(self): - pass diff --git a/tests/model/__init__.py b/tests/model/__init__.py new file mode 100644 index 0000000..0ecdcc7 --- /dev/null +++ b/tests/model/__init__.py @@ -0,0 +1,47 @@ +from src.view import View +from src.model import Model +from src.controller import Controller + +from tests.exception import ExceptionNoTeste + + +class TesteDoModel: + + def __init__(self, loop): + self.loop = loop + + view = View() + self.model = Model() + controller = Controller() + + def iniciar(self): + pass + # self.teste_do_init_do_aluno() + # self.teste_do_ler_arquivo_do_aluno() + # self.teste_do_limpar_linha_do_aluno() + # self.teste_geral_do_aluno() + # + # def teste_do_init_do_aluno(self): + # local = 'model.aluno.__init__' + # + # self.model.aluno.iniciar() + # + # if self.model.aluno.alunos == []: + # erro = 'arquivo nao foi carregado' + # raise ExceptionNoTeste(local=local, erro=erro) + # + # def teste_do_ler_arquivo_do_aluno(self): + # local = 'model.aluno.ler_arquivo' + # + # self.model.aluno.alunos = [] + # self.model.aluno.ler_arquivo() + # + # if self.model.aluno.alunos == []: + # erro = 'conteudo do arquivo nao foi carregado' + # raise ExceptionNoTeste(local=local, erro=erro) + # + # def teste_do_limpar_linha_do_aluno(self): + # pass + # + # def teste_geral_do_aluno(self): + # pass diff --git a/tests/store.py b/tests/store/__init__.py similarity index 100% rename from tests/store.py rename to tests/store/__init__.py diff --git a/tests/utils.py b/tests/utils.py index 484a5d6..4799ce4 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -1,40 +1,65 @@ +"""Conjunto de testes relacionados a todos os niveis de Utils.""" + from src.utils import Utils +from src.utils.caminho import Caminho + from src.utils.tk import TKUtils from tests.exception import ExceptionNoTeste -class TesteDoUtils: +class TUtils(object): + """Testes na camada root de Utils.""" - def __init__(self, loop): + def __init__(self, loop) -> None: + """Init padrao.""" self.loop = loop - self.utils = Utils - self.tk_utils = TKUtils + def iniciar(self) -> None: + """Segundo init.""" + self.inteiro_aleatorio() + self.data_e_hora_atual() - def iniciar(self): - self.teste_do_obter_inteiro_aleatorio() - self.teste_do_caminho_de_execucao() + self.caminho_ate() - def teste_do_obter_inteiro_aleatorio(self): - local = 'utils.obter_inteiro_aleatorio' - inteiro = self.utils.obter_inteiro_aleatorio(inicio=self.loop, fim=100) + def inteiro_aleatorio(self) -> None: + """Testes de retorno.""" + local = 'utils.inteiro_aleatorio' + erro = 'Nao retornou um inteiro' + inteiro = Utils.inteiro_aleatorio(inicio=self.loop, fim=100) if not isinstance(inteiro, int): - erro = 'nao retornou um inteiro' - raise ExceptionNoTeste(local=local, erro=erro) + raise ExceptionNoTeste(local, erro) + erro = 'Nao respeitou o numero minimo e maximo' + inteiro = Utils.inteiro_aleatorio(inicio=self.loop, fim=100) if inteiro < self.loop or inteiro > 100: - erro = 'nao respeitou o numero minimo e maximo' - raise ExceptionNoTeste(local=local, erro=erro) + raise ExceptionNoTeste(local, erro) + erro = 'Inteiro negativo' + inteiro = Utils.inteiro_aleatorio(inicio=self.loop, fim=100) if inteiro < 0: - erro = 'inteiro negativo' - raise ExceptionNoTeste(local=local, erro=erro) + raise ExceptionNoTeste(local, erro) + + def data_e_hora_atual(self) -> None: + """Testes de retorno.""" + local = 'utils.data_e_hora_atual' + + erro = 'O valor nao e do tipo string' + data_hora = Utils.data_e_hora_atual() + if not isinstance(data_hora, str): + raise ExceptionNoTeste(local, erro) + + erro = 'Formato invalido' + data, hora = Utils.data_e_hora_atual().split(' ') + if (len(data.split('/')) != 3 or len(data.replace('/', '')) != 8 or + len(hora.split(':')) != 2 or len(hora.replace(':', '')) != 4): + raise ExceptionNoTeste(local, erro) - def teste_do_caminho_de_execucao(self): - local = 'utils.obter_caminho_de_execucao' + def caminho_ate(self) -> None: + """Teste de retorno.""" + local = 'utils.caminho.ate' - if self.utils.obter_caminho_de_execucao() != '': - erro = 'valor precisa ser vazio' - raise ExceptionNoTeste(local=local, erro=erro) + erro = 'O caminho nao esta completo' + if Caminho.ate('caminho/do/arquivo.aqui')[0] != '/': + raise ExceptionNoTeste(local, erro) diff --git a/tests/view.py b/tests/view/__init__.py similarity index 61% rename from tests/view.py rename to tests/view/__init__.py index 26c165f..0a261b2 100644 --- a/tests/view.py +++ b/tests/view/__init__.py @@ -8,10 +8,9 @@ class TesteDaView: def __init__(self, loop): self.loop = loop + model = Model() + self.view = View() controller = Controller() - model = Model(controller=controller) - self.view = View(controller=controller) - controller.segundo_init(model=model, view=self.view) def iniciar(self): pass