diff --git a/COMPILING.md b/COMPILING.md index 603f358e2..228a26450 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -10,6 +10,7 @@ Compiling Requirements * Qt 4.7.x library or above (qt.nokia.com) * LibXML2 library (www.xmlsoft.org) * libpq library (www.postgresql.org) +* pgModeler source (github.com/pgmodeler/pgmodeler/tags) Compiling ---------- diff --git a/PLUGINS.md b/PLUGINS.md index c7661d84c..09c3c1e34 100644 --- a/PLUGINS.md +++ b/PLUGINS.md @@ -1,16 +1,16 @@ PostgreSQL Database Modeler - pgModeler --------------------------------------- -This document describes a simple way how to create third party plugins on pgModeler. ATTENTION: Any plugin must be compiled using the most current source of pgModeler. +This document describes a simple way to create third party plugins on pgModeler. ATTENTION: Any plugin must be compiled using the most current source and libs of pgModeler. Basic Rules ----------- To be used as a plugin your class must: -1) Inherit the class "PgModelerPlugin" -2) Use the macro Q_INTERFACES in its declaration. -3) Overloadthe methods PgModelerPlugin::obterRotuloPlugin(void) and PgModelerPlugin::executarPlugin(ModeloWidget *model) +* Inherit the class "PgModelerPlugin" +* Use the macro Q_INTERFACES in its declaration. +* Overloadthe methods PgModelerPlugin::obterRotuloPlugin(void) and PgModelerPlugin::executarPlugin(ModeloWidget *model) Plugin directory structure -------------------------- @@ -23,8 +23,8 @@ The plugins in pgModeler must be within the "plugins" folder in its own director +---(lib)*(pluginA.)(so|dylib|dll) (library) +---pluginA.png (icon) -* Library: is the shared object that represents the plugin. The prefix (lib) and suffix (so|dylib|dll) are plataform dependent. -* Icon: It is a PNG image that represents the plugin on the plugins toolbar. +* Library: it is the shared object that represents the plugin. The prefix (lib) and suffix (so|dylib|dll) are plataform dependent. +* Icon: it is a PNG image that represents the plugin on the plugins toolbar. The dummy plugin ---------------- @@ -36,4 +36,4 @@ Advanced plugins To create advanced plugins you need to study the source code of pgModeler (particularly the headers). The code is well documented but in Portuguese. If you want to create a plugin and have questions please contact me via e-mail. -In the near future all the code will be cataloged and online documentation in English will be available to developers (help wanted!). \ No newline at end of file +In the near future all the code will be cataloged and online documentation in English will be available to developers (help wanted!). diff --git a/README.md b/README.md index 3f4dbde63..10a5b274b 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ For details about compilation and installation process see [COMPILING.md](https: Warning ------- -Although this is first stable version of pgModeler it is recommended NOT EXPORT the models created directly to production environments. Not all possible code generation were tested in this way, is its your own risk export the models into environments that are not intended for testing. The project's author is not responsible for any possible loss of data due the inappropriate use of this tool. +Although this is a major upgrade version of pgModeler it is recommended NOT EXPORT the models created directly to production environments. Not all possible code generation were tested in this way, is its your own risk export the models into environments that are not intended for testing. The project's author is not responsible for any possible loss of data due the inappropriate use of this tool. Change History -------------- diff --git a/build/conf/pgmodeler.conf b/build/conf/pgmodeler.conf index 8e1ad003c..0eaebae47 100644 --- a/build/conf/pgmodeler.conf +++ b/build/conf/pgmodeler.conf @@ -9,7 +9,7 @@ --> + + icones/convrelnn.png + icones/seltodos.png + icones/movimentado.png + icones/abrir.png + icones/parameter.png + icones/uid.png + icones/database.png + icones/grant.png + icones/validade.png + icones/editar.png + icones/moverultimo.png + icones/moverprimeiro.png + icones/movercima.png + icones/moverbaixo.png + icones/bloqtodosobjetos.png + icones/desbloqtodosobjetos.png + icones/limpartexto.png + icones/relationshipusr.png + icones/codigosql.png + icones/codigoxml.png + icones/bloqobjeto.png + icones/desbloqobjeto.png + icones/relationshipgen.png + icones/relationshipdep.png + icones/cast.png + icones/adicionar.png + icones/aggregate.png + icones/aggregate_grp.png + icones/anterior.png + icones/aparencia.png + icones/atualizar.png + icones/baixo.png + icones/buscar.png + icones/cast_grp.png + icones/cima.png + icones/codigofonte.png + icones/colar.png + icones/column.png + icones/column_grp.png + icones/conexaobd.png + icones/config.png + icones/confirmar.png + icones/constraint.png + icones/constraint_ck.png + icones/constraint_fk.png + icones/constraint_grp.png + icones/constraint_pk.png + icones/constraint_uq.png + icones/consttrigger.png + icones/consttrigger_grp.png + icones/conversion.png + icones/conversion_grp.png + icones/copiar.png + icones/cores.png + icones/criado.png + icones/desfazer.png + icones/domain.png + icones/domain_grp.png + icones/excluir.png + icones/exportar.png + icones/fechar1.png + icones/fechar.png + icones/funcao.png + icones/function.png + icones/function_grp.png + icones/grade.png + icones/imprimir.png + icones/index.png + icones/index_grp.png + icones/language.png + icones/language_grp.png + icones/modificado.png + icones/msgbox_alerta.png + icones/msgbox_erro.png + icones/msgbox_info.png + icones/msgbox_quest.png + icones/novo.png + icones/opclass.png + icones/opclass_grp.png + icones/operator.png + icones/operator_grp.png + icones/opfamily.png + icones/opfamily_grp.png + icones/pgsqlModeler48x48.png + icones/proximo.png + icones/recortar.png + icones/refazer.png + icones/relationship1n.png + icones/relationship11.png + icones/relationship.png + icones/relationship_grp.png + icones/relationshipnn.png + icones/relationshiptv.png + icones/relationshiptv_grp.png + icones/remover.png + icones/removido.png + icones/restaurarobjeto.png + icones/role.png + icones/role_grp.png + icones/rule.png + icones/rule_grp.png + icones/sair.png + icones/salvar.png + icones/salvar_como.png + icones/schema.png + icones/schema_grp.png + icones/selecionar.png + icones/selmovobjeto.png + icones/sequence.png + icones/sequence_grp.png + icones/table.png + icones/table_grp.png + icones/tablespace.png + icones/tablespace_grp.png + icones/textbox.png + icones/textbox_grp.png + icones/trigger.png + icones/trigger_grp.png + icones/usertype.png + icones/usertype_grp.png + icones/view.png + icones/view_grp.png + icones/visaoarvore.png + icones/visaogeral.png + icones/visaolista.png + icones/zoom_mais.png + icones/zoom_menos.png + icones/zoom_normal.png + icones/alinhargrade.png + icones/depsrefs.png + icones/novoobjeto.png + icones/telacheia.png + icones/exibirlimpag.png + icones/padroes.png + + + imagens/pgsqldbm_logo_grande.png + imagens/barra_logo_meio_cinza.png + imagens/barra_logo_topo.png + imagens/barra_logo_base.png + imagens/model2sql.png + imagens/model2sgdb.png + imagens/twitter.png + imagens/facebook.png + imagens/github.png + + diff --git a/libpgmodeler_ui/src/bancodadoswidget.cpp b/libpgmodeler_ui/src/bancodadoswidget.cpp new file mode 100644 index 000000000..2d8a277bc --- /dev/null +++ b/libpgmodeler_ui/src/bancodadoswidget.cpp @@ -0,0 +1,122 @@ +#include "bancodadoswidget.h" +//*********************************************************** +BancoDadosWidget::BancoDadosWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_BANCO_DADOS) +{ + map > mapa_campos; + QFrame *frame=NULL; + QLocale loc; + QStringList lista_loc, codificacoes; + unsigned i,i1; + + Ui_BancoDadosWidget::setupUi(this); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + configurarLayouFormulario(bancodados_grid, OBJETO_BANCO_DADOS); + + //Define os campos exclusivos para cada versão + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_83)].push_back(limconexao_lbl); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(lccollate_lbl); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(lcctype_lbl); + + //Gera o frame de alerta + frame=gerarFrameAlertaVersao(mapa_campos); + bancodados_grid->addWidget(frame, bancodados_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + //Define as alturas mínimas e máxima do formulário + janela_pai->setMinimumWidth(530); + janela_pai->setMinimumHeight(420); + janela_pai->setMaximumHeight(420); + + //Obtém os nomes das codificações e as insere no combo de codificação + TipoCodificacao::obterTipos(codificacoes); + codificacao_cmb->addItems(codificacoes); + + //Obtém todas as localizações padrão e as armazena em uma lista de QString + for(i=QLocale::C; i <= QLocale::Chewa; i++) + { + for(i1=QLocale::Afghanistan; i1 <= QLocale::Zimbabwe; i1++) + { + loc=QLocale(static_cast(i),static_cast(i1)); + lista_loc.append(loc.name()); + } + } + + //Remove as localizações duplicadas + lista_loc.removeDuplicates(); + //Ordena as localizações + lista_loc.sort(); + + //Insere as localizações nos combos + lccollate_cmb->addItem(trUtf8("Padrão")); + lcctype_cmb->addItem(trUtf8("Padrão")); + lccollate_cmb->addItems(lista_loc); + lcctype_cmb->addItems(lista_loc); +} +//---------------------------------------------------------- +void BancoDadosWidget::definirAtributos(ModeloBD *modelo) +{ + if(modelo) + { + int idx; + + //Configura os atributos de limite de conexão, banco modelo e autor + limconexao_sb->setValue(modelo->obterLimiteConexao()); + bdmodelo_edt->setText(QString::fromUtf8(modelo->obterBDModelo())); + autor_edt->setText(QString::fromUtf8(modelo->obterAutor())); + + //Configura o combo de codificação com a codificação atual + idx=codificacao_cmb->findText(~modelo->obterCodificacao()); + if(idx < 0) idx=0; + codificacao_cmb->setCurrentIndex(idx); + + //Configura as localizações LC_COLLATE E LC_CTYPE de acordo com a conf. atual + idx=lccollate_cmb->findText(modelo->obterLocalizacao(LC_COLLATE)); + if(idx < 0) idx=0; + lccollate_cmb->setCurrentIndex(idx); + + idx=lcctype_cmb->findText(modelo->obterLocalizacao(LC_CTYPE)); + if(idx < 0) idx=0; + lcctype_cmb->setCurrentIndex(idx); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, NULL, modelo); + } +} +//---------------------------------------------------------- +void BancoDadosWidget::aplicarConfiguracao(void) +{ + try + { + //Aplica as configurações básicas do objeto + ObjetoBaseWidget::aplicarConfiguracao(); + + //Define o autor do modelo + modelo->definirAutor(autor_edt->text().toUtf8()); + + /* Define a condificação do modelo de acordo com a selecionada no formulário + caso a codifição 'Padrão' seja selecionada o modelo usará a codificação padrão + do SGBD em que for executado o script sql gerado */ + modelo->definirCodificacao(TipoCodificacao(codificacao_cmb->currentText())); + + /* Define as localização LC_COLLATE e LC_CTYPE do modelo de acordo com a selecionada + no formulário caso a localização 'Padrão' seja selecionada o modelo usará a localização + padrão do SGBD em que for executado o script sql gerado */ + if(lccollate_cmb->currentIndex() > 0) + modelo->definirLocalizacao(LC_COLLATE, lccollate_cmb->currentText()); + else + modelo->definirLocalizacao(LC_COLLATE, ""); + + if(lcctype_cmb->currentIndex() > 0) + modelo->definirLocalizacao(LC_CTYPE, lcctype_cmb->currentText()); + else + modelo->definirLocalizacao(LC_CTYPE, ""); + + finalizarConfiguracao(); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/bancodadoswidget.h b/libpgmodeler_ui/src/bancodadoswidget.h new file mode 100644 index 000000000..a30cdcca3 --- /dev/null +++ b/libpgmodeler_ui/src/bancodadoswidget.h @@ -0,0 +1,45 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: BancoDadosWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos do banco de dados. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef BANCODADOS_WIDGET_H +#define BANCODADOS_WIDGET_H + +#include "ui_bancodadoswidget.h" +#include "objetobasewidget.h" +//*********************************************************** +class BancoDadosWidget: public ObjetoBaseWidget, public Ui::BancoDadosWidget { + Q_OBJECT + + private: + + public: + BancoDadosWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo); + + private slots: + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/caixamensagem.cpp b/libpgmodeler_ui/src/caixamensagem.cpp new file mode 100644 index 000000000..538186709 --- /dev/null +++ b/libpgmodeler_ui/src/caixamensagem.cpp @@ -0,0 +1,248 @@ +#include "caixamensagem.h" +//*********************************************************** +CaixaMensagem::CaixaMensagem(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) +{ + setupUi(this); + cancelada=false; + connect(sim_ok_btn,SIGNAL(clicked()),this,SLOT(clickSimOK())); + connect(nao_btn,SIGNAL(clicked()),this,SLOT(clickNaoCancelar())); + connect(cancelar_btn,SIGNAL(clicked()),this,SLOT(clickNaoCancelar())); + connect(exibir_exec_tb,SIGNAL(clicked()),this,SLOT(exibirListaExecoes())); + exibir_exec_tb->setVisible(false); +} +//---------------------------------------------------------- +void CaixaMensagem::clickSimOK(void) +{ + excecoes_trw->clear(); + accept(); +} +//---------------------------------------------------------- +void CaixaMensagem::clickNaoCancelar(void) +{ + excecoes_trw->clear(); + + if((sender()==nao_btn && !cancelar_btn->isVisible()) || + (sender()==cancelar_btn && !nao_btn->isVisible())) + reject(); + else if(sender()==nao_btn && cancelar_btn->isVisible()) + reject(); + else if(sender()==cancelar_btn && nao_btn->isVisible()) + { + cancelada=true; + reject(); + } +} +//---------------------------------------------------------- +bool CaixaMensagem::caixaCanceleda(void) +{ + return(cancelada); +} +//---------------------------------------------------------- +void CaixaMensagem::exibirListaExecoes(void) +{ + /* Caso o botao de exibiçao da lista de excecoes esteja ativado, + alterna o icone do mesmo indicando que a lista pode ser ocultada + e alem disso exibe a lista de exceçoes */ + if(exibir_exec_tb->isChecked()) + { + exibir_exec_tb->setIcon(QPixmap(QString::fromUtf8(":/icones/icones/desfazer.png"))); + grupo_objs_wgt->setCurrentIndex(1); + } + /* Caso nao esteja marcado o botao de exibiçao da lista de exceçoes + alterna o icone do mesmo indicando que a lista pode ser exibida e alem + disso exibe o label de mensagem de erro */ + else + { + exibir_exec_tb->setIcon(QPixmap(QString::fromUtf8(":/icones/icones/refazer.png"))); + grupo_objs_wgt->setCurrentIndex(0); + } +} +//---------------------------------------------------------- +void CaixaMensagem::show(Excecao e, const QString &msg, unsigned tipo_ico) +{ + deque lista; + deque::reverse_iterator itr,itr_end; + QTreeWidgetItem *item=NULL,*item1=NULL,*item2=NULL; + QLabel *label=NULL; + int idx=0; + Excecao *ex=NULL; + QString str_aux, titulo; + QFont fonte=this->font(); + + //Obtém a lista de erros contida na exceção passada + e.obterListaExcecoes(lista); + + /* Varre a lista de erros obtidas em ordem reversa mostrando + de onde partiu cada em sua ordem correta */ + itr=lista.rbegin(); + itr_end=lista.rend(); + fonte.setPointSize(8); + + while(itr!=itr_end) + { + ex=&(*itr); + + /* Configura o item da lista responsável pela exibiação da função ou + método onde foi gerado o erro */ + item=new QTreeWidgetItem; + str_aux=QString("[%1] - %2") + .arg(idx) + .arg(ex->obterLocal()); + item->setIcon(0,QPixmap(QString::fromUtf8(":/icones/icones/funcao.png"))); + excecoes_trw->insertTopLevelItem(0,item); + label=new QLabel; + label->setFont(fonte); + label->setWordWrap(true); + label->setText(str_aux); + excecoes_trw->setItemWidget(item, 0, label); + + /* Configura o item da lista responsável pela exibição do nome de arquivo + onde foi gerado o erro */ + item1=new QTreeWidgetItem(item); + item1->setIcon(0,QPixmap(QString::fromUtf8(":/icones/icones/codigofonte.png"))); + item1->setText(0,ex->obterArquivo() + " (" + ex->obterLinha() + ")"); + + //Configura o item o qual denota o código interno do erro + item2=new QTreeWidgetItem(item); + item2->setIcon(0,QPixmap(QString::fromUtf8(":/icones/icones/msgbox_alerta.png"))); + item2->setText(0,Excecao::obterNomeErro(ex->obterTipoErro()) + + " (" + QString("%1").arg(ex->obterTipoErro()) + ")"); + + //Configura o item da lista o qual exibe a mensagem de erro da exceção + item1=new QTreeWidgetItem(item); + item1->setIcon(0,QPixmap(":/icones/icones/msgbox_erro.png")); + label=new QLabel; + label->setWordWrap(true); + label->setFont(fonte); + label->setStyleSheet("color: #ff0000;"); + excecoes_trw->setItemWidget(item1, 0, label); + label->setText(QString::fromUtf8(ex->obterMensagemErro())); + + if(!ex->obterInfoAdicional().isEmpty()) + { + //Configura o item da lista o qual exibe a mensagem de erro da exceção + item1=new QTreeWidgetItem(item); + item1->setIcon(0,QPixmap(QString::fromUtf8(":/icones/icones/msgbox_info.png"))); + label=new QLabel; + label->setWordWrap(true); + label->setFont(fonte); + label->setStyleSheet("color: #000080;"); + excecoes_trw->setItemWidget(item1, 0, label); + label->setText(QString::fromUtf8(ex->obterInfoAdicional())); + } + + itr++; + idx++; + } + + switch(tipo_ico) + { + case ICONE_ERRO: + titulo=trUtf8("Erro"); + break; + + case ICONE_ALERTA: + titulo=trUtf8("Alerta"); + break; + + case ICONE_INFO: + titulo=trUtf8("Informação"); + break; + + default: + titulo=""; + break; + } + + /* Configura a caixa de mensagem com apenas o botão OK e com o ícone + de erro crítico */ + if(msg.isEmpty()) + str_aux=QString::fromUtf8(e.obterMensagemErro()); + else + str_aux=msg; + + this->show(titulo,str_aux,tipo_ico,BOTAO_OK); +} +//---------------------------------------------------------- +void CaixaMensagem::show(const QString &titulo, const QString &texto, unsigned icone, unsigned botoes) +{ + QString nome_icone; + + //Configurando os botões para cada tipo de opção + switch(botoes) + { + case BOTAO_SIM_NAO: + nao_btn->setText(trUtf8("&Não")); + sim_ok_btn->setText(trUtf8("&Sim")); + break; + + case BOTAO_OK_CANCELAR: + cancelar_btn->setText(trUtf8("&Cancelar")); + sim_ok_btn->setText(trUtf8("&Ok")); + break; + + case BOTAO_SIM_NAO_CANCELAR: + cancelar_btn->setText(trUtf8("&Cancelar")); + nao_btn->setText(trUtf8("&Não")); + sim_ok_btn->setText(trUtf8("&Sim")); + break; + + default: + case BOTAO_OK: + sim_ok_btn->setText(trUtf8("&Ok")); + break; + } + + nao_btn->setVisible(botoes==BOTAO_SIM_NAO || botoes==BOTAO_SIM_NAO_CANCELAR); + cancelar_btn->setVisible(botoes==BOTAO_OK_CANCELAR || botoes==BOTAO_SIM_NAO_CANCELAR); + + //Configurando o ícone da caixa de mensagem + switch(icone) + { + case ICONE_ERRO: + nome_icone="msgbox_erro.png"; + break; + + case ICONE_INFO: + nome_icone="msgbox_info.png"; + break; + + case ICONE_ALERTA: + nome_icone="msgbox_alerta.png"; + break; + + case ICONE_CONFIRM: + nome_icone="msgbox_quest.png"; + break; + + default: + nome_icone=""; + break; + } + + cancelada=false; + + //Carrega o ícone da caixa de mensagem + if(nome_icone!="") + icone_lb->setPixmap(QPixmap((":/icones/icones/" + nome_icone))); + + //Configura o texto da mensagem traduzindo-a automaticamente + texto_lb->setText(texto); + + /* Redimensiona a caixa de mensagem para seu tamanho mínimo toda vez que + mesma é exibida */ + this->resize(this->minimumWidth(),this->minimumHeight()); + + //Configura o título da caixa de mensagem + this->setWindowTitle("pgModeler - " + titulo); + + /* Por padrão exibe o label de mensagem, o botão de exibição + da lista de erros é escondido */ + this->grupo_objs_wgt->setCurrentIndex(0); + this->exibir_exec_tb->setChecked(false); + this->exibir_exec_tb->setVisible((excecoes_trw->topLevelItemCount() > 0)); + exibirListaExecoes(); + + QDialog::exec(); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/caixamensagem.h b/libpgmodeler_ui/src/caixamensagem.h new file mode 100644 index 000000000..d50d067a5 --- /dev/null +++ b/libpgmodeler_ui/src/caixamensagem.h @@ -0,0 +1,74 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: CaixaMensagem +# Descrição: Definição da classe usada para exibição de caixas +# de mensagens personalizadas, como exibição de pilha +# de exceções geradas no software, icones indicativos +# de erros, alertas, informações , etc. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CAIXA_MENSAGEM_H +#define CAIXA_MENSAGEM_H + +#include "ui_caixamensagem.h" +#include "excecao.h" +//*********************************************************** +class CaixaMensagem: public QDialog, public Ui::CaixaMensagem { + private: + Q_OBJECT + bool cancelada; + + public: + //Constantes usadas para definir o ícone da mensagem + static const unsigned SEM_ICONE=10, + ICONE_ERRO=11, + ICONE_INFO=12, + ICONE_ALERTA=13, + ICONE_CONFIRM=14; + + //Constantes usadas para configurar quais botões são visíveis + static const unsigned BOTAO_SIM_NAO=0, + BOTAO_OK_CANCELAR=1, + BOTAO_OK=2, + BOTAO_SIM_NAO_CANCELAR=3; + + CaixaMensagem(QWidget * parent = 0, Qt::WindowFlags f = 0); + ~CaixaMensagem(void){} + + //Método padrão de exibição da mensagem, necessário configurar icone, texto, titulo e botões + void show(const QString &titulo, const QString &texto, unsigned icone=SEM_ICONE, + unsigned botoes=BOTAO_OK); + + /* Exibe a caixa de mensagem configurando-a com as mensagens de uma Exceção, por padrão + é exibida uma caixa com icone de erro e um botão ok além disso a árvore de + exceções é exibida. Os parâmetros 'msg' e 'tipo_ico' são usados para personalizar a exibição + da mensagem de erro da exceção. Se usado o parametro 'msg' a mensagem da exceção é sobrepostas + estando disponível apenas na pilha de erros. */ + void show(Excecao e, const QString &msg="", unsigned tipo_ico=ICONE_ERRO); + + //Retorna se o usuário marcou a opção de cancela na caixa + bool caixaCanceleda(void); + +private slots: + void clickSimOK(void); + void clickNaoCancelar(void); + void exibirListaExecoes(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/caixatextowidget.cpp b/libpgmodeler_ui/src/caixatextowidget.cpp new file mode 100644 index 000000000..859618840 --- /dev/null +++ b/libpgmodeler_ui/src/caixatextowidget.cpp @@ -0,0 +1,90 @@ +#include "caixatextowidget.h" +//*********************************************************** +CaixaTextoWidget::CaixaTextoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_CAIXA_TEXTO) +{ + Ui_CaixaTextoWidget::setupUi(this); + configurarLayouFormulario(caixatexto_grid, OBJETO_CAIXA_TEXTO); + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(sel_cor_tb, SIGNAL(clicked(void)), this, SLOT(selecionarCorTexto(void))); + janela_pai->definirBotoes(CaixaMensagem::BOTAO_OK_CANCELAR); + janela_pai->setMinimumSize(500,250); +} +//---------------------------------------------------------- +void CaixaTextoWidget::hideEvent(QHideEvent *evento) +{ + QPalette palette; + + //Limpa as caixas de texto + texto_txt->clear(); + negrito_chk->setChecked(false); + italico_chk->setChecked(false); + + palette.setColor(QPalette::Button, QColor(0,0,0)); + sel_cor_tb->setPalette(palette); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void CaixaTextoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, CaixaTexto *caixa_texto, float px_objeto, float py_objeto) +{ + /* Caso a caixa de texto esteja alocada, preenche o formulário + com os valores deste objeto */ + if(caixa_texto) + { + QPalette palette; + palette.setColor(QPalette::Button, caixa_texto->obterCorTexto()); + sel_cor_tb->setPalette(palette); + + texto_txt->setPlainText(QString::fromUtf8(caixa_texto->obterComentario())); + negrito_chk->setChecked(caixa_texto->obterAtributoTexto(CaixaTexto::TEXTO_NEGRITO)); + italico_chk->setChecked(caixa_texto->obterAtributoTexto(CaixaTexto::TEXTO_ITALICO)); + } + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, caixa_texto, NULL, px_objeto, py_objeto); +} +//---------------------------------------------------------- +void CaixaTextoWidget::selecionarCorTexto(void) +{ + QColorDialog cor_dlg; + QPalette palette; + + cor_dlg.setWindowTitle(trUtf8("Selecionar cor de texto")); + cor_dlg.exec(); + + if(cor_dlg.result()==QDialog::Accepted) + { + palette.setColor(QPalette::Button, cor_dlg.selectedColor()); + sel_cor_tb->setPalette(palette); + } +} +//---------------------------------------------------------- +void CaixaTextoWidget::aplicarConfiguracao(void) +{ + try + { + CaixaTexto *caixa=NULL; + + iniciarConfiguracao(); + + caixa=dynamic_cast(this->objeto); + //caixa->definirPosicaoObjeto(QPointF(this->px_objeto, this->py_objeto)); + caixa->definirComentario(texto_txt->toPlainText()); + caixa->definirAtributoTexto(CaixaTexto::TEXTO_ITALICO, italico_chk->isChecked()); + caixa->definirAtributoTexto(CaixaTexto::TEXTO_NEGRITO, negrito_chk->isChecked()); + caixa->definirCorTexto(sel_cor_tb->palette().color(QPalette::Button)); + + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/caixatextowidget.h b/libpgmodeler_ui/src/caixatextowidget.h new file mode 100644 index 000000000..6e34f941f --- /dev/null +++ b/libpgmodeler_ui/src/caixatextowidget.h @@ -0,0 +1,47 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: CaixaTextoWidget +# Descrição: Definição da classe que implementa o formulário de criação e +# edição de caixa de texto no modelo de banco de dados. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CAIXATEXTO_WIDGET_H +#define CAIXATEXTO_WIDGET_H + +#include "ui_caixatextowidget.h" +#include "objetobasewidget.h" +//*********************************************************** +class CaixaTextoWidget: public ObjetoBaseWidget, public Ui::CaixaTextoWidget { + Q_OBJECT + + private: + + public: + CaixaTextoWidget(QWidget * parent = 0); + void hideEvent(QHideEvent *evento); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, CaixaTexto *caixa_texto=NULL, float px_objeto=NAN, float py_objeto=NAN); + + private slots: + void selecionarCorTexto(void); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/classeoperadoreswidget.cpp b/libpgmodeler_ui/src/classeoperadoreswidget.cpp new file mode 100644 index 000000000..e6b61281c --- /dev/null +++ b/libpgmodeler_ui/src/classeoperadoreswidget.cpp @@ -0,0 +1,317 @@ +#include "classeoperadoreswidget.h" +//*********************************************************** +ClasseOperadoresWidget::ClasseOperadoresWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_CLASSE_OPER) +{ + try + { + QStringList tipos; + QGridLayout *grid=NULL; + + Ui_ClasseOperadoresWidget::setupUi(this); + + sel_familiaop=NULL; + sel_operador=NULL; + sel_funcao=NULL; + tipo_dado=NULL; + tipo_armazenamento=NULL; + tab_elementos=NULL; + + sel_familiaop=new SeletorObjetoWidget(OBJETO_FAMILIA_OPER, false, this); + sel_operador=new SeletorObjetoWidget(OBJETO_OPERADOR, true, this); + sel_funcao=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + tipo_dado=new TipoPgSQLWidget(this); + tipo_armazenamento=new TipoPgSQLWidget(this, trUtf8("Tipo de Armazenamento")); + tab_elementos=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES, true, this); + + /* A tabela de elementos é constituída de 4 colunas: + Nome do objeto, tipo, nº de suporte/estratégia e rechecagem. */ + tab_elementos->definirNumColunas(4); + tab_elementos->definirRotuloCabecalho(trUtf8("Objeto"),0); + tab_elementos->definirIconeCabecalho(QPixmap(":/icones/icones/table.png"),0); + + tab_elementos->definirRotuloCabecalho(trUtf8("Tipo"),1); + tab_elementos->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + + tab_elementos->definirRotuloCabecalho(trUtf8("Suporte/Estratégia"),2); + tab_elementos->definirRotuloCabecalho(trUtf8("Rechecar"),3); + + //Configurando a disposição dos campos no layout + grid=new QGridLayout; + grid->setContentsMargins(0,0,0,0); + grid->addWidget(classepadrao_lbl,0,2,1,1); + grid->addWidget(classepadrao_chk,0,3,1,1); + grid->addWidget(tipo_index_lbl,0,0,1,1); + grid->addWidget(tipo_index_cmb,0,1,1,1); + grid->addWidget(familia_lbl,2,0,1,1); + grid->addWidget(sel_familiaop,2,1,1,4); + grid->addWidget(tipo_dado,4,0,1,5); + grid->addWidget(elementos_grp,5,0,1,5); + this->setLayout(grid); + configurarLayouFormulario(grid, OBJETO_CLASSE_OPER); + + grid=dynamic_cast(elementos_grp->layout()); + grid->addWidget(sel_funcao, 1,1,1,4); + grid->addWidget(sel_operador, 2,1,1,4); + grid->addWidget(tipo_armazenamento, 5,0,1,5); + grid->addWidget(tab_elementos, 6,0,1,4); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(tipo_elem_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(selecionarTipoElemento(int))); + + //Conectando os sinais emitidos pela tabela de elementos ao slots de manipulação de elementos + connect(tab_elementos, SIGNAL(s_linhaAdicionada(int)), this, SLOT(manipularElemento(int))); + connect(tab_elementos, SIGNAL(s_linhaAtualizada(int)), this, SLOT(manipularElemento(int))); + connect(tab_elementos, SIGNAL(s_linhaEditada(int)), this, SLOT(editarElemento(int))); + + janela_pai->setMinimumSize(540, 590); + selecionarTipoElemento(0); + + //Configura o combobox do formulário listando todos os tipos de indexação do PostgreSQL + TipoIndexacao::obterTipos(tipos); + tipo_index_cmb->addItems(tipos); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ClasseOperadoresWidget::hideEvent(QHideEvent *evento) +{ + //Retorna os widgets aos valores padrão + sel_funcao->removerObjetoSelecionado(); + sel_operador->removerObjetoSelecionado(); + num_suporte_sb->setValue(1); + rechecar_chk->setChecked(false); + tab_elementos->removerLinhas(); + selecionarTipoElemento(0); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void ClasseOperadoresWidget::selecionarTipoElemento(int tipo) +{ + unsigned tipo_sel=static_cast(tipo); + + //Exibe os campos do elemento conforme o tipo selecionado + + //Campos exclusivos para o tipo FUNÇÃO + funcao_lbl->setVisible(tipo_sel==ElemClasseOperadores::ELEM_FUNCAO); + sel_funcao->setVisible(tipo_sel==ElemClasseOperadores::ELEM_FUNCAO); + + //Campos exclusivos para o tipo OPERADOR + operador_lbl->setVisible(tipo_sel==ElemClasseOperadores::ELEM_OPERADOR); + sel_operador->setVisible(tipo_sel==ElemClasseOperadores::ELEM_OPERADOR); + rechecar_chk->setVisible(tipo_sel==ElemClasseOperadores::ELEM_OPERADOR); + + //Campos exclusivos para o tipo ARMAZENAMENTO + tipo_armazenamento->setVisible(tipo_sel==ElemClasseOperadores::ELEM_ARMAZENAMENTO); + + //Campos comuns aos tipos FUNÇÃO e OPERADOR + num_suporte_lbl->setVisible(tipo_sel!=ElemClasseOperadores::ELEM_ARMAZENAMENTO); + num_suporte_sb->setVisible(tipo_sel!=ElemClasseOperadores::ELEM_ARMAZENAMENTO); +} +//---------------------------------------------------------- +void ClasseOperadoresWidget::editarElemento(int idx_linha) +{ + ElemClasseOperadores elem; + + //Obtém o elemento da linha selecionada na tabela + elem=tab_elementos->obterDadoLinha(idx_linha).value(); + + //Preenche o formulário com atributos do elemento + tipo_elem_cmb->setCurrentIndex(elem.obterTipoElemento()); + sel_funcao->definirObjeto(elem.obterFuncao()); + sel_operador->definirObjeto(elem.obterOperador()); + rechecar_chk->setChecked(elem.rechecarElemento()); + num_suporte_sb->setValue(elem.obterNumEstrategia()); + tipo_armazenamento->definirAtributos(elem.obterTipoArmazenamento(),this->modelo); +} +//---------------------------------------------------------- +void ClasseOperadoresWidget::exibirDadosElemento(ElemClasseOperadores elem, int idx_linha) +{ + unsigned tipo_elem; + + //Obtém o tipo do elemento + tipo_elem=elem.obterTipoElemento(); + + /* Para o tipo FUNÇÃO são exibidas na coluna 0 e 1, respectivamente, + a assinatura da função e o tipo do objeto (função) */ + if(tipo_elem==ElemClasseOperadores::ELEM_FUNCAO) + { + tab_elementos->definirTextoCelula(QString::fromUtf8(elem.obterFuncao()->obterAssinatura()), idx_linha, 0); + tab_elementos->definirTextoCelula(QString::fromUtf8(elem.obterFuncao()->obterNomeTipoObjeto()), idx_linha, 1); + } + /* Para o tipo OPERADOR são exibidas na coluna 0 e 1, respectivamente, + a assinatura do operador e o tipo do objeto (operador) */ + else if(tipo_elem==ElemClasseOperadores::ELEM_OPERADOR) + { + tab_elementos->definirTextoCelula(QString::fromUtf8(elem.obterOperador()->obterAssinatura()), idx_linha, 0); + tab_elementos->definirTextoCelula(QString::fromUtf8(elem.obterOperador()->obterNomeTipoObjeto()), idx_linha, 1); + } + /* Para o tipo ARMAZENAMENTO são exibidas na coluna 0 e 1, respectivamente, + a nome completo do tipo e o tipo do objeto (tipo) */ + else + { + tab_elementos->definirTextoCelula(*elem.obterTipoArmazenamento(), idx_linha, 0); + tab_elementos->definirTextoCelula(QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(OBJETO_TIPO)), idx_linha, 1); + } + + /* Para os tipos FUNÇÃO e OPERADOR é na coluna 2 + o número de suporte/estratégia da função ou operador */ + if(tipo_elem!=ElemClasseOperadores::ELEM_ARMAZENAMENTO) + tab_elementos->definirTextoCelula(QString("%1").arg(elem.obterNumEstrategia()), idx_linha, 2); + /* Para o tipo ARMAZENAMENTO este campo não é preenchido pois não aplica + esta categoria de elemento */ + else + tab_elementos->definirTextoCelula("-", idx_linha, 2); + + /* Para o tipo OPERADOR na coluna 3 é exibido se o operador + necessita ser rechecado ou não */ + if(tipo_elem==ElemClasseOperadores::ELEM_OPERADOR) + { + if(elem.rechecarElemento()) + tab_elementos->definirTextoCelula(trUtf8("Sim"), idx_linha, 3); + else + tab_elementos->definirTextoCelula(trUtf8("Não"), idx_linha, 3); + } + /* Para os tipos FUNÇÃO e ARMAZENAMENTO este campo não é preenchido + pois não aplica esta categorias de elementos */ + else + tab_elementos->definirTextoCelula("-", idx_linha, 3); + + //Define o dado da linha como sendo o elemento fornecido no parâmetro. + tab_elementos->definirDadoLinha(QVariant::fromValue(elem), idx_linha); +} +//---------------------------------------------------------- +void ClasseOperadoresWidget::manipularElemento(int idx_linha) +{ + ElemClasseOperadores elem; + unsigned tipo_elem; + + //Obtém o tipo do elemento + tipo_elem=tipo_elem_cmb->currentIndex(); + + try + { + /* Caso seja do tipo FUNÇÃO, atribui a função selecionado no widget seletor de função + e também o valor configurado como suporte no formulário */ + if(tipo_elem==ElemClasseOperadores::ELEM_FUNCAO) + elem.definirFuncao(dynamic_cast(sel_funcao->obterObjeto()), num_suporte_sb->value()); + /* Caso seja do tipo OPERADOR, atribui o operador selecionado no widget seletor de operador, + o valor configurado como suporte no formulário e o estado do checkbox de rechecagem */ + else if(tipo_elem==ElemClasseOperadores::ELEM_OPERADOR) + elem.definirOperador(dynamic_cast(sel_operador->obterObjeto()), num_suporte_sb->value(), rechecar_chk->isChecked()); + //Caso seja do tipo ARMAZENAMENTO, atribui o tipo configurado no widget de configuração de tipo + else + elem.definirArmazenamento(tipo_armazenamento->obterTipoPgSQL()); + + //Exibe o elemento configurado na tabela + exibirDadosElemento(elem, idx_linha); + + //Reinicia o formulário de configuração de elementos + sel_funcao->removerObjetoSelecionado(); + sel_operador->removerObjetoSelecionado(); + num_suporte_sb->setValue(1); + rechecar_chk->setChecked(false); + tab_elementos->limparSelecao(); + } + catch(Excecao &e) + { + /* Em caso de erro e caso a linha atual da tabela esteja sem dados (algum campo sem texto) + indica que a operação de inserção de um elemento é que gerou a exceção e para tanto + a linha recém adicionada precisa ser removida */ + if(tab_elementos->obterTextoCelula(idx_linha, 0).isEmpty()) + tab_elementos->removerLinha(idx_linha); + + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ClasseOperadoresWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, ClasseOperadores *classe_op) +{ + TipoPgSQL tipo; + unsigned i, qtd; + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, classe_op); + + //Configura o modelo de objetos de referência dos widgets + sel_familiaop->definirModelo(modelo); + sel_funcao->definirModelo(modelo); + sel_operador->definirModelo(modelo); + tipo_armazenamento->definirAtributos(tipo, modelo); + + //Caso a classe de operadores passada esteja alcada + if(classe_op) + { + //Obtém o tipo de dado que a classe opera + tipo=classe_op->obterTipoDado(); + + //Exibe no formulário a família de operadores usada pela classe + sel_familiaop->definirObjeto(classe_op->obterFamilia()); + + //Marca no formulário se a classe é considerada padrão + classepadrao_chk->setChecked(classe_op->classePadrao()); + + //Marca no combobox o tipo de indexão usada pela classe + tipo_index_cmb->setCurrentIndex(tipo_index_cmb->findText(~(classe_op->obterTipoIndexacao()))); + + //Exibe na tabela os elementos configuradas para a classe de operadores + tab_elementos->blockSignals(true); + qtd=classe_op->obterNumElemClasseOperadores(); + for(i=0; i < qtd; i++) + { + tab_elementos->adicionarLinha(); + exibirDadosElemento(classe_op->obterElementoClasse(i), i); + } + tab_elementos->blockSignals(false); + tab_elementos->limparSelecao(); + } + + //Exibe no widget de tipos pgsql, o tipo de dados que a classe opera + tipo_dado->definirAtributos(tipo, modelo); +} +//---------------------------------------------------------- +void ClasseOperadoresWidget::aplicarConfiguracao(void) +{ + try + { + ClasseOperadores *classe_op=NULL; + unsigned i, qtd; + + iniciarConfiguracao(); + + //Obtém a referência à classe de objetos que está sendo manipulada + classe_op=dynamic_cast(this->objeto); + + //Atribui os valores configurados no formulário à classe de operadores + classe_op->definirPadrao(classe_op->classePadrao()); + classe_op->definirFamilia(dynamic_cast(sel_familiaop->obterObjeto())); + classe_op->definirTipoIndexacao(TipoIndexacao(tipo_index_cmb->currentText())); + classe_op->definirTipoDado(tipo_dado->obterTipoPgSQL()); + + /* Remove todos os elementos da classe de operadores e em seguida + insere aqueles configurados na tabela à classe */ + classe_op->removerElementosClasse(); + qtd=tab_elementos->obterNumLinhas(); + + for(i=0; i < qtd; i++) + classe_op->adicionarElementoClasse(tab_elementos->obterDadoLinha(i).value()); + + //Aplica e finaliza a configuração da classe de operadores + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/classeoperadoreswidget.h b/libpgmodeler_ui/src/classeoperadoreswidget.h new file mode 100644 index 000000000..1bd1389c1 --- /dev/null +++ b/libpgmodeler_ui/src/classeoperadoreswidget.h @@ -0,0 +1,80 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FamiliaOperadoresWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de classe de operadores. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CLASSEOPERADORES_WIDGET_H +#define CLASSEOPERADORES_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_classeoperadoreswidget.h" +#include "tipopgsqlwidget.h" +#include "tabelaobjetoswidget.h" + +/* Declarando a classe ElemClasseOperadores como metatype para que esta + possa ser usada em conjunto com a classe QVariant (vide documentação + da classe QVariant e QMetaType). Esta declaração é uma macro específica + do Qt e está sendo usada para facilitar o uso com o formulário de edição + de classes de operadores.*/ +#include +Q_DECLARE_METATYPE(ElemClasseOperadores) +//*********************************************************** +class ClasseOperadoresWidget: public ObjetoBaseWidget, public Ui::ClasseOperadoresWidget { + Q_OBJECT + + private: + SeletorObjetoWidget *sel_familiaop, + *sel_funcao, + *sel_operador; + + TipoPgSQLWidget *tipo_dado, + *tipo_armazenamento; + + //Tabela de objetos que armazena os elementos de classe de operadores + TabelaObjetosWidget *tab_elementos; + + public: + ClasseOperadoresWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, ClasseOperadores *classe_op); + + private slots: + void hideEvent(QHideEvent *); + + /* Métodos que muda a visualização do formulário de configuração de elementos + conforme o tipo de elemento selecionado no combobox 'tipo_elem_cmb' */ + void selecionarTipoElemento(int tipo); + + //Exibe as informações de um dado elemento na tabela de elementos na linha especificada + void exibirDadosElemento(ElemClasseOperadores elem, int idx_linha); + + /* Configura uma instância da classe ElemClasseOperadores com os dados fornecidos no formulário + adicionalmente o elemento configurado é exibido na linha especificada da tabela de elementos */ + void manipularElemento(int idx_linha); + + /* Preenche o formulário de elemento com os dados do elemento selecionado na tabela para + permitir uma posterior atualização dos atributos */ + void editarElemento(int idx_linha); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/codigofontewidget.cpp b/libpgmodeler_ui/src/codigofontewidget.cpp new file mode 100644 index 000000000..9bfd5de1b --- /dev/null +++ b/libpgmodeler_ui/src/codigofontewidget.cpp @@ -0,0 +1,198 @@ +#include "codigofontewidget.h" +#include "progressotarefa.h" +extern ProgressoTarefa *prog_tarefa; +//*********************************************************** +CodigoFonteWidget::CodigoFonteWidget(QWidget *parent): ObjetoBaseWidget(parent) +{ + try + { + vector versoes; + QFont fonte; + + Ui_CodigoFonteWidget::setupUi(this); + configurarLayouFormulario(codigofonte_grid, OBJETO_BASE); + comentario_lbl->setText(trUtf8("Tipo:")); + + destaque_sql=NULL; + destaque_xml=NULL; + + fonte=nome_edt->font(); + fonte.setItalic(true); + comentario_edt->setFont(fonte); + comentario_edt->setReadOnly(true); + nome_edt->setFont(fonte); + nome_edt->setReadOnly(true); + + //Obtém as versões disponíveis de esquemas SQL + ParserEsquema::obterVersoesPgSQL(versoes); + + //Preenche o combobox de versões + versoes_cmb->addItems(QStringList(QList::fromVector(QVector::fromStdVector(versoes)))); + + //Define os atributos do formulários e da janela pai + janela_pai->setWindowTitle(trUtf8("Visualização de Código-Fonte")); + janela_pai->definirBotoes(CaixaMensagem::BOTAO_OK); + janela_pai->setMinimumSize(550, 450); + + //Conecta o botão ok do formulário pai com o método de fechamento do formulário + connect(janela_pai->aplicar_ok_btn, SIGNAL(clicked(bool)), janela_pai, SLOT(close(void))); + + /* Conecta o sinal de mudança de itens no combo box com a geração da sql do objeto. + Isso permite que a SQL seja gerada para a versão apropriada, toda vez que o + usuário mudar um item no combobox */ + connect(versoes_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(gerarCodigoFonteObjeto(int))); + connect(codigofonte_twg, SIGNAL(currentChanged(int)), this, SLOT(definirAbaCodigoFonte(int))); + + destaque_sql=new DestaqueSintaxe(codigosql_txt, false); + destaque_xml=new DestaqueSintaxe(codigoxml_txt, false); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void CodigoFonteWidget::hideEvent(QHideEvent *evento) +{ + versoes_cmb->blockSignals(true); + codigofonte_twg->blockSignals(true); + versoes_cmb->setCurrentIndex(0); + codigofonte_twg->setCurrentIndex(0); + versoes_cmb->blockSignals(false); + codigofonte_twg->blockSignals(false); + + //Limpa a caixa de texto de código fonte + codigosql_txt->clear(); + codigoxml_txt->clear(); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void CodigoFonteWidget::definirAbaCodigoFonte(int) +{ + QString icone_codigo; + bool campos_ativos=false; + QPixmap icone; + TipoObjetoBase tipo_obj=objeto->obterTipoObjeto(); + + //Caso a aba código SQL esteja visível configura o icone de código SQL + if(codigofonte_twg->currentIndex()==0) + icone_codigo="codigosql.png"; + else + //Caso contrário configura o ícone de código XML + icone_codigo="codigoxml.png"; + + /* Os campos de seleção de versão e seus respectivos labels + devem estar ativados quando a aba de código SQL está ativa + ou quando o tipo de objeto seja um dos muitos os quais + possuem definição SQL, caso contrário os campos citados + aparecerão desabilitados no formulário */ + campos_ativos=(codigofonte_twg->currentIndex()==0 && + (tipo_obj!=OBJETO_RELACAO_BASE && tipo_obj!=OBJETO_CAIXA_TEXTO)); + + //Configura o ícone de tipo de código fonte a ser exibido + icone=QPixmap(QString(":/icones/icones/") + icone_codigo); + iconecodigo_lbl->setPixmap(icone); + + //Ativa/desativa os campos de acordo com a aba visível + versoes_cmb->setEnabled(campos_ativos); + pgsql_lbl->setEnabled(campos_ativos); + versao_lbl->setEnabled(campos_ativos); +} +//---------------------------------------------------------- +void CodigoFonteWidget::gerarCodigoFonteObjeto(int) +{ + TipoObjetoBase tipo_obj; + + try + { + //Limpa os campos antes de preenche-los com o código fonte do objeto + codigosql_txt->clear(); + codigoxml_txt->clear(); + + //Obtém o código SQL do objeto caso o mesmo não seja um relacionamento ou caixa de texto + tipo_obj=objeto->obterTipoObjeto(); + if(tipo_obj!=OBJETO_RELACAO_BASE && tipo_obj!=OBJETO_CAIXA_TEXTO) + { + if(tipo_obj==OBJETO_BANCO_DADOS) + { + prog_tarefa->setWindowTitle(trUtf8("Gerando código-fonte...")); + connect(this->modelo, SIGNAL(s_objetoCarregado(int,QString,unsigned)), + prog_tarefa, SLOT(executarProgesso(int,QString,unsigned))); + } + + ParserEsquema::definirVersaoPgSQL(versoes_cmb->currentText()); + codigosql_txt->setPlainText(QString::fromUtf8(ModeloBD::validarDefinicaoObjeto(objeto, ParserEsquema::DEFINICAO_SQL))); + } + + //Caso o objeto não possua uma definição SQL exibe o texto avisando o fato + if(codigosql_txt->toPlainText()=="") + codigosql_txt->setPlainText(trUtf8("-- Código SQL não disponível para este tipo de objeto. --")); + + //Configura a caixa de código fonte XML com o código XML do objeto + codigoxml_txt->setPlainText(QString::fromUtf8(ModeloBD::validarDefinicaoObjeto(objeto, ParserEsquema::DEFINICAO_XML))); + + //Configura a aba e os ícones de acordo com a que está em foco + definirAbaCodigoFonte(); + + prog_tarefa->close(); + disconnect(this->modelo, NULL, prog_tarefa, NULL); + } + catch(Excecao &e) + { + prog_tarefa->close(); + disconnect(this->modelo, NULL, prog_tarefa, NULL); + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void CodigoFonteWidget::definirAtributos(ModeloBD *modelo, ObjetoBase *objeto) +{ + /* Caso o objeto esteja alocado, preenche o formulário + com o codigo SQL que o define em banco de dados */ + if(objeto) + { + QPixmap icone_obj; + + try + { + //Executa a configuração específica do widget + ObjetoBaseWidget::definirAtributos(modelo, NULL, objeto); + this->janela_pai->aplicar_ok_btn->setEnabled(true); + this->obj_protegido_frm->setVisible(false); + + //Configura o icone do objeto a ser exibido + icone_obj=QPixmap(QString(":/icones/icones/") + + ObjetoBase::obterNomeEsquemaObjeto(objeto->obterTipoObjeto()) + QString(".png")); + iconeobj_lbl->setPixmap(icone_obj); + + //Preenche os campos do formulario com os atributos do objeto + comentario_edt->setText(QString::fromUtf8(objeto->obterNomeTipoObjeto())); + + if(!destaque_sql->configuracaoCarregada()) + { + destaque_sql->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + } + + if(!destaque_xml->configuracaoCarregada()) + { + destaque_xml->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_XML + + AtributosGlobais::EXT_CONFIGURACAO); + } + + gerarCodigoFonteObjeto(); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/codigofontewidget.h b/libpgmodeler_ui/src/codigofontewidget.h new file mode 100644 index 000000000..160cde699 --- /dev/null +++ b/libpgmodeler_ui/src/codigofontewidget.h @@ -0,0 +1,49 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: CodigoFonteWidget +# Descrição: Definição da classe que implementa o formulário de visualização +# do código SQL/XML de um dado objeto. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CODIGOFONTE_WIDGET_H +#define CODIGOFONTE_WIDGET_H + +#include "ui_codigofontewidget.h" +#include "objetobasewidget.h" +//*********************************************************** +class CodigoFonteWidget: public ObjetoBaseWidget, public Ui::CodigoFonteWidget { + Q_OBJECT + private: + DestaqueSintaxe *destaque_sql, + *destaque_xml; + + void aplicarConfiguracao(void){} + + public: + CodigoFonteWidget(QWidget * parent = 0); + void hideEvent(QHideEvent *evento); + void definirAtributos(ModeloBD *modelo, ObjetoBase *objeto=NULL); + + private slots: + void gerarCodigoFonteObjeto(int=0); + void definirAbaCodigoFonte(int=0); +}; +//*********************************************************** +#endif + diff --git a/libpgmodeler_ui/src/colunawidget.cpp b/libpgmodeler_ui/src/colunawidget.cpp new file mode 100644 index 000000000..ced5e911a --- /dev/null +++ b/libpgmodeler_ui/src/colunawidget.cpp @@ -0,0 +1,91 @@ +#include "colunawidget.h" +//*********************************************************** +ColunaWidget::ColunaWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_COLUNA) +{ + try + { + Ui_ColunaWidget::setupUi(this); + + //Cria um destacador de sintaxe no campo de expressão de checagem do domínio + dest_valor_padrao=NULL; + dest_valor_padrao=new DestaqueSintaxe(valor_padrao_txt, false); + dest_valor_padrao->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + tipo_col=NULL; + tipo_col=new TipoPgSQLWidget(this); + coluna_grid->addWidget(tipo_col,3,0,1,0); + + configurarLayouFormulario(coluna_grid, OBJETO_COLUNA); + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->setMinimumSize(530, 380); + janela_pai->setMaximumHeight(380); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ColunaWidget::hideEvent(QHideEvent *evento) +{ + valor_padrao_txt->clear(); + nao_nulo_chk->setChecked(false); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void ColunaWidget::definirAtributos(ModeloBD *modelo, ObjetoBase *objeto_pai, ListaOperacoes *lista_op, Coluna *coluna) +{ + TipoPgSQL tipo; + + if(!objeto_pai) + throw Excecao(ERR_PGMODELER_ATROBJNAOALOC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, coluna, objeto_pai); + + if(coluna) + { + tipo=coluna->obterTipo(); + nao_nulo_chk->setChecked(coluna->naoNulo()); + valor_padrao_txt->setPlainText(QString::fromUtf8(coluna->obterValorPadrao())); + } + + //Marca o tipo do domínio no widget de tipos pgsql + tipo_col->definirAtributos(tipo, modelo); +} +//---------------------------------------------------------- +void ColunaWidget::aplicarConfiguracao(void) +{ + try + { + Coluna *coluna=NULL; + + iniciarConfiguracao(); + + //Obtém a referência à coluna que está sendo criada/editada + coluna=dynamic_cast(this->objeto); + + //Atribui os dados do formulário à coluna + coluna->definirNaoNulo(nao_nulo_chk->isChecked()); + coluna->definirValorPadrao(valor_padrao_txt->toPlainText()); + coluna->definirTipo(tipo_col->obterTipoPgSQL()); + + ObjetoBaseWidget::aplicarConfiguracao(); + + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/colunawidget.h b/libpgmodeler_ui/src/colunawidget.h new file mode 100644 index 000000000..7034bf7da --- /dev/null +++ b/libpgmodeler_ui/src/colunawidget.h @@ -0,0 +1,52 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ColunaWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de colunas. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef COLUNA_WIDGET_H +#define COLUNA_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_colunawidget.h" +#include "tipopgsqlwidget.h" +//*********************************************************** +class ColunaWidget: public ObjetoBaseWidget, public Ui::ColunaWidget { + Q_OBJECT + + private: + //Destacador de sintaxe para o campo de valor padrão da coluna + DestaqueSintaxe *dest_valor_padrao; + + //Seletor de tipo da coluna + TipoPgSQLWidget *tipo_col; + + public: + ColunaWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ObjetoBase *objeto_pai, ListaOperacoes *lista_op, Coluna *coluna); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/confaparenciawidget.cpp b/libpgmodeler_ui/src/confaparenciawidget.cpp new file mode 100644 index 000000000..578c35a20 --- /dev/null +++ b/libpgmodeler_ui/src/confaparenciawidget.cpp @@ -0,0 +1,426 @@ +#include "confaparenciawidget.h" +//*********************************************************** +ConfAparenciaWidget::ConfAparenciaWidget(QWidget * parent) : QWidget(parent) +{ + setupUi(this); + + //Armazena cada id de elemento no arquivo de configuração + QString ids_confs[]={ + AtributosParsers::GLOBAL, AtributosParsers::RESTRICOES, AtributosParsers::SELECAO_OBJETO, + AtributosParsers::INFO_POSICAO, AtributosParsers::INFO_POSICAO, + AtributosParsers::TIPO_OBJETO, AtributosParsers::ARCO_CADEADO, AtributosParsers::CORPO_CADEADO, + AtributosParsers::NOME_ESQUEMA_TABELA, AtributosParsers::NOME_TABELA, AtributosParsers::CORPO_TABELA, + AtributosParsers::CORPO_EXT_TABELA, AtributosParsers::TITULO_TABELA, ObjetoBase::obterNomeEsquemaObjeto(OBJETO_REGRA), + ObjetoBase::obterNomeEsquemaObjeto(OBJETO_REGRA), ObjetoBase::obterNomeEsquemaObjeto(OBJETO_INDICE), + ObjetoBase::obterNomeEsquemaObjeto(OBJETO_INDICE), ObjetoBase::obterNomeEsquemaObjeto(OBJETO_GATILHO), + ObjetoBase::obterNomeEsquemaObjeto(OBJETO_GATILHO), AtributosParsers::NOME_ESQUEMA_VISAO, AtributosParsers::NOME_VISAO, + AtributosParsers::CORPO_VISAO, AtributosParsers::TITULO_VISAO, AtributosParsers::ALIAS, + AtributosParsers::COLUNA_REF, AtributosParsers::TABELA_REF, AtributosParsers::REFERENCIA, + ObjetoBase::obterNomeEsquemaObjeto(OBJETO_CAIXA_TEXTO), AtributosParsers::COLUNA, AtributosParsers::COLUNA, + AtributosParsers::COLUNA_HERDADA, AtributosParsers::COLUNA_PROTEGIDA, AtributosParsers::COLUNA_PK, + AtributosParsers::COLUNA_PK, AtributosParsers::COLUNA_FK, AtributosParsers::COLUNA_FK, + AtributosParsers::COLUNA_UQ, AtributosParsers::COLUNA_UQ, AtributosParsers::COLUNA_NN, + AtributosParsers::COLUNA_NN, AtributosParsers::RELACIONAMENTO, AtributosParsers::ROTULO, + AtributosParsers::ROTULO, AtributosParsers::ATRIBUTO, AtributosParsers::ATRIBUTO }; + int i, qtd=elemento_cmb->count(), + //Este vetor armazena os índices dos elementos os quais referem-se a configuraçao de cor de objetos + vet_ids_aux[]={ 2, 4, 6, 7, 10, 11, 12, 14, 16, 18, 21, 22, + 26, 27, 29, 33, 35, 37, 39, 40, 42, 44 }; + vector ids_confs_obj(vet_ids_aux, vet_ids_aux + sizeof(vet_ids_aux) / sizeof(int)); + + //Aloca o vetor de itens de configuração e atribui cada id de configuração aos elementos + itens_conf.resize(qtd); + for(i=0; i < qtd; i++) + { + itens_conf[i].id_conf=ids_confs[i]; + itens_conf[i].conf_obj=(std::find(ids_confs_obj.begin(), ids_confs_obj.end(), i)!=ids_confs_obj.end()); + } + + modelo=new ModeloBD; + cena=new CenaObjetos; + cena->setSceneRect(QRectF(0,0,500,500)); + + //Aloca o viewport com algumas opções de otimização na renderização + viewp=new QGraphicsView(cena); + viewp->setEnabled(false); + viewp->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + viewp->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + viewp->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + //Ativa o antialiasing de fonte e objetos + viewp->setRenderHint(QPainter::Antialiasing); + viewp->setRenderHint(QPainter::TextAntialiasing); + viewp->setRenderHint(QPainter::SmoothPixmapTransform); + + //Força a cena a ser desenhada da esquerda para a direita e de cima para baixo + viewp->setAlignment(Qt::AlignLeft | Qt::AlignTop); + + //Otimizações: Cache do background (grade) e atualização mínima do viewport + viewp->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); + viewp->centerOn(0,0); + + confaparencia_grid->addWidget(viewp, confaparencia_grid->count()-1, 0, 1, 5); + + connect(elemento_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(habilitarElemConfiguracao(void))); + connect(cor1_tb, SIGNAL(clicked(void)), this, SLOT(aplicarCorElemento(void))); + connect(cor2_tb, SIGNAL(clicked(void)), this, SLOT(aplicarCorElemento(void))); + connect(cor3_tb, SIGNAL(clicked(void)), this, SLOT(aplicarCorElemento(void))); + + connect(fonte_cmb, SIGNAL(currentFontChanged(QFont)), this, SLOT(aplicarEstiloFonte(void))); + connect(tam_fonte_spb, SIGNAL(valueChanged(double)), this, SLOT(aplicarEstiloFonte(void))); + connect(negrito_chk, SIGNAL(toggled(bool)), this, SLOT(aplicarEstiloFonte(void))); + connect(sublinhado_chk, SIGNAL(toggled(bool)), this, SLOT(aplicarEstiloFonte(void))); + connect(italico_chk, SIGNAL(toggled(bool)), this, SLOT(aplicarEstiloFonte(void))); +} +//----------------------------------------------------------- +ConfAparenciaWidget::~ConfAparenciaWidget(void) +{ + delete(viewp); + delete(cena); + delete(modelo); +} +//----------------------------------------------------------- +void ConfAparenciaWidget::criarObjetosExemplo(void) +{ + try + { + OGRelacionamento *rel=NULL; + OGCaixaTexto *caixa=NULL; + OGTabela *tab=NULL; + OGVisao *visao=NULL; + unsigned qtd, i; + + //Caso não existam objetos no modelo faz o carregamento do arquivo + if(modelo->obterNumObjetos()==0) + { + modelo->carregarModelo(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::MODELO_EXEMPLO); + + qtd=modelo->obterNumObjetos(OBJETO_TABELA); + for(i=0; i < qtd; i++) + { + tab=new OGTabela(modelo->obterTabela(i)); + tab->setSelected(i==1); + cena->addItem(tab); + } + + qtd=modelo->obterNumObjetos(OBJETO_VISAO); + for(i=0; i < qtd; i++) + { + visao=new OGVisao(modelo->obterVisao(i)); + cena->addItem(visao); + } + + qtd=modelo->obterNumObjetos(OBJETO_RELACAO); + for(i=0; i < qtd; i++) + { + rel=new OGRelacionamento(modelo->obterRelacionamento(i, OBJETO_RELACAO)); + cena->addItem(rel); + } + + qtd=modelo->obterNumObjetos(OBJETO_RELACAO_BASE); + for(i=0; i < qtd; i++) + { + rel=new OGRelacionamento(modelo->obterRelacionamento(i, OBJETO_RELACAO_BASE)); + cena->addItem(rel); + } + + qtd=modelo->obterNumObjetos(OBJETO_CAIXA_TEXTO); + for(i=0; i < qtd; i++) + { + caixa=new OGCaixaTexto(modelo->obterCaixaTexto(i)); + caixa->setSelected(i==0); + cena->addItem(caixa); + } + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfAparenciaWidget::carregarConfiguracao(void) +{ + try + { + int i, qtd=itens_conf.size(); + + //Carrega o arquivo de estilo de objetos + ObjetoGrafico::carregarEstiloObjetos(); + + //Cria os objetos de exemplo + this->criarObjetosExemplo(); + + //Obtém cada estilo carregado do arquivo e os atribui ao itens de configuração + for(i=0; i < qtd; i++) + { + //Caso o item de configuração atual refere-se a cores de um objeto + if(itens_conf[i].conf_obj) + { + //Obtém o estilo de preenchimento e da borda e os armazena no item atual + ObjetoGrafico::obterEstiloPreenchimento(itens_conf[i].id_conf, + itens_conf[i].cores[0], itens_conf[i].cores[1]); + itens_conf[i].cores[2]=ObjetoGrafico::obterEstiloBorda(itens_conf[i].id_conf).color(); + } + else + //Caso o item atual seja um elemento de configuração de fonte, obtém o estilo de fonte respectivo + itens_conf[i].fmt_fonte=ObjetoGrafico::obterEstiloFonte(itens_conf[i].id_conf); + } + + //Inicializa o formulário de configuração de aparência + this->habilitarElemConfiguracao(); + + //Marca no combo de fontes, a fonte global + fonte_cmb->setCurrentFont(ObjetoGrafico::obterEstiloFonte(AtributosParsers::GLOBAL).font()); + + //Define todos os objetos do modelo de exemplo como modificados, forçando seu redesenho + modelo->definirObjetosModificados(); + cena->update(); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfAparenciaWidget::salvarConfiguracao(void) +{ + try + { + map atribs; + vector::iterator itr, itr_end; + ItemConfAparencia item; + QString id_atrib; + QFont fonte; + + itr=itens_conf.begin(); + itr_end=itens_conf.end(); + + while(itr!=itr_end) + { + item=(*itr); + itr++; + + //Caso o item atual refere-se a um elemento de cor de objeto + if(item.conf_obj) + { + //Cria um atributo o qual armazena a cor de preenchimento + id_atrib=item.id_conf + QString("-color"); + if(item.cores[0]==item.cores[1]) + atribs[id_atrib]=item.cores[0].name(); + else + atribs[id_atrib]=item.cores[0].name() + QString(",") + item.cores[1].name(); + + //Cria um atributo o qual armazena a cor da borda + id_atrib=item.id_conf + QString("-bcolor"); + atribs[id_atrib]=item.cores[2].name(); + } + /* Caso o item atual seja um elemento de fonte do objeto porém não seja o + elemento de configuração global de fonte */ + else if(item.id_conf!=AtributosParsers::GLOBAL && !item.conf_obj) + { + //Obtém a fonte do item + fonte=item.fmt_fonte.font(); + + //Cria um atributo que armazena a cor da fonte + id_atrib=item.id_conf + QString("-fcolor"); + atribs[id_atrib]=item.fmt_fonte.foreground().color().name(); + + //Cria um atributo que armazena se a fonte está em itálico, negrito e sublinhado + id_atrib=item.id_conf + QString("-") + AtributosParsers::ITALICO; + atribs[id_atrib]=(fonte.italic() ? AtributosParsers::VERDADEIRO : AtributosParsers::FALSO); + + id_atrib=item.id_conf + QString("-") + AtributosParsers::NEGRITO; + atribs[id_atrib]=(fonte.bold() ? AtributosParsers::VERDADEIRO : AtributosParsers::FALSO); + + id_atrib=item.id_conf + QString("-") + AtributosParsers::SUBLINHADO; + atribs[id_atrib]=(fonte.underline() ? AtributosParsers::VERDADEIRO : AtributosParsers::FALSO); + } + //Caso o item atual seja o elemento global de fonte + else + { + //Cria dois atributos que armazenam o nome e o tamanho da fonte global do modelo + atribs["font-name"]=QFontInfo(item.fmt_fonte.font()).family(); + atribs["font-size"]=QString("%1").arg(item.fmt_fonte.font().pointSizeF()); + } + } + + //Especifica aos parâmetros de configuração de estilo de objetos os atributos configurados acima + params_config[AtributosGlobais::CONF_ESTILO_OBJETOS]=atribs; + + //Salva a configuração em arquivo + ConfBaseWidget::salvarConfiguracao(AtributosGlobais::CONF_ESTILO_OBJETOS); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfAparenciaWidget::habilitarElemConfiguracao(void) +{ + QPalette pal; + int idx=elemento_cmb->currentIndex(); + + //Widgets que ficam habilitados somente quando o elemento global de fonte está selecionado + fonte_cmb->setEnabled(idx==0); + fonte_lbl->setEnabled(idx==0); + tam_fonte_spb->setEnabled(idx==0); + unidade_lbl->setEnabled(idx==0); + + /* Widgets que ficam habilitados somente quando o elemento atual não é o global e o + mesmo também não é elemento de cor de objetos */ + sublinhado_chk->setEnabled(idx!=0 && !itens_conf[idx].conf_obj); + negrito_chk->setEnabled(idx!=0 && !itens_conf[idx].conf_obj); + italico_chk->setEnabled(idx!=0 && !itens_conf[idx].conf_obj); + + //Estes elementos ficam visíveis quando o elemento global não está selecionado + cores_lbl->setVisible(idx!=0); + cor1_tb->setVisible(idx!=0); + + //Estes widgets ficam visíveis somente quando o elemento atual é referente a cor de objetos + cor2_tb->setVisible(itens_conf[idx].conf_obj); + cor3_tb->setVisible(itens_conf[idx].conf_obj); + + //Bloqueia os sinais de todos os widgets para evitar que slots sejam executados antes do tempo + cor1_tb->blockSignals(true); + cor2_tb->blockSignals(true); + cor3_tb->blockSignals(true); + sublinhado_chk->blockSignals(true); + italico_chk->blockSignals(true); + negrito_chk->blockSignals(true); + fonte_cmb->blockSignals(true); + tam_fonte_spb->blockSignals(true); + + /* Caso o elemento atual refere-se a uma configuração de fonte, + preenche os widgets com os dados da fonte */ + if(!itens_conf[idx].conf_obj) + { + QTextCharFormat fmt=ObjetoGrafico::obterEstiloFonte(itens_conf[idx].id_conf); + pal.setColor(QPalette::Button, fmt.foreground()); + cor1_tb->setPalette(pal); + sublinhado_chk->setChecked(fmt.font().underline()); + italico_chk->setChecked(fmt.font().italic()); + negrito_chk->setChecked(fmt.font().bold()); + fonte_cmb->setCurrentFont(fmt.font()); + tam_fonte_spb->setValue(fmt.font().pointSizeF()); + } + /* Caso o elemento atual seja de configuração de cor do objeto, + preenche os botões de cores com as cores configuradas ao elemento */ + else + { + QColor cor1, cor2; + + ObjetoGrafico::obterEstiloPreenchimento(itens_conf[idx].id_conf, cor1, cor2); + + pal.setColor(QPalette::Button, cor1); + cor1_tb->setPalette(pal); + + pal.setColor(QPalette::Button, cor2); + cor2_tb->setPalette(pal); + + pal.setColor(QPalette::Button, ObjetoGrafico::obterEstiloBorda(itens_conf[idx].id_conf).color()); + cor3_tb->setPalette(pal); + + sublinhado_chk->setChecked(false); + italico_chk->setChecked(false); + negrito_chk->setChecked(false); + } + + //Desbloqueia os sinais dos widgets + cor1_tb->blockSignals(false); + cor2_tb->blockSignals(false); + cor3_tb->blockSignals(false); + sublinhado_chk->blockSignals(false); + italico_chk->blockSignals(false); + negrito_chk->blockSignals(false); + fonte_cmb->blockSignals(false); + tam_fonte_spb->blockSignals(false); +} +//----------------------------------------------------------- +void ConfAparenciaWidget::aplicarCorElemento(void) +{ + QToolButton *btn=dynamic_cast(sender()); + + if(btn) + { + QPalette pal; + unsigned idx_cor; + + //Executa o diálogo de seleção de cores + pal=btn->palette(); + cor_dlg.setCurrentColor(pal.color(QPalette::Button)); + cor_dlg.exec(); + + //Caso o usuário selecionou uma cor + if(cor_dlg.result()==QDialog::Accepted) + { + //Preenche o botão acionado com a cor escolhida do diálogo de cores + pal.setColor(QPalette::Button, cor_dlg.selectedColor()); + btn->setPalette(pal); + + //Caso seja uma configuração de cor de objetos + if(itens_conf[elemento_cmb->currentIndex()].conf_obj) + { + //Conforme o botão acionado define-se o índice da cor a ser configurada + if(btn==cor1_tb) idx_cor=0; + else if(btn==cor2_tb) idx_cor=1; + else idx_cor=3; + + //Atribui a cor configurada ao elemento atual + itens_conf[elemento_cmb->currentIndex()].cores[idx_cor]=cor_dlg.selectedColor(); + ObjetoGrafico::definirCorElemento(itens_conf[elemento_cmb->currentIndex()].id_conf, cor_dlg.selectedColor(), idx_cor); + } + //Caso seja uma configuração de fonte + else + { + //Atribui a cor selecionada à cor da fonte do elemento atual + itens_conf[elemento_cmb->currentIndex()].fmt_fonte.setForeground(cor_dlg.selectedColor()); + ObjetoGrafico::definirEstiloFonte(itens_conf[elemento_cmb->currentIndex()].id_conf, + itens_conf[elemento_cmb->currentIndex()].fmt_fonte); + } + + //Atualiza o modelo de exemplo para exibir as modificações de aparência + modelo->definirObjetosModificados(); + cena->update(); + } + } +} +//----------------------------------------------------------- +void ConfAparenciaWidget::aplicarEstiloFonte(void) +{ + QFont fonte; + + //Configura uma fonte com os dados configurados no formulário + fonte=fonte_cmb->currentFont(); + fonte.setBold(negrito_chk->isChecked()); + fonte.setItalic(italico_chk->isChecked()); + fonte.setUnderline(sublinhado_chk->isChecked()); + fonte.setPointSizeF(tam_fonte_spb->value()); + + //Atribui a fonte configurada ao elemento + itens_conf[elemento_cmb->currentIndex()].fmt_fonte.setFont(fonte); + ObjetoGrafico::definirEstiloFonte(itens_conf[elemento_cmb->currentIndex()].id_conf, + itens_conf[elemento_cmb->currentIndex()].fmt_fonte); + + //Atualiza o modelo de exemplo para exibir as modificações de aparência + modelo->definirObjetosModificados(); + cena->update(); +} +//----------------------------------------------------------- +void ConfAparenciaWidget::restaurarPadroes(void) +{ + try + { + //Restaura as configurações padrão e recarrega o arquivo restaurado + ConfBaseWidget::restaurarPadroes(AtributosGlobais::CONF_ESTILO_OBJETOS); + this->carregarConfiguracao(); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/confaparenciawidget.h b/libpgmodeler_ui/src/confaparenciawidget.h new file mode 100644 index 000000000..cedd5f9aa --- /dev/null +++ b/libpgmodeler_ui/src/confaparenciawidget.h @@ -0,0 +1,88 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ConfAparenciaWidget +# Descrição: Implementa o widget de configurações de aparência dos objetos do modelo. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CONF_APARENCIA_WIDGET_H +#define CONF_APARENCIA_WIDGET_H + +#include "ui_confaparenciawidget.h" +#include "confbasewidget.h" +#include "cenaobjetos.h" +#include "modelobd.h" +#include +//*********************************************************** +class ConfAparenciaWidget: public QWidget, public Ui::ConfAparenciaWidget, public ConfBaseWidget { + private: + Q_OBJECT + + //Classe auxiliar que armazena os dados da formatação de cada elemento + class ItemConfAparencia { + public: + QString id_conf; + QTextCharFormat fmt_fonte; + QColor cores[3]; + bool conf_obj; + }; + + //Diálogo de seleção de cor + QColorDialog cor_dlg; + + //Viewport que mostra o modelo de exemplo + QGraphicsView *viewp; + + //Cena que armazena os objetos do modelo de exemplo + CenaObjetos *cena; + + //Modelo de objetos exemplo + ModeloBD *modelo; + + //Vetor o qual armazena cada elemento de configuração de aparência do modelo + vector itens_conf; + + //Carrega o modelo de exemplo + void criarObjetosExemplo(void); + + public: + ConfAparenciaWidget(QWidget * parent=0); + ~ConfAparenciaWidget(void); + + void salvarConfiguracao(void); + void carregarConfiguracao(void); + + private slots: + //Habilita os itens do formulário conforme o elemento selecionado no combobox 'elemento_cmb' + void habilitarElemConfiguracao(void); + + //Aplica o estilo de fonte ao elemento atual + void aplicarEstiloFonte(void); + + //Aplica o estilo de cor ao elemento atual + void aplicarCorElemento(void); + + /* Este método não é usado nesta classe pois as modificações são aplicadas diretamente + ao arquivo, operação esta tratada pelo método salvarConfiguracao() */ + void aplicarConfiguracao(void){} + + public slots: + void restaurarPadroes(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/confbasewidget.cpp b/libpgmodeler_ui/src/confbasewidget.cpp new file mode 100644 index 000000000..e200b86b0 --- /dev/null +++ b/libpgmodeler_ui/src/confbasewidget.cpp @@ -0,0 +1,197 @@ +#include "confbasewidget.h" +//*********************************************************** +void ConfBaseWidget::adicionarParamConfiguracao(const QString ¶m, const map &atributos) +{ + //Adiciona um parâmetro somente se o identificador 'param' e os atributos não estejam vazio + if(!param.isEmpty() && !atributos.empty()) + params_config[param]=atributos; +} +//----------------------------------------------------------- +map > ConfBaseWidget::obterParamsConfiguracao(void) +{ + return(params_config); +} +//----------------------------------------------------------- +void ConfBaseWidget::excluirParamConfiguracao(const QString ¶m) +{ + params_config.erase(param); +} +//----------------------------------------------------------- +void ConfBaseWidget::excluirParamsConfiguracao(void) +{ + params_config.clear(); +} +//----------------------------------------------------------- +void ConfBaseWidget::salvarConfiguracao(const QString &id_conf) +{ + QString buf, + //Configura o nome do arquivo de modelo (esquema) de configuração + nome_arq_sch=AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::DIR_ESQUEMAS + + AtributosGlobais::SEP_DIRETORIO + + id_conf + + AtributosGlobais::EXT_ESQUEMA, + //Configura o nome do arquivo de configuração + nome_arq=AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + id_conf + + AtributosGlobais::EXT_CONFIGURACAO; + QFile saida(nome_arq); + map atribs; + map >::iterator itr, itr_end; + + try + { + itr=params_config.begin(); + itr_end=params_config.end(); + + while(itr!=itr_end) + { + atribs.insert((itr->second).begin(), (itr->second).end()); + itr++; + } + + //Gera o modelo de configuração com base nos parâmetros atuais + buf=ParserEsquema::obterDefinicaoObjeto(nome_arq_sch, atribs); + + //Abre o arquivo de configuração para gravação + saida.open(QFile::WriteOnly); + + //Caso não consiga abrir o arquivo para gravação + if(!saida.isOpen()) + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELER_ARQNAOGRAVADO).arg(nome_arq), + ERR_PGMODELER_ARQNAOGRAVADO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Grava o buffer gerado no arquivo + saida.write(buf.toStdString().c_str(), buf.size()); + saida.close(); + } + catch(Excecao &e) + { + if(saida.isOpen()) saida.close(); + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELER_ARQNAOGRAVADODEFINV).arg(nome_arq), + ERR_PGMODELER_ARQNAOGRAVADODEFINV,__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfBaseWidget::restaurarPadroes(const QString &id_conf) +{ + QString arq_atual, arq_orig; + + //Monta o caminho para o arquivo de configuração atual (conf/arquivo.conf) + arq_atual=AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + id_conf + + AtributosGlobais::EXT_CONFIGURACAO; + + //Monta o caminho para o arquivo de configuração original (padrão) (conf/defaults/arquivo.conf) + arq_orig=AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::DIR_CONF_PADRAO+ + AtributosGlobais::SEP_DIRETORIO + + id_conf + + AtributosGlobais::EXT_CONFIGURACAO; + + //Verifica a existência do arquivo padrão, caso não existe emite uma exceção e a restauração é abortada + if(!QFile::exists(arq_orig)) + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_CONFPADRAONAORESTAURADA).arg(arq_orig), + ERR_PGMODELERUI_CONFPADRAONAORESTAURADA,__PRETTY_FUNCTION__,__FILE__,__LINE__); + else + { + //Remove o arquivo atual + QFile::remove(arq_atual); + //Copia o arquivo original no lugar do arquivo atual + QFile::copy(arq_orig, arq_atual); + } +} +//----------------------------------------------------------- +void ConfBaseWidget::carregarConfiguracao(const QString &id_conf, const vector &atribs_chave) +{ + try + { + //Limpa os parâmetros de configuração atuais + params_config.clear(); + + //Reinicia o parser XML para a leitura do arquivo + ParserXML::reiniciarParser(); + + ParserXML::definirArquivoDTD(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::DIR_DTD_OBJETO + + AtributosGlobais::SEP_DIRETORIO + + id_conf + + AtributosGlobais::EXT_DTD_OBJETO, + id_conf); + + ParserXML::carregarArquivoXML(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + id_conf + + AtributosGlobais::EXT_CONFIGURACAO); + + if(ParserXML::acessarElemento(ParserXML::ELEMENTO_FILHO)) + { + do + { + /* Certificando que só elementos xml serão lidos do parser, + qualquer outro tipo de objeto xml será ignorado */ + if(ParserXML::obterTipoElemento()==XML_ELEMENT_NODE) + { + this->obterParamsConfiguracao(atribs_chave); + + if(ParserXML::possuiElemento(ParserXML::ELEMENTO_FILHO)) + { + ParserXML::salvarPosicao(); + ParserXML::acessarElemento(ParserXML::ELEMENTO_FILHO); + + do + { + this->obterParamsConfiguracao(atribs_chave); + } + while(ParserXML::acessarElemento(ParserXML::ELEMENTO_POSTERIOR)); + + ParserXML::restaurarPosicao(); + } + } + } + while(ParserXML::acessarElemento(ParserXML::ELEMENTO_POSTERIOR)); + } + } + catch(Excecao &e) + { + //Redireciona qualquer exceção capturada + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfBaseWidget::obterParamsConfiguracao(const vector &atribs_chave) +{ + map atrib_aux; + map::iterator itr, itr_end; + QString chave; + + //Obtém os atributos do elemento atual + ParserXML::obterAtributosElemento(atrib_aux); + + itr=atrib_aux.begin(); + itr_end=atrib_aux.end(); + + //Substituindo a chave pelo atributo chave passado + while(itr!=itr_end && chave.isEmpty()) + { + //Caso o atributo chave seja encontrado em um dos atributos obtidos do elemento + if(chave.isEmpty() && find(atribs_chave.begin(), atribs_chave.end(), itr->first)!=atribs_chave.end()) + //A chave passa a ser o valor do atributo encontrado + chave=itr->second; + itr++; + } + + //Caso a chave não foi definida, a chave padrão será o nome do elemento + if(chave.isEmpty()) + chave=ParserXML::obterNomeElemento(); + + //Atribui os dados obtidos do elemento atual à chave do mapa de parâmetros de configuração + if(!atrib_aux.empty()) + params_config[chave]=atrib_aux; +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/confbasewidget.h b/libpgmodeler_ui/src/confbasewidget.h new file mode 100644 index 000000000..d97b717a8 --- /dev/null +++ b/libpgmodeler_ui/src/confbasewidget.h @@ -0,0 +1,71 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ConfBaseWidget +# Descrição: Implementa operações básicas para gravação de arquivos e acesso às configuraçoẽs +# nos widgets de configurações. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CONF_BASE_WIDGET_H +#define CONF_BASE_WIDGET_H + +#include "excecao.h" +#include "parserxml.h" +#include "atributosparsers.h" +#include +//*********************************************************** +class ConfBaseWidget { + protected: + //Mapa que armazena os parâmetros de configuração carregados do arquivos + map > params_config; + + /* Salva as configurações em arquivo. O parâmetro 'id_conf' indica qual o + tipo da configuração a ser salva. (vide AtributosGlobais::CONF_???) */ + void salvarConfiguracao(const QString &id_conf); + + /* Carrega as configurações do arquivo. O vetor 'atribs_chaves' é usado para especificar o nome de elementos + considerados chave do mapa de configuração */ + void carregarConfiguracao(const QString &id_conf, const vector &atribs_chave=vector()); + + //Obtém um parâmetro do arquivo de configuração carregado pelo ParserXML + void obterParamsConfiguracao(const vector &atribs_chave); + + //Restaura as configurações padrão carregando-as do arquivo original (na pasta conf/defaults) + void restaurarPadroes(const QString &id_conf); + + public: + ConfBaseWidget(void){} + + //Adiciona um parâmetro de configuração ao mapa de configurações. Caso o mesmo já existe seus valores são substituídos + void adicionarParamConfiguracao(const QString ¶m, const map &atributos); + + //Obtém os parâmetros carregados do arquivo + map > obterParamsConfiguracao(void); + + //Exclui os valores de um dado parâmetro de configuração + void excluirParamConfiguracao(const QString ¶m); + + //Exclui todos os parâmetros de configuração + void excluirParamsConfiguracao(void); + + /** Método puramente virtual **/ + //Aplica as configurações padrão + virtual void aplicarConfiguracao(void)=0; +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/confconexoeswidget.cpp b/libpgmodeler_ui/src/confconexoeswidget.cpp new file mode 100644 index 000000000..c6b8057aa --- /dev/null +++ b/libpgmodeler_ui/src/confconexoeswidget.cpp @@ -0,0 +1,461 @@ +#include "confconexoeswidget.h" +#include "caixamensagem.h" + +extern CaixaMensagem *caixa_msg; +//*********************************************************** +ConfConexoesWidget::ConfConexoesWidget(QWidget * parent) : QWidget(parent) +{ + setupUi(this); + + connect(modo_ssl_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(habilitarCertificados(void))); + + connect(nova_tb, SIGNAL(clicked(bool)), this, SLOT(novaConexao(void))); + connect(cancelar_tb, SIGNAL(clicked(bool)), this, SLOT(novaConexao(void))); + + connect(testar_tb, SIGNAL(clicked(bool)), this, SLOT(testarConexao(void))); + connect(adicionar_tb, SIGNAL(clicked(bool)), this, SLOT(manipularConexao(void))); + connect(atualizar_tb, SIGNAL(clicked(bool)), this, SLOT(manipularConexao(void))); + connect(editar_tb, SIGNAL(clicked(bool)), this, SLOT(editarConexao(void))); + connect(excluir_tb, SIGNAL(clicked(bool)), this, SLOT(removerConexao(void))); + + connect(alias_edt, SIGNAL(textChanged(QString)), this, SLOT(habilitarTesteConexao(void))); + connect(host_edt, SIGNAL(textChanged(QString)), this, SLOT(habilitarTesteConexao(void))); + connect(usuario_edt, SIGNAL(textChanged(QString)), this, SLOT(habilitarTesteConexao(void))); + connect(senha_edt, SIGNAL(textChanged(QString)), this, SLOT(habilitarTesteConexao(void))); + connect(bd_conexao_edt, SIGNAL(textChanged(QString)), this, SLOT(habilitarTesteConexao(void))); + + atualizar_tb->setVisible(false); + cancelar_tb->setVisible(false); +} +//------------------------------------------------------------ +ConfConexoesWidget::~ConfConexoesWidget(void) +{ + /* Remove todas as conexões carregadas ao destruir o formulário, + (desalocando os descritores de conexão criados) */ + while(conexoes_cmb->count() > 0) + this->removerConexao(); +} +//------------------------------------------------------------ +void ConfConexoesWidget::carregarConfiguracao(void) +{ + vector atribs_chave; + map >::iterator itr, itr_end; + ConexaoBD *conexao=NULL; + + //Expressão regular usada para validar o endereço digitado para o servidor + QRegExp ip_regexp("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"); + + //Para a sessão de configuração de conexões, o 'alias' será usado como campo chave + atribs_chave.push_back(AtributosParsers::ALIAS); + + //Carrega as configurações + ConfBaseWidget::carregarConfiguracao(AtributosGlobais::CONF_CONEXOES, atribs_chave); + + itr=params_config.begin(); + itr_end=params_config.end(); + + while(itr!=itr_end) + { + //Aloca uma nova conexão + conexao=new ConexaoBD; + + /* Caso o host da conexão seja um IP, atribui o valor ao parâmetro, + ConexaoBD::PARAM_IP_SERVIDOR da conexão. Caso contrário atribui ao + ConexaoBD::PARAM_FQDN_SERVIDOR. A libpq trata separadamente IP e FQDN do servidor + por isso é necessária esta distinção */ + if(ip_regexp.exactMatch(itr->second[ConexaoBD::PARAM_FQDN_SERVIDOR])) + conexao->definirParamConexao(ConexaoBD::PARAM_IP_SERVIDOR, itr->second[ConexaoBD::PARAM_FQDN_SERVIDOR]); + else + conexao->definirParamConexao(ConexaoBD::PARAM_FQDN_SERVIDOR, itr->second[ConexaoBD::PARAM_FQDN_SERVIDOR]); + + //Atribuindo os demais valores à conexão + conexao->definirParamConexao(ConexaoBD::PARAM_PORTA, itr->second[ConexaoBD::PARAM_PORTA]); + conexao->definirParamConexao(ConexaoBD::PARAM_USUARIO, itr->second[ConexaoBD::PARAM_USUARIO]); + conexao->definirParamConexao(ConexaoBD::PARAM_SENHA,itr->second[ConexaoBD::PARAM_SENHA]); + conexao->definirParamConexao(ConexaoBD::PARAM_NOME_BD, itr->second[ConexaoBD::PARAM_NOME_BD]); + conexao->definirParamConexao(ConexaoBD::PARAM_TEMPO_CONEXAO, itr->second[ConexaoBD::PARAM_TEMPO_CONEXAO]); + conexao->definirParamConexao(ConexaoBD::PARAM_MODO_SSL, itr->second[ConexaoBD::PARAM_MODO_SSL]); + conexao->definirParamConexao(ConexaoBD::PARAM_CERT_RAIZ_SSL, itr->second[ConexaoBD::PARAM_CERT_RAIZ_SSL]); + conexao->definirParamConexao(ConexaoBD::PARAM_CERT_SSL, itr->second[ConexaoBD::PARAM_CERT_SSL]); + conexao->definirParamConexao(ConexaoBD::PARAM_CHAVE_SSL, itr->second[ConexaoBD::PARAM_CHAVE_SSL]); + conexao->definirParamConexao(ConexaoBD::PARAM_CRL_SSL, itr->second[ConexaoBD::PARAM_CRL_SSL]); + conexao->definirParamConexao(ConexaoBD::PARAM_LIB_GSSAPI, itr->second[ConexaoBD::PARAM_LIB_GSSAPI]); + conexao->definirParamConexao(ConexaoBD::PARAM_SERVIDOR_KERBEROS, itr->second[ConexaoBD::PARAM_SERVIDOR_KERBEROS]); + conexao->definirParamConexao(ConexaoBD::PARAM_OPCOES, itr->second[ConexaoBD::PARAM_OPCOES]); + + //Adiciona a conexão ao combo de conexões + conexoes_cmb->addItem(QString::fromUtf8(itr->second[AtributosParsers::ALIAS]), + QVariant::fromValue(reinterpret_cast(conexao))); + + itr++; + } + + /* Habilita os botões de edição e exclusão caso, após o carregamento, + hajam conexões inseridas no combo */ + editar_tb->setEnabled(conexoes_cmb->count() > 0); + excluir_tb->setEnabled(conexoes_cmb->count() > 0); +} +//------------------------------------------------------------ +void ConfConexoesWidget::habilitarCertificados(void) +{ + /* Habilita os campos relacionados aos certificados SSL quando o modo + SSL escolhido é diferente de 'disable ' */ + cert_cliente_lbl->setEnabled(modo_ssl_cmb->currentIndex()!=0); + cert_cliente_edt->setEnabled(modo_ssl_cmb->currentIndex()!=0); + cert_raiz_lbl->setEnabled(modo_ssl_cmb->currentIndex()!=0); + cert_raiz_edt->setEnabled(modo_ssl_cmb->currentIndex()!=0); + crl_edt->setEnabled(modo_ssl_cmb->currentIndex()!=0); + crl_lbl->setEnabled(modo_ssl_cmb->currentIndex()!=0); + chave_cli_lbl->setEnabled(modo_ssl_cmb->currentIndex()!=0); + chave_cli_edt->setEnabled(modo_ssl_cmb->currentIndex()!=0); +} +//------------------------------------------------------------ +void ConfConexoesWidget::habilitarTesteConexao(void) +{ + /* O teste de conexão só é habilitado quando informações básicas + como alias, host, usuario, senha e db de conexão estão especificados */ + testar_tb->setEnabled(!alias_edt->text().isEmpty() && + !host_edt->text().isEmpty() && + !usuario_edt->text().isEmpty() && + !senha_edt->text().isEmpty() && + !bd_conexao_edt->text().isEmpty()); + adicionar_tb->setEnabled(testar_tb->isEnabled()); + atualizar_tb->setEnabled(testar_tb->isEnabled()); +} +//------------------------------------------------------------ +void ConfConexoesWidget::novaConexao(void) +{ + /* Limpa todo o formulário e reverte os valores de alguns + campos para seus valores padrão */ + bd_conexao_edt->clear(); + alias_edt->clear(); + usuario_edt->clear(); + host_edt->clear(); + porta_sbp->setValue(5432); + senha_edt->clear(); + opcoes_edt->clear(); + + modo_ssl_cmb->setCurrentIndex(0); + cert_cliente_edt->setText("~/.postgresql/postgresql.crt"); + cert_raiz_edt->setText("~/.postgresql/root.crt"); + crl_edt->setText("~/.postgresql/root.crl"); + chave_cli_edt->setText("~/.postgresql/postgresql.key"); + + aut_gssapi_chk->setChecked(false); + serv_kerberus_edt->clear(); + + timeout_sbp->setValue(2); + adicionar_tb->setVisible(true); + atualizar_tb->setVisible(false); + conexoes_cmb->setEnabled(true); + + nova_tb->setVisible(true); + cancelar_tb->setVisible(false); + + editar_tb->setEnabled(conexoes_cmb->count() > 0); + excluir_tb->setEnabled(conexoes_cmb->count() > 0); +} +//------------------------------------------------------------ +void ConfConexoesWidget::manipularConexao(void) +{ + ConexaoBD *conexao=NULL; + QString alias; + unsigned i=1; + + try + { + /* Verificando duplicidade nos alias das conexões antes de manipular. + Caso alguma seja detectada, a conexão terá um sufixo '([0-9]+)' + adicionado */ + alias=alias_edt->text(); + while(conexoes_cmb->findText(alias)>=0) + alias=QString("%1(%2)").arg(alias_edt->text()).arg(i++); + + if(!atualizar_tb->isVisible()) + { + conexao=new ConexaoBD; + this->configurarConexao(conexao); + conexoes_cmb->addItem(alias, QVariant::fromValue(reinterpret_cast(conexao))); + } + else + { + conexao=reinterpret_cast(conexoes_cmb->itemData(conexoes_cmb->currentIndex()).value()); + this->configurarConexao(conexao); + conexoes_cmb->setItemText(conexoes_cmb->currentIndex(), alias); + } + + this->novaConexao(); + editar_tb->setEnabled(conexoes_cmb->count() > 0); + excluir_tb->setEnabled(conexoes_cmb->count() > 0); + } + catch(Excecao &e) + { + if(adicionar_tb->isVisible()) + delete(conexao); + + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//------------------------------------------------------------ +void ConfConexoesWidget::removerConexao(void) +{ + //Caso haja uma conexão selecionada no combo + if(conexoes_cmb->currentIndex() >= 0) + { + ConexaoBD *conexao=NULL; + + //Obtém a conexão do item do combobox + conexao=reinterpret_cast(conexoes_cmb->itemData(conexoes_cmb->currentIndex()).value()); + + //Remove o item do combo + conexoes_cmb->removeItem(conexoes_cmb->currentIndex()); + + //Desaloca o descritor de conexão + delete(conexao); + + //Reinicia o formulário + this->novaConexao(); + } +} +//------------------------------------------------------------ +void ConfConexoesWidget::editarConexao(void) +{ + //Caso hajam itens no combo de conexões + if(conexoes_cmb->count() > 0) + { + ConexaoBD *conexao=NULL; + + //Obtém a conexão selecionada + conexao=reinterpret_cast(conexoes_cmb->itemData(conexoes_cmb->currentIndex()).value()); + + //Preenche os campos do formulário com os valores dos atributos da conexão + alias_edt->setText(conexoes_cmb->currentText()); + + if(!conexao->obterParamConexao(ConexaoBD::PARAM_FQDN_SERVIDOR).isEmpty()) + host_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_FQDN_SERVIDOR)); + else + host_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_IP_SERVIDOR)); + + bd_conexao_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_NOME_BD)); + usuario_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_USUARIO)); + senha_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_SENHA)); + porta_sbp->setValue(conexao->obterParamConexao(ConexaoBD::PARAM_PORTA).toInt()); + timeout_sbp->setValue(conexao->obterParamConexao(ConexaoBD::PARAM_TEMPO_CONEXAO).toInt()); + + serv_kerberus_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_SERVIDOR_KERBEROS)); + aut_gssapi_chk->setChecked(conexao->obterParamConexao(ConexaoBD::PARAM_LIB_GSSAPI)=="gssapi"); + opcoes_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_OPCOES)); + + //Seta o modo de conexão SSL + if(conexao->obterParamConexao(ConexaoBD::PARAM_MODO_SSL)==ConexaoBD::SSL_DESATIVADO) + modo_ssl_cmb->setCurrentIndex(0); + else if(conexao->obterParamConexao(ConexaoBD::PARAM_MODO_SSL)==ConexaoBD::SSL_PERMITIR) + modo_ssl_cmb->setCurrentIndex(1); + else if(conexao->obterParamConexao(ConexaoBD::PARAM_MODO_SSL)==ConexaoBD::SSL_REQUERER) + modo_ssl_cmb->setCurrentIndex(2); + else if(conexao->obterParamConexao(ConexaoBD::PARAM_MODO_SSL)==ConexaoBD::SSL_VERIF_AUT_CERT) + modo_ssl_cmb->setCurrentIndex(3); + else + modo_ssl_cmb->setCurrentIndex(4); + + //Caso haja um modo SSL escolhido, preenche os campos de certificados digitais + if(modo_ssl_cmb->currentIndex() > 0) + { + cert_cliente_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_CERT_SSL)); + cert_raiz_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_CERT_RAIZ_SSL)); + chave_cli_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_CHAVE_SSL)); + crl_edt->setText(conexao->obterParamConexao(ConexaoBD::PARAM_CRL_SSL)); + } + + atualizar_tb->setVisible(true); + adicionar_tb->setVisible(false); + conexoes_cmb->setEnabled(false); + + nova_tb->setVisible(false); + cancelar_tb->setVisible(true); + editar_tb->setEnabled(false); + } +} +//------------------------------------------------------------ +void ConfConexoesWidget::configurarConexao(ConexaoBD *conexao) +{ + if(conexao) + { + QRegExp ip_regexp("[0-9]+\\.[0-9]+\\.[0-9]+\\.[0-9]+"); + + /* Caso o nome do host especificado no formulário seja um IP (combinando com a expressão regular) + atribui o valor ao campo respectivo na conexão. Caso contrário atribui ao campo de + nome de host (fqdn) */ + if(ip_regexp.exactMatch(host_edt->text())) + conexao->definirParamConexao(ConexaoBD::PARAM_IP_SERVIDOR, host_edt->text()); + else + conexao->definirParamConexao(ConexaoBD::PARAM_FQDN_SERVIDOR, host_edt->text()); + + //Atribuindo os valores básicos de conexão + conexao->definirParamConexao(ConexaoBD::PARAM_PORTA, QString("%1").arg(porta_sbp->value())); + conexao->definirParamConexao(ConexaoBD::PARAM_USUARIO, usuario_edt->text()); + conexao->definirParamConexao(ConexaoBD::PARAM_SENHA, senha_edt->text()); + conexao->definirParamConexao(ConexaoBD::PARAM_NOME_BD, bd_conexao_edt->text()); + conexao->definirParamConexao(ConexaoBD::PARAM_TEMPO_CONEXAO, QString("%1").arg(timeout_sbp->value())); + + //Configurando o modo SSL da conexão + switch(modo_ssl_cmb->currentIndex()) + { + case 1: + conexao->definirParamConexao(ConexaoBD::PARAM_MODO_SSL, ConexaoBD::SSL_PERMITIR); + break; + case 2: + conexao->definirParamConexao(ConexaoBD::PARAM_MODO_SSL, ConexaoBD::SSL_REQUERER); + break; + case 3: + conexao->definirParamConexao(ConexaoBD::PARAM_MODO_SSL, ConexaoBD::SSL_VERIF_AUT_CERT); + break; + case 4: + conexao->definirParamConexao(ConexaoBD::PARAM_MODO_SSL, ConexaoBD::SSL_VERIF_COMPLETA); + break; + default: + case 0: + conexao->definirParamConexao(ConexaoBD::PARAM_MODO_SSL, ConexaoBD::SSL_DESATIVADO); + break; + } + + //Caso haja um modo SSL selecionado, atribui os certificados usados para conexão + if(modo_ssl_cmb->currentIndex()!=0) + { + conexao->definirParamConexao(ConexaoBD::PARAM_CERT_RAIZ_SSL, cert_raiz_edt->text()); + conexao->definirParamConexao(ConexaoBD::PARAM_CERT_SSL, cert_cliente_edt->text()); + conexao->definirParamConexao(ConexaoBD::PARAM_CHAVE_SSL, chave_cli_edt->text()); + conexao->definirParamConexao(ConexaoBD::PARAM_CRL_SSL, crl_edt->text()); + } + + //Especificando autenticação GSSAPI caso esteja marcada no formulário + if(aut_gssapi_chk->isChecked()) + conexao->definirParamConexao(ConexaoBD::PARAM_LIB_GSSAPI, "gssapi"); + + //Especificando o endereço do servidor Kerberus quando especificado + if(!serv_kerberus_edt->text().isEmpty()) + conexao->definirParamConexao(ConexaoBD::PARAM_SERVIDOR_KERBEROS, serv_kerberus_edt->text()); + + //Atribuindo opções adicionas de conexão + if(!opcoes_edt->text().isEmpty()) + conexao->definirParamConexao(ConexaoBD::PARAM_OPCOES, opcoes_edt->text()); + } +} +//------------------------------------------------------------ +void ConfConexoesWidget::testarConexao(void) +{ + ConexaoBD conexao; + + try + { + //Configura uma conexão com os valores do formulário + this->configurarConexao(&conexao); + + /* Tenta a conexão. Se neste ponto nenhuma exceção for disparada + considera-se que a conexão foi realizada com sucesso */ + conexao.conectar(); + + //Exibe a mensagem de sucesso + caixa_msg->show(trUtf8("Sucesso"), trUtf8("Conexão efetuada com sucesso!"), CaixaMensagem::ICONE_INFO); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfConexoesWidget::restaurarPadroes(void) +{ + try + { + //Restaura as configurações padrão e recarrega o arquivo restaurado + ConfBaseWidget::restaurarPadroes(AtributosGlobais::CONF_CONEXOES); + + //Remove as conexões atuais + while(conexoes_cmb->count() > 0) + this->removerConexao(); + + //Recarrega a configuração de conexões + this->carregarConfiguracao(); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfConexoesWidget::salvarConfiguracao(void) +{ + try + { + int i, qtd; + ConexaoBD *conexao=NULL; + map atribs; + + params_config[AtributosGlobais::CONF_CONEXOES].clear(); + qtd=conexoes_cmb->count(); + + /* Workaround: Quando não existem conexões, para se gravar um arquivo vazio, é necessário + preencher o atributo 'params_config[AtributosGlobais::CONF_CONEXOES][AtributosParsers::CONEXOES]' + espaços */ + if(qtd==0) + params_config[AtributosGlobais::CONF_CONEXOES][AtributosParsers::CONEXOES]=" "; + else + { + /* Quando se tem conexões no combo, os atributos de cada uma são obtidos e é + gerado um esquema com base nestes valores */ + for(i=0; i < qtd; i++) + { + //Obtém uma conexão e seus atributos + conexao=reinterpret_cast(conexoes_cmb->itemData(i).value()); + atribs=conexao->obterParamsConexao(); + + /* Caso na conexão não esteja especificado o host significa que o endereço usado é o IP, + sendo assim, o IP é atribuido ao parâmetro FQDN, desta forma ao gerar o esquema + da conexão, o parser conseguirá identificar o parâmetro 'host' */ + if(atribs.count(ConexaoBD::PARAM_FQDN_SERVIDOR)==0) + atribs[ConexaoBD::PARAM_FQDN_SERVIDOR]=atribs[ConexaoBD::PARAM_IP_SERVIDOR]; + + /* Armazena também nos atributos o alias da conexão pois este precisa ser gravado + no arquivo de configuração */ + atribs[AtributosParsers::ALIAS]=conexoes_cmb->itemText(i); + + /* Ativa o modo de ignorar atributos desconhecidos do parser, pois, alguns + atributos da conexão nem sempre são especificados (opcionais) e isso + geraria muitos erros se o modo citado não estivesse ativado */ + ParserEsquema::ignorarAtributosDesc(true); + + //Gera o esquema da conexão e contatena à demais geradas + params_config[AtributosGlobais::CONF_CONEXOES][AtributosParsers::CONEXOES]+= + ParserEsquema::obterDefinicaoObjeto(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::DIR_ESQUEMAS + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_CONEXOES + + AtributosGlobais::EXT_ESQUEMA, + atribs); + ParserEsquema::ignorarAtributosDesc(false); + } + } + + //Gera o arquivo de configuração completo + ConfBaseWidget::salvarConfiguracao(AtributosGlobais::CONF_CONEXOES); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfConexoesWidget::obterConexoes(map &conexoes) +{ + int i, qtd; + + conexoes.clear(); + qtd=conexoes_cmb->count(); + + for(i=0; i < qtd; i++) + conexoes[conexoes_cmb->itemText(i)]=reinterpret_cast(conexoes_cmb->itemData(i).value()); +} +//*********************************************************** + diff --git a/libpgmodeler_ui/src/confconexoeswidget.h b/libpgmodeler_ui/src/confconexoeswidget.h new file mode 100644 index 000000000..dfe3e6673 --- /dev/null +++ b/libpgmodeler_ui/src/confconexoeswidget.h @@ -0,0 +1,77 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ConfConexoesWidget +# Descrição: Implementa o widget de configurações de conexões com o sgbd. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CONF_CONEXOES_WIDGET_H +#define CONF_CONEXOES_WIDGET_H + +#include "ui_confconexoeswidget.h" +#include "confbasewidget.h" +#include "conexaobd.h" +//*********************************************************** +class ConfConexoesWidget: public QWidget, public Ui::ConfConexoesWidget, public ConfBaseWidget { + private: + Q_OBJECT + + //Configura uma instância de conexão com os valores preenchidos no formulário + void configurarConexao(ConexaoBD *conexao); + + public: + ConfConexoesWidget(QWidget * parent=0); + ~ConfConexoesWidget(void); + + void salvarConfiguracao(void); + void carregarConfiguracao(void); + + //Preenche um mapa com as conexões carregadas no formulário + void obterConexoes(map &conexoes); + + public slots: + void restaurarPadroes(void); + + private slots: + //Limpa o formulário para criação de uma nova conexão + void novaConexao(void); + + //Manipula (cria / atualiza) uma conexão com base nos dados do formulário + void manipularConexao(void); + + //Edita uma conexão selecionada no combo de conexões + void editarConexao(void); + + //Efetua o teste de conexão com base nos dados do formulário + void testarConexao(void); + + //Remove a conexão selecionada no combo + void removerConexao(void); + + //Habilita os campos relacionados com os certificados digitais + void habilitarCertificados(void); + + //Habilita o botão de teste de conexão + void habilitarTesteConexao(void); + + /* Este método não é usado nesta classe pois as modificações são aplicadas diretamente + ao arquivo, operação esta tratada pelo método salvarConfiguracao() */ + void aplicarConfiguracao(void){} +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/confgeralwidget.cpp b/libpgmodeler_ui/src/confgeralwidget.cpp new file mode 100644 index 000000000..84916f305 --- /dev/null +++ b/libpgmodeler_ui/src/confgeralwidget.cpp @@ -0,0 +1,194 @@ +#include "confgeralwidget.h" +//*********************************************************** +ConfGeralWidget::ConfGeralWidget(QWidget * parent) : QWidget(parent) +{ + QPrinter::PaperSize cod_tipo_papel[]={QPrinter::A0, QPrinter::A1, QPrinter::A2, QPrinter::A3, QPrinter::A4, QPrinter::A5, + QPrinter::A6, QPrinter::A7, QPrinter::A8, QPrinter::A9, QPrinter::B0, QPrinter::B1, + QPrinter::B10, QPrinter::B2, QPrinter::B3, QPrinter::B4, QPrinter::B5, QPrinter::B6, + QPrinter::B7, QPrinter::B8, QPrinter::B9, QPrinter::C5E, QPrinter::Comm10E, QPrinter::DLE, + QPrinter::Executive, QPrinter::Folio, QPrinter::Ledger, QPrinter::Legal, QPrinter::Letter, + QPrinter::Tabloid, QPrinter::Custom }; + + Ui_ConfGeralWidget::setupUi(this); + + //Atribui os tipos de papel aos elementos do combo de tipo de papel + for(int i=0; i < 31; i++) + papel_cmb->setItemData(i, QVariant(cod_tipo_papel[i])); + + connect(unidade_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(converterUnidadeMargem(void))); + connect(salvar_mod_chk, SIGNAL(toggled(bool)), salvar_mod_spb, SLOT(setEnabled(bool))); + + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TAM_GRADE]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TAM_LISTA_OP]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::INTERVALO_SALVAR_AUTO]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TIPO_PAPEL_IMP]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::ORIENTACAO_PAPEL]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::MARGEM_PAPEL]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::SALVAR_SESSAO]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::SALVAR_WIDGETS]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::ARQUIVO]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::WIDGET]=""; +} +//----------------------------------------------------------- +void ConfGeralWidget::carregarConfiguracao(void) +{ + QStringList margem; + vector atribs_chave; + unsigned interv; + + //Para a sessão de configuração geral, o 'id' será usado como campo chave + atribs_chave.push_back(AtributosParsers::ID); + + //Carrega as configurações + ConfBaseWidget::carregarConfiguracao(AtributosGlobais::CONF_GERAL, atribs_chave); + + //Repassa os valores obtidos no arquivo de configuração para os widgets do formulário + tam_grade_spb->setValue((params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TAM_GRADE]).toUInt()); + tam_lista_spb->setValue((params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TAM_LISTA_OP]).toUInt()); + + interv=(params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::INTERVALO_SALVAR_AUTO]).toUInt(); + salvar_mod_chk->setChecked(interv > 0); + salvar_mod_spb->setValue(interv); + salvar_mod_spb->setEnabled(salvar_mod_chk->isChecked()); + + salvar_wgts_chk->setChecked(params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::SALVAR_WIDGETS]==AtributosParsers::VERDADEIRO); + salvar_sessao_chk->setChecked(params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::SALVAR_SESSAO]==AtributosParsers::VERDADEIRO); + + papel_cmb->setCurrentIndex((params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TIPO_PAPEL_IMP]).toUInt()); + retrato_rb->setChecked(params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::ORIENTACAO_PAPEL]==AtributosParsers::RETRATO); + paisagem_rb->setChecked(params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::ORIENTACAO_PAPEL]==AtributosParsers::PAISAGEM); + + margem=params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::MARGEM_PAPEL].split(","); + + marg_esq->setValue((margem.count() >= 1 ? margem[0].toFloat() : 10)); + marg_topo->setValue((margem.count()>= 2 ? margem[1].toFloat() : 10)); + marg_dir->setValue((margem.count() >= 3 ? margem[2].toFloat() : 10)); + marg_base->setValue((margem.count() >= 4 ? margem[3].toFloat() : 10)); + + //Efetiva as configurações do formulário aplicando-as às classes interessadas + this->aplicarConfiguracao(); +} +//----------------------------------------------------------- +void ConfGeralWidget::salvarConfiguracao() +{ + try + { + map >::iterator itr, itr_end; + QString sch_widget, sch_arquivo, dir_raiz; + + dir_raiz=AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO; + + sch_widget=dir_raiz + + AtributosGlobais::DIR_ESQUEMAS + + AtributosGlobais::SEP_DIRETORIO + + AtributosParsers::WIDGET + + AtributosGlobais::EXT_ESQUEMA; + + sch_arquivo=dir_raiz + + AtributosGlobais::DIR_ESQUEMAS + + AtributosGlobais::SEP_DIRETORIO + + AtributosParsers::ARQUIVO + + AtributosGlobais::EXT_ESQUEMA; + + //Armazena no mapa de parâmetros de configuração os valores dos widgets no formulário + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TAM_GRADE]=QString("%1").arg(tam_grade_spb->value()); + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TAM_LISTA_OP]=QString("%1").arg(tam_lista_spb->value()); + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::INTERVALO_SALVAR_AUTO]=QString("%1").arg(salvar_mod_chk->isChecked() ? salvar_mod_spb->value() : 0); + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::TIPO_PAPEL_IMP]=QString("%1").arg(papel_cmb->currentIndex()); + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::ORIENTACAO_PAPEL]=(retrato_rb->isChecked() ? AtributosParsers::RETRATO : AtributosParsers::PAISAGEM); + + unidade_cmb->setCurrentIndex(0); + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::MARGEM_PAPEL]=QString("%1,%2,%3,%4").arg(marg_esq->value()) + .arg(marg_topo->value()) + .arg(marg_dir->value()) + .arg(marg_base->value()); + + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::SALVAR_SESSAO]=(salvar_sessao_chk->isChecked() ? "1" : ""); + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::SALVAR_WIDGETS]=(salvar_wgts_chk->isChecked() ? "1" : ""); + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::ARQUIVO]=""; + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::WIDGET]=""; + + itr=params_config.begin(); + itr_end=params_config.end(); + + //Salvando as configurações da sessão e dos widgets + while(itr!=itr_end) + { + if(salvar_sessao_chk->isChecked() && + (itr->first).contains(QRegExp(QString("(") + + AtributosParsers::ARQUIVO + + QString(")([0-9]+)")))) + { + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::ARQUIVO]+= + ParserEsquema::obterDefinicaoObjeto(sch_arquivo, itr->second); + } + else if(salvar_wgts_chk->isChecked() && + (itr->first).contains(QRegExp(QString("(") + + AtributosParsers::WIDGET + + QString(")([0-9]+)")))) + { + params_config[AtributosParsers::CONFIGURACAO][AtributosParsers::WIDGET]+= + ParserEsquema::obterDefinicaoObjeto(sch_widget, itr->second); + } + + itr++; + } + + //Salva a configuração em arquivo + ConfBaseWidget::salvarConfiguracao(AtributosGlobais::CONF_GERAL); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfGeralWidget::aplicarConfiguracao(void) +{ + //Aplica as configurações de papel à cena + CenaObjetos::definirConfiguracaoPagina(static_cast(papel_cmb->itemData(papel_cmb->currentIndex()).toInt()), + (retrato_rb->isChecked() ? QPrinter::Portrait : QPrinter::Landscape), + QRectF(marg_esq->value(), marg_topo->value(), + marg_dir->value(), marg_base->value())); + + //Aplica a configuração de grade à cena + CenaObjetos::definirGrade(tam_grade_spb->value()); + + //Aplica as configurações à lista de operações + ListaOperacoes::definirTamanhoMaximo(tam_lista_spb->value()); +} +//----------------------------------------------------------- +void ConfGeralWidget::restaurarPadroes(void) +{ + try + { + //Restaura as configurações padrão e recarrega o arquivo restaurado + ConfBaseWidget::restaurarPadroes(AtributosGlobais::CONF_GERAL); + this->carregarConfiguracao(); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ConfGeralWidget::converterUnidadeMargem(void) +{ + static int unidade_ant=0; + float fator_conv[]={1.0f, 2.83f, 0.04f, 0.1f}, + esq, dir, topo, base; + + esq=marg_esq->value() / fator_conv[unidade_ant]; + dir=marg_dir->value() / fator_conv[unidade_ant]; + base=marg_base->value() / fator_conv[unidade_ant]; + topo=marg_topo->value() / fator_conv[unidade_ant]; + + marg_esq->setValue(esq * fator_conv[unidade_cmb->currentIndex()]); + marg_dir->setValue(dir * fator_conv[unidade_cmb->currentIndex()]); + marg_base->setValue(base * fator_conv[unidade_cmb->currentIndex()]); + marg_topo->setValue(topo * fator_conv[unidade_cmb->currentIndex()]); + + unidade_ant=unidade_cmb->currentIndex(); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/confgeralwidget.h b/libpgmodeler_ui/src/confgeralwidget.h new file mode 100644 index 000000000..3cf3cbe58 --- /dev/null +++ b/libpgmodeler_ui/src/confgeralwidget.h @@ -0,0 +1,50 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ConfGeralWidget +# Descrição: Implementa o widget de configurações gerais do modelo. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CONF_GERAL_WIDGET_H +#define CONF_GERAL_WIDGET_H + +#include "ui_confgeralwidget.h" +#include "confbasewidget.h" +#include "cenaobjetos.h" +#include "listaoperacoes.h" +//*********************************************************** +class ConfGeralWidget: public QWidget, public Ui::ConfGeralWidget, public ConfBaseWidget { + private: + Q_OBJECT + + public: + ConfGeralWidget(QWidget * parent=0); + + void salvarConfiguracao(void); + void carregarConfiguracao(void); + + public slots: + void aplicarConfiguracao(void); + void restaurarPadroes(void); + + private slots: + //Faz a conversão dos valores das margens para a unidade selecionada + void converterUnidadeMargem(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/conversaocodificacaowidget.cpp b/libpgmodeler_ui/src/conversaocodificacaowidget.cpp new file mode 100644 index 000000000..3118b1e3e --- /dev/null +++ b/libpgmodeler_ui/src/conversaocodificacaowidget.cpp @@ -0,0 +1,98 @@ +#include "conversaocodificacaowidget.h" +//*********************************************************** +ConversaoCodificacaoWidget::ConversaoCodificacaoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_CONV_CODIFICACAO) +{ + try + { + QFrame *frame=NULL; + QStringList codificacoes; + + Ui_ConversaoCodificacaoWidget::setupUi(this); + + //Alocando o widget seletor de função de conversão + sel_funcao_conv=NULL; + sel_funcao_conv=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + convcod_grid->addWidget(sel_funcao_conv,1,1,1,3); + + configurarLayouFormulario(convcod_grid, OBJETO_CONV_CODIFICACAO); + + //Gera o frame de informação sobre a função de conversão + frame=gerarFrameInformacao(trUtf8("A função a ser atribuída a uma conversão de codificação deve possuir a seguinte assinatura:\ + void funcao(integer, integer, cstring, internal, integer).")); + convcod_grid->addWidget(frame, convcod_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + + //Obtém os nomes das codificações e as insere no combo de codificação + TipoCodificacao::obterTipos(codificacoes); + cod_orig_cmb->addItems(codificacoes); + cod_dest_cmb->addItems(codificacoes); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->setMinimumSize(600, 370); + janela_pai->setMaximumHeight(370); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ConversaoCodificacaoWidget::hideEvent(QHideEvent *evento) +{ + sel_funcao_conv->removerObjetoSelecionado(); + conv_padrao_chk->setChecked(false); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//--------------------------------------------------------- +void ConversaoCodificacaoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, ConversaoCodificacao *conv_cod) +{ + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, conv_cod); + sel_funcao_conv->definirModelo(modelo); + + if(conv_cod) + { + sel_funcao_conv->definirObjeto(conv_cod->obterFuncaoConversao()); + conv_cod->definirPadrao(conv_padrao_chk->isChecked()); + cod_orig_cmb->setCurrentIndex(cod_dest_cmb->findText(~(conv_cod->obterCodificacao(ConversaoCodificacao::CONV_COD_ORIGEM)))); + cod_dest_cmb->setCurrentIndex(cod_dest_cmb->findText(~(conv_cod->obterCodificacao(ConversaoCodificacao::CONV_COD_DESTINO)))); + } +} +//---------------------------------------------------------- +void ConversaoCodificacaoWidget::aplicarConfiguracao(void) +{ + try + { + ConversaoCodificacao *conv_cod=NULL; + + iniciarConfiguracao(); + conv_cod=dynamic_cast(this->objeto); + + //Aplica as configurações básicas + ObjetoBaseWidget::aplicarConfiguracao(); + + //Configurando a conversão com os atributos especificados no formulário + conv_cod->definirCodificacao(ConversaoCodificacao::CONV_COD_ORIGEM, cod_orig_cmb->currentText()); + conv_cod->definirCodificacao(ConversaoCodificacao::CONV_COD_DESTINO, cod_dest_cmb->currentText()); + conv_cod->definirPadrao(conv_padrao_chk->isChecked()); + + //Atribui a função de conversão com aquela que está selecionada no seletor de função + conv_cod->definirFuncaoConversao(dynamic_cast(sel_funcao_conv->obterObjeto())); + + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/conversaocodificacaowidget.h b/libpgmodeler_ui/src/conversaocodificacaowidget.h new file mode 100644 index 000000000..9570b8d23 --- /dev/null +++ b/libpgmodeler_ui/src/conversaocodificacaowidget.h @@ -0,0 +1,48 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ConversaoCodificacaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de conversão de codificação. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CONVERSAOCODIFICACAO_WIDGET_H +#define CONVERSAOCODIFICACAO_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_conversaocodificacaowidget.h" +//*********************************************************** +class ConversaoCodificacaoWidget: public ObjetoBaseWidget, public Ui::ConversaoCodificacaoWidget { + Q_OBJECT + + private: + //Widget seletor da função de conversão + SeletorObjetoWidget *sel_funcao_conv; + + public: + ConversaoCodificacaoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, ConversaoCodificacao *conv_cod); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/conversaotipowidget.cpp b/libpgmodeler_ui/src/conversaotipowidget.cpp new file mode 100644 index 000000000..889485dda --- /dev/null +++ b/libpgmodeler_ui/src/conversaotipowidget.cpp @@ -0,0 +1,138 @@ +#include "conversaotipowidget.h" +//*********************************************************** +ConversaoTipoWidget::ConversaoTipoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_CONV_TIPO) +{ + try + { + QFont fonte; + QFrame *frame=NULL; + + Ui_ConversaoTipoWidget::setupUi(this); + + //Alocando os widgets de seleção de tipos envolvidos na conversão + tipo_dado_orig=NULL; + tipo_dado_dest=NULL; + sel_funcao_conv=NULL; + + tipo_dado_orig=new TipoPgSQLWidget(this, tr("Tipo de Dado de Origem")); + tipo_dado_dest=new TipoPgSQLWidget(this, tr("Tipo de Dado de Destino")); + //Alocando o widget seletor de função de conversão + sel_funcao_conv=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + + //Insere os widgets alocados no layout do formulário + convtipo_grid->addWidget(sel_funcao_conv,1,1,1,3); + convtipo_grid->addWidget(tipo_dado_orig,2,0,1,4); + convtipo_grid->addWidget(tipo_dado_dest,3,0,1,4); + + configurarLayouFormulario(convtipo_grid, OBJETO_CONV_TIPO); + + /* Deixa como somente-leitura o campo de nome do objeto pois, + o nome de conversões de tipo são geradas automaticamente */ + nome_edt->setReadOnly(true); + fonte=nome_edt->font(); + fonte.setItalic(true); + nome_edt->setFont(fonte); + + //Gera o frame de informação + frame=gerarFrameInformacao(trUtf8("A função a ser atribuída a uma conversão do tipoA para o tipoB\ + deve possuir a seguinte assinatura: tipoB funcao(tipoA, integer, boolean).")); + convtipo_grid->addWidget(frame, convtipo_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->setMinimumSize(530, 500); + janela_pai->setMaximumSize(16777215, 500); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ConversaoTipoWidget::hideEvent(QHideEvent *evento) +{ + entradasaida_chk->setChecked(false); + implicita_rb->setChecked(true); + sel_funcao_conv->removerObjetoSelecionado(); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//--------------------------------------------------------- +void ConversaoTipoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, ConversaoTipo *conv_tipo) +{ + TipoPgSQL tipo_orig, tipo_dest; + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, conv_tipo); + sel_funcao_conv->definirModelo(modelo); + + //Caso a conversão de tipo esteja alocada + if(conv_tipo) + { + //Obtém os tipos envolvidos na conversão + tipo_orig=conv_tipo->obterTipoDado(ConversaoTipo::CONV_TIPO_ORIGEM); + tipo_dest=conv_tipo->obterTipoDado(ConversaoTipo::CONV_TIPO_DESTINO); + + //Atribui a função da conversão ao widget seletor + sel_funcao_conv->definirObjeto(conv_tipo->obterFuncaoConversao()); + + /* Marca o se a conversão é de entrada/saida de acordo com o que está configurado + na instância passada */ + entradasaida_chk->setChecked(conv_tipo->obterEntradaSaida()); + + /* Configura o tipo da conversão de acordo com o que está configurado + na instância passada */ + implicita_rb->setChecked(conv_tipo->obterTipoConversao()==ConversaoTipo::CONV_IMPLICITA); + atribuicao_rb->setChecked(!implicita_rb->isChecked()); + } + + //Atribui os tipos aos widgets de configuração de tipo de dados da conversão + tipo_dado_orig->definirAtributos(tipo_orig,modelo); + tipo_dado_dest->definirAtributos(tipo_dest,modelo); +} +//---------------------------------------------------------- +void ConversaoTipoWidget::aplicarConfiguracao(void) +{ + try + { + ConversaoTipo *conv_tipo=NULL; + + iniciarConfiguracao(); + + //Obtém a conversão a partir da refência ao objeto configurado + conv_tipo=dynamic_cast(this->objeto); + + //Configura os tipos de dados da conversão obtendo-os dos widgets de configuração de tipos + conv_tipo->definirTipoDado(ConversaoTipo::CONV_TIPO_ORIGEM, tipo_dado_orig->obterTipoPgSQL()); + conv_tipo->definirTipoDado(ConversaoTipo::CONV_TIPO_DESTINO, tipo_dado_dest->obterTipoPgSQL()); + + /* Configura se a conversão é de entrada/saída conforme o estado do + checkbox que representa o atributo no formulário */ + conv_tipo->definirEntradaSaida(entradasaida_chk->isChecked()); + + //Configura o tipo da conversão conforme o radiobox selecionado no formulário + if(implicita_rb->isChecked()) + conv_tipo->definirTipoConversao(ConversaoTipo::CONV_IMPLICITA); + else + conv_tipo->definirTipoConversao(ConversaoTipo::CONV_ATRIBUICAO); + + //Atribui a função de conversão com aquela que está selecionada no seletor de função + conv_tipo->definirFuncaoConversao(dynamic_cast(sel_funcao_conv->obterObjeto())); + + //Aplica as configurações básicas + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/conversaotipowidget.h b/libpgmodeler_ui/src/conversaotipowidget.h new file mode 100644 index 000000000..72f1f1de2 --- /dev/null +++ b/libpgmodeler_ui/src/conversaotipowidget.h @@ -0,0 +1,53 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ConversaoTipoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de conversão de tipos. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef CONVERSAOTIPO_WIDGET_H +#define CONVERSAOTIPO_WIDGET_H + +#include "objetobasewidget.h" +#include "tipopgsqlwidget.h" +#include "ui_conversaotipowidget.h" +//*********************************************************** +class ConversaoTipoWidget: public ObjetoBaseWidget, public Ui::ConversaoTipoWidget { + Q_OBJECT + + private: + /* Widgets de configuração dos tipos de dados (origem / destino) + da conversão */ + TipoPgSQLWidget *tipo_dado_orig, *tipo_dado_dest; + + //Widget seletor da função de conversão + SeletorObjetoWidget *sel_funcao_conv; + + public: + ConversaoTipoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, ConversaoTipo *conv_tipo); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/destaquesintaxe.cpp b/libpgmodeler_ui/src/destaquesintaxe.cpp new file mode 100644 index 000000000..38290ac30 --- /dev/null +++ b/libpgmodeler_ui/src/destaquesintaxe.cpp @@ -0,0 +1,797 @@ +#include "destaquesintaxe.h" +//*********************************************************** +DestaqueSintaxe::DestaqueSintaxe(QTextDocument *parent, bool auto_redestaque) : QSyntaxHighlighter(parent) +{ + this->auto_redestaque=auto_redestaque; + configurarAtributos(); +} +//----------------------------------------------------------- +DestaqueSintaxe::DestaqueSintaxe(QTextEdit *parent, bool auto_redestaque) : QSyntaxHighlighter(parent) +{ + this->auto_redestaque=auto_redestaque; + configurarAtributos(); +} +//----------------------------------------------------------- +void DestaqueSintaxe::configurarAtributos(void) +{ + conf_carregada=false; + bloco_atual=-1; + qtd_info_bloco_atual=0; + + if(auto_redestaque) + { + connect(document(), SIGNAL(blockCountChanged(int)), this, SLOT(rehighlight(void))); + connect(document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(validarModificacaoTexto(int,int,int))); + } +} +//----------------------------------------------------------- +void DestaqueSintaxe::validarModificacaoTexto(int, int rem, int ins) +{ + unsigned qtd; + + //Obtém a quantidade de informações de multilinha do bloco atual + qtd=obterNumInfoMultiLinha(bloco_atual); + + /* Caso a quantidade obtida seja diferente da quantidade capturada + antes da entrada do texto pelo usuário, ou se não exista nenhuma + informação de multilinha para o bloco atual porém foram inseridos + ou removidos alguns caracteres, o documento passará por um redestaque + completo pois os caracteres removidos ou inseridos podem interferir + na forma de apresentação do destaque e por isso o documento como + um todo precisa ser redestacado */ + if(qtd!=qtd_info_bloco_atual || + (/*qtd==0 && qtd_info_bloco_atual==qtd &&*/ (ins > 0 || rem > 0))) + rehighlight(); +} +//----------------------------------------------------------- +DestaqueSintaxe::InfoMultiLinha *DestaqueSintaxe::obterInfoMultiLinha(int col_ini, int col_fim, int bloco) +{ + unsigned i, qtd; + bool enc=false; + InfoMultiLinha *info=NULL; + + /* Varre o vetor de informações de multilinha a fim de verificar se + os parâmetros passados estão dentro de um bloco (informação) multilinha */ + qtd=info_multi_linha.size(); + for(i=0; i < qtd; i++) + { + //Obtém uma informação + info=info_multi_linha[i]; + + /* Primeiramente é preciso verificar se o bloco passado está dentro dos limites + estabelecidos pelos blocos inicial e final da informação de multilinha. + É importante salientar que quando um bloco multilinha está em aberto, por exemplo, + o usuário abriu um multilinha com '/ *' e não fechou com '* /' os atributos + bloco_fim e col_fim da informação de multilinha possuirão o valor -1 até + que o usuário feche o multilinha e o destacador identifique em que parte + do texto se encontra esse fechamento */ + if(bloco >= info->bloco_ini && (info->bloco_fim < 0 || bloco <= info->bloco_fim)) + { + /* A seguir várias condições são testadas a fim de verificar se os parâmetros + passados estão dentro de um bloco multilinha.*/ + + /* Condição 1: O bloco passado é o mesmo da informação atual e a informação + atual trata de um multilinha porém aberto e fechado na mesma linha + de texto (info->bloco_ini==info->bloco_fim), será verificado + se o parâmetro col_ini e col_fim estão nos limites estabelecidos + pelas colunas inicial e final do informação */ + if(bloco==info->bloco_ini && info->bloco_ini==info->bloco_fim) + enc=(col_ini >= info->col_ini && col_fim <= info->col_fim); + + /* Condição 2: O bloco passado é o mesmo da informação atual e a informação + atual trata de um multilinha em aberto. Testa apenas se + a coluna inicial do parâmetro está após da coluna inicial da + informação. Isso indica que o texto digitado está após a + abertura do multilinha e consequentemente dentro do mesmo */ + else if(bloco == info->bloco_ini) + enc=(col_ini >= info->col_ini); + + /* Condição 3: O bloco passado é o mesmo do bloco final da informação atual + e a informação atual trata de um multilinha fechado. Testa + apenas se a coluna final do parâmetro está antes da coluna + final da informação multilinha atual indicando que o texto + inserido está dentro do bloco multilinha */ + else if(info->bloco_fim >=0 && bloco == info->bloco_fim) + enc=(col_fim <= info->col_fim); + + /* Condição 4: A informação atual trata de um multilinha em aberto. Testa + apenas se o bloco passado está no mesmo bloco inicial da informação + ou após sem a necessidade de se testar as colunas e o bloco final. + Isso é feito pois se o texto é inserido no meio do multilinha + após o bloco de abertura, e como o bloco está em aberto, todo texto + inserido após o bloco de aberto será considerado um multibloco */ + else if(info->bloco_fim < 0) + enc=(bloco >= info->bloco_ini); + + /* Condição 5: A informação atual trata de um multilinha fechado. Testa + apenas se o bloco passado está no meio do intervalo estabelecido + pelos blocos inicial e final da informação. Isso é feito + pois se o texto é inserido no meio do multilinha após o bloco de + abertura e antes do fechamento a linha do texto como um todo + é considerada um multibloco */ + else if(info->bloco_fim >=0 && info->bloco_ini!=info->bloco_fim) + enc=(bloco >= info->bloco_ini && bloco <= info->bloco_fim); + } + } + + if(enc) + return(info); + else + return(NULL); +} +//----------------------------------------------------------- +void DestaqueSintaxe::removerInfoMultiLinha(int bloco) +{ + vector::iterator itr, itr_end; + + itr=info_multi_linha.begin(); + itr_end=info_multi_linha.end(); + + //Varre a lista de informações de multilinha + while(itr!=itr_end) + { + //Caso a info atual tenha como bloco inicial o mesmo bloco passado + if((*itr)->bloco_ini==bloco) + { + //Remove a informação da memória + delete(*itr); + //Remove o elemento da lista e reinicia a varredura + info_multi_linha.erase(itr); + itr=info_multi_linha.begin(); + itr_end=info_multi_linha.end(); + } + else + itr++; + } +} +//----------------------------------------------------------- +unsigned DestaqueSintaxe::obterNumInfoMultiLinha(int bloco) +{ + vector::iterator itr, itr_end; + unsigned qtd=0; + + itr=info_multi_linha.begin(); + itr_end=info_multi_linha.end(); + + /* Varre a lista de informação de multilinha e contabiliza + aquelas as quais tem como bloco inicial o bloco passado */ + while(itr!=itr_end) + { + if((*itr)->bloco_ini==bloco) qtd++; + itr++; + } + + return(qtd); +} +//----------------------------------------------------------- +QString DestaqueSintaxe::identificarGrupoPalavra(const QString &palavra, const QChar &chr_lookup, int idx, int &idx_comb, int &comp_combinacao) +{ + QRegExp expr; + vector::iterator itr, itr_end; + vector::iterator itr_exp, itr_exp_end; + vector *vet_expr=NULL; + QString grupo; + bool combina=false, comb_parcial=false; + InfoMultiLinha *info=NULL; + + //Tenta obter uma informação de multilinha do bloco atual + info=obterInfoMultiLinha(idx, idx, bloco_atual); + + /* Caso o destacador estiver no meio do destaque de um bloco + multi linha, é executado um procedimento diferente que + é verificar se a palavra em questão não combina com uma + das expressões finais do grupo indicando que o detaque + do grupo deve ser interrompido após a palavra em questão */ + if(info) + { + grupo=info->grupo; + + /* Varre as expresões finais exclusivamente do grupo atual + para verificar se a palavra em questão naõ é a de finalização + do destaque do grupo */ + itr_exp=exp_finais[grupo].begin(); + itr_exp_end=exp_finais[grupo].end(); + comb_parcial=combinacao_parcial[grupo]; + + while(itr_exp!=itr_exp_end && !combina) + { + //Obtém a expressão do iterador atual + expr=(*itr_exp); + + //Caso a expressão esteja configurara para combinação parcial + if(comb_parcial) + { + //Obtém o índice inicial na palavra onde a expressão combina + idx_comb=palavra.indexOf(expr); + //Obtém o comprimento da combinação + comp_combinacao=expr.matchedLength(); + /* Para se saber se a expressão combinou parcialmente com a palavra + verifica se o indice da combinação é igual ou superior a zero */ + combina=(idx_comb >= 0); + } + else + { + /* Caso a expressão esteja com o tipo de padrão configurado como + como FixedString indica que a mesmo não precisa ser tratada como + uma expressão regular e sim como uma string comum, sendo assim + a comparação feita é de string com string o que acaba se tornando + mais rápido */ + if(expr.patternSyntax()==QRegExp::FixedString) + combina=((expr.pattern().compare(palavra, expr.caseSensitivity())==0)); + else + //Combina a expressão regular com a palavra + combina=expr.exactMatch(palavra); + + if(combina) + { + idx_comb=0; + comp_combinacao=palavra.length(); + } + } + + if(combina && caractere_lookup.count(grupo) > 0 && chr_lookup!=caractere_lookup.at(grupo)) + combina=false; + + itr_exp++; + } + + /* Caso a palavra combina com uma das expressões finais do grupo + marca a informação multilinha obtida e configura a coluna final + e bloco final da informção de bloco multilinha. */ + if(combina) + { + info->col_fim=idx + idx_comb + comp_combinacao-1; + info->bloco_fim=bloco_atual; + } + /* Caso o destacador permaneça num bloco de multilinha o índice + de combinação e o comprimento da combinação serão, respectivamente, + zero e o comprimento da palavra para forçar o destaque da palavra + atual no grupo de multi linha atual indicando que o destacador ainda + se encontra no bloco deste tipo */ + else + { + idx_comb=0; + comp_combinacao=palavra.length(); + } + + return(grupo); + } + else + { + /* Obtém os iteradores do vetor de ordem de grupos + para que as expressões dos mesmos sejam aplicadas + à palavra em questão com o intuito de verificar se + a mesma faz parte do grupo */ + itr=ordem_grupos.begin(); + itr_end=ordem_grupos.end(); + + while(itr!=itr_end && !combina) + { + //Obtém o grupo a partir do iterador + grupo=(*itr); + //Obtém o vetor de expressões iniciais do grupo + vet_expr=&exp_iniciais[grupo]; + itr++; + + //Varre a lista de expressões comparando com a palavra atual + itr_exp=vet_expr->begin(); + itr_exp_end=vet_expr->end(); + comb_parcial=combinacao_parcial[grupo]; + + while(itr_exp!=itr_exp_end && !combina) + { + //Obtém a expressão a partir do iterador atual + expr=(*itr_exp); + + //Caso a expressão esteja configurara para combinação parcial + if(comb_parcial) + { + //Obtém o índice inicial na palavra onde a expressão combina + idx_comb=palavra.indexOf(expr); + //Obtém o comprimento da combinação + comp_combinacao=expr.matchedLength(); + /* Para se saber se a expressão combinou parcialmente com a palavra + verifica se o indice da combinação é igual ou superior a zero */ + combina=(idx_comb >= 0); + } + else + { + /* Caso a expressão esteja com o tipo de padrão configurado como + como FixedString indica que a mesmo não precisa ser tratada como + uma expressão regular e sim como uma string comum, sendo assim + a comparação feita é de string com string o que acaba se tornando + mais rápido */ + if(expr.patternSyntax()==QRegExp::FixedString) + combina=((expr.pattern().compare(palavra, expr.caseSensitivity())==0)); + else + //Combina a expressão regular com a palavra + combina=expr.exactMatch(palavra); + + if(combina) + { + idx_comb=0; + comp_combinacao=palavra.length(); + } + } + + if(combina && caractere_lookup.count(grupo) > 0 && chr_lookup!=caractere_lookup.at(grupo)) + combina=false; + + itr_exp++; + } + + /* Caso a palavra combine com uma das expressões do grupo + verifica se o mesmo possui expressões finais o que indica + que o grupo se trata de elementos de multi linha, ou seja, + que o destaque do grupo se extende além da linha atual até + um delimitador final do grupo ser encontrado. Desta + forma aloca uma informção de multilinha com configurações iniciais */ + if(combina && exp_finais.count(grupo)) + { + if(!info) + { + info=new InfoMultiLinha; + info->grupo=grupo; + info->col_ini=idx + idx_comb + comp_combinacao; + info->bloco_ini=bloco_atual; + info_multi_linha.push_back(info); + } + } + } + + /* Caso a palavra não combine com nenhuma expressão de nenhum + grupo força o método a retornar um nome de grupo vazio + indicando que a palavra não combina com grupo algum */ + if(!combina) grupo=""; + + return(grupo); + } +} +//----------------------------------------------------------- +void DestaqueSintaxe::rehighlight(void) +{ + InfoMultiLinha *info=NULL; + + /* Remove todas as informações de multilinha + pois durante o redestaque as mesmas são obtidas + novamente */ + while(!info_multi_linha.empty()) + { + info=info_multi_linha.back(); + info_multi_linha.pop_back(); + delete(info); + } + + QSyntaxHighlighter::rehighlight(); +} +//----------------------------------------------------------- +void DestaqueSintaxe::highlightBlock(const QString &txt) +{ + /* Caso a linha esteja vazia ou consita apenas de uma + linha em branco não executa o destacamento para não + gerar processamento desnecessário. */ + bloco_atual=currentBlock().blockNumber(); + + if(!txt.isEmpty()) + { + QString palavra, grupo, texto; + unsigned i=0, tam, idx=0, i1; + int idx_comb, comp_comb, tam_aux, col_ini; + QChar chr_delim, chr_lookup; + + //Obtém o tamanho total do bloco de texto + texto=txt + '\n'; + tam=texto.length(); + + /* Remove as informações de multilinha do bloco atual + para forçar a identifição de novas informações + de multilinha no bloco atual */ + removerInfoMultiLinha(bloco_atual); + + do + { + /* Remove os caracteres que constam na lista de caracteres + ignorandos enquanto estes aparecerem no texto */ + while(i < tam && chr_ignorados.indexOf(texto[i])>=0) i++; + + //Caso o fim do texto não tenha sido alcançado + if(i < tam) + { + /* Armazena a posição atual no texto pois é a partir dela que será + feito o destaque da palavra extraída nas iterações abaixo */ + idx=i; + + //Caso o caractere atual seja um caractere separador de palavras + if(sep_palavras.indexOf(texto[i])>=0) + { + /* Enquanto o caractere for um separado, o mesmo é concatenada junto + com os demais separadores */ + while(i < tam && sep_palavras.indexOf(texto[i])>=0) + palavra+=texto[i++]; + } + //Caso o caractere atual seja um delimitador de palavras + else if(delim_palavras.indexOf(texto[i])>=0) + { + //Armazena o caractere delimitador + chr_delim=texto[i++]; + //Adiciona-o na palavra que está sendo extraída + palavra+=chr_delim; + + /* Extrai todos os próximos caracteres concatenando-os à palavra, + idenpendente da categoria destes, enquanto o caractere final + delimitador de palavra não seja encontrado ou o fim do texto + seja alcançado. */ + while(i < tam && chr_delim!=texto[i]) + palavra+=texto[i++]; + + /* Caso o caractere delimitador final for encontrado concatena-o à palavra + formando a palavra delimitada como um todo */ + if(i < tam && texto[i]==chr_delim) + { + palavra+=chr_delim; + i++; + } + } + /* Caso o caractere atual não se encaixe em nenhuma das categorias + acima, será a executada a iteração padrão, que é extrair + o caractere até alcançar um separadaor ou delimitador de palavra + ou um caractere a ser ignorado */ + else + { + while(i < tam && + sep_palavras.indexOf(texto[i]) < 0 && + delim_palavras.indexOf(texto[i]) < 0 && + chr_ignorados.indexOf(texto[i]) < 0) + { + palavra+=texto[i++]; + } + } + } + + /* Caso a palavra não esteja vazia, tenta localizar o grupo + ao qual ela pertence */ + if(!palavra.isEmpty()) + { + i1=i; + while(i1 < tam && chr_ignorados.indexOf(texto[i1])>=0) i1++; + + if(i1 < tam) + chr_lookup=texto[i1]; + else + chr_lookup='\0'; + + //Obtém o grupo ao qual a palavra faz parte + idx_comb=-1; + comp_comb=0; + grupo=identificarGrupoPalavra(palavra,chr_lookup, idx, idx_comb, comp_comb); + + /* Caso o grupo foi identificado faz o destaque da palavra + usando a posição inicial da palavra com o comprimento + da mesma */ + if(!grupo.isEmpty()) + { + col_ini=idx + idx_comb; + setFormat(col_ini, comp_comb, formatacoes[grupo]); + } + + tam_aux=(idx_comb + comp_comb); + if(idx_comb >=0 && tam_aux != palavra.length()) + i-=palavra.length() - tam_aux; + + //Limpa a palavra atual para obter uma nova + palavra=""; + } + } + while(i < tam); + + /* Armazena a quantidade de informação de multilinhas no bloco atual, + pois este atributo é usado para se saber se o documento passará + por um redestaque ou não */ + qtd_info_bloco_atual=obterNumInfoMultiLinha(bloco_atual); + } +} +//----------------------------------------------------------- +bool DestaqueSintaxe::configuracaoCarregada(void) +{ + return(conf_carregada); +} +//----------------------------------------------------------- +void DestaqueSintaxe::limparConfiguracao(void) +{ + exp_iniciais.clear(); + exp_finais.clear(); + formatacoes.clear(); + combinacao_parcial.clear(); + ordem_grupos.clear(); + grupos_sep_palavras.clear(); + sep_palavras.clear(); + delim_palavras.clear(); + chr_ignorados.clear(); + caractere_lookup.clear(); + + configurarAtributos(); +} +//----------------------------------------------------------- +void DestaqueSintaxe::carregarConfiguracao(const QString &nome_arq) +{ + if(nome_arq!="") + { + map atributos; + QString elem, tipo_exp, grupo; + bool decl_grupos=false, sensivel_chr=false, + negrito=false, italico=false, + sublinhado=false, comb_parcial=false; + QTextCharFormat formatacao; + QRegExp exp_regular; + QColor cor_fundo, cor_fonte; + vector::iterator itr, itr_end; + + try + { + /* Caso o usuário tente carregar uma nova configuração na mesma instância, + as configurações anteriores são descartadas */ + limparConfiguracao(); + + //Reinicia o parser XML para a leitura do arquivo + ParserXML::reiniciarParser(); + + /* Montando o caminho padrão para localização do arquivo DTD que define a sintaxe + do arquivo xml de destaque de código fonte. */ + ParserXML::definirArquivoDTD(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::DIR_DTD_OBJETO + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_CODIGO + + AtributosGlobais::EXT_DTD_OBJETO, + AtributosGlobais::CONF_DESTAQUE_CODIGO); + + //Carrega o arquivo validando-o de acordo com a DTD informada + ParserXML::carregarArquivoXML(nome_arq); + + //Acessa o elemento inicial do arquivo de destaque de código fonte + if(ParserXML::acessarElemento(ParserXML::ELEMENTO_FILHO)) + { + do + { + if(ParserXML::obterTipoElemento()==XML_ELEMENT_NODE) + { + //Obtém o elemento atual + elem=ParserXML::obterNomeElemento(); + + //Obtém os separadores de palavras da linguagem + if(elem==AtributosParsers::SEP_PALAVRAS) + { + //Obtém os atributos do mesmo + ParserXML::obterAtributosElemento(atributos); + sep_palavras=atributos[AtributosParsers::VALOR]; + } + + //Obtém os delimitadores de palavras da linguagem + else if(elem==AtributosParsers::DELIM_PALAVRAS) + { + //Obtém os atributos do mesmo + ParserXML::obterAtributosElemento(atributos); + delim_palavras=atributos[AtributosParsers::VALOR]; + } + else if(elem==AtributosParsers::CARACTERES_IGNORADOS) + { + //Obtém os atributos do mesmo + ParserXML::obterAtributosElemento(atributos); + chr_ignorados=atributos[AtributosParsers::VALOR]; + } + + /* Caso o elemento seja o que define a ordem de aplicação dos grupos + de destaque (highlight-order). É neste bloco que são declarados + os grupos usados para destacar o código-fonte. TODOS os grupos + precisam ser declarados neste bloco antes de serem construídos + caso contrário será disparado um erro. */ + else if(elem==AtributosParsers::ORDEM_DESTAQUE) + { + //Marca a flag indicando que os grupos estão sendo declarados + decl_grupos=true; + //Salva a posição atual do parser xml + ParserXML::salvarPosicao(); + /* Acesso o primeiro elemento filho da tag de ordem de destaque que + no caso é uma tag de declaração de grupo */ + ParserXML::acessarElemento(ParserXML::ELEMENTO_FILHO); + //Obtém o nome do elemento, no caso + elem=ParserXML::obterNomeElemento(); + } + + //Caso o elemento atual seja de construção de um grupo '' + if(elem==AtributosParsers::GRUPO) + { + //Obtém os atributos do mesmo + ParserXML::obterAtributosElemento(atributos); + //Armazena seu nome em uma variável auxiliar + grupo=atributos[AtributosParsers::NOME]; + + /* Caso o parser estiver no bloco de declaração de grupos e não no bloco + de construção dos mesmos, algumas validações serão executadas. */ + if(decl_grupos) + { + /* 1ª Validação: Verifica se o grupo já não foi declarando anteriormente, + para isso o mesmo é buscado na lista que armazena a ordem + de aplicação dos grupos (ordem_grupos). Caso o mesmo seja + encontrado um erro é disparado. Um grupo é dito como localizado + na lista quando a chamada a função find() retorna o iterador + diferente do iterador final da lista 'ordem_grupos.end()' */ + if(find(ordem_grupos.begin(), ordem_grupos.end(), grupo)!=ordem_grupos.end()) + { + //Dispara o erro indicado que o grupo está sendo redeclarado + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_REDECLGRUPODESTAQUE).arg(grupo), + ERR_PGMODELERUI_REDECLGRUPODESTAQUE,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + /* 2ª Validação: Verifica se o grupo está sendo declarado e construído ao mesmo tempo no + bloco de declaração. Um grupo no bloco de declaração deve aparecer no + formato , qualquer construção diferente da apresentada + seja com mais atributos ou elementos filhos é considerado que o grupo está + sendo construído em local inválido */ + else if(atributos.size() > 1 || ParserXML::possuiElemento(ParserXML::ELEMENTO_FILHO)) + { + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_DEFGRUPOLOCALINV) + .arg(grupo).arg(AtributosParsers::ORDEM_DESTAQUE), + ERR_PGMODELERUI_REDECLGRUPODESTAQUE,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + + /* Caso nenhum erro for disparado o grupo é adicionado à lista de + ordem de aplicação dos grupos */ + ordem_grupos.push_back(grupo); + } + /* Caso o parser estiver no bloco de construção de grupos e não no bloco + de declaração dos mesmos, algumas validações iniciais serão executadas. */ + else + { + /* 1ª Validação: Verifica se o grupo está sendo construído pela segunda vez. + Para tal, verifica se o mapa de expressões do grupo foi criado + em alguma iteração anterior. Caso exista essa ocorrencia indica + que o grupo já foi construído anteriormente, + desta forma um erro será disparado ao usuário */ + if(exp_iniciais.count(grupo)!=0) + { + //Dispara o erro ao usuário indicando construção duplicada + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_DEFGRUPODUPLICADA).arg(grupo), + ERR_PGMODELERUI_DEFGRUPODUPLICADA,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + /* 2ª Validação: Verifica se o grupo está sendo construído sem ter sido declarado. + Para tal, verifica se grupo que está sendo construído não existe + na lista de ordem de aplicação de grupos. Um grupo é dito como + não localizado na lista quando a chamada a função find() retorna + o iterador final da lista 'ordem_grupos.end() */ + else if(find(ordem_grupos.begin(), ordem_grupos.end(), grupo)==ordem_grupos.end()) + { + //Dispara o erro indicando que o grupo foi construído e não declarado + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_DEFGRUPONAODECL) + .arg(grupo).arg(AtributosParsers::ORDEM_DESTAQUE), + ERR_PGMODELERUI_DEFGRUPONAODECL,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + /* 3ª Validação: Verifica se o grupo possui elementos filhos. No bloco de construção + do grupo é necessário que ele possua pelo menos um filho ''. + Caso ele não possua elementos deste tipo um erro é retornado ao usuário */ + else if(!ParserXML::possuiElemento(ParserXML::ELEMENTO_FILHO)) + { + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_DEFGRUPOSEMELEM).arg(grupo), + ERR_PGMODELERUI_DEFGRUPOSEMELEM,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + + //Obtém e armazena em variáveis os atributos do grupo que está sendo construído + sensivel_chr=(atributos[AtributosParsers::SENSIVEL_CARACTERE]==AtributosParsers::VERDADEIRO); + italico=(atributos[AtributosParsers::ITALICO]==AtributosParsers::VERDADEIRO); + negrito=(atributos[AtributosParsers::NEGRITO]==AtributosParsers::VERDADEIRO); + sublinhado=(atributos[AtributosParsers::SUBLINHADO]==AtributosParsers::VERDADEIRO); + comb_parcial=(atributos[AtributosParsers::COMBINACAO_PARCIAL]==AtributosParsers::VERDADEIRO); + cor_fonte.setNamedColor(atributos[AtributosParsers::COR_FONTE]); + cor_fundo.setNamedColor(atributos[AtributosParsers::COR_FUNDO]); + + if(!atributos[AtributosParsers::CARACTERE_LOOKUP].isEmpty()) + caractere_lookup[grupo]=atributos[AtributosParsers::CARACTERE_LOOKUP][0]; + + //Configura a formatação do grupo de acordo com os atributos obtidos + formatacao.setFontItalic(italico); + formatacao.setFontUnderline(sublinhado); + + if(negrito) + formatacao.setFontWeight(QFont::Bold); + else + formatacao.setFontWeight(QFont::Normal); + + formatacao.setForeground(cor_fonte); + formatacao.setBackground(cor_fundo); + formatacoes[grupo]=formatacao; + + //Salva a posição atual do parser e acesso os elementos filhos do grupo + ParserXML::salvarPosicao(); + ParserXML::acessarElemento(ParserXML::ELEMENTO_FILHO); + + /* Configura a variável de expressão regular para ser sensível a + caracteres (case sensitive) de acordo com o mesmo atributo + obtido do xml */ + if(sensivel_chr) + exp_regular.setCaseSensitivity(Qt::CaseSensitive); + else + exp_regular.setCaseSensitivity(Qt::CaseInsensitive); + + combinacao_parcial[grupo]=comb_parcial; + + do + { + if(ParserXML::obterTipoElemento()==XML_ELEMENT_NODE) + { + //Obtém os atributos do elemento filho do grupo + ParserXML::obterAtributosElemento(atributos); + //Obtém o tipo do elemento + tipo_exp=atributos[AtributosParsers::TIPO]; + + //Configura a expressão regular com o valor presente no atributo 'value' do elemento + exp_regular.setPattern(atributos[AtributosParsers::VALOR]); + + if(atributos[AtributosParsers::EXP_REGULAR]==AtributosParsers::VERDADEIRO) + exp_regular.setPatternSyntax(QRegExp::RegExp); + else + exp_regular.setPatternSyntax(QRegExp::FixedString); + + /* A expressão regular configura será inserida na lista de expressões + de acordo com o tipo do elemento */ + if(tipo_exp=="" || + tipo_exp==AtributosParsers::EXP_SIMPLES || + tipo_exp==AtributosParsers::EXP_INICIAL) + exp_iniciais[grupo].push_back(exp_regular); + else + exp_finais[grupo].push_back(exp_regular); + } + } + while(ParserXML::acessarElemento(ParserXML::ELEMENTO_POSTERIOR)); + + //Restaura a posição do parser para continuar a leitura dos próximos grupos + ParserXML::restaurarPosicao(); + } + } + } + + /* Após a inserção do grupo, verifica se existem outros grupos a serem + declarados. Caso não existe, desmarca a flag de declaração de grupos + e restaura a posição do parser para que o restante do arquivo possa + ser lido */ + if(decl_grupos && !ParserXML::possuiElemento(ParserXML::ELEMENTO_POSTERIOR)) + { + decl_grupos=false; + ParserXML::restaurarPosicao(); + } + + } + while(ParserXML::acessarElemento(ParserXML::ELEMENTO_POSTERIOR)); + } + + /* Executa a validação final do carregamento do arquivo que consiste em + verificar se algum grupo foi declarado porém não construído. Para + isso, a lista de ordem de grupos é varrida e verifica-se se + existem expressões para tal grupo. Caso não exista expressões + para o grupo indica que o mesmo foi declarado e não foi construído */ + itr=ordem_grupos.begin(); + itr_end=ordem_grupos.end(); + + while(itr!=itr_end) + { + grupo=(*itr); + itr++; + + //Caso o número de expressões do grupo seja zero + if(exp_iniciais[grupo].size()==0) + { + //Dispara o erro indicando que o grupo foi declarado porém não construído + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_GRUPODECLNAODEF).arg(grupo), + ERR_PGMODELERUI_GRUPODECLNAODEF,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + } + + //Marca a flag indicando que a configuração foi carregada com sucesso + conf_carregada=true; + } + catch(Excecao &e) + { + //Captura e redireciona erros das demais bibliotecas + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/destaquesintaxe.h b/libpgmodeler_ui/src/destaquesintaxe.h new file mode 100644 index 000000000..d9ac61547 --- /dev/null +++ b/libpgmodeler_ui/src/destaquesintaxe.h @@ -0,0 +1,185 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: DestaqueSintaxe +# Descrição: Definição da classe que implementa um destacador de sintaxe de +# linguagens (código fonte) com padrões de marcação definidos pelo usuário. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef DESTAQUE_SINTAXE_H +#define DESTAQUE_SINTAXE_H + +#include +#include +#include +#include "excecao.h" +#include "parserxml.h" +#include "atributosglobais.h" +#include "atributosparsers.h" +#include +//*********************************************************** +class DestaqueSintaxe: public QSyntaxHighlighter { + Q_OBJECT + private: + /* Classe auxiliar do destacador que indica em qual bloco e + coluna se inicia e termina um determinado grupo de destaque multi linha */ + class InfoMultiLinha: public QTextBlockUserData { + public: + int col_ini, //Coluna onde se inicia a info multilinha + bloco_ini, //Bloco (linha) onde se inicia a info multilinha + + /* Coluna onde termina a info multilinha (pode ser -1) + enquanto o destacador não localizar o terminador de multilinha */ + col_fim, + + /* Bloco (linha) onde termina a info multilinha (pode ser -1) + enquanto o destacador não localizar o terminador de multilinha */ + bloco_fim; + + //Grupo de destaque usado entre a coluna inicial e final + QString grupo; + + //Constrói uma instância de informação de bloco + InfoMultiLinha(void) + { + this->grupo=""; + this->col_ini=-1; + this->bloco_ini=-1; + this->col_fim=-1; + this->bloco_fim=-1; + }; + + + ~InfoMultiLinha(void){} + }; + + /* Vetor o qual armazena as informações de multi linha para se saber + quando um texto digita pelo usuário está em um bloco multi linha + ou não fazendo assim os destaques corretos */ + vector info_multi_linha; + + /* Armazena as expressões regulares simples, ou seja, expressões + que indicam que o elemento a identificar é encontrado em uma + linha apenas. Usado para identificar elementos como palavras-chave, + identificadores, strings, números. Armazena também expressões iniciais + as quais identificam o começo de um bloco do grupo o qual pode aparecer + em mais de uma linha */ + map > exp_iniciais; + + /* Armazenam as expressões finais que indicam o término + do bloco do grupo. Estas expressões são usadas para identificar + principalmente comentários os quais possuem mais de uma linha */ + map > exp_finais; + + //Armazena as formatações de texto para cada grupo + map formatacoes; + + //Armazena as grupos que possuem de combinação parcial + map combinacao_parcial; + + //Armazena as grupos que possuem de combinação parcial + map caractere_lookup; + + //Armazena a ordem em que os grupos devem ser aplicados + vector ordem_grupos; + vector grupos_sep_palavras; + + //Indica se a configuração foi carregada ou não + bool conf_carregada, + /* Indica que o código deve ser redestacado conforme as + modificações executada pelo usuário. Este atributo é útil + para economizar processamento, pois, o auto redestaque só é + necessário quando o usuário está digitando o código fonte, + em casos em que o usuário já insere um codigo pronto na caixa + de texto, o código é destacado neste momento. + + Caso este atributo esteja marcado como false, o usuário deve + chamar o método rehighlight() para forçar o redestaque */ + auto_redestaque; + + //Armazena os caracteres indicativos de separador de palavras + QString sep_palavras, + //Armazena os caracteres indicativos de delimitadores de palavras + delim_palavras, + /* Armazena os caracteres os quais não são processados durante + a leitura das palavras */ + chr_ignorados; + + //Bloco atual no qual o destacador se encontra + int bloco_atual; + + /* Quantidade de informações de multilinha no bloco atual. + Este atributo é usado para se saber quando o destacador + deve chamar o método rehighlight para destacar o documento + inteiro novamente */ + unsigned qtd_info_bloco_atual; + + //Configura os atributos iniciais do destaque de sintaxe + void configurarAtributos(void); + + /* Identifica o grupo ao qual a palavra pertence. Informa ainda em que parte da palavra + combina com o grupo através dos parâmetros idx_comb e comp_combinacao, que são + respectivamente o índice inicial da combinação e o comprimento em caracteres da + combinação */ + QString identificarGrupoPalavra(const QString &palavra, const QChar &chk_lookup, int idx, int &idx_comb, int &comp_combinacao); + + /* Retorna a informção de multilinha em que o bloco atual se encontra caso o mesmo + esteja dentro de um bloco multilinha. Caso contrário retorna uma informação + multilinha vazia */ + InfoMultiLinha *obterInfoMultiLinha(int col_ini, int col_fim, int bloco); + + //Remove as informações de multilinha de um dado bloco + void removerInfoMultiLinha(int bloco); + + /* Retorna a quantiade de informações de multilinha relacionadas a um + determinado bloco */ + unsigned obterNumInfoMultiLinha(int bloco); + + public: + DestaqueSintaxe(QTextDocument *parent, bool auto_redestaque); + DestaqueSintaxe(QTextEdit *parent, bool auto_redestaque); + + /* Faz o carregamento do arquivo XML o qual armazena todas as definições + dos grupos de expressões responsáveis pelo destaque das palavras + do código fonte. */ + void carregarConfiguracao(const QString &nome_arq); + + //Retorna se a configuração foi carregada + bool configuracaoCarregada(void); + + public slots: + //Método resposável pelo destaque do texto completo + void rehighlight(void); + + private slots: + //Método resposável pelo destaque de uma linha de texto + void highlightBlock(const QString &txt); + + /* Faz a validação das modificações de texto promovidas pelo usuário. Este slot + é ligado ao sinal contentsChange() do documento, pois é nele que são + capturados a quantidade de caracteres removidos e inseridos pelo usuário */ + void validarModificacaoTexto(int,int,int); + + /* Limpa todas as configurações e atributos de destaque obtidos de + um carregamento prévio das configurações */ + void limparConfiguracao(void); +}; +//*********************************************************** +#endif + + diff --git a/libpgmodeler_ui/src/dominiowidget.cpp b/libpgmodeler_ui/src/dominiowidget.cpp new file mode 100644 index 000000000..584f60fc2 --- /dev/null +++ b/libpgmodeler_ui/src/dominiowidget.cpp @@ -0,0 +1,94 @@ +#include "dominiowidget.h" +//*********************************************************** +DominioWidget::DominioWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_DOMINIO) +{ + try + { + Ui_DominioWidget::setupUi(this); + + //Cria um destacador de sintaxe no campo de expressão de checagem do domínio + destaque_expr=NULL; + destaque_expr=new DestaqueSintaxe(expr_checagem_txt, false); + destaque_expr->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + tipo_dominio=NULL; + tipo_dominio=new TipoPgSQLWidget(this); + dominio_grid->addWidget(tipo_dominio,4,0,1,2); + + configurarLayouFormulario(dominio_grid, OBJETO_DOMINIO); + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->setMinimumSize(530, 450); + janela_pai->setMaximumHeight(450); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void DominioWidget::hideEvent(QHideEvent *evento) +{ + valor_padrao_edt->clear(); + expr_checagem_txt->clear(); + nome_rest_edt->clear(); + nao_nulo_chk->setChecked(false); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void DominioWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Dominio *dominio) +{ + TipoPgSQL tipo; + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, dominio); + + //Caso o domínio passado esteja alocado + if(dominio) + { + //Preenche o formulário com os atributos do domínio + tipo=dominio->obterTipo(); + valor_padrao_edt->setText(QString::fromUtf8(dominio->obterValorPadrao())); + expr_checagem_txt->setPlainText(QString::fromUtf8(dominio->obterExpressao())); + nome_rest_edt->setText(QString::fromUtf8(dominio->obterNomeRestricao())); + nao_nulo_chk->setChecked(dominio->naoNulo()); + } + + //Marca o tipo do domínio no widget de tipos pgsql + tipo_dominio->definirAtributos(tipo, modelo); +} +//---------------------------------------------------------- +void DominioWidget::aplicarConfiguracao(void) +{ + try + { + Dominio *dominio=NULL; + iniciarConfiguracao(); + + //Obtém a referência ao domínio que está sendo editado/criado + dominio=dynamic_cast(this->objeto); + + //Configura os atributos do mesmo com os valores definidos no formulário + dominio->definirTipo(tipo_dominio->obterTipoPgSQL()); + dominio->definirValorPadrao(valor_padrao_edt->text()); + dominio->definirExpressao(expr_checagem_txt->toPlainText()); + dominio->definirNomeRestricao(nome_rest_edt->text()); + dominio->definirNaoNulo(nao_nulo_chk->isChecked()); + + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/dominiowidget.h b/libpgmodeler_ui/src/dominiowidget.h new file mode 100644 index 000000000..9ffa6875e --- /dev/null +++ b/libpgmodeler_ui/src/dominiowidget.h @@ -0,0 +1,49 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: DominioWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de esquemas. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef DOMINIO_WIDGET_H +#define DOMINIO_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_dominiowidget.h" +#include "tipopgsqlwidget.h" +//*********************************************************** +class DominioWidget: public ObjetoBaseWidget, public Ui::DominioWidget { + Q_OBJECT + + private: + DestaqueSintaxe *destaque_expr; + TipoPgSQLWidget *tipo_dominio; + + public: + DominioWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Dominio *dominio); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/espacotabelawidget.cpp b/libpgmodeler_ui/src/espacotabelawidget.cpp new file mode 100644 index 000000000..bc6811154 --- /dev/null +++ b/libpgmodeler_ui/src/espacotabelawidget.cpp @@ -0,0 +1,56 @@ +#include "espacotabelawidget.h" +//*********************************************************** +EspacoTabelaWidget::EspacoTabelaWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_ESPACO_TABELA) +{ + Ui_EspacoTabelaWidget::setupUi(this); + configurarLayouFormulario(espacotabela_grid, OBJETO_ESPACO_TABELA); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->setMinimumSize(480, 260); + janela_pai->setMaximumSize(16777215, 260); +} +//---------------------------------------------------------- +void EspacoTabelaWidget::hideEvent(QHideEvent *evento) +{ + //Limpa as caixas de texto + diretorio_edt->clear(); + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void EspacoTabelaWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, EspacoTabela *espaco_tab) +{ + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, espaco_tab); + + if(espaco_tab) + diretorio_edt->setText(espaco_tab->obterDiretorio()); +} +//---------------------------------------------------------- +void EspacoTabelaWidget::aplicarConfiguracao(void) +{ + try + { + EspacoTabela *esp_tab=NULL; + + iniciarConfiguracao(); + + //Converte o objeto para espaço de tabela + esp_tab=dynamic_cast(this->objeto); + //Configura o diretório do espaço de tabelas com o caminho configurado no formulário + esp_tab->definirDiretorio(diretorio_edt->text()); + + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/espacotabelawidget.h b/libpgmodeler_ui/src/espacotabelawidget.h new file mode 100644 index 000000000..533233c83 --- /dev/null +++ b/libpgmodeler_ui/src/espacotabelawidget.h @@ -0,0 +1,46 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: EspacoTabelaWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de espaços de tabela. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef ESPACOTABELA_WIDGET_H +#define ESPACOTABELA_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_espacotabelawidget.h" +//*********************************************************** +class EspacoTabelaWidget: public ObjetoBaseWidget, public Ui::EspacoTabelaWidget { + Q_OBJECT + + private: + + public: + EspacoTabelaWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, EspacoTabela *espaco_tab); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/esquemawidget.cpp b/libpgmodeler_ui/src/esquemawidget.cpp new file mode 100644 index 000000000..212c725a4 --- /dev/null +++ b/libpgmodeler_ui/src/esquemawidget.cpp @@ -0,0 +1,36 @@ +#include "esquemawidget.h" +//*********************************************************** +EsquemaWidget::EsquemaWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_ESQUEMA) +{ + configurarLayouFormulario(NULL, OBJETO_ESQUEMA); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->setMinimumSize(500, 220); + janela_pai->setMaximumSize(16777215, 220); +} +//---------------------------------------------------------- +void EsquemaWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Esquema *esquema) +{ + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, esquema); +} +//---------------------------------------------------------- +void EsquemaWidget::aplicarConfiguracao(void) +{ + try + { + iniciarConfiguracao(); + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/esquemawidget.h b/libpgmodeler_ui/src/esquemawidget.h new file mode 100644 index 000000000..ae1bce435 --- /dev/null +++ b/libpgmodeler_ui/src/esquemawidget.h @@ -0,0 +1,44 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: EsquemaWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de esquemas. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef ESQUEMA_WIDGET_H +#define ESQUEMA_WIDGET_H + +#include "objetobasewidget.h" +//*********************************************************** +class EsquemaWidget: public ObjetoBaseWidget { + Q_OBJECT + + private: + + public: + EsquemaWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Esquema *esquema); + + private slots: + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/familiaoperadoreswidget.cpp b/libpgmodeler_ui/src/familiaoperadoreswidget.cpp new file mode 100644 index 000000000..7415fff38 --- /dev/null +++ b/libpgmodeler_ui/src/familiaoperadoreswidget.cpp @@ -0,0 +1,61 @@ +#include "familiaoperadoreswidget.h" +//*********************************************************** +FamiliaOperadoresWidget::FamiliaOperadoresWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_FAMILIA_OPER) +{ + QStringList tipos; + + Ui_FamiliaOperadoresWidget::setupUi(this); + configurarLayouFormulario(familiaop_grid, OBJETO_FAMILIA_OPER); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + //Configura o combobox do formulário listando todos os tipos de indexação do PostgreSQL + TipoIndexacao::obterTipos(tipos); + tipo_index_cmb->addItems(tipos); + + janela_pai->setMinimumSize(480, 270); + janela_pai->setMaximumSize(16777215, 270); +} +//---------------------------------------------------------- +void FamiliaOperadoresWidget::hideEvent(QHideEvent *evento) +{ + tipo_index_cmb->setCurrentIndex(0); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void FamiliaOperadoresWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, FamiliaOperadores *familia_op) +{ + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, familia_op); + + /* Caso a familia de operadores esteja alocada, marca o tipo de indexação + que o objeto usa */ + if(familia_op) + tipo_index_cmb->setCurrentIndex(tipo_index_cmb->findText(~(familia_op->obterTipoIndexacao()))); +} +//---------------------------------------------------------- +void FamiliaOperadoresWidget::aplicarConfiguracao(void) +{ + try + { + FamiliaOperadores *familia_op=NULL; + + iniciarConfiguracao(); + familia_op=dynamic_cast(this->objeto); + familia_op->definirTipoIndexacao(TipoIndexacao(tipo_index_cmb->currentText())); + + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/familiaoperadoreswidget.h b/libpgmodeler_ui/src/familiaoperadoreswidget.h new file mode 100644 index 000000000..d9516266b --- /dev/null +++ b/libpgmodeler_ui/src/familiaoperadoreswidget.h @@ -0,0 +1,46 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FamiliaOperadoresWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de família de operadores. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef FAMILIAOPERADORES_WIDGET_H +#define FAMILIAOPERADORES_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_familiaoperadoreswidget.h" +//*********************************************************** +class FamiliaOperadoresWidget: public ObjetoBaseWidget, public Ui::FamiliaOperadoresWidget { + Q_OBJECT + + private: + + public: + FamiliaOperadoresWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, FamiliaOperadores *familia_op); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/formbasico.cpp b/libpgmodeler_ui/src/formbasico.cpp new file mode 100644 index 000000000..0ad0f478f --- /dev/null +++ b/libpgmodeler_ui/src/formbasico.cpp @@ -0,0 +1,33 @@ +#include "formbasico.h" +//*********************************************************** +FormBasico::FormBasico(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) +{ + setupUi(this); + + /** ticket#2 **/ + /* Fix específico para Windows: permite que janelas passíveis de + maximização exibam o botão maximizar, adicionalmente, os diálogos de + edição de objetos ficam AlwayOnTop forçadamente */ + #ifdef Q_OS_WIN + this->setWindowFlags(this->windowFlags() | + Qt::Dialog | + Qt::WindowMaximizeButtonHint); + + this->widgetgeral_wgt->setFrameShape(QFrame::WinPanel); + #endif +} +//---------------------------------------------------------- +void FormBasico::definirBotoes(unsigned conf_botoes) +{ + if(conf_botoes==CaixaMensagem::BOTAO_OK_CANCELAR) + { + aplicar_ok_btn->setText(trUtf8("&Aplicar")); + cancelar_btn->setVisible(true); + } + else + { + aplicar_ok_btn->setText(trUtf8("&Ok")); + cancelar_btn->setVisible(false); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/formbasico.h b/libpgmodeler_ui/src/formbasico.h new file mode 100644 index 000000000..b1c3ac1fc --- /dev/null +++ b/libpgmodeler_ui/src/formbasico.h @@ -0,0 +1,45 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FormBasico +# Descrição: Definição da classe que um container de widgets de configuração +# de objetos no modelo de banco de dados. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef FROM_BASICO_H +#define FROM_BASICO_H + +#include +#include "ui_formbasico.h" +#include "excecao.h" +#include "caixamensagem.h" +//*********************************************************** +class FormBasico: public QDialog, public Ui::FormBasico { + Q_OBJECT + + private: + + public: + FormBasico(QWidget * parent = 0, Qt::WindowFlags f = 0); + ~FormBasico(void){} + void definirBotoes(unsigned conf_botoes=CaixaMensagem::BOTAO_OK_CANCELAR); + + public slots: +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/formconfiguracao.cpp b/libpgmodeler_ui/src/formconfiguracao.cpp new file mode 100644 index 000000000..9fa4eca35 --- /dev/null +++ b/libpgmodeler_ui/src/formconfiguracao.cpp @@ -0,0 +1,124 @@ +#include "formconfiguracao.h" +#include "caixamensagem.h" + +extern CaixaMensagem *caixa_msg; +//*********************************************************** +FormConfiguracao::FormConfiguracao(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) +{ + QGridLayout *layout=NULL; + + setupUi(this); + + conf_geral=NULL; + conf_aparencia=NULL; + conf_conexoes=NULL; + + conf_geral=new ConfGeralWidget(this); + conf_aparencia=new ConfAparenciaWidget(this); + conf_conexoes=new ConfConexoesWidget(this); + + layout=new QGridLayout; + layout->setContentsMargins(2,2,2,2); + layout->addWidget(conf_geral); + geral_frm->setLayout(layout); + + layout=new QGridLayout; + layout->setContentsMargins(2,2,2,2); + layout->addWidget(conf_aparencia); + aparencia_frm->setLayout(layout); + + layout=new QGridLayout; + layout->setContentsMargins(2,2,2,2); + layout->addWidget(conf_conexoes); + conexoes_frm->setLayout(layout); + + connect(lista_ico_lst, SIGNAL(currentRowChanged(int)), stackedWidget, SLOT(setCurrentIndex(int))); + connect(cancelar_btn, SIGNAL(clicked(void)), this, SLOT(close(void))); + connect(aplicar_btn, SIGNAL(clicked(void)), this, SLOT(aplicarConfiguracao(void))); + connect(padroes_btn, SIGNAL(clicked(void)), this, SLOT(restaurarPadroes(void))); +} +//----------------------------------------------------------- +void FormConfiguracao::close(void) +{ + try + { + if(sender()==cancelar_btn) + { + conf_aparencia->carregarConfiguracao(); + conf_conexoes->carregarConfiguracao(); + } + } + catch(Excecao &e) + {} + + QDialog::close(); +} +//----------------------------------------------------------- +void FormConfiguracao::aplicarConfiguracao(void) +{ + conf_geral->salvarConfiguracao(); + conf_geral->aplicarConfiguracao(); + conf_aparencia->salvarConfiguracao(); + conf_conexoes->salvarConfiguracao(); + this->close(); +} +//----------------------------------------------------------- +void FormConfiguracao::carregarConfiguracao(void) +{ + try + { + conf_geral->carregarConfiguracao(); + conf_aparencia->carregarConfiguracao(); + conf_conexoes->carregarConfiguracao(); + } + catch(Excecao &e) + { + throw Excecao(ERR_PGMODELERUI_CONFNAOCARREGADA,__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void FormConfiguracao::restaurarPadroes(void) +{ + caixa_msg->show(trUtf8("Confirmação"), + trUtf8("Qualquer modificação feita até agora na seção atual será perdida! Deseja realmente restaurar as configurações padrão?"), + CaixaMensagem::ICONE_CONFIRM, + CaixaMensagem::BOTAO_SIM_NAO); + + if(caixa_msg->result()==QDialog::Accepted) + { + switch(stackedWidget->currentIndex()) + { + case WGT_CONF_GERAL: + dynamic_cast(this->obterWidgetConfiguracao(0))->restaurarPadroes(); + break; + + case WGT_CONF_APARENCIA: + dynamic_cast(this->obterWidgetConfiguracao(1))->restaurarPadroes(); + break; + + case WGT_CONF_CONEXOES: + dynamic_cast(this->obterWidgetConfiguracao(2))->restaurarPadroes(); + break; + + default: + break; + } + } +} +//----------------------------------------------------------- +ConfBaseWidget *FormConfiguracao::obterWidgetConfiguracao(unsigned idx) +{ + if(idx >= static_cast(stackedWidget->count())) + return(NULL); + else + { + switch(idx) + { + case WGT_CONF_GERAL: return(dynamic_cast(conf_geral)); break; + case WGT_CONF_APARENCIA: return(dynamic_cast(conf_aparencia)); break; + default: + case WGT_CONF_CONEXOES: return(dynamic_cast(conf_conexoes)); break; + } + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/formconfiguracao.h b/libpgmodeler_ui/src/formconfiguracao.h new file mode 100644 index 000000000..a3e8b81a3 --- /dev/null +++ b/libpgmodeler_ui/src/formconfiguracao.h @@ -0,0 +1,55 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FormConfiguracao +# Descrição: Formulario que reúne todos os widgets de configuração. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef FORM_CONFIGURACAO_H +#define FORM_CONFIGURACAO_H + +#include "ui_formconfiguracao.h" +#include "confaparenciawidget.h" +#include "confgeralwidget.h" +#include "confconexoeswidget.h" +//*********************************************************** +class FormConfiguracao: public QDialog, public Ui::FormConfiguracao { + private: + Q_OBJECT + + ConfGeralWidget *conf_geral; + ConfAparenciaWidget *conf_aparencia; + ConfConexoesWidget *conf_conexoes; + + public: + static const int WGT_CONF_GERAL=0, + WGT_CONF_APARENCIA=1, + WGT_CONF_CONEXOES=2; + FormConfiguracao(QWidget * parent = 0, Qt::WindowFlags f = 0); + ConfBaseWidget *obterWidgetConfiguracao(unsigned idx); + + public slots: + void aplicarConfiguracao(void); + void carregarConfiguracao(void); + void close(void); + + private slots: + void restaurarPadroes(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/formexportacao.cpp b/libpgmodeler_ui/src/formexportacao.cpp new file mode 100644 index 000000000..79503c616 --- /dev/null +++ b/libpgmodeler_ui/src/formexportacao.cpp @@ -0,0 +1,393 @@ +#include "formexportacao.h" +#include "progressotarefa.h" +#include "formconfiguracao.h" + +extern ProgressoTarefa *prog_tarefa; +extern FormConfiguracao *fconfiguracao; +//*********************************************************** +FormExportacao::FormExportacao(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) +{ + vector versoes; + + modelo=NULL; + + setupUi(this); + connect(exportacao_arq_rb, SIGNAL(toggled(bool)), this, SLOT(habilitarTipoExportacao(void))); + connect(exportacao_sgbd_rb, SIGNAL(toggled(bool)), this, SLOT(habilitarTipoExportacao(void))); + connect(pgsqlvers_chk, SIGNAL(toggled(bool)), pgsqlvers1_cmb, SLOT(setEnabled(bool))); + connect(fechar_btn, SIGNAL(clicked(bool)), this, SLOT(close(void))); + connect(sel_arquivo_tb, SIGNAL(clicked(void)), this, SLOT(selecionarArquivoDestino(void))); + connect(exportar_btn, SIGNAL(clicked(void)), this, SLOT(exportarModelo(void))); + + //Obtém as versões disponíveis de esquemas SQL + ParserEsquema::obterVersoesPgSQL(versoes); + + //Preenche os comboboxes de versões + pgsqlvers_cmb->addItems(QStringList(QList::fromVector(QVector::fromStdVector(versoes)))); + pgsqlvers1_cmb->addItems(QStringList(QList::fromVector(QVector::fromStdVector(versoes)))); + + /** ticket#2 **/ + //Fix específico para Windows: força a aparência do frame para WinPanel + #ifdef Q_OS_WIN + this->frame->setFrameShape(QFrame::WinPanel); + #endif +} +//----------------------------------------------------------- +void FormExportacao::show(ModeloBD *modelo) +{ + if(modelo) + { + map conexoes; + map::iterator itr; + QString host; + + /* Atualiza a lista de conexões ao exibir o formulário de exportação, obtendo-as + do widget de configuração de conexões */ + this->modelo=modelo; + dynamic_cast(fconfiguracao->obterWidgetConfiguracao(FormConfiguracao::WGT_CONF_CONEXOES))->obterConexoes(conexoes); + + conexoes_cmb->clear(); + itr=conexoes.begin(); + + while(itr!=conexoes.end()) + { + host=(itr->second)->obterParamConexao(ConexaoBD::PARAM_FQDN_SERVIDOR); + + if(host.isEmpty()) + host=(itr->second)->obterParamConexao(ConexaoBD::PARAM_IP_SERVIDOR); + + conexoes_cmb->addItem(itr->first + QString(" (%1)").arg(host), + QVariant::fromValue(itr->second)); + itr++; + } + + //Esconde os widgets de progresso da exportação + this->ocultarProgressoExportacao(); + QDialog::show(); + } +} +//----------------------------------------------------------- +void FormExportacao::hideEvent(QHideEvent *) +{ + this->modelo=NULL; + arquivo_edt->clear(); + exportacao_arq_rb->setChecked(true); + exportar_btn->setEnabled(false); +} +//----------------------------------------------------------- +void FormExportacao::exportarModelo(void) +{ + int id_tipo; + QString versao, buf_sql, cmd_sql; + ConexaoBD *conexao=NULL, conex_novo_bd; + unsigned i, qtd; + bool bd_criado=false; + int idx_objs[]={-1, -1}; + TipoObjetoBase vet_tipos[]={OBJETO_PAPEL, OBJETO_ESPACO_TABELA}; + ObjetoBase *objeto=NULL; + + + /* Vetor que armazena os códigos de erros referentes a objetos duplicados no PostgreSQL: + Estes erros podem ser consultados na íntegra em: + http://www.postgresql.org/docs/current/static/errcodes-appendix.html + + Códigos usados neste método: + 42P04 duplicate_database + 42723 duplicate_function + 42P06 duplicate_schema + 42P07 duplicate_table + 42710 duplicate_object + */ + QString cod_erros[]={"42P04", "42723", "42P06", "42P07", "42710"}; + vector vet_cod_erros; + + try + { + for(i=0; i < 5; i++) + vet_cod_erros.push_back(cod_erros[i]); + + //Redimensiona a janela para exibição dos widgets de progresso + this->resize(this->maximumSize()); + + //Exibe os widgets de progresso + ln2_frm->setVisible(true); + rot_prog_lbl->setVisible(true); + prog_pb->setVisible(true); + + //Inicialmente o ícone de sucesso/erro da exportação fica escondido + ico_lbl->setVisible(false); + + //Configura o widget de progresso para capturar o progresso da geração do código + prog_tarefa->setWindowTitle(trUtf8("Gerando código-fonte...")); + connect(this->modelo, SIGNAL(s_objetoCarregado(int,QString,unsigned)), + prog_tarefa, SLOT(executarProgesso(int,QString,unsigned))); + + rot_prog_lbl->setText(trUtf8("Iniciando exportação do modelo...")); + rot_prog_lbl->repaint(); + + //Caso seja exportação em arquivo + if(exportacao_arq_rb->isChecked()) + { + //Define a versão do postgresql a ser adotada + ParserEsquema::definirVersaoPgSQL(pgsqlvers_cmb->currentText()); + + rot_prog_lbl->setText(trUtf8("Salvando arquivo '%1'").arg(arquivo_edt->text())); + + //Salva o modelo em arquivo + modelo->salvarModelo(arquivo_edt->text(), ParserEsquema::DEFINICAO_SQL); + prog_pb->setValue(25); + } + //Caso seja exportação direto para o SGBD + else + { + //Obtém a conexão selecionada no combo + conexao=reinterpret_cast(conexoes_cmb->itemData(conexoes_cmb->currentIndex()).value()); + //Tenta se conectar + conexao->conectar(); + //Obtém a versão do servidor PostgreSQL. Essa versão é usada na geração de código a seguir + versao=(conexao->obterVersaoSGBD()).mid(0,3); + + /* Caso o checkbox de versão esteja marcada então a versão do servidor é ignorada + usando aquela escolhida no combo */ + if(pgsqlvers_chk->isChecked()) + ParserEsquema::definirVersaoPgSQL(pgsqlvers1_cmb->currentText()); + else + ParserEsquema::definirVersaoPgSQL(versao); + + + //Cria os Papéis e espaços de tabela separadamente dos demais + for(id_tipo=0; id_tipo < 2; id_tipo++) + { + qtd=modelo->obterNumObjetos(vet_tipos[id_tipo]); + for(i=0; i < qtd; i++) + { + objeto=modelo->obterObjeto(i, vet_tipos[id_tipo]); + rot_prog_lbl->setText(trUtf8("Criando objeto '%1' (%2)...").arg(QString::fromUtf8(objeto->obterNome())).arg(objeto->obterNomeTipoObjeto())); + rot_prog_lbl->repaint(); + + try + { + conexao->executarComandoDDL(objeto->obterDefinicaoObjeto(ParserEsquema::DEFINICAO_SQL)); + } + catch(Excecao &e) + { + /* Caso o checkbox de ignorar duplicidade não esteja marcado ou se este está marcado porém a + informação adicinal da exceção não carrega um dos códigos indicando duplicidade de objeto + redireciona o erro, caso contrário apenas o ignora */ + if(!ignorar_dup_chk->isChecked() || + (ignorar_dup_chk->isChecked() && + std::find(vet_cod_erros.begin(), vet_cod_erros.end(), e.obterInfoAdicional())==vet_cod_erros.end())) + throw Excecao(e.obterMensagemErro(), + e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } + + prog_pb->setValue((10 * (id_tipo+1)) + ((i/static_cast(qtd)) * 10)); + idx_objs[id_tipo]++; + } + } + + //Cria o banco de dados no servidor + rot_prog_lbl->setText(trUtf8("Criando banco de dados '%1'...").arg(QString::fromUtf8(modelo->obterNome()))); + rot_prog_lbl->repaint(); + + try + { + conexao->executarComandoDDL(modelo->__obterDefinicaoObjeto(ParserEsquema::DEFINICAO_SQL)); + } + catch(Excecao &e) + { + /* Caso o checkbox de ignorar duplicidade não esteja marcado ou se este está marcado porém a + informação adicinal da exceção não carrega um dos códigos indicando duplicidade de objeto + redireciona o erro, caso contrário apenas o ignora */ + if(!ignorar_dup_chk->isChecked() || + (ignorar_dup_chk->isChecked() && + std::find(vet_cod_erros.begin(), vet_cod_erros.end(), e.obterInfoAdicional())==vet_cod_erros.end())) + throw Excecao(e.obterMensagemErro(), + e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } + + prog_pb->setValue(30); + bd_criado=true; + + conex_novo_bd=(*conexao); + conex_novo_bd.definirParamConexao(ConexaoBD::PARAM_NOME_BD, modelo->obterNome()); + rot_prog_lbl->setText(trUtf8("Conectando ao banco de dados '%1'...").arg(QString::fromUtf8(modelo->obterNome()))); + rot_prog_lbl->repaint(); + conex_novo_bd.conectar(); + prog_pb->setValue(50); + + //Cria os demais objetos no novo banco + rot_prog_lbl->setText(trUtf8("Criando objetos No banco de dados '%1'...").arg(QString::fromUtf8(modelo->obterNome()))); + rot_prog_lbl->repaint(); + + //Gera o código SQL de todo o banco + buf_sql=modelo->obterDefinicaoObjeto(ParserEsquema::DEFINICAO_SQL, false); + + /* Extrai cada comando SQL do buffeer e o executa separadamente, isso é feito + para que, em caso de erro, o usuário saiba exatamente a SQL que gerou a + exceção uma vez que a libpq não proporciona este nível de detalhes */ + i=0; + qtd=buf_sql.size(); + + while(i < qtd) + { + try + { + cmd_sql.clear(); + + //Extrai os caracteres até encontrar o final do buffer ou um ';' + while(i < qtd && buf_sql.at(i)!=';') + { + cmd_sql+=buf_sql.at(i); + i++; + } + + //Executa um trimm no comando SQL extraído + cmd_sql=cmd_sql.trimmed(); + + //Caso o comando não esteja vazio + if(!cmd_sql.isEmpty()) + { + i++; + //Concatena um ';' para finalizar o comando + cmd_sql+=';'; + //Executa-o na conexão + conex_novo_bd.executarComandoDDL(cmd_sql); + } + + prog_pb->setValue(50 + ((i/static_cast(qtd)) * 10)); + } + catch(Excecao &e) + { + /* Caso o checkbox de ignorar duplicidade não esteja marcado ou se este está marcado porém a + informação adicinal da exceção não carrega um dos códigos indicando duplicidade de objeto + redireciona o erro, caso contrário apenas o ignora */ + if(!ignorar_dup_chk->isChecked() || + (ignorar_dup_chk->isChecked() && + std::find(vet_cod_erros.begin(), vet_cod_erros.end(), e.obterInfoAdicional())==vet_cod_erros.end())) + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_FALHAEXPORTACAO).arg(cmd_sql), + ERR_PGMODELERUI_FALHAEXPORTACAO,__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } + } + } + + //Finaliza o progresso da exportação + prog_pb->setValue(100); + rot_prog_lbl->setText(trUtf8("Exportação finalizada com sucesso!")); + rot_prog_lbl->repaint(); + ico_lbl->setPixmap(QPixmap(QString(":/icones/icones/msgbox_info.png"))); + ico_lbl->setVisible(true); + + prog_tarefa->close(); + disconnect(this->modelo, NULL, prog_tarefa, NULL); + + //Oculta os widgets de progresso após 10 segundos + QTimer::singleShot(10000, this, SLOT(ocultarProgressoExportacao(void))); + } + catch(Excecao &e) + { + QString drop_cmd=QString("DROP %1 %2;"); + + prog_tarefa->close(); + disconnect(this->modelo, NULL, prog_tarefa, NULL); + + /* Caso os algum objeto tenha sido criado é preciso excluí-los do banco. + Para isso, os mesmos são removidos na ordem contrária de criação: + banco de dados, espaço de tabelas e papéis */ + if(bd_criado || idx_objs[0] >= 0 || idx_objs[1] >= 0) + { + if(conex_novo_bd.conexaoEstabelecida()) + conex_novo_bd.fechar(); + + //Caso o banco de dados foi criado, exclui o mesmo + if(bd_criado) + conexao->executarComandoDDL(drop_cmd + .arg(modelo->obterNomeSQLObjeto()) + .arg(modelo->obterNome(true))); + + //Removendo os espaços de tabela e papéis + for(id_tipo=1; id_tipo >=0; id_tipo--) + { + while(idx_objs[id_tipo] >= 0) + { + objeto=modelo->obterObjeto(idx_objs[id_tipo], vet_tipos[id_tipo]); + + try + { + conexao->executarComandoDDL(drop_cmd + .arg(objeto->obterNomeSQLObjeto()) + .arg(objeto->obterNome(true))); + } + catch(Excecao &e) + {} + + idx_objs[id_tipo]--; + } + } + } + + //Exibe no progresso a mensagem de falha + rot_prog_lbl->setText(trUtf8("Falha na exportação!")); + rot_prog_lbl->repaint(); + ico_lbl->setPixmap(QPixmap(QString(":/icones/icones/msgbox_erro.png"))); + ico_lbl->setVisible(true); + + //Oculta os widgets de progresso após 10 segundos + QTimer::singleShot(10000, this, SLOT(ocultarProgressoExportacao(void))); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void FormExportacao::ocultarProgressoExportacao(void) +{ + ln2_frm->setVisible(false); + rot_prog_lbl->setVisible(false); + prog_pb->setVisible(false); + ico_lbl->setVisible(false); + this->resize(this->minimumSize()); +} +//----------------------------------------------------------- +void FormExportacao::habilitarTipoExportacao(void) +{ + bool exp_arq=(sender()==exportacao_arq_rb); + + //Widgets habilitados quando a exportação é para arquivo + modelo_sql_lbl->setEnabled(exp_arq); + arquivo_lbl->setEnabled(exp_arq); + arquivo_edt->setEnabled(exp_arq); + sel_arquivo_tb->setEnabled(exp_arq); + pgsql_lbl->setEnabled(exp_arq); + pgsqlvers_cmb->setEnabled(exp_arq); + dica_lbl->setEnabled(exp_arq); + + //Widgets habilitados quando a exportação é para o sgbd + modelo_sgbd->setEnabled(!exp_arq); + conexoes_lbl->setEnabled(!exp_arq); + conexoes_cmb->setEnabled(!exp_arq); + pgsqlvers_chk->setEnabled(!exp_arq); + pgsqlvers1_cmb->setEnabled(!exp_arq && pgsqlvers_chk->isChecked()); + dica1_lbl->setEnabled(!exp_arq); + dica2_lbl->setEnabled(!exp_arq); + ignorar_dup_lbl->setEnabled(!exp_arq); + ignorar_dup_chk->setEnabled(!exp_arq); + + exportar_btn->setEnabled((exportacao_sgbd_rb->isChecked() && conexoes_cmb->count() > 0) || + (exportacao_arq_rb->isChecked() && !arquivo_edt->text().isEmpty())); +} +//----------------------------------------------------------- +void FormExportacao::selecionarArquivoDestino(void) +{ + QFileDialog arquivo_dlg; + + arquivo_dlg.setWindowTitle(trUtf8("Exportar modelo como...")); + arquivo_dlg.setFilter(trUtf8("Código SQL (*.sql);;Todos os Arquivos (*.*)")); + arquivo_dlg.setFileMode(QFileDialog::AnyFile); + arquivo_dlg.setAcceptMode(QFileDialog::AcceptSave); + arquivo_dlg.setModal(true); + + if(arquivo_dlg.exec()==QFileDialog::Accepted) + arquivo_edt->setText(arquivo_dlg.selectedFile()); + + exportar_btn->setEnabled(!arquivo_edt->text().isEmpty()); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/formexportacao.h b/libpgmodeler_ui/src/formexportacao.h new file mode 100644 index 000000000..953340f7d --- /dev/null +++ b/libpgmodeler_ui/src/formexportacao.h @@ -0,0 +1,48 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FormExportacao +# Descrição: Formulário de exportação do modelo +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef FORM_EXPORTACAO_H +#define FORM_EXPORTACAO_H + +#include "ui_formexportacao.h" +#include "parseresquema.h" +#include "modelobd.h" +//*********************************************************** +class FormExportacao: public QDialog, public Ui::FormExportacao { + private: + Q_OBJECT + ModeloBD *modelo; + + public: + FormExportacao(QWidget * parent = 0, Qt::WindowFlags f = 0); + + public slots: + void show(ModeloBD *modelo); + void hideEvent(QHideEvent *); + + private slots: + void habilitarTipoExportacao(void); + void exportarModelo(void); + void selecionarArquivoDestino(void); + void ocultarProgressoExportacao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/formprincipal.cpp b/libpgmodeler_ui/src/formprincipal.cpp new file mode 100644 index 000000000..c85fb45dd --- /dev/null +++ b/libpgmodeler_ui/src/formprincipal.cpp @@ -0,0 +1,1160 @@ +#include "formprincipal.h" +//---------------------------------------------------------- +#include "caixatextowidget.h" +#include "codigofontewidget.h" +#include "bancodadoswidget.h" +#include "esquemawidget.h" +#include "papelwidget.h" +#include "permissaowidget.h" +#include "espacotabelawidget.h" +#include "linguagemwidget.h" +#include "funcaowidget.h" +#include "parametrowidget.h" +#include "conversaotipowidget.h" +#include "conversaocodificacaowidget.h" +#include "dominiowidget.h" +#include "funcaoagregacaowidget.h" +#include "sequenciawidget.h" +#include "operadorwidget.h" +#include "familiaoperadoreswidget.h" +#include "classeoperadoreswidget.h" +#include "tipowidget.h" +#include "visaowidget.h" +#include "colunawidget.h" +#include "restricaowidget.h" +#include "regrawidget.h" +#include "gatilhowidget.h" +#include "indicewidget.h" +#include "relacionamentowidget.h" +#include "tabelawidget.h" +#include "progressotarefa.h" +#include "listaobjetoswidget.h" +#include "formconfiguracao.h" +#include "formexportacao.h" + +/* Formulários globais. Como são formulários os mesmos podem ser + compartilhados e usados em outros arquivos não havendo a necessidade + de se instanciar cada um toda vez em que forem usados. + O formulário principal é o responsável por alocar e desalocar esses objetos. */ +FormSobre *fsobre=NULL; +CaixaMensagem *caixa_msg=NULL; +VisaoObjetosWidget *selecaoobjetos_wgt=NULL; +CaixaTextoWidget *caixatexto_wgt=NULL; +CodigoFonteWidget *codigofonte_wgt=NULL; +BancoDadosWidget *bancodados_wgt=NULL; +EsquemaWidget *esquema_wgt=NULL; +PapelWidget *papel_wgt=NULL; +PermissaoWidget *permissao_wgt=NULL; +EspacoTabelaWidget *espacotabela_wgt=NULL; +LinguagemWidget *linguagem_wgt=NULL; +ParametroWidget *parametro_wgt=NULL; +FuncaoWidget *funcao_wgt=NULL; +ConversaoTipoWidget *convtipo_wgt=NULL; +ConversaoCodificacaoWidget *convcodif_wgt=NULL; +DominioWidget *dominio_wgt=NULL; +FuncaoAgregacaoWidget *funcaoag_wgt=NULL; +SequenciaWidget *sequencia_wgt=NULL; +OperadorWidget *operador_wgt=NULL; +FamiliaOperadoresWidget *familiaop_wgt=NULL; +ClasseOperadoresWidget *classeop_wgt=NULL; +TipoWidget *tipo_wgt=NULL; +VisaoWidget *visao_wgt=NULL; +ColunaWidget *coluna_wgt=NULL; +RestricaoWidget *restricao_wgt=NULL; +RegraWidget *regra_wgt=NULL; +GatilhoWidget *gatilho_wgt=NULL; +IndiceWidget *indice_wgt=NULL; +RelacionamentoWidget *relacao_wgt=NULL; +TabelaWidget *tabela_wgt=NULL; +ProgressoTarefa *prog_tarefa=NULL; +ListaObjetosWidget *deps_refs_wgt=NULL; +FormConfiguracao *fconfiguracao=NULL; +FormExportacao *fexportacao=NULL; +//---------------------------------------------------------- +FormPrincipal::FormPrincipal(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) +{ + map >confs; + map >::iterator itr, itr_end; + map atribs; + map areas_dock; + map areas_toolbar; + map dock_wgts; + map toolbars; + QString tipo; + ConfBaseWidget *conf_wgt=NULL; + TipoObjetoBase tipos[27]={ + OBJETO_RELACAO_BASE,OBJETO_RELACAO, OBJETO_TABELA, OBJETO_VISAO, + OBJETO_FUNC_AGREGACAO, OBJETO_OPERADOR, OBJETO_INDICE, OBJETO_RESTRICAO, + OBJETO_SEQUENCIA, OBJETO_CONV_CODIFICACAO, + OBJETO_CONV_TIPO, OBJETO_FAMILIA_OPER, OBJETO_CLASSE_OPER, + OBJETO_RELACAO_BASE, OBJETO_CAIXA_TEXTO, + OBJETO_DOMINIO, OBJETO_TIPO, OBJETO_FUNCAO, OBJETO_ESQUEMA, + OBJETO_LINGUAGEM, OBJETO_ESPACO_TABELA, OBJETO_PAPEL, + OBJETO_REGRA, OBJETO_COLUNA, OBJETO_GATILHO, OBJETO_INDICE, OBJETO_RESTRICAO }; + + setupUi(this); + + //Alocando os formulários globais + fsobre=new FormSobre; + caixa_msg=new CaixaMensagem(this, (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)); + fconfiguracao=new FormConfiguracao(this); + fexportacao=new FormExportacao(this); + + lista_oper=new ListaOperacoesWidget; + visao_objs=new VisaoObjetosWidget; + selecaoobjetos_wgt=new VisaoObjetosWidget(true); + + + //*** CRIAÇÃO DOS FORMULÁRIOS GLOBAIS *** + permissao_wgt=new PermissaoWidget(this); + codigofonte_wgt=new CodigoFonteWidget(this); + caixatexto_wgt=new CaixaTextoWidget(this); + bancodados_wgt=new BancoDadosWidget(this); + esquema_wgt=new EsquemaWidget(this); + papel_wgt=new PapelWidget(this); + espacotabela_wgt=new EspacoTabelaWidget(this); + linguagem_wgt=new LinguagemWidget(this); + parametro_wgt=new ParametroWidget(this); + funcao_wgt=new FuncaoWidget(this); + convtipo_wgt=new ConversaoTipoWidget(this); + convcodif_wgt=new ConversaoCodificacaoWidget(this); + dominio_wgt=new DominioWidget(this); + funcaoag_wgt=new FuncaoAgregacaoWidget(this); + sequencia_wgt=new SequenciaWidget(this); + operador_wgt=new OperadorWidget(this); + familiaop_wgt=new FamiliaOperadoresWidget(this); + classeop_wgt=new ClasseOperadoresWidget(this); + tipo_wgt=new TipoWidget(this); + visao_wgt=new VisaoWidget(this); + coluna_wgt=new ColunaWidget(this); + restricao_wgt=new RestricaoWidget(this); + regra_wgt=new RegraWidget(this); + gatilho_wgt=new GatilhoWidget(this); + indice_wgt=new IndiceWidget(this); + relacao_wgt=new RelacionamentoWidget(this); + tabela_wgt=new TabelaWidget(this); + prog_tarefa=new ProgressoTarefa(this); + deps_refs_wgt=new ListaObjetosWidget(this); + + for(unsigned i=0; i < 27; i++) + prog_tarefa->adicionarIcone(tipos[i], + QIcon(QString(":/icones/icones/") + + ObjetoBase::obterNomeEsquemaObjeto(tipos[i]) + + QString(".png"))); + + icone_op=new QLabel; + icone_op->setFrameShape(QFrame::Panel); + icone_op->setFrameShadow(QFrame::Raised); + icone_op->setGeometry(0,0,1,22); + + nome_op=new QLabel; + nome_op->setFont(QFont(this->font().family(),10,1,true)); + nome_op->setFrameShape(QFrame::Panel); + nome_op->setFrameShadow(QFrame::Raised); + + this->statusBar()->addPermanentWidget(icone_op,0); + this->statusBar()->addPermanentWidget(nome_op,1); + this->statusBar()->hide(); + + connect(action_sair,SIGNAL(triggered(bool)),this,SLOT(close())); + connect(action_novo_modelo,SIGNAL(triggered(bool)),this,SLOT(adicionarNovoModelo())); + connect(action_fechar_modelo,SIGNAL(triggered(bool)),this,SLOT(fecharModelo())); + + connect(modelos_tab,SIGNAL(currentChanged(int)),this,SLOT(definirModeloAtual())); + connect(action_proximo,SIGNAL(triggered(bool)),this,SLOT(definirModeloAtual())); + connect(action_anterior,SIGNAL(triggered(bool)),this,SLOT(definirModeloAtual())); + connect(action_sobre,SIGNAL(triggered(bool)),fsobre,SLOT(show())); + + connect(action_ampliar_zoom,SIGNAL(triggered(bool)),this,SLOT(aplicarZoom())); + connect(action_diminuir_zoom,SIGNAL(triggered(bool)),this,SLOT(aplicarZoom())); + connect(action_zoom_normal,SIGNAL(triggered(bool)),this,SLOT(aplicarZoom())); + + connect(action_carregar_modelo,SIGNAL(triggered(bool)),this,SLOT(carregarModelo())); + connect(action_salvar_modelo,SIGNAL(triggered(bool)),this,SLOT(salvarModelo())); + connect(action_salvar_como,SIGNAL(triggered(bool)),this,SLOT(salvarModelo())); + connect(action_salvar_tudo,SIGNAL(triggered(bool)),this,SLOT(salvarTodosModelos())); + + connect(lista_oper, SIGNAL(s_operacaoExecutada(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(lista_oper, SIGNAL(s_listaOperacoesAtualizada(void)), this, SLOT(__atualizarEstadoFerramentas(void))); + connect(action_desfazer,SIGNAL(triggered(bool)),lista_oper,SLOT(desfazerOperacao())); + connect(action_refazer,SIGNAL(triggered(bool)),lista_oper,SLOT(refazerOperacao())); + + connect(action_tela_cheia, SIGNAL(toggled(bool)), this, SLOT(exibirTelaCheia(bool))); + connect(modelos_tab, SIGNAL(tabCloseRequested(int)), this, SLOT(fecharModelo(int))); + + connect(action_imprimir, SIGNAL(triggered(bool)), this, SLOT(imprimirModelo(void))); + connect(action_configuracoes, SIGNAL(triggered(bool)), fconfiguracao, SLOT(show(void))); + + /* Conectando os sinais de objetos manipulados disparados pelos formulários de criação de objetos + para forçar a atualização da visão de objetos */ + connect(bancodados_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(esquema_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(papel_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(caixatexto_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(espacotabela_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(linguagem_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(funcao_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(convtipo_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(convcodif_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(dominio_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(funcaoag_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(sequencia_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(operador_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(familiaop_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(classeop_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(tipo_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(visao_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(coluna_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(restricao_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(regra_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(gatilho_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(indice_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(relacao_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + connect(tabela_wgt, SIGNAL(s_objetoManipulado(void)), this, SLOT(__atualizarDockWidgets(void))); + + connect(arquivo_tb, SIGNAL(visibilityChanged(bool)), action_arquivo, SLOT(setChecked(bool))); + connect(action_arquivo, SIGNAL(toggled(bool)), arquivo_tb, SLOT(setVisible(bool))); + + connect(edicao_tb, SIGNAL(visibilityChanged(bool)), action_edicao, SLOT(setChecked(bool))); + connect(action_edicao, SIGNAL(toggled(bool)), edicao_tb, SLOT(setVisible(bool))); + + connect(exibicao_tb, SIGNAL(visibilityChanged(bool)), action_exibicao, SLOT(setChecked(bool))); + connect(action_exibicao, SIGNAL(toggled(bool)), exibicao_tb, SLOT(setVisible(bool))); + + connect(modelo_tb, SIGNAL(visibilityChanged(bool)), action_modelo, SLOT(setChecked(bool))); + connect(action_modelo, SIGNAL(toggled(bool)), modelo_tb, SLOT(setVisible(bool))); + + connect(action_operacoes, SIGNAL(toggled(bool)), lista_oper, SLOT(setVisible(bool))); + connect(lista_oper, SIGNAL(visibilityChanged(bool)), this, SLOT(atualizarDockWidgets(void))); + + connect(action_visao_objetos, SIGNAL(toggled(bool)), visao_objs, SLOT(setVisible(bool))); + connect(visao_objs, SIGNAL(visibilityChanged(bool)), this, SLOT(atualizarDockWidgets(void))); + + connect(fconfiguracao, SIGNAL(finished(int)), this, SLOT(atualizarModelos(void))); + connect(&tm_salvamento, SIGNAL(timeout(void)), this, SLOT(salvarTodosModelos(void))); + + connect(action_exportar, SIGNAL(triggered(bool)), this, SLOT(exportarModelo(void))); + + modelo_atual=NULL; + + //Inserindo a versão do software na janela principal + titulo_janela=this->windowTitle() + " " + AtributosGlobais::VERSAO_PGMODELER; + this->setWindowTitle(titulo_janela); + this->addDockWidget(Qt::RightDockWidgetArea, visao_objs); + this->addDockWidget(Qt::RightDockWidgetArea, lista_oper); + this->menuPlugins->setVisible(false); + + //Faz o carregamento dos plugins + try + { + this->carregarPlugins(); + } + catch(Excecao &e) + { + caixa_msg->show(e); + } + + + //Faz o carregamento das configurações + try + { + fconfiguracao->carregarConfiguracao(); + + areas_dock[AtributosParsers::ESQUERDA]=Qt::LeftDockWidgetArea; + areas_dock[AtributosParsers::DIREITA]=Qt::RightDockWidgetArea; + areas_dock[AtributosParsers::BASE]=Qt::BottomDockWidgetArea; + areas_dock[AtributosParsers::TOPO]=Qt::TopDockWidgetArea; + dock_wgts[AtributosParsers::DK_OBJETOS]=visao_objs; + dock_wgts[AtributosParsers::DK_OPERACOES]=lista_oper; + + areas_toolbar[AtributosParsers::ESQUERDA]=Qt::LeftToolBarArea; + areas_toolbar[AtributosParsers::DIREITA]=Qt::RightToolBarArea; + areas_toolbar[AtributosParsers::BASE]=Qt::BottomToolBarArea; + areas_toolbar[AtributosParsers::TOPO]=Qt::TopToolBarArea; + toolbars[AtributosParsers::TB_ARQUIVO]=arquivo_tb; + toolbars[AtributosParsers::TB_EDICAO]=edicao_tb; + toolbars[AtributosParsers::TB_EXIBICAO]=exibicao_tb; + toolbars[AtributosParsers::TB_PLUGINS]=plugins_tb; + toolbars[AtributosParsers::TB_MODELO]=modelo_tb; + + //Aplicando as configurações carregadas + conf_wgt=fconfiguracao->obterWidgetConfiguracao(0); + confs=conf_wgt->obterParamsConfiguracao(); + + itr=confs.begin(); + itr_end=confs.end(); + + /* Configurando a exibição dos widgets conforme as configurações e + carregando arquivos anteriormente abertos */ + while(itr!=itr_end) + { + atribs=itr->second; + tipo=atribs[AtributosParsers::TIPO]; + + if(tipo==AtributosParsers::DK_OBJETOS || + tipo==AtributosParsers::DK_OPERACOES) + { + this->addDockWidget(areas_dock[atribs[AtributosParsers::POSICAO]], dock_wgts[tipo]); + dock_wgts[tipo]->setVisible(atribs[AtributosParsers::VISIVEL]==AtributosParsers::VERDADEIRO); + } + else if(tipo==AtributosParsers::TB_ARQUIVO || + tipo==AtributosParsers::TB_EDICAO || + tipo==AtributosParsers::TB_EXIBICAO || + tipo==AtributosParsers::TB_MODELO || + tipo==AtributosParsers::TB_PLUGINS) + { + this->addToolBar(areas_toolbar[atribs[AtributosParsers::POSICAO]], toolbars[tipo]); + toolbars[tipo]->setVisible(atribs[AtributosParsers::VISIVEL]==AtributosParsers::VERDADEIRO); + } + else if(atribs.count(AtributosParsers::CAMINHO)!=0) + { + try + { + if(!atribs[AtributosParsers::CAMINHO].isEmpty()) + this->adicionarNovoModelo(atribs[AtributosParsers::CAMINHO]); + } + catch(Excecao &e) + { + caixa_msg->show(e); + } + } + + itr++; + } + } + catch(Excecao &e) + { + caixa_msg->show(e); + } + + //Inicializa o atributo de tempo de salvamento automático + interv_salvar=confs[AtributosParsers::CONFIGURACAO][AtributosParsers::INTERVALO_SALVAR_AUTO].toInt() * 60000; + + //Caso o intervalo de salvamento esteja setado inicializa o timer + if(interv_salvar > 0) + tm_salvamento.start(interv_salvar, false); +} +//---------------------------------------------------------- +FormPrincipal::~FormPrincipal(void) +{ + //Destrói os plugins carregados + this->destruirPlugins(); + + //Desalocando os formulários globais + delete(icone_op); + delete(nome_op); + delete(lista_oper); + delete(visao_objs); + delete(fsobre); +} +//---------------------------------------------------------- +void FormPrincipal::closeEvent(QCloseEvent *) +{ + ConfGeralWidget *conf_wgt=NULL; + map > confs; + bool salvar_conf=false, modificado=false; + int i=0; + + //Checa se existem modelos modificados e pergunta ao usuário se deseja salvá-los antes de sair + if(modelos_tab->count() > 0) + { + //Varre os modelos e obtém o estado da modificação + i=0; + while(i < modelos_tab->count() && !modificado) + modificado=dynamic_cast(modelos_tab->widget(i++))->modeloModificado(); + + //Se algum modelo foi encontrado como modificado + if(modificado) + { + caixa_msg->show(trUtf8("Salvar modelos"), + trUtf8("Alguns modelos foram modificados! Deseja salvar todos antes de encerrar o pgModeler?"), + CaixaMensagem::ICONE_CONFIRM,CaixaMensagem::BOTAO_SIM_NAO); + + if(caixa_msg->result()==QDialog::Accepted) + this->salvarTodosModelos(); + } + } + + conf_wgt=dynamic_cast(fconfiguracao->obterWidgetConfiguracao(0)); + confs=conf_wgt->obterParamsConfiguracao(); + conf_wgt->excluirParamsConfiguracao(); + + //Caso seja preciso salvar a posição dos widgets + if(!confs[AtributosParsers::CONFIGURACAO][AtributosParsers::SALVAR_WIDGETS].isEmpty()) + { + int i, qtd=7; + QString id_param; + map atribs; + map areas_dock; + map areas_toolbar; + map id_widgets; + QWidget *vet_wgts[]={ arquivo_tb, edicao_tb, exibicao_tb, + plugins_tb, modelo_tb, visao_objs, lista_oper }; + QToolBar *toolbar=NULL; + QDockWidget *dock=NULL; + + salvar_conf=true; + + id_widgets[visao_objs]=AtributosParsers::DK_OBJETOS; + id_widgets[lista_oper]=AtributosParsers::DK_OPERACOES; + id_widgets[arquivo_tb]=AtributosParsers::TB_ARQUIVO; + id_widgets[edicao_tb]=AtributosParsers::TB_EDICAO; + id_widgets[exibicao_tb]=AtributosParsers::TB_EXIBICAO; + id_widgets[plugins_tb]=AtributosParsers::TB_PLUGINS; + id_widgets[modelo_tb]=AtributosParsers::TB_MODELO; + + areas_dock[Qt::LeftDockWidgetArea]=AtributosParsers::ESQUERDA; + areas_dock[Qt::RightDockWidgetArea]=AtributosParsers::DIREITA; + areas_dock[Qt::BottomDockWidgetArea]=AtributosParsers::BASE; + areas_dock[Qt::TopDockWidgetArea]=AtributosParsers::TOPO; + + areas_toolbar[Qt::LeftToolBarArea]=AtributosParsers::ESQUERDA; + areas_toolbar[Qt::RightToolBarArea]=AtributosParsers::DIREITA; + areas_toolbar[Qt::BottomToolBarArea]=AtributosParsers::BASE; + areas_toolbar[Qt::TopToolBarArea]=AtributosParsers::TOPO; + + for(i=0; i < qtd; i++) + { + toolbar=dynamic_cast(vet_wgts[i]); + dock=dynamic_cast(vet_wgts[i]); + + id_param=QString("%1%2").arg(AtributosParsers::WIDGET).arg(i); + atribs[AtributosParsers::TIPO]=id_widgets[vet_wgts[i]]; + atribs[AtributosParsers::ID]=id_param; + atribs[AtributosParsers::VISIVEL]=(vet_wgts[i]->isVisible() ? + AtributosParsers::VERDADEIRO : AtributosParsers::FALSO); + + if(dock) + atribs[AtributosParsers::POSICAO]=areas_dock[this->dockWidgetArea(dock)]; + else + atribs[AtributosParsers::POSICAO]=areas_toolbar[this->toolBarArea(toolbar)]; + + conf_wgt->adicionarParamConfiguracao(id_param, atribs); + atribs.clear(); + } + } + + //Caso seja necessário salvar a sessão de arquivos carregados + if(!confs[AtributosParsers::CONFIGURACAO][AtributosParsers::SALVAR_SESSAO].isEmpty()) + { + int i, qtd; + ModeloWidget *modelo=NULL; + QString id_param; + map atribs; + + qtd=modelos_tab->count(); + for(i=0; i < qtd; i++) + { + modelo=dynamic_cast(modelos_tab->widget(i)); + + if(!modelo->obterNomeArquivo().isEmpty()) + { + id_param=QString("%1%2").arg(AtributosParsers::ARQUIVO).arg(i); + atribs[AtributosParsers::ID]=id_param; + atribs[AtributosParsers::CAMINHO]=modelo->obterNomeArquivo(); + conf_wgt->adicionarParamConfiguracao(id_param, atribs); + atribs.clear(); + } + } + salvar_conf=true; + } + + if(salvar_conf) + conf_wgt->salvarConfiguracao(); +} +//---------------------------------------------------------- +void FormPrincipal::adicionarNovoModelo(const QString &nome_arq) +{ + ModeloWidget *tab_modelo; + QString nome_obj, nome_tab, str_aux; + Esquema *esq_publico=NULL; + Linguagem *ling=NULL; + QLayout *layout=NULL; + + //Converte a quantidade de abas para QString + str_aux=QString("%1").arg(modelos_tab->count()); + + //Define o nome da nova aba + nome_obj="tab_modelo"; + nome_obj+=str_aux; + nome_tab=nome_obj; + + tab_modelo = new ModeloWidget(modelos_tab); + tab_modelo->setObjectName(QString::fromUtf8(nome_obj)); + + //Adiciona a aba criada ao conjuto de abas existentes + nome_obj=tab_modelo->modelo->obterNome(); + modelos_tab->addTab(tab_modelo, QString::fromUtf8(nome_obj)); + modelos_tab->setCurrentIndex(modelos_tab->count()-1); + layout=modelos_tab->currentWidget()->layout(); + layout->setContentsMargins(4,4,4,4); + + //Cria objetos do sistema (esquema public e linguagens c, sql e plpgsql) + esq_publico=new Esquema; + esq_publico->definirNome("public"); + tab_modelo->modelo->adicionarObjeto(esq_publico); + + ling=new Linguagem; + ling->ObjetoBase::definirNome(~TipoLinguagem(TipoLinguagem::c)); + tab_modelo->modelo->adicionarObjeto(ling); + + ling=new Linguagem; + ling->ObjetoBase::definirNome(~TipoLinguagem(TipoLinguagem::sql)); + tab_modelo->modelo->adicionarObjeto(ling); + + ling=new Linguagem; + ling->ObjetoBase::definirNome(~TipoLinguagem(TipoLinguagem::plpgsql)); + tab_modelo->modelo->adicionarObjeto(ling); + + if(!nome_arq.isEmpty()) + { + try + { + //Carrega o modelo caso o nome do arquivo esteja especificado + tab_modelo->carregarModelo(nome_arq); + modelos_tab->setTabText(modelos_tab->currentIndex(), + QString::fromUtf8(tab_modelo->modelo->obterNome())); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } + + definirModeloAtual(); +} +//---------------------------------------------------------- +void FormPrincipal::definirModeloAtual(void) +{ + QObject *objeto=NULL; + + objeto=sender(); + + //Limpa as barras de edição de de modelo + modelo_tb->clear(); + edicao_tb->clear(); + menuEditar->clear(); + + //Adiciona as ações de desfazer/refazer na barra/menu de edição + edicao_tb->addAction(action_desfazer); + edicao_tb->addAction(action_refazer); + edicao_tb->addSeparator(); + menuEditar->addAction(action_desfazer); + menuEditar->addAction(action_refazer); + menuEditar->addSeparator(); + + //Atualiza os botões de navegação de modelos + if(objeto==action_proximo) + modelos_tab->setCurrentIndex(modelos_tab->currentIndex()+1); + else if(objeto==action_anterior) + modelos_tab->setCurrentIndex(modelos_tab->currentIndex()-1); + + //O modelo atual obtido a partir da aba atual no 'modelos_tab' + modelo_atual=dynamic_cast(modelos_tab->currentWidget()); + + //Caso haja um modelo + if(modelo_atual) + { + //Atualiza o zoom do memos + this->aplicarZoom(); + + //Focaliza o modelo + modelo_atual->setFocus(Qt::OtherFocusReason); + //Cancela qualquer operação que possa ter sido ativada pelo usuário antes de abrir o modelo atual + modelo_atual->cancelarAdicaoObjeto(); + + //Configura a barra de ferramentas do modelo conforme as ações respectivas no modelo atual + modelo_tb->addAction(modelo_atual->action_novo_obj); + modelo_tb->addAction(modelo_atual->action_editar); + modelo_tb->addAction(modelo_atual->action_codigo_fonte); + modelo_tb->addAction(modelo_atual->action_converter_relnn); + modelo_tb->addAction(modelo_atual->action_deps_refs); + modelo_tb->addAction(modelo_atual->action_proteger); + modelo_tb->addAction(modelo_atual->action_desproteger); + modelo_tb->addAction(modelo_atual->action_selecionar_todos); + + edicao_tb->addAction(modelo_atual->action_copiar); + edicao_tb->addAction(modelo_atual->action_recortar); + edicao_tb->addAction(modelo_atual->action_colar); + edicao_tb->addAction(modelo_atual->action_excluir); + + menuEditar->addAction(modelo_atual->action_copiar); + menuEditar->addAction(modelo_atual->action_recortar); + menuEditar->addAction(modelo_atual->action_colar); + menuEditar->addAction(modelo_atual->action_excluir); + + //Configura o titulo da janela da aplicação + if(modelo_atual->obterNomeArquivo().isEmpty()) + this->setWindowTitle(titulo_janela); + else + //Caso o modelo atual venha de um arquivo, concatena o caminho para o arquivo + this->setWindowTitle(titulo_janela + " - " + QDir::toNativeSeparators(modelo_atual->obterNomeArquivo())); + + connect(modelo_atual, SIGNAL(s_objetoModificado(void)),lista_oper, SLOT(atualizarListaOperacoes(void))); + connect(modelo_atual, SIGNAL(s_objetoCriado(void)),lista_oper, SLOT(atualizarListaOperacoes(void))); + connect(modelo_atual, SIGNAL(s_objetoRemovido(void)),lista_oper, SLOT(atualizarListaOperacoes(void))); + connect(modelo_atual, SIGNAL(s_objetosMovimentados(void)),lista_oper, SLOT(atualizarListaOperacoes(void))); + + connect(modelo_atual, SIGNAL(s_objetoModificado(void)),visao_objs, SLOT(atualizarVisaoObjetos(void))); + connect(modelo_atual, SIGNAL(s_objetoCriado(void)),visao_objs, SLOT(atualizarVisaoObjetos(void))); + connect(modelo_atual, SIGNAL(s_objetoRemovido(void)),visao_objs, SLOT(atualizarVisaoObjetos(void))); + + connect(action_alin_objs_grade, SIGNAL(triggered(bool)), this, SLOT(definirOpcoesGrade(void))); + connect(action_exibir_grade, SIGNAL(triggered(bool)), this, SLOT(definirOpcoesGrade(void))); + connect(action_exibir_lim_paginas, SIGNAL(triggered(bool)), this, SLOT(definirOpcoesGrade(void))); + + connect(modelo_atual, SIGNAL(s_zoomModificado(void)), this, SLOT(atualizarEstadoFerramentas(void))); + } + else + this->setWindowTitle(titulo_janela); + + menuEditar->addSeparator(); + menuEditar->addAction(action_configuracoes); + + atualizarEstadoFerramentas(); + + //Atualiza os dockwidgets com os dados do modelo atual + lista_oper->definirModelo(modelo_atual); + visao_objs->definirModelo(modelo_atual); +} +//---------------------------------------------------------- +void FormPrincipal::definirOpcoesGrade(void) +{ + //Configura, globalmente na cena, as opçoẽs da grade + CenaObjetos::definirOpcoesGrade(action_exibir_grade->isChecked(), + action_alin_objs_grade->isChecked(), + action_exibir_lim_paginas->isChecked()); + + + if(modelo_atual) + { + /* Caso o alinhamento de objetos esteja ativado, chama o método de + alinhamento da cena do modelo */ + if(action_alin_objs_grade->isChecked()) + modelo_atual->cena->alinharObjetosGrade(); + + //Atualiza a cena do modelo + modelo_atual->cena->update(); + } +} +//---------------------------------------------------------- +void FormPrincipal::aplicarZoom(void) +{ + if(modelo_atual) + { + //Obtém o zoom atual do modelo + float zoom=modelo_atual->zoomAtual(); + + //Configura a aplicação do zoom conforme a ação qu disparou o método + if(sender()==action_zoom_normal) + zoom=1; + else if(sender()==action_ampliar_zoom && zoom < ModeloWidget::ZOOM_MAXIMO) + zoom+=ModeloWidget::INC_ZOOM; + else if(sender()==action_diminuir_zoom && zoom > ModeloWidget::ZOOM_MINIMO) + zoom-=ModeloWidget::INC_ZOOM; + + //Aplica o zoom configurado + modelo_atual->aplicarZoom(zoom); + } +} +//---------------------------------------------------------- +void FormPrincipal::exibirTelaCheia(bool tela_cheia) +{ + //Barras/Widgets que são escondidas quando o pgModeler está em tela cheia + menu_principal_mb->setVisible(!tela_cheia); + arquivo_tb->setVisible(!tela_cheia); + edicao_tb->setVisible(!tela_cheia); + lista_oper->setVisible(!tela_cheia); + visao_objs->setVisible(!tela_cheia); + + + //Caso não esteja em tela cheia, reinsere as barras na área destinada a toolbars + if(!tela_cheia) + { + arquivo_tb->setAllowedAreas(Qt::AllToolBarAreas); + this->addToolBar(Qt::TopToolBarArea, arquivo_tb); + + edicao_tb->setAllowedAreas(Qt::AllToolBarAreas); + this->addToolBar(Qt::TopToolBarArea, edicao_tb); + + exibicao_tb->setAllowedAreas(Qt::AllToolBarAreas); + this->addToolBar(Qt::TopToolBarArea, exibicao_tb); + + modelo_tb->setAllowedAreas(Qt::AllToolBarAreas); + this->addToolBar(Qt::BottomToolBarArea, modelo_tb); + } + else + { + //Caso esteja em tela cheia remove as barras de suas áreas e as torna flutuantes + arquivo_tb->setParent(NULL); + arquivo_tb->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + arquivo_tb->setVisible(true); + arquivo_tb->setAllowedAreas(Qt::NoToolBarArea); + arquivo_tb->adjustSize(); + + edicao_tb->setParent(NULL); + this->removeToolBar(edicao_tb); + + modelo_tb->setParent(NULL); + modelo_tb->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + modelo_tb->setVisible(true); + modelo_tb->setAllowedAreas(Qt::NoToolBarArea); + modelo_tb->adjustSize(); + + exibicao_tb->setParent(NULL); + exibicao_tb->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); + exibicao_tb->setVisible(true); + exibicao_tb->setAllowedAreas(Qt::NoToolBarArea); + exibicao_tb->adjustSize(); + } +} +//---------------------------------------------------------- +void FormPrincipal::fecharModelo(int idx_modelo) +{ + QWidget *tab=NULL; + + if(idx_modelo >= 0) + { + tab=modelos_tab->widget(idx_modelo); + modelos_tab->removeTab(idx_modelo); //Remove a aba + } + else + { + tab=modelos_tab->currentWidget(); //Obtém a aba em foco + modelos_tab->removeTab(modelos_tab->currentIndex()); //Remove a aba + } + + if(tab) + { + disconnect(tab, NULL, lista_oper, NULL); + disconnect(tab, NULL, visao_objs, NULL); + disconnect(action_alin_objs_grade, NULL, this, NULL); + disconnect(action_exibir_grade, NULL, this, NULL); + disconnect(action_exibir_lim_paginas, NULL, this, NULL); + + delete(dynamic_cast(tab)); //Desaloca a aba selecionada + } + + if(modelos_tab->count()==0) + { + modelo_atual=NULL; + this->exibirTelaCheia(false); + visao_objs->definirModelo(static_cast(NULL)); + lista_oper->definirModelo(static_cast(NULL)); + atualizarEstadoFerramentas(true); + } + else + { + definirModeloAtual(); + } +} +//---------------------------------------------------------- +void FormPrincipal::atualizarModelos(void) +{ + ConfGeralWidget *conf_wgt=NULL; + int qtd, i; + + //Obtém o widget de configuração geral + conf_wgt=dynamic_cast(fconfiguracao->obterWidgetConfiguracao(0)); + + //Caso a opção de salvamento do modelo não esteja marcada + if(!conf_wgt->salvar_mod_chk->isChecked()) + { + //Interrompe o timer de salvamento + interv_salvar=0; + tm_salvamento.stop(); + } + //Caso contrário configura o intervalo de salvamento + else + { + interv_salvar=conf_wgt->salvar_mod_spb->value() * 60000; + tm_salvamento.start(interv_salvar, false); + } + + //Força a atualização de todos os modelos abertos + qtd=modelos_tab->count(); + for(i=0; i < qtd; i++) + dynamic_cast(modelos_tab->widget(i))->modelo->definirObjetosModificados(); +} +//---------------------------------------------------------- +void FormPrincipal::salvarTodosModelos(void) +{ + //Caso o intervalo de salvamento esteja setado + if(interv_salvar > 0) + { + ModeloWidget *modelo=NULL; + int i, qtd; + + //Executa o método de salvamento em todos os modelos abertos + qtd=modelos_tab->count(); + for(i=0; i < qtd; i++) + { + modelo=dynamic_cast(modelos_tab->widget(i)); + this->salvarModelo(modelo); + } + } +} +//---------------------------------------------------------- +void FormPrincipal::salvarModelo(ModeloWidget *modelo) +{ + try + { + //Caso nenhum modelo foi especificado toma como base o modelo atual + if(!modelo) + modelo=modelo_atual; + + if(modelo) + { + //Caso a ação que disparou o método foi o de 'Salvar como' + if(sender()==action_salvar_como || modelo->nome_arquivo.isEmpty()) + { + QFileDialog arquivo_dlg; + + //Exibe o diálogo de salvamento do arquivo + arquivo_dlg.setWindowTitle(trUtf8("Salvar '%1' como...").arg(modelo->modelo->obterNome())); + arquivo_dlg.setFilter(tr("Modelo de Banco de Dados (*.pgmodel);;Todos os Arquivos (*.*)")); + arquivo_dlg.setFileMode(QFileDialog::AnyFile); + arquivo_dlg.setAcceptMode(QFileDialog::AcceptSave); + arquivo_dlg.setModal(true); + + //Caso o usuário confirme o salvamento, executa o método de salvamento do modelo + if(arquivo_dlg.exec()==QFileDialog::Accepted) + { + if(!arquivo_dlg.selectedFiles().isEmpty()) + modelo->salvarModelo(arquivo_dlg.selectedFiles().at(0)); + } + } + else + //Caso o usuário acione a ação de salvamento comum, executa direto o método do modelo + modelo->salvarModelo(); + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void FormPrincipal::exportarModelo(void) +{ + //Caso haja um modelo aberto exibe o formulário de exportação do modelo + if(modelo_atual) + fexportacao->show(modelo_atual->modelo); +} +//---------------------------------------------------------- +void FormPrincipal::imprimirModelo(void) +{ + if(modelo_atual) + { + QPrinter *printer=NULL; + QPrintDialog print_dlg; + QPrinter::PageSize tam_papel, tam_papel_atual; + QPrinter::Orientation orientacao, orient_atual; + QRectF margens; + unsigned ml,mt,mr,mb, ml1, mt1, mr1, mb1; + QCheckBox *impgrade_chk=NULL, *impnumpag_chk; + QVBoxLayout *layout=NULL; + QGridLayout *grid=NULL; + deque wgts; + QGroupBox *gb=new QGroupBox(&print_dlg); + + /* Cria dois checkboxes no diálogo de impressão, um + que indica a impressão da grade e outro do número de páginas */ + impgrade_chk=new QCheckBox(&print_dlg); + impgrade_chk->setText(trUtf8("Imprimir grade")); + impgrade_chk->setChecked(true); + + impnumpag_chk=new QCheckBox(&print_dlg); + impnumpag_chk->setText(trUtf8("Imprimir número de páginas")); + impnumpag_chk->setChecked(true); + + grid=new QGridLayout; + grid->addWidget(impgrade_chk,0,0,1,1); + grid->addWidget(impnumpag_chk,0,1,1,1); + gb->setLayout(grid); + gb->setTitle(trUtf8("Opções do modelo")); + + layout=dynamic_cast(print_dlg.layout()); + while(layout->count()!=0) + { + wgts.push_back(layout->itemAt(0)->widget()); + layout->removeItem(layout->itemAt(0)); + } + + //Adiciona os widgets no diálogo + layout->addWidget(gb); + while(!wgts.empty()) + { + layout->addWidget(wgts.front()); + wgts.pop_front(); + } + + print_dlg.setOption(QAbstractPrintDialog::PrintCurrentPage, false); + print_dlg.setWindowTitle(trUtf8("Impressão de modelo de banco de dados")); + + //Obtém as configurações de impressão da cena + CenaObjetos::obterConfiguracaoPagina(tam_papel, orientacao, margens); + + //Obtém a referência à impressora configuada no diálogo de impressão + printer=print_dlg.printer(); + + //Atribui as configurações de impressão da cena à impressora + printer->setPaperSize(tam_papel); + printer->setOrientation(orientacao); + printer->setPageMargins(margens.left(), margens.top(), margens.right(), margens.bottom(), QPrinter::Millimeter); + printer->margins(&mt,&ml,&mb,&mr); + print_dlg.exec(); + + //Caso o usuário confirme a impressão do modelo + if(print_dlg.result() == QDialog::Accepted) + { + /* Caso o usuário modifique as configurações da impressora este será alertado de + que as configurações divergem daquelas setadas na Cena, e assim a impressão + pode ser prejudicada */ + printer->margins(&mt1,&ml1,&mb1,&mr1); + orient_atual=print_dlg.printer()->orientation(); + tam_papel_atual=print_dlg.printer()->paperSize(); + + if(ml!=ml1 || mr!=mr1 || mt!=mt1 || mb!=mb1 || + orientacao!=orient_atual || tam_papel_atual!=tam_papel) + { + //Exibe a caixa de confirmação de impressão ao usuário + caixa_msg->show(trUtf8("Confirmação"), + trUtf8("Foram detectadas modificações nas definições de papel/margem do modelo o que pode provocar a impressão incorreta dos objetos. Deseja prosseguir com a impressão usando as novas configurações? Para usar as configurações padrão clique 'Não' ou em 'Cancelar' para abortar a impressão."), + CaixaMensagem::ICONE_ALERTA, CaixaMensagem::BOTAO_SIM_NAO_CANCELAR); + } + + if(!caixa_msg->caixaCanceleda()) + { + //Caso o usuário rejeite as configurações personalizada + if(caixa_msg->result()==QDialog::Rejected) + { + //Reverte para as configurações originais da cena + printer->setPaperSize(tam_papel); + printer->setOrientation(orientacao); + printer->setPageMargins(margens.left(), margens.top(), margens.right(), margens.bottom(), QPrinter::Millimeter); + } + + //Imprime o modelo com as configurações setadas + modelo_atual->imprimirModelo(printer, impgrade_chk->isChecked(), impnumpag_chk->isChecked()); + } + } + } +} +//---------------------------------------------------------- +void FormPrincipal::carregarModelo(void) +{ + QStringList lista; + int i, qtd; + QFileDialog arquivo_dlg; + + try + { + //Exibe o diálogo de carregamento do arquivo + arquivo_dlg.setFilter(tr("Modelo de Banco de Dados (*.pgmodel);;Todos os Arquivos (*.*)")); + arquivo_dlg.setWindowIcon(QPixmap(QString(":/icones/icones/pgsqlModeler48x48.png"))); + arquivo_dlg.setWindowTitle(trUtf8("Carregar modelo")); + arquivo_dlg.setFileMode(QFileDialog::ExistingFiles); + arquivo_dlg.setAcceptMode(QFileDialog::AcceptOpen); + + //Caso o usuário confirme o carregamento dos arquivos + if(arquivo_dlg.exec()==QFileDialog::Accepted) + { + lista=arquivo_dlg.selectedFiles(); + qtd=lista.count(); + + //Varre a lista de arquivos selecionados e os carrega + for(i=0; i < qtd; i++) + { + if(QFileInfo(lista[i]).isFile()) + adicionarNovoModelo(lista[i]); + } + } + } + catch(Excecao &e) + { + fecharModelo(modelos_tab->currentIndex()); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void FormPrincipal::__atualizarEstadoFerramentas(void) +{ + atualizarEstadoFerramentas(false); +} +//---------------------------------------------------------- +void FormPrincipal::atualizarEstadoFerramentas(bool modelo_fechado) +{ + bool ativo=!modelo_fechado; + + action_imprimir->setEnabled(ativo); + action_salvar_como->setEnabled(ativo); + action_salvar_modelo->setEnabled(ativo); + action_salvar_tudo->setEnabled(ativo); + action_exportar->setEnabled(ativo); + action_fechar_modelo->setEnabled(ativo); + action_exibir_grade->setEnabled(ativo); + action_exibir_lim_paginas->setEnabled(ativo); + + action_zoom_normal->setEnabled(ativo); + action_ampliar_zoom->setEnabled(ativo); + action_diminuir_zoom->setEnabled(ativo); + action_alin_objs_grade->setEnabled(ativo); + action_tela_cheia->setEnabled(ativo); + action_desfazer->setEnabled(ativo); + action_refazer->setEnabled(ativo); + + if(!modelo_fechado && modelo_atual && modelos_tab->count() > 0) + { + action_anterior->setEnabled(modelos_tab->currentIndex() > 0 && + modelos_tab->count() > 1); + action_proximo->setEnabled(modelos_tab->currentIndex() >= 0 && + modelos_tab->currentIndex()!=(modelos_tab->count()-1)); + action_desfazer->setEnabled(modelo_atual->lista_op->desfazerHabilitado()); + action_refazer->setEnabled(modelo_atual->lista_op->refazerHabilitado()); + + action_ampliar_zoom->setEnabled(modelo_atual->zoomAtual() <= ModeloWidget::ZOOM_MAXIMO - ModeloWidget::INC_ZOOM); + action_zoom_normal->setEnabled(modelo_atual->zoomAtual()!=0); + action_diminuir_zoom->setEnabled(modelo_atual->zoomAtual() >= ModeloWidget::ZOOM_MINIMO + ModeloWidget::INC_ZOOM); + } + + plugins_tb->setEnabled(modelos_tab->count() > 0); + menuPlugins->setEnabled(modelos_tab->count() > 0); +} +//---------------------------------------------------------- +void FormPrincipal::atualizarDockWidgets(void) +{ + if(modelo_atual) + { + lista_oper->atualizarListaOperacoes(); + __atualizarEstadoFerramentas(); + } + action_operacoes->setChecked(lista_oper->isVisible()); + action_visao_objetos->setChecked(visao_objs->isVisible()); +} +//---------------------------------------------------------- +void FormPrincipal::__atualizarDockWidgets(void) +{ + lista_oper->atualizarListaOperacoes(); + visao_objs->atualizarVisaoObjetos(); +} +//---------------------------------------------------------- +void FormPrincipal::carregarPlugins(void) +{ + vector vet_erros; + QString lib, nome_plugin, + dir_plugins=AtributosGlobais::DIR_PLUGINS + + AtributosGlobais::SEP_DIRETORIO; + QPluginLoader pl; + /* Configura uma instância de QDir para manipular as entradas no diretório raiz + de plugins. O pgModeler obterá somente diretórios, caso o usuário crie um plugin + e não o coloque em uma pasta o pgModeler ignora tal arquivo */ + QDir dir(dir_plugins, "*", QDir::Name, QDir::AllDirs | QDir::NoDotAndDotDot); + QStringList lista_dirs=dir.entryList(); + PgModelerPlugin *plugin=NULL; + QAction *acao_plugin=NULL; + QPixmap ico_acao; + + //O QPluginLoader deve resolver todos os símbolos da biblioteca + pl.setLoadHints(QLibrary::ResolveAllSymbolsHint); + + while(!lista_dirs.isEmpty()) + { + //Armazena o nome do plugin + nome_plugin=lista_dirs.front(); + + /* Monta o caminho básico para a biblioteca. + O pgModeler configura o caminho da seguinte forma: + + [DIR. RAIZ PLUGINS]/[NOME PLUGIN]/lib[NOME PLUGIN].[SUFIXO] */ + //Resolve do o sufixo da biblioteca em tempo de compilação + #ifdef Q_OS_WIN + lib=dir_plugins + nome_plugin + + AtributosGlobais::SEP_DIRETORIO + + nome_plugin + QString(".dll"); //Sufixo em Windows + #elif Q_OS_MAC + lib=dir_plugins + nome_plugin + + AtributosGlobais::SEP_DIRETORIO + + nome_plugin + QString(".dylib"); //Sufixo em Mac + #else + lib=dir_plugins + nome_plugin + + AtributosGlobais::SEP_DIRETORIO + + QString("lib") + nome_plugin + QString(".so"); //Sufixo em Unix/Linux + #endif + + //Carrega a biblioteca + pl.setFileName(lib); + if(pl.load()) + { + //Caso carregada com sucesso, insere uma instância do plugin no vetor de plugins + plugin=qobject_cast(pl.instance()); + plugins[nome_plugin]=plugin; + + //Cria a ação que é usada para disparar o plugin + acao_plugin=new QAction(this); + acao_plugin->setText(plugin->obterRotuloPlugin()); + + /* O nome da ação é setado como o nome do plugin para que este possa ser + referenciado no mapa de plugins quando o método FormPrincipal::executarPlugin() + for executado */ + acao_plugin->setName(nome_plugin.toStdString().c_str()); + + ico_acao.load(dir_plugins + nome_plugin + + AtributosGlobais::SEP_DIRETORIO + + nome_plugin + QString(".png")); + acao_plugin->setIcon(ico_acao); + + //Conecta a ação ao método do form principal que executa o plugin + connect(acao_plugin, SIGNAL(triggered(void)), this, SLOT(executarPlugin(void))); + + //Adiciona a ação na barra de plugins + plugins_tb->addAction(acao_plugin); + menuPlugins->addAction(acao_plugin); + } + else + { + //Caso o plugin não foi carregado, armazena o erro para posterior exibição + vet_erros.push_back(Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_PLUGINNAOCARREGADO) + .arg(lista_dirs.front()) + .arg(lib) + .arg(pl.errorString()), + ERR_PGMODELERUI_PLUGINNAOCARREGADO, __PRETTY_FUNCTION__,__FILE__,__LINE__)); + } + lista_dirs.pop_front(); + } + + //Exibe a barra de plugins caso este esteja visível + plugins_tb->setVisible(!plugins.empty()); + menuPlugins->setVisible(!plugins.empty()); + + //Caso algum erro foi disparado no carregamento, redireciona o erro + if(!vet_erros.empty()) + throw Excecao(ERR_PGMODELERUI_PLUGINSNAOCARREGADOS,__PRETTY_FUNCTION__,__FILE__,__LINE__, vet_erros); +} +//---------------------------------------------------------- +void FormPrincipal::destruirPlugins(void) +{ + map::iterator itr; + + //Varre o mapa de plugins destruindo cada instância (itr->second) + itr=plugins.begin(); + while(itr!=plugins.end()) + { + delete(itr->second); + itr->second=NULL; + itr++; + } + + plugins.clear(); +} +//---------------------------------------------------------- +void FormPrincipal::executarPlugin(void) +{ + QAction *acao=dynamic_cast(sender()); + + /* Um plugin só será executado caso um modelo esteja aberto + e ação tenha o nome de um plugin registrado */ + if(modelo_atual && acao && plugins.count(acao->name())==1) + plugins[acao->name()]->executarPlugin(modelo_atual); +} +//********************************************************** diff --git a/libpgmodeler_ui/src/formprincipal.h b/libpgmodeler_ui/src/formprincipal.h new file mode 100644 index 000000000..9f271323a --- /dev/null +++ b/libpgmodeler_ui/src/formprincipal.h @@ -0,0 +1,139 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FormPrincipal +# Descrição: Definição da classe que implementa o formulário principal do software, +# Reune e gerencia todas as classes das bibliotecas implementadas. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef FORM_PRINCIPAL_H +#define FORM_PRINCIPAL_H + +#include +#include "ui_formprincipal.h" +#include "modelowidget.h" +#include "formsobre.h" +#include "caixamensagem.h" +#include "formbasico.h" +#include "listaoperacoeswidget.h" +#include "visaoobjetoswidget.h" +#include "pgmodelerplugin.h" + +using namespace std; +//*********************************************************** +class FormPrincipal: public QMainWindow, public Ui::FormPrincipal { + Q_OBJECT + + private: + //Atributo estático e constante que guarda a versão atual do pgModeler + static const QString VERSAO_PGMODELER; + + //Timer de salvamento automático do modelo + QTimer tm_salvamento; + + //Dockwidget o qual exibe as operações executadas sobre os objetos + ListaOperacoesWidget *lista_oper; + + //Dockwidget o qual exibe todos os objetos do modelo em forma de árvore/lista + VisaoObjetosWidget *visao_objs; + + //Armazena a referência para o modelo atualmente aberto + ModeloWidget *modelo_atual; + + //Armazena o nome da operação atualmente selecionada + QLabel *nome_op; + + //Armazena o nome ícone da operação atualmente selecionada + QLabel *icone_op; + + //Título da janela principal + QString titulo_janela; + + //Armazena o intevalo de salvamento automático do modelo + int interv_salvar; + + //Mapa de plugins carregados + map plugins; + + //Sobrecarga do closeEvent(): Salva as configurações antes do encerramento do aplicativo + void closeEvent(QCloseEvent *); + + //Carrega os plugins no diretório plugins/ + void carregarPlugins(void); + + //Destrói todos os plugins carregados + void destruirPlugins(void); + + public: + FormPrincipal(QWidget *parent = 0, Qt::WindowFlags flags = 0); + ~FormPrincipal(void); + + private slots: + //Atualiza as definições da grade com base nas ações: Exibir Grade, Alin. Grade e Exibir limites + void definirOpcoesGrade(void); + + /* Adiciona um novo modelo, caso o parâmetro 'nome_arq' esteja preenchido, o pgModeler + tentará carregar o modelo especificado pelo arquivo */ + void adicionarNovoModelo(const QString &nome_arq=""); + + /* Atualiza o estado (ativo/inativo) dos botões das barras + de ferramentas de acordo com a ação de abertura ou + fechamento de modelo */ + void atualizarEstadoFerramentas(bool modelo_fechado=false); + void __atualizarEstadoFerramentas(void); + + /* Efetua a atualização dos dockwidgets de visão geral, + lista de operações e arvore de objetos */ + void atualizarDockWidgets(void); + void __atualizarDockWidgets(void); + + //Atualiza a referência ao modelo atual quando as abas de modelos são ativadas + void definirModeloAtual(void); + + /* Executa o fechamento do modelo atual, o parâmetro 'idx_modelo' pode ser usado + para fechar um modelo especificado por seu índice */ + void fecharModelo(int idx_modelo=-1); + + //Carrega um modelo a partir do disco + void carregarModelo(void); + + //Salva um determinado ModeloWidget + void salvarModelo(ModeloWidget *modelo=NULL); + + //Salva todos os modelos abertos + void salvarTodosModelos(void); + + //Imprime o modelo atual + void imprimirModelo(void); + + //Executa a exportação no modelo atual + void exportarModelo(void); + + //Atualiza os modelos abertos com as novas configurações + void atualizarModelos(void); + + //Aplica o zoom sobre o modelo atual + void aplicarZoom(void); + + //Exibe o pgModeler em tela cheia + void exibirTelaCheia(bool tela_cheixa); + + //Executa o plugin representado pela ação que disparou o slot + void executarPlugin(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/formsobre.cpp b/libpgmodeler_ui/src/formsobre.cpp new file mode 100644 index 000000000..4f3ae394f --- /dev/null +++ b/libpgmodeler_ui/src/formsobre.cpp @@ -0,0 +1,8 @@ +#include "formsobre.h" +//********************************************************** +FormSobre::FormSobre(QWidget *parent) : QWidget(parent) +{ + setupUi(this); + pgmodeler_ver_lbl->setText(trUtf8("Versão %1").arg(AtributosGlobais::VERSAO_PGMODELER)); +} +//********************************************************** diff --git a/libpgmodeler_ui/src/formsobre.h b/libpgmodeler_ui/src/formsobre.h new file mode 100644 index 000000000..82a92a9c0 --- /dev/null +++ b/libpgmodeler_ui/src/formsobre.h @@ -0,0 +1,42 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FormPrincipal +# Descrição: Definição da classe que implementa a caixa de informações do software. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef FORM_SOBRE_H +#define FORM_SOBRE_H + +#include +#include "ui_formsobre.h" +#include "atributosglobais.h" +//*********************************************************** +class FormSobre: public QWidget, public Ui::FormSobre { + Q_OBJECT + + private: + + public: + FormSobre(QWidget *parent = 0); + ~FormSobre(void){} + + private slots: +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/funcaoagregacaowidget.cpp b/libpgmodeler_ui/src/funcaoagregacaowidget.cpp new file mode 100644 index 000000000..70ba29eed --- /dev/null +++ b/libpgmodeler_ui/src/funcaoagregacaowidget.cpp @@ -0,0 +1,195 @@ +#include "funcaoagregacaowidget.h" +//*********************************************************** +FuncaoAgregacaoWidget::FuncaoAgregacaoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_FUNC_AGREGACAO) +{ + try + { + QGridLayout *grid=NULL; + Ui_FuncaoAgregacaoWidget::setupUi(this); + QSpacerItem *spacer=NULL; + QFrame *frame=NULL; + + //Cria um destacador de sintaxe no campo de condição inicial da função + destaque_cond=NULL; + destaque_cond=new DestaqueSintaxe(cond_inicial_txt, false); + destaque_cond->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + //Alocando os seletores de objetos (função e operador) que são atribuídos à função de agregação + sel_func_final=NULL; + sel_func_transicao=NULL; + sel_op_ordenacao=NULL; + + sel_func_final=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + sel_func_transicao=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + sel_op_ordenacao=new SeletorObjetoWidget(OBJETO_OPERADOR, true, this); + + //Alocando os widgets de configuração de tipo pgsql + tipo_entrada=NULL; + tipo_estado=NULL; + + tipo_entrada=new TipoPgSQLWidget(this, trUtf8("Tipo de Dados de Entrada")); + tipo_estado=new TipoPgSQLWidget(this, trUtf8("Tipo de Dado de Estado")); + + //Alocando a tabela de tipos de entrada da função de agregação. + tab_tipos_entrada=NULL; + tab_tipos_entrada=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + TabelaObjetosWidget::BTN_EDITAR_ITEM, true, this); + tab_tipos_entrada->definirNumColunas(1); + + //Adicionando os objetos recém alocados no layout do formulário + funcaoagregacao_grid->addWidget(sel_func_final,0,1,1,1); + funcaoagregacao_grid->addWidget(sel_func_transicao,1,1,1,1); + funcaoagregacao_grid->addWidget(sel_op_ordenacao,2,1,1,1); + + grid=new QGridLayout; + grid->setContentsMargins(2,2,2,2); + grid->addWidget(tipo_entrada,0,0); + grid->addWidget(tab_tipos_entrada,1,0); + tipos_entrada_estado_twg->widget(0)->setLayout(grid); + + grid=new QGridLayout; + spacer=new QSpacerItem(20, 1, QSizePolicy::Minimum, QSizePolicy::Expanding); + + grid->setContentsMargins(2,2,2,2); + grid->addWidget(tipo_estado,0,0); + grid->addItem(spacer,1,0); + tipos_entrada_estado_twg->widget(1)->setLayout(grid); + + //Gera o frame de informação sobre a criação de funções agregadas + frame=gerarFrameInformacao(trUtf8("Uma função de agregação que aceita os tipos tipoA e tipoB\ + como entrada e cujo tipo de estado seja tipo_estado, deve obedecer às seguintes regras:

\ +    • Função Final: void funcao_final(tipo_estado)
\ +    • Função Transição: tipo_estado funcao_transicao(tipo_estado, tipoA, tipoB)")); + funcaoagregacao_grid->addWidget(frame, funcaoagregacao_grid->count()+1, 0, 1, 2); + frame->setParent(this); + + configurarLayouFormulario(funcaoagregacao_grid, OBJETO_FUNC_AGREGACAO); + + janela_pai->setMinimumSize(600, 500); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(tab_tipos_entrada, SIGNAL(s_linhaAdicionada(int)), this, SLOT(manipularTipoDado(int))); + connect(tab_tipos_entrada, SIGNAL(s_linhaAtualizada(int)), this, SLOT(manipularTipoDado(int))); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void FuncaoAgregacaoWidget::hideEvent(QHideEvent *evento) +{ + sel_func_final->removerObjetoSelecionado(); + sel_func_transicao->removerObjetoSelecionado(); + sel_op_ordenacao->removerObjetoSelecionado(); + tab_tipos_entrada->removerLinhas(); + cond_inicial_txt->clear(); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void FuncaoAgregacaoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, FuncaoAgregacao *funcao_ag) +{ + unsigned qtd, i; + TipoPgSQL tipo; + + //Preenchendo os campos básicos do formulário com os atributos da função de agregação + ObjetoBaseWidget::definirAtributos(modelo,lista_op,funcao_ag); + + //Configurado o modelo de banco de dados referênciado pelos widget seletores + tipo_entrada->definirAtributos(tipo, modelo); + tipo_estado->definirAtributos(tipo, modelo); + sel_func_final->definirModelo(modelo); + sel_func_transicao->definirModelo(modelo); + sel_op_ordenacao->definirModelo(modelo); + + //Caso a função de agregação esteja alocada (sendo editada) + if(funcao_ag) + { + //Preenche os seletores de função e operador com as funções e operador configurados na função de agregação + sel_func_final->definirObjeto(funcao_ag->obterFuncao(FuncaoAgregacao::FUNCAO_FINAL)); + sel_func_transicao->definirObjeto(funcao_ag->obterFuncao(FuncaoAgregacao::FUNCAO_TRANSICAO)); + sel_op_ordenacao->definirObjeto(funcao_ag->obterOperadorOrdenacao()); + + //Exibe a expressão de condição inicial da função no formulário + cond_inicial_txt->setPlainText(QString::fromUtf8(funcao_ag->obterCondicaoInicial())); + + //Preenche a tabela de tipos de entrada com os tipos configurados na função de agregação + tab_tipos_entrada->blockSignals(true); + qtd=funcao_ag->obterNumTipoDados(); + + for(i=0; i < qtd; i++) + { + tab_tipos_entrada->adicionarLinha(); + tipo=funcao_ag->obterTipoDado(i); + tab_tipos_entrada->definirDadoLinha(QVariant::fromValue(tipo), i); + tab_tipos_entrada->definirTextoCelula(QString::fromUtf8(*tipo),i,0); + } + tab_tipos_entrada->blockSignals(false); + tab_tipos_entrada->limparSelecao(); + + //Configura o widget de tipo de estado marcando o tipo de dado configurado na função + tipo_estado->definirAtributos(funcao_ag->obterTipoEstado(), modelo); + } +} +//--------------------------------------------------------- +void FuncaoAgregacaoWidget::manipularTipoDado(int linha) +{ + TipoPgSQL tipo; + + //Obtém o tipo de dado configurado no widget de tipo de entrada + tipo=tipo_entrada->obterTipoPgSQL(); + //O tipo obtido é inserido na tabela e a linha correspondente guarda-o como dado interno + tab_tipos_entrada->definirDadoLinha(QVariant::fromValue(tipo), linha); + tab_tipos_entrada->definirTextoCelula(QString::fromUtf8(*tipo),linha,0); +} +//--------------------------------------------------------- +void FuncaoAgregacaoWidget::aplicarConfiguracao(void) +{ + try + { + FuncaoAgregacao *funcao_ag=NULL; + unsigned qtd, i; + + iniciarConfiguracao(); + + //Obtém a referência à função de agregação que está sendo editada/criada + funcao_ag=dynamic_cast(this->objeto); + + //Configura os atributos do mesmo com os valores definidos no formulário + funcao_ag->definirCondicaoInicial(cond_inicial_txt->toPlainText()); + funcao_ag->definirTipoEstado(tipo_estado->obterTipoPgSQL()); + + /* Remove todos os tipos de dados da função de agregação para inserir os + que estão na tabela de tipos de entrada */ + funcao_ag->removerTiposDado(); + qtd=tab_tipos_entrada->obterNumLinhas(); + + /* Obtém de cada linha da tabela de tipos de entrada o dado interno o qual é + uma instância da classe TipoPgSQL e que será atribuída à função de agregação + como tipo de dado de entrada */ + for(i=0; i < qtd; i++) + funcao_ag->adicionarTipoDado(tab_tipos_entrada->obterDadoLinha(i).value()); + + //Define as funções e operador obtendo tais objetos dos respectivos seletores + funcao_ag->definirFuncao(FuncaoAgregacao::FUNCAO_TRANSICAO, dynamic_cast(sel_func_transicao->obterObjeto())); + funcao_ag->definirFuncao(FuncaoAgregacao::FUNCAO_FINAL, dynamic_cast(sel_func_final->obterObjeto())); + funcao_ag->definirOperadorOrdenacao(dynamic_cast(sel_op_ordenacao->obterObjeto())); + + //Finaliza a configuração da função de agregação + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/funcaoagregacaowidget.h b/libpgmodeler_ui/src/funcaoagregacaowidget.h new file mode 100644 index 000000000..58b85205a --- /dev/null +++ b/libpgmodeler_ui/src/funcaoagregacaowidget.h @@ -0,0 +1,68 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FuncaoAgregacaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de funções de agregação. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef FUNCAO_AGREGADA_WIDGET_H +#define FUNCAO_AGREGADA_WIDGET_H + +#include +#include "objetobasewidget.h" +#include "ui_funcaoagregacaowidget.h" +#include "tipopgsqlwidget.h" +#include "tabelaobjetoswidget.h" +//*********************************************************** +class FuncaoAgregacaoWidget: public ObjetoBaseWidget, public Ui::FuncaoAgregacaoWidget { + Q_OBJECT + + private: //Widget de seleção de tipo de entrada da função + TipoPgSQLWidget *tipo_entrada, + //Widget de tipo de estado da função + *tipo_estado; + + /* Tabela de listagem de tipos de entrada da função. + Os elementos desta tabela são convertidos em TipoPgSQL e + atribuídos como tipos de entrada da função agregada */ + TabelaObjetosWidget *tab_tipos_entrada; + + //Destacador de sintaxe usado no campo de expressão condicional + DestaqueSintaxe *destaque_cond; + + //Seletores de funções e operador relacionados à função de agregação + SeletorObjetoWidget *sel_op_ordenacao, + *sel_func_final, + *sel_func_transicao; + + public: + FuncaoAgregacaoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, FuncaoAgregacao *funcao_ag); + + private slots: + void hideEvent(QHideEvent *); + + //Adiciona ou atualiza o tipo selecionado no widget 'tipo_entrada' à tabela de tipos de entrada + void manipularTipoDado(int linha); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/funcaowidget.cpp b/libpgmodeler_ui/src/funcaowidget.cpp new file mode 100644 index 000000000..a848cd5c6 --- /dev/null +++ b/libpgmodeler_ui/src/funcaowidget.cpp @@ -0,0 +1,670 @@ +#include "funcaowidget.h" +#include "parametrowidget.h" +extern ParametroWidget *parametro_wgt; +//*********************************************************** +FuncaoWidget::FuncaoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_FUNCAO) +{ + try + { + QStringList tipos; + QGridLayout *grid=NULL, *grid1=NULL; + map > mapa_campos; + QFrame *frame=NULL; + + Ui_FuncaoWidget::setupUi(this); + configurarLayouFormulario(funcao_grid, OBJETO_FUNCAO); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + //Aloca um destacador de código fonte para o campo de definição da função + destaque_codigo=new DestaqueSintaxe(codigofonte_txt, true); + + //Aloca o widget de configuração de tipo de retorno simples + tipo_ret=new TipoPgSQLWidget(this); + + /* Aloca a tabela que armazena as colunas da tabela de retorno. + Esta tabela possui 2 colunas que são o Nome da coluna e o tipo de dado */ + tab_retorno=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + TabelaObjetosWidget::BTN_ATUALIZAR_ITEM, true, this); + tab_retorno->definirNumColunas(2); + tab_retorno->definirRotuloCabecalho(trUtf8("Coluna"), 0); + tab_retorno->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + tab_retorno->definirRotuloCabecalho(trUtf8("Tipo"), 1); + tab_retorno->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + + /* Aloca a tabela que armazena os parâmetros da função. + Esta tabela possui 4 colunas que são: + Nome do parâmetro, tipo do parâmetro, comportamento do parâmetro (IN/OUT), + valor padrâo do parâmetro */ + tab_parametros=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + TabelaObjetosWidget::BTN_ATUALIZAR_ITEM, true, this); + tab_parametros->definirNumColunas(4); + tab_parametros->definirRotuloCabecalho(trUtf8("Nome"),0); + tab_parametros->definirIconeCabecalho(QPixmap(":/icones/icones/parameter.png"),0); + tab_parametros->definirRotuloCabecalho(trUtf8("Tipo"),1); + tab_parametros->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + tab_parametros->definirRotuloCabecalho(trUtf8("IN/OUT"),2); + tab_parametros->definirRotuloCabecalho(trUtf8("Valor Padrão"),3); + + grid=new QGridLayout; + grid->addWidget(tab_parametros,0,0,1,1); + grid->setContentsMargins(2,2,2,2); + funcaowidget_twg->widget(1)->setLayout(grid); + + grid=dynamic_cast(funcaowidget_twg->widget(0)->layout()); + grid->addWidget(tipo_ret, grid->count(), 0, 1, 4); + grid->addWidget(tabela_ret_gb, grid->count()-1, 0, 1, 4); + + grid1=new QGridLayout; + grid1->addWidget(tab_retorno, 0, 0, 1, 1); + grid1->setContentsMargins(2,2,2,2); + tabela_ret_gb->setLayout(grid1); + tabela_ret_gb->setVisible(false); + + //Define os campos exclusivos para cada versão + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(tabela_rb); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(func_janela_lbl); + + //Gera o frame de alerta + frame=gerarFrameAlertaVersao(mapa_campos); + grid->addWidget(frame, grid->count()+1, 0, 1, 0); + frame->setParent(funcaowidget_twg->widget(0)); + + janela_pai->setMinimumSize(600, 660); + + //Configura o combo de tipos de segurança da função + TipoSeguranca::obterTipos(tipos); + seguranca_cmb->addItems(tipos); + + //Configura o combo de tipo da função + TipoFuncao::obterTipos(tipos); + tipo_func_cmb->addItems(tipos); + + //Configura o combo de tipo de comportamento da função + TipoComportamento::obterTipos(tipos); + comportamento_cmb->addItems(tipos); + + connect(simples_rb, SIGNAL(clicked(bool)), this, SLOT(alternarTiposRetorno(void))); + connect(conjunto_rb, SIGNAL(clicked(bool)), this, SLOT(alternarTiposRetorno(void))); + connect(tabela_rb, SIGNAL(clicked(bool)), this, SLOT(alternarTiposRetorno(void))); + connect(linguagem_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(selecionarLinguagem(void))); + + connect(tab_parametros, SIGNAL(s_linhaAdicionada(int)), this, SLOT(exibirFormParametro())); + connect(tab_parametros, SIGNAL(s_linhaEditada(int)), this, SLOT(exibirFormParametro())); + connect(tab_retorno, SIGNAL(s_linhaAdicionada(int)), this, SLOT(exibirFormParametro())); + connect(tab_retorno, SIGNAL(s_linhaEditada(int)), this, SLOT(exibirFormParametro())); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void FuncaoWidget::manipularParametro(int res) +{ + int qtd_lin, lin; + QString str_aux; + TabelaObjetosWidget *tabela=NULL; + + /* Seleciona a tabela a ser manipulado o parâmetro de + * acordo com a visibilidade da mesma */ + if(tab_parametros->isVisible()) + //Seleciona a tabela de parâmetros caso esta esteja visível (em foco) + tabela=tab_parametros; + else + //Seleciona a tabela de retorno caso esta esteja visível (em foco) + tabela=tab_retorno; + + //Obtém a quantidade de linhas da tabela selecionada + qtd_lin=tabela->obterNumLinhas(); + + //Caso o usuário clique no botão 'aplicar' da janela de conf. de parâmetro + if(res==QDialog::Accepted) + { + //Obtém a linha selecionada da tabela. + lin=tabela->obterLinhaSelecionada(); + + /* Caso o índice da linha seja negativo indica que a linha em + questão está vazia, ou seja, o usuário não está editando + uma linha existente e sim adicionando uma nova, sendo assim + a linha a ser considerada na tabela sempre será a última recentemente + incluída */ + if(lin < 0) lin=qtd_lin-1; + + /* Exibe os dados do parâmetro configurado no formulário de prâmetros + na tabela selecionada na linha selecionada */ + exibirDadosParametro(parametro_wgt->obterParametro(), tabela, lin); + } + //Caso o usuário clique no botão 'cancelar' da janela de conf. de parâmetro + else if(res==QDialog::Rejected) + { + //Remove a última linha da tabela quando se tratar de adição de novo parâmetro + if(qtd_lin > 0 && tabela->obterTextoCelula(qtd_lin-1,0).isEmpty()) + tabela->removerLinha(qtd_lin-1); + } +} +//---------------------------------------------------------- +void FuncaoWidget::exibirFormParametro(void) +{ + QObject *obj_sender=sender(); + TabelaObjetosWidget *tabela=NULL; + Parametro param_aux; + int idx_lin; + + /* O formulário de conf. de parâmetro só será exibido + se o sender for uma das tabelas de parâmetros */ + if(obj_sender==tab_parametros || obj_sender==tab_retorno) + { + tabela=dynamic_cast(obj_sender); + + /* Desabilita alguns campos do formulário de parâmetro quando + se tratar de um parametro da tabela de retorno da função, + pois são atributos não usados na declaração SQL */ + parametro_wgt->param_in_chk->setEnabled(obj_sender==tab_parametros); + parametro_wgt->param_out_chk->setEnabled(obj_sender==tab_parametros); + parametro_wgt->valorpadrao_edt->setEnabled(obj_sender==tab_parametros); + + //Obtém a linha selecionada da tabela + idx_lin=tabela->obterLinhaSelecionada(); + + /* Caso haja uma linha selecionada obtém o parâmetro daquela linha + para que seus dados sejam exibidos no formulário de manipulação + de parâmetro */ + if(idx_lin >= 0 && !tabela->obterTextoCelula(idx_lin, 0).isEmpty()) + param_aux=obterParametro(tabela, idx_lin); + + //Exibe o formulário de parâmetros + parametro_wgt->definirAtributos(param_aux, modelo); + parametro_wgt->show(); + } +} +//---------------------------------------------------------- +Parametro FuncaoWidget::obterParametro(TabelaObjetosWidget *tab, unsigned idx_lin) +{ + Parametro param; + QString str_aux; + + if(tab) + { + try + { + /* Configura o nome do parâmetro com o texto da coluna de nome + da linha especificada da tabela */ + param.definirNome(tab->obterTextoCelula(idx_lin,0)); + + //Configura o tipo do parâmetro com o tipo armazenado na linha atual da tabela + param.definirTipo(tab->obterDadoLinha(idx_lin).value()); + + //Obtendo informações específicas quando se trata da tabela de parâmetros + if(tab==tab_parametros) + { + //Marcando se o parâmetro é de entrada/saída de acordo com o texto da coluna da tabela + str_aux=tab->obterTextoCelula(idx_lin, 2); + param.definirEntrada(str_aux.contains("IN")); + param.definirSaida(str_aux.contains("OUT")); + + //Configura o valor padrâo do parâmetro + param.definirValorPadrao(tab->obterTextoCelula(idx_lin,3)); + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } + + return(param); +} +//---------------------------------------------------------- +void FuncaoWidget::exibirDadosParametro(Parametro param, TabelaObjetosWidget *tab, unsigned idx_lin) +{ + if(tab) + { + QString str_aux; + + /* Para as duas tabelas (tab_parametros ou tab_retorno) as duas primeiras colunas + são destinadas, respectivamente, ao nome e tipo do parâmetro */ + tab->definirTextoCelula(QString::fromUtf8(param.obterNome()),idx_lin,0); + tab->definirTextoCelula(QString::fromUtf8(*param.obterTipo()),idx_lin,1); + + /* Armazena na linha da tabela uma cópia do tipo do parâmetro. + Isso é usado pelo método obterParametro() quando o usuário + solicita obter um parâmetro a partir de um a linha da tabela */ + tab->definirDadoLinha(QVariant::fromValue(param.obterTipo()), idx_lin); + + /* Caso a tabela passada seja a de parâmetro configura as demais + colunas com os demais atributos do parâmetro */ + if(tab==tab_parametros) + { + //Exibe se o parâmetro é de entrada/saída + if(param.parametroEntrada()) str_aux="IN"; + if(param.parametroSaida()) str_aux+="OUT"; + tab->definirTextoCelula(str_aux,idx_lin,2); + + //Exibe o valor padrão do parâmetro + tab->definirTextoCelula(QString::fromUtf8(param.obterValorPadrao()),idx_lin,3); + } + } +} +//---------------------------------------------------------- +void FuncaoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Funcao *funcao) +{ + vector linguagens; + Linguagem *ling=NULL; + QStringList lista; + unsigned qtd=0, i; + Parametro param; + QString str_aux; + TipoPgSQL tipo_aux; + + connect(parametro_wgt, SIGNAL(finished(int)), this, SLOT(manipularParametro(int))); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, funcao); + +//Obtém todas as linguagens criadas no modelo para armazená-las num combo + linguagens=modelo->obterObjetos(OBJETO_LINGUAGEM); + + //Caso existam linguagens insere-as numa QStringList para ordená-las alfabeticamente + while(!linguagens.empty()) + { + ling=dynamic_cast(linguagens.back()); + linguagens.pop_back(); + lista.append(ling->obterNome()); + } + + //Ordena e insere as linguagens num combobox + lista.sort(); + linguagem_cmb->addItems(lista); + + if(funcao) + { + tipo_aux=funcao->obterTipoRetorno(); + + //Seleciona no combobox a linguagem configurada para a função + linguagem_cmb->setCurrentIndex(linguagem_cmb->findText(funcao->obterLinguagem()->obterNome())); + + //Seleciona no combobox o tipo da função + tipo_func_cmb->setCurrentIndex(tipo_func_cmb->findText(~funcao->obterTipoFuncao())); + + //Marca o checkbox se a função é janela ou não de acordo com o configurado na instância de função + func_janela_chk->setChecked(funcao->funcaoJanela()); + + //Exibe o custo de execução da função no formulário + custo_exec_spb->setValue(funcao->obterCustoExecucao()); + + //Exibe a quantidade de linhas retornadas pela função + linhas_ret_sbp->setValue(funcao->obterQuantidadeLinhas()); + + //Seleciona no combo o comportamento da função de acordo com o configurado na instância + comportamento_cmb->setCurrentIndex(comportamento_cmb->findText(~funcao->obterTipoComportamento())); + + //Seleciona no combo tipo de segurança da função de acordo com o configurado na instância + seguranca_cmb->setCurrentIndex(seguranca_cmb->findText(~funcao->obterTipoSeguranca())); + + //Configura no formulário o tipo de retorno da função + //Caso a função retorne um conjunto de dados marca o radiobox respecitivo + if(funcao->retornaSetOf()) + conjunto_rb->setChecked(true); + /* Caso a função retorna uma tabela marca o radiobox respectivo isso + também faz com que o widget que armazena os detalhes da tabela de + retorno seja exibido */ + else if(funcao->retornaTabela()) + tabela_rb->setChecked(true); + else + simples_rb->setChecked(true); + + //Obtém o número de parâmetros da função + qtd=funcao->obterNumParams(); + + + /* Bloqueia os sinais dos widgets de tabela para evitar o disparo + de sinais e execução de slots. Isso é feito pois no preenchimento do + formulário através do método definirAtributos() não é necessário + executar os slots ligados a estas duas tabelas, isso deve acontecer + somente quando o usuário interagir (via mouse ou teclado) com + esses widgets */ + tab_parametros->blockSignals(true); + tab_retorno->blockSignals(true); + + //Preenche a tabela de parâmetros com os parâmetros da função + for(i=0; i < qtd; i++) + { + tab_parametros->adicionarLinha(); + param=funcao->obterParametro(i); + exibirDadosParametro(param,tab_parametros,i); + } + tab_parametros->limparSelecao(); + + /* Obtém a quantidade de colunas na tabela de retorno. + caso exista algum a tabela é exibida e as colunas + da tabela de retorno da função exibidas */ + qtd=funcao->obterNumTiposRetTabela(); + if(qtd > 0) + { + tabela_ret_gb->setVisible(true); + tipo_ret->setVisible(false); + + //Exibindo as colunas da tabela de retorno no widget + for(i=0; i < qtd; i++) + { + tab_retorno->adicionarLinha(); + param=funcao->obterTipoRetTabela(i); + exibirDadosParametro(param,tab_retorno,i); + } + } + tab_retorno->limparSelecao(); + + + //Caso a função referencie (esteja definida) uma biblioteca + if(!funcao->obterBiblioteca().isEmpty()) + { + //Exibe o nome do símbolo e caminho para a biblioteca no sistema de arquivos + simbolo_edt->setText(funcao->obterSimbolo()); + biblioteca_edt->setText(funcao->obterBiblioteca()); + } + //Caso a função esteja definida por um código fonte + else + { + //Exibe o código fonte da função na caixa de destaque de código fonte + codigofonte_txt->setPlainText(QString::fromUtf8(funcao->obterCodigoFonte())); + } + + /* Desbloqueia os sinais dos widgets de tabela para que o usuário possa + interagir com estes */ + tab_parametros->blockSignals(false); + tab_retorno->blockSignals(false); + } + + tipo_ret->definirAtributos(tipo_aux, modelo); +} +//---------------------------------------------------------- +void FuncaoWidget::hideEvent(QHideEvent *evento) +{ + linguagem_cmb->clear(); + tab_parametros->removerLinhas(); + tab_retorno->removerLinhas(); + codigofonte_txt->clear(); + simbolo_edt->clear(); + biblioteca_edt->clear(); + funcaowidget_twg->setCurrentIndex(0); + disconnect(parametro_wgt,NULL, this, NULL); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void FuncaoWidget::alternarTiposRetorno(void) +{ + QObject *obj_sender=sender(); + tabela_ret_gb->setVisible(obj_sender==tabela_rb); + tipo_ret->setVisible(!tabela_ret_gb->isVisible()); +} +//---------------------------------------------------------- +void FuncaoWidget::selecionarLinguagem(void) +{ + bool ling_c; + + ling_c=(linguagem_cmb->currentText()==~TipoLinguagem(TipoLinguagem::c)); + codigofonte_frm->setVisible(!ling_c); + biblioteca_frm->setVisible(ling_c); + + if(!ling_c) + { + try + { + destaque_codigo->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + linguagem_cmb->currentText() + + AtributosGlobais::SUF_ARQ_DESTAQUE + + AtributosGlobais::EXT_CONFIGURACAO); + } + catch(Excecao &e) + { + destaque_codigo->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + } + + destaque_codigo->rehighlight(); + } +} +//---------------------------------------------------------- +void FuncaoWidget::validarFuncaoConfigurada(void) +{ + vector *lista_obj; + vector::iterator itr, itr_end; + ConversaoCodificacao *conv_cod=NULL; + ConversaoTipo *conv_tipo=NULL; + FuncaoAgregacao *func_ag=NULL; + Gatilho *gatilho=NULL; + Linguagem *ling=NULL; + Operador *oper=NULL; + Tipo *tipo=NULL; + Tabela *tab=NULL; + Funcao *funcao=NULL; + ObjetoBase *objeto=NULL; + unsigned i, i1, qtd; + + //Vetor de tipos de objetos os quais referenciam direta/indiretamente a função + TipoObjetoBase tipos[7]={ OBJETO_CONV_CODIFICACAO, OBJETO_CONV_TIPO, + OBJETO_FUNC_AGREGACAO, OBJETO_TABELA, + OBJETO_LINGUAGEM, OBJETO_OPERADOR, OBJETO_TIPO }; + + //Obtém a referência para a função recém configurada + funcao=dynamic_cast(this->objeto); + + try + { + for(i=0; i < 7; i++) + { + //Obtém a lista de objetos do tipo atual + lista_obj=modelo->obterListaObjetos(tipos[i]); + itr=lista_obj->begin(); + itr_end=lista_obj->end(); + + while(itr!=itr_end) + { + objeto=(*itr); + itr++; + + /* A validação da função se dá da seguinte forma: + > Para cada tipo de objeto constante no vetor 'tipos' + é obtida a lista de objetos. + Caso haja elementos nesta lista, a função é atribuída + a cada elemento e internamente nestes elementos a função + e validada de acordo com o exigido por cada classe. + + Caso a função seja inválida as instâncias dispararão + exceções acusando o erro isso é o suficiente para verificar + a validade da função em relação aos objetos que a referenciam. */ + if(tipos[i]==OBJETO_CONV_CODIFICACAO) + { + conv_cod=dynamic_cast(objeto); + if(conv_cod->obterFuncaoConversao()==funcao) + conv_cod->definirFuncaoConversao(funcao); + } + else if(tipos[i]==OBJETO_CONV_TIPO) + { + conv_tipo=dynamic_cast(objeto); + if(conv_tipo->obterFuncaoConversao()==funcao) + conv_tipo->definirFuncaoConversao(funcao); + } + else if(tipos[i]==OBJETO_FUNC_AGREGACAO) + { + func_ag=dynamic_cast(objeto); + if(func_ag->obterFuncao(FuncaoAgregacao::FUNCAO_FINAL)==funcao) + func_ag->definirFuncao(FuncaoAgregacao::FUNCAO_FINAL, funcao); + else if(func_ag->obterFuncao(FuncaoAgregacao::FUNCAO_TRANSICAO)==funcao) + func_ag->definirFuncao(FuncaoAgregacao::FUNCAO_TRANSICAO, funcao); + } + /* A única validação diferente é para gatilhos, como gatilhos são objetos, + internos das tabelas, primeiro são obtidas as tabelas e em seguida + com cada instância a função será validada com os gatilhos constantes + nas tabelas */ + else if(tipos[i]==OBJETO_TABELA) + { + tab=dynamic_cast(objeto); + qtd=tab->obterNumGatilhos(); + + for(i1=0; i1 < qtd; i1++) + { + gatilho=tab->obterGatilho(i1); + if(gatilho->obterFuncao()==funcao) + gatilho->definirFuncao(funcao); + } + } + else if(tipos[i]==OBJETO_LINGUAGEM) + { + ling=dynamic_cast(objeto); + + for(i1=Linguagem::FUNC_VALIDATOR; i1 <= Linguagem::FUNC_INLINE; i1++) + { + if(ling->obterFuncao(i1)==funcao) + ling->definirFuncao(funcao, i1); + } + } + else if(tipos[i]==OBJETO_OPERADOR) + { + oper=dynamic_cast(objeto); + for(i1=Operador::FUNC_OPERADOR; i1 <= Operador::FUNC_RESTRICAO; i1++) + { + if(oper->obterFuncao(i1)==funcao) + oper->definirFuncao(funcao, i1); + } + } + else if(tipos[i]==OBJETO_TIPO) + { + tipo=dynamic_cast(objeto); + if(tipo->obterConfiguracao()==Tipo::TIPO_BASE) + { + for(i1=Tipo::FUNCAO_INPUT; i1 <=Tipo::FUNCAO_ANALYZE; i1++) + { + if(tipo->obterFuncao(i1)==funcao) + tipo->definirFuncao(i1, funcao); + } + } + } + } + } + } + catch(Excecao &e) + { + //Caso alguma validação acima dispare um erro o mesmo é redirecionado + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_CONFFUNCINVALIDAOBJ) + .arg(objeto->obterNome(true)) + .arg(objeto->obterNomeTipoObjeto()), + ERR_PGMODELERUI_CONFFUNCINVALIDAOBJ, + __PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void FuncaoWidget::aplicarConfiguracao(void) +{ + try + { + Funcao *func=NULL; + unsigned qtd, i; + Parametro param; + QString str_aux; + + //Inicia a configuração da função + iniciarConfiguracao(); + + //Faz a conversão do objeto editado (genérico) para o tipo função + func=dynamic_cast(this->objeto); + + //Atribui os valores básicos configurados no formulário para a função + func->definirLinguagem(modelo->obterObjeto(linguagem_cmb->currentText(), OBJETO_LINGUAGEM)); + func->definirTipoFuncao(tipo_func_cmb->currentText()); + func->definirFuncaoJanela(func_janela_chk->isChecked()); + func->definirCustoExecucao(custo_exec_spb->value()); + func->definirQuantidadeLinhas(linhas_ret_sbp->value()); + func->definirTipoComportamento(comportamento_cmb->currentText()); + func->definirTipoSeguranca(seguranca_cmb->currentText()); + + /* Remove todos os parâmetros da função para adicionar os que foram + configurados no formulário */ + func->removerParametros(); + + //Obtém a quantidade de parâmetros configurados no formulário + qtd=tab_parametros->obterNumLinhas(); + + for(i=0; i < qtd; i++) + { + /* Cria um parâmetro auxiliar e os configura de acordo com os valores + do parâmetro atual (i) na tabela */ + param.definirNome(tab_parametros->obterTextoCelula(i,0)); + param.definirTipo(tab_parametros->obterDadoLinha(i).value()); + + str_aux=tab_parametros->obterTextoCelula(i,2); + param.definirEntrada(str_aux.indexOf("IN") >= 0); + param.definirSaida(str_aux.indexOf("OUT") >= 0); + + param.definirValorPadrao(tab_parametros->obterTextoCelula(i,3)); + + //Uma vez configurado esse parâmetro e inserido na função + func->adicionarParametro(param); + } + + + /* Caso a linguagem selecionada no formulário for a C + indica que a função está definida em uma biblioteca externa + para tanto os valores dos campos biblioteca e simbolo + serão atribuídos à função que está sendo configurada */ + if(linguagem_cmb->currentText()==~TipoLinguagem(TipoLinguagem::c)) + { + func->definirBiblioteca(biblioteca_edt->text()); + func->definirSimbolo(simbolo_edt->text()); + } + /* Caso a linguagem seja diferente de C atribui o código fonte + definido no destacador de código do formulário */ + else + func->definirCodigoFonte(codigofonte_txt->toPlainText()); + + //Caso o tipo de retorno configurado no formulário seja simples ou conjunto + if(simples_rb->isChecked() || conjunto_rb->isChecked()) + { + /* Define o tipo de retorno da função obtendo o tipo definido no widget de + configuração de tipos pgsql */ + func->definirTipoRetorno(tipo_ret->obterTipoPgSQL()); + + /* Marca na função se a mesma retorna um conjunto de dados de acordo + com o estado do radiobox 'conjunto_rb' */ + func->definirRetornaSetOf(conjunto_rb->isChecked()); + } + //Caso a função retorna uma tabela, a mesma é atribuída à função + else + { + func->removerTiposRetTabela(); + qtd=tab_retorno->obterNumLinhas(); + + /* Adiciona uma coluna na tabela de retorno com os dados configurados na tabela + respectiva do formulário */ + for(i=0; iadicionarTipoRetTabela(tab_retorno->obterTextoCelula(i,0), + tab_retorno->obterDadoLinha(i).value()); + } + } + + //Finaliza a configuração da função + ObjetoBaseWidget::aplicarConfiguracao(); + + /* Executa a validação da função em relação aos objetos das classes + ConversaoCodificacao, ConversaoTipo, ElemClasseOperadores, FuncaoAgregada, + Gatilho, Linguagem, Operador, Tipo */ + validarFuncaoConfigurada(); + + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/funcaowidget.h b/libpgmodeler_ui/src/funcaowidget.h new file mode 100644 index 000000000..a52256914 --- /dev/null +++ b/libpgmodeler_ui/src/funcaowidget.h @@ -0,0 +1,84 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: FuncaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de funções. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef FUNCAO_WIDGET_H +#define FUNCAO_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_funcaowidget.h" +#include "tipopgsqlwidget.h" +#include "tabelaobjetoswidget.h" +//*********************************************************** +class FuncaoWidget: public ObjetoBaseWidget, public Ui::FuncaoWidget { + Q_OBJECT + + private: + /* Destaque de código-fonte usado para destacar o código da função + definido pelo usuário */ + DestaqueSintaxe *destaque_codigo; + + //Widget de tipo Pgsql usado para configurar o tipo de retorno da função + TipoPgSQLWidget *tipo_ret; + + //Tabela que representa a tabela de retorno da função + TabelaObjetosWidget *tab_retorno, + //Tabela de parâmetros da função + *tab_parametros; + + //Converte os dados da linha da tabela informada em um parâmetro + Parametro obterParametro(TabelaObjetosWidget *tab, unsigned idx_lin); + + //Exibe os dados do parâmetro na tabela e linha selecionadas + void exibirDadosParametro(Parametro param, TabelaObjetosWidget *tab, unsigned idx_lin); + + /* Valida a nova configuração da função em relação a demais objetos que a referenciam. + A exemplo disso temos objetos das classes ConversaoCodificacao, ConversaoTipo, + FuncaoAgregada, Gatilho, Linguagem, Operador, Tipo */ + void validarFuncaoConfigurada(void); + + public: + FuncaoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Funcao *funcao); + + private slots: + void alternarTiposRetorno(void); + + /* Seleciona a linguagem de definição da função, e caso disponível, + carrega o arquivo de destaque de sintaxe referênte à linguagem + selecionada */ + void selecionarLinguagem(void); + + //Exibe a janela de configuração de parâmetros + void exibirFormParametro(void); + + /* Manipula um parâmetro que foi configurado pelo form. de parâmetro + exibindo seus dados na tabela da parâmetros correta */ + void manipularParametro(int); + + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/gatilhowidget.cpp b/libpgmodeler_ui/src/gatilhowidget.cpp new file mode 100644 index 000000000..2cf2462ac --- /dev/null +++ b/libpgmodeler_ui/src/gatilhowidget.cpp @@ -0,0 +1,329 @@ +#include "gatilhowidget.h" +//*********************************************************** +GatilhoWidget::GatilhoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_GATILHO) +{ + try + { + QStringList lista; + map > mapa_campos; + map > mapa_valores; + QFrame *frame=NULL; + + Ui_GatilhoWidget::setupUi(this); + + //Cria um destacador de sintaxe no campo de expressão de checagem + dest_exp_condicional=new DestaqueSintaxe(exp_condicional_txt, false); + dest_exp_condicional->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + //Aloca as tabelas que recebem as colunas usadas na restrição + tab_colunas=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + (TabelaObjetosWidget::BTN_EDITAR_ITEM | + TabelaObjetosWidget::BTN_ATUALIZAR_ITEM), true, this); + + tab_argumentos=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES, true, this); + + //Alocando seletor de tabela referenciada + sel_tabela_ref=new SeletorObjetoWidget(OBJETO_TABELA, true, this); + sel_funcao=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + gatilho_grid->addWidget(sel_funcao, 5, 1, 1, 2); + gatilho_grid->addWidget(sel_tabela_ref, 6, 1, 1, 2); + + //Configurando as tabelas com 2 colunas (nome da coluna e tipo) + tab_colunas->definirNumColunas(2); + tab_colunas->definirRotuloCabecalho(trUtf8("Coluna"), 0); + tab_colunas->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + tab_colunas->definirRotuloCabecalho(trUtf8("Tipo"), 1); + tab_colunas->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + + dynamic_cast(arg_cols_tbw->widget(0)->layout())->addWidget(tab_colunas, 1,0,1,3); + dynamic_cast(arg_cols_tbw->widget(1)->layout())->addWidget(tab_argumentos, 1,0,1,3); + + //Configurando o combo de tipo de postergação com os tipos disponíveis + TipoPostergacao::obterTipos(lista); + tipo_postergacao_cmb->addItems(lista); + + //Configurando o combo de tipo disparo com os tipos disponíveis + TipoDisparo::obterTipos(lista); + tipo_disparo_cmb->addItems(lista); + + //Define os campos exclusivos para cada versão + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(truncate_chk); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_90)].push_back(exp_condicional_lbl); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_90)].push_back(coluna_lbl); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_91)].push_back(tipo_disparo_lbl); + mapa_valores[tipo_disparo_lbl].push_back(tipo_disparo_cmb->itemText(tipo_disparo_cmb->count()-1)); + + //Gera o frame de alerta + frame=gerarFrameAlertaVersao(mapa_campos, &mapa_valores); + gatilho_grid->addWidget(frame, gatilho_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + configurarLayouFormulario(gatilho_grid, OBJETO_GATILHO); + janela_pai->setMinimumSize(600, 640); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(postergavel_chk, SIGNAL(toggled(bool)), tipo_postergacao_cmb, SLOT(setEnabled(bool))); + connect(postergavel_chk, SIGNAL(toggled(bool)), tipo_postergacao_lbl, SLOT(setEnabled(bool))); + connect(tab_colunas, SIGNAL(s_linhaAdicionada(int)), this, SLOT(adicionarColuna(int))); + connect(tab_colunas, SIGNAL(s_linhaRemovida(int)), this, SLOT(atualizarComboColunas(void))); + connect(tab_colunas, SIGNAL(s_linhasRemovidas(void)), this, SLOT(atualizarComboColunas(void))); + connect(tab_argumentos, SIGNAL(s_linhaAdicionada(int)), this, SLOT(manipularArgumento(int))); + connect(tab_argumentos, SIGNAL(s_linhaAtualizada(int)), this, SLOT(manipularArgumento(int))); + connect(tab_argumentos, SIGNAL(s_linhaEditada(int)), this, SLOT(editarArgumento(int))); + connect(gat_rest_chk, SIGNAL(toggled(bool)), this, SLOT(definirGratilhoRestricao(bool))); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void GatilhoWidget::definirGratilhoRestricao(bool valor) +{ + exec_por_linha_chk->setEnabled(!valor); + exec_por_linha_chk->setChecked(valor); + sel_tabela_ref->setEnabled(valor); + if(!valor) + sel_tabela_ref->removerObjetoSelecionado(); +} +//---------------------------------------------------------- +void GatilhoWidget::adicionarColuna(int idx_lin) +{ + Coluna *coluna=NULL; + + try + { + //Obtém a referência à coluna no item atual do combo box + coluna=reinterpret_cast(coluna_cmb->itemData(coluna_cmb->currentIndex(),Qt::UserRole).value()); + //Quando a coluna vai ser atribuída a tabela a mesma é removida do combo + coluna_cmb->removeItem(coluna_cmb->currentIndex()); + //Adiciona a coluna à tabela + adicionarColuna(coluna, idx_lin); + //Caso não houver itens no combo o botão de inserção da respectiva tabela será desabilitado + tab_colunas->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, (coluna_cmb->count()!=0)); + } + catch(Excecao &e) + { + tab_colunas->removerLinha(idx_lin); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void GatilhoWidget::adicionarColuna(Coluna *coluna, int idx_lin) +{ + //Caso a coluna esteja alocada e o índice da linha seja válido (não-negativo) + if(coluna && idx_lin >= 0) + { + /* Exibe os dados da coluna na linha especificada, definindo a referência à coluna + como dado da linha */ + tab_colunas->definirTextoCelula(QString::fromUtf8(coluna->obterNome()),idx_lin,0); + tab_colunas->definirTextoCelula(QString::fromUtf8(~coluna->obterTipo()),idx_lin,1); + tab_colunas->definirDadoLinha(QVariant::fromValue(coluna), idx_lin); + } +} +//---------------------------------------------------------- +void GatilhoWidget::atualizarComboColunas(void) +{ + Coluna *coluna=NULL; + unsigned i, qtd_col=0; + + try + { + qtd_col=tabela->obterNumColunas(); + coluna_cmb->clear(); + + for(i=0; i < qtd_col; i++) + { + coluna=tabela->obterColuna(i); + + /* Insere a coluna no combo somente a mesma não existir na tabela, + essa checagem é feita tentando se obter o índice da linha na tabela + a qual possui a coluna, caso esse índice seja negativo indica que a + coluna não está presente na tabela */ + if(tab_colunas->obterIndiceLinha(QVariant::fromValue(coluna)) < 0) + { + coluna_cmb->addItem(QString::fromUtf8(coluna->obterNome()) + " (" + ~coluna->obterTipo() +")", + QVariant::fromValue(coluna)); + } + } + //Desabilita o obtão de inserir itens na tabela caso não hajam itens no combobox + tab_colunas->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, (coluna_cmb->count()!=0)); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void GatilhoWidget::manipularArgumento(int idx_lin) +{ + //Caso o argumento esteja preenchido + if(!argumento_edt->text().isEmpty()) + { + //Insere o nome na tabela e limpa o campo de nome + tab_argumentos->definirTextoCelula(argumento_edt->text(), idx_lin, 0); + argumento_edt->clear(); + } + else if(tab_argumentos->obterTextoCelula(idx_lin, 0).isEmpty()) + /* Remove a linha inserida para que a tabela não fique com + uma linha em branco */ + tab_argumentos->removerLinha(idx_lin); +} +//---------------------------------------------------------- +void GatilhoWidget::editarArgumento(int idx_lin) +{ + argumento_edt->setText(tab_argumentos->obterTextoCelula(idx_lin, 0)); +} +//---------------------------------------------------------- +void GatilhoWidget::hideEvent(QHideEvent *evento) +{ + ObjetoBaseWidget::hideEvent(evento); + + exp_condicional_txt->clear(); + coluna_cmb->clear(); + argumento_edt->clear(); + + postergavel_chk->setChecked(false); + tipo_disparo_cmb->setCurrentIndex(0); + tipo_postergacao_cmb->setCurrentIndex(0); + + tab_colunas->blockSignals(true); + tab_argumentos->blockSignals(true); + tab_colunas->removerLinhas(); + tab_argumentos->removerLinhas(); + tab_colunas->blockSignals(false); + tab_argumentos->blockSignals(false); + + insert_chk->setChecked(false); + update_chk->setChecked(false); + delete_chk->setChecked(false); + truncate_chk->setChecked(false); + + sel_funcao->removerObjetoSelecionado(); + sel_tabela_ref->removerObjetoSelecionado(); +} +//---------------------------------------------------------- +void GatilhoWidget::definirAtributos(ModeloBD *modelo, Tabela *tabela_pai, ListaOperacoes *lista_op, Gatilho *gatilho) +{ + unsigned qtd=0, i; + Coluna *coluna=NULL; + + if(!tabela_pai) + throw Excecao(ERR_PGMODELER_ATROBJNAOALOC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, gatilho, tabela_pai); + + //Define o modelo de banco de dados dos seletores de objetos + sel_tabela_ref->definirModelo(modelo); + sel_funcao->definirModelo(modelo); + + //Caso a restrição esteja alocada (sendo editada) + if(gatilho) + { + //Preenche os demais campos do formulário com os valores presentes na instância da restrição + gat_rest_chk->setChecked(gatilho->obterTabReferenciada()); + exp_condicional_txt->setPlainText(QString::fromUtf8(gatilho->obterCondicao())); + postergavel_chk->setChecked(gatilho->gatilhoPostergavel()); + tipo_postergacao_cmb->setCurrentIndex(tipo_postergacao_cmb->findText(~gatilho->obterTipoPostergacao())); + tipo_disparo_cmb->setCurrentIndex(tipo_disparo_cmb->findText(~gatilho->obterTipoDisparo())); + + insert_chk->setChecked(gatilho->executaNoEvento(TipoEvento::on_insert)); + delete_chk->setChecked(gatilho->executaNoEvento(TipoEvento::on_delete)); + update_chk->setChecked(gatilho->executaNoEvento(TipoEvento::on_update)); + truncate_chk->setChecked(gatilho->executaNoEvento(TipoEvento::on_truncate)); + sel_tabela_ref->definirObjeto(gatilho->obterTabReferenciada()); + sel_funcao->definirObjeto(gatilho->obterFuncao()); + + tab_colunas->blockSignals(true); + tab_argumentos->blockSignals(true); + + //Adicionando as colunas referenciadas pelo gatilho na tabela do formulário + qtd=gatilho->obterNumColunas(); + for(i=0; i < qtd; i++) + { + coluna=gatilho->obterColuna(i); + //Adiciona uma linha na tabela e adiciona a coluna + tab_colunas->adicionarLinha(); + adicionarColuna(coluna, i); + } + + qtd=gatilho->obterNumArgs(); + for(i=0; i < qtd; i++) + { + //Adiciona uma linha na tabela e adiciona o argumento + tab_argumentos->adicionarLinha(); + tab_argumentos->definirTextoCelula(gatilho->obterArgumento(i), i, 0); + } + + tab_colunas->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, (coluna_cmb->count()!=0)); + tab_argumentos->blockSignals(false); + tab_colunas->blockSignals(false); + } + + //Atualiza o combo de colunas com as colunas restantes da tabela pai + atualizarComboColunas(); +} +//---------------------------------------------------------- +void GatilhoWidget::aplicarConfiguracao(void) +{ + try + { + Gatilho *gatilho=NULL; + unsigned i, qtd; + Coluna *coluna=NULL; + + iniciarConfiguracao(); + + //Obtém a referência ao gatilho que está sendo criado/editado + gatilho=dynamic_cast(this->objeto); + + //Configura no gatilhos todos os atributos preenchidos no formulário + gatilho->definirTipoDisparo(TipoDisparo(tipo_disparo_cmb->currentText())); + gatilho->executarPorLinha(exec_por_linha_chk->isChecked()); + gatilho->definirPostergavel(postergavel_chk->isChecked()); + gatilho->definirTipoPostergacao(TipoPostergacao(tipo_postergacao_cmb->currentText())); + gatilho->definirCondicao(exp_condicional_txt->toPlainText()); + gatilho->definirFuncao(dynamic_cast(sel_funcao->obterObjeto())); + gatilho->definirTabReferenciada(dynamic_cast(sel_tabela_ref->obterObjeto())); + gatilho->definirEvento(TipoEvento::on_insert, insert_chk->isChecked()); + gatilho->definirEvento(TipoEvento::on_update, update_chk->isChecked()); + gatilho->definirEvento(TipoEvento::on_delete, delete_chk->isChecked()); + gatilho->definirEvento(TipoEvento::on_truncate, truncate_chk->isChecked()); + + /* Remove todas as colunas e argumentos para inserir aqueles + configurados no formulário */ + gatilho->removerArgumentos(); + gatilho->removerColunas(); + + //Adiciona os argumentos + qtd=tab_argumentos->obterNumLinhas(); + for(i=0; i < qtd; i++) + gatilho->adicionarArgumento(tab_argumentos->obterTextoCelula(i, 0)); + + //Adiciona as colunas + qtd=tab_colunas->obterNumLinhas(); + for(i=0; i < qtd; i++) + { + coluna=reinterpret_cast(tab_colunas->obterDadoLinha(i).value()); + gatilho->adicionarColuna(coluna); + } + + //Aplica as configurações básicas + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/gatilhowidget.h b/libpgmodeler_ui/src/gatilhowidget.h new file mode 100644 index 000000000..f2b981747 --- /dev/null +++ b/libpgmodeler_ui/src/gatilhowidget.h @@ -0,0 +1,65 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: GatilhoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de gatilhos / gatilhos restrições. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef GATILHO_WIDGET_H +#define GATILHO_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_gatilhowidget.h" +#include "tabelaobjetoswidget.h" +//*********************************************************** +class GatilhoWidget: public ObjetoBaseWidget, public Ui::GatilhoWidget { + Q_OBJECT + + private: + //Destaque de sintaxe do campo de expressão condicional + DestaqueSintaxe *dest_exp_condicional; + + //Tabelas de objetos para controlar colunas e argumentos + TabelaObjetosWidget *tab_colunas, + *tab_argumentos; + + //Seletor de tabela referenciada e função executada pelo gatilho + SeletorObjetoWidget *sel_tabela_ref, + *sel_funcao; + + //Adiciona uma coluna à tabelade colunas referenciadas pelo gatilho + void adicionarColuna(Coluna *coluna, int idx_lin); + + public: + GatilhoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, Tabela *tabela_pai, ListaOperacoes *lista_op, Gatilho *restricao); + + private slots: + void hideEvent(QHideEvent *); + void adicionarColuna(int idx_lin); + void manipularArgumento(int idx_lin); + void editarArgumento(int idx_lin); + void atualizarComboColunas(void); + void definirGratilhoRestricao(bool valor); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/indicewidget.cpp b/libpgmodeler_ui/src/indicewidget.cpp new file mode 100644 index 000000000..c0aa0d7a4 --- /dev/null +++ b/libpgmodeler_ui/src/indicewidget.cpp @@ -0,0 +1,356 @@ +#include "indicewidget.h" +//*********************************************************** +IndiceWidget::IndiceWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_INDICE) +{ + try + { + map > mapa_campos; + map > mapa_valores; + QFrame *frame=NULL; + QStringList lista; + QGridLayout *grid=NULL; + + Ui_IndiceWidget::setupUi(this); + + //Cria um destacador de sintaxe no campo de expressão de checagem + dest_exp_condicional=new DestaqueSintaxe(exp_condicional_txt, false); + dest_exp_condicional->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + dest_exp_elemento=new DestaqueSintaxe(exp_elemento_txt, false); + dest_exp_elemento->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + tab_elementos=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES, true, this); + sel_classe_op=new SeletorObjetoWidget(OBJETO_CLASSE_OPER, true, this); + + tab_elementos->definirNumColunas(5); + tab_elementos->definirRotuloCabecalho(trUtf8("Elemento"), 0); + tab_elementos->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + tab_elementos->definirRotuloCabecalho(trUtf8("Tipo"), 1); + tab_elementos->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + tab_elementos->definirRotuloCabecalho(trUtf8("Classe Operadores"), 2); + tab_elementos->definirIconeCabecalho(QPixmap(":/icones/icones/opclass.png"),2); + tab_elementos->definirRotuloCabecalho(trUtf8("Ordenação"), 3); + tab_elementos->definirRotuloCabecalho(trUtf8("Nulos Primeiro"), 4); + + grid=dynamic_cast(elementos_grp->layout()); + grid->addWidget(sel_classe_op, 2,1,1,3); + grid->addWidget(tab_elementos, 5,0,1,4); + + configurarLayouFormulario(indice_grid, OBJETO_INDICE); + janela_pai->setMinimumSize(600, 640); + + TipoIndexacao::obterTipos(lista); + tipo_index_cmb->addItems(lista); + + //Define os campos exclusivos para cada versão + mapa_campos[gerarIntervaloVersoes(ATE_VERSAO, ParserEsquema::VERSAO_PGSQL_81)].push_back(tipo_index_lbl); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_82)].push_back(concorrente_chk); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_83)].push_back(ordenacao_lbl); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(atual_rapida_chk); + mapa_valores[tipo_index_lbl].push_back(~TipoIndexacao(TipoIndexacao::rtree)); + + //Gera o frame de alerta + frame=gerarFrameAlertaVersao(mapa_campos, &mapa_valores); + indice_grid->addWidget(frame, indice_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(tab_elementos, SIGNAL(s_linhaAdicionada(int)), this, SLOT(manipularElemento(int))); + connect(tab_elementos, SIGNAL(s_linhaAtualizada(int)), this, SLOT(manipularElemento(int))); + connect(tab_elementos, SIGNAL(s_linhaEditada(int)), this, SLOT(editarElemento(int))); + connect(coluna_rb, SIGNAL(toggled(bool)), this, SLOT(selecionarObjetoElemento(void))); + connect(expressao_rb, SIGNAL(toggled(bool)), this, SLOT(selecionarObjetoElemento(void))); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void IndiceWidget::hideEvent(QHideEvent *evento) +{ + ObjetoBaseWidget::hideEvent(evento); + + exp_condicional_txt->clear(); + coluna_cmb->clear(); + concorrente_chk->setChecked(false); + unico_chk->setChecked(false); + tipo_index_cmb->setCurrentIndex(0); + fator_preenc_sb->setValue(fator_preenc_sb->minimum()); + + tab_elementos->blockSignals(true); + tab_elementos->removerLinhas(); + tab_elementos->blockSignals(false); + + sel_classe_op->removerObjetoSelecionado(); + exp_elemento_txt->clear(); + ascendente_rb->setChecked(true); + coluna_rb->setChecked(true); +} +//---------------------------------------------------------- +void IndiceWidget::atualizarComboColunas(void) +{ + Coluna *coluna=NULL; + unsigned i, qtd_col=0; + + try + { + coluna_cmb->clear(); + + /* Varre a lista de colunas da tabela inserindo-as + no combo box do formulário */ + qtd_col=tabela->obterNumColunas(); + for(i=0; i < qtd_col; i++) + { + coluna=tabela->obterColuna(i); + coluna_cmb->addItem(QString::fromUtf8(coluna->obterNome()), + QVariant::fromValue(coluna)); + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void IndiceWidget::exibirDadosElemento(ElementoIndice elem, int idx_elem) +{ + //Caso o elemento possua uma coluna + if(elem.obterColuna()) + { + //Exibe os dados da coluna + tab_elementos->definirTextoCelula(QString::fromUtf8(elem.obterColuna()->obterNome()), idx_elem, 0); + tab_elementos->definirTextoCelula(QString::fromUtf8(elem.obterColuna()->obterNomeTipoObjeto()), idx_elem, 1); + } + //Caso possua uma expressão + else + { + //Exibe a expressão + tab_elementos->definirTextoCelula(QString::fromUtf8(elem.obterExpressao()), idx_elem, 0); + tab_elementos->definirTextoCelula(trUtf8("Expressão"), idx_elem, 1); + } + + /* Exibindo o nome da classe de operadores caso exista. + se não existir exibe um '-' */ + if(elem.obterClasseOperadores()) + tab_elementos->definirTextoCelula(QString::fromUtf8(elem.obterClasseOperadores()->obterNome(true)), idx_elem, 2); + else + tab_elementos->definirTextoCelula("-", idx_elem, 2); + + if(elem.obterAtributo(ElementoIndice::ORDEM_ASCENDENTE)) + tab_elementos->definirTextoCelula(ascendente_rb->text(), idx_elem, 3); + else + tab_elementos->definirTextoCelula(descendente_rb->text(), idx_elem, 3); + + if(elem.obterAtributo(ElementoIndice::NULOS_PRIMEIRO)) + tab_elementos->definirTextoCelula(trUtf8("Sim"), idx_elem, 4); + else + tab_elementos->definirTextoCelula(trUtf8("Não"), idx_elem, 4); + + /* O elemento é definido como dado da linha para facilitar a configuração + no método aplicarConfiguracao() */ + tab_elementos->definirDadoLinha(QVariant::fromValue(elem), idx_elem); +} +//---------------------------------------------------------- +void IndiceWidget::manipularElemento(int idx_elem) +{ + /* Caso a radio box de coluna esteja marcado ou se o de expressão esteja + marcado e a expressão esteja preenchida */ + if(coluna_rb->isChecked() || + (expressao_rb->isChecked() && !exp_elemento_txt->toPlainText().isEmpty())) + { + ElementoIndice elem; + + //Configura um elemento com todos os dados configurados no formulário d elementos + elem.definirAtributo(ElementoIndice::NULOS_PRIMEIRO, nulos_primeiro_chk->isChecked()); + elem.definirAtributo(ElementoIndice::ORDEM_ASCENDENTE, ascendente_rb->isChecked()); + elem.definirClasseOperadores(dynamic_cast(sel_classe_op->obterObjeto())); + + if(expressao_rb->isChecked()) + elem.definirExpressao(exp_elemento_txt->toPlainText()); + else + elem.definirColuna(reinterpret_cast(coluna_cmb->itemData(coluna_cmb->currentIndex()).value())); + + //Exibe os dados do elemento na tabela de elementos do índice + exibirDadosElemento(elem, idx_elem); + + //Limpa o formulário de elementos para posteriores inserções + exp_elemento_txt->clear(); + ascendente_rb->setChecked(true); + sel_classe_op->removerObjetoSelecionado(); + nulos_primeiro_chk->setChecked(false); + } + else if(tab_elementos->obterTextoCelula(idx_elem,0).isEmpty()) + tab_elementos->removerLinha(idx_elem); +} +//---------------------------------------------------------- +void IndiceWidget::editarElemento(int idx_elem) +{ + ElementoIndice elem; + + //Obtém o elemento na linha especificada + elem=tab_elementos->obterDadoLinha(idx_elem).value(); + + /* Caso possua coluna marca o radio box de coluna + e marca no combo box o nome da coluna que o elemento possui */ + if(elem.obterColuna()) + { + coluna_rb->setChecked(true); + coluna_cmb->setCurrentIndex(coluna_cmb->findText(QString::fromUtf8(elem.obterColuna()->obterNome()))); + } + /* Caso seja uma expressão marca o radiobox de expressão e a + insere no campo de expressão */ + else + { + expressao_rb->setChecked(true); + exp_elemento_txt->setPlainText(elem.obterExpressao()); + } + + //Configura a ordenação do formulário conforme configurado no elemento + if(elem.obterAtributo(ElementoIndice::ORDEM_ASCENDENTE)) + ascendente_rb->setChecked(true); + else + descendente_rb->setChecked(true); + nulos_primeiro_chk->setChecked(elem.obterAtributo(ElementoIndice::NULOS_PRIMEIRO)); + + //Exibe a classe de operadores no formulário + sel_classe_op->definirObjeto(elem.obterClasseOperadores()); +} +//---------------------------------------------------------- +void IndiceWidget::selecionarObjetoElemento(void) +{ + QObject *obj_sender=sender(); + + coluna_rb->blockSignals(true); + expressao_rb->blockSignals(true); + + /* Caso a radiobox de coluna seja o sender + desmarca o radio de expressão e limpa e + desabilita o campo de expressão. */ + if(obj_sender==coluna_rb) + { + exp_elemento_txt->clear(); + coluna_cmb->setEnabled(true); + expressao_rb->setChecked(false); + coluna_rb->setChecked(true); + exp_elemento_txt->setEnabled(false); + } + /* Caso o sender seja o radio de expressão + ativa o campo de expressão e desmarca o + radio de coluna */ + else + { + coluna_cmb->setEnabled(false); + coluna_rb->setChecked(false); + expressao_rb->setChecked(true); + exp_elemento_txt->setEnabled(true); + } + + coluna_rb->blockSignals(false); + expressao_rb->blockSignals(false); +} +//---------------------------------------------------------- +void IndiceWidget::definirAtributos(ModeloBD *modelo, Tabela *tabela_pai, ListaOperacoes *lista_op, Indice *indice) +{ + unsigned i, qtd; + + if(!tabela_pai) + throw Excecao(ERR_PGMODELER_ATROBJNAOALOC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, indice, tabela_pai); + + //Define o modelo de banco de dados do seletor de classe de operadores + sel_classe_op->definirModelo(modelo); + + //Exibe o nome das colunas da tabela no combobox de colunas dos elementos + atualizarComboColunas(); + + //Caso o índice esteja alocado (sendo editado) + if(indice) + { + /* Configura os campos do formulário com os respectivos valores + configurados no índice */ + tipo_index_cmb->setCurrentIndex(tipo_index_cmb->findText(~indice->obterTipoIndexacao())); + fator_preenc_sb->setValue(indice->obterFatorPreenchimento()); + concorrente_chk->setChecked(indice->obterAtributo(Indice::CONCORRENTE)); + atual_rapida_chk->setChecked(indice->obterAtributo(Indice::ATUAL_RAPIDA)); + unico_chk->setChecked(indice->obterAtributo(Indice::UNIQUE)); + exp_condicional_txt->setPlainText(indice->obterExpCondicional()); + + //Exibe os elementos do índice na tabela + tab_elementos->blockSignals(true); + qtd=indice->obterNumElementos(); + for(i=0; i < qtd; i++) + { + tab_elementos->adicionarLinha(); + exibirDadosElemento(indice->obterElemento(i), i); + } + tab_elementos->blockSignals(false); + } +} +//---------------------------------------------------------- +void IndiceWidget::aplicarConfiguracao(void) +{ + try + { + Indice *indice=NULL; + unsigned i, qtd; + ElementoIndice elem; + + iniciarConfiguracao(); + + //Obtém a referência ao índice que está sendo criado/editado + indice=dynamic_cast(this->objeto); + + //Configura no índice os valores preenchidos no formulário + indice->definirAtributo(Indice::ATUAL_RAPIDA, atual_rapida_chk->isChecked()); + indice->definirAtributo(Indice::CONCORRENTE, concorrente_chk->isChecked()); + indice->definirAtributo(Indice::UNIQUE, unico_chk->isChecked()); + indice->definirExpCondicional(exp_condicional_txt->toPlainText()); + indice->definirTipoIndexacao(TipoIndexacao(tipo_index_cmb->currentText())); + indice->definirFatorPreenchimento(fator_preenc_sb->value()); + + //Insere os elementos da tabela no índice + indice->removerElementos(); + qtd=tab_elementos->obterNumLinhas(); + + for(i=0; i < qtd; i++) + { + //Obtém o elemento na linha da tabela + elem=tab_elementos->obterDadoLinha(i).value(); + + //Caso o mesmo possua uma coluna + if(elem.obterColuna()) + //Adiciona um elmento como sendo um com coluna + indice->adicionarElemento(elem.obterColuna(), elem.obterClasseOperadores(), + elem.obterAtributo(ElementoIndice::ORDEM_ASCENDENTE), + elem.obterAtributo(ElementoIndice::NULOS_PRIMEIRO)); + else + //Adiciona um elmento como sendo um com expressão + indice->adicionarElemento(elem.obterExpressao(), elem.obterClasseOperadores(), + elem.obterAtributo(ElementoIndice::ORDEM_ASCENDENTE), + elem.obterAtributo(ElementoIndice::NULOS_PRIMEIRO)); + } + + //Aplica as configurações básicas + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/indicewidget.h b/libpgmodeler_ui/src/indicewidget.h new file mode 100644 index 000000000..24412bf99 --- /dev/null +++ b/libpgmodeler_ui/src/indicewidget.h @@ -0,0 +1,77 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: RestricaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de índices. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef INDICE_WIDGET_H +#define INDICE_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_indicewidget.h" +#include "tabelaobjetoswidget.h" + +/* Declarando a classe ElementoIndice como metatype para que esta + possa ser usada em conjunto com a classe QVariant (vide documentação + da classe QVariant e QMetaType). Esta declaração é uma macro específica + do Qt e está sendo usada para facilitar o uso com classes que necessitam + armazenar instancias de classes em seus containeres (TabelaObjetosWidget). + Essa declaração não afeta o comportamento das demais classes que de algum + modo referenciam a classe ElementoIndice.*/ +#include +Q_DECLARE_METATYPE(ElementoIndice); +//*********************************************************** +class IndiceWidget: public ObjetoBaseWidget, public Ui::IndiceWidget { + Q_OBJECT + + private: + //Destaque de sintaxe do campo de expressão condicional + DestaqueSintaxe *dest_exp_condicional, + *dest_exp_elemento; + + //Tabelas de objetos para controlar elementos do índice + TabelaObjetosWidget *tab_elementos; + + //Seletor de classe de operadores dos elementos + SeletorObjetoWidget *sel_classe_op; + + //Atualiza o combo de colunas com as existentes na tabela + void atualizarComboColunas(void); + + //Exibe o dado de um elemento na linha especificada da tabela + void exibirDadosElemento(ElementoIndice elem, int idx_elem); + + public: + IndiceWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, Tabela *tabela_pai, ListaOperacoes *lista_op, Indice *indice); + + private slots: + void hideEvent(QHideEvent *); + void selecionarObjetoElemento(void); + + //Métodos de manipulação dos elementos do índice + void manipularElemento(int idx_elem); + void editarElemento(int idx_elem); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/linguagemwidget.cpp b/libpgmodeler_ui/src/linguagemwidget.cpp new file mode 100644 index 000000000..bb3696438 --- /dev/null +++ b/libpgmodeler_ui/src/linguagemwidget.cpp @@ -0,0 +1,115 @@ +#include "linguagemwidget.h" +//*********************************************************** +LinguagemWidget::LinguagemWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_LINGUAGEM) +{ + try + { + map > mapa_campos; + QFrame *frame=NULL; + QString chave_ver; + + Ui_LinguagemWidget::setupUi(this); + + sel_func_handler=NULL; + sel_func_validator=NULL; + sel_func_inline=NULL; + + sel_func_handler=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + sel_func_validator=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + sel_func_inline=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + + linguagem_grid->addWidget(sel_func_handler,1,1,1,2); + linguagem_grid->addWidget(sel_func_validator,2,1,1,2); + linguagem_grid->addWidget(sel_func_inline,3,1,1,2); + + configurarLayouFormulario(linguagem_grid, OBJETO_LINGUAGEM); + + //Gera o frame de informação + frame=gerarFrameInformacao(trUtf8("As funções a serem atribuídas à linguagem devem possuir, respectivamente, as seguintes assinaturas:

\ + Função Handler: language_handler funcao()
\ + Função Validator: void funcao(oid)
\ + Função Inline: void funcao(internal)")); + linguagem_grid->addWidget(frame, linguagem_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + //Define os campos exclusivos para cada versão + chave_ver=gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84); + mapa_campos[chave_ver].push_back(func_inline_lbl); + //Gera o frame de alerta + frame=gerarFrameAlertaVersao(mapa_campos); + linguagem_grid->addWidget(frame, linguagem_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->setMinimumSize(550, 510); + janela_pai->setMaximumSize(16777215, 510); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void LinguagemWidget::hideEvent(QHideEvent *evento) +{ + sel_func_handler->removerObjetoSelecionado(); + sel_func_validator->removerObjetoSelecionado(); + sel_func_inline->removerObjetoSelecionado(); + confiavel_chk->setChecked(false); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void LinguagemWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Linguagem *linguagem) +{ + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, linguagem); + + /* Obtém as funções da linguagem e exibe suas assinaturas nas caixas + de texto respectivas */ + sel_func_handler->definirModelo(modelo); + sel_func_validator->definirModelo(modelo); + sel_func_inline->definirModelo(modelo); + + if(linguagem) + { + //Marca o checkbox de confiável de acordo com o que está definido na linguagem + confiavel_chk->setChecked(linguagem->linguagemConfiavel()); + sel_func_handler->definirObjeto(linguagem->obterFuncao(Linguagem::FUNC_HANDLER)); + sel_func_validator->definirObjeto(linguagem->obterFuncao(Linguagem::FUNC_VALIDATOR)); + sel_func_inline->definirObjeto(linguagem->obterFuncao(Linguagem::FUNC_INLINE)); + } +} +//---------------------------------------------------------- +void LinguagemWidget::aplicarConfiguracao(void) +{ + try + { + Linguagem *linguagem=NULL; + + iniciarConfiguracao(); + + //Converte o objeto para linguagem + linguagem=dynamic_cast(this->objeto); + linguagem->definirConfiavel(confiavel_chk->isChecked()); + + linguagem->definirFuncao(dynamic_cast(sel_func_handler->obterObjeto()), Linguagem::FUNC_HANDLER); + linguagem->definirFuncao(dynamic_cast(sel_func_validator->obterObjeto()), Linguagem::FUNC_VALIDATOR); + linguagem->definirFuncao(dynamic_cast(sel_func_inline->obterObjeto()), Linguagem::FUNC_INLINE); + + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/linguagemwidget.h b/libpgmodeler_ui/src/linguagemwidget.h new file mode 100644 index 000000000..575a1a968 --- /dev/null +++ b/libpgmodeler_ui/src/linguagemwidget.h @@ -0,0 +1,48 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: LinguagemWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de linguagens. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef LINGUAGEM_WIDGET_H +#define LINGUAGEM_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_linguagemwidget.h" +//*********************************************************** +class LinguagemWidget: public ObjetoBaseWidget, public Ui::LinguagemWidget { + Q_OBJECT + + private: + SeletorObjetoWidget *sel_func_handler, + *sel_func_validator, + *sel_func_inline; + public: + LinguagemWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Linguagem *linguagem); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/listaobjetoswidget.cpp b/libpgmodeler_ui/src/listaobjetoswidget.cpp new file mode 100644 index 000000000..f22041898 --- /dev/null +++ b/libpgmodeler_ui/src/listaobjetoswidget.cpp @@ -0,0 +1,108 @@ +#include "listaobjetoswidget.h" +//*********************************************************** +ListaObjetosWidget::ListaObjetosWidget(QWidget *parent): ObjetoBaseWidget(parent) +{ + Ui_ListaObjetosWidget::setupUi(this); + configurarLayouFormulario(listaobjetos_grid, OBJETO_BASE); + + //Define os atributos do formulários e da janela pai + janela_pai->setWindowTitle(trUtf8("Dependências / Referências do Objeto")); + janela_pai->definirBotoes(CaixaMensagem::BOTAO_OK); + janela_pai->setMinimumSize(550, 300); + + //Conecta o botão ok do formulário pai com o método de fechamento do formulário + connect(janela_pai->aplicar_ok_btn, SIGNAL(clicked(bool)), janela_pai, SLOT(close(void))); +} +//----------------------------------------------------------- +void ListaObjetosWidget::definirAtributos(ModeloBD *modelo, ObjetoBase *objeto, ObjetoBase *objeto_pai) +{ + vector vet_objs; + + ObjetoBaseWidget::definirAtributos(modelo, NULL, objeto, objeto_pai); + + this->nome_edt->setReadOnly(true); + this->janela_pai->aplicar_ok_btn->setEnabled(true); + this->obj_protegido_frm->setVisible(false); + this->comentario_edt->setVisible(false); + this->comentario_lbl->setVisible(false); + + //Configura o icone do objeto a ser exibido + iconeobj_lbl->setPixmap(QPixmap(QString(":/icones/icones/") + + ObjetoBase::obterNomeEsquemaObjeto(objeto->obterTipoObjeto()) + QString(".png"))); + + //Carrega as dependências e referências do objeto + modelo->obterDependenciasObjeto(objeto, vet_objs); + this->atualizarListaObjetos(vet_objs, dependencias_tbw); + + modelo->obterReferenciasObjeto(objeto, vet_objs); + this->atualizarListaObjetos(vet_objs, referencias_tbw); +} +//----------------------------------------------------------- +void ListaObjetosWidget::hideEvent(QHideEvent *evento) +{ + tabWidget->setCurrentIndex(0); + + //Limpa as tabelas de objetos + while(dependencias_tbw->rowCount() > 0) + dependencias_tbw->removeRow(0); + + while(referencias_tbw->rowCount() > 0) + referencias_tbw->removeRow(0); + + ObjetoBaseWidget::hideEvent(evento); +} +//----------------------------------------------------------- +void ListaObjetosWidget::atualizarListaObjetos(vector &objetos, QTableWidget *listaobjetos_tbw) +{ + int qtd, id_lin, i; + QTableWidgetItem *item_tab=NULL; + ObjetoBase *obj_pai=NULL; + + qtd=objetos.size(); + + //Varre a lista de objtes inserindo cada um na lista (tabela) + for(id_lin=0, i=0; i < qtd; i++) + { + /* Caso o objeto da lista for o mesmo do objeto de origem (o qual ser que exibir + as refs. e deps.) este será ignorado */ + if(objetos[i]!=this->objeto) + { + listaobjetos_tbw->insertRow(id_lin); + + //Aloca o item de nome do objeto de ref/dep + item_tab=new QTableWidgetItem; + item_tab->setText(QString::fromUtf8(objetos[i]->obterNome())); + item_tab->setIcon(QPixmap(QString(":/icones/icones/") + + ObjetoBase::obterNomeEsquemaObjeto(objetos[i]->obterTipoObjeto())+ QString(".png"))); + listaobjetos_tbw->setItem(id_lin, 0, item_tab); + + //Aloca o item de tipo do objeto de ref/dep + item_tab=new QTableWidgetItem; + item_tab->setText(QString::fromUtf8(objetos[i]->obterNomeTipoObjeto())); + listaobjetos_tbw->setItem(id_lin, 1, item_tab); + + //Aloca o item do objeto pai do objeto de ref/dep + item_tab=new QTableWidgetItem; + objeto=objetos[i]; + if(dynamic_cast(objetos[i])) + obj_pai=dynamic_cast(objetos[i])->obterTabelaPai(); + else if(objetos[i]->obterEsquema()) + obj_pai=objetos[i]->obterEsquema(); + else + obj_pai=this->modelo; + + //Aloca o item de tipo do objeto pai do objeto de ref/dep + item_tab->setText(QString::fromUtf8(obj_pai->obterNome())); + item_tab->setIcon(QPixmap(QString(":/icones/icones/") + + ObjetoBase::obterNomeEsquemaObjeto(obj_pai->obterTipoObjeto())+ QString(".png"))); + listaobjetos_tbw->setItem(id_lin, 2, item_tab); + + item_tab=new QTableWidgetItem; + item_tab->setText(QString::fromUtf8(obj_pai->obterNomeTipoObjeto())); + listaobjetos_tbw->setItem(id_lin, 3, item_tab); + + id_lin++; + } + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/listaobjetoswidget.h b/libpgmodeler_ui/src/listaobjetoswidget.h new file mode 100644 index 000000000..3b84480a2 --- /dev/null +++ b/libpgmodeler_ui/src/listaobjetoswidget.h @@ -0,0 +1,48 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ListaObjetosWidget +# Descrição: Definição da classe que implementa o formulário de +# exibição das dependências e referências a um objeto +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef LISTA_OBJETOS_WIDGET_H +#define LISTA_OBJETOS_WIDGET_H + +#include "ui_listaobjetoswidget.h" +#include "objetobasewidget.h" +#include "objetografico.h" +//*********************************************************** +class ListaObjetosWidget: public ObjetoBaseWidget, public Ui::ListaObjetosWidget { + Q_OBJECT + + private: + void aplicarConfiguracao(void){} + + //Carrega os widgets que contém as referências e dependências do objeto + void atualizarListaObjetos(vector &objetos, QTableWidget *tabela_wgt); + + protected slots: + void hideEvent(QHideEvent *); + + public: + ListaObjetosWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ObjetoBase *objeto, ObjetoBase *objeto_pai=NULL); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/listaoperacoeswidget.cpp b/libpgmodeler_ui/src/listaoperacoeswidget.cpp new file mode 100644 index 000000000..0174f0d3b --- /dev/null +++ b/libpgmodeler_ui/src/listaoperacoeswidget.cpp @@ -0,0 +1,235 @@ +#include "listaoperacoeswidget.h" +#include "progressotarefa.h" +//*********************************************************** +extern CaixaMensagem *caixa_msg; +extern ProgressoTarefa *prog_tarefa; +//*********************************************************** +ListaOperacoesWidget::ListaOperacoesWidget(QWidget *parent, Qt::WindowFlags f) : QDockWidget(parent, f) +{ + setupUi(this); + modelo_wgt=NULL; + operacoes_tw->headerItem()->setHidden(true); + connect(desfazer_tb,SIGNAL(clicked()),this,SLOT(desfazerOperacao(void))); + connect(refazer_tb,SIGNAL(clicked()),this,SLOT(refazerOperacao(void))); + connect(excluiroperacoes_tb,SIGNAL(clicked()),this,SLOT(excluirOperacoes(void))); + connect(operacoes_tw,SIGNAL(itemClicked(QTreeWidgetItem *, int)), + this,SLOT(selecionarItem(QTreeWidgetItem *, int))); +} +//---------------------------------------------------------- +void ListaOperacoesWidget::selecionarItem(QTreeWidgetItem *item, int) +{ + //Limpa os itens selecionados na lista + operacoes_tw->clearSelection(); + + if(item) + { + /* Caso o item clicado seja um subitem, faz com que o item atual + aponte para seu pai */ + if(item->parent()) + item=item->parent(); + + //Seleciona o item + item->setSelected(true); + /* Define o item atual da lista como sendo o que acaba + de ser selecionado */ + operacoes_tw->setCurrentItem(item); + } +} +//---------------------------------------------------------- +void ListaOperacoesWidget::atualizarListaOperacoes(void) +{ + //Caso o modelo não esteja alocado + if(!modelo_wgt) + { + //Limpa a seleção + operacoes_tw->clear(); + //Desativa o formulário inteiro e reinicia os labels + dockWidgetContents->setEnabled(false); + num_operacao_lb->setText("-"); + num_posicao_lb->setText("-"); + } + else + { + unsigned qtd, i, tipo_op; + TipoObjetoBase tipo_obj; + QString nome_obj, str_aux, nome_op, icone_op; + QTreeWidgetItem *item=NULL,*item1=NULL, *item2=NULL; + QFont fonte=this->font(); + bool valor=false; + + //Ativa o formulário + dockWidgetContents->setEnabled(true); + //Atualiza os labels com seus respectivos valores + num_operacao_lb->setText(QString("%1").arg(modelo_wgt->lista_op->obterTamanhoAtual())); + num_posicao_lb->setText(QString("%1").arg(modelo_wgt->lista_op->obterIndiceAtual())); + + /* Ativa/desativa os botões de refazer e defazer de acordo com + com a situação das respectivas operações na lista */ + refazer_tb->setEnabled(modelo_wgt->lista_op->refazerHabilitado()); + desfazer_tb->setEnabled(modelo_wgt->lista_op->desfazerHabilitado()); + + //Obtém a quantidade de operações + qtd=modelo_wgt->lista_op->obterTamanhoAtual(); + + //Limpa a lista + operacoes_tw->clear(); + excluiroperacoes_tb->setEnabled(qtd > 0); + + //Varre a lista de operações + for(i=0; i < qtd; i++) + { + //Obtém os dados da operação atual + modelo_wgt->lista_op->obterDadosOperacao(i,tipo_op,nome_obj,tipo_obj); + + /* Caso o indice atual seja o mesmo da operação atual na lista + a mesma será destacada como negrito e itálico na lista de operações */ + valor=(i==static_cast(modelo_wgt->lista_op->obterIndiceAtual()-1)); + fonte.setBold(valor); + fonte.setItalic(valor); + + //Aloca um item da lista como sendo o tipo do objeto com seu ícone respectivo + item=new QTreeWidgetItem; + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(tipo_obj)); + //Armazena o tipo do objeto no item da lista de operações + item->setData(0, Qt::UserRole, QVariant(tipo_obj)); + + if(tipo_obj==OBJETO_RELACAO_BASE) + str_aux+="tv"; + + item->setIcon(0,QPixmap(QString(":/icones/icones/") + str_aux + QString(".png"))); + + operacoes_tw->insertTopLevelItem(i,item); + item->setFont(0,fonte); + item->setText(0,trUtf8("Objeto: %1").arg(ObjetoBase::obterNomeTipoObjeto(tipo_obj))); + + //Aloca um item da lista como o nome do objeto com seu ícone respectivo + item2=new QTreeWidgetItem(item); + item2->setIcon(0,QPixmap(QString(":/icones/icones/uid.png"))); + item2->setFont(0,fonte); + item2->setText(0,QString::fromUtf8(trUtf8("Nome: %1").arg(nome_obj))); + + //Identifica o tipo da operação executada + if(tipo_op==Operacao::OBJETO_CRIADO) + { + icone_op="criado"; + nome_op=trUtf8("criado"); + } + else if(tipo_op==Operacao::OBJETO_REMOVIDO) + { + icone_op="removido"; + nome_op=trUtf8("removido"); + } + else if(tipo_op==Operacao::OBJETO_MODIFICADO) + { + icone_op="modificado"; + nome_op=trUtf8("modificado"); + } + else if(tipo_op==Operacao::OBJETO_MOVIMENTADO) + { + icone_op="movimentado"; + nome_op=trUtf8("movimentado"); + } + //Aloca um item da lista como sendo o tipo da operação objeto com seu ícone respectivo + item1=new QTreeWidgetItem(item); + item1->setIcon(0,QPixmap(QString(":/icones/icones/") + icone_op + QString(".png"))); + item1->setFont(0,fonte); + item1->setText(0,trUtf8("Operação: %1").arg(nome_op)); + + //Expande o novo item para exibir todos os seus filhos + operacoes_tw->expandItem(item); + + if(valor) + operacoes_tw->scrollToItem(item1); + } + } + + emit s_listaOperacoesAtualizada(); +} +//---------------------------------------------------------- +void ListaOperacoesWidget::definirModelo(ModeloWidget *modelo) +{ + operacoes_tw->clear(); + this->modelo_wgt=modelo; + atualizarListaOperacoes(); + //QDockWidget::show(); +} +//----------------------------------------------------------- +void ListaOperacoesWidget::desfazerOperacao(void) +{ + try + { + //Exibe o progresso de operações de desfazer + connect(modelo_wgt->lista_op, SIGNAL(s_operacaoExecutada(int,QString,unsigned)), prog_tarefa, SLOT(executarProgesso(int,QString,unsigned))); + prog_tarefa->setWindowTitle(trUtf8("Desfazendo operações...")); + + modelo_wgt->lista_op->desfazerOperacao(); + + prog_tarefa->close(); + disconnect(modelo_wgt->lista_op, NULL, prog_tarefa, NULL); + + atualizarModeloObjetos(); + + //Limpa a seleção na cena + modelo_wgt->cena->clearSelection(); + } + catch(Excecao &e) + { + prog_tarefa->close(); + disconnect(modelo_wgt->lista_op, NULL, prog_tarefa, NULL); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ListaOperacoesWidget::refazerOperacao(void) +{ + try + { + //Exibe o progresso de operações de refazer + connect(modelo_wgt->lista_op, SIGNAL(s_operacaoExecutada(int,QString,unsigned)), prog_tarefa, SLOT(executarProgesso(int,QString,unsigned))); + prog_tarefa->setWindowTitle(trUtf8("Refazendo operações...")); + + modelo_wgt->lista_op->refazerOperacao(); + + prog_tarefa->close(); + disconnect(modelo_wgt->lista_op, NULL, prog_tarefa, NULL); + + atualizarModeloObjetos(); + + //Limpa a seleção na cena + modelo_wgt->cena->clearSelection(); + } + catch(Excecao &e) + { + prog_tarefa->close(); + disconnect(modelo_wgt->lista_op, NULL, prog_tarefa, NULL); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void ListaOperacoesWidget::excluirOperacoes(void) +{ + //Exibe a mensagem de confirmação ao usuário + caixa_msg->show(trUtf8("Exclusão de histórico de operações"), + trUtf8("Excluir o histórico de operações executadas é uma ação irreversível, deseja realmente prosseguir?"), + CaixaMensagem::ICONE_CONFIRM, + CaixaMensagem::BOTAO_SIM_NAO); + + //Caso o usuário confirme a exclusão a lista é limpa e atualizada + if(caixa_msg->result()==QDialog::Accepted) + { + modelo_wgt->lista_op->removerOperacoes(); + atualizarListaOperacoes(); + excluiroperacoes_tb->setEnabled(false); + } +} +//----------------------------------------------------------- +void ListaOperacoesWidget::atualizarModeloObjetos(void) +{ + //Atualiza a lista de operações + atualizarListaOperacoes(); + + /* Emite um sinal indicando que o modelo foi atualizado devido a + operação na lista de objetos */ + emit s_operacaoExecutada(); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/listaoperacoeswidget.h b/libpgmodeler_ui/src/listaoperacoeswidget.h new file mode 100644 index 000000000..99a90e760 --- /dev/null +++ b/libpgmodeler_ui/src/listaoperacoeswidget.h @@ -0,0 +1,61 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ListaOperacoesWidget +# Descrição: Definição da classe que implementa a arvore de operações executadas +# no modelo de banco de dados. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef LISTA_OPERACOES_WIDGET_H +#define LISTA_OPERACOES_WIDGET_H + +#include +#include "ui_listaoperacoeswidget.h" +#include "modelowidget.h" +#include "caixamensagem.h" +//*********************************************************** +class ListaOperacoesWidget: public QDockWidget, public Ui::ListaOperacoesWidget { + Q_OBJECT + + private: + //Armazena o modelo atual o qual será exibido na visão geral + ModeloWidget *modelo_wgt; + + void atualizarModeloObjetos(void); + + public: + ListaOperacoesWidget(QWidget * parent = 0, Qt::WindowFlags f = 0); + + public slots: + void atualizarListaOperacoes(void); + void definirModelo(ModeloWidget *modelo); + void desfazerOperacao(void); + void refazerOperacao(void); + void excluirOperacoes(void); + + private slots: + void selecionarItem(QTreeWidgetItem *item, int coluna); + + signals: + /* Sinal emitido pelo widget quando uma operação sobre + a lista é executada */ + void s_operacaoExecutada(void); + void s_listaOperacoesAtualizada(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/modelowidget.cpp b/libpgmodeler_ui/src/modelowidget.cpp new file mode 100644 index 000000000..eb3aec1d6 --- /dev/null +++ b/libpgmodeler_ui/src/modelowidget.cpp @@ -0,0 +1,2317 @@ +#include "modelowidget.h" +#include "codigofontewidget.h" +#include "bancodadoswidget.h" +#include "esquemawidget.h" +#include "papelwidget.h" +#include "espacotabelawidget.h" +#include "linguagemwidget.h" +#include "funcaowidget.h" +#include "conversaotipowidget.h" +#include "conversaocodificacaowidget.h" +#include "dominiowidget.h" +#include "funcaoagregacaowidget.h" +#include "sequenciawidget.h" +#include "operadorwidget.h" +#include "familiaoperadoreswidget.h" +#include "classeoperadoreswidget.h" +#include "tipowidget.h" +#include "visaowidget.h" +#include "caixatextowidget.h" +#include "colunawidget.h" +#include "restricaowidget.h" +#include "regrawidget.h" +#include "gatilhowidget.h" +#include "indicewidget.h" +#include "relacionamentowidget.h" +#include "tabelawidget.h" +#include "progressotarefa.h" +#include "listaobjetoswidget.h" +//*********************************************************** +extern CaixaMensagem *caixa_msg; +extern BancoDadosWidget *bancodados_wgt; +extern EsquemaWidget *esquema_wgt; +extern PapelWidget *papel_wgt; +extern EspacoTabelaWidget *espacotabela_wgt; +extern LinguagemWidget *linguagem_wgt; +extern CodigoFonteWidget *codigofonte_wgt; +extern FuncaoWidget *funcao_wgt; +extern ConversaoTipoWidget *convtipo_wgt; +extern ConversaoCodificacaoWidget *convcodif_wgt; +extern DominioWidget *dominio_wgt; +extern FuncaoAgregacaoWidget *funcaoag_wgt; +extern SequenciaWidget *sequencia_wgt; +extern OperadorWidget *operador_wgt; +extern FamiliaOperadoresWidget *familiaop_wgt; +extern ClasseOperadoresWidget *classeop_wgt; +extern TipoWidget *tipo_wgt; +extern VisaoWidget *visao_wgt; +extern CaixaTextoWidget *caixatexto_wgt; +extern ColunaWidget *coluna_wgt; +extern RestricaoWidget *restricao_wgt; +extern RegraWidget *regra_wgt; +extern GatilhoWidget *gatilho_wgt; +extern IndiceWidget *indice_wgt; +extern RelacionamentoWidget *relacao_wgt; +extern TabelaWidget *tabela_wgt; +extern ProgressoTarefa *prog_tarefa; +extern ListaObjetosWidget *deps_refs_wgt; +//********************************************************** +vector ModeloWidget::objs_copiados; +bool ModeloWidget::op_recortar=false; +ModeloWidget *ModeloWidget::modelo_orig=NULL; +//********************************************************** +ModeloWidget::ModeloWidget(QWidget *parent) : QWidget(parent) +{ + QFont fonte; + QLabel *label=NULL; + QGridLayout *grid=NULL; + QMenu *menu_rels=NULL; + QAction *acao=NULL; + QString str_ico, str_txt, + vet_tipos_rel[]={"11", "1n", "nn", "dep", "gen" }, + vet_rot_rel[]={"1-1", "1-n", "n-n", trUtf8("Dependência"), trUtf8("Generalização")}; + TipoObjetoBase tipos[]={ OBJETO_TABELA, OBJETO_VISAO, OBJETO_CAIXA_TEXTO, OBJETO_RELACAO, + OBJETO_CONV_TIPO, OBJETO_CONV_CODIFICACAO, OBJETO_DOMINIO, + OBJETO_FUNCAO, OBJETO_FUNC_AGREGACAO, OBJETO_LINGUAGEM, + OBJETO_CLASSE_OPER, OBJETO_OPERADOR, OBJETO_FAMILIA_OPER, + OBJETO_PAPEL, OBJETO_ESQUEMA, OBJETO_SEQUENCIA, OBJETO_TIPO, + OBJETO_COLUNA, OBJETO_RESTRICAO, OBJETO_REGRA, OBJETO_GATILHO, OBJETO_INDICE }; + unsigned i, qtd=22, + tipos_rel[]={ RelacionamentoBase::RELACIONAMENTO_11, RelacionamentoBase::RELACIONAMENTO_1N, + RelacionamentoBase::RELACIONAMENTO_NN, RelacionamentoBase::RELACIONAMENTO_DEP, + RelacionamentoBase::RELACIONAMENTO_GEN }; + + zoom_atual=1; + modificado=true; + tipo_novo_obj=OBJETO_BASE; + + modelo_protegido_frm=new QFrame(this); + modelo_protegido_frm->setGeometry(QRect(20, 10, 511, 48)); + modelo_protegido_frm->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + modelo_protegido_frm->setMinimumSize(QSize(0, 48)); + modelo_protegido_frm->setFrameShape(QFrame::StyledPanel); + modelo_protegido_frm->setFrameShadow(QFrame::Raised); + modelo_protegido_frm->setVisible(false); + + label=new QLabel(modelo_protegido_frm); + label->setMinimumSize(QSize(32, 32)); + label->setMaximumSize(QSize(32, 32)); + label->setPixmap(QPixmap(QString::fromUtf8(":/icones/icones/msgbox_alerta.png"))); + + grid=new QGridLayout; + grid->addWidget(label, 0, 0, 1, 1); + + label=new QLabel(modelo_protegido_frm); + + fonte.setPointSize(9); + fonte.setBold(false); + fonte.setItalic(false); + fonte.setUnderline(false); + fonte.setWeight(50); + fonte.setStrikeOut(false); + fonte.setKerning(true); + label->setFont(fonte); + label->setWordWrap(true); + label->setText(trUtf8("ATENÇÃO: O modelo de objetos encontra-se protegido! Novos objetos só poderão ser inseridos quando esta situação for revertida!")); + + grid->addWidget(label, 0, 1, 1, 1); + modelo_protegido_frm->setLayout(grid); + + //Aloca o modelo e a lista de operações + modelo=new ModeloBD; + lista_op=new ListaOperacoes(modelo); + cena=new CenaObjetos; + cena->setSceneRect(QRectF(0,0,2000,2000)); + + //Aloca o viewport com algumas opções de otimização na renderização + viewport=new QGraphicsView(cena); + viewport->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + + //Ativa o antialiasing de fonte e objetos + viewport->setRenderHint(QPainter::Antialiasing); + viewport->setRenderHint(QPainter::TextAntialiasing); + viewport->setRenderHint(QPainter::SmoothPixmapTransform); + + //Força a cena a ser desenhada da esquerda para a direita e de cima para baixo + viewport->setAlignment(Qt::AlignLeft | Qt::AlignTop); + + //Otimizações: Cache do background (grade) e atualização mínima do viewport + //viewport->setCacheMode(QGraphicsView::CacheBackground); + viewport->setViewportUpdateMode(QGraphicsView::SmartViewportUpdate); + viewport->centerOn(0,0); + this->aplicarZoom(1); + + //Aloca um grid layout para agrupar os widgets que formam o ModeloWidget + grid=new QGridLayout; + grid->addWidget(modelo_protegido_frm, 0,0,1,1); + grid->addWidget(viewport, 1,0,1,1); + this->setLayout(grid); + + //Aloca as ações do menu popup + action_codigo_fonte=new QAction(QIcon(QString(":/icones/icones/codigosql.png")), trUtf8("Código-fonte"), this); + action_codigo_fonte->setShortcut(QKeySequence("Alt+S")); + action_codigo_fonte->setToolTip(trUtf8("Exibe o código-fonte do objeto")); + + action_editar=new QAction(QIcon(QString(":/icones/icones/editar.png")), trUtf8("Propriedades"), this); + action_editar->setShortcut(QKeySequence("Space")); + action_editar->setToolTip(trUtf8("Edita as propriedades do objeto")); + + action_proteger=new QAction(QIcon(QString(":/icones/icones/bloqobjeto.png")), trUtf8("Proteger"), this); + action_desproteger=new QAction(QIcon(QString(":/icones/icones/desbloqobjeto.png")), trUtf8("Desproteger"), this); + action_proteger->setToolTip(trUtf8("Protege o(s) objeto(s) contra modificações")); + action_desproteger->setToolTip(trUtf8("Remove a proteção contra modificação do(s) objeto(s)")); + + action_excluir=new QAction(QIcon(QString(":/icones/icones/excluir.png")), trUtf8("Excluir"), this); + action_excluir->setShortcut(QKeySequence("Del")); + action_excluir->setToolTip(trUtf8("Exclui o(s) objeto(s) selecionado(s)")); + + action_selecionar_todos=new QAction(QIcon(QString(":/icones/icones/seltodos.png")), trUtf8("Selecionar todos"), this); + action_selecionar_todos->setShortcut(QKeySequence("Ctrl+A")); + action_selecionar_todos->setToolTip(trUtf8("Seleciona todos os objetos gráficos no modelo")); + + action_converter_relnn=new QAction(QIcon(QString(":/icones/icones/convrelnn.png")), trUtf8("Converter rel. n-n"), this); + action_converter_relnn->setToolTip(trUtf8("Converte o relacionamento n-n para tabela própria")); + + action_copiar=new QAction(QIcon(QString(":/icones/icones/copiar.png")), trUtf8("Copiar"), this); + action_copiar->setShortcut(QKeySequence("Ctrl+C")); + action_copiar->setToolTip(trUtf8("Copia o(s) objeto(s) selecionado(s)")); + + action_colar=new QAction(QIcon(QString(":/icones/icones/colar.png")), trUtf8("Colar"), this); + action_colar->setShortcut(QKeySequence("Ctrl+V")); + action_colar->setToolTip(trUtf8("Cola o(s) objeto(s) anteriormente copiado(s)")); + + action_recortar=new QAction(QIcon(QString(":/icones/icones/recortar.png")), trUtf8("Recortar"), this); + action_recortar->setShortcut(QKeySequence("Ctrl+X")); + action_recortar->setToolTip(trUtf8("Recorta o(s) objeto(s) selecionado(s)")); + + action_deps_refs=new QAction(QIcon(QString(":/icones/icones/depsrefs.png")), trUtf8("Depend. / Refer."), this); + action_deps_refs->setToolTip(trUtf8("Exibe os objetos que referenciam e os que são dependência do objeto selecionado")); + + action_novo_obj=new QAction(QIcon(QString(":/icones/icones/novoobjeto.png")), trUtf8("Novo objeto"), this); + action_novo_obj->setToolTip(trUtf8("Adiciona um novo objeto no modelo")); + + //Aloca as ações de criação de novo objeto + for(i=0; i < qtd; i++) + { + acoes_ins_objs[tipos[i]]=new QAction(QIcon(QString(":/icones/icones/") + + ObjetoBase::obterNomeEsquemaObjeto(tipos[i]) + QString(".png")), + QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(tipos[i])), this); + acoes_ins_objs[tipos[i]]->setData(QVariant(tipos[i])); + connect(acoes_ins_objs[tipos[i]], SIGNAL(triggered(bool)), this, SLOT(adicionarNovoObjeto(void))); + } + + + //Caso especial, criando um submenu de criação de relacionamentos. + menu_rels=new QMenu(this); + acoes_ins_objs[OBJETO_RELACAO]->setMenu(menu_rels); + + for(i=0; i < 5; i++) + { + str_ico=ObjetoBase::obterNomeEsquemaObjeto(OBJETO_RELACAO) + vet_tipos_rel[i] + QString(".png"); + + if(i < 3) + str_txt=trUtf8("Relacionamento ") + vet_rot_rel[i]; + else + str_txt=vet_rot_rel[i]; + + /* Aloca a ação para o tipo de relacionamento. O dado da ação será o tipo do objeto + OBJETO_RELACAO somado ao tipo do relacionamento (1-1,1-n,n-n,dep,gen). O tipo do + relacionamento é obtido posteriormente quando o usuário clica na ação para + criação do tipo desejado de relação, vide implementação de exibirFormObjeto() */ + acao=new QAction(QIcon(QString(":/icones/icones/") + str_ico), str_txt, this); + acao->setData(QVariant(OBJETO_RELACAO + tipos_rel[i])); + + connect(acao, SIGNAL(triggered(bool)), this, SLOT(adicionarNovoObjeto(void))); + menu_rels->addAction(acao); + } + + connect(action_codigo_fonte, SIGNAL(triggered(bool)), this, SLOT(exibirCodigoFonte(void))); + connect(action_editar, SIGNAL(triggered(bool)),this,SLOT(editarObjeto(void))); + connect(action_proteger, SIGNAL(triggered(bool)),this,SLOT(protegerObjeto(void))); + connect(action_desproteger, SIGNAL(triggered(bool)),this,SLOT(protegerObjeto(void))); + connect(action_excluir, SIGNAL(triggered(bool)),this,SLOT(excluirObjetos(void))); + connect(action_selecionar_todos, SIGNAL(triggered(bool)),this,SLOT(selecionarTodos(void))); + connect(action_converter_relnn, SIGNAL(triggered(bool)), this, SLOT(converterRelacionamentoNN(void))); + connect(action_deps_refs, SIGNAL(triggered(bool)), this, SLOT(exibirDepsRefs(void))); + connect(action_copiar, SIGNAL(triggered(bool)),this,SLOT(copiarObjetos(void))); + connect(action_colar, SIGNAL(triggered(bool)),this,SLOT(colarObjetos(void))); + connect(action_recortar, SIGNAL(triggered(bool)),this,SLOT(recortarObjetos(void))); + + connect(modelo, SIGNAL(s_objetoAdicionado(ObjetoBase*)), this, SLOT(manipularAdicaoObjeto(ObjetoBase *))); + connect(modelo, SIGNAL(s_objetoRemovido(ObjetoBase*)), this, SLOT(manipularRemocaoObjeto(ObjetoBase *))); + connect(cena, SIGNAL(s_objetosMovimentados(bool)), this, SLOT(manipularMovimentoObjetos(bool))); + connect(cena, SIGNAL(s_objetoModificado(ObjetoGraficoBase*)), this, SLOT(manipularModificacaoObjeto(ObjetoGraficoBase*))); + connect(cena, SIGNAL(s_objetoDuploClique(ObjetoGraficoBase*)), this, SLOT(manipularDuploCliqueObjeto(ObjetoGraficoBase*))); + connect(cena, SIGNAL(s_menupopupRequisitado(vector)), this, SLOT(exibirMenuObjetoTabela(vector))); + + connect(cena, SIGNAL(s_objetoSelecionado(ObjetoGraficoBase*,bool)), this, SLOT(configurarSelecaoObjetos(void))); + + viewport->horizontalScrollBar()->installEventFilter(this); + viewport->verticalScrollBar()->installEventFilter(this); +} +//---------------------------------------------------------- +ModeloWidget::~ModeloWidget(void) +{ + objs_copiados.clear(); + delete(viewport); + delete(cena); + delete(lista_op); + delete(modelo); +} +//---------------------------------------------------------- +void ModeloWidget::resizeEvent(QResizeEvent *) +{ + //Obtém o tamanho da cena + QRectF ret=cena->sceneRect(); + + /* Caso a largura/altura do viewport seja maior que a largura/altura é necessário + atualiza o tamanho da cena com os maiores valores de largura/altura */ + if(viewport->rect().width() > ret.width()) + ret.setWidth(viewport->rect().width()); + + if(viewport->rect().height() > ret.height()) + ret.setHeight(viewport->rect().height()); + + //Reconfigura o tamanho da cena + cena->setSceneRect(ret); +} +//---------------------------------------------------------- +bool ModeloWidget::eventFilter(QObject *objeto, QEvent *evento) +{ + //Filtra o evento Wheel caso seja disparado pelas barras de rolagem do viewport + if(evento->type() == QEvent::Wheel && + (objeto==viewport->horizontalScrollBar() || + (objeto==viewport->verticalScrollBar()))) + { + //Redireciona o evento para o wheelEvent() do modelo + this->wheelEvent(dynamic_cast(evento)); + return(true); + } + else + return(QWidget::eventFilter(objeto, evento)); +} +//---------------------------------------------------------- +void ModeloWidget::keyPressEvent(QKeyEvent *evento) +{ + //Cancela a ação de inserção do objeto quando ESC é pressionado + if(evento->key()==Qt::Key_Escape) + { + this->cancelarAdicaoObjeto(); + cena->clearSelection(); + } +} +//---------------------------------------------------------- +void ModeloWidget::mousePressEvent(QMouseEvent *evento) +{ + //Caso o usuário pressione o botão direito exibe o menu popup na posição do cursor + if(evento->buttons()==Qt::RightButton) + { + menu_popup.exec(QCursor::pos()); + //cancelarAdicaoObjeto(); + } + //Caso o usuário pressione o botão esquerdo + else if(evento->buttons()==Qt::LeftButton) + { + /* Se estiver inserindo um novo objeto (tipo_novo_objeto!=OBJETO_BASE), + o clique do mouse indica que o usuário deseja inserir um objeto na posição + do cursor, assim o cursor tem seu ícone alterado para o padrão (ArrowCursor) + e o formulário do tipo de objeto a ser inserido é exibido */ + if(tipo_novo_obj==OBJETO_TABELA || tipo_novo_obj==OBJETO_CAIXA_TEXTO || + tipo_novo_obj==OBJETO_VISAO) + { + this->exibirFormObjeto(tipo_novo_obj, NULL, NULL, + viewport->mapToScene(evento->pos())); + this->cancelarAdicaoObjeto(); + } + } +} +//---------------------------------------------------------- +void ModeloWidget::focusInEvent(QFocusEvent *evento) +{ + cena->update(); + QWidget::focusInEvent(evento); +} +//---------------------------------------------------------- +void ModeloWidget::wheelEvent(QWheelEvent * evento) +{ + if(evento->modifiers()==Qt::ControlModifier) + { + //Delta < 0 indica que o usuário rolou o wheel para baixo + if(evento->delta() < 0) + //Diminui o zoom + this->aplicarZoom(this->zoom_atual - INC_ZOOM); + else + //Aumenta o zoom + this->aplicarZoom(this->zoom_atual + INC_ZOOM); + } +} +//---------------------------------------------------------- +void ModeloWidget::aplicarZoom(float zoom) +{ + //Aplica o zoom somente se este for válido + if(zoom >= ZOOM_MINIMO && zoom <= ZOOM_MAXIMO) + { + //Reinicia a matriz de tranformação do viewport + viewport->resetTransform(); + //Aplica a matriz de escala para ampliar/reduzir a visão + viewport->scale(zoom, zoom); + //Armazena o zoom aplicado como atual + this->zoom_atual=zoom; + + emit s_zoomModificado(); + } +} +//---------------------------------------------------------- +float ModeloWidget::zoomAtual(void) +{ + return(zoom_atual); +} +//---------------------------------------------------------- +void ModeloWidget::manipularAdicaoObjeto(ObjetoBase *objeto) +{ + //Converte o objeto base para objeto gráfico + ObjetoGraficoBase *obj_graf=dynamic_cast(objeto); + + //Caso seja um objeto gráfico + if(obj_graf) + { + TipoObjetoBase tipo_obj=obj_graf->obterTipoObjeto(); + QGraphicsItem *item=NULL; + + //Cria um objeto gráfico na cena conforme o tipo do objeto base + switch(tipo_obj) + { + case OBJETO_TABELA: + item=new OGTabela(dynamic_cast(obj_graf)); + break; + + case OBJETO_VISAO: + item=new OGVisao(dynamic_cast(obj_graf)); + break; + + case OBJETO_RELACAO: + case OBJETO_RELACAO_BASE: + item=new OGRelacionamento(dynamic_cast(obj_graf)); break; + break; + + default: + item=new OGCaixaTexto(dynamic_cast(obj_graf)); break; + break; + } + + //Após a criação do objeto o mesmo é inserido na cena + cena->addItem(item); + } + + this->modificado=true; +} +//---------------------------------------------------------- +void ModeloWidget::adicionarNovoObjeto(void) +{ + //Obtém a ação de chamou o slot + QAction *acao=dynamic_cast(sender()); + + if(acao) + { + ObjetoBase *objeto_pai=NULL; + //Obtém o tipo do objeto que necessita ser inserido no modelo + TipoObjetoBase tipo_obj=static_cast(acao->data().toUInt()); + + /* Caso haja um objeto selecionado e o tipo do objeto for um dos + tipos de objetos de tabela, o objeto selecionado é a própria + tabela que receberá o objeto, sendo assim o referência 'objeto_pai' recebe + a própria tabela */ + if(objs_selecionados.size()==1 && + (tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_RESTRICAO || + tipo_obj==OBJETO_GATILHO || tipo_obj==OBJETO_INDICE || + tipo_obj==OBJETO_REGRA)) + objeto_pai=objs_selecionados[0]; + + /* Caso o tipo de objeto a ser inserido não seja visão, tabela ou caixa de texto + exibe o formulário de criação do objeto */ + if(tipo_obj!=OBJETO_TABELA && tipo_obj!=OBJETO_VISAO && + tipo_obj!=OBJETO_CAIXA_TEXTO && tipo_obj <= OBJETO_TABELA_BASE) + this->exibirFormObjeto(tipo_obj, NULL, objeto_pai); + else + { + /* Para os tipos tabela, visão e caixa de texto o processo de criação é + diferente: o usuário precisa clicar no ícone do objeto (no meno novo objeto) + e clicar no modelo. Ao clicar no menu o cursor do mouse é modificado com + o ícone do tipo de objeto a ser criado */ + viewport->setCursor(QCursor(acao->icon().pixmap(),0,0)); + //Armazena o tipo do objeto a ser criado pois este é referenciado no mousePressEvent() */ + this->tipo_novo_obj=tipo_obj; + this->desabilitarAcoesModelo(); + } + } +} +//---------------------------------------------------------- +void ModeloWidget::manipularRemocaoObjeto(ObjetoBase *objeto) +{ + ObjetoGraficoBase *obj_graf=dynamic_cast(objeto); + + //Caso o objeto seja gráfico remove-o da cena + if(obj_graf) + //Remove o objeto obtendo a referência ao objeto receptor (representação gráfico do mesmo na cena) + cena->removeItem(dynamic_cast(obj_graf->obterObjetoReceptor())); + + this->modificado=true; +} +//---------------------------------------------------------- +void ModeloWidget::manipularDuploCliqueObjeto(ObjetoGraficoBase *objeto) +{ + if(objeto) + this->exibirFormObjeto(objeto->obterTipoObjeto(), objeto, NULL, objeto->obterPosicaoObjeto()); +} +//---------------------------------------------------------- +void ModeloWidget::manipularMovimentoObjetos(bool fim_movimento) +{ + /* O parâmetro fim_movimento indica se a operação de movimentação de objetos + foi finalizada. Quando este parâmetro é false, indica que a movimentação + foi iniciada, desta forma os objetos são adicionados à lista de operações + antes do movimento acontecer */ + if(!fim_movimento) + { + vector ::iterator itr, itr_end; + ObjetoGraficoBase *obj=NULL; + + itr=objs_selecionados.begin(); + itr_end=objs_selecionados.end(); + + //Inicia um encadeamento de operações + lista_op->iniciarEncadeamentoOperacoes(); + + //Varre a lista de objetos selec + while(itr!=itr_end) + { + obj=dynamic_cast(*itr); + if(!dynamic_cast(obj) && (obj && !obj->objetoProtegido())) + lista_op->adicionarObjeto(obj, Operacao::OBJETO_MOVIMENTADO); + + itr++; + } + } + else + { + //Caso seja o final do movimento finaliza o encadeamento de operações + lista_op->finalizarEncadeamentoOperacoes(); + this->modificado=true; + //Emite um sinal indicando que objetos foram movimentados + emit s_objetosMovimentados(); + } +} +//---------------------------------------------------------- +void ModeloWidget::manipularModificacaoObjeto(ObjetoGraficoBase *objeto) +{ + //Adciona o objeto modificado à lista de operações + lista_op->adicionarObjeto(objeto, Operacao::OBJETO_MODIFICADO); + this->modificado=true; + //Emite um sinal indicando que um objeto foi modificado + emit s_objetoModificado(); +} +//---------------------------------------------------------- +void ModeloWidget::configurarSelecaoObjetos(void) +{ + QList itens=cena->selectedItems(); + ObjetoGrafico *item=NULL; + map mapa_objs; + deque vet_ordenacao; + + //Limpa a lista atual de objetos selecionados + objs_selecionados.clear(); + + //Armazena em um vector os objetos de origem dos objetos gráficos da cena + while(!itens.isEmpty()) + { + //Obtém um item da lista de objetos da cena + item=dynamic_cast(itens.front()); + itens.pop_front(); + + if(item) + { + //Armazena o objeto origem da representação gráfica no mapa para ordenação posterior + mapa_objs[item->obterOrdemSelecao()]=item; + vet_ordenacao.push_front(item->obterOrdemSelecao()); + } + } + + //Ordena os ids de seleção obtidos anteriomente + std::sort(vet_ordenacao.begin(), vet_ordenacao.end()); + + //Armazena os objetos no vetor de objetos selecionados obtendo cada um em ordem se seleção + while(!vet_ordenacao.empty()) + { + //Armazena o objeto origem da representação gráfica na lista de objetos selecionados + item=dynamic_cast(mapa_objs[vet_ordenacao.front()]); + objs_selecionados.push_back(item->obterObjetoOrigem()); + vet_ordenacao.pop_front(); + } + + /* Caso o tipo de novo objeto seja um valor acima de OBJETO_TABELA_BASE + indica que o usuário selecionou/deselecionou um objeto usando a ferramenta + de adição de relacionamento */ + if(tipo_novo_obj > OBJETO_TABELA_BASE) + { + unsigned qtd=objs_selecionados.size(); + TipoObjetoBase tipo_obj1, tipo_obj2; + + //Caso haja mais de 2 objeto selecionados, cancela a operação + if(qtd > 2 || qtd==0) + this->cancelarAdicaoObjeto(); + //Caso haja 1 ou dois objetos selecionados + else if(qtd >=1 && qtd <=2) + { + //Obtém os tipos dos objetos + tipo_obj1=objs_selecionados[0]->obterTipoObjeto(); + tipo_obj2=(qtd==2 ? objs_selecionados[1]->obterTipoObjeto() : OBJETO_BASE); + + //Caso haja apenas 1 objeto selecionado ativa a linha que simula a criação do relacionamento + if(qtd==1 && tipo_obj1==OBJETO_TABELA && + tipo_novo_obj > OBJETO_TABELA_BASE && + QApplication::keyboardModifiers()==0) + { + ObjetoGraficoBase *obj_graf=dynamic_cast(objs_selecionados[0]); + ObjetoGrafico *objeto=dynamic_cast(obj_graf->obterObjetoReceptor()); + + cena->exibirLinhaRelacionamento(true, + QPointF(objeto->scenePos().x() + objeto->boundingRect().width()/2, + objeto->scenePos().y() + objeto->boundingRect().height()/2)); + } + //Caso o usuário seleciona objetos que não sejam tabelas cancela a operação + else if(tipo_obj1!=OBJETO_TABELA || + (tipo_obj2!=OBJETO_TABELA && tipo_obj2!=OBJETO_BASE)) + { + this->cancelarAdicaoObjeto(); + } + + /* Caso haja apenas 1 objeto selecionado e o SHIFT esteja pressionado, cria um auto relacionamento ou + se houver 2 objetos selecionados (tabelas) cria um relacionamento entre eles */ + else if((qtd==1 && tipo_obj1==OBJETO_TABELA && QApplication::keyboardModifiers()==Qt::ShiftModifier) || + (qtd==2 && tipo_obj1==OBJETO_TABELA && tipo_obj2==OBJETO_TABELA)) + { + //Exibe o form de edição de relacionamento + this->exibirFormObjeto(tipo_novo_obj); + //Cancela a operação restaurando o estado original das ações + this->cancelarAdicaoObjeto(); + } + } + } + else + this->configurarMenuPopup(objs_selecionados); +} +//---------------------------------------------------------- +void ModeloWidget::selecionarTodos(void) +{ + QPainterPath pth; + /* Cria um QPainterPath com as dimensões do tamanho total da cena, + desta forma todos os objetos dentro do retângulo formado serão + selecionados com o método cena->setSelectionArea() */ + pth.addRect(cena->sceneRect()); + cena->setSelectionArea(pth); +} +//---------------------------------------------------------- +void ModeloWidget::converterRelacionamentoNN(void) +{ + //Obtém o relacionamento a ser convertido da ação que disparou o método + Relacionamento *rel=reinterpret_cast(action_converter_relnn->data().value()); + + if(rel) + { + unsigned qtd_op, qtd; + + //Só converte o relacionamento caso este seja n-n + if(rel->obterTipoRelacionamento()==Relacionamento::RELACIONAMENTO_NN) + { + try + { + Relacionamento *rel1=NULL, *rel2=NULL; + Tabela *tab=NULL, *tab_nn=NULL, + *tab_orig=dynamic_cast(rel->obterTabela(Relacionamento::TABELA_ORIGEM)), + *tab_dest=dynamic_cast(rel->obterTabela(Relacionamento::TABELA_DESTINO)); + Restricao *rest=NULL, *rest_aux=NULL; + Coluna *col=NULL; + bool obrig_orig=true,//rel->tabelaObrigatoria(Relacionamento::TABELA_ORIGEM), + obrig_dest=true;//rel->tabelaObrigatoria(Relacionamento::TABELA_DESTINO); + QString nome_rel, nome_tab, xml_tab; + QPointF pnt; + unsigned i=1, idx, qtd, idx1, qtd1, x; + + qtd_op=lista_op->obterTamanhoAtual(); + + //Obtém o xml que define a tabela do relacionamento + tab_nn=rel->obterTabelaReceptora(); + xml_tab=tab_nn->obterDefinicaoObjeto(ParserEsquema::DEFINICAO_XML); + + //Cria a mesma a partir do xml + ParserXML::reiniciarParser(); + ParserXML::carregarBufferXML(xml_tab); + tab=modelo->criarTabela(); + nome_tab=tab->obterNome(); + + /* Caso haja outras tabelas no modelo com o nome da tabela recém criada a mesma terá + seu nome alterado até que não existam tabelas com mesmo nome que ela */ + while(modelo->obterObjeto(tab->obterNome(true), OBJETO_TABELA)) + { + tab->definirNome(nome_tab + QString("_%1").arg(i)); + i++; + } + + //Copia os atributos do relacionamento n-n para a tabela gerada + qtd=rel->obterNumAtributos(); + for(idx=0; idx < qtd; idx++) + { + col=new Coluna; + (*col)=(*rel->obterAtributo(idx)); + col->definirTabelaPai(NULL); + tab->adicionarColuna(col); + } + + //Copia as restrições do relacionamento n-n para a tabela gerada + qtd=rel->obterNumRestricoes(); + for(idx=0; idx < qtd; idx++) + { + rest=new Restricao; + rest_aux=rel->obterRestricao(idx); + (*rest)=(*rest_aux); + rest->removerColunas(); + rest->definirTabelaPai(NULL); + + for(x=Restricao::COLUNA_ORIGEM; x <= Restricao::COLUNA_REFER; x++) + { + qtd1=rest_aux->obterNumColunas(x); + for(idx1=0; idx1 < qtd1; idx1++) + { + col=tab->obterColuna(rest_aux->obterColuna(idx, x)->obterNome()); + if(col) rest->adicionarColuna(col, x); + } + } + tab->adicionarRestricao(rest); + } + + //Inicia o encadeamento de operaçẽos + lista_op->iniciarEncadeamentoOperacoes(); + + //Remove o relacionamento n-n do modelo + modelo->removerObjeto(rel); + //Adiciona-o à lista de operações + lista_op->adicionarObjeto(rel, Operacao::OBJETO_REMOVIDO); + + //A posição padrão da tabela originada será o ponto médio entre as tabelas participantes do relacionamento + pnt.setX((tab_orig->obterPosicaoObjeto().x() + tab_dest->obterPosicaoObjeto().x())/2.0f); + pnt.setY((tab_orig->obterPosicaoObjeto().y() + tab_dest->obterPosicaoObjeto().y())/2.0f); + tab->definirPosicaoObjeto(pnt); + + //Adiciona a tabela criada ao modelo + modelo->adicionarObjeto(tab); + //Adiciona uma operação à lista de operações indicando a criação da tabela + lista_op->adicionarObjeto(tab, Operacao::OBJETO_CRIADO); + + //Aloca um relacionamento entre a nova tabela e a tabela de origem do relacionamento + nome_rel=QString("rel_") + tab->obterNome(false) + QString("_") + tab_orig->obterNome(false); + rel1=new Relacionamento(nome_rel, Relacionamento::RELACIONAMENTO_1N, + tab_orig, tab, obrig_orig, false, + rel->obterSufixoTabela(Relacionamento::TABELA_ORIGEM), + "", true); + + //Adiciona o relacionamento criado ao modelo e à lista de operações + modelo->adicionarRelacionamento(rel1); + lista_op->adicionarObjeto(rel1, Operacao::OBJETO_CRIADO); + + //Aloca um relacionamento entre a nova tabela e a tabela de destino do relacionamento + nome_rel=QString("rel_") + tab->obterNome() + QString("_") + tab_dest->obterNome(); + if(rel->autoRelacionamento()) + nome_rel+=QString("1"); + + rel2=new Relacionamento(nome_rel, Relacionamento::RELACIONAMENTO_1N, + tab_dest, tab, obrig_dest, false, + rel->obterSufixoTabela(Relacionamento::TABELA_DESTINO), + "", true); + + //Adiciona o relacionamento criado ao modelo e à lista de operações + modelo->adicionarRelacionamento(rel2); + lista_op->adicionarObjeto(rel2, Operacao::OBJETO_CRIADO); + + //Finaliza o encademanento de operações + lista_op->finalizarEncadeamentoOperacoes(); + + emit s_objetoCriado(); + } + catch(Excecao &e) + { + if(qtd_op < lista_op->obterTamanhoAtual()) + { + //Obtém a quantidade de operações que necessitam ser removidas + qtd=lista_op->obterTamanhoAtual()-qtd_op; + + /* Anula o encadeamento de operações para que as mesmas seja + desfeitas uma a uma ignorando o encadeamento */ + lista_op->anularEncadeamentoOperacoes(true); + + /* Desfaz as operações na quantidade calculada e remove a + operação da lista */ + for(unsigned i=0; i < qtd; i++) + { + lista_op->desfazerOperacao(); + lista_op->removerUltimaOperacao(); + } + + //Desfaz a anulação do encadeamento + lista_op->anularEncadeamentoOperacoes(false); + } + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } + } + } +} +//---------------------------------------------------------- +void ModeloWidget::carregarModelo(const QString &nome_arq) +{ + try + { + //Configura o widget de progresso para exibir o progresso de carregamento do modelo + connect(modelo, SIGNAL(s_objetoCarregado(int,QString,unsigned)), prog_tarefa, SLOT(executarProgesso(int,QString,unsigned))); + prog_tarefa->setWindowTitle(trUtf8("Carregando modelo de banco de dados")); + + //Carrega o arquivo + modelo->carregarModelo(nome_arq); + this->nome_arquivo=nome_arq; + + //Ajusta o tamanho da cena + this->ajustarTamanhoCena(); + + prog_tarefa->close(); + disconnect(modelo, NULL, prog_tarefa, NULL); + + modelo_protegido_frm->setVisible(modelo->objetoProtegido()); + this->modificado=false; + } + catch(Excecao &e) + { + prog_tarefa->close(); + disconnect(modelo, NULL, prog_tarefa, NULL); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ModeloWidget::ajustarTamanhoCena(void) +{ + QRectF ret_cena, ret_objs; + bool alin_objs, exibir_grade, exibir_lim_pag; + + CenaObjetos::obterOpcoesGrade(exibir_grade, alin_objs, exibir_lim_pag); + + /* Reconfigura o retângulo da cena, para isso obtem-se o boundingRect + de todos os itens juntos e caso esse retangulo seja maior que o + da cena o mesmo será o novo retângulo da cena */ + ret_cena=cena->sceneRect(); + ret_objs=cena->itemsBoundingRect(); + + if(ret_cena.width() < ret_objs.left() + ret_objs.width()) + ret_cena.setWidth(ret_objs.left() + ret_objs.width()); + + if(ret_cena.height() < ret_objs.top() + ret_objs.height()) + ret_cena.setHeight(ret_objs.top() + ret_objs.height()); + + cena->setSceneRect(ret_cena); + viewport->centerOn(0,0); + + //Alinha os objetos à grade caso a opção esteja ativa + if(alin_objs) + cena->alinharObjetosGrade(); +} +//---------------------------------------------------------- +vector ModeloWidget::obterPaginasImpressao(const QSizeF &tam_papel, unsigned &qtd_pag_h, unsigned &qtd_pag_v) +{ + vector paginas; + QRectF ret_pagina, ret_pmax; + float larg, alt; + unsigned pag_h, pag_v; + + //Calcula a quantidade de páginas horizontais e verticais com base no tamanho do papel passado + qtd_pag_h=roundf(cena->sceneRect().width()/tam_papel.width()) + 1; + qtd_pag_v=roundf(cena->sceneRect().height()/tam_papel.height()) + 1; + + //Calcula a quantidade máxima de paginas horizontas e verticais + for(pag_v=0; pag_v < qtd_pag_v; pag_v++) + { + for(pag_h=0; pag_h < qtd_pag_h; pag_h++) + { + //Calcula o retângulo da página atual (horizontal x vertical) + ret_pagina=QRectF(QPointF(pag_h * tam_papel.width(), pag_v * tam_papel.height()), tam_papel); + + //Caso na pagina atual existam items selecionados, recaulcula o tamanho máximo de página + if(!cena->items(ret_pagina).isEmpty()) + { + //Calcula a largura/altura da página atual + larg=ret_pagina.left() + ret_pagina.width(); + alt=ret_pagina.top() + ret_pagina.height(); + + /* Caso a largura calculada exceda a largura/altura máxima calculada anterior, a mesma passa + a ser usada como largura/altura máxima */ + if(larg > ret_pmax.width()) + ret_pmax.setWidth(larg); + + if(alt > ret_pmax.height()) + ret_pmax.setHeight(alt); + } + } + } + + //Recalcula a quantidade de páginas com base no tamanho de página calculado + qtd_pag_h=roundf(ret_pmax.width()/tam_papel.width()); + qtd_pag_v=roundf(ret_pmax.height()/tam_papel.height()); + + //Adiciona os retângulos de cada página no vetor + for(pag_v=0; pag_v < qtd_pag_v; pag_v++) + for(pag_h=0; pag_h < qtd_pag_h; pag_h++) + paginas.push_back(QRectF(QPointF(pag_h * tam_papel.width(), pag_v * tam_papel.height()), tam_papel)); + + return(paginas); +} +//---------------------------------------------------------- +void ModeloWidget::imprimirModelo(QPrinter *printer, bool exibir_grade_imp, bool imp_num_pag) +{ + if(printer) + { + bool exibir_grade, alin_grade, exibir_lim_pag; + unsigned qtd_pag, pag, qtd_pag_h, qtd_pag_v, id_pag_h, id_pag_v; + vector paginas; + QSizeF tam_pagina; + QPen pen; + QFont fonte; + QPointF sup_esq, sup_dir, inf_esq, inf_dir, + meio_h_sup, meio_h_inf, meio_v_esq, meio_v_dir, dx, dy; + + //Faz um backup das configurações de grade da cena + CenaObjetos::obterOpcoesGrade(exibir_grade, alin_grade, exibir_lim_pag); + + //Reconfigura a grade do modelo com as opções passadas, escondendo os limites de página + CenaObjetos::definirOpcoesGrade(exibir_grade_imp, alin_grade, false); + + //Atualiza o cena e limpa a seleção + cena->update(); + cena->clearSelection(); + + //Obtém o tamanho de página com base na configuração da impressora + tam_pagina=printer->pageRect(QPrinter::DevicePixel).size(); + + //Obtém a quantinde de páginas com base no tamanho da página + paginas=this->obterPaginasImpressao(tam_pagina, qtd_pag_h, qtd_pag_v); + + //Cria um painter para desenhar direto na impressoa + QPainter painter(printer); + painter.setRenderHint(QPainter::Antialiasing); + fonte.setPointSizeF(7.5f); + pen.setColor(QColor(120,120,120)); + pen.setWidthF(1.0f); + + //Calcula os pontos auxiliares para desenhar as linhas delmitadores de página + sup_esq.setX(01); sup_esq.setY(0); + sup_dir.setX(tam_pagina.width()); sup_dir.setY(0); + inf_esq.setX(0); inf_esq.setY(tam_pagina.height()); + inf_dir.setX(sup_dir.x()); inf_dir.setY(inf_esq.y()); + meio_h_sup.setX(tam_pagina.width()/2); meio_h_sup.setY(0); + meio_h_inf.setX(meio_h_sup.x()); meio_h_inf.setY(inf_dir.y()); + meio_v_esq.setX(sup_esq.x()); meio_v_esq.setY(tam_pagina.height()/2); + meio_v_dir.setX(sup_dir.x()); meio_v_dir.setY(meio_v_esq.y()); + dx.setX(10); + dy.setY(10); + + qtd_pag=paginas.size(); + for(pag=0, id_pag_h=0, id_pag_v=0; pag < qtd_pag; pag++) + { + //Desenha a página atual na impressora + cena->render(&painter, QRectF(), paginas[pag]); + + /* Caso seja para imprimir o número de página + a mesma será impressa no canto superoir esquerdo */ + if(imp_num_pag) + { + painter.setPen(QColor(120,120,120)); + painter.drawText(10, 20, QString("%1").arg(pag+1)); + } + + //Imprime as linhas guias de página com base na pagina atual (posição vertical e horizontal) + painter.setPen(pen); + if(id_pag_h==0 && id_pag_v==0) + { + painter.drawLine(sup_esq, sup_esq + dx); + painter.drawLine(sup_esq, sup_esq + dy); + } + + if(id_pag_h==qtd_pag_h-1 && id_pag_v==0) + { + painter.drawLine(sup_dir, sup_dir - dx); + painter.drawLine(sup_dir, sup_dir + dy); + } + + if(id_pag_h==0 && id_pag_v==qtd_pag_v-1) + { + painter.drawLine(inf_esq, inf_esq + dx); + painter.drawLine(inf_esq, inf_esq - dy); + } + + if(id_pag_h==qtd_pag_h-1 && id_pag_v==qtd_pag_v-1) + { + painter.drawLine(inf_dir, inf_dir - dx); + painter.drawLine(inf_dir, inf_dir - dy); + } + + if(id_pag_h >=1 && id_pag_h < qtd_pag_h-1 && id_pag_v==0) + { + painter.drawLine(meio_h_sup, meio_h_sup - dx); + painter.drawLine(meio_h_sup, meio_h_sup + dx); + } + + if(id_pag_h >=1 && id_pag_h < qtd_pag_h-1 && id_pag_v==qtd_pag_v-1) + { + painter.drawLine(meio_h_inf, meio_h_inf - dx); + painter.drawLine(meio_h_inf, meio_h_inf + dx); + } + + if(id_pag_v >=1 && id_pag_v < qtd_pag_v-1 && id_pag_h==0) + { + painter.drawLine(meio_v_esq, meio_v_esq - dy); + painter.drawLine(meio_v_esq, meio_v_esq + dy); + } + + if(id_pag_v >=1 && id_pag_v < qtd_pag_v-1 && id_pag_h==qtd_pag_h-1) + { + painter.drawLine(meio_v_dir, meio_v_dir - dy); + painter.drawLine(meio_v_dir, meio_v_dir + dy); + } + + id_pag_h++; + + if(id_pag_h==qtd_pag_h) + { + id_pag_h=0; + id_pag_v++; + } + + //Adiciona uma nova página enquanto a página não for a penultmima + if(pag < qtd_pag-1) + printer->newPage(); + } + + //Restaura as opções da grade + CenaObjetos::definirOpcoesGrade(exibir_grade, alin_grade, exibir_lim_pag); + cena->update(); + } +} +//---------------------------------------------------------- +void ModeloWidget::salvarModelo(void) +{ + salvarModelo(this->nome_arquivo); +} + //---------------------------------------------------------- +void ModeloWidget::salvarModelo(const QString &nome_arq) +{ + try + { + //Configura o widget de progresso de tarefa para exibir o progresso do salvamento do arquivo + connect(modelo, SIGNAL(s_objetoCarregado(int,QString,unsigned)), prog_tarefa, SLOT(executarProgesso(int,QString,unsigned))); + prog_tarefa->setWindowTitle(trUtf8("Salvando modelo de banco de dados")); + + //Salva o modelo em arquivo + modelo->salvarModelo(nome_arq, ParserEsquema::DEFINICAO_XML); + this->nome_arquivo=nome_arq; + + //Fecha o widget de progresso de tarefa + prog_tarefa->close(); + disconnect(modelo, NULL, prog_tarefa, NULL); + this->modificado=false; + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +QString ModeloWidget::obterNomeArquivo(void) +{ + return(this->nome_arquivo); +} +//---------------------------------------------------------- +void ModeloWidget::exibirFormObjeto(TipoObjetoBase tipo_obj, ObjetoBase *objeto, ObjetoBase *objeto_pai, QPointF pos) +{ + try + { + unsigned tipo_rel=0; + + /* Caso o tipo_obj seja maior que o ultimo código de tipo de objeto, indica + que se trata de um tipo específico de relacionamento (1-1, 1-n, n-n, gen, dep). + Para se obter qual o tipo correto do relacionamento, subtrai-se o tipo do objeto + padrão, OBJETO_RELACAO ao tipo_obj, o resultado da subtração será o tipo + específico de relacionamento */ + if(tipo_obj > OBJETO_TABELA_BASE) + { + tipo_rel=tipo_obj - OBJETO_RELACAO; + tipo_obj=OBJETO_RELACAO; + } + + + if(objeto && tipo_obj!=objeto->obterTipoObjeto()) + throw Excecao(ERR_PGMODELER_OPROBJTIPOINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + /* Caso se tente chamar o formulário de criação de um objeto de tabela + sem se especificar a tabela pai (objeto_pai) */ + else if(!objeto_pai && + (tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_RESTRICAO || + tipo_obj==OBJETO_GATILHO || tipo_obj==OBJETO_REGRA || + tipo_obj==OBJETO_INDICE)) + throw Excecao(ERR_PGMODELER_OPROBJNAOALOC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + /* Caso o objeto esteja alocado e seja gráfico indica que o mesmo será editado, + sendo assim sua posição precisa ser armazena e em seguida informada ao + formulário de edição respectivo */ + if(objeto && dynamic_cast(objeto)) + pos=dynamic_cast(objeto)->obterPosicaoObjeto(); + + /* O esquema 'public' e as linguagens C e SQL não pode ser manipuladas + por serem do sistema, caso o usuário tente esta operação um erro será disparado */ + if(objeto && + ((tipo_obj==OBJETO_LINGUAGEM && + (objeto->obterNome()==~TipoLinguagem("c") || + objeto->obterNome()==~TipoLinguagem("sql") || + objeto->obterNome()==~TipoLinguagem("plpgsql"))) || + (tipo_obj==OBJETO_ESQUEMA && + objeto->obterNome()=="public"))) + throw Excecao(ERR_PGMODELERUI_OPROBJRESERVADO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + switch(tipo_obj) + { + case OBJETO_ESQUEMA: + esquema_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + esquema_wgt->show(); + break; + + case OBJETO_PAPEL: + papel_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + papel_wgt->show(); + break; + + case OBJETO_ESPACO_TABELA: + espacotabela_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + espacotabela_wgt->show(); + break; + + case OBJETO_LINGUAGEM: + linguagem_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + linguagem_wgt->show(); + break; + + case OBJETO_FUNCAO: + funcao_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + funcao_wgt->show(); + break; + + case OBJETO_CONV_TIPO: + convtipo_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + convtipo_wgt->show(); + break; + + case OBJETO_CONV_CODIFICACAO: + convcodif_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + convcodif_wgt->show(); + break; + + case OBJETO_DOMINIO: + dominio_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + dominio_wgt->show(); + break; + + case OBJETO_FUNC_AGREGACAO: + funcaoag_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + funcaoag_wgt->show(); + break; + + case OBJETO_SEQUENCIA: + sequencia_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + sequencia_wgt->show(); + break; + + case OBJETO_OPERADOR: + operador_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + operador_wgt->show(); + break; + + case OBJETO_FAMILIA_OPER: + familiaop_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + familiaop_wgt->show(); + break; + + case OBJETO_CLASSE_OPER: + classeop_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + classeop_wgt->show(); + break; + + case OBJETO_TIPO: + tipo_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + tipo_wgt->show(); + break; + + case OBJETO_VISAO: + Visao *visao; + visao=dynamic_cast(objeto); + visao_wgt->definirAtributos(modelo, lista_op, visao, pos.x(), pos.y()); + visao_wgt->show(); + break; + + case OBJETO_CAIXA_TEXTO: + CaixaTexto *caixa; + caixa=dynamic_cast(objeto); + caixatexto_wgt->definirAtributos(modelo, lista_op, caixa, pos.x(), pos.y()); + caixatexto_wgt->show(); + break; + + case OBJETO_COLUNA: + Coluna *coluna; + coluna=dynamic_cast(objeto); + coluna_wgt->definirAtributos(modelo, objeto_pai, lista_op, coluna); + coluna_wgt->show(); + + //Valida os relacionamento para refletirem as modificações na coluna + if(coluna) + modelo->validarRelacObjetoTabela(coluna, dynamic_cast(objeto_pai)); + else + modelo->validarRelacionamentos(); + break; + + case OBJETO_RESTRICAO: + Restricao *restricao; + restricao=dynamic_cast(objeto); + restricao_wgt->definirAtributos(modelo, dynamic_cast(objeto_pai), lista_op, restricao); + restricao_wgt->show(); + + //Valida os relacionamento para refletirem as modificações na restrição + if(restricao) + modelo->validarRelacObjetoTabela(restricao, dynamic_cast(objeto_pai)); + else + modelo->validarRelacionamentos(); + break; + + case OBJETO_REGRA: + regra_wgt->definirAtributos(modelo, dynamic_cast(objeto_pai), lista_op, dynamic_cast(objeto)); + regra_wgt->show(); + break; + + case OBJETO_GATILHO: + gatilho_wgt->definirAtributos(modelo, dynamic_cast(objeto_pai), lista_op, dynamic_cast(objeto)); + gatilho_wgt->show(); + break; + + case OBJETO_INDICE: + indice_wgt->definirAtributos(modelo, dynamic_cast(objeto_pai), lista_op, dynamic_cast(objeto)); + indice_wgt->show(); + break; + + case OBJETO_RELACAO_BASE: + case OBJETO_RELACAO: + + /* Na criação de relacionamentos, o usuário precisa selecionar 2 tabelas ou + 1 quando se tratar de autorelacionamento */ + if(!objeto && tipo_rel > 0 && + objs_selecionados.size() > 0 && + objs_selecionados[0]->obterTipoObjeto()==OBJETO_TABELA) + { + Tabela *tab1=dynamic_cast(objs_selecionados[0]), + *tab2=(objs_selecionados.size()==2 ? + dynamic_cast(objs_selecionados[1]) : tab1); + relacao_wgt->definirAtributos(modelo, lista_op, tab1, tab2, tipo_rel); + } + else + relacao_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto)); + + relacao_wgt->show(); + break; + + case OBJETO_TABELA: + tabela_wgt->definirAtributos(modelo, lista_op, dynamic_cast(objeto), pos.x(), pos.y()); + tabela_wgt->show(); + break; + + default: + case OBJETO_BANCO_DADOS: + bancodados_wgt->definirAtributos(modelo); + bancodados_wgt->show(); + break; + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ModeloWidget::exibirDepsRefs(void) +{ + QAction *obj_sender=dynamic_cast(sender()); + + if(obj_sender) + { + //Obtém o objeto do modelo armazenado na ação + ObjetoBase *objeto=reinterpret_cast(obj_sender->data().value()); + + //Caso haja um objeto vindo da ação + if(objeto) + { + //Exibe o formulário de dependências / referências + deps_refs_wgt->definirAtributos(this->modelo, objeto); + deps_refs_wgt->show(); + } + } +} +//---------------------------------------------------------- +void ModeloWidget::exibirCodigoFonte(void) +{ + QAction *obj_sender=dynamic_cast(sender()); + + if(obj_sender) + { + //Obtém o objeto do modelo armazenado na ação + ObjetoBase *objeto=reinterpret_cast(obj_sender->data().value()); + + if(objeto) + { + //Exibe o formulário de código fonte do mesmo + codigofonte_wgt->definirAtributos(this->modelo, objeto); + codigofonte_wgt->show(); + } + } +} +//---------------------------------------------------------- +void ModeloWidget::cancelarAdicaoObjeto(void) +{ + /* Reinicia o tipo do objeto, isso fará com que o usuário escolha + novamente a ferramenta de criação de objeto */ + tipo_novo_obj=OBJETO_BASE; + //Restaura o cursor original do mouse + viewport->setCursor(QCursor(Qt::ArrowCursor)); + //Esconde a linha que simula a inserção de relacionamento + cena->exibirLinhaRelacionamento(false); + this->configurarMenuPopup(this->objs_selecionados); +} +//---------------------------------------------------------- +void ModeloWidget::editarObjeto(void) +{ + QObject *obj_sender=dynamic_cast(sender()); + ObjetoTabela *obj_tab=NULL; + ObjetoBase *objeto=NULL; + + /* Workaround: Para possibilitar a edição de objetos com duplo clique na visão de objetos + o sender é configurado como sendo a ação de editar quando este não está definido */ + if(!obj_sender) + obj_sender=action_editar; + + //Obtém o objeto do modelo contido na ação + objeto=reinterpret_cast(dynamic_cast(obj_sender)->data().value()); + /* Tenta convertê-lo para objeto de tabela. Caso este seja convertido com sucesso + envia para o formulário a tabela possuidora deste objeto */ + obj_tab=dynamic_cast(objeto); + + //Exibe o formulário pra o objeto + if(objeto) + exibirFormObjeto(objeto->obterTipoObjeto(), objeto, + (obj_tab ? obj_tab->obterTabelaPai() : NULL)); +} +//---------------------------------------------------------- +void ModeloWidget::protegerObjeto(void) +{ + try + { + QObject *obj_sender=sender(); + TipoObjetoBase tipo_obj; + ObjetoTabela *obj_tab=NULL; + ObjetoBase *objeto=NULL; + ObjetoGraficoBase *obj_graf=NULL; + bool proteger; + vector::iterator itr, itr_end; + + cena->blockSignals(true); + + //Caso haja apenas um objeto selecionado + if(this->objs_selecionados.size()==1) + { + //Tenta convertê-lo para objeto de tabela e objeto gráfico + obj_tab=dynamic_cast(this->objs_selecionados[0]); + obj_graf=dynamic_cast(this->objs_selecionados[0]); + + //Caso seja um objeto gráfico + if(obj_graf) + { + //Caso seja uma tabela, usa o método de proteção/desproteção da tabela + obj_graf->definirProtegido(!obj_graf->objetoProtegido()); + } + else if(obj_tab) + { + /* Caso seja um objto de tabela protege/desprotege o mesmo e marca como modificada a tabela pai + para forçar o seu redesenho */ + obj_tab->definirProtegido(!obj_tab->objetoProtegido()); + dynamic_cast(obj_tab->obterTabelaPai())->definirModificado(true); + } + else + { + /* O esquema 'public' e as linguagens C e SQL não pode ser manipuladas + por serem do sistema, caso o usuário tente esta operação um erro será disparado */ + if(this->objs_selecionados[0] && + ((this->objs_selecionados[0]->obterTipoObjeto()==OBJETO_LINGUAGEM && + (this->objs_selecionados[0]->obterNome()==~TipoLinguagem("c") || + this->objs_selecionados[0]->obterNome()==~TipoLinguagem("sql") || + this->objs_selecionados[0]->obterNome()==~TipoLinguagem("plpgsql"))) || + (this->objs_selecionados[0]->obterTipoObjeto()==OBJETO_ESQUEMA && + this->objs_selecionados[0]->obterNome()=="public"))) + throw Excecao(ERR_PGMODELERUI_OPROBJRESERVADO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + this->objs_selecionados[0]->definirProtegido(!this->objs_selecionados[0]->objetoProtegido()); + } + } + //Caso não haja objetos selecionados faz a proteção/desproteção do modelo + else if(this->objs_selecionados.empty()) + { + if(obj_sender==action_proteger || obj_sender==action_desproteger) + modelo->definirProtegido(!modelo->objetoProtegido()); + } + //Caso haja mais de um objeto selecionado, faz a proteção em lote + else + { + itr=this->objs_selecionados.begin(); + itr_end=this->objs_selecionados.end(); + proteger=(!this->objs_selecionados[0]->objetoProtegido()); + + while(itr!=itr_end) + { + objeto=(*itr); + obj_graf=dynamic_cast(objeto); + itr++; + + /* Caso o objeto seja uma coluna ou restrição adicionada automaticamente por um + relacionamento, um erro será disparado pois objetos deste tipo não pode + ser manipulados diretamente pelo usuário */ + tipo_obj=objeto->obterTipoObjeto(); + + /* O esquema 'public' e as linguagens C e SQL não pode ser manipuladas + por serem do sistema, caso o usuário tente esta operação um erro será disparado */ + if(objeto && + ((tipo_obj==OBJETO_LINGUAGEM && + (objeto->obterNome()==~TipoLinguagem("c") || + objeto->obterNome()==~TipoLinguagem("sql") || + objeto->obterNome()==~TipoLinguagem("plpgsql") )) || + (tipo_obj==OBJETO_ESQUEMA && + objeto->obterNome()=="public"))) + throw Excecao(ERR_PGMODELERUI_OPROBJRESERVADO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + else if(tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_RESTRICAO) + { + obj_tab=dynamic_cast(objeto); + if(obj_tab->incluidoPorRelacionamento()) + { + //Monta a mensagem de que o objeto não pode ser removido por estar protegido + throw Excecao(QString(Excecao::obterMensagemErro(ERR_PGMODELERUI_OPROBJINCRELACAO)) + .arg(objeto->obterNome()).arg(objeto->obterNomeTipoObjeto()), + ERR_PGMODELERUI_OPROBJINCRELACAO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + } + + objeto->definirProtegido(proteger); + } + } + + modelo_protegido_frm->setVisible(modelo->objetoProtegido()); + cena->blockSignals(false); + cena->clearSelection(); + + //Emite um sinal indica que vários objetos foram modificados + emit s_objetoModificado(); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ModeloWidget::recortarObjetos(void) +{ + /* Marca que o modelo de origem da operação de recorte foi o modelo 'this'. + Este atributo é usado no método de colagem dos objetos onde pois ao final + da execução é preciso excluir os objetos selecionados no modelo de origem */ + ModeloWidget::modelo_orig=this; + + //Marca que a operação de recorte foi iniciada + ModeloWidget::op_recortar=true; + + //Efetua a cópia dos objetos selecionados + this->copiarObjetos(); +} +//---------------------------------------------------------- +void ModeloWidget::copiarObjetos(void) +{ + map mapa_objs; + vector id_objs; + vector::iterator itr, itr_end; + vector::iterator itr1, itr1_end; + vector vet_deps; + ObjetoBase *objeto=NULL; + ObjetoTabela *obj_tab=NULL; + Tabela *tabela=NULL; + TipoObjetoBase tipos[]={ OBJETO_GATILHO, OBJETO_INDICE, OBJETO_RESTRICAO }; + unsigned i, id_tipo, qtd; + + //Solicia a confirmação ao usuário se o mesmo deseja copiar as dependências dos objetos + caixa_msg->show(trUtf8("Confirmação"), + trUtf8("Deseja copiar também todas dependências dos objetos selecionados? Isso minimiza a quebra de referências quando os objetos copiados forem colados em outro modelo."), + CaixaMensagem::ICONE_CONFIRM, CaixaMensagem::BOTAO_SIM_NAO); + + itr=objs_selecionados.begin(); + itr_end=objs_selecionados.end(); + + //Varre a lista de objetos selecionados + while(itr!=itr_end) + { + objeto=(*itr); + + //Relacionamentos Tabela-visão não são copiados pois são criados automaticamente pelo modelo + if(objeto->obterTipoObjeto()!=OBJETO_RELACAO_BASE) + { + //Obtém as dependências do objeto atual caso o usuário tenha confirmado a obtenção das mesmas + modelo->obterDependenciasObjeto(objeto, vet_deps, caixa_msg->result()==QDialog::Accepted); + + /* Caso especial para tabelas: É preciso copiar para a lista os objetos especiais + (indices, gatilhos e restrições) que referenciam colunas incluídas por relacionamento. + Para que seja possível a recriação dos mesmos quando colados */ + if(objeto->obterTipoObjeto()==OBJETO_TABELA) + { + tabela=dynamic_cast(objeto); + + for(id_tipo=0; id_tipo < 3; id_tipo++) + { + //Varre cada lista de objetos especiais validando-os e inserindo-os na lista de dependências + qtd=tabela->obterNumObjetos(tipos[id_tipo]); + + for(i=0; i < qtd; i++) + { + //Obtém um objeto especial + obj_tab=dynamic_cast(tabela->obterObjeto(i, tipos[id_tipo])); + + /* O objeto só será incluído na lista se o mesmo não foi incluído por relacionamento mas + referencia colunas incluídas por relacionamento. Caso se tratar de uma restrição, a mesma + não pode ser chave primária pois estas são tratadas separadamente nos relacionamentos */ + if(!obj_tab->incluidoPorRelacionamento() && + ((tipos[id_tipo]==OBJETO_RESTRICAO && + dynamic_cast(obj_tab)->obterTipoRestricao()!=TipoRestricao::primary_key && + dynamic_cast(obj_tab)->referenciaColunaIncRelacao()) || + (tipos[id_tipo]==OBJETO_GATILHO && dynamic_cast(obj_tab)->referenciaColunaIncRelacao()) || + (tipos[id_tipo]==OBJETO_INDICE && dynamic_cast(obj_tab)->referenciaColunaIncRelacao()))) + vet_deps.push_back(obj_tab); + } + } + } + } + itr++; + } + + /* Organiza por ordem crescente de id os objetos obtidos. Isso + evita a quebra de referências criando, por exemplo um objeto B de id 10 + antes do A de id 5, sendo que A necessita de B para ser validado */ + itr=vet_deps.begin(); + itr_end=vet_deps.end(); + + //Armazena os ids dos objetos num vetor numéros + while(itr!=itr_end) + { + objeto=(*itr); + id_objs.push_back(objeto->obterIdObjeto()); + mapa_objs[objeto->obterIdObjeto()]=objeto; + itr++; + } + + //O vetor é ordenado + std::sort(id_objs.begin(), id_objs.end()); + itr1=id_objs.begin(); + itr1_end=id_objs.end(); + + //Insere na ordem os objetos na lista de objetos copiados + while(itr1!=itr1_end) + { + objs_copiados.push_back(mapa_objs[(*itr1)]); + itr1++; + } +} +//---------------------------------------------------------- +void ModeloWidget::colarObjetos(void) +{ + map xml_objs; + vector::iterator itr, itr_end; + map nome_orig_objs; + ObjetoBase *objeto=NULL, *objeto_aux=NULL; + ObjetoTabela *obj_tab=NULL; + Funcao *func=NULL; + //Tipo *tipo=NULL; + Operador *oper=NULL; + QString nome_aux, nome_obj_copia; + TipoObjetoBase tipo_obj; + Excecao erro; + unsigned idx=1, pos=0; + + //Exibe o progresso de tarefas pois a operação de colagem + prog_tarefa->setWindowTitle(trUtf8("Colando objetos...")); + prog_tarefa->open(); + + itr=objs_copiados.begin(); + itr_end=objs_copiados.end(); + + while(itr!=itr_end) + { + //Obtém um objeto selecionado + objeto=(*itr); + tipo_obj=objeto->obterTipoObjeto(); + itr++; + + //Atualiza a mensagem do widget de progresso de tarefa + pos++; + prog_tarefa->executarProgesso((pos/static_cast(objs_copiados.size()))*100, + tr("Validando objeto: %1 (%2)").arg(objeto->obterNome()) + .arg(objeto->obterNomeTipoObjeto()), + objeto->obterTipoObjeto()); + + + //Caso não seja um objeto de tabela + if(!dynamic_cast(objeto)) + { + /* A primeira validação a ser feita é checar se o objeto a ser colado + não conflita com algum objeto de mesmo nome no modelo onde se está + colando os novos objetos */ + + //Para isso, no caso de função e operador, checa esse conflito através de sua assinatura + if(tipo_obj==OBJETO_FUNCAO) + { + dynamic_cast(objeto)->criarAssinatura(true); + nome_aux=dynamic_cast(objeto)->obterAssinatura(); + } + else if(tipo_obj==OBJETO_OPERADOR) + nome_aux=dynamic_cast(objeto)->obterAssinatura(); + //Para os demais tipos de objeto checa através do nome completo + else + nome_aux=objeto->obterNome(true); + + //Tenta obter um objeto de mesmo nome no modelo + if(!dynamic_cast(objeto)) + objeto_aux=modelo->obterObjeto(nome_aux, tipo_obj); + + /* Segunda operação na colagem: caso um objeto de mesmo nome é encontrado no modelo é necessário + validar se as definições XML de ambos são diferentes. Quandos estas são iguais o objeto não é + colado no modelo pois o objeto encontrado no modelo pode ser usado seguramente em substituição + ao objeto que não foi colado. Essa alternativa não se aplica a objetos gráficos, que idependentemente + de terem ou não o mesmo nome ou definição XML serão SEMPRE colados no modelo. */ + if(objeto_aux && + (dynamic_cast(objeto) || + (modelo->validarDefinicaoObjeto(objeto_aux, ParserEsquema::ParserEsquema::DEFINICAO_XML) != + modelo->validarDefinicaoObjeto(objeto, ParserEsquema::ParserEsquema::DEFINICAO_XML)))) + { + //Resolvendo conflitos de nomes + if(tipo_obj!=OBJETO_CONV_TIPO) + { + func=NULL; oper=NULL; //tipo=NULL; + //Armazena o nome original do objeto em um mapa + nome_orig_objs[objeto]=objeto->obterNome(); + + do + { + //Cria um sufixo para o nome do objeto a ser colado a fim de se resolver conflitos + nome_aux=QString("_cp%1").arg(idx++); + + /* Para cada tipo a seguir configura o objeto com o nome e o sufixo gerado e o + armazena em uma string ('nome_obj_copia'). Essa string será usada para checar + se existe no modelo um objeto de mesmo tipo e nome. Enquanto o valor de 'nome_obj_copia' + conflitar com algum objeto no modelo, esta validação será executada */ + if(tipo_obj==OBJETO_FUNCAO) + { + func=dynamic_cast(objeto); + func->definirNome(nome_orig_objs[objeto] + nome_aux); + nome_obj_copia=func->obterAssinatura(); + func->definirNome(nome_orig_objs[objeto]); + } + else if(tipo_obj==OBJETO_OPERADOR) + { + oper=dynamic_cast(objeto); + oper->definirNome(nome_orig_objs[objeto] + nome_aux); + nome_obj_copia=oper->obterAssinatura(); + oper->definirNome(nome_orig_objs[objeto]); + } + /*else if(tipo_obj==OBJETO_TIPO) + { + tipo=dynamic_cast(objeto); + tipo->definirNome(nome_orig_objs[objeto] + nome_aux); + nome_obj_copia=tipo->obterNome(true); + tipo->definirNome(nome_orig_objs[objeto]); + } */ + else + { + objeto->definirNome(nome_orig_objs[objeto] + nome_aux); + nome_obj_copia=objeto->obterNome(true); + objeto->definirNome(nome_orig_objs[objeto]); + } + } + while(modelo->obterObjeto(nome_obj_copia, tipo_obj)); + + //Define o novo nome do objeto concatenando o nome original ao sufixo configurado. + /*if(func) + func->definirNome(nome_orig_objs[objeto] + nome_aux); + else if(tipo) + tipo->definirNome(nome_orig_objs[objeto] + nome_aux); + else if(oper) + oper->definirNome(nome_orig_objs[objeto] + nome_aux); + else */ + objeto->definirNome(nome_orig_objs[objeto] + nome_aux); + + nome_aux.clear(); + idx=1; + } + } + } + } + + /* O terceiro passo da colagem dos objetos é a obtenção do XML + do arquivos copiados. É com eles que são alocados os objetos cópia + que serão efetivamente inseridos no modelo */ + itr=objs_copiados.begin(); + itr_end=objs_copiados.end(); + pos=0; + while(itr!=itr_end) + { + objeto=(*itr); + itr++; + + //Atualiza a mensagem do widget de progresso de tarefa + pos++; + prog_tarefa->executarProgesso((pos/static_cast(objs_copiados.size()))*100, + tr("Gerando código XML do objeto: %1 (%2)").arg(objeto->obterNome()) + .arg(objeto->obterNomeTipoObjeto()), + objeto->obterTipoObjeto()); + + //Armazena a definição XML do objeto num mapa de buffers xml + xml_objs[objeto]=modelo->validarDefinicaoObjeto(objeto, ParserEsquema::DEFINICAO_XML); + } + + /* O quarto passo da colagem é a restauração dos nomes originais dos objetos + copiados. Como estes objetos continuam sendo usados em seu modelo de objetos + original os mesmos precisam ter seus nomes originais de volta */ + itr=objs_copiados.begin(); + itr_end=objs_copiados.end(); + + while(itr!=itr_end) + { + objeto=(*itr); + itr++; + + if(nome_orig_objs[objeto].count()) + { + /*if(tipo_obj==OBJETO_FUNCAO) + dynamic_cast(objeto)->definirNome(nome_orig_objs[objeto]); + else if(tipo_obj==OBJETO_OPERADOR) + dynamic_cast(objeto)->definirNome(nome_orig_objs[objeto]); + else if(tipo_obj==OBJETO_TIPO) + dynamic_cast(objeto)->definirNome(nome_orig_objs[objeto]); + else*/ + if(tipo_obj!=OBJETO_CONV_TIPO) + objeto->definirNome(nome_orig_objs[objeto]); + } + } + + /* Último passo da colagem: os objetos são criados a partir dos xmls + obtidos no passo anterior */ + itr=objs_copiados.begin(); + itr_end=objs_copiados.end(); + pos=0; + + lista_op->iniciarEncadeamentoOperacoes(); + + while(itr!=itr_end) + { + //Carrega o parser xml com o buffer + ParserXML::reiniciarParser(); + ParserXML::carregarBufferXML(xml_objs[*itr]); + itr++; + + try + { + //Cria um objeto com o xml obtido + objeto=modelo->criarObjeto(modelo->obterTipoObjeto(ParserXML::obterNomeElemento())); + obj_tab=dynamic_cast(objeto); + + //Atualiza a mensagem do widget de progresso de tarefa + pos++; + prog_tarefa->executarProgesso((pos/static_cast(objs_copiados.size()))*100, + tr("Colando o objeto: %1 (%2)").arg(objeto->obterNome()) + .arg(objeto->obterNomeTipoObjeto()), + objeto->obterTipoObjeto()); + + /* Com o objeto criado o mesmo é inserido no modelo, exceto para relacionamentos e objetos + de tabelas pois estes são inseridos automaticamente em seus objetos pais */ + if(objeto && + !dynamic_cast(objeto) && + !dynamic_cast(objeto)) + modelo->adicionarObjeto(objeto); + + //Adiciona o objeto criado à lista de operações + if(obj_tab) + lista_op->adicionarObjeto(obj_tab, Operacao::OBJETO_CRIADO, -1, obj_tab->obterTabelaPai()); + else + lista_op->adicionarObjeto(objeto, Operacao::OBJETO_CRIADO); + } + catch(Excecao &e) + { + erro=e; + } + } + lista_op->finalizarEncadeamentoOperacoes(); + + //Força a validação de relacionamentos para refletir qualquer alteração de colunas não propagadas + modelo->validarRelacionamentos(); + + //Ajusta o tamanho da cena para comportar os novos objetos inseridos + this->ajustarTamanhoCena(); + + //Fecha o progresso de tarefas + prog_tarefa->close(); + + /* Caso algum erro foi capturado durante a colagem o mesmo é mostrado ao usuário acompanhado + de um alerta */ + if(erro.obterTipoErro()!=ERR_NULO) + caixa_msg->show(erro, + trUtf8("Nem todos objetos foram colados ao modelo devido a erros retornados durante o processo! Consulte a pilha de erros para mais detalhes!"), + CaixaMensagem::ICONE_ALERTA); + + //Caso não seja uma operação de recorte + if(!ModeloWidget::op_recortar) + { + //Limpa a lista de objetos copiados e emite um sinal indicando que objetos foram criados no modelo + objs_copiados.clear(); + emit s_objetoCriado(); + } + //Caso seja a operação de recorte + else + { + //Exclui os objetos selecionados no modelo de origem + ModeloWidget::modelo_orig->excluirObjetos(); + //Desmarca a flag que indica uma operação de recorte + ModeloWidget::op_recortar=false; + + //Limpa a lista de objetos copiados + objs_copiados.clear(); + + //Reconfigura o menu popup do modelo de origem + if(this!=ModeloWidget::modelo_orig) + ModeloWidget::modelo_orig->configurarMenuPopup(); + + //Zera a referência ao modelo de origem + ModeloWidget::modelo_orig=NULL; + } + + //Reconfigura o menu popup do modelo onde os objetos foram colados + this->configurarMenuPopup(); + this->modificado=true; +} +//---------------------------------------------------------- +void ModeloWidget::excluirObjetos(void) +{ + int idx_obj=-1; + unsigned qtd, qtd_op; + Tabela *tabela=NULL; + TabelaBase *tab_orig=NULL, *tab_dest=NULL; + RelacionamentoBase *relac=NULL; + ObjetoTabela *objeto_tab=NULL; + TipoObjetoBase tipo_obj; + ObjetoBase *objeto=NULL; + vector::iterator itr, itr_end; + vector::reverse_iterator ritr, ritr_end; + vector vet_aux; + vector vet_ids; + vector::reverse_iterator itr1, itr1_end; + map mapa_objs; + QAction *obj_sender=dynamic_cast(sender()); + + if(obj_sender) + objeto=reinterpret_cast(obj_sender->data().value()); + + //Caso exista pelo menos 1 objeto selecionado + if(!objs_selecionados.empty() || objeto) + { + //Caso não seja operação de recortar faz a confirmação da exclusão + if(!ModeloWidget::op_recortar) + { + /* Caso haja mais de 1 objeto selecionado, exibe uma mensagem diferente avisando + sobre a exclusão de multiplos objetos e a invalidação de objetos */ + if(objs_selecionados.size() > 1) + { + caixa_msg->show(trUtf8("Confirmação"), + trUtf8("ATENÇÃO: Remover vários objetos de uma só vez pode provocar invalidações irreversíveis de outros objetos no modelo. Tem certeza de que deseja excluir TODOS os objetos selecionados?"), + CaixaMensagem::ICONE_CONFIRM, CaixaMensagem::BOTAO_SIM_NAO); + } + else + { + caixa_msg->show(trUtf8("Confirmação"), + trUtf8("Tem certeza de que deseja excluir o objeto selecionado?"), + CaixaMensagem::ICONE_CONFIRM, CaixaMensagem::BOTAO_SIM_NAO); + } + } + + //Caso o usuário tenha confirmado a exclusão ou a operação de recortar esteja ativa + if(caixa_msg->result()==QDialog::Accepted || ModeloWidget::op_recortar) + { + try + { + if(!objeto) + { + itr=objs_selecionados.begin(); + itr_end=objs_selecionados.end(); + + /* Armazena os objetos em um mapa cuja chave é o id do objeto. + Com base neste mapa os objetos são ordenados conforme seus ids + pois a exclusão dos mesmos devem seguir uma dada ordem (relacionamentos primeiro) */ + while(itr!=itr_end) + { + objeto=(*itr); + mapa_objs[objeto->obterIdObjeto()]=objeto; + vet_ids.push_back(objeto->obterIdObjeto()); + itr++; + } + + //Ordena os ids dos objetos + sort(vet_ids.begin(), vet_ids.end()); + + //Varre de forma reversa o vetor de ids pegando do maior para o menor id + itr1=vet_ids.rbegin(); + itr1_end=vet_ids.rend(); + while(itr1!=itr1_end) + { + //Obtém um objeto do mapa através do id + vet_aux.push_back(mapa_objs[(*itr1)]); + itr1++; + } + + ritr=vet_aux.rbegin(); + ritr_end=vet_aux.rend(); + objeto=NULL; + } + + qtd_op=lista_op->obterTamanhoAtual(); + lista_op->iniciarEncadeamentoOperacoes(); + + do + { + if(!objeto) objeto=(*ritr++); + tipo_obj=objeto->obterTipoObjeto(); + + //Caso o objeto esteja protegido a exclusão será negada + /* O esquema 'public' e as linguagens C e SQL não pode ser manipuladas + por serem do sistema, caso o usuário tente esta operação um erro será disparado */ + if(objeto && + ((tipo_obj==OBJETO_LINGUAGEM && + (objeto->obterNome()==~TipoLinguagem("c") || + objeto->obterNome()==~TipoLinguagem("sql") || + objeto->obterNome()==~TipoLinguagem("plpgsql") )) || + (tipo_obj==OBJETO_ESQUEMA && + objeto->obterNome()=="public"))) + throw Excecao(ERR_PGMODELERUI_OPROBJRESERVADO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + else if(objeto->objetoProtegido()) + { + //Monta a mensagem de que o objeto não pode ser removido por estar protegido + throw Excecao(QString(Excecao::obterMensagemErro(ERR_PGMODELERUI_REMOBJPROTEGIDO)) + .arg(objeto->obterNome(true)) + .arg(objeto->obterNomeTipoObjeto()), + ERR_PGMODELERUI_REMOBJPROTEGIDO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + else if(tipo_obj!=OBJETO_RELACAO_BASE) + { + objeto_tab=dynamic_cast(objeto); + + if(objeto_tab) + { + tabela=dynamic_cast(objeto_tab->obterTabelaPai()); + idx_obj=tabela->obterIndiceObjeto(objeto_tab->obterNome(true), tipo_obj); + + try + { + /* Caso seja uma coluna valida a sua remoção verificando se outros objetos + não estão referenciando a mesma */ + if(tipo_obj==OBJETO_COLUNA) + modelo->validarRemocaoColuna(dynamic_cast(objeto_tab)); + + modelo->removerPermissoes(objeto_tab); + + //Adiciona o objeto removido à lista de operações e redesenha o modelo + lista_op->adicionarObjeto(objeto_tab, Operacao::OBJETO_REMOVIDO, idx_obj, tabela); + tabela->removerObjeto(idx_obj, tipo_obj); + + tabela->definirModificado(true); + + modelo->validarRelacObjetoTabela(objeto_tab, tabela); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } + } + else + { + //Remove o objeto do modelo usando seu indice + idx_obj=modelo->obterIndiceObjeto(objeto); + + if(idx_obj >=0 ) + { + if(tipo_obj==OBJETO_RELACAO) + { + relac=dynamic_cast(objeto); + tab_orig=relac->obterTabela(RelacionamentoBase::TABELA_ORIGEM); + tab_dest=relac->obterTabela(RelacionamentoBase::TABELA_DESTINO); + } + + try + { + //Adiciona o objeto removido à lista de operações e redesenha o modelo + lista_op->adicionarObjeto(objeto, Operacao::OBJETO_REMOVIDO, idx_obj); + modelo->removerObjeto(objeto, idx_obj); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } + + /* Caso um relacionamento foi removido é necessário redimensionar as tabelas participantes + para o caso de alguma coluna ter sido removido das tabelas */ + if(relac) + { + tab_orig->definirModificado(true); + tab_dest->definirModificado(true); + relac=NULL; + tab_dest=tab_orig=NULL; + } + } + } + } + objeto=NULL; + } + while(ritr!=ritr_end); + + lista_op->finalizarEncadeamentoOperacoes(); + cena->clearSelection(); + this->configurarMenuPopup(); + this->modificado=true; + emit s_objetoRemovido(); + } + catch(Excecao &e) + { + if(e.obterTipoErro()==ERR_PGMODELER_REFCOLUNAINVTABELA) + lista_op->removerOperacoes(); + + if(lista_op->encadeamentoIniciado()) + lista_op->finalizarEncadeamentoOperacoes(); + + /* Caso a quantidade de operações seja diferente da quantidade inicial + obtida antes da remoção dos objetos */ + if(qtd_op < lista_op->obterTamanhoAtual()) + { + //Obtém a quantidade de operações que necessitam ser removidas + qtd=lista_op->obterTamanhoAtual()-qtd_op; + + /* Anula o encadeamento de operações para que as mesmas seja + desfeitas uma a uma ignorando o encadeamento */ + lista_op->anularEncadeamentoOperacoes(true); + + /* Desfaz as operações na quantidade calculada e remove a + operação da lista */ + for(unsigned i=0; i < qtd; i++) + lista_op->removerUltimaOperacao(); + + //Desfaz a anulação do encadeamento + lista_op->anularEncadeamentoOperacoes(false); + } + + cena->clearSelection(); + emit s_objetoRemovido(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__,&e); + } + } + } +} +//---------------------------------------------------------- +void ModeloWidget::exibirMenuObjetoTabela(vector objs_selecionados) +{ + this->configurarMenuPopup(objs_selecionados); + menu_popup.exec(QCursor::pos()); +} +//---------------------------------------------------------- +void ModeloWidget::desabilitarAcoesModelo(void) +{ + action_codigo_fonte->setEnabled(false); + action_editar->setEnabled(false); + action_proteger->setEnabled(false); + action_desproteger->setEnabled(false); + action_selecionar_todos->setEnabled(false); + action_converter_relnn->setEnabled(false); + action_deps_refs->setEnabled(false); + action_novo_obj->setEnabled(false); + action_copiar->setEnabled(false); + action_colar->setEnabled(false); + action_recortar->setEnabled(false); + action_excluir->setEnabled(false); +} +//---------------------------------------------------------- +void ModeloWidget::configurarMenuPopup(vector objs_sel) +{ + QMenu *submenu=NULL; + Tabela *tabela=NULL; + unsigned qtd, i; + vector submenus; + Restricao *rest=NULL; + QAction *acao=NULL; + ObjetoTabela *obj_tab=NULL; + QString str_aux; + bool obj_protegido=false; + + //Limpa os menus padrão do modelo + menu_novo_obj.clear(); + menu_popup.clear(); + + //Desabilitar as ações padrão do menu popup + this->desabilitarAcoesModelo(); + this->objs_selecionados=objs_sel; + + menu_novo_obj.setEnabled(!this->modelo->objetoProtegido()); + + if(objs_sel.size() <= 1) + { + //Caso não haja objetos selecionados + if(objs_sel.empty() || + (objs_sel.size()==1 && objs_sel[0]==modelo)) + { + TipoObjetoBase tipos[]={ OBJETO_TABELA, OBJETO_VISAO, OBJETO_RELACAO, OBJETO_CAIXA_TEXTO, OBJETO_CONV_TIPO, OBJETO_CONV_CODIFICACAO, OBJETO_DOMINIO, + OBJETO_FUNCAO, OBJETO_FUNC_AGREGACAO, OBJETO_LINGUAGEM, OBJETO_CLASSE_OPER, OBJETO_OPERADOR, + OBJETO_FAMILIA_OPER, OBJETO_PAPEL, OBJETO_ESQUEMA, OBJETO_SEQUENCIA, OBJETO_TIPO }; + + //Configura o menu de inserção de novos objetos com os tipos do vetor 'tipos[]' + for(i=0; i < 17; i++) + menu_novo_obj.addAction(acoes_ins_objs[tipos[i]]); + + //Adiciona o menu configurado à ação de novo objeto + action_novo_obj->setMenu(&menu_novo_obj); + menu_popup.addAction(action_novo_obj); + menu_popup.addSeparator(); + + //Inclui a ação de edição do modelo e exibição de seu código fonte + action_editar->setData(QVariant::fromValue(dynamic_cast(modelo))); + action_codigo_fonte->setData(QVariant::fromValue(dynamic_cast(modelo))); + menu_popup.addAction(action_editar); + menu_popup.addAction(action_codigo_fonte); + + //Caso o modelo esteja protegido exibe a ação de desproteger e vice-versa + if(modelo->objetoProtegido()) + menu_popup.addAction(action_desproteger); + else + menu_popup.addAction(action_proteger); + + if(cena->items().count() > 1) + menu_popup.addAction(action_selecionar_todos); + } + //Caso haja apenas 1 objeto selecionado + else if(objs_sel.size()==1) + { + ObjetoBase *obj=objs_sel[0]; + Relacionamento *rel=dynamic_cast(obj); + TipoObjetoBase tipos[]={ OBJETO_COLUNA, OBJETO_RESTRICAO, OBJETO_GATILHO, + OBJETO_REGRA, OBJETO_INDICE/*, OBJETO_RELACAO */ }; + + //Se o objeto não está protegido e o mesmo seja um relacionamento ou tabela + if(!obj->objetoProtegido() && + (obj->obterTipoObjeto()==OBJETO_TABELA || + obj->obterTipoObjeto()==OBJETO_RELACAO)) + { + //Caso seja tabela, inclui a ação de adição de objetos de tabela + if(obj->obterTipoObjeto() == OBJETO_TABELA) + { + for(i=0; i < 5; i++) + menu_novo_obj.addAction(acoes_ins_objs[tipos[i]]); + action_novo_obj->setMenu(&menu_novo_obj); + } + //Caso seja tabela, inclui a ação de adição de atributos e restrições ao relacionamento + else if(obj->obterTipoObjeto()==OBJETO_RELACAO) + { + for(i=0; i < 2; i++) + menu_novo_obj.addAction(acoes_ins_objs[tipos[i]]); + action_novo_obj->setMenu(&menu_novo_obj); + + //Caso seja um relacionametno N-N inclui a ação de conversão do relacionamento + if(rel->obterTipoRelacionamento()==Relacionamento::RELACIONAMENTO_NN) + { + action_converter_relnn->setData(QVariant::fromValue(rel)); + menu_popup.addAction(action_converter_relnn); + } + } + + menu_popup.addAction(action_novo_obj); + menu_popup.addSeparator(); + } + + //Adiciona as ações de edição, exibição do código fonte e dependências/referências do objeto + action_editar->setData(QVariant::fromValue(obj)); + action_codigo_fonte->setData(QVariant::fromValue(obj)); + action_deps_refs->setData(QVariant::fromValue(obj)); + obj_tab=dynamic_cast(obj); + + menu_popup.addAction(action_editar); + menu_popup.addAction(action_codigo_fonte); + menu_popup.addAction(action_deps_refs); + } + } + + /* Adiciona a ação de proteger/desproteger quando o objeto selecionado + não foi incluído por relacionamento e caso se tratar de um objeto de + tabela, a tabela pai não está protegido. Caso o modelo esteja protegido a ação + de proteger/desproteger não será exibida pois isso força o usário a desproteger + todo o modelo para depois manipular os demais objetos */ + if(!objs_sel.empty() && + !this->modelo->objetoProtegido() && + (!obj_tab || (obj_tab && !obj_tab->obterTabelaPai()->objetoProtegido() && !obj_tab->incluidoPorRelacionamento()))) + { + if(!objs_sel[0]->objetoProtegido()) + menu_popup.addAction(action_proteger); + else + menu_popup.addAction(action_desproteger); + + menu_popup.addSeparator(); + } + + //Adiciona a ação de copiar e recortar quando há objetos selecionados + if(!(objs_sel.size()==1 && objs_sel[0]==modelo) && + !objs_sel.empty() && !obj_tab) + { + menu_popup.addAction(action_copiar); + + qtd=objs_sel.size(); + i=0; + while(i < qtd && !obj_protegido) + obj_protegido=objs_sel[i++]->objetoProtegido(); + + menu_popup.addAction(action_recortar); + } + + //Caso haja objetos copiados adiciona a ação de colar objetos + if(!objs_copiados.empty()) + menu_popup.addAction(action_colar); + + //Caso haja objeto selecionado adiciona a ação de excluir + if((!(objs_sel.size()==1 && objs_sel[0]==modelo) && !objs_sel.empty()) || obj_tab) + menu_popup.addAction(action_excluir); + + /* Caso o objeto seja uma coluna (objeto de tabela) cria um menu + especial que permite acesso rápido às retrições que são pertinentes + a coluna */ + if(obj_tab) + { + tabela=dynamic_cast(obj_tab->obterTabelaPai()); + + if(obj_tab->obterTipoObjeto()==OBJETO_COLUNA) + { + qtd=tabela->obterNumRestricoes(); + + for(i=0; i < qtd; i++) + { + rest=tabela->obterRestricao(i); + if(rest->colunaExistente(dynamic_cast(obj_tab), Restricao::COLUNA_ORIGEM)) + { + /* Fazendo uma configuração específica de ícone para restrições. + Cada tipo de restrição tem seu ícone específico. + O sufixos sufixo _pk, _fk, _ck, e _uq, são concatenados + ao nome do tipo (constraint) para identificar o ícone */ + switch(!rest->obterTipoRestricao()) + { + case TipoRestricao::primary_key: str_aux="_pk"; break; + case TipoRestricao::foreign_key: str_aux="_fk"; break; + case TipoRestricao::check: str_aux="_ck"; break; + case TipoRestricao::unique: str_aux="_uq"; break; + } + + //Cria um menu poup para restrição. Para cada restrição as ações de editar, codigo fonte, bloquear/desbloquear e excluir são incluídas + submenu=new QMenu(&menu_popup); + submenu->setIcon(QPixmap(QString(":/icones/icones/") + + ObjetoBase::obterNomeEsquemaObjeto(OBJETO_RESTRICAO) + str_aux + QString(".png"))); + submenu->setTitle(QString::fromUtf8(rest->obterNome())); + + acao=new QAction(dynamic_cast(submenu)); + acao->setIcon(QPixmap(QString(":/icones/icones/editar.png"))); + acao->setText(trUtf8("Propriedades")); + acao->setData(QVariant::fromValue(dynamic_cast(rest))); + connect(acao, SIGNAL(triggered(bool)), this, SLOT(editarObjeto(void))); + submenu->addAction(acao); + + acao=new QAction(dynamic_cast(submenu)); + acao->setIcon(QPixmap(QString(":/icones/icones/codigosql.png"))); + acao->setText(trUtf8("Código-fonte")); + acao->setData(QVariant::fromValue(dynamic_cast(rest))); + connect(acao, SIGNAL(triggered(bool)), this, SLOT(exibirCodigoFonte(void))); + submenu->addAction(acao); + + if(!rest->incluidoPorRelacionamento()) + { + if(!rest->obterTabelaPai()->objetoProtegido()) + { + acao=new QAction(dynamic_cast(&menu_popup)); + acao->setData(QVariant::fromValue(dynamic_cast(rest))); + connect(acao, SIGNAL(triggered(bool)), this, SLOT(protegerObjeto(void))); + submenu->addAction(acao); + + if(rest->objetoProtegido()) + { + acao->setIcon(QPixmap(QString(":/icones/icones/desbloqobjeto.png"))); + acao->setText(trUtf8("Desproteger")); + } + else + { + acao->setIcon(QPixmap(QString(":/icones/icones/bloqobjeto.png"))); + acao->setText(trUtf8("Proteger")); + } + } + + acao=new QAction(dynamic_cast(submenu)); + acao->setData(QVariant::fromValue(dynamic_cast(rest))); + acao->setIcon(QPixmap(QString(":/icones/icones/excluir.png"))); + acao->setText(trUtf8("Excluir")); + connect(acao, SIGNAL(triggered(bool)), this, SLOT(excluirObjetos(void))); + submenu->addAction(acao); + } + submenus.push_back(submenu); + } + } + + /* Caso um submenu de restrições foi adicionado o mesmo é incluído no + menu popup principal através de uma ação criada com o nome da restrição + a qual o menu popup faz referência */ + if(!submenus.empty()) + { + submenu=new QMenu(&menu_popup); + submenu->setTitle(trUtf8("Restrições")); + submenu->setIcon(QPixmap(QString(":/icones/icones/") + + ObjetoBase::obterNomeEsquemaObjeto(OBJETO_RESTRICAO) + QString("_grp.png"))); + qtd=submenus.size(); + for(i=0; i < qtd; i++) + submenu->addMenu(submenus[i]); + + menu_popup.addSeparator(); + menu_popup.addMenu(submenu); + } + } + } + + //Ativa as ações do menu popup principal que estão visíveis + QList acoes=menu_popup.actions(); + while(!acoes.isEmpty()) + { + acoes.back()->setEnabled(true); + acoes.pop_back(); + } +} +//---------------------------------------------------------- +bool ModeloWidget::modeloModificado(void) +{ + return(modificado); +} +//********************************************************** diff --git a/libpgmodeler_ui/src/modelowidget.h b/libpgmodeler_ui/src/modelowidget.h new file mode 100644 index 000000000..dba9076bb --- /dev/null +++ b/libpgmodeler_ui/src/modelowidget.h @@ -0,0 +1,236 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ModeloWidget +# Descrição: Definição da classe que implementa o modelo de banco de dados +# em sua forma de widget, ou seja, que permite a interação do usuário +# para criação de objetos gráficos e outras operações sobre os mesmos. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef MODELO_WIDGET_H +#define MODELO_WIDGET_H + +#include +#include "modelobd.h" +#include "listaoperacoes.h" +#include "caixamensagem.h" +#include "formbasico.h" +#include "cenaobjetos.h" +#include "progressotarefa.h" +//*********************************************************** +class ModeloWidget: public QWidget { + Q_OBJECT + + private: + //Fator de zoom atual da cena de objetos + float zoom_atual; + + bool modificado; + + protected: + //Constantes usadas nas operações de zoom + static const float ZOOM_MINIMO=0.35f, + ZOOM_MAXIMO=4.0f, + INC_ZOOM=0.05f; + + /* Flag que indica se o modelo está em uma operação de recorte. + Essa flag modifica o funcionamento dos métodos colarObjetos, excluirObjeto e + copiarObjetos() */ + static bool op_recortar; + + //Armazena a nível de classe o modelo que deu origem a operação de copia/recorte + static ModeloWidget *modelo_orig; + + //Objetos copiados no modelo de origem + static vector objs_copiados; + + //Frame que indica que o modelo está protegido + QFrame *modelo_protegido_frm; + + //Cena de objetos gráficos do modelo + CenaObjetos *cena; + + //Viewport que gerencia a cena de objetos + QGraphicsView *viewport; + + //Menu popup geral do modelo + QMenu menu_popup, + //Menu de inserção de novo objeto no modelo + menu_novo_obj; + + //Ações do menu popup + QAction *action_codigo_fonte, + *action_editar, + *action_proteger, + *action_desproteger, + *action_excluir, + *action_selecionar_todos, + *action_converter_relnn, + *action_copiar, + *action_colar, + *action_recortar, + *action_deps_refs, + *action_novo_obj; + + //Ações de inserção de novos objetos no modelo + map acoes_ins_objs; + + //Armazena os objetos do modelo selecionados na cena + vector objs_selecionados; + + //Tipo do objeto a ser inserido no modelo + TipoObjetoBase tipo_novo_obj; + + //Lista de operações executadas sobre os objetos do modelo + ListaOperacoes *lista_op; + + //Modelo de objetos do widget + ModeloBD *modelo; + + //Armazena o nome do arquivo de modelo carregado no widget + QString nome_arquivo; + + /* Configura a cena alinhando os objetos e a redimensionando quandos + os objetos extrapolam o tamanho máximo dela */ + void ajustarTamanhoCena(void); + + void resizeEvent(QResizeEvent *); + void mousePressEvent(QMouseEvent *evento); + void keyPressEvent(QKeyEvent *evento); + void focusInEvent(QFocusEvent *evento); + + //Modifica o zoom do viewport quando se pressiona CONTROL e utiliza o wheel do mouse + void wheelEvent(QWheelEvent * evento); + + /* Filtro de eventos usados quando é necessário desviar eventos de objetos filhos. + Um desses desvios é o tratamento do WheelEvent das barras de rolagens do viewport + pelo modelo widget, isso faz com que o WheelEvent seja executado no Modelo e não + nas barras */ + bool eventFilter(QObject *objeto, QEvent *evento); + + //Cancela a operação de adição de novo objeto (valido apenas para objetos gráficos) + void cancelarAdicaoObjeto(void); + + //Desabilita as ações do modelo quando uma ação de adição de objeto gráfica está ativa + void desabilitarAcoesModelo(void); + + public: + ModeloWidget(QWidget *parent = 0); + ~ModeloWidget(void); + + //Obtém o nome do arquivo que deu origem ao modelo + QString obterNomeArquivo(void); + + //Exibe o formulário de edição do objeto conforme o tipo passado + void exibirFormObjeto(TipoObjetoBase tipo_obj, ObjetoBase *objeto=NULL, ObjetoBase *objeto_pai=NULL, QPointF pos=QPointF(NAN, NAN)); + + //Aplica um zoom ao modelo + void aplicarZoom(float zoom); + + //Retorna o zoom atual em que se encontra o modelo + float zoomAtual(void); + + //Retorna se o modelo foi modificado ou não + bool modeloModificado(void); + + private slots: + /* Os slots manipular*() gerenciam os sinais enviados pela cena e modelo para execução + de operações adicionais como incluir objetos modificados na lista de operações, criar + objetos na cena e remover objetos da cena de forma automática */ + void manipularAdicaoObjeto(ObjetoBase *objeto); + void manipularRemocaoObjeto(ObjetoBase *objeto); + void manipularMovimentoObjetos(bool fim_movimento); + void manipularModificacaoObjeto(ObjetoGraficoBase *objeto); + void manipularDuploCliqueObjeto(ObjetoGraficoBase *objeto); + + //Configura o menu popup conforme a lista de objetos passada + void configurarMenuPopup(vector objs_selecionados=vector()); + + //Exibe um menu popup específico para objetos de tabela + void exibirMenuObjetoTabela(vector objs_selecionados); + + //Exibe as dependências e referências do objeto + void exibirDepsRefs(void); + + //Exibe o formulário de edição do objeto selecionado + void editarObjeto(void); + + //Protege os objetos selecionados + void protegerObjeto(void); + + //Exclui os objetos selecionados + void excluirObjetos(void); + + //Seleciona todos os objetos no modelo + void selecionarTodos(void); + + //Copia todos os objetos selecionados no modelo + void copiarObjetos(void); + + //Cola todos os objetos no modelo + void colarObjetos(void); + + /* Recorta os objetos selecionados no modelo. Este método executa + apenas a cópia de objetos, marcando a flag op_recortar e setando + o modelo de origem. O restante da operação de recorte que é exlcuir + os objetos selecionados é executado no método colarObjetos() */ + void recortarObjetos(void); + + //Faz a conversão de um relacionamento n-n + void converterRelacionamentoNN(void); + + //Exibe o código fonte do objeto selecionado + void exibirCodigoFonte(void); + + //Adiciona um novo objeto ao modelo ou tabela selecionada + void adicionarNovoObjeto(void); + + /* Configura a lista de objetos selecionados toda vez que o + sinal selectionChanged() vindo da cena é disparado */ + void configurarSelecaoObjetos(void); + + /* Retorna um vetor com as dimensões das páginas que contém objetos + para serem impressos */ + vector obterPaginasImpressao(const QSizeF &tam_papel, unsigned &qtd_pag_h, unsigned &qtd_pag_v); + + public slots: + void carregarModelo(const QString &nome_arq); + void salvarModelo(const QString &nome_arq); + void salvarModelo(void); + + /* Imprime o modelo no objeto QPrinter passado. Os dois parâmetros bool + são usados para exibir ou não a grade e número de páginas na impressão */ + void imprimirModelo(QPrinter *printer, bool exibir_grade_imp, bool imp_num_pag); + + signals: + /* Sinais personalizados usados para sinalizarem + a modificação do modelo. Este sinal é capturado pelo + form principal para atualizar as ferramentas */ + void s_objetoModificado(void); + void s_objetosMovimentados(void); + void s_objetoCriado(void); + void s_objetoRemovido(void); + void s_selecaoObjetoAtualizada(void); + void s_zoomModificado(void); + + friend class FormPrincipal; + friend class ListaOperacoesWidget; + friend class VisaoObjetosWidget; +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/objetobasewidget.cpp b/libpgmodeler_ui/src/objetobasewidget.cpp new file mode 100644 index 000000000..48743a333 --- /dev/null +++ b/libpgmodeler_ui/src/objetobasewidget.cpp @@ -0,0 +1,827 @@ +#include "objetobasewidget.h" +#include "visaoobjetoswidget.h" +#include "permissaowidget.h" + +extern VisaoObjetosWidget *selecaoobjetos_wgt; +extern PermissaoWidget *permissao_wgt; +//********************************************************** +const QColor ObjetoBaseWidget::COR_FUNDO_LIN_PROT=QColor(255,180,180); +const QColor ObjetoBaseWidget::COR_TEXTO_LIN_PROT=QColor(80,80,80); +const QColor ObjetoBaseWidget::COR_FUNDO_LIN_INCREL=QColor(164,249,176); +const QColor ObjetoBaseWidget::COR_TEXTO_LIN_INCREL=QColor(80,80,80); +//*********************************************************** +ObjetoBaseWidget::ObjetoBaseWidget(QWidget *parent, TipoObjetoBase tipo_obj): QDialog(parent) +{ + try + { + setupUi(this); + modelo=NULL; + tabela=NULL; + relacionamento=NULL; + lista_op=NULL; + objeto=NULL; + px_objeto=NAN; + py_objeto=NAN; + alt_min_jp=-1; + alt_max_jp=-1; + dest_nomepai_txt=NULL; + janela_pai=NULL; + sel_esquema=NULL; + sel_dono=NULL; + sel_esptabela=NULL; + + //Aloca um destacador de código fonte + dest_nomepai_txt=new DestaqueSintaxe(objeto_pai_txt, false); + + //A configuração padrão carregada é a de destaque de código SQL + dest_nomepai_txt->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + janela_pai=new FormBasico(NULL, (Qt::WindowTitleHint | Qt::WindowSystemMenuHint)); + janela_pai->setWindowTitle(trUtf8("Criação / Edição: ") + QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(tipo_obj))); + janela_pai->widgetgeral_wgt->insertWidget(0, this); + janela_pai->widgetgeral_wgt->setCurrentIndex(0); + janela_pai->definirBotoes(CaixaMensagem::BOTAO_OK_CANCELAR); + + connect(edt_permissoes_tb, SIGNAL(clicked(bool)),this, SLOT(editarPermissoes(void))); + connect(janela_pai->cancelar_btn, SIGNAL(clicked(bool)), janela_pai, SLOT(close(void))); + connect(janela_pai, SIGNAL(rejected()), this, SLOT(reject())); + + sel_esquema=new SeletorObjetoWidget(OBJETO_ESQUEMA, true, this); + sel_dono=new SeletorObjetoWidget(OBJETO_PAPEL, true, this); + sel_esptabela=new SeletorObjetoWidget(OBJETO_ESPACO_TABELA, true, this); + + //Configura o layout do formulário padrão + objetobase_grid = new QGridLayout; + objetobase_grid->setObjectName(QString::fromUtf8("objetobase_grid")); + + objetobase_grid->addWidget(obj_protegido_frm, 0, 0, 1, 0); + objetobase_grid->addWidget(nome_lbl, 1, 0, 1, 1); + objetobase_grid->addWidget(nome_edt, 1, 1, 1, 3); + objetobase_grid->addWidget(iconeobj_lbl, 1, 4, 1, 1); + + objetobase_grid->addWidget(objeto_pai_lbl, 2, 0, 1, 1); + objetobase_grid->addWidget(objeto_pai_txt, 2, 1, 1, 3); + objetobase_grid->addWidget(iconeobjpai_lbl, 2, 4, 1, 1); + + + objetobase_grid->addWidget(div_ln, 3, 0, 1, 5); + + objetobase_grid->addWidget(comentario_lbl, 4, 0, 1, 1); + objetobase_grid->addWidget(comentario_edt, 4, 1, 1, 4); + + objetobase_grid->addWidget(esptabela_lbl, 5, 0, 1, 1); + objetobase_grid->addWidget(sel_esptabela, 5, 1, 1, 4); + + objetobase_grid->addWidget(dono_lbl, 6, 0, 1, 1); + objetobase_grid->addWidget(sel_dono, 6, 1, 1, 4); + + objetobase_grid->addWidget(esquema_lbl, 7, 0, 1, 1); + objetobase_grid->addWidget(sel_esquema, 7, 1, 1, 4); + + objetobase_grid->addWidget(permissoes_lbl, 8, 0, 1, 1); + objetobase_grid->addWidget(edt_permissoes_tb, 8, 1, 1, 4); + + objetobase_grid->addWidget(div1_ln, 9, 0, 1, 5); + } + catch(Excecao &e) + { + if(janela_pai) delete(janela_pai); + + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +ObjetoBaseWidget::~ObjetoBaseWidget(void) +{ + delete(janela_pai); +} +//---------------------------------------------------------- +void ObjetoBaseWidget::show(void) +{ + janela_pai->exec(); + QDialog::show(); +} +//---------------------------------------------------------- +void ObjetoBaseWidget::showEvent(QShowEvent *) +{ + /* Na primeira exibição do formulário a altura minima e máxima + da janela pai não foi armazenada, sendo assim, os atributos + são configurados com as alturas da janela */ + if(alt_min_jp < 0) + { + alt_min_jp=janela_pai->minimumHeight(); + alt_max_jp=janela_pai->maximumHeight(); + } + + //Caso o frame de objeto protegido esteja visível + if(obj_protegido_frm->isVisible()) + { + //Redimensiona a janela pai para que o frame seja exibido + janela_pai->setMinimumHeight(alt_min_jp + obj_protegido_frm->height() + 10); + janela_pai->setMaximumHeight(alt_max_jp + obj_protegido_frm->height() + 10); + janela_pai->resize(janela_pai->minimumWidth(),janela_pai->minimumHeight()); + } + else if(alt_min_jp > 0) + { + //Retorna a janela pai ao seu tamanho original caso o frame de alerta esteja invisível + janela_pai->setMinimumHeight(alt_min_jp); + janela_pai->setMaximumHeight(alt_max_jp); + janela_pai->resize(janela_pai->minimumWidth(), alt_min_jp); + } +} +//---------------------------------------------------------- +void ObjetoBaseWidget::hideEvent(QHideEvent *) +{ + nome_edt->clear(); + comentario_edt->clear(); + objeto_pai_txt->clear(); + + sel_esptabela->removerObjetoSelecionado(); + sel_esquema->removerObjetoSelecionado(); + sel_dono->removerObjetoSelecionado(); + + janela_pai->blockSignals(true); + janela_pai->close(); + janela_pai->blockSignals(false); +} +//---------------------------------------------------------- +void ObjetoBaseWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, ObjetoBase *objeto, ObjetoBase *objeto_pai, float px_objeto, float py_objeto) +{ + TipoObjetoBase tipo_obj, tipo_obj_pai=OBJETO_BASE; + + if(!modelo) + throw Excecao(ERR_PGMODELER_ATROBJNAOALOC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + this->modelo=modelo; + + if(objeto_pai) + { + tipo_obj_pai=objeto_pai->obterTipoObjeto(); + + if(tipo_obj_pai==OBJETO_TABELA) + this->tabela=dynamic_cast(objeto_pai); + else if(tipo_obj_pai==OBJETO_RELACAO) + this->relacionamento=dynamic_cast(objeto_pai); + else + throw Excecao(ERR_PGMODELER_ATROBJTIPOINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + else + { + ObjetoTabela *obj_tab=dynamic_cast(objeto); + + if(objeto && objeto->obterEsquema()) + objeto_pai=objeto->obterEsquema(); + else if(obj_tab && obj_tab->obterTabelaPai()) + objeto_pai=obj_tab->obterTabelaPai(); + else + objeto_pai=modelo; + } + + if(dynamic_cast(objeto)) + dynamic_cast(objeto)->definirModificado(false); + + this->lista_op=lista_op; + this->objeto=objeto; + + if(this->tabela) + { + this->px_objeto=this->tabela->obterPosicaoObjeto().x(); + this->py_objeto=this->tabela->obterPosicaoObjeto().y(); + } + else + { + this->px_objeto=px_objeto; + this->py_objeto=py_objeto; + } + + edt_permissoes_tb->setEnabled(objeto!=NULL); + objeto_pai_txt->setPlainText(QString::fromUtf8(objeto_pai->obterNome(true))); + + iconeobjpai_lbl->setPixmap(QPixmap(QString::fromUtf8(":/icones/icones/") + objeto_pai->obterNomeEsquemaObjeto() + QString(".png"))); + iconeobjpai_lbl->setToolTip(objeto_pai->obterNomeTipoObjeto()); + + /* Configura os seletores de dono/esquema/espaço de tabela somente quando + um modelo está definido */ + sel_dono->definirModelo(modelo); + sel_esquema->definirModelo(modelo); + sel_esptabela->definirModelo(modelo); + + //Caso o objeto a ser editado esteja alocado configura os campos básicos do formulário + if(objeto) + { + bool protegido; + + //Configura os campos de nome e comentário + nome_edt->setText(QString::fromUtf8(objeto->obterNome())); + comentario_edt->setText(QString::fromUtf8(objeto->obterComentario())); + + sel_dono->definirObjeto(objeto->obterDono()); + sel_esquema->definirObjeto(objeto->obterEsquema()); + sel_esptabela->definirObjeto(objeto->obterEspacoTabela()); + + /* Exibe o frame de objeto protegido caso o mesmo esteja protegido + ou seja incluído por relacionamento (coluna ou restrição). + Para atributos e restrições de relacionamentos o atributo protegido/inc_relacionamento + é desconsiderado pois quando conectado o relacionamento marca as flags citadas, e para + permitir que o usuário edite uma restrição ou atributo do relacionamento é necessária + essa exceção */ + tipo_obj=objeto->obterTipoObjeto(); + protegido=(tipo_obj_pai!=OBJETO_RELACAO && + (objeto->objetoProtegido() || + ((tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_RESTRICAO) && + dynamic_cast(objeto)->incluidoPorRelacionamento()))); + obj_protegido_frm->setVisible(protegido); + + janela_pai->aplicar_ok_btn->setEnabled(!protegido); + } + else obj_protegido_frm->setVisible(false); +} +//---------------------------------------------------------- +void ObjetoBaseWidget::configurarLayouFormulario(QGridLayout *grid, TipoObjetoBase tipo_obj) +{ + bool exibir_esq, exibir_dono, exibir_esptab, exibir_coment, exibir_obj_pai; + + if(grid) + { + QLayoutItem *item=NULL; + int lin, col, col_span,row_span, id_item, qtd_item; + + /* Move todos os itens do layout passado uma linha para baixo + isso permite que o layout do formulário básico seja incluído + no início do formulário passado */ + qtd_item=grid->count(); + for(id_item=qtd_item-1; id_item >= 0; id_item--) + { + item=grid->itemAt(id_item); + grid->getItemPosition(id_item, &lin, &col, &row_span, &col_span); + grid->removeItem(item); + grid->addItem(item, lin+1, col, row_span, col_span); + } + + //Adiciona o layout no início do formulário + grid->addLayout(objetobase_grid, 0,0,1,0); + objetobase_grid=grid; + } + else + this->setLayout(objetobase_grid); + + objetobase_grid->setContentsMargins(4, 4, 4, 4); + + //Definindo a exibição do campo de configuração de esquema dos objetos de acordo com o tipo passado + exibir_esq=(tipo_obj==OBJETO_FUNCAO || tipo_obj==OBJETO_TABELA || tipo_obj==OBJETO_VISAO || + tipo_obj==OBJETO_DOMINIO || tipo_obj==OBJETO_FUNC_AGREGACAO || tipo_obj==OBJETO_OPERADOR || + tipo_obj==OBJETO_SEQUENCIA || tipo_obj==OBJETO_CONV_CODIFICACAO || tipo_obj==OBJETO_TIPO || + tipo_obj==OBJETO_FAMILIA_OPER || tipo_obj==OBJETO_CLASSE_OPER); + + //Definindo a exibição do campo de configuração de dono dos objetos de acordo com o tipo passado + exibir_dono=(tipo_obj==OBJETO_FUNCAO || tipo_obj==OBJETO_TABELA || tipo_obj==OBJETO_DOMINIO || + tipo_obj==OBJETO_ESQUEMA || tipo_obj==OBJETO_FUNC_AGREGACAO || tipo_obj==OBJETO_OPERADOR || + tipo_obj==OBJETO_CONV_CODIFICACAO || tipo_obj==OBJETO_LINGUAGEM || tipo_obj==OBJETO_TIPO || + tipo_obj==OBJETO_ESPACO_TABELA || tipo_obj==OBJETO_FAMILIA_OPER || tipo_obj==OBJETO_BANCO_DADOS); + + //Definindo a exibição do campo de configuração de espaço dos objetos de acordo com o tipo passado + exibir_esptab=(tipo_obj==OBJETO_RESTRICAO || tipo_obj==OBJETO_INDICE || tipo_obj==OBJETO_TABELA || tipo_obj==OBJETO_BANCO_DADOS); + + //Definindo a exibição do campo de configuração de comentário dos objetos de acordo com o tipo passado + exibir_coment=(tipo_obj!=OBJETO_RELACAO && tipo_obj!=OBJETO_CAIXA_TEXTO && + tipo_obj!=OBJETO_PARAMETRO); + + //Definindo a exibição do campo de objeto pai + exibir_obj_pai=(tipo_obj!=OBJETO_PARAMETRO && tipo_obj!=OBJETO_BANCO_DADOS && + tipo_obj!=OBJETO_PERMISSAO && tipo_obj!=OBJETO_BASE); + + if(tipo_obj!=OBJETO_TABELA && tipo_obj!=OBJETO_COLUNA && tipo_obj!=OBJETO_VISAO && + tipo_obj!=OBJETO_SEQUENCIA && tipo_obj!=OBJETO_BANCO_DADOS && tipo_obj!=OBJETO_FUNCAO && + tipo_obj!=OBJETO_FUNC_AGREGACAO && tipo_obj!=OBJETO_LINGUAGEM && tipo_obj!=OBJETO_ESQUEMA && + tipo_obj!=OBJETO_ESPACO_TABELA) + { + permissoes_lbl->setVisible(false); + edt_permissoes_tb->setVisible(false); + } + + esquema_lbl->setVisible(exibir_esq); + sel_esquema->setVisible(exibir_esq); + + dono_lbl->setVisible(exibir_dono); + sel_dono->setVisible(exibir_dono); + + esptabela_lbl->setVisible(exibir_esptab); + sel_esptabela->setVisible(exibir_esptab); + + comentario_edt->setVisible(exibir_coment); + comentario_lbl->setVisible(exibir_coment); + + objeto_pai_lbl->setVisible(exibir_obj_pai); + objeto_pai_txt->setVisible(exibir_obj_pai); + iconeobjpai_lbl->setVisible(exibir_obj_pai); + + div1_ln->setVisible(exibir_obj_pai && tipo_obj!=OBJETO_TABELA && + tipo_obj!=OBJETO_ESQUEMA && + tipo_obj!=OBJETO_RELACAO && + tipo_obj!=OBJETO_RELACAO_BASE); + + //Configura o ícone de acordo com o tipo de objeto + if(tipo_obj!=OBJETO_BASE) + { + iconeobj_lbl->setPixmap(QPixmap(QString::fromUtf8(":/icones/icones/") + ObjetoBase::obterNomeEsquemaObjeto(tipo_obj) + QString(".png"))); + iconeobj_lbl->setToolTip(ObjetoBase::obterNomeTipoObjeto(tipo_obj)); + } +} +//---------------------------------------------------------- +QString ObjetoBaseWidget::gerarIntervaloVersoes(unsigned tipo_intervalo, const QString &ver_ini, const QString &ver_fim) +{ + if(tipo_intervalo==ATE_VERSAO && !ver_ini.isEmpty()) + return(ParserXML::CHR_MENORQUE + QString("= ") + ver_ini); + else if(tipo_intervalo==INTER_VERSOES && !ver_ini.isEmpty() && !ver_fim.isEmpty()) + return(ParserXML::CHR_MAIORQUE + QString("= ") + ver_ini + ParserXML::CHR_ECOMERCIAL + ParserXML::CHR_MENORQUE + QString("= ") + ver_fim); + else if(tipo_intervalo==APOS_VERSAO && !ver_ini.isEmpty()) + return(ParserXML::CHR_MAIORQUE + QString("= ") + ver_ini); + else + return(""); +} +//---------------------------------------------------------- +QFrame *ObjetoBaseWidget::gerarFrameInformacao(const QString &mensagem) +{ + QFrame *info_frm=NULL; + QGridLayout *grid=NULL; + QLabel *icone_lbl=NULL, *mensagem_lbl=NULL; + QFont fonte; + + //Aloca o frame de alerta + info_frm = new QFrame; + + fonte.setPointSize(8); + fonte.setItalic(false); + fonte.setBold(false); + info_frm->setFont(fonte); + + info_frm->setObjectName(QString::fromUtf8("info_frm")); + info_frm->setFrameShape(QFrame::Box); + info_frm->setFrameShadow(QFrame::Sunken); + + //Aloca o layout em grade para disposição dos demais objetos dentro do frame de alerta + grid = new QGridLayout(info_frm); + grid->setContentsMargins(4, 4, 4, 4); + grid->setObjectName(QString::fromUtf8("grid")); + + //Configura o icone de alerta + icone_lbl = new QLabel(info_frm); + icone_lbl->setObjectName(QString::fromUtf8("icone_lbl")); + icone_lbl->setMinimumSize(QSize(32, 32)); + icone_lbl->setMaximumSize(QSize(32, 32)); + icone_lbl->setPixmap(QPixmap(QString::fromUtf8(":/icones/icones/msgbox_info.png"))); + icone_lbl->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); + + //Adiciona-o ao layout + grid->addWidget(icone_lbl, 0, 0, 1, 1); + + //Cria o label o qual levará a mensagem de alerta + mensagem_lbl = new QLabel(info_frm); + mensagem_lbl->setObjectName(QString::fromUtf8("mensagelm_lb")); + mensagem_lbl->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); + mensagem_lbl->setWordWrap(true); + + //Configura a mensagem de alerta + mensagem_lbl->setText(mensagem); + + //Adiciona o o label de mensagem ao layout + grid->addWidget(mensagem_lbl, 0, 1, 1, 1); + grid->setContentsMargins(4,4,4,4); + + return(info_frm); +} +//---------------------------------------------------------- +QFrame *ObjetoBaseWidget::gerarFrameAlertaVersao(map > &campos, + map< QWidget *, vector > *valores) +{ + QFrame *alerta_frm=NULL; + QGridLayout *grid=NULL; + QLabel *icone_lbl=NULL, *mensagem_lbl=NULL; + QString nome_cmp, str_aux; + QFont fonte; + QWidget *wgt=NULL; + map >::iterator itr, itr_end; + vector vet_valores; + unsigned i, qtd, qtd1, i1; + + itr=campos.begin(); + itr_end=campos.end(); + + while(itr!=itr_end) + { + qtd=itr->second.size(); + + /* Monta a string com os nomes dos campos removendo o ':', além disso a fonte dos labels + é modificada para denotar a particularidade do campo */ + for(i=0; i < qtd; i++) + { + wgt=itr->second.at(i); + if(valores && valores->count(wgt) > 0) + { + vet_valores=valores->at(wgt); + qtd1=vet_valores.size(); + + nome_cmp+=QString("
") + trUtf8("Valor(es)") + QString(": ("); + for(i1=0; i1 < qtd1; i1++) + { + nome_cmp+=vet_valores.at(i1); + if(i1 < qtd1-1) nome_cmp+=", "; + } + nome_cmp+=")"; + } + + fonte=wgt->font(); + fonte.setBold(true); + fonte.setItalic(true); + wgt->setFont(fonte); + wgt->setToolTip(QString::fromUtf8("") + trUtf8("Versão") + + itr->first + QString::fromUtf8(" %1").arg(nome_cmp)); + } + itr++; + } + + + //Aloca o frame de alerta + alerta_frm = new QFrame; + + fonte.setPointSize(8); + fonte.setItalic(false); + fonte.setBold(false); + alerta_frm->setFont(fonte); + + alerta_frm->setObjectName(QString::fromUtf8("alerta_frm")); + alerta_frm->setFrameShape(QFrame::Box); + alerta_frm->setFrameShadow(QFrame::Sunken); + + //Aloca o layout em grade para disposição dos demais objetos dentro do frame de alerta + grid = new QGridLayout(alerta_frm); + grid->setObjectName(QString::fromUtf8("grid")); + + //Configura o icone de alerta + icone_lbl = new QLabel(alerta_frm); + icone_lbl->setObjectName(QString::fromUtf8("icone_lbl")); + icone_lbl->setMinimumSize(QSize(32, 32)); + icone_lbl->setMaximumSize(QSize(32, 32)); + icone_lbl->setPixmap(QPixmap(QString::fromUtf8(":/icones/icones/msgbox_alerta.png"))); + icone_lbl->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop); + + //Adiciona-o ao layout + grid->addWidget(icone_lbl, 0, 0, 1, 1); + + //Cria o label o qual levará a mensagem de alerta + mensagem_lbl = new QLabel(alerta_frm); + mensagem_lbl->setObjectName(QString::fromUtf8("mensagelm_lb")); + mensagem_lbl->setAlignment(Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter); + mensagem_lbl->setWordWrap(true); + + //Configura a mensagem de alerta + mensagem_lbl->setText(trUtf8("O(s) campo(s) ou valor(es) destacado(s) no formulário é(são) de\ + uso exclusivo e/ou obrigatório em versões específicas do PostgreSQL.\ + O não preenchimento do(s) mesmo(s) pode ocasionar erros na geração de código SQL\ + de cada versão indicada nas dicas de ferramenta dos campos destacados.")); + + //Adiciona o o label de mensagem ao layout + grid->addWidget(mensagem_lbl, 0, 1, 1, 1); + grid->setContentsMargins(4,4,4,4); + + return(alerta_frm); +} +//---------------------------------------------------------- +void ObjetoBaseWidget::editarPermissoes(void) +{ + ObjetoBase *objeto_pai=NULL; + + if(this->relacionamento) + objeto_pai=this->relacionamento; + + permissao_wgt->definirAtributos(this->modelo, objeto_pai, this->objeto); + permissao_wgt->show(); +} +//---------------------------------------------------------- +void ObjetoBaseWidget::aplicarConfiguracao(void) +{ + if(objeto) + { + try + { + ObjetoBase *obj_aux=NULL, *obj_aux1=NULL, *obj_pai=NULL; + //ObjetoGraficoBase *obj_graf=dynamic_cast(objeto); + bool novo_obj; + TipoObjetoBase tipo_obj; + QString nome_obj; + + tipo_obj=objeto->obterTipoObjeto(); + nome_obj=ObjetoBase::formatarNome(nome_edt->text().toUtf8(), tipo_obj==OBJETO_OPERADOR); + + if(sel_esquema->obterObjeto()) + nome_obj=sel_esquema->obterObjeto()->obterNome(true) + "." + nome_obj; + + /* Caso o tipo do objeto nao seja um dos três da condição faz a verificação + de duplicidade de objetos. + + Permissões e Parâmetros não são tratados neste bloco pois, permissões não + tem a chance de terem o mesmo nome e os parâmetros são tratados dentro + das funções aos quais pertencem. + + Para o Modelo de Banco de dados também não é validado a duplicidade pois ele + é uma instância única */ + if(tipo_obj!=OBJETO_BANCO_DADOS && tipo_obj!=OBJETO_PERMISSAO && tipo_obj!=OBJETO_PARAMETRO) + { + if(tabela) + { + //Validação do objeto em relação a sua tabela pai + obj_pai=tabela; + obj_aux=tabela->obterObjeto(nome_obj,tipo_obj); + obj_aux1=tabela->obterObjeto(objeto->obterNome(),tipo_obj); + novo_obj=(!obj_aux && !obj_aux1); + //obj_graf=tabela; + } + else if(relacionamento) + { + //Validação do objeto em relação a sua tabela pai + obj_pai=relacionamento; + obj_aux=relacionamento->obterObjeto(nome_obj,tipo_obj); + obj_aux1=relacionamento->obterObjeto(objeto->obterNome(),tipo_obj); + novo_obj=(!obj_aux && !obj_aux1); + //obj_graf=relacionamento; + } + //Valida o nome do objeto em relação aos objetos presentes no modelo + else + { + obj_pai=modelo; + obj_aux=modelo->obterObjeto(nome_obj,tipo_obj); + + if(tipo_obj==OBJETO_FUNCAO) + obj_aux1=modelo->obterObjeto(dynamic_cast(objeto)->obterAssinatura(),tipo_obj); + else if(tipo_obj==OBJETO_OPERADOR) + obj_aux1=modelo->obterObjeto(dynamic_cast(objeto)->obterAssinatura(),tipo_obj); + else + obj_aux1=modelo->obterObjeto(objeto->obterNome(),tipo_obj); + + novo_obj=(!obj_aux && !obj_aux1); + } + + if(!novo_obj && obj_aux && obj_aux!=objeto) + { + throw Excecao(QString(Excecao::obterMensagemErro(ERR_PGMODELER_ATROBJDUPLIC)) + .arg(nome_obj) + .arg(ObjetoBase::obterNomeTipoObjeto(tipo_obj)) + .arg(obj_pai->obterNome(true)) + .arg(obj_pai->obterNomeTipoObjeto()), + ERR_PGMODELER_ATROBJDUPLIC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + } + + /* Executa a nomeção do objeto chamando o método + de acordo com a classe referente ao tipo de objeto */ + if(tipo_obj!=OBJETO_CONV_TIPO) + /* Caso o objeto ser renomeado não seja de nenhum dos tipos acima + e não seja conversão de tipo (o unico objeto que não recebe um nome explicitamente) + utiliza o método de nomeação geral da classe ObjetoBase */ + objeto->definirNome(nome_edt->text().toUtf8()); + + //Configura o comentário do objeto + if(comentario_edt->isVisible()) + objeto->definirComentario(comentario_edt->text().toUtf8()); + + /* Selecionando o espaço de tabelas do objeto somente se o mesmo + aceita receber um espaço de tabela, para se validar esta situação + basta verificar se o campo de texto com o nome do espaço de tabela + está visível, pois este campo é escondido ou mostrado no momento da + alocação do formulário de cada tipo de objeto. */ + if(sel_esptabela->isVisible()) + objeto->definirEspacoTabela(sel_esptabela->obterObjeto()); + + /* Selecionando o dono do objeto somente se o mesmo aceita receber um dono, + para se validar esta situação basta verificar se o campo de texto com o + nome do dono está visível, pois este campo é escondido ou mostrado no momento da + alocação do formulário de cada tipo de objeto. */ + if(sel_dono->isVisible()) + objeto->definirDono(sel_dono->obterObjeto()); + + /* Selecionando o esquema do objeto somente se o mesmo aceita receber um esquema, + para se validar esta situação basta verificar se o campo de texto com o + nome do esquema está visível, pois este campo é escondido ou mostrado no momento da + alocação do formulário de cada tipo de objeto. */ + if(sel_esquema->isVisible()) + { + Esquema *esquema=dynamic_cast(sel_esquema->obterObjeto()); + objeto->definirEsquema(esquema); + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } +} +//----------------------------------------------------------- +void ObjetoBaseWidget::finalizarConfiguracao(void) +{ + if(this->objeto) + { + TipoObjetoBase tipo_obj=this->objeto->obterTipoObjeto(); + ObjetoGraficoBase *obj_graf=dynamic_cast(this->objeto); + ObjetoTabela *obj_tab=dynamic_cast(this->objeto); + + /* Caso o objeto seja novo, é necessário adicioná-lo à lista + de operações como objeto criado para permitir sua remoção + quando o usuário executar a operação de desfazer */ + if(novo_obj) + { + if(tabela && (tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_REGRA || + tipo_obj==OBJETO_GATILHO || + tipo_obj==OBJETO_INDICE || tipo_obj==OBJETO_RESTRICAO)) + tabela->adicionarObjeto(this->objeto); + else if(relacionamento && (tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_RESTRICAO)) + relacionamento->adicionarObjeto(dynamic_cast(this->objeto)); + else if(tipo_obj!=OBJETO_PARAMETRO) + modelo->adicionarObjeto(this->objeto); + + if(lista_op) + { + if(this->tabela) + lista_op->adicionarObjeto(this->objeto, Operacao::OBJETO_CRIADO, -1, this->tabela); + /* Relacionamento não são adicionados à lista de operações por este trecho de código. + Isso é tratado no método definirAtributos() da classe RelacionamentoWidget */ + else if(tipo_obj!=OBJETO_RELACAO && tipo_obj!=OBJETO_TABELA) + lista_op->adicionarObjeto(this->objeto, Operacao::OBJETO_CRIADO, -1, this->relacionamento); + } + novo_obj=false; + } + else + //Caso o objeto esteja sendo atualizado, apenas valida a definição do mesmo. + modelo->validarDefinicaoObjeto(this->objeto, ParserEsquema::DEFINICAO_SQL); + + + /* Caso o objeto em questão seja um esquema,faz com que os objetos do tipo + tabela, visão e relacionamento sejam marcados como modificado para + forçar o redimensionamento dos mesmos, pois se o esquema tem o nome modificado + consequentimente os objetos citados tem seus tamanhos mudados pois o nome + do esquema é exibido nos objtos. */ + if(tipo_obj==OBJETO_ESQUEMA) + { + vector *lista_obj=NULL; + vector::iterator itr, itr_end; + TipoObjetoBase tipos[]={ OBJETO_TABELA, OBJETO_VISAO, + OBJETO_RELACAO, OBJETO_RELACAO_BASE }; + unsigned i; + ObjetoGraficoBase *obj=NULL, *obj1=NULL; + RelacionamentoBase *rel=NULL; + + for(i=0; i < 4; i++) + { + //Obtém a lista do tipo de objeto atual + lista_obj=modelo->obterListaObjetos(tipos[i]); + itr=lista_obj->begin(); + itr_end=lista_obj->end(); + + //Faz a varredura da lista obtida + while(itr!=itr_end) + { + //Obtém o objeto do iterador atual + obj=dynamic_cast(*itr); + itr++; + + //Caso o objeto seja um relacionamento + if(obj->obterTipoObjeto()==OBJETO_RELACAO || + obj->obterTipoObjeto()==OBJETO_RELACAO_BASE) + { + //Converte o objeto para relacionamento básico + rel=dynamic_cast(obj); + + /* Obtém as tabelas participantes do relacionamento para + verificar se uma delas referencia o esquema modificado, + caso isso seja verdadeiro as tabelas e o relacionamento + serão marcados como modificados */ + obj=rel->obterTabela(RelacionamentoBase::TABELA_ORIGEM); + obj1=rel->obterTabela(RelacionamentoBase::TABELA_DESTINO); + } + + //Caso o objeto referencia o esquema, marca como modificado + if(obj->obterEsquema()==this->objeto) + obj->definirModificado(true); + + /* Caso o objeto1, neste caso sempre será uma tabela participante + de um relacionamento quando alocado, referencia o esquema, marca-o como + modificado */ + if(obj1 && obj1->obterEsquema()==this->objeto) + obj1->definirModificado(true); + + /* Caso o relacionamento esteja alocado, sinal de que o objeto atual é um relacionamento + verifica uma das tabelas participantes estão modificadas, caso seja veradeiro + o próprio relacionamento é marcado como modificado */ + if(rel && (obj->objetoModificado() || (obj1 && obj1->objetoModificado()))) + { + rel->definirModificado(true); + obj1=NULL; + rel=NULL; + } + } + } + } + + //Seta o resultado como Accepted para indicar que o objeto foi criado/editado com sucesso + this->accept(); + janela_pai->hide(); + + + //Atualiza o objeto gráfico + if(obj_graf || obj_tab) + { + /* Caso o objeto editado seja um objeto de tabela (exceto um parâmetro de função, + pois este herda a classe Coluna), atualiza a tabela pai */ + if(!obj_graf && obj_tab && obj_tab->obterTipoObjeto()!=OBJETO_PARAMETRO) + { + if(this->tabela) + obj_graf=dynamic_cast(this->tabela); + else + obj_graf=dynamic_cast(this->relacionamento); + + obj_graf->definirModificado(true); + } + //Caso não seja um objeto de tabela atualiza o próprio objeto + else if(obj_graf) + { + if(!isnan(px_objeto) && !isnan(py_objeto)) + obj_graf->definirPosicaoObjeto(QPointF(px_objeto, py_objeto)); + + //Força o redesenho do objeto gráfico marcando-o como modificado + obj_graf->definirModificado(true); + } + } + + /* Emite um sinal indicando que o objeto foi manipulado com sucesso + isso faz com que a lista de operações e objetos do modelo assim + como a visão geral do modelo seja atualizada */ + emit s_objetoManipulado(); + } +} +//----------------------------------------------------------- +void ObjetoBaseWidget::cancelarConfiguracao(void) +{ + TipoObjetoBase tipo_obj; + + tipo_obj=this->objeto->obterTipoObjeto(); + + /* Cancela a configuração do objeto caso o mesmo seja um novo objeto + e não seja do tipo banco de dados, pois este tipo de objeto + não pode ser desalocado por ser a instância que armazena + os demais tipos de objetos */ + if(novo_obj) + { + /* Caso o atributo 'tabela' não esteja alocado indica que o objeto configurado + não é um objeto de tabela (coluna, restrição, gatilho, etc) sendo assim + o mesmo será removido do modelo */ + if(!tabela) + modelo->removerObjeto(this->objeto); + else if(tabela) + /* Caso o atributo 'tabela' esteja alocado indica que o objeto configurado + é um objeto de tabela (coluna, restrição, gatilho, etc) sendo assim + o mesmo será removido da própria */ + tabela->removerObjeto(dynamic_cast(this->objeto)); + /* Caso o atributo 'relacionamento' esteja alocado indica que o objeto configurado + é um objeto de tabela (coluna, restrição) sendo assim + o mesmo será removido da própria */ + else if(relacionamento) + relacionamento->removerObjeto(dynamic_cast(this->objeto)); + + /* Desaloca o objeto, porém tabelas e relacionamentos, que são casos especiais, + não são desalocados */ + if(tipo_obj!=OBJETO_TABELA && tipo_obj!=OBJETO_RELACAO) + { + delete(this->objeto); + this->objeto=NULL; + } + + if(lista_op) + lista_op->removerUltimaOperacao(); + } + + /* Caso o objeto não seja novo, restaura seu estado anterior + desfazendo a operação de modificação do mesmo na lista + de operações */ + if(!novo_obj && + lista_op && tipo_obj!=OBJETO_BANCO_DADOS && + tipo_obj!=OBJETO_PERMISSAO) + { + try + { + lista_op->desfazerOperacao(); + //Remove a ultima operação adicionada referente ao objeto editado/criado + lista_op->removerUltimaOperacao(); + } + catch(Excecao &e) + {} + } + + /* Emite um sinal indicando que o objeto foi manipulado de modo que + seu estado anterior à edição foi restaurado e assim como a lista + de operações sofreu modificações */ + emit s_objetoManipulado(); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/objetobasewidget.h b/libpgmodeler_ui/src/objetobasewidget.h new file mode 100644 index 000000000..93b1a3a8c --- /dev/null +++ b/libpgmodeler_ui/src/objetobasewidget.h @@ -0,0 +1,207 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ObjetoBaseWidget +# Descrição: Definição da classe que implementa operações básicas +# dos formulários de criação e edição de objetos no modelo +# de banco de dados. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef OBJETO_BASE_WIDGET_H +#define OBJETO_BASE_WIDGET_H + +#include +#include "modelobd.h" +#include "listaoperacoes.h" +#include "formbasico.h" +#include "seletorobjetowidget.h" +#include "ui_objetobasewidget.h" + +/* Declarando a classe TipoPgSQL como metatype para que esta + possa ser usada em conjunto com a classe QVariant (vide documentação + da classe QVariant e QMetaType). Esta declaração é uma macro específica + do Qt e está sendo usada para facilitar o uso com classes que necessitam + armazenar Tipos pgsql em seus containeres (TabelaObjetosWidget). + Essa declaração não afeta o comportamento das demais classes que de algum + modo referenciam a classe TipoPgSQL.*/ +#include +Q_DECLARE_METATYPE(TipoPgSQL) +//*********************************************************** +class ObjetoBaseWidget: public QDialog, public Ui::ObjetoBaseWidget { + Q_OBJECT + + private: + /* Armazena a altura mínima e máxima da janela pai. + Estes atributos são usados para controlar a exibição do + frame de alerta de objeto protegido e redimensionamento + da janela pai quando este está visível */ + int alt_min_jp, alt_max_jp; + + protected: + static const QColor COR_FUNDO_LIN_PROT, + COR_TEXTO_LIN_PROT, + COR_FUNDO_LIN_INCREL, + COR_TEXTO_LIN_INCREL; + + //Janela que sustenta todos os widgets do formulário + FormBasico *janela_pai; + + //Modelo de banco de dados de referência + ModeloBD *modelo; + + //Tabela de referência (usado em formulário de objeto de tabela) + Tabela *tabela; + + /* Relacionamento de referência (pode ser usado em formulários + de coluna e restrição relacionamentos tabela-tabela podem + ter colunas (atributos) e restriões nos atributos */ + Relacionamento *relacionamento; + + //Lista de operações de referência + ListaOperacoes *lista_op; + + //Objeto que está sendo editado ou criado + ObjetoBase *objeto; + + /* Armazena a posição do objeto no momento da chamado do + formulário (apenas para objetos gráficos) */ + float px_objeto, py_objeto; + + QGridLayout *objetobase_grid; + + /* Indica se o objeto é novo (que não se trata de um objeto já + existente e não está sendo editado) */ + bool novo_obj; + + /* Armazena o destacador de sintaxe que é usado para destacar + o nome do objeto pai */ + DestaqueSintaxe *dest_nomepai_txt; + + //Seletores de esquema, dono e espaço de tabela + SeletorObjetoWidget *sel_esquema, + *sel_dono, + *sel_esptabela; + + /* Constantes usadas para gerar strings intervalos de versões. + Estas constantes deve ser aplicadas ao método gerarIntervaloVersoes() + pois é um metodo que gera chaves para os mapas de campos passados + para o método gerarFrameAlertaVersao() */ + static const unsigned ATE_VERSAO=0, + INTER_VERSOES=1, + APOS_VERSAO=2; + + /* Gera strings de intervalos de versões para servirem de informativo ao + usuário no método gerarFrameAlertaVersao(). + Os intervalos gerados têm um dos seguinte formatos: + + * ver_ini <= ver_fim - Intervalo de versões + * <= ver_ini - Até a versão indicada + * >= ver_ini - Igual ou após a versão indicada. */ + static QString gerarIntervaloVersoes(unsigned tipo_intervalo, const QString &ver_ini, const QString &ver_fim=""); + + /* Gera o frame de alerta dos campos específicos das versões do pgsql. + Os mapas de campos manipulados por este método devem ter como chaves + as versões do pgsql os quais os campos são obrigatório. Recomenda-se + o uso das constantes de versão da classe ParserEsquema */ + QFrame *gerarFrameAlertaVersao(map > &campos, map > *valores=NULL); + + //Gera um frame informativo com icone de informação e a mensagem + QFrame *gerarFrameInformacao(const QString &mensagem); + + /* Faz a mesclagem dos layouts de formulário desta classe base (objetobase_grid) + com os formulários das classes filhas desta no caso o parâmetro 'grid'. + Isso é feito para que os campos comuns a todas as classes filhas os quais + pertencem a esta classe estejam acessíveis. O parâmetro 'tipo_obj' é usado + para esconder alguns campos do formulário básico quando estes não se aplicam + ao tipo de objeto informado */ + void configurarLayouFormulario(QGridLayout *grid=NULL, TipoObjetoBase tipo_obj=OBJETO_BASE); + + /* Este método se aplica aos tipos de objetos diferentes do tipo OBJETO_BANCO_DADOS + e que são passíveis de alocação e e desalocação, pois este método faz a cópia do + objeto em edição para a lista de operação no caso de edição ou aloca um novo + objeto no caso de criação de um novo elemento.*/ + template + void iniciarConfiguracao(void); + + /* Finaliza a edição/criação do objeto, inserindo o mesmo na lista de operações + para possibilitar a reversão da criação do mesmo. Além disso, procede + com a emissão do sinal de objeto manipulado e fechamento do formulário.*/ + void finalizarConfiguracao(void); + + /* Aborta a configuração do objeto, desalocando o mesmo em caso de novo objeto, + restaurando o objeto a seu estado original antes da edição + e removendo a operação de lista de operações referente a este objeto */ + void cancelarConfiguracao(void); + + /* Aplica as configurações básicas (nome, esquema, comentario, espaço tabela e dono) + ao objeto que está sendo modificado */ + void aplicarConfiguracao(void); + + public: + ObjetoBaseWidget(QWidget * parent = 0, TipoObjetoBase tipo_obj=OBJETO_BASE); + ~ObjetoBaseWidget(void); + void hideEvent(QHideEvent *); + void showEvent(QShowEvent *); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, + ObjetoBase *objeto, ObjetoBase *objeto_pai=NULL, + float px_objeto=NAN, float py_objeto=NAN); + + protected slots: + void editarPermissoes(void); + + public slots: + void show(void); + + signals: + void s_objetoManipulado(void); +}; +//---------------------------------------------------------- +template +void ObjetoBaseWidget::iniciarConfiguracao(void) +{ + try + { + Classe *novo_obj_tmpl=NULL; + + if(this->objeto && lista_op && + this->objeto->obterTipoObjeto()!=OBJETO_BANCO_DADOS) + { + if(this->tabela) + lista_op->adicionarObjeto(this->objeto, Operacao::OBJETO_MODIFICADO, -1, this->tabela); + else + lista_op->adicionarObjeto(this->objeto, Operacao::OBJETO_MODIFICADO, -1, this->relacionamento); + novo_obj=false; + } + /* Caso o formulário esteja sendo usado para criar um novo + objeto ou seja o ponteiro this->objeto está nulo */ + else if(!this->objeto) + { + //Aloca um novo esquema e o atribui ao objeto this->objeto + novo_obj_tmpl=new Classe; + this->objeto=novo_obj_tmpl; + //Marca o flag indicando que um novo objeto foi criado + novo_obj=true; + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/operadorwidget.cpp b/libpgmodeler_ui/src/operadorwidget.cpp new file mode 100644 index 000000000..b99140e4c --- /dev/null +++ b/libpgmodeler_ui/src/operadorwidget.cpp @@ -0,0 +1,175 @@ +#include "operadorwidget.h" +//*********************************************************** +OperadorWidget::OperadorWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_OPERADOR) +{ + try + { + QGridLayout *grid=NULL; + unsigned i; + map > mapa_campos; + QFrame *frame=NULL; + + Ui_OperadorWidget::setupUi(this); + + //Alocando os widget de configuração de argumento do operador + tipo_args[0]=NULL; + tipo_args[0]=new TipoPgSQLWidget(this, trUtf8("Tipo Argumento Direita")); + tipo_args[1]=NULL; + tipo_args[1]=new TipoPgSQLWidget(this, trUtf8("Tipo Argumento Esquerda")); + + grid=new QGridLayout; + grid->setContentsMargins(2,2,2,2); + grid->addWidget(tipo_args[0],0,0); + grid->addWidget(tipo_args[1],1,0); + + //Gera o frame de informação sobre a criação de operador unário + frame=gerarFrameInformacao(trUtf8("Para a criação de um operador unário é necessário especificar como 'any'\ + um de seus argumentos. Adicionalmente, a função que define o operador deve possuir apenas uma parâmetro\ + e este, por sua vez, deve ter o tipo de dado igual ao tipo de dado do argumento do operador unário.")); + grid->addWidget(frame, 2, 0); + atributos_twg->widget(0)->setLayout(grid); + + //Alocando os seletores de função + grid=dynamic_cast(atributos_twg->widget(1)->layout()); + for(i=Operador::FUNC_OPERADOR; i <= Operador::FUNC_RESTRICAO; i++) + { + sel_funcoes[i]=NULL; + sel_funcoes[i]=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + grid->addWidget(sel_funcoes[i],i,1,1,1); + } + + //Alocando os seletores de operador + grid=dynamic_cast(atributos_twg->widget(2)->layout()); + for(i=Operador::OPER_COMUTACAO; i <= Operador::OPER_MAIOR; i++) + { + sel_operadores[i]=NULL; + sel_operadores[i]=new SeletorObjetoWidget(OBJETO_OPERADOR, true, this); + grid->addWidget(sel_operadores[i],i,1,1,1); + } + + //Gera o frame de alerta com os campos que são exclusivos para versões do postgresql + mapa_campos[gerarIntervaloVersoes(ATE_VERSAO, ParserEsquema::VERSAO_PGSQL_82)].push_back(op_ordenacao1_lbl); + mapa_campos[gerarIntervaloVersoes(ATE_VERSAO, ParserEsquema::VERSAO_PGSQL_82)].push_back(op_ordenacao2_lbl); + mapa_campos[gerarIntervaloVersoes(ATE_VERSAO, ParserEsquema::VERSAO_PGSQL_82)].push_back(op_menorque_lbl); + mapa_campos[gerarIntervaloVersoes(ATE_VERSAO, ParserEsquema::VERSAO_PGSQL_82)].push_back(op_maiorque_lbl); + frame=gerarFrameAlertaVersao(mapa_campos); + grid->addWidget(frame, grid->count()+1, 0, 1, 0); + frame->setParent(atributos_twg->widget(2)); + + configurarLayouFormulario(operador_grid, OBJETO_OPERADOR); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->resize(530, 560); + janela_pai->setMinimumWidth(530); + janela_pai->setMinimumHeight(560); + janela_pai->setMaximumHeight(560); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void OperadorWidget::hideEvent(QHideEvent *evento) +{ + unsigned i; + + //Desmarca os checkboxes + hashes_chk->setChecked(false); + merges_chk->setChecked(false); + + //Zera os valores do seletores de operador + for(i=Operador::FUNC_OPERADOR; i <= Operador::FUNC_RESTRICAO; i++) + sel_funcoes[i]->removerObjetoSelecionado(); + + //Zera os valores do seletores de função + for(i=Operador::OPER_COMUTACAO; i <= Operador::OPER_MAIOR; i++) + sel_operadores[i]->removerObjetoSelecionado(); + + atributos_twg->setCurrentIndex(0); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void OperadorWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Operador *operador) +{ + unsigned i; + TipoPgSQL tipo_esq, tipo_dir; + + //Preenchendo os campos básicos do formulário com os atributos do operador + ObjetoBaseWidget::definirAtributos(modelo,lista_op,operador); + + //Define o modelo de objetos usado pelos seletores de função e operador + for(i=Operador::FUNC_OPERADOR; i <= Operador::FUNC_RESTRICAO; i++) + sel_funcoes[i]->definirModelo(modelo); + + for(i=Operador::OPER_COMUTACAO; i <= Operador::OPER_MAIOR; i++) + sel_operadores[i]->definirModelo(modelo); + + /* Caso o operador esteja alocado configura os atributos do formulário + com os valores preenchidos na instância do operador */ + if(operador) + { + hashes_chk->setChecked(operador->aceitaHashes()); + merges_chk->setChecked(operador->aceitaMerges()); + + //Preenche os widget seletores de função com as funções usadas pelo operador + for(i=Operador::FUNC_OPERADOR; i <= Operador::FUNC_RESTRICAO; i++) + sel_funcoes[i]->definirObjeto(operador->obterFuncao(i)); + + //Preenche os widget seletores de operador com os operadores usadas pelo operador + for(i=Operador::OPER_COMUTACAO; i <= Operador::OPER_MAIOR; i++) + sel_operadores[i]->definirObjeto(operador->obterOperador(i)); + + //Obtém os tipos dos argumentos do operador + tipo_esq=operador->obterTipoDadoArgumento(Operador::ARG_ESQUERDA); + tipo_dir=operador->obterTipoDadoArgumento(Operador::ARG_DIREITA); + } + + tipo_args[0]->definirAtributos(tipo_esq, modelo); + tipo_args[1]->definirAtributos(tipo_dir, modelo); +} +//--------------------------------------------------------- +void OperadorWidget::aplicarConfiguracao(void) +{ + try + { + unsigned i; + Operador *operador=NULL; + iniciarConfiguracao(); + + //Obtém a referência à sequência que está sendo editada/criada + operador=dynamic_cast(this->objeto); + + /* Atribui os valores configurados no formulário à instância do + operador que está sendo configurado */ + operador->definirHashes(hashes_chk->isChecked()); + operador->definirMerges(merges_chk->isChecked()); + + //Atribuindo os tipos de argumentos configurados no formulário ao operador + for(i=Operador::ARG_ESQUERDA; i <= Operador::ARG_DIREITA; i++) + operador->definirTipoDadoArgumento(tipo_args[i]->obterTipoPgSQL(), i); + + //Atribuindo as funções selecionadas no formulário ao operador + for(i=Operador::FUNC_OPERADOR; i <= Operador::FUNC_RESTRICAO; i++) + operador->definirFuncao(dynamic_cast(sel_funcoes[i]->obterObjeto()), i); + + //Atribuindo os operadores selecionados no formulário ao operador + for(i=Operador::OPER_COMUTACAO; i <= Operador::OPER_MAIOR; i++) + operador->definirOperador(dynamic_cast(sel_operadores[i]->obterObjeto()), i); + + //Finaliza a configuração + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/operadorwidget.h b/libpgmodeler_ui/src/operadorwidget.h new file mode 100644 index 000000000..d550033bb --- /dev/null +++ b/libpgmodeler_ui/src/operadorwidget.h @@ -0,0 +1,50 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: OperadorWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de operadores. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef OPERADOR_WIDGET_H +#define OPERADOR_WIDGET_H + +#include "objetobasewidget.h" +#include "tipopgsqlwidget.h" +#include "ui_operadorwidget.h" +//*********************************************************** +class OperadorWidget: public ObjetoBaseWidget, public Ui::OperadorWidget { + Q_OBJECT + + private: + TipoPgSQLWidget *tipo_args[2]; + SeletorObjetoWidget *sel_funcoes[3], + *sel_operadores[6]; + + public: + OperadorWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Operador *operador); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/papelwidget.cpp b/libpgmodeler_ui/src/papelwidget.cpp new file mode 100644 index 000000000..51418d016 --- /dev/null +++ b/libpgmodeler_ui/src/papelwidget.cpp @@ -0,0 +1,356 @@ +#include "papelwidget.h" +#include "visaoobjetoswidget.h" +extern VisaoObjetosWidget *selecaoobjetos_wgt; +//*********************************************************** +PapelWidget::PapelWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_PAPEL) +{ + TabelaObjetosWidget *tab_obj=NULL; + QGridLayout *grid=NULL; + unsigned i; + + Ui_PapelWidget::setupUi(this); + configurarLayouFormulario(papel_grid, OBJETO_PAPEL); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(membros_twg, SIGNAL(currentChanged(int)), this, SLOT(configurarSelecaoPapeis(void))); + + //Alocação e configuração das tabela de papéis membros + for(i=0; i < 3; i++) + { + //Aloca uma tabela e armazena seu endereço no vetor + tab_obj=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + TabelaObjetosWidget::BTN_ATUALIZAR_ITEM, true, this); + tab_membros[i]=tab_obj; + + /* + Cada tabela de membros possui 6 colunas, sendo elas: + * Nome do papel membro + * Id do papel membro + * Validade do papel membro + * Lista de papéis os quais o papel membro faz parte + * Membros do papel membro + * Membros com privilégio de adm. do papel membro + */ + tab_obj->definirNumColunas(6); + + tab_obj->definirRotuloCabecalho(trUtf8("Papel"),0); + tab_obj->definirIconeCabecalho(QPixmap(":/icones/icones/role.png"),0); + + tab_obj->definirRotuloCabecalho(trUtf8("SysID"),1); + tab_obj->definirIconeCabecalho(QPixmap(":/icones/icones/uid.png"),1); + + tab_obj->definirRotuloCabecalho(trUtf8("Validade"),2); + tab_obj->definirIconeCabecalho(QPixmap(":/icones/icones/validade.png"),2); + + tab_obj->definirRotuloCabecalho(trUtf8("Membro de"),3); + tab_obj->definirIconeCabecalho(QPixmap(":/icones/icones/role.png"),3); + + tab_obj->definirRotuloCabecalho(trUtf8("Membros"),4); + tab_obj->definirIconeCabecalho(QPixmap(":/icones/icones/role.png"),4); + + tab_obj->definirRotuloCabecalho(trUtf8("Membros (Admin.)"),5); + tab_obj->definirIconeCabecalho(QPixmap(":/icones/icones/role.png"),5); + + /* Cria um layout em grade adiciona a tabela alocada e a + insere na tabwidget o qual comporta as tabelas */ + grid=new QGridLayout; + grid->addWidget(tab_obj,0,0,1,1); + grid->setContentsMargins(2,2,2,2); + membros_twg->widget(i)->setLayout(grid); + } + + janela_pai->setMinimumSize(500, 530); +} +//---------------------------------------------------------- +void PapelWidget::configurarSelecaoPapeis(void) +{ + unsigned i; + + /* Desconecta todos os sinais-slots das tabelas de membros + isso evita que o método de selecionar papel membro seja + executado várias vezes por estar conectado às três + instâncias das tabelas de membros */ + for(i=0; i < 3; i++) + disconnect(tab_membros[i],0,this,0); + + /* Conecta os sinais enviados pela tabela atual para executar o + método de seleção papel membro */ + connect(tab_membros[membros_twg->currentIndex()], SIGNAL(s_linhaAdicionada(int)), this, SLOT(selecionarPapelMembro(void))); + connect(tab_membros[membros_twg->currentIndex()], SIGNAL(s_linhaEditada(int)), this, SLOT(selecionarPapelMembro(void))); +} +//---------------------------------------------------------- +void PapelWidget::selecionarPapelMembro(void) +{ + selecaoobjetos_wgt->definirObjetoVisivel(OBJETO_PAPEL, true); + selecaoobjetos_wgt->definirModelo(this->modelo); + selecaoobjetos_wgt->show(); +} +//---------------------------------------------------------- +void PapelWidget::hideEvent(QHideEvent *evento) +{ + unsigned i; + + disconnect(selecaoobjetos_wgt,0,this,0); + + //Remove todas as linhas das tabelas de membros + for(i=0; i < 3; i++) + tab_membros[i]->blockSignals(true); + //disconnect(tab_membros[i],0,this,0); + + for(i=0; i < 3; i++) + { + tab_membros[i]->removerLinhas(); + tab_membros[i]->blockSignals(false); + } + + //Configura o tab widget de membros para exibir a primeira tabela + membros_twg->setCurrentIndex(0); + + sysid_sb->setValue(sysid_sb->minValue()); + senha_edt->clear(); + limconexao_sb->setValue(limconexao_sb->minValue()); + superusr_chk->setChecked(false); + herdarperm_chk->setChecked(false); + criarbd_chk->setChecked(false); + permitirlogin_chk->setChecked(false); + criarusr_chk->setChecked(false); + senhacripto_chk->setChecked(false); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void PapelWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Papel *papel) +{ + if(papel) + { + /* Preenche os widgets do formulário específicos de objetos papel + com os valores presentes no objeto papel passado */ + sysid_sb->setValue(papel->obterSysid()); + limconexao_sb->setValue(papel->obterLimiteConexao()); + senha_edt->setText(papel->obterSenha()); + validade_dte->setDateTime(QDateTime::fromString(papel->obterValidade(),"yyyy-MM-dd hh:mm")); + + /* Marca as checkboxes de opção do papel de acordo com a configuração + atual de tais opções no papel passado */ + superusr_chk->setChecked(papel->obterOpcao(Papel::OP_SUPERUSER)); + criarbd_chk->setChecked(papel->obterOpcao(Papel::OP_CREATEDB)); + criarusr_chk->setChecked(papel->obterOpcao(Papel::OP_CREATEROLE)); + senhacripto_chk->setChecked(papel->obterOpcao(Papel::OP_ENCRYPTED)); + herdarperm_chk->setChecked(papel->obterOpcao(Papel::OP_INHERIT)); + permitirlogin_chk->setChecked(papel->obterOpcao(Papel::OP_LOGIN)); + } + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, papel); + + //Preenche a tabela de membros do papel + preencherTabelaMembros(); + + connect(selecaoobjetos_wgt, SIGNAL(s_visibilityChanged(ObjetoBase*,bool)), this, SLOT(exibirDadosPapelSelecionado(void))); + configurarSelecaoPapeis(); +} +//---------------------------------------------------------- +void PapelWidget::exibirDadosPapel(Papel *papel, unsigned idx_tabela, unsigned lin) +{ + if(papel) + { + QString str_aux; + Papel *papel_aux=NULL; + unsigned qtd, i, id_tipo, + tipo_papeis[3]={ Papel::PAPEL_REF, Papel::PAPEL_MEMBRO, Papel::PAPEL_ADMIN }; + + if(idx_tabela > 3) + throw Excecao(ERR_PGMODELER_REFOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + /* Atribui como dado da linha a referência ao papel membro, para tanto é necessário + converter a referência para void * pois é a única forma de ponteiro que + a classe QVariant aceita */ + tab_membros[idx_tabela]->definirDadoLinha(QVariant::fromValue(reinterpret_cast(papel)), lin); + + //Configura as informações básicas do membro + tab_membros[idx_tabela]->definirTextoCelula(QString::fromUtf8(papel->obterNome()), lin, 0); + tab_membros[idx_tabela]->definirTextoCelula(QString("%1").arg(papel->obterSysid()), lin, 1); + tab_membros[idx_tabela]->definirTextoCelula(papel->obterValidade(), lin, 2); + + /* Varre a lista de membros do papel obtido como membro atual + concatena todos os nomes obtidos em uma string e a coloca + na coluna respectiva ao tipo de membro auxiliar */ + for(id_tipo=0; id_tipo < 3; id_tipo++) + { + //Obtém a quantidade de tipos de membro atual do papel membro atual + qtd=papel->obterNumPapeis(tipo_papeis[id_tipo]); + + //Varre a lista atual concatenando os nomes + for(i=0; i < qtd; i++) + { + papel_aux=papel->obterPapel(tipo_papeis[id_tipo], i); + str_aux+=papel_aux->obterNome(); + if(i < qtd-1) str_aux+=", "; + } + + //Atribui a string configurada à coluna do tipo de membro do papel membro atual + tab_membros[idx_tabela]->definirTextoCelula(QString::fromUtf8(str_aux), lin, 3 + id_tipo); + str_aux.clear(); + } + } +} +//---------------------------------------------------------- +void PapelWidget::preencherTabelaMembros(void) +{ + //Caso exista um objeto a ser editado + if(this->objeto) + { + QString str_aux; + Papel *papel_aux=NULL, *papel=NULL; + unsigned qtd, i, id_tipo, + tipo_papeis[3]={ Papel::PAPEL_REF, Papel::PAPEL_MEMBRO, Papel::PAPEL_ADMIN }; + + //Converte a referência do objeto a ser editado em um referência a um papel + papel=dynamic_cast(this->objeto); + + /* O processo de preenchimento das tabelas se dá da seguinte forma: + * Os membros do papel em cada tipo (PAPEL_REF, PAPEL_MEMBRO, PAPEL_ADMIN) + são obtidos e colocados nas suas respectivas tabelas. Para isso a + varredura é feita usando um for e com o auxílio do vetor 'tipo_papeis'. + + * Adicionalmente algumas informações importantes são obtidas desses membros + como a data de validade da conta, o sysid, e os membros do papel membro + que é adicionado na tabela */ + for(id_tipo=0; id_tipo < 3; id_tipo++) + { + //Obtém o número de papéis membros do tipo atual + qtd=papel->obterNumPapeis(tipo_papeis[id_tipo]); + tab_membros[id_tipo]->blockSignals(true); + + //Varre a lista de tipos atual + for(i=0; i < qtd; i++) + { + //Obtém um papel da lista de membros + papel_aux=papel->obterPapel(tipo_papeis[id_tipo], i); + + //Adiciona uma linha na tabela respectiva ao tipo de membro + tab_membros[id_tipo]->adicionarLinha(); + + //Exibe o dado do papel na linha atual (i) + exibirDadosPapel(papel_aux, id_tipo, i); + } + + tab_membros[id_tipo]->blockSignals(true); + tab_membros[id_tipo]->limparSelecao(); + } + } +} +//---------------------------------------------------------- +void PapelWidget::exibirDadosPapelSelecionado(void) +{ + unsigned idx_tab; + int lin, idx_lin=-1; + ObjetoBase *obj_sel=NULL; + + //Obtém o papel selecionado na janela de seleção de objetos + obj_sel=selecaoobjetos_wgt->obterObjetoSelecao(); + + //Obtém o índice da tabela em foco atualmente + idx_tab=membros_twg->currentIndex(); + + //Obtém a linha selecionada da tabela atual + lin=tab_membros[idx_tab]->obterLinhaSelecionada(); + + /* Caso haja um objeto selecionado tenta obter o índice da linha + a qual armazene como dado o objeto selecionado isso é feito + para se validar se o usuário está tentando inserir na mesma + tabela um objeto por mais de uma vez */ + if(obj_sel) + idx_lin=tab_membros[idx_tab]->obterIndiceLinha(QVariant::fromValue(dynamic_cast(obj_sel))); + + /* Caso o objeto da seleção seja o mesmo do objeto sendo editado + um erro será disparado pois o objeto não pode referenciar + a ele mesmo */ + if(obj_sel && obj_sel==this->objeto) + { + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELER_REFREDUNDANTEPAPEIS) + .arg(QString::fromUtf8(obj_sel->obterNome())) + .arg(QString::fromUtf8(nome_edt->text())), + ERR_PGMODELER_REFREDUNDANTEPAPEIS,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + //Se o objeto da seleção não existir na tabela exibe seus dados + else if(obj_sel && idx_lin < 0) + exibirDadosPapel(dynamic_cast(obj_sel), idx_tab, lin); + else + { + /* Caso a linha atual da tabela não contenha nenhum dado isso indica + que a mesmo é uma linha vazia ou seja que foi inclúida recentemente + e sendo assim esta linha precisa ser removida caso o objeto da seleção + não seja usado */ + if(!tab_membros[idx_tab]->obterDadoLinha(lin).value()) + tab_membros[idx_tab]->removerLinha(lin); + + /* Caso o objeto da seleção já exista na tabela dispara uma exceção + pois o mesmo objeto não pode aparecer mais de uma vez na mesma tabela */ + if(obj_sel && idx_lin >= 0) + { + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELER_INSITEMPAPELDUPLIC) + .arg(QString::fromUtf8(obj_sel->obterNome())) + .arg(QString::fromUtf8(nome_edt->text())), + ERR_PGMODELER_INSITEMPAPELDUPLIC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + } +} +//---------------------------------------------------------- +void PapelWidget::aplicarConfiguracao(void) +{ + Papel *papel=NULL, *papel_aux=NULL; + unsigned qtd, i, id_tipo, + tipo_papeis[3]={ Papel::PAPEL_REF, Papel::PAPEL_MEMBRO, Papel::PAPEL_ADMIN }; + + try + { + //Inicia configuração do papel, alocando-o caso seja um novo objeto + iniciarConfiguracao(); + + /* Converte o objeto em edição para o tipo Papel, para se ter acesso + ao métodos específicos da classe */ + papel=dynamic_cast(this->objeto); + + //Configura o papel com os valores informados no formulário + papel->definirSysid(sysid_sb->value()); + papel->definirLimiteConexao(limconexao_sb->value()); + papel->definirSenha(senha_edt->text()); + papel->definirValidade(validade_dte->dateTime().toString("yyyy-MM-dd hh:mm")); + + papel->definirOpcao(Papel::OP_SUPERUSER, superusr_chk->isChecked()); + papel->definirOpcao(Papel::OP_CREATEDB, criarbd_chk->isChecked()); + papel->definirOpcao(Papel::OP_CREATEROLE, criarusr_chk->isChecked()); + papel->definirOpcao(Papel::OP_ENCRYPTED, senhacripto_chk->isChecked()); + papel->definirOpcao(Papel::OP_INHERIT, herdarperm_chk->isChecked()); + papel->definirOpcao(Papel::OP_LOGIN, permitirlogin_chk->isChecked()); + + /* Varre as tabelas de membros atribuindo os papéis constantes + nestas tabelas como papeis membros do papel em edição */ + for(id_tipo=0; id_tipo < 3; id_tipo++) + { + //Obtém a quantidade de elementos na tabela atual + qtd=tab_membros[id_tipo]->obterNumLinhas(); + if(qtd > 0) papel->removerPapeis(tipo_papeis[id_tipo]); + + for(i=0; i < qtd; i++) + { + //Extrái um objeto da linha atual + papel_aux=reinterpret_cast(tab_membros[id_tipo]->obterDadoLinha(i).value()); + //Atribui o mesmo como papel membro do papel atual + papel->definirPapel(tipo_papeis[id_tipo], papel_aux); + } + } + + //Aplica a configuração ao objeto + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/papelwidget.h b/libpgmodeler_ui/src/papelwidget.h new file mode 100644 index 000000000..307ea5004 --- /dev/null +++ b/libpgmodeler_ui/src/papelwidget.h @@ -0,0 +1,69 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: PapelWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de esquemas. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef PAPEL_WIDGET_H +#define PAPEL_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_papelwidget.h" +#include "tabelaobjetoswidget.h" +//*********************************************************** +class PapelWidget: public ObjetoBaseWidget, public Ui::PapelWidget { + Q_OBJECT + + private: + /* Armazena as referências às tabelas de membros do papel para que sejam + referenciados nos demais métodos de forma mais eficaz */ + TabelaObjetosWidget *tab_membros[3]; + + //Preenche as tabelas de membros do papel + void preencherTabelaMembros(void); + + //Exibe o dado do papel na tabela especificada + void exibirDadosPapel(Papel *papel, unsigned idx_tabela, unsigned lin); + + public: + PapelWidget(QWidget * parent = 0); + + void hideEvent(QHideEvent *); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Papel *papel); + + private slots: + /* Preenche com informações relacionadas ao papel selecionado + na linha atual da tabela em foco */ + void exibirDadosPapelSelecionado(void); + + /* Seleciona um papel membro para ser inserido na tabela de membro + atualmente em foco. Este slot é usando tanto para adicionar + um membro na tabela quanto para editar um membro selecionado */ + void selecionarPapelMembro(void); + + /* Faz a conexão de sinais-slots para cada tabela de objetos + à medida que a tabela em foco mude */ + void configurarSelecaoPapeis(void); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/parametrowidget.cpp b/libpgmodeler_ui/src/parametrowidget.cpp new file mode 100644 index 000000000..59d54991b --- /dev/null +++ b/libpgmodeler_ui/src/parametrowidget.cpp @@ -0,0 +1,89 @@ +#include "parametrowidget.h" +//*********************************************************** +ParametroWidget::ParametroWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_PARAMETRO) +{ + try + { + QGridLayout *parametro_grid=NULL; + QSpacerItem *hspacer=NULL; + + Ui_ParametroWidget::setupUi(this); + + tipo_pgsql=NULL; + tipo_pgsql=new TipoPgSQLWidget(this); + parametro_grid=new QGridLayout(this); + hspacer=new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + parametro_grid->setContentsMargins(0, 0, 0, 0); + + parametro_grid->addWidget(valorpadrao_lbl, 0, 0, 1, 1); + parametro_grid->addWidget(valorpadrao_edt, 0, 1, 1, 3); + parametro_grid->addWidget(modo_lbl, 1, 0, 1, 1); + parametro_grid->addWidget(param_in_chk, 1, 1, 1, 1); + parametro_grid->addWidget(param_out_chk, 1, 2, 1, 1); + parametro_grid->addItem(hspacer, 1, 3, 1, 1); + parametro_grid->addWidget(tipo_pgsql,2,0,1,4); + + configurarLayouFormulario(parametro_grid, OBJETO_PARAMETRO); + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->setMinimumSize(500, 270); + janela_pai->setMaximumSize(16777215, 270); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void ParametroWidget::hideEvent(QHideEvent *evento) +{ + //Reseta os campos do formulário ao esconder o mesmo + param_in_chk->setChecked(false); + param_out_chk->setChecked(false); + valorpadrao_edt->clear(); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void ParametroWidget::definirAtributos(Parametro param, ModeloBD *modelo) +{ + this->parametro=param; + + //Configura os campos do formulário com os valores do parâmetro passado + param_in_chk->setChecked(param.parametroEntrada()); + param_out_chk->setChecked(param.parametroSaida()); + valorpadrao_edt->setText(QString::fromUtf8(param.obterValorPadrao())); + tipo_pgsql->definirAtributos(param.obterTipo(), modelo); + + ObjetoBaseWidget::definirAtributos(modelo,NULL,&this->parametro); +} +//---------------------------------------------------------- +void ParametroWidget::aplicarConfiguracao(void) +{ + try + { + //iniciarConfiguracao(); + + //Configura o parâmetro com os valores do formulário + parametro.definirEntrada(param_in_chk->isChecked()); + parametro.definirSaida(param_out_chk->isChecked()); + parametro.definirValorPadrao(valorpadrao_edt->text()); + parametro.definirTipo(tipo_pgsql->obterTipoPgSQL()); + + /* Efetiva as configurações chamando o método de + aplicação das configurações da classe pai */ + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +Parametro ParametroWidget::obterParametro(void) +{ + return(parametro); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/parametrowidget.h b/libpgmodeler_ui/src/parametrowidget.h new file mode 100644 index 000000000..9ca88f958 --- /dev/null +++ b/libpgmodeler_ui/src/parametrowidget.h @@ -0,0 +1,56 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ParametroWidget +# Descrição: Definição da classe que implementa o formulário de +# edição de parâmetro de funções. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef PARAMETRO_WIDGET_H +#define PARAMETRO_WIDGET_H + + +#include "objetobasewidget.h" +#include "ui_parametrowidget.h" +#include "tipopgsqlwidget.h" +//*********************************************************** +class ParametroWidget: public ObjetoBaseWidget, public Ui::ParametroWidget { + Q_OBJECT + + private: + TipoPgSQLWidget *tipo_pgsql; + + //Armazena a cópia do parâmetro configurado + Parametro parametro; + + public: + ParametroWidget(QWidget * parent = 0); + void definirAtributos(Parametro parametro, ModeloBD *modelo); + + /* Retorna a cópia do parâmetro configurado. Este método deve + ser usado para se ter acesso ao parâmetro configurado */ + Parametro obterParametro(void); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/permissaowidget.cpp b/libpgmodeler_ui/src/permissaowidget.cpp new file mode 100644 index 000000000..7de2395ab --- /dev/null +++ b/libpgmodeler_ui/src/permissaowidget.cpp @@ -0,0 +1,637 @@ +#include "permissaowidget.h" +#include "visaoobjetoswidget.h" +extern VisaoObjetosWidget *selecaoobjetos_wgt; +//*********************************************************** +PermissaoWidget::PermissaoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_PERMISSAO) +{ + QGridLayout *grid=NULL; + QFont fonte; + QCheckBox *check=NULL; + unsigned i; + QString vet_priv[12]={ AtributosParsers::PRIV_SELECT, AtributosParsers::PRIV_INSERT, + AtributosParsers::PRIV_UPDATE, AtributosParsers::PRIV_DELETE, + AtributosParsers::PRIV_TRUNCATE, AtributosParsers::PRIV_REFERENCES, + AtributosParsers::PRIV_TRIGGER, AtributosParsers::PRIV_CREATE, + AtributosParsers::PRIV_CONNECT, AtributosParsers::PRIV_TEMPORARY, + AtributosParsers::PRIV_EXECUTE, AtributosParsers::PRIV_USAGE }; + + Ui_PermissaoWidget::setupUi(this); + + permissao=NULL; + + /* Configura a janela pai inserindo o formulário de + edição de permissões como filho */ + janela_pai->widgetgeral_wgt->insertWidget(0, this); + janela_pai->widgetgeral_wgt->setCurrentIndex(0); + janela_pai->definirBotoes(CaixaMensagem::BOTAO_OK); + connect(janela_pai->aplicar_ok_btn, SIGNAL(clicked(bool)), janela_pai, SLOT(close(void))); + + //Configura a dimensão da janela pai + janela_pai->setMinimumSize(670, 480); + + /* Alterando o texto do label de comentário para 'Tipo:'. + como este formulário é herdado do formulário padrão, o + campo 'Comentário' passa a ser o campo que mostra o + tipo do objeto o qual se está configurando as permissões. + Além disso o campo nome e comentario são marcados como + read-only pois o usuário não tem acesso a esses campos. */ + comentario_lbl->setText(trUtf8("Tipo:")); + fonte=nome_edt->font(); + fonte.setItalic(true); + comentario_edt->setFont(fonte); + comentario_edt->setReadOnly(true); + nome_edt->setFont(fonte); + nome_edt->setReadOnly(true); + + //Configura o formulário adicionando os campos de edição de permissão + configurarLayouFormulario(permissao_grid, OBJETO_PERMISSAO); + + //Cria a tabela de papéis com os botões de inserir, remover e editar item + tab_papeis=new TabelaObjetosWidget(TabelaObjetosWidget::BTN_INSERIR_ITEM | + TabelaObjetosWidget::BTN_REMOVER_ITEM | + TabelaObjetosWidget::BTN_EDITAR_ITEM, false, this); + tab_papeis->definirNumColunas(1); + tab_papeis->definirRotuloCabecalho(trUtf8("Papel"),0); + tab_papeis->definirIconeCabecalho(QPixmap(":/icones/icones/role.png"),0); + + /* Insere a tabela de papéis em um grid layout para que a mesma + se adapte ao layout da janela */ + grid=new QGridLayout; + grid->addWidget(tab_papeis,0,0,1,1); + grid->setContentsMargins(2,2,2,2); + papeis_gb->setLayout(grid); + + //Cria a tabela de permissões com os botões de inserir, remover e editar item + tab_permissoes=new TabelaObjetosWidget(TabelaObjetosWidget::BTN_REMOVER_ITEM | + TabelaObjetosWidget::BTN_EDITAR_ITEM | + TabelaObjetosWidget::BTN_LIMPAR_ITENS, true, this); + tab_permissoes->definirNumColunas(3); + tab_permissoes->definirRotuloCabecalho(trUtf8("Id"),0); + tab_permissoes->definirIconeCabecalho(QPixmap(":/icones/icones/uid.png"),0); + tab_permissoes->definirRotuloCabecalho(trUtf8("Papéis"),1); + tab_permissoes->definirIconeCabecalho(QPixmap(":/icones/icones/role.png"),1); + tab_permissoes->definirRotuloCabecalho(trUtf8("Privilégios"),2); + tab_permissoes->definirIconeCabecalho(QPixmap(":/icones/icones/grant.png"),2); + + /* Insere a tabela de permissões em um grid layout para que a mesma + se adapte ao layout da janela */ + grid=new QGridLayout; + grid->addWidget(tab_permissoes,0,0,1,1); + grid->setContentsMargins(2,2,2,2); + permissoes_gb->setLayout(grid); + + /* Cria a lista de privilégios criando checkboxes com as + descrições de cada privilégio */ + for(i=Permissao::PRIV_SELECT; i<=Permissao::PRIV_USAGE; i++) + { + //O primeiro checkbox é o que possui o nome do privilégio + check=new QCheckBox; + check->setText(vet_priv[i].toUpper()); + privilegios_tbw->insertRow(i); + privilegios_tbw->setCellWidget(i,0,check); + //Conecta o sinal de clique no chebox ao método que mapeia a marcação de privilégio + connect(check, SIGNAL(clicked(bool)), this, SLOT(marcarPrivilegio(void))); + + //O segundo checkbox é o que indica se o privilégio é com GRANT OPTION + check=new QCheckBox; + check->setText("GRANT OPTION"); + privilegios_tbw->setCellWidget(i,1,check); + //Conecta o sinal de clique no chebox ao método que mapeia a marcação de privilégio + connect(check, SIGNAL(clicked(bool)), this, SLOT(marcarPrivilegio(void))); + } + + connect(tab_papeis, SIGNAL(s_linhaAdicionada(int)), tab_papeis, SLOT(selecionarLinha(int))); + connect(tab_papeis, SIGNAL(s_linhaEditada(int)), this, SLOT(selecionarPapel(void))); + connect(tab_papeis, SIGNAL(s_linhaRemovida(int)), this, SLOT(habilitarBotoesEdicao(void))); + + connect(tab_permissoes, SIGNAL(s_linhaEditada(int)), this, SLOT(editarPermissao(void))); + connect(tab_permissoes, SIGNAL(s_linhaSelecionada(int)), this, SLOT(selecionarPermissao(int))); + connect(tab_permissoes, SIGNAL(s_linhaRemovida(int)), this, SLOT(removerPermissao(void))); + + connect(cancelar_tb, SIGNAL(clicked(bool)), this, SLOT(cancelarOperacao(void))); + connect(inserir_perm_tb, SIGNAL(clicked(bool)), this, SLOT(adicionarPermissao(void))); + connect(atualizar_perm_tb, SIGNAL(clicked(bool)), this, SLOT(atualizarPermissao(void))); +} +//---------------------------------------------------------- +void PermissaoWidget::hideEvent(QHideEvent *evento) +{ + disconnect(selecaoobjetos_wgt,0,this,0); + cancelarOperacao(); + + /* Desconecta o sinal de linhasRemovidas da tabela de permissões para que todas + as linhas existentes sejam removidas sem disparar o método removerPermissoes + da classe PermissaoWidget */ + tab_permissoes->blockSignals(true); + tab_permissoes->removerLinhas(); + tab_permissoes->blockSignals(false); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//----------------------------------------------------------- +void PermissaoWidget::definirAtributos(ModeloBD *modelo, ObjetoBase *objeto_pai, ObjetoBase *objeto) +{ + /* Chama o método de definição de atributos da classe Pai para depois + configurar os atributos relacionados à classe PermissaoWidget */ + ObjetoBaseWidget::definirAtributos(modelo,NULL,objeto,objeto_pai); + + if(objeto) + { + unsigned priv; + QCheckBox *chk=NULL, *chk1=NULL; + TipoObjetoBase tipo_obj; + + connect(selecaoobjetos_wgt, SIGNAL(s_visibilityChanged(ObjetoBase*,bool)), this, SLOT(exibirDadosPapelSelecionado(void))); + connect(tab_papeis, SIGNAL(s_linhaAdicionada(int)), this, SLOT(selecionarPapel(void))); + connect(tab_permissoes, SIGNAL(s_linhasRemovidas(void)), this, SLOT(removerPermissoes(void))); + + //Preenche os campos do formulario com os atributos do objeto + nome_edt->setText(QString::fromUtf8(objeto->obterNome(true))); + comentario_edt->setText(QString::fromUtf8(objeto->obterNomeTipoObjeto())); + tipo_obj=objeto->obterTipoObjeto(); + + /* Faz uma varredura usando os privilégios disponíveis para os objetos. + O objetivo é deixar visível ao usuário somente os privilégios referentes + ao objeto atualmente em edição. */ + for(priv=Permissao::PRIV_SELECT; priv<=Permissao::PRIV_USAGE; priv++) + { + //Obtém os checkboxes que representam o priviléigo e a opção GRANT OPTION + chk=dynamic_cast(privilegios_tbw->cellWidget(priv,0)); + chk1=dynamic_cast(privilegios_tbw->cellWidget(priv,1)); + //Desmarca ambos os checks + chk->setChecked(false); + chk1->setChecked(false); + + /* Valida o tipo de privilégio atual com o tipo do objeto editado atualmente. + caso o par (privilégio, tipo do objeto) coincida com uma das condições a + seguir a linha referente ao privilégio é mostrada na tabela, caso contrário + é ocultada */ + if(((priv==Permissao::PRIV_SELECT || priv==Permissao::PRIV_UPDATE) && + (tipo_obj==OBJETO_TABELA || tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_SEQUENCIA)) || + + ((priv==Permissao::PRIV_INSERT || priv==Permissao::PRIV_DELETE) && + (tipo_obj==OBJETO_TABELA)) || + + ((priv==Permissao::PRIV_INSERT) && (tipo_obj==OBJETO_COLUNA)) || + + ((priv==Permissao::PRIV_TRUNCATE || priv==Permissao::PRIV_TRIGGER) && + (tipo_obj==OBJETO_TABELA)) || + + (priv==Permissao::PRIV_REFERENCES && + (tipo_obj==OBJETO_TABELA || tipo_obj==OBJETO_COLUNA)) || + + (priv==Permissao::PRIV_CREATE && + (tipo_obj==OBJETO_BANCO_DADOS || tipo_obj==OBJETO_ESQUEMA || tipo_obj==OBJETO_ESPACO_TABELA)) || + + ((priv==Permissao::PRIV_CONNECT || priv==Permissao::PRIV_TEMPORARY) && + (tipo_obj==OBJETO_BANCO_DADOS)) || + + (priv==Permissao::PRIV_EXECUTE && + (tipo_obj==OBJETO_FUNCAO || tipo_obj==OBJETO_FUNC_AGREGACAO)) || + + (priv==Permissao::PRIV_USAGE && + (tipo_obj==OBJETO_SEQUENCIA || tipo_obj==OBJETO_LINGUAGEM || tipo_obj==OBJETO_ESQUEMA)) || + + (priv==Permissao::PRIV_SELECT && tipo_obj==OBJETO_VISAO)) + { + privilegios_tbw->setRowHidden(priv, false); + } + else + privilegios_tbw->setRowHidden(priv, true); + } + + //Atualiza a listagem das permissões + listarPermissoes(); + //Por padrão, deseleciona qualquer permissão marcada na tabela + tab_permissoes->limparSelecao(); + } +} +//----------------------------------------------------------- +void PermissaoWidget::selecionarPapel(void) +{ + selecaoobjetos_wgt->definirObjetoVisivel(OBJETO_PAPEL, true); + selecaoobjetos_wgt->definirModelo(this->modelo); + selecaoobjetos_wgt->show(); +} +//----------------------------------------------------------- +void PermissaoWidget::selecionarPermissao(int idx_perm) +{ + if(idx_perm >= 0) + permissao=reinterpret_cast(tab_permissoes->obterDadoLinha(idx_perm).value()); + else + permissao=NULL; +} +//----------------------------------------------------------- +void PermissaoWidget::listarPermissoes(void) +{ + if(modelo) + { + vector permissoes; + Permissao *perm=NULL; + unsigned i, qtd, i1, qtd1; + QString str_aux; + + //Obtém as permissões relacionadas ao objeto armazenando em uma lista + modelo->obterPermissoes(this->objeto, permissoes); + qtd=permissoes.size(); + + /* Disconecta o sinal linhasRemovidas da tabela de permissões para remover + todas as linhas sem que o método removerPermissoes seja chamado, ou seja, + as linhas são removidas sem qualquer tipo de tratamento */ + tab_permissoes->blockSignals(true); + //Remove as linhas da tabela sem qualquer tratamento + tab_permissoes->removerLinhas(); + + /* Reconecta o sinal para que interações de remoção de permissões por parte do usuário + possam ser tratadas normalmente */ + tab_permissoes->blockSignals(false); + + //Varre a lista de permissões obtidas exibindo os dados de cada uma na tabela de permissões + for(i=0; i < qtd; i++) + { + //Obtém uma permissão + perm=permissoes[i]; + + //Adiciona uma linha à tabela + tab_permissoes->adicionarLinha(); + //Define como dado da linha adicionada a permissão atual + tab_permissoes->definirDadoLinha(QVariant::fromValue(reinterpret_cast(perm)),i); + //Define o texto da celuna (0) da linha atual com o nome do privilégio (gerado automaticamente) + tab_permissoes->definirTextoCelula(perm->obterNome(),i,0); + //A segunda coluna da linha será a string que define os privilégios da permissão + tab_permissoes->definirTextoCelula(perm->obterStringPrivilegios(),i,2); + + /* A terceira coluna armazena os nomes concatenados de todos + os papéis relacionados à permissão */ + qtd1=perm->obterNumPapeis(); + for(i1=0; i1 < qtd1; i1++) + { + str_aux+=QString::fromUtf8(perm->obterPapel(i1)->obterNome()); + str_aux+=","; + } + str_aux.remove(str_aux.size()-1,1); + tab_permissoes->definirTextoCelula(str_aux,i,1); + str_aux.clear(); + } + } +} +//----------------------------------------------------------- +void PermissaoWidget::exibirDadosPapelSelecionado(void) +{ + int lin, idx_lin=-1; + Papel *papel=NULL; + + //Obtém o papel selecionado na janela de seleção de objetos + papel=dynamic_cast(selecaoobjetos_wgt->obterObjetoSelecao()); + + //Obtém a linha selecionada da tabela atual + lin=tab_papeis->obterLinhaSelecionada(); + + /* Caso haja um objeto selecionado tenta obter o índice da linha + a qual armazene como dado o objeto selecionado isso é feito + para se validar se o usuário está tentando inserir na mesma + tabela um objeto por mais de uma vez */ + if(papel) + idx_lin=tab_papeis->obterIndiceLinha(QVariant::fromValue(dynamic_cast(papel))); + + //Se o objeto da seleção não existir na tabela exibe seus dados + if(papel && idx_lin < 0) + { + tab_papeis->definirTextoCelula(QString::fromUtf8(papel->obterNome()), lin, 0); + tab_papeis->definirDadoLinha(QVariant::fromValue(dynamic_cast(papel)), lin); + } + else + { + /* Caso a linha atual da tabela não contenha nenhum dado isso indica + que a mesmo é uma linha vazia ou seja que foi inclúida recentemente + e sendo assim esta linha precisa ser removida caso o objeto da seleção + não seja usado */ + if(!tab_papeis->obterDadoLinha(lin).value()) + tab_papeis->removerLinha(lin); + + /* Caso o objeto da seleção já exista na tabela dispara uma exceção + pois o mesmo objeto não pode aparecer mais de uma vez na mesma tabela */ + if(papel && idx_lin >= 0) + { + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELER_ATROBJDUPLICCONT) + .arg(QString::fromUtf8(papel->obterNome())) + .arg(QString::fromUtf8(papel->obterNomeTipoObjeto())) + .arg(papeis_gb->title()), + ERR_PGMODELER_INSITEMPAPELDUPLIC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + } +} +//----------------------------------------------------------- +void PermissaoWidget::adicionarPermissao(void) +{ + Permissao *perm_aux=NULL; + + try + { + //Aloca uma permissão para o objeto + perm_aux=new Permissao(this->objeto); + + //Configura a nova permissão criada + configurarPermissao(perm_aux); + + //Adiciona a permissão ao modelo + modelo->adicionarPermissao(perm_aux); + + //Atualiza a lista de permissões + listarPermissoes(); + + /* Executa o método de cancelamento da operação + apenas para limpar o formulário e desabilitar + os botões. */ + cancelarOperacao(); + } + catch(Excecao &e) + { + /* Em caso de qualuqer erro for disparado + a permissão alocada é removida do modelo e + desalocada da memória */ + if(perm_aux) + { + modelo->removerPermissao(perm_aux); + delete(perm_aux); + } + + /* Cancela a operação de criação da permissão + limpando o formulário e desabilitando botões + de edição */ + cancelarOperacao(); + + //Redireciona o erro capturado + throw Excecao(e.obterMensagemErro(), e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void PermissaoWidget::atualizarPermissao(void) +{ + Permissao *perm_aux=NULL,*perm_bkp=NULL; + int idx_perm; + + try + { + //Aloca uma nova permissão para ser configurada + perm_aux=new Permissao(this->objeto); + + /* Cria uma permissão de backup. Esta receberá os + os valores atuais da permissão que está sendo editada + pois em caso de erro seus atributos originais são restaurados */ + perm_bkp=new Permissao(this->objeto); + (*perm_bkp)=(*permissao); + + //Configura a nova permissão com os atributos preenchidos no formulário + configurarPermissao(perm_aux); + + /* Tenta obter o índice de uma permissão no modelo na qual + suas configurações conincidam com as configurações da + permissão recém configurada (perm_aux) */ + idx_perm=modelo->obterIndicePermissao(perm_aux); + + /* Caso o índice seja negativo isso indica que a configuração da permissão auxiliar (perm_aux) não + se assemelha a nehuma permissão no modelo. Já se o índice for positivo e a permissão no + índice seja a mesma que está sendo edita (permissao) isso indica que a permissão auxiliar é + igual à permissão atual, podendo claramente ser atualizada. */ + if(idx_perm < 0 || (idx_perm >=0 && modelo->obterObjeto(idx_perm,OBJETO_PERMISSAO)==permissao)) + { + /* Copia os atributos da permissão auxiliar para a permissão atual + efetivando as alterações */ + (*permissao)=(*perm_aux); + //Atualiza a lista de permissões para exibir os dados da permissão atualizada + listarPermissoes(); + //Limpa o formulário e desabilita os botões de edição + cancelarOperacao(); + } + else + { + /* Qualquer outra situação além da comentado no if acima é considerada duplicação + de permissões gerando assim um erro */ + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELER_ATRPERMISSAODUPLIC) + .arg(permissao->obterObjeto()->obterNome()) + .arg(permissao->obterObjeto()->obterNomeTipoObjeto()), + ERR_PGMODELER_ATRPERMISSAODUPLIC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + + //Remove a permissão de backup + delete(perm_bkp); + } + catch(Excecao &e) + { + //Em caso de erro restaura os valores originais da permissão + (*permissao)=(*perm_bkp); + + //Desaloca as permissões de backup e auxiliar + delete(perm_aux); + delete(perm_bkp); + + cancelarOperacao(); + + //Redireciona o erro capturado + throw Excecao(e.obterMensagemErro(), e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void PermissaoWidget::editarPermissao(void) +{ + if(permissao) + { + unsigned priv, i, qtd; + QCheckBox *chk=NULL, *chk1=NULL; + Papel *papel=NULL; + + /* Disconecta o sinal de linhaAdicionada da tabela de papéis para que + mesma possa ter linhas adicionadas sem qualquer tratamento pelo + método selecionarPapel */ + tab_papeis->blockSignals(true); + + //Limpa a tabela de papéis + tab_papeis->removerLinhas(); + //Preenche o campo do formulário com o noome da permissão selecionada + id_perm_edt->setText(permissao->obterNome()); + + /* Obtém a quantidade de papéis relacionados à permissão para que os + mesmos possam ser exibidos na tabela de papéis */ + qtd=permissao->obterNumPapeis(); + for(i=0; i < qtd; i++) + { + //Adiciona uma linha à tabela de permissão + tab_papeis->adicionarLinha(); + //Obtém um papel da permissão + papel=permissao->obterPapel(i); + //Define como dado da linha atual o papel obtido + tab_papeis->definirDadoLinha(QVariant::fromValue(reinterpret_cast(papel)), i); + //Define como texo da linha atual o nome do papel + tab_papeis->definirTextoCelula(QString::fromUtf8(papel->obterNome()),i,0); + } + + //Reconect o sinal de adição de linha da tabela de papéis ao método selecionarPapel + tab_papeis->blockSignals(false); + + //Preenchendo a tabela de privilégios com os valores dos privilégios da permissão + for(priv=Permissao::PRIV_SELECT; priv<=Permissao::PRIV_USAGE; priv++) + { + //Obtém os checkboxes que representam o priviléigo e a opção GRANT OPTION + chk=dynamic_cast(privilegios_tbw->cellWidget(priv,0)); + chk1=dynamic_cast(privilegios_tbw->cellWidget(priv,1)); + + chk->setChecked(permissao->obterPrivilegio(priv)); + chk1->setChecked(permissao->obterOpConcessao(priv)); + } + + //Habilita os botões de edição da permissão + habilitarBotoesEdicao(); + } +} +//----------------------------------------------------------- +void PermissaoWidget::removerPermissao(void) +{ + //Remove a permissão atualmente selecionada + modelo->removerPermissao(permissao); + //Limpa o formulário e desabilita os botões de edição + cancelarOperacao(); + permissao=NULL; + /* Limpa a seleção de itens na tabela de permissões + forçando o usuário a selecionar novamente outro + item para edição/remoção */ + tab_permissoes->limparSelecao(); +} +//----------------------------------------------------------- +void PermissaoWidget::removerPermissoes(void) +{ + //Remove todas as permissões relacionadas ao objeto + modelo->removerPermissoes(objeto); + cancelarOperacao(); +} +//----------------------------------------------------------- +void PermissaoWidget::configurarPermissao(Permissao *permissao) +{ + if(permissao) + { + unsigned qtd, i, priv; + QCheckBox *chk=NULL, *chk1=NULL; + + /* Remove os papéis da permissão pois esta receberá + os papéis da tabela de papéis */ + permissao->removerPapeis(); + qtd=tab_papeis->obterNumLinhas(); + + //Adiciona cada papel da tabela à permissão + for(i=0; i < qtd; i++) + permissao->adicionarPapel(reinterpret_cast(tab_papeis->obterDadoLinha(i).value())); + + /* Configura os privilégios da permissão com base nos checkboxes + selecionados ta tabela de privilégios */ + for(priv=Permissao::PRIV_SELECT; priv <= Permissao::PRIV_USAGE; priv++) + { + if(!privilegios_tbw->isRowHidden(priv)) + { + chk=dynamic_cast(privilegios_tbw->cellWidget(priv,0)); + chk1=dynamic_cast(privilegios_tbw->cellWidget(priv,1)); + permissao->definirPrivilegio(priv, chk->isChecked(), chk1->isChecked()); + } + } + } +} +//----------------------------------------------------------- +void PermissaoWidget::cancelarOperacao(void) +{ + unsigned priv; + QCheckBox *chk=NULL; + + /* Define a permissão atual como NULL indicando que nenhuma permissão + está sendo editada no momento */ + permissao=NULL; + + //Desmarca todos os privilégios na tabela de privilégios + for(priv=Permissao::PRIV_SELECT; priv<=Permissao::PRIV_USAGE; priv++) + { + chk=dynamic_cast(privilegios_tbw->cellWidget(priv,0)); + chk->setChecked(false); + chk=dynamic_cast(privilegios_tbw->cellWidget(priv,1)); + chk->setChecked(false); + } + + //Limpa a tabela de papéis selecionados + tab_papeis->removerLinhas(); + //Limpa o campo que armazena o nome da permissão + id_perm_edt->clear(); + //Desabilita os botẽos de edição + habilitarBotoesEdicao(); + //Desabilita o próprio botão de cancelar operação + cancelar_tb->setEnabled(false); + //Limpa a seleção na tabela de permissões + tab_permissoes->limparSelecao(); +} +//----------------------------------------------------------- +void PermissaoWidget::marcarPrivilegio(void) +{ + QObject *obj_sender=sender(); + + //Este método só será executado caso o objeto sender seja um checkbox + if(obj_sender && obj_sender->metaObject()->className()==QString("QCheckBox")) + { + QCheckBox *chk=NULL, *chk_priv=NULL, *chk_gop=NULL; + unsigned priv; + + //Converte o objeto sender em checkbox + chk=dynamic_cast(obj_sender); + + for(priv=Permissao::PRIV_SELECT; priv<=Permissao::PRIV_USAGE; priv++) + { + //Obtém os checkboxes que representam o priviléigo e a opção GRANT OPTION + chk_priv=dynamic_cast(privilegios_tbw->cellWidget(priv,0)); + chk_gop=dynamic_cast(privilegios_tbw->cellWidget(priv,1)); + + /* Caso o checkbox clicado (sender) seja o checkbox + da coluna GRANT OPTION, o checkbox de privilégio + receberá o mesmo estado do checkbox de grant option */ + if(chk==chk_gop) + { + chk_priv->setChecked(chk_gop->isChecked()); + break; + } + /* Caso o checkbox clicado (sender) seja o checkbox + do privilégio e o mesmo for desmarcado, o checkbox de GRANT OPTION + será também desmarcado */ + else if(chk==chk_priv && !chk->isChecked()) + { + chk_gop->setChecked(false); + break; + } + } + + //Habilita/desabilita os botões de edição + habilitarBotoesEdicao(); + } +} +//----------------------------------------------------------- +void PermissaoWidget::habilitarBotoesEdicao(void) +{ + bool priv_marcados=false; + unsigned priv; + QCheckBox *chk=NULL, *chk1=NULL; + + for(priv=Permissao::PRIV_SELECT; priv<=Permissao::PRIV_USAGE && !priv_marcados; priv++) + { + //Obtém os checkboxes que representam o priviléigo e a opção GRANT OPTION + chk=dynamic_cast(privilegios_tbw->cellWidget(priv,0)); + chk1=dynamic_cast(privilegios_tbw->cellWidget(priv,1)); + //Verifica se algum privilégio está marcado + priv_marcados=(chk->isChecked() || chk1->isChecked()); + } + + /* O botão de atualizar permissão estará ativo caso haja algum privilégio marcado, + também existam papéis selecionados e exista uma permissão sendo editada */ + atualizar_perm_tb->setEnabled(priv_marcados && tab_papeis->obterNumLinhas() > 0 && permissao!=NULL); + + /* O botão de inserção permissão estará ativo caso haja algum privilégio marcado, + também existam papéis selecionados */ + inserir_perm_tb->setEnabled(priv_marcados && tab_papeis->obterNumLinhas() > 0); + + /* O botão de cancelar a operação estará ativo caso o obtão de inserir ou atualizar esteja habilitado + ou caso haja alguma permissão criada (tabela de permissões com pelo menos 1 item) */ + cancelar_tb->setEnabled(inserir_perm_tb->isEnabled() || atualizar_perm_tb->isEnabled() || tab_permissoes->obterNumLinhas() > 0); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/permissaowidget.h b/libpgmodeler_ui/src/permissaowidget.h new file mode 100644 index 000000000..3ddc4ae28 --- /dev/null +++ b/libpgmodeler_ui/src/permissaowidget.h @@ -0,0 +1,117 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: PermissaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de permissões de objetos. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef PERMISSAO_WIDGET_H +#define PERMISSAO_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_permissaowidget.h" +#include "tabelaobjetoswidget.h" +//*********************************************************** +class PermissaoWidget: public ObjetoBaseWidget, public Ui::PermissaoWidget { + Q_OBJECT + + private: + //Armazena a permissão selecionada atualmente para edição + Permissao *permissao; + //Conteineres de papéis e de permissões + TabelaObjetosWidget *tab_papeis, *tab_permissoes; + + public: + PermissaoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ObjetoBase *objeto_pai, ObjetoBase *objeto); + + private slots: + //Exibe a janela de seleção de objetos do modelo + void selecionarPapel(void); + + //Seleciona uma permissão cujo índice é especificado no parâmetro + void selecionarPermissao(int idx_perm); + + //Adiciona ao modelo a permissão configurada no formulário + void adicionarPermissao(void); + + /* Método de configuração de uma permissão. Este método + faz a atribuição dos valores preenchidos no formulário + à permissão do parâmetro. Este método é compartilhado + entre as ações de adição e atualização de permissão */ + void configurarPermissao(Permissao *permissao); + + /* Preenche o formulário com os dados da permissão selecionada + na tabela de permissões para uma posterior edição */ + void editarPermissao(void); + + //Remove a permissão selecionada na tabela de permissões + void removerPermissao(void); + + //Remove todas as permissões da tabela de permissão + void removerPermissoes(void); + /* + # Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) + # Sub-projeto: Biblioteca libpgsqldbm_ui + # Classe: VisaoObjetosWidget + # Descrição: Definição da classe que implementa a arvore e lista de objetos + # no modelo de banco de dados. + # + # Copyleft 2006-2012 - Raphael Araujo e Silva + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License + + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software Foundation, + # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + //Atualiza os dados da permissão atualmente em edição + void atualizarPermissao(void); + + //Lista todas as permissões relacionadas ao objeto atual + void listarPermissoes(void); + + /* Cancela a operação de criação/edição de uma permissão + limpando o formulário e bloqueando os botões relacionados */ + void cancelarOperacao(void); + + //Exibe os dados do papel selecionado na tabela de papéis + void exibirDadosPapelSelecionado(void); + + /* Habilita ou desabilita os botões de edição com base + nos dados preenchidos ou não no formulário */ + void habilitarBotoesEdicao(void); + + /* Selecionao checkbox relacionados a um privilégio na + tabela de privilégios */ + void marcarPrivilegio(void); + + public slots: + void hideEvent(QHideEvent *); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/pgmodelerplugin.h b/libpgmodeler_ui/src/pgmodelerplugin.h new file mode 100644 index 000000000..563cfa95d --- /dev/null +++ b/libpgmodeler_ui/src/pgmodelerplugin.h @@ -0,0 +1,58 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgsqlDBM) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: PgModelerLibrary +# Descrição: Definição da classe que implementa a base para suporte de plugins de terceiros, +# baseados em bibliotecas compartilhadas. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef PGMODELER_PLUGIN_H +#define PGMODELER_PLUGIN_H + +#include "modelowidget.h" +//*********************************************************** +/* Os plugins no pgModeler deve estar dentro da pasta "plugins" + em um diretório próprio (recomenda-se usar o mesmo nome do plugin) + e deve possuir a seguinte estrutura básica: + + pgmodeler_root/plugins/ + +- pluginA + +---(lib)*(pluginA.)(so|dll) (biblioteca que represnta o plugin) + +---pluginA.png (ícone que representa o plugin, deve possuir o mesmo nome + + Obs.: Plugins podem fazer uso de subdiretórios mas qualquer referência a estes devem ser feitas + manualmente pelo criado do plugin. +*/ +class PgModelerPlugin { + public: + PgModelerPlugin(void) {} + virtual ~PgModelerPlugin(void) {} + + //Método que executa o plugin + virtual void executarPlugin(ModeloWidget *modelo)=0; + + //Retorna o texto que é exibido na ação que executa o plugin + virtual QString obterRotuloPlugin(void)=0; +}; + +/* Declara a classe PgModelerPlugin como interface, ou seja, a base para + implementação de plugins. Todo plugin deve herdar esta classe e usar a + diretiva Q_INTERFACE em sua construção */ +Q_DECLARE_INTERFACE(PgModelerPlugin,"pgmodelerplugin") +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/progressotarefa.cpp b/libpgmodeler_ui/src/progressotarefa.cpp new file mode 100644 index 000000000..df0bc5412 --- /dev/null +++ b/libpgmodeler_ui/src/progressotarefa.cpp @@ -0,0 +1,46 @@ +#include "progressotarefa.h" +//*********************************************************** +ProgressoTarefa::ProgressoTarefa(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) +{ + setupUi(this); + //Por padrão o progresso de tarefa é modal e não tem bordas + this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); +} +//----------------------------------------------------------- +void ProgressoTarefa::adicionarIcone(unsigned id, const QIcon &ico) +{ + icones[id]=ico; +} +//----------------------------------------------------------- +void ProgressoTarefa::executarProgesso(int progresso, const QString &texto, unsigned id_icone) +{ + if(!this->isVisible()) + this->open(); + + //Caso o progresso seja maior que o máximo da barra de progresso + if(progresso > progresso_pb->maximum()) + //O progresso recebe o valor máximo da barra de progresso + progresso=progresso_pb->maximum(); + + //Exibe o valor do progresso e o texto + progresso_pb->setValue(progresso); + texto_lbl->setText(QString::fromUtf8(texto)); + + //Caso o id de ícone passado exista um ícone respectivo, exibe-o + if(icones.count(id_icone)) + icone_lbl->setPixmap(icones[id_icone].pixmap(QSize(32,32))); + else + icone_lbl->clear(); + + //Força o redesenho do formulário para atualizar os valores + this->repaint(); +} +//----------------------------------------------------------- +void ProgressoTarefa::close(void) +{ + progresso_pb->setValue(0); + texto_lbl->clear(); + icone_lbl->clear(); + QDialog::close(); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/progressotarefa.h b/libpgmodeler_ui/src/progressotarefa.h new file mode 100644 index 000000000..b1f3f1eb3 --- /dev/null +++ b/libpgmodeler_ui/src/progressotarefa.h @@ -0,0 +1,52 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: ProgressaoTarefa +# Descrição: Definição da classe que implementa um widget que sinaliza a progressão +# de execução de tarefas +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef PROGRESSO_TAREFA_H +#define PROGRESSO_TAREFA_H + +#include +#include "ui_progressotarefa.h" +#include +using namespace std; +//*********************************************************** +class ProgressoTarefa: public QDialog, public Ui::ProgressoTarefa +{ + private: + Q_OBJECT + + /* Armazena os icones que são exibidos conforme os tokes dos icones + 'id_icone' no slot executarProgresso() são enviados */ + map icones; + + public: + ProgressoTarefa(QWidget *parent=0, Qt::WindowFlags f=0); + + //Adiciona um ícone identificado pelo código 'id' + void adicionarIcone(unsigned id, const QIcon &ico); + + public slots: + void close(void); + void executarProgesso(int progresso, const QString &texto, unsigned id_ico); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/regrawidget.cpp b/libpgmodeler_ui/src/regrawidget.cpp new file mode 100644 index 000000000..47dc0d0cd --- /dev/null +++ b/libpgmodeler_ui/src/regrawidget.cpp @@ -0,0 +1,158 @@ +#include "regrawidget.h" +//*********************************************************** +RegraWidget::RegraWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_REGRA) +{ + try + { + QStringList lista; + QFrame *frame=NULL; + + Ui_RegraWidget::setupUi(this); + + /* Alocando os destacadores de sintaxe para o campo de expressão + condicional e de comando sql */ + dest_exp_condicional=new DestaqueSintaxe(exp_condicional_txt, false); + dest_exp_condicional->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + dest_comando=new DestaqueSintaxe(comando_txt, false); + dest_comando->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + //Criando a tabela que armazena os comandos SQL da regra + tab_comandos=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES, true, this); + tab_comandos->definirRotuloCabecalho(trUtf8("Comando SQL"),0); + tab_comandos->definirIconeCabecalho(QPixmap(":/icones/icones/codigosql.png"),0); + dynamic_cast(comandos_gb->layout())->addWidget(tab_comandos, 1, 0, 1, 2); + + //Gera o frame de informação + frame=gerarFrameInformacao(trUtf8("Para se criar uma regra que não execute ação alguma (DO NOTHING) basta não especificar comandos na tabela de comandos SQL.")); + regra_grid->addWidget(frame, regra_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + configurarLayouFormulario(regra_grid, OBJETO_REGRA); + janela_pai->setMinimumSize(550, 520); + + //Configurando o combo de tipo de evento com os tipos disponíveis + TipoEvento::obterTipos(lista); + tipo_evento_cmb->addItems(lista); + + //Configurando o combo de tipo de execução com os tipos disponíveis + TipoExecucao::obterTipos(lista); + tipo_execucao_cmb->addItems(lista); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(tab_comandos, SIGNAL(s_linhaAdicionada(int)), this, SLOT(manipularComando(int))); + connect(tab_comandos, SIGNAL(s_linhaAtualizada(int)), this, SLOT(manipularComando(int))); + connect(tab_comandos, SIGNAL(s_linhaEditada(int)), this, SLOT(editarComando(int))); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RegraWidget::hideEvent(QHideEvent *evento) +{ + ObjetoBaseWidget::hideEvent(evento); + comando_txt->clear(); + tab_comandos->removerLinhas(); + tipo_evento_cmb->setCurrentIndex(0); + tipo_execucao_cmb->setCurrentIndex(0); +} +//---------------------------------------------------------- +void RegraWidget::editarComando(int idx_lin) +{ + //Exibe o comando na linha atual da tabela no campo de comando sql + comando_txt->setPlainText(tab_comandos->obterTextoCelula(idx_lin,0)); +} +//---------------------------------------------------------- +void RegraWidget::manipularComando(int idx_lin) +{ + //Caso haja texto inserido no campo + if(!comando_txt->toPlainText().isEmpty()) + { + //Exibe o comando digitado na linha 'idx_lin' da tabela de comandos + tab_comandos->definirTextoCelula(comando_txt->toPlainText(),idx_lin,0); + comando_txt->clear(); + } + /* Caso não haja um comando digitado e o usuário tente inserir + mesmo assim, remove a linha criada em branco */ + else if(tab_comandos->obterTextoCelula(idx_lin,0).isEmpty()) + tab_comandos->removerLinha(idx_lin); +} +//---------------------------------------------------------- +void RegraWidget::definirAtributos(ModeloBD *modelo, Tabela *tabela_pai, ListaOperacoes *lista_op, Regra *regra) +{ + unsigned qtd, i; + + if(!tabela_pai) + throw Excecao(ERR_PGMODELER_ATROBJNAOALOC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, regra, tabela_pai); + + if(regra) + { + //Configura o formulário com os valores dos atributos da regra + tipo_evento_cmb->setCurrentIndex(tipo_evento_cmb->findText(~regra->obterTipoEvento())); + tipo_execucao_cmb->setCurrentIndex(tipo_execucao_cmb->findText(~regra->obterTipoExecucao())); + exp_condicional_txt->setPlainText(regra->obterExpCondicional()); + + //Insere na tabela de comandos os comandos presentes na regra + tab_comandos->blockSignals(true); + qtd=regra->obterNumComandos(); + for(i=0; i < qtd; i++) + { + tab_comandos->adicionarLinha(); + tab_comandos->definirTextoCelula(regra->obterComando(i),i,0); + } + tab_comandos->blockSignals(false); + } +} +//---------------------------------------------------------- +void RegraWidget::aplicarConfiguracao(void) +{ + try + { + Regra *regra=NULL; + unsigned qtd, i; + + iniciarConfiguracao(); + + //Obtém a referência à regra que está sendo criada/editada + regra=dynamic_cast(this->objeto); + + //Configura a regra com base nos atributos preenchidos no formulário + regra->definirTipoEvento(TipoEvento(tipo_evento_cmb->currentText())); + regra->definirTipoExecucao(TipoExecucao(tipo_execucao_cmb->currentText())); + regra->definirExpCondicional(exp_condicional_txt->toPlainText()); + + /* Remove todos os comandos da regra para inserção dos que + foram criados no formulário */ + regra->removerComandos(); + qtd=tab_comandos->obterNumLinhas(); + + //Inserindo os comandos sql do formulário na regra + for(i=0; i < qtd; i++) + regra->adicionarComando(tab_comandos->obterTextoCelula(i,0)); + + //Aplica as configurações básicas + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/regrawidget.h b/libpgmodeler_ui/src/regrawidget.h new file mode 100644 index 000000000..583ea6103 --- /dev/null +++ b/libpgmodeler_ui/src/regrawidget.h @@ -0,0 +1,57 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: RegraWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de regras. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef REGRA_WIDGET_H +#define REGRA_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_regrawidget.h" +#include "tabelaobjetoswidget.h" +//*********************************************************** +class RegraWidget: public ObjetoBaseWidget, public Ui::RegraWidget { + Q_OBJECT + + private: + //Destacadores de sintaxe dos campos de expressão condicional e comando sql + DestaqueSintaxe *dest_exp_condicional, + *dest_comando; + + //Tabela que armazena os comandos sql da regra + TabelaObjetosWidget *tab_comandos; + + public: + RegraWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, Tabela *tabela_pai, ListaOperacoes *lista_op, Regra *regra); + + private slots: + void hideEvent(QHideEvent *); + //Exibe o comando digitado no campo de comando sql na tabela, na linha idx_lin + void manipularComando(int idx_lin); + //Exibe o dado da linha da tabela (idx_lin) no campo de comando sql + void editarComando(int idx_lin); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/relacionamentowidget.cpp b/libpgmodeler_ui/src/relacionamentowidget.cpp new file mode 100644 index 000000000..96725e2c0 --- /dev/null +++ b/libpgmodeler_ui/src/relacionamentowidget.cpp @@ -0,0 +1,752 @@ +#include "relacionamentowidget.h" +#include "restricaowidget.h" +#include "colunawidget.h" +#include "caixamensagem.h" + +extern RestricaoWidget *restricao_wgt; +extern ColunaWidget *coluna_wgt; +extern CaixaMensagem *caixa_msg; +//*********************************************************** +RelacionamentoWidget::RelacionamentoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_RELACAO) +{ + try + { + QStringList lista; + QGridLayout *grid=NULL; + QFrame *frame=NULL; + + Ui_RelacionamentoWidget::setupUi(this); + //Alocando e configurando os destcadores de nomes das tabelas + dest_tab_orig=NULL; + qtd_operacoes=0; + dest_tab_orig=new DestaqueSintaxe(tabela_orig_txt, false); + dest_tab_orig->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + dest_tab_dest=NULL; + dest_tab_dest=new DestaqueSintaxe(tabela_dest_txt, false); + dest_tab_dest->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + //Alocando as tabela de atributos e restrições do relacionamento + tab_atributos=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + (TabelaObjetosWidget::BTN_ATUALIZAR_ITEM | + TabelaObjetosWidget::BTN_MOVER_ITENS), true, this); + + tab_restricoes=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + (TabelaObjetosWidget::BTN_ATUALIZAR_ITEM | + TabelaObjetosWidget::BTN_MOVER_ITENS), true, this); + + //Configurando os rótulos e ícones das colunas das tabelas + tab_atributos->definirNumColunas(2); + tab_atributos->definirRotuloCabecalho(trUtf8("Atributo"), 0); + tab_atributos->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + tab_atributos->definirRotuloCabecalho(trUtf8("Tipo"), 1); + tab_atributos->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + + tab_restricoes->definirNumColunas(2); + tab_restricoes->definirRotuloCabecalho(trUtf8("Restrição"), 0); + tab_restricoes->definirIconeCabecalho(QPixmap(":/icones/icones/constraint.png"),0); + tab_restricoes->definirRotuloCabecalho(trUtf8("Tipo"), 1); + tab_restricoes->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + + //Adiciona as tabelas alocadas às respectivas abas + grid=new QGridLayout; + grid->addWidget(tab_atributos, 0,0,1,1); + grid->setContentsMargins(2,2,2,2); + atributosrel_tbw->widget(1)->setLayout(grid); + + grid=new QGridLayout; + grid->addWidget(tab_restricoes, 0,0,1,1); + grid->setContentsMargins(2,2,2,2); + atributosrel_tbw->widget(2)->setLayout(grid); + + grid=dynamic_cast(atributosrel_tbw->widget(0)->layout()); + //Gera um frame de alerta sobre a edição de atributos do relacionamento + frame=gerarFrameInformacao(trUtf8("A edição de atributos de um relacionamento já existente é permitida, porém, deve ser\ + feita com atenção pois pode quebrar referências à colunas e causar a invalidez de objetos como gatilhos,\ + índices, restrições e sequências.")); + grid->addWidget(frame, grid->count()+1, 0, 1, 3); + frame->setParent(atributosrel_tbw->widget(0)); + + grid=dynamic_cast(atributosrel_tbw->widget(3)->layout()); + //Gera um frame de informação sobre a criação de chave primária especial + frame=gerarFrameInformacao(trUtf8("Utilize o recurso de chave-primária especial caso queira incluir uma chave-primária contendo\ + as colunas heradas/copiadas na tabela receptora. Este é um recurso disponível apenas para relacionamentos\ + de generalização/dependência.")); + + grid->addWidget(frame, 1, 0, 1, 1); + frame->setParent(atributosrel_tbw->widget(3)); + + configurarLayouFormulario(relacionamento_grid, OBJETO_RELACAO); + janela_pai->setMinimumSize(600, 520); + + //Configurando o combo de tipo de postergação com os tipos disponíveis + TipoPostergacao::obterTipos(lista); + tipo_postergacao_cmb->addItems(lista); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(janela_pai->cancelar_btn,SIGNAL(clicked(bool)), this, SLOT(cancelarConfiguracao(void))); + connect(postergavel_chk, SIGNAL(toggled(bool)), tipo_postergacao_cmb, SLOT(setEnabled(bool))); + connect(postergavel_chk, SIGNAL(toggled(bool)), tipo_postergacao_lbl, SLOT(setEnabled(bool))); + + connect(identificador_chk, SIGNAL(toggled(bool)), tab_orig_obrig_chk, SLOT(setDisabled(bool))); + connect(identificador_chk, SIGNAL(toggled(bool)), tab_dest_obrig_chk, SLOT(setDisabled(bool))); + + connect(tab_atributos, SIGNAL(s_linhasRemovidas(void)), this, SLOT(removerObjetos(void))); + connect(tab_atributos, SIGNAL(s_linhaAdicionada(int)), this, SLOT(adicionarObjeto(void))); + connect(tab_atributos, SIGNAL(s_linhaEditada(int)), this, SLOT(editarObjeto(int))); + connect(tab_atributos, SIGNAL(s_linhaRemovida(int)), this, SLOT(removerObjeto(int))); + + connect(tab_restricoes, SIGNAL(s_linhasRemovidas(void)), this, SLOT(removerObjetos(void))); + connect(tab_restricoes, SIGNAL(s_linhaAdicionada(int)), this, SLOT(adicionarObjeto(void))); + connect(tab_restricoes, SIGNAL(s_linhaEditada(int)), this, SLOT(editarObjeto(int))); + connect(tab_restricoes, SIGNAL(s_linhaRemovida(int)), this, SLOT(removerObjeto(int))); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RelacionamentoWidget::hideEvent(QHideEvent *evento) +{ + RelacionamentoBase *rel=dynamic_cast(this->objeto); + + identificador_chk->setChecked(false); + tab_orig_obrig_chk->setChecked(false); + tab_dest_obrig_chk->setChecked(false); + nome_tab_relnn_edt->clear(); + sufixo_dest_edt->clear(); + sufixo_orig_edt->clear(); + postergavel_chk->setChecked(false); + tipo_postergacao_cmb->setCurrentIndex(0); + atributosrel_tbw->setCurrentIndex(0); + + tab_atributos->blockSignals(true); + tab_restricoes->blockSignals(true); + tab_atributos->removerLinhas(); + tab_restricoes->removerLinhas(); + tab_atributos->blockSignals(false); + tab_restricoes->blockSignals(false); + + coluna_rel_lst->clear(); + + /* Caso o objeto seja novo e o usuário fecha a janela sem aplicar + as configurações o mesmo será destruído */ + if(rel && !rel->objetoModificado()) + { + this->cancelarConfiguracao(); + + /*if(this->novo_obj) + { + delete(this->objeto); + this->objeto=NULL; + }*/ + } + + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void RelacionamentoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Tabela *tab_orig, Tabela *tab_dest, unsigned tipo_rel) +{ + Relacionamento *rel=NULL; + + try + { + QString nome; + + //Cria um nome temporário para o relacionamento + nome=QString("rel_") + tab_orig->obterNome() + QString("_") + tab_dest->obterNome(); + + //Aloca o novo relacionamento + rel=new Relacionamento(nome, tipo_rel, tab_orig, tab_dest); + + /* Marca como novo objeto o relacionamento gerado, assim o mesmo é tratado + de forma diferente nos métodos de configuração da classe superior */ + this->novo_obj=true; + + /* Inicia o encademanento de operações, assim todo objeto editado dentro + do relacionameto será encadeado na lista, desta forma quando o usuário + necessitar desfazer as modificações do relacionamentos, os objetos do + relacionemento também serão restaurados */ + lista_op->iniciarEncadeamentoOperacoes(); + + qtd_operacoes=lista_op->obterTamanhoAtual(); + + //Adiciona o relacionamento criado à lista de operações + lista_op->adicionarObjeto(rel, Operacao::OBJETO_CRIADO); + + //Chama o método publico de definição dos atributos + this->definirAtributos(modelo, lista_op, rel); + } + catch(Excecao &e) + { + if(rel) delete(rel); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RelacionamentoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, RelacionamentoBase *relacao) +{ + static QWidget *tabs[3]={ atributosrel_tbw->widget(1), atributosrel_tbw->widget(2), atributosrel_tbw->widget(3) }; + static QString rot_tabs[3]={ atributosrel_tbw->tabText(1), atributosrel_tbw->tabText(2), atributosrel_tbw->tabText(3) }; + unsigned tipo_rel, i; + Relacionamento *relacao_aux=NULL; + bool rel1n, relnn, relgen_dep; + + //Caso o relacionamento não esteja alocado dispara um erro + if(!relacao) + throw Excecao(ERR_PGMODELER_ATROBJNAOALOC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, relacao); + + /* Inicia o encademanento de operações, assim todo objeto editado dentro + do relacionameto será encadeado na lista, desta forma quando o usuário + necessitar desfazer as modificações do relacionamentos, os objetos do + relacionemento também serão restaurados */ + if(!this->novo_obj) + { + lista_op->iniciarEncadeamentoOperacoes(); + qtd_operacoes=lista_op->obterTamanhoAtual(); + } + + + tipo_rel=relacao->obterTipoRelacionamento(); + + //Marcado o radiobox que indica o tipo do relacionamento + switch(tipo_rel) + { + case RelacionamentoBase::RELACIONAMENTO_11: rel_11_rb->setChecked(true); break; + case RelacionamentoBase::RELACIONAMENTO_1N: rel_1n_rb->setChecked(true); break; + case RelacionamentoBase::RELACIONAMENTO_NN: rel_nn_rb->setChecked(true); break; + case RelacionamentoBase::RELACIONAMENTO_GEN: rel_gen_rb->setChecked(true); break; + case RelacionamentoBase::RELACIONAMENTO_DEP: rel_dep_rb->setChecked(true); break; + } + + //Exibe o nome das tabelas participantes relacionamento no formulário + tabela_orig_txt->setPlainText(QString::fromUtf8(relacao->obterTabela(RelacionamentoBase::TABELA_ORIGEM)->obterNome(true))); + tabela_dest_txt->setPlainText(QString::fromUtf8(relacao->obterTabela(RelacionamentoBase::TABELA_DESTINO)->obterNome(true))); + + //Caso o relacionamento seja entre tabelas + if(relacao->obterTipoObjeto()==OBJETO_RELACAO) + { + vector vet_cols; + vector vet_id_cols; + int qtd, i; + QListWidgetItem *item=NULL; + + //Converte o objeto para relacionamento entre tabelas para acessar os atributos + relacao_aux=dynamic_cast(relacao); + + //Preenche os campos do formulário com os valores presentes no relacionamento + sufixo_orig_edt->setText(QString::fromUtf8(relacao_aux->obterSufixoTabela(RelacionamentoBase::TABELA_ORIGEM))); + sufixo_dest_edt->setText(QString::fromUtf8(relacao_aux->obterSufixoTabela(RelacionamentoBase::TABELA_DESTINO))); + tab_orig_obrig_chk->setChecked(relacao_aux->tabelaObrigatoria(RelacionamentoBase::TABELA_ORIGEM)); + tab_dest_obrig_chk->setChecked(relacao_aux->tabelaObrigatoria(RelacionamentoBase::TABELA_DESTINO)); + identificador_chk->setChecked(relacao_aux->relacionamentoIdentificador()); + postergavel_chk->setChecked(relacao_aux->obterPostergavel()); + nome_tab_relnn_edt->setText(relacao_aux->obterNomeTabelaRelNN()); + + //Habilita os botões das tabelas de restições e atributos caso o relacionamento esteja protegido + tab_atributos->habilitarBotoes(TabelaObjetosWidget::TODOS_BOTOES, !relacao_aux->objetoProtegido()); + tab_restricoes->habilitarBotoes(TabelaObjetosWidget::TODOS_BOTOES, !relacao_aux->objetoProtegido()); + + //Lista as restrições e atributos do relacionamento + listarObjetos(OBJETO_COLUNA); + listarObjetos(OBJETO_RESTRICAO); + + /* Caso seja um novo objeto é necessário conectar o relacionamento para que + as colunas sejam criadas na tabela receptora e seus nomes obtidos + para listagem no campo "chave primária" */ + if(tipo_rel==RelacionamentoBase::RELACIONAMENTO_GEN || + tipo_rel==RelacionamentoBase::RELACIONAMENTO_DEP) + { + if(this->novo_obj) + { + relacao_aux->conectarRelacionamento(); + vet_cols=relacao_aux->obterColunasRelacionamento(); + relacao_aux->desconectarRelacionamento(); + } + else + vet_cols=relacao_aux->obterColunasRelacionamento(); + + //Obtém os índices das colunas da chave primária especial no relacionamento + vet_id_cols=relacao_aux->obterColChavePrimariaEspecial(); + + //Lista os nomes da colunas criadas pelo relacionamento + qtd=vet_cols.size(); + for(i=0; i < qtd; i++) + { + coluna_rel_lst->addItem(vet_cols[i]); + item=coluna_rel_lst->item(i); + item->setCheckState(Qt::Unchecked); + } + + /* Marca na lista de colunas da chave primária especial os itens + conforme os ids vindos do relacionamento */ + qtd=vet_id_cols.size(); + for(i=0; i < qtd; i++) + { + if(vet_id_cols[i] < static_cast(coluna_rel_lst->count())) + coluna_rel_lst->item(vet_id_cols[i])->setCheckState(Qt::Checked); + } + } + } + + //Configurando quais objetos do formulário devem ser exibidos conforme o tipo do relacionamento + rel1n=(tipo_rel==RelacionamentoBase::RELACIONAMENTO_11 || + tipo_rel==RelacionamentoBase::RELACIONAMENTO_1N); + + relnn=(tipo_rel==RelacionamentoBase::RELACIONAMENTO_NN); + + relgen_dep=(tipo_rel==RelacionamentoBase::RELACIONAMENTO_DEP || + tipo_rel==RelacionamentoBase::RELACIONAMENTO_GEN); + + //Sufixo de origem: exibido para 1-n ou n-n + sufixo_orig_lbl->setVisible(rel1n || relnn); + sufixo_orig_edt->setVisible(rel1n || relnn); + + //Sufixo de destino: exibido para n-n + sufixo_dest_lbl->setVisible(rel1n || relnn); + sufixo_dest_lbl->setEnabled(relnn); + sufixo_dest_edt->setVisible(rel1n || relnn); + sufixo_dest_edt->setEnabled(relnn); + + //Obrigatoriedade de tabela de origem: exibido para 1-n e n-n + card_lbl->setVisible(rel1n); + tab_orig_obrig_chk->setEnabled(rel1n); + tab_orig_obrig_chk->setVisible(rel1n); + //Obrigatoriedade de tabela de destino: exibido para 1-1 e n-n + tab_dest_obrig_chk->setEnabled(tipo_rel==RelacionamentoBase::RELACIONAMENTO_11); + tab_dest_obrig_chk->setVisible(rel1n); + + /* Rel. Identificador: exibido para 1-n E quando as tabelas participantes + são diferentes (não é autorelacionamento) */ + identificador_chk->setVisible(rel1n && + (relacao->obterTabela(RelacionamentoBase::TABELA_ORIGEM) != + relacao->obterTabela(RelacionamentoBase::TABELA_DESTINO))); + + //Postergação de restrição: exibido para 1-n + /*postergavel_lbl->setVisible(rel1n); + postergavel_chk->setVisible(rel1n); + tipo_postergacao_lbl->setVisible(rel1n); + tipo_postergacao_cmb->setVisible(rel1n);*/ + chave_estrang_gb->setVisible(rel1n); + + //Obrigatoriedade de tabelas: exibido para 1-n + nome_tab_relnn_lbl->setVisible(relnn); + nome_tab_relnn_edt->setVisible(relnn); + + for(i=0; i < 3; i++) + atributosrel_tbw->removeTab(1); + + if(!relgen_dep) + { + for(i=0; i < 2; i++) + atributosrel_tbw->addTab(tabs[i], rot_tabs[i]); + } + else if(relgen_dep && relacao->obterTipoObjeto()==OBJETO_RELACAO) + { + atributosrel_tbw->addTab(tabs[2], rot_tabs[2]); + } +} +//---------------------------------------------------------- +void RelacionamentoWidget::listarObjetos(TipoObjetoBase tipo_obj) +{ + TabelaObjetosWidget *tab=NULL; + Relacionamento *relacao=NULL; + unsigned qtd, i; + + try + { + //Seleciona a tabela de objetos de acordo com o tipo especificado + if(tipo_obj==OBJETO_COLUNA) + tab=tab_atributos; + else + tab=tab_restricoes; + + //Obtém a referência ao relacionamento + relacao=dynamic_cast(this->objeto); + + //Remove as linhas da tabela antes da exibição dos elementos + tab->blockSignals(true); + tab->removerLinhas(); + + //Obtém a quantidade de elementos a serem exibidos + qtd=relacao->obterNumObjetos(tipo_obj); + for(i=0; i < qtd; i++) + { + //Adicionar uma linha + tab->adicionarLinha(); + //Exibe o objeto atual na linha atual da tabela + exibirDadosObjeto(relacao->obterObjeto(i, tipo_obj), i); + } + tab->limparSelecao(); + tab->blockSignals(false); + + //Habilita o botão de inserção de restrições somente quando há atributos no relacionamento + tab_restricoes->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, + tab_atributos->obterNumLinhas() > 0); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RelacionamentoWidget::adicionarObjeto(void) +{ + TipoObjetoBase tipo_obj=OBJETO_BASE; + + try + { + //Caso o objeto que acionou o método seja a tabela de atributos + if(sender()==tab_atributos) + { + //Seleciona a tabela de atributos para manipulação + tipo_obj=OBJETO_COLUNA; + tab=tab_atributos; + } + else + { + //Seleciona a tabela de restrições para manipulação + tipo_obj=OBJETO_RESTRICAO; + tab=tab_restricoes; + } + + //Caso o tipo do objeto seja uma coluna + if(tipo_obj==OBJETO_COLUNA) + { + //Exibe o formulário de criação de colunas (atributos) + coluna_wgt->definirAtributos(this->modelo, this->objeto, this->lista_op, NULL); + coluna_wgt->show(); + } + else + { + //Exibe o formulário de criação de restrições + restricao_wgt->definirAtributos(this->modelo, this->objeto, this->lista_op, NULL); + restricao_wgt->show(); + } + + //Atualiza a lista de objetos exibindo o objeto recém criado + listarObjetos(tipo_obj); + } + catch(Excecao &e) + { + listarObjetos(tipo_obj); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RelacionamentoWidget::editarObjeto(int idx_lin) +{ + try + { + /* Anula a operação de encadeamento para que, em caso de erro na edição do objeto, + as demais operações encadeadas não sejam desfeitas desnecessariamente */ + lista_op->anularEncadeamentoOperacoes(true); + + //Caso seja a tabela de atributos que acionou o método + if(sender()==tab_atributos) + { + /* Procede com a edição de uma coluna (atributo), sendo que a coluna a ser + editada é obtida do dado armazenado na linha 'idx_lin' da tabela */ + coluna_wgt->definirAtributos(this->modelo, this->objeto, this->lista_op, + reinterpret_cast(tab_atributos->obterDadoLinha(idx_lin).value())); + coluna_wgt->show(); + } + else + { + //Edita uma restrição caso a tabela de restrições for a acionadora do método + restricao_wgt->definirAtributos(this->modelo, this->objeto, this->lista_op, + reinterpret_cast(tab_restricoes->obterDadoLinha(idx_lin).value())); + restricao_wgt->show(); + } + + //Desfaz a anulação do encadeamento da lista de operações + lista_op->anularEncadeamentoOperacoes(false); + } + catch(Excecao &e) + { + lista_op->anularEncadeamentoOperacoes(false); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RelacionamentoWidget::exibirDadosObjeto(ObjetoTabela *objeto, int idx_lin) +{ + TabelaObjetosWidget *tab=NULL; + + //Caso o tipo do objeto seja uma coluna + if(objeto->obterTipoObjeto()==OBJETO_COLUNA) + { + //Exibe o nome do tipo da coluna na tabela de atributos + tab=tab_atributos; + tab_atributos->definirTextoCelula(QString::fromUtf8(~dynamic_cast(objeto)->obterTipo()),idx_lin,1); + } + else + { + //Exibe o nome do tipo da restrição na tabela de restrições + tab=tab_restricoes; + tab_restricoes->definirTextoCelula(QString::fromUtf8(~dynamic_cast(objeto)->obterTipoRestricao()),idx_lin,1); + } + + tab->definirTextoCelula(QString::fromUtf8(objeto->obterNome()),idx_lin,0); + + //Define como dado da linha o próprio objeto para facilitar referências ao mesmo + tab->definirDadoLinha(QVariant::fromValue(objeto), idx_lin); +} +//---------------------------------------------------------- +void RelacionamentoWidget::removerObjetos(void) +{ + Relacionamento *relacao=NULL; + TipoObjetoBase tipo_obj=OBJETO_BASE; + unsigned qtd, qtd_op=0, i; + ObjetoTabela *objeto=NULL; + + try + { + //Obtém a referência ao relacionamento + relacao=dynamic_cast(this->objeto); + + //Caso seja remoção de atributos + if(sender()==tab_atributos) + { + //Obtém a quantidade de atributos do relacionamento + tipo_obj=OBJETO_COLUNA; + qtd=relacao->obterNumAtributos(); + } + else + { + //Obtém a quantidade de restrições do relacionamento + tipo_obj=OBJETO_RESTRICAO; + qtd=relacao->obterNumRestricoes(); + } + + /* Armazena a quantidade de operações antes da remoção de objetos. + Caso um erro seja gerado e a quantidade de operações na lista + seja diferente do valor na variável 'qtd_op' indica que operações + foram inseridas na lista e precisam ser removidas */ + qtd_op=lista_op->obterTamanhoAtual(); + + for(i=0; i < qtd; i++) + { + //Obtém o objeto do relacionamento + objeto=relacao->obterObjeto(0, tipo_obj); + + //Tenta removê-lo do relacionamento + relacao->removerObjeto(objeto); + + //Adiciona o objeto removido na lista de operações para ser restaurado se necessário + lista_op->adicionarObjeto(objeto, Operacao::OBJETO_REMOVIDO, 0, relacao); + } + } + catch(Excecao &e) + { + /* Caso a quantidade de operações seja diferente da quantidade inicial + obtida antes da remoção dos objetos */ + if(qtd_op < lista_op->obterTamanhoAtual()) + { + //Obtém a quantidade de operações que necessitam ser removidas + qtd=lista_op->obterTamanhoAtual()-qtd_op; + + /* Anula o encadeamento de operações para que as mesmas seja + desfeitas uma a uma ignorando o encadeamento */ + lista_op->anularEncadeamentoOperacoes(true); + + /* Desfaz as operações na quantidade calculada e remove a + operação da lista */ + for(i=0; i < qtd; i++) + { + lista_op->desfazerOperacao(); + lista_op->removerUltimaOperacao(); + } + + //Desfaz a anulação do encadeamento + lista_op->anularEncadeamentoOperacoes(false); + } + + //Atualiza a lista de objeto do relacionamento + listarObjetos(tipo_obj); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RelacionamentoWidget::removerObjeto(int idx_lin) +{ + Relacionamento *relacao=NULL; + TipoObjetoBase tipo_obj; + ObjetoTabela *objeto=NULL; + + try + { + //Obtém a referência ao relacionamento + relacao=dynamic_cast(this->objeto); + + //Caso o sender do método seja a tabela de atributos + if(sender()==tab_atributos) + //Marca que o tipo do objeto a ser removido é uma coluna + tipo_obj=OBJETO_COLUNA; + else + tipo_obj=OBJETO_RESTRICAO; + + //Obtém o objeto no índice especificado + objeto=relacao->obterObjeto(idx_lin, tipo_obj); + + //Remove o objeto e o adiciona a lista de operações para ser restaurado se necessário + relacao->removerObjeto(objeto); + + lista_op->adicionarObjeto(objeto, Operacao::OBJETO_REMOVIDO, 0, relacao); + } + catch(Excecao &e) + { + listarObjetos(tipo_obj); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RelacionamentoWidget::aplicarConfiguracao(void) +{ + try + { + Relacionamento *relacao=NULL; + unsigned tipo_rel, qtd, i; + vector id_cols; + + /* Devido a complexidade da classe Relacionamento e a forte ligação entre todos os + relacinamentos do modelo, é necessário armazenar o XML dos objetos especiais e + desconectar TODOS os relacionamentos, executar a modificação no + relacionamento e logo após revalidar todos os demais */ + modelo->obterXMLObjetosEspeciais(); + modelo->desconectarRelacionamentos(); + + if(!this->novo_obj) + { + //Adiciona o relacionamento à lista de operações antes de ser modificado + lista_op->adicionarObjeto(this->objeto, Operacao::OBJETO_MODIFICADO); + } + + //Aplica as configurações básicas + ObjetoBaseWidget::aplicarConfiguracao(); + + //Caso o objeto seja um relacionamento tabela-tabela + if(this->objeto->obterTipoObjeto()==OBJETO_RELACAO) + { + //Obtém a referência ao mesmo fazendo o cast correto + relacao=dynamic_cast(this->objeto); + tipo_rel=relacao->obterTipoRelacionamento(); + relacao->blockSignals(true); + + /* Atribui os valores configurados no formulário ao relacionamento. + Alguns campos são atribuído ao objeto somente para um tipo específico + de relacionamento */ + relacao->definirSufixoTabela(RelacionamentoBase::TABELA_ORIGEM, sufixo_orig_edt->text()); + relacao->definirSufixoTabela(RelacionamentoBase::TABELA_DESTINO, sufixo_dest_edt->text()); + + relacao->definirTabelaObrigatoria(RelacionamentoBase::TABELA_ORIGEM, false); + relacao->definirTabelaObrigatoria(RelacionamentoBase::TABELA_DESTINO, false); + + if(tab_orig_obrig_chk->isEnabled()) + relacao->definirTabelaObrigatoria(RelacionamentoBase::TABELA_ORIGEM, tab_orig_obrig_chk->isChecked()); + + if(tab_dest_obrig_chk->isEnabled()) + relacao->definirTabelaObrigatoria(RelacionamentoBase::TABELA_DESTINO, tab_dest_obrig_chk->isChecked()); + + if(tipo_rel==RelacionamentoBase::RELACIONAMENTO_GEN || + tipo_rel==RelacionamentoBase::RELACIONAMENTO_DEP) + { + //Obtém os ids das colunas selecionadas como participantes da chave primária especial + qtd=coluna_rel_lst->count(); + for(i=0; i < qtd; i++) + { + //Caso o item na lista esteja selecionado seu id é armazenado no vetor de ids + if(coluna_rel_lst->item(i)->checkState()==Qt::Checked) + id_cols.push_back(i); + } + + //Atribui o vetor de ids configurado acima como sendo os ids das colunas da chave primária especial + relacao->definirColsChavePrimariaEspecial(id_cols); + } + //Campos específicos para relacionamentos 1-n e 1-1 + else if(tipo_rel==RelacionamentoBase::RELACIONAMENTO_1N || + tipo_rel==RelacionamentoBase::RELACIONAMENTO_11) + { + relacao->definirIdentificador(identificador_chk->isChecked()); + relacao->definirPostergavel(postergavel_chk->isChecked()); + relacao->definirTipoPostergacao(TipoPostergacao(tipo_postergacao_cmb->currentText())); + } + //Campos específicos para relacionamentos n-n + else if(tipo_rel==RelacionamentoBase::RELACIONAMENTO_NN) + relacao->definirNomeTabelaRelNN(nome_tab_relnn_edt->text()); + + try + { + /* Caso o relacinamento seja de dependência, generalização ou + identificador verifica se existe redundância de relacionamentos */ + if(tipo_rel==RelacionamentoBase::RELACIONAMENTO_DEP || + tipo_rel==RelacionamentoBase::RELACIONAMENTO_GEN || + relacao->relacionamentoIdentificador()) + modelo->verificarRedundanciaRelacoes(relacao); + + /* Faz a validação dos relacionamentos para refletir a nova configuração + do relacionamento */ + modelo->validarRelacionamentos(); + relacao->blockSignals(false); + relacao->definirModificado(true); + } + catch(Excecao &e) + { + /* O único erro que é desconsiderado é o de invalidação de objetos, pois, + mesmo com a restauração do estado original do relacionamento estes + objetos não são recuperados */ + if(e.obterTipoErro()==ERR_PGMODELER_REFCOLUNAINVTABELA) + //Exibe uma mensagem de erro com o conteúdo da exceção + caixa_msg->show(e); + //Para os demais erros a exceção é encaminhada + else + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } + + //Finaliza o encademanto de operações aberto + lista_op->finalizarEncadeamentoOperacoes(); + + //Finaliza a configuração do relacionamento + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + lista_op->anularEncadeamentoOperacoes(true); + this->cancelarConfiguracao(); + lista_op->anularEncadeamentoOperacoes(false); + + /* Faz a validação dos relacionamentos para refletir a nova configuração + do relacionamento */ + modelo->validarRelacionamentos(); + + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void RelacionamentoWidget::cancelarConfiguracao(void) +{ + if(lista_op->encadeamentoIniciado()) + lista_op->finalizarEncadeamentoOperacoes(); + + //Caso a lista de operações sofreu modificações + if(qtd_operacoes < lista_op->obterTamanhoAtual()) + /* Executa o cancelamento da configuração e remove as operações + adicionadas durante a edição do relacionamento */ + ObjetoBaseWidget::cancelarConfiguracao(); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/relacionamentowidget.h b/libpgmodeler_ui/src/relacionamentowidget.h new file mode 100644 index 000000000..62624ed2a --- /dev/null +++ b/libpgmodeler_ui/src/relacionamentowidget.h @@ -0,0 +1,81 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: RestricaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de relacionamentos. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef RELACIONAMENTO_WIDGET_H +#define RELACIONAMENTO_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_relacionamentowidget.h" +#include "tabelaobjetoswidget.h" +//*********************************************************** +class RelacionamentoWidget: public ObjetoBaseWidget, public Ui::RelacionamentoWidget { + private: + Q_OBJECT + /* Quantidade de elementos na lista de operações antes do relacionamento + ser editado. Este atributo é usado para se saber, em caso de cancelamento + da edição do relacionamento, a quantidade de operações relacionada ao + objeto que necessitam ser removidas. Vide: cancelarConfiguracao() */ + unsigned qtd_operacoes; + + //Destacadores de sintaxe para os campos de nome da tabela de origem e destino + DestaqueSintaxe *dest_tab_orig, + *dest_tab_dest; + + //Tabela as quais armazenam os atributos e restrições do relacionamento + TabelaObjetosWidget *tab_atributos, + *tab_restricoes; + + /* Lista os objetos do relacionamento na tabela respectiva, de acordo + com o tipo do objeto passado */ + void listarObjetos(TipoObjetoBase tipo_obj); + + //Exibe os dados de um objeto do relacionamento na lista específica de sua tabela + void exibirDadosObjeto(ObjetoTabela *objeto, int idx_lin); + + protected: + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Tabela *tab_orig, Tabela *tab_dest, unsigned tipo_rel); + + public: + RelacionamentoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, RelacionamentoBase *relacao); + + private slots: + void hideEvent(QHideEvent *); + + //Adiciona um objeto à tabela a qual aciona o método + void adicionarObjeto(void); + //Edita um objeto selecionado na tabela a qual aciona o método + void editarObjeto(int idx_lin); + //Remove um objeto selecionado na tabela a qual aciona o método + void removerObjeto(int idx_lin); + //Remove todos os objetos da tabela a qual aciona o método + void removerObjetos(void); + + public slots: + void aplicarConfiguracao(void); + void cancelarConfiguracao(void); + + friend class ModeloWidget; +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/restricaowidget.cpp b/libpgmodeler_ui/src/restricaowidget.cpp new file mode 100644 index 000000000..10d4d652d --- /dev/null +++ b/libpgmodeler_ui/src/restricaowidget.cpp @@ -0,0 +1,553 @@ +#include "restricaowidget.h" +#include "caixamensagem.h" +//*********************************************************** +extern CaixaMensagem *caixa_msg; +//*********************************************************** +RestricaoWidget::RestricaoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_RESTRICAO) +{ + try + { + QStringList lista; + + Ui_RestricaoWidget::setupUi(this); + + //Cria um destacador de sintaxe no campo de expressão de checagem + dest_exp_checagem=NULL; + dest_exp_checagem=new DestaqueSintaxe(exp_checagem_txt, false); + dest_exp_checagem->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + //Aloca as tabelas que recebem as colunas usadas na restrição + tab_colunas=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + (TabelaObjetosWidget::BTN_EDITAR_ITEM | + TabelaObjetosWidget::BTN_ATUALIZAR_ITEM), true, this); + + tab_colunas_ref=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + (TabelaObjetosWidget::BTN_EDITAR_ITEM | + TabelaObjetosWidget::BTN_ATUALIZAR_ITEM), true, this); + + //Alocando seletor de tabela referenciada + sel_tabela_ref=NULL; + sel_tabela_ref=new SeletorObjetoWidget(OBJETO_TABELA, true, this); + + //Configurando as tabelas com 2 colunas (nome da coluna e tipo) + tab_colunas->definirNumColunas(2); + tab_colunas->definirRotuloCabecalho(trUtf8("Coluna"), 0); + tab_colunas->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + tab_colunas->definirRotuloCabecalho(trUtf8("Tipo"), 1); + tab_colunas->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + + tab_colunas_ref->setEnabled(false); + tab_colunas_ref->definirNumColunas(2); + tab_colunas_ref->definirRotuloCabecalho(trUtf8("Coluna"), 0); + tab_colunas_ref->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + tab_colunas_ref->definirRotuloCabecalho(trUtf8("Tipo"), 1); + tab_colunas_ref->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + + dynamic_cast(colunas_tbw->widget(0)->layout())->addWidget(tab_colunas, 1,0,1,3); + dynamic_cast(colunas_tbw->widget(1)->layout())->addWidget(sel_tabela_ref, 0,1,1,2); + dynamic_cast(colunas_tbw->widget(1)->layout())->addWidget(tab_colunas_ref, 3,0,1,3); + + configurarLayouFormulario(restricao_grid, OBJETO_RESTRICAO); + janela_pai->setMinimumSize(580, 520); + + //Configurando o combo de tipo de restrição com os tipos disponíveis + TipoRestricao::obterTipos(lista); + tipo_rest_cmb->addItems(lista); + selecionarTipoRestricao(); + + //Configurando o combo de tipo de comparação com os tipos disponíveis + TipoComparacao::obterTipos(lista); + tipo_comparacao_cmb->addItems(lista); + + //Configurando o combo de tipo de postergação com os tipos disponíveis + TipoPostergacao::obterTipos(lista); + tipo_postergacao_cmb->addItems(lista); + + //Configurando o combo de tipo de ação update e delete com os tipos disponíveis + TipoAcao::obterTipos(lista); + acao_delete_cmb->addItems(lista); + acao_update_cmb->addItems(lista); + + //Gera o frame de informação + frame_info=gerarFrameInformacao(trUtf8("Colunas as quais foram incluídas por relacionamento não podem ser adicionadas/removidas\ + manualmente das chaves-primárias. Caso isso ocorra tais alterações serão ignoradas. Para criar chaves-primárias\ + usando colunas incluídas por relacionamentos utilize o recurso de atributos, restrições e chave-primária no formulário de edição relacionamentos.")); + + restricao_grid->addWidget(frame_info, restricao_grid->count()+1, 0, 1, 0); + frame_info->setParent(this); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(tipo_rest_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(selecionarTipoRestricao(void))); + connect(postergavel_chk, SIGNAL(toggled(bool)), tipo_postergacao_cmb, SLOT(setEnabled(bool))); + connect(postergavel_chk, SIGNAL(toggled(bool)), tipo_postergacao_lbl, SLOT(setEnabled(bool))); + connect(tab_colunas, SIGNAL(s_linhaAdicionada(int)), this, SLOT(adicionarColuna(int))); + connect(tab_colunas, SIGNAL(s_linhaRemovida(int)), this, SLOT(removerColuna(int))); + connect(tab_colunas, SIGNAL(s_linhasRemovidas(void)), this, SLOT(removerColunas(void))); + connect(tab_colunas_ref, SIGNAL(s_linhaAdicionada(int)), this, SLOT(adicionarColuna(int))); + connect(tab_colunas_ref, SIGNAL(s_linhaRemovida(int)), this, SLOT(removerColuna(int))); + connect(tab_colunas_ref, SIGNAL(s_linhasRemovidas(void)), this, SLOT(removerColunas(void))); + connect(sel_tabela_ref, SIGNAL(s_objetoRemovido(void)), this, SLOT(selecionarTabelaReferenciada(void))); + connect(sel_tabela_ref, SIGNAL(s_objetoSelecionado(void)), this, SLOT(selecionarTabelaReferenciada(void))); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RestricaoWidget::adicionarColuna(int idx_lin) +{ + QObject *obj_sender=sender(); + TabelaObjetosWidget *tab_col_aux=NULL; + QComboBox *combo=NULL; + Coluna *coluna=NULL; + unsigned tipo_col; + + try + { + //Caso o objeto sender do slot seja a tabela de colunas de origem + if(obj_sender==tab_colunas) + { + /* Os objetos utilizados no método serão o combo de colunas + de origem e a tabela de colunas de origem */ + tab_col_aux=tab_colunas; + combo=coluna_cmb; + tipo_col=Restricao::COLUNA_ORIGEM; + } + else + { + /* Os objetos utilizados no método serão o combo de colunas + de referência e a tabela de colunas de referência */ + tab_col_aux=tab_colunas_ref; + combo=coluna_ref_cmb; + tipo_col=Restricao::COLUNA_REFER; + } + + //Obtém a referência à coluna no item atual do combo box + coluna=reinterpret_cast(combo->itemData(combo->currentIndex(),Qt::UserRole).value()); + //Quando a coluna vai ser atribuída a tabela a mesma é removida do combo + combo->removeItem(combo->currentIndex()); + //Adiciona a coluna à tabela + adicionarColuna(coluna, tipo_col, idx_lin); + //Caso não houver itens no combo o botão de inserção da respectiva tabela será desabilitado + tab_col_aux->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, (combo->count()!=0)); + } + catch(Excecao &e) + { + tab_col_aux->removerLinha(idx_lin); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RestricaoWidget::removerColuna(int) +{ + //Caso o sender seja a tabela de colunas da origem + if(sender()==tab_colunas) + //Atualiza o combo de colunas da origem + atualizarComboColunas(Restricao::COLUNA_ORIGEM); + else + //Atualiza o combo de colunas de referência + atualizarComboColunas(Restricao::COLUNA_REFER); +} +//---------------------------------------------------------- +void RestricaoWidget::removerColunas(void) +{ + //Caso o sender seja a tabela de colunas da origem + if(sender()==tab_colunas) + { + //Atualiza o combo de colunas da origem + atualizarComboColunas(Restricao::COLUNA_ORIGEM); + } + else + { + //Atualiza o combo de colunas de referência + atualizarComboColunas(Restricao::COLUNA_REFER); + } +} +//---------------------------------------------------------- +void RestricaoWidget::adicionarColuna(Coluna *coluna, unsigned tipo_col, int idx_lin) +{ + TabelaObjetosWidget *tabela_wgt=NULL; + + //Casp a cpçima esteja aloca e o índice da linha seja válido (não-negativo) + if(coluna && idx_lin >= 0) + { + /* Caso o tipo da coluna for de origem seleciona a tabela de colunas + da origem caso contrário seleciona a tabela de colunas referenciadas */ + if(tipo_col==Restricao::COLUNA_ORIGEM) + tabela_wgt=tab_colunas; + else + tabela_wgt=tab_colunas_ref; + + /* Exibe os dados da coluna na linha especificada, definindo a referência à coluna + como dado da linha */ + tabela_wgt->definirTextoCelula(QString::fromUtf8(coluna->obterNome()),idx_lin,0); + tabela_wgt->definirTextoCelula(QString::fromUtf8(~coluna->obterTipo()),idx_lin,1); + tabela_wgt->definirDadoLinha(QVariant::fromValue(coluna), idx_lin); + + /* Caso o objeto esteja protegido ou foi incluído por relacionamento + muda a coloração da linha para denotar o fato */ + if(coluna->incluidoPorRelacionamento() || coluna->objetoProtegido()) + { + QFont fonte; + fonte=tabela_wgt->font(); + fonte.setItalic(true); + + if(coluna->objetoProtegido()) + tabela_wgt->definirFonteLinha(idx_lin, fonte, COR_TEXTO_LIN_PROT, COR_FUNDO_LIN_PROT); + else + tabela_wgt->definirFonteLinha(idx_lin, fonte, COR_TEXTO_LIN_INCREL, COR_FUNDO_LIN_INCREL); + } + } +} +//---------------------------------------------------------- +void RestricaoWidget::atualizarComboColunas(unsigned tipo_cmb) +{ + TabelaObjetosWidget *tab_col_aux=NULL; + Coluna *coluna=NULL; + Tabela *tabela=NULL; + QComboBox *combo=NULL; + Relacionamento *relacao=NULL; + unsigned i, qtd_col=0; + + try + { + //Caso o tipo de combo seja o de colunas da origem + if(tipo_cmb==Restricao::COLUNA_ORIGEM) + { + //Serão considerados no método o combo e a tabela de colunas da origem + combo=coluna_cmb; + tab_col_aux=tab_colunas; + + /* Caso o objeto 'this->relacionamento' não esteja especificado + indica que o usuário está editando uma restrição pertencente + a uma tabela sendo assim usa como referência a tabela + ligada a esta */ + if(!this->relacionamento) + { + tabela=this->tabela; + qtd_col=tabela->obterNumColunas(); + } + /* Caso o relacionamento esteja especificado usa o mesmo como + referência para obtenção das colunas */ + else + { + relacao=this->relacionamento; + qtd_col=relacao->obterNumAtributos(); + } + } + //Caso o tipo de combo seja o de colunas de referência + else + { + //Serão considerados no método o combo e a tabela de colunas de referência + combo=coluna_ref_cmb; + tab_col_aux=tab_colunas_ref; + tabela=dynamic_cast(sel_tabela_ref->obterObjeto()); + + if(tabela) + qtd_col=tabela->obterNumColunas(); + } + + //Limpa o combo de colunas + combo->clear(); + + for(i=0; i < qtd_col; i++) + { + /* Caso o relacionamento esteja especificado + obtém um atributo do mesmo para listar no combo + caso contrário obtém uma coluna da tabela */ + if(relacao) + coluna=relacao->obterAtributo(i); + else + coluna=tabela->obterColuna(i); + + /* Insere a coluna na tabela somente a mesma não existir na tabela, + essa checagem é feita tentando se obter o índice da linha na tabela + a qual possui a coluna, caso esse índice seja negativo indica que a + coluna não está presente na tabela */ + if(tab_col_aux->obterIndiceLinha(QVariant::fromValue(coluna)) < 0) + { + combo->addItem(QString::fromUtf8(coluna->obterNome()) + " (" + ~coluna->obterTipo() +")", QVariant::fromValue(coluna)); + } + } + //Desabilita o obtão de inserir itens na tabela caso não hajam itens no combobox + tab_col_aux->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, (combo->count()!=0)); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void RestricaoWidget::selecionarTabelaReferenciada(void) +{ + //Obtém a tabela configurada no seletor + Tabela *tabela=dynamic_cast(sel_tabela_ref->obterObjeto()); + + //Caso não haja tabela selecionada + if(!tabela) + { + //Limpa o combo de colunas de referência e a tabela de colunas de referência + coluna_ref_cmb->clear(); + tab_colunas_ref->blockSignals(true); + tab_colunas_ref->removerLinhas(); + tab_colunas_ref->setEnabled(false); + tab_colunas_ref->blockSignals(false); + } + else + { + //Caso haja uma tabela selecionada, atualiza o combo de colunas de referência + tab_colunas_ref->setEnabled(true); + atualizarComboColunas(Restricao::COLUNA_REFER); + } +} +//---------------------------------------------------------- +void RestricaoWidget::hideEvent(QHideEvent *evento) +{ + exp_checagem_txt->clear(); + coluna_cmb->clear(); + coluna_ref_cmb->clear(); + + postergavel_chk->setChecked(false); + tipo_rest_lbl->setEnabled(true); + tipo_rest_cmb->setEnabled(true); + tipo_rest_cmb->setCurrentIndex(0); + tipo_comparacao_cmb->setCurrentIndex(0); + tipo_postergacao_cmb->setCurrentIndex(0); + + tab_colunas->blockSignals(true); + tab_colunas_ref->blockSignals(true); + tab_colunas->removerLinhas(); + tab_colunas_ref->removerLinhas(); + tab_colunas->blockSignals(false); + tab_colunas_ref->blockSignals(false); + + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void RestricaoWidget::selecionarTipoRestricao(void) +{ + static QWidget *tab=colunas_tbw->widget(1); + static QString rot_tab=colunas_tbw->tabText(1); + + //Obtém o tipo atual da restrição + TipoRestricao tipo_rest=TipoRestricao(tipo_rest_cmb->currentText()); + + //Campos exibidos somente para chaves primárias e únicas + esptabela_lbl->setVisible(tipo_rest==TipoRestricao::primary_key || tipo_rest==TipoRestricao::unique); + sel_esptabela->setVisible(tipo_rest==TipoRestricao::primary_key || tipo_rest==TipoRestricao::unique); + + if(!sel_esptabela->isVisible()) sel_esptabela->removerObjetoSelecionado(); + + //Campos exibidos somente para restrições de checagem + exp_checagem_lbl->setVisible(tipo_rest==TipoRestricao::check); + exp_checagem_txt->setVisible(tipo_rest==TipoRestricao::check); + + //Campos exibidos somente para chaves primárias e estrangeiras + fator_preenc_lbl->setVisible(tipo_rest==TipoRestricao::foreign_key || tipo_rest==TipoRestricao::primary_key); + fator_preenc_sb->setVisible(tipo_rest==TipoRestricao::foreign_key || tipo_rest==TipoRestricao::primary_key); + + //Campos exibidos somente para chaves estrangeiras + postergavel_lbl->setVisible(tipo_rest==TipoRestricao::foreign_key); + postergavel_chk->setVisible(tipo_rest==TipoRestricao::foreign_key); + tipo_postergacao_cmb->setVisible(tipo_rest==TipoRestricao::foreign_key); + tipo_postergacao_lbl->setVisible(tipo_rest==TipoRestricao::foreign_key); + tipo_comparacao_lbl->setVisible(tipo_rest==TipoRestricao::foreign_key); + tipo_comparacao_cmb->setVisible(tipo_rest==TipoRestricao::foreign_key); + acao_delete_cmb->setVisible(tipo_rest==TipoRestricao::foreign_key); + acao_delete_lbl->setVisible(tipo_rest==TipoRestricao::foreign_key); + acao_update_cmb->setVisible(tipo_rest==TipoRestricao::foreign_key); + acao_update_lbl->setVisible(tipo_rest==TipoRestricao::foreign_key); + + //Campos exibidos para todos os tipos de restrições exceto restrições de checagem + colunas_tbw->setVisible(tipo_rest!=TipoRestricao::check); + + //Caso o tipo da restição não seja chave estrangeira esconde a aba de colunas referenciadas + if(tipo_rest!=TipoRestricao::foreign_key) + colunas_tbw->removeTab(1); + else + colunas_tbw->addTab(tab, rot_tab); +} +//---------------------------------------------------------- +void RestricaoWidget::definirAtributos(ModeloBD *modelo, ObjetoBase *objeto_pai, ListaOperacoes *lista_op, Restricao *restricao) +{ + TipoObjetoBase tipo_obj; + unsigned qtd, i, lin_tab; + Coluna *coluna=NULL; + Tabela *tabela_ref=NULL; + + if(!objeto_pai) + throw Excecao(ERR_PGMODELER_ATROBJNAOALOC,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, restricao, objeto_pai); + + frame_info->setVisible(this->tabela!=NULL); + + //Define o modelo de banco de dados do seletor de tabela referenciada + sel_tabela_ref->definirModelo(modelo); + + //Obtém o tipo de objeto pai da restrição o qual pode ser uma tabela ou relacionamento + tipo_obj=objeto_pai->obterTipoObjeto(); + + //Obtém a quantidade de colunas existentes no objeto pai + if(tipo_obj==OBJETO_TABELA) + qtd=tabela->obterNumColunas(); + else + qtd=relacionamento->obterNumAtributos(); + + //Adiciona as colunas de origem da tabela pai na tabela de colunas do formulário + tab_colunas->blockSignals(true); + for(i=0, lin_tab=0; i < qtd; i++) + { + /* Caso o objeto pai seja uma tabela usa a referência à tabela pai + para obter a coluna atual */ + if(tipo_obj==OBJETO_TABELA) + coluna=tabela->obterColuna(i); + /* Caso contrário usa a referência ao relacionamento pai + para obter a coluna atual */ + else + coluna=relacionamento->obterAtributo(i); + + /* Caso a restrição naõ seja nova, ou seja, esteja sendo editada e a coluna atual + está sendo referenciada por ela */ + if(restricao && restricao->colunaExistente(coluna, Restricao::COLUNA_ORIGEM)) + { + //Adiciona uma linha na tabela de origem e adiciona a coluna + tab_colunas->adicionarLinha(); + adicionarColuna(coluna, Restricao::COLUNA_ORIGEM, lin_tab); + lin_tab++; + } + } + //Atualiza o combo de colunas de origem com as colunas restantes da tabela + atualizarComboColunas(Restricao::COLUNA_ORIGEM); + tab_colunas->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, (coluna_cmb->count()!=0)); + tab_colunas->blockSignals(false); + + //Caso a restrição esteja alocada (sendo editada) + if(restricao) + { + /* Configura o tipo de restrição no formulário e já desabilita o referido campo pois o mesmo + só pode ser mudado enquanto a restrição está sendo criada */ + tipo_rest_cmb->setCurrentIndex(tipo_rest_cmb->findText(~restricao->obterTipoRestricao())); + tipo_rest_cmb->setEnabled(false); + tipo_rest_lbl->setEnabled(false); + + //Preenche os demais campos do formulário com os valores presentes na instância da restrição + exp_checagem_txt->setPlainText(QString::fromUtf8(restricao->obterExpChecagem())); + postergavel_chk->setChecked(restricao->restricaoPostergavel()); + tipo_postergacao_cmb->setCurrentIndex(tipo_postergacao_cmb->findText(~restricao->obterTipoPostergacao())); + tipo_comparacao_cmb->setCurrentIndex(tipo_comparacao_cmb->findText(~restricao->obterTipoComparacao())); + fator_preenc_sb->setValue(restricao->obterFatorPreenchimento()); + acao_delete_cmb->setCurrentIndex(acao_delete_cmb->findText(~restricao->obterTipoAcao(false))); + acao_update_cmb->setCurrentIndex(acao_update_cmb->findText(~restricao->obterTipoAcao(true))); + + //Caso a coluna esteja refereciando uma tabela (chave estrangeira) + tabela_ref=dynamic_cast(restricao->obterTabReferenciada()); + if(tabela_ref) + { + tab_colunas_ref->blockSignals(true); + //Configura o seletor de tabela referenciada com a tabela usada na restrição + sel_tabela_ref->definirObjeto(tabela_ref); + + /* Exibe, na tabela do formulário, todas as colunas da tabela referenciada + usadas na restrição */ + qtd=tabela_ref->obterNumColunas(); + for(i=0, lin_tab=0; i < qtd; i++) + { + coluna=tabela_ref->obterColuna(i); + if(restricao->colunaExistente(coluna, Restricao::COLUNA_REFER)) + { + tab_colunas_ref->adicionarLinha(); + adicionarColuna(coluna, Restricao::COLUNA_REFER, lin_tab); + lin_tab++; + } + } + /* Atualiza o combo de colunas referenciadas com as demais colunas que + não são usadas na restrição */ + atualizarComboColunas(Restricao::COLUNA_REFER); + tab_colunas_ref->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, (coluna_cmb->count()!=0)); + tab_colunas_ref->blockSignals(false); + } + } +} +//---------------------------------------------------------- +void RestricaoWidget::aplicarConfiguracao(void) +{ + try + { + Restricao *restricao=NULL; + unsigned i, tipo_col, qtd; + Coluna *coluna=NULL; + TabelaObjetosWidget *tab_obj_aux=NULL; + + iniciarConfiguracao(); + + //Obtém a referência à restrição que está sendo criada/editada + restricao=dynamic_cast(this->objeto); + + //Preenche os atributos básicos da restição com os valores configurados no formulário + restricao->definirTipo(TipoRestricao(tipo_rest_cmb->currentText())); + restricao->definirExpChecagem(exp_checagem_txt->toPlainText()); + restricao->definirFatorPreenchimento(fator_preenc_sb->value()); + restricao->definirTipoComparacao(TipoComparacao(tipo_comparacao_cmb->currentText())); + restricao->definirPostergavel(postergavel_chk->isChecked()); + restricao->definirTipoPostergacao(TipoPostergacao(tipo_postergacao_cmb->currentText())); + restricao->definirTipoAcao(TipoAcao(acao_delete_cmb->currentText()),false); + restricao->definirTipoAcao(TipoAcao(acao_update_cmb->currentText()),true); + + //Remove todas as colunas da restrição para inserir as presentes na tabela + restricao->removerColunas(); + for(tipo_col=Restricao::COLUNA_ORIGEM; tipo_col <= Restricao::COLUNA_REFER; tipo_col++) + { + //Seleciona uma tabela por vez + tab_obj_aux=(tipo_col==Restricao::COLUNA_ORIGEM ? tab_colunas : tab_colunas_ref); + + /* Varre a tabela selecionada, obtendo o dado de cada linha que nada mais é do que + uma coluna, inserindo a mesma na restrição */ + qtd=tab_obj_aux->obterNumLinhas(); + for(i=0; i < qtd; i++) + { + coluna=reinterpret_cast(tab_obj_aux->obterDadoLinha(i).value()); + restricao->adicionarColuna(coluna, tipo_col); + } + } + + //Aplica as configurações básicas + ObjetoBaseWidget::aplicarConfiguracao(); + + /* Dispara um erro caso o tipo da restrição seja um que exija o uso + de colunas de origem e/ou de referência (para chaves primárias e estrangeiras) */ + if(((restricao->obterTipoRestricao()==TipoRestricao::foreign_key || + restricao->obterTipoRestricao()==TipoRestricao::primary_key) && + restricao->obterNumColunas(Restricao::COLUNA_ORIGEM)==0) || + (restricao->obterTipoRestricao()==TipoRestricao::foreign_key && + restricao->obterNumColunas(Restricao::COLUNA_REFER)==0)) + throw Excecao(ERR_PGMODELERUI_RESTPKFKSEMCOLUNAS,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + + /** BUG: Foi notado que quando uma exceção é encaminhada a partir daqui para o método Aplicacao::notify() + o software falha devido a um segmentation fault sem causa conhecida. E a falha acontece SOMENTE neste + formulário nos demais, cujo funcionamento é semelhante, tal manifestação não acontece. + + Após várias testes verificou-se que se a a exceção for exibida neste ponto com o uso de uma + caixa de mensagem o programa cessa o travamento. A priori, para permitir o bom funcionamento deste + formulário, qualquer exceção será exibida usando a caixa de mensagem. Este bug será corrigido em + versões posteriores. **/ + //throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + caixa_msg->show(e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/restricaowidget.h b/libpgmodeler_ui/src/restricaowidget.h new file mode 100644 index 000000000..38c40732b --- /dev/null +++ b/libpgmodeler_ui/src/restricaowidget.h @@ -0,0 +1,77 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: RestricaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de restrições. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef RESTRICAO_WIDGET_H +#define RESTRICAO_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_restricaowidget.h" +#include "tabelaobjetoswidget.h" +//*********************************************************** +class RestricaoWidget: public ObjetoBaseWidget, public Ui::RestricaoWidget { + Q_OBJECT + + private: + QFrame *frame_info; + + //Destaque de sintaxe do campo de expressão de checagem + DestaqueSintaxe *dest_exp_checagem; + + //Tabelas de objetos para controlar colunas referenciadas na restrição + TabelaObjetosWidget *tab_colunas, + *tab_colunas_ref; + + //Seletor de tabela referenciada + SeletorObjetoWidget *sel_tabela_ref; + + //Atualiza o combo de colunas do tipo especificado (Origem ou Referenciadas) + void atualizarComboColunas(unsigned tipo_cmb); + + /* Adiciona uma coluna à tabela de tipo especificado (origem ou referenciada) + na linha especificada */ + void adicionarColuna(Coluna *coluna, unsigned tipo_col, int idx_lin); + + public: + RestricaoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ObjetoBase *objeto_pai, ListaOperacoes *lista_op, Restricao *restricao); + + private slots: + void hideEvent(QHideEvent *); + + //Exibe os campos pertinentes ao tipo da restição selecionado + void selecionarTipoRestricao(void); + + /* Atualiza o combo de colunas referenciadas conforme o usuário + manipule o seletor de tabela referenciada */ + void selecionarTabelaReferenciada(void); + + //Métodos de manipulação das tabelas de colunas + void adicionarColuna(int idx_lin); + void removerColuna(int idx_lin); + void removerColunas(void); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/seletorobjetowidget.cpp b/libpgmodeler_ui/src/seletorobjetowidget.cpp new file mode 100644 index 000000000..92a670068 --- /dev/null +++ b/libpgmodeler_ui/src/seletorobjetowidget.cpp @@ -0,0 +1,153 @@ +#include "seletorobjetowidget.h" +#include "visaoobjetoswidget.h" +extern VisaoObjetosWidget *selecaoobjetos_wgt; +//*********************************************************** +QObject *SeletorObjetoWidget::seletor_atual=NULL; +//----------------------------------------------------------- +SeletorObjetoWidget::SeletorObjetoWidget(TipoObjetoBase tipo_obj_seletor, bool inst_destaque_txt, QWidget *parent): QWidget(parent) +{ + try + { + Ui_SeletorObjetoWidget::setupUi(this); + + modelo=NULL; + objeto=NULL; + destaque_txt=NULL; + + //Define o tipo de objeto que o seletor aceita + this->tipo_obj_seletor=tipo_obj_seletor; + + /* Caso a flag de instalação de destacador de código fonte + esteja setada. */ + if(inst_destaque_txt) + { + //Aloca um destacador de código fonte + destaque_txt=new DestaqueSintaxe(nome_objeto_txt, false); + + //A configuração padrão carregada é a de destaque de código SQL + destaque_txt->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + } + + connect(sel_objeto_tb, SIGNAL(clicked(bool)), this, SLOT(exibirSelecaoObjetos(void))); + connect(rem_objeto_tb, SIGNAL(clicked(bool)), this, SLOT(removerObjetoSelecionado(void))); + connect(selecaoobjetos_wgt, SIGNAL(s_visibilityChanged(ObjetoBase*,bool)), this, SLOT(exibirObjetoSelecionado(ObjetoBase*, bool))); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +ObjetoBase *SeletorObjetoWidget::obterObjeto(void) +{ + return(objeto); +} +//----------------------------------------------------------- +void SeletorObjetoWidget::definirObjeto(ObjetoBase *objeto) +{ + TipoObjetoBase tipo_obj; + QString nome_obj; + + //Caso o objeto esteja alocado + if(objeto) + { + //Obtém o seu tipo + tipo_obj=objeto->obterTipoObjeto(); + + /* Dependendo do tipo do objeto obtém o nome ou assinatura + do mesmo com o método correto. */ + if(tipo_obj==OBJETO_FUNCAO) + nome_obj=dynamic_cast(objeto)->obterAssinatura(); + else if(tipo_obj==OBJETO_OPERADOR) + nome_obj=dynamic_cast(objeto)->obterAssinatura(); + /* Formatando o nome do objeto caso o mesmo seja um objeto de tabela. + nesse modo o nome será exibido da seguinte forma: + esquema.tabela.objeto */ + else if(tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_RESTRICAO || tipo_obj==OBJETO_REGRA || + tipo_obj==OBJETO_GATILHO ||tipo_obj==OBJETO_INDICE) + { + ObjetoBase *tab_pai=dynamic_cast(objeto)->obterTabelaPai(); + if(tab_pai) + { + /*if(tab_pai->obterEsquema()) + nome_obj+=tab_pai->obterEsquema()->obterNome() + ".";*/ + nome_obj+=tab_pai->obterNome(true) + "."; + } + nome_obj+=objeto->obterNome(); + } + else + { + /* if(objeto->obterEsquema()) + nome_obj=objeto->obterEsquema()->obterNome() + "."; + nome_obj+=objeto->obterNome(); */ + nome_obj=objeto->obterNome(true); + } + } + + /* A identificação do objeto só será exibida caso o tipo do mesmo seja compatível + com o tipo de objeto aceito pelo seletor e caso o objeto esteja alocado (selecionado) */ + if(objeto && tipo_obj==tipo_obj_seletor) + { + //Exibe o nome do objeto + nome_objeto_txt->setPlainText(QString::fromUtf8(nome_obj)); + //Habilita o botão de remoção do objeto no seletor + rem_objeto_tb->setEnabled(objeto); + //Armazena a referência ao objeto no seletor + this->objeto=objeto; + + //Emite o sinal indicando que um objeto foi selecionado + emit s_objetoSelecionado(); + } + else + removerObjetoSelecionado(); +} +//----------------------------------------------------------- +void SeletorObjetoWidget::definirModelo(ModeloBD *modelo) +{ + this->modelo=modelo; +} +//----------------------------------------------------------- +void SeletorObjetoWidget::exibirObjetoSelecionado(ObjetoBase *obj_sel, bool) +{ + /* Caso se tente atribuir um objeto ao seletor é necessário verificar + se o seletor atual (em foco) é o mesmo que chamou o método pois + isso evita que outros seletores num mesmo formulário recebam o + objeto escolhido (o que seria incorreto) */ + if(SeletorObjetoWidget::seletor_atual==this && obj_sel) + definirObjeto(obj_sel); +} +//----------------------------------------------------------- +void SeletorObjetoWidget::removerObjetoSelecionado(void) +{ + //Limpa a referência ao objeto selecionado + this->objeto=NULL; + //Limpa o campo de texto que contém o nome do objeto + nome_objeto_txt->clear(); + //Desabilita o botão de remoção do objeto + rem_objeto_tb->setEnabled(false); + + //Emite o sinal indicando que um objeto foi selecionado + emit s_objetoRemovido(); +} +//----------------------------------------------------------- +void SeletorObjetoWidget::exibirSelecaoObjetos(void) +{ + /* Antes de exibir o form de seleção de objeto é preciso armazenar + o seletor que chama este form para que o objeto escolhido pelo + usuário seja exibido no seletor correto. Para isso sua referência + é armazenada no atributo estático da classe o qual é checado por + todas as instâncias desta classe a fim de se evitar atribuições + incorretas. */ + SeletorObjetoWidget::seletor_atual=this; + + /* Exibe o form de seleção de objetos exibindo apenas os objetos + do tipo aceito pelo seletor */ + selecaoobjetos_wgt->definirObjetoVisivel(tipo_obj_seletor, true); + selecaoobjetos_wgt->definirModelo(this->modelo); + selecaoobjetos_wgt->show(); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/seletorobjetowidget.h b/libpgmodeler_ui/src/seletorobjetowidget.h new file mode 100644 index 000000000..6a768793e --- /dev/null +++ b/libpgmodeler_ui/src/seletorobjetowidget.h @@ -0,0 +1,94 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: SeletorObjetoWidget +# Descrição: Definição da classe que implementa um seletor de objetos simples +# o qual integra o formulário de visão de objetos onde o usuário +# pode selecionar o objeto a ser exibido e alguns botões de controle +# do próprio seletor, usados para limpar o campo e para abrir a janela +# de seleção. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef SELETOR_OBJETO_WIDGET_H +#define SELETOR_OBJETO_WIDGET_H + +#include +#include "modelobd.h" +#include "destaquesintaxe.h" +#include "ui_seletorobjetowidget.h" +//*********************************************************** +class SeletorObjetoWidget: public QWidget, public Ui::SeletorObjetoWidget { + Q_OBJECT + + private: + /* Armazena o seletor que está focalizado atualmente. Este atributo é usado + para que outro seletor em um mesmo formulário não recebe o + valor selecionado para o seletor que realmente deve mostrar o nome + do objeto */ + static QObject *seletor_atual; + + /* Armazena o destacador de sintaxe que pode ser usado + para colorir o texto do seletor de acordo com a sintaxe SQL */ + DestaqueSintaxe *destaque_txt; + + //Armazena o objeto selecionado pelo usuário + ObjetoBase *objeto; + + //Armazena o tipo de objeto que deve ser selecionado pelo seletor + TipoObjetoBase tipo_obj_seletor; + + /* Armazena o modelo usado como referencia para seleção dos objetos + se este objeto não estive definido o seletor de objetos não + será exibido ficando inativo */ + ModeloBD *modelo; + + public: + /* Um seletor deve sempre ser instanciado com um rótulo e o tipo de objeto + que o seletor aceita */ + SeletorObjetoWidget(TipoObjetoBase tipo_obj_seletor, bool inst_destaque_txt, QWidget * parent = 0); + + //Retorna o objeto selecionado pelo usuário + ObjetoBase *obterObjeto(void); + + //Define o objeto inicial a ser exibido no seletor + void definirObjeto(ObjetoBase *objeto); + + //Define o modelo o qual o seletor de objeto buscará os objetos + void definirModelo(ModeloBD *modelo); + + private slots: + //Preenche um dos campos os quais referenciam um esquema, espaço tabela ou dono. + void exibirObjetoSelecionado(ObjetoBase *obj_sel, bool=false); + + //Exibe o formulário de seleção de objetos + void exibirSelecaoObjetos(void); + + public slots: + //Remove o objeto selecionado, limpando o campo do nome e anulando a referência ao objeto + void removerObjetoSelecionado(void); + + signals: + /* Sinal disparando quando um objeto é selecionado + e tem seu nome exibido na caixa de texto. */ + void s_objetoSelecionado(void); + + //Sinal disparando quando um objeto é deselecionado (removido) + void s_objetoRemovido(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/sequenciawidget.cpp b/libpgmodeler_ui/src/sequenciawidget.cpp new file mode 100644 index 000000000..985cad4cc --- /dev/null +++ b/libpgmodeler_ui/src/sequenciawidget.cpp @@ -0,0 +1,103 @@ +#include "sequenciawidget.h" +//*********************************************************** +SequenciaWidget::SequenciaWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_SEQUENCIA) +{ + try + { + map > mapa_campos; + QFrame *frame=NULL; + + Ui_SequenciaWidget::setupUi(this); + sel_coluna=NULL; + sel_coluna=new SeletorObjetoWidget(OBJETO_COLUNA, true, this); + + //Adicionando os objetos recém alocados no layout do formulário + sequencia_grid->addWidget(sel_coluna,3,1,1,3); + + //Define os campos exclusivos para cada versão + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_83)].push_back(possuidora_lbl); + + //Gera o frame de alerta + frame=gerarFrameAlertaVersao(mapa_campos); + sequencia_grid->addWidget(frame, sequencia_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + configurarLayouFormulario(sequencia_grid, OBJETO_SEQUENCIA); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + + janela_pai->resize(540, 410); + janela_pai->setMinimumWidth(540); + janela_pai->setMinimumHeight(430); + janela_pai->setMaximumHeight(430); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void SequenciaWidget::hideEvent(QHideEvent *evento) +{ + sel_coluna->removerObjetoSelecionado(); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void SequenciaWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Sequencia *sequencia) +{ + sel_coluna->definirModelo(modelo); + + if(sequencia) + { + sel_coluna->definirObjeto(sequencia->obterPossuidora()); + ciclica_chk->setChecked(sequencia->sequenciaCiclica()); + inicio_edt->setText(sequencia->obterInicio()); + maximo_edt->setText(sequencia->obterValorMax()); + minimo_edt->setText(sequencia->obterValorMin()); + cache_edt->setText(sequencia->obterCache()); + incremento_edt->setText(sequencia->obterIncremento()); + } + else + { + ciclica_chk->setChecked(false); + inicio_edt->setText("1"); + maximo_edt->setText(Sequencia::VALOR_MAX_POSITIVO); + minimo_edt->setText("0"); + cache_edt->setText("1"); + incremento_edt->setText("1"); + } + + //Preenchendo os campos básicos do formulário com os atributos da sequência + ObjetoBaseWidget::definirAtributos(modelo,lista_op,sequencia); +} +//--------------------------------------------------------- +void SequenciaWidget::aplicarConfiguracao(void) +{ + try + { + Sequencia *sequencia=NULL; + iniciarConfiguracao(); + + //Obtém a referência à sequência que está sendo editada/criada + sequencia=dynamic_cast(this->objeto); + + sequencia->definirCiclica(ciclica_chk->isChecked()); + sequencia->definirValores(minimo_edt->text(), maximo_edt->text(), incremento_edt->text(), + inicio_edt->text(), cache_edt->text()); + sequencia->definirPossuidora(dynamic_cast(sel_coluna->obterObjeto())); + + //Finaliza a configuração + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/sequenciawidget.h b/libpgmodeler_ui/src/sequenciawidget.h new file mode 100644 index 000000000..7f0076609 --- /dev/null +++ b/libpgmodeler_ui/src/sequenciawidget.h @@ -0,0 +1,47 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: SequenciaWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de sequências. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef SEQUENCIA_WIDGET_H +#define SEQUENCIA_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_sequenciawidget.h" +//*********************************************************** +class SequenciaWidget: public ObjetoBaseWidget, public Ui::SequenciaWidget { + Q_OBJECT + + private: + SeletorObjetoWidget *sel_coluna; + + public: + SequenciaWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Sequencia *sequencia); + + private slots: + void hideEvent(QHideEvent *); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/tabelaobjetoswidget.cpp b/libpgmodeler_ui/src/tabelaobjetoswidget.cpp new file mode 100644 index 000000000..fb90dcc9b --- /dev/null +++ b/libpgmodeler_ui/src/tabelaobjetoswidget.cpp @@ -0,0 +1,638 @@ +#include "tabelaobjetoswidget.h" +#include "caixamensagem.h" +extern CaixaMensagem *caixa_msg; +//*********************************************************** +TabelaObjetosWidget::TabelaObjetosWidget(unsigned conf_botoes, bool conf_exclusoes, QWidget *parent): QWidget(parent) +{ + setupUi(this); + connect(mover_baixo_tb, SIGNAL(clicked(bool)), this, SLOT(moverLinhas(void))); + connect(mover_cima_tb, SIGNAL(clicked(bool)), this, SLOT(moverLinhas(void))); + connect(mover_primeiro_tb, SIGNAL(clicked(bool)), this, SLOT(moverLinhas(void))); + connect(mover_ultimo_tb, SIGNAL(clicked(bool)), this, SLOT(moverLinhas(void))); + connect(adicionar_tb, SIGNAL(clicked(bool)), this, SLOT(adicionarLinha(void))); + connect(remover_tb, SIGNAL(clicked(bool)), this, SLOT(removerLinha(void))); + connect(editar_tb, SIGNAL(clicked(bool)), this, SLOT(editarLinha(void))); + connect(atualizar_tb, SIGNAL(clicked(bool)), this, SLOT(atualizarLinha(void))); + connect(remover_todas_tb, SIGNAL(clicked(bool)), this, SLOT(removerLinhas(void))); + connect(tabela_tbw, SIGNAL(cellClicked(int,int)), this, SLOT(habilitarBotoes(void))); + connect(tabela_tbw, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(editarLinha(void))); + + this->conf_exclusoes=conf_exclusoes; + definirConfiguracaoBotoes(conf_botoes); + + definirNumColunas(1); + + adicionar_tb->setToolTip(adicionar_tb->toolTip() + QString(" (%1)").arg(adicionar_tb->shortcut().toString())); + remover_tb->setToolTip(remover_tb->toolTip() + QString(" (%1)").arg(remover_tb->shortcut().toString())); + remover_todas_tb->setToolTip(remover_todas_tb->toolTip() + QString(" (%1)").arg(remover_todas_tb->shortcut().toString())); + atualizar_tb->setToolTip(atualizar_tb->toolTip() + QString(" (%1)").arg(atualizar_tb->shortcut().toString())); + editar_tb->setToolTip(editar_tb->toolTip() + QString(" (%1)").arg(editar_tb->shortcut().toString())); + mover_ultimo_tb->setToolTip(mover_ultimo_tb->toolTip() + QString(" (%1)").arg(mover_ultimo_tb->shortcut().toString())); + mover_primeiro_tb->setToolTip(mover_primeiro_tb->toolTip() + QString(" (%1)").arg(mover_primeiro_tb->shortcut().toString())); + mover_cima_tb->setToolTip(mover_cima_tb->toolTip() + QString(" (%1)").arg(mover_cima_tb->shortcut().toString())); + mover_baixo_tb->setToolTip(mover_baixo_tb->toolTip() + QString(" (%1)").arg(mover_baixo_tb->shortcut().toString())); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::definirConfiguracaoBotoes(unsigned conf_botoes) +{ + bool btn_mover, btn_edt, btn_ins, btn_limpar, btn_rem, btn_atual; + + /* Verificando, através de operações bit a bit, a presença de cada tipo de + botão na configuração passada */ + btn_mover=(conf_botoes & BTN_MOVER_ITENS) == BTN_MOVER_ITENS; + btn_edt=(conf_botoes & BTN_EDITAR_ITEM) == BTN_EDITAR_ITEM; + btn_ins=(conf_botoes & BTN_INSERIR_ITEM) == BTN_INSERIR_ITEM; + btn_rem=(conf_botoes & BTN_REMOVER_ITEM) == BTN_REMOVER_ITEM; + btn_limpar=(conf_botoes & BTN_LIMPAR_ITENS) == BTN_LIMPAR_ITENS; + btn_atual=(conf_botoes & BTN_ATUALIZAR_ITEM) == BTN_ATUALIZAR_ITEM; + + //Seta os btões visíveis de acordo com a presença dos mesmos na configuração de botões + mover_baixo_tb->setVisible(btn_mover); + mover_cima_tb->setVisible(btn_mover); + mover_primeiro_tb->setVisible(btn_mover); + mover_ultimo_tb->setVisible(btn_mover); + + editar_tb->setVisible(btn_edt); + remover_todas_tb->setVisible(btn_limpar); + + adicionar_tb->setVisible(btn_ins); + remover_tb->setVisible(btn_rem); + atualizar_tb->setVisible(btn_atual); + + if(!btn_edt && !btn_mover && !btn_ins && !btn_limpar && !btn_rem && !btn_atual) + { + tabelaobj_grid->removeWidget(tabela_tbw); + tabelaobj_grid->addWidget(tabela_tbw,0,0,1,10); + } +} +//----------------------------------------------------------- +void TabelaObjetosWidget::definirNumColunas(unsigned num_colunas) +{ + if(num_colunas > 0) + { + unsigned i; + QTableWidgetItem *item=NULL; + + /* A adição dos rótulos de cabeçalhos das colunas se iniciará + a partir da ultima coluna */ + i=tabela_tbw->columnCount(); + //Define o novo número de colunas da tabela + tabela_tbw->setColumnCount(num_colunas); + + /* Adiciona novos rótulos caso o número de colunas do parâmetro + seja superior ao número de colunas atual da tabela */ + for(;i < num_colunas; i++) + { + item=new QTableWidgetItem; + tabela_tbw->setHorizontalHeaderItem(static_cast(i),item); + } + } +} +//----------------------------------------------------------- +void TabelaObjetosWidget::definirRotuloCabecalho(const QString &rotulo, unsigned idx_col) +{ + QTableWidgetItem *item=NULL; + + /* Caso o índice da coluna do cabeçalho referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_col >= static_cast(tabela_tbw->columnCount())) + throw Excecao(ERR_PGMODELERUI_REFCOLTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Obtém o item que representa o cabeçalho na coluna indicada + item=tabela_tbw->horizontalHeaderItem(idx_col); + //Define o rótulo do item + item->setText(rotulo); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::definirIconeCabecalho(const QIcon &icone, unsigned idx_col) +{ + QTableWidgetItem *item=NULL; + + /* Caso o índice da coluna do cabeçalho referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_col >= static_cast(tabela_tbw->columnCount())) + throw Excecao(ERR_PGMODELERUI_REFCOLTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Obtém o item que representa o cabeçalho na coluna indicada + item=tabela_tbw->horizontalHeaderItem(idx_col); + //Define o ícone do item obtido + item->setIcon(icone); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::definirIconeCelula(const QIcon &icone, unsigned idx_lin, unsigned idx_col) +{ + QTableWidgetItem *item=NULL; + + /* Caso o índice da linha da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_lin >= static_cast(tabela_tbw->rowCount())) + throw Excecao(ERR_PGMODELERUI_REFLINTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + /* Caso o índice da coluna da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_col >= static_cast(tabela_tbw->columnCount())) + throw Excecao(ERR_PGMODELERUI_REFCOLTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Obtém o item o qual representa a célula + item=tabela_tbw->item(idx_lin, idx_col); + //Define o ícone da célula + item->setIcon(icone); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::definirTextoCelula(const QString &texto, unsigned idx_lin, unsigned idx_col) +{ + QTableWidgetItem *item=NULL; + + /* Caso o índice da linha da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_lin >= static_cast(tabela_tbw->rowCount())) + throw Excecao(ERR_PGMODELERUI_REFLINTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + /* Caso o índice da coluna da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_col >= static_cast(tabela_tbw->columnCount())) + throw Excecao(ERR_PGMODELERUI_REFCOLTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Obtém o item o qual representa a célula + item=tabela_tbw->item(idx_lin,idx_col); + //Define o texto da célula + item->setText(texto); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::definirFonteLinha(int idx_lin, const QFont &fonte, const QColor &cor_texto, const QColor &cor_fundo) +{ + QTableWidgetItem *item=NULL; + int qtd_col, i; + + /* Caso o índice da linha da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_lin >= tabela_tbw->rowCount()) + throw Excecao(ERR_PGMODELERUI_REFLINTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + qtd_col=tabela_tbw->columnCount(); + for(i=0; i < qtd_col; i++) + { + item=tabela_tbw->item(idx_lin, i); + item->setFont(fonte); + item->setForeground(cor_texto); + item->setBackgroundColor(cor_fundo); + } +} +//----------------------------------------------------------- +void TabelaObjetosWidget::definirDadoLinha(const QVariant &dado, unsigned idx_lin) +{ + QTableWidgetItem *item=NULL; + + /* Caso o índice da linha da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_lin >= static_cast(tabela_tbw->rowCount())) + throw Excecao(ERR_PGMODELERUI_REFLINTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + /* Obtém o ítem que representa o cabeçalho vertical da linha. + Este cabeçalho é usado para armazenar o dado que a linha guarda. + Os dados são guardados em forma de um QVariant. */ + item=tabela_tbw->verticalHeaderItem(idx_lin); + //Armazena dentro do item o dado passado no parâmetro + item->setData(Qt::UserRole, dado); +} +//----------------------------------------------------------- +unsigned TabelaObjetosWidget::obterNumColunas(void) +{ + //Retorna o número de colunas do objeto tabela + return(tabela_tbw->columnCount()); +} +//----------------------------------------------------------- +unsigned TabelaObjetosWidget::obterNumLinhas(void) +{ + //Retorna o número de linhas do objeto tabela + return(tabela_tbw->rowCount()); +} +//----------------------------------------------------------- +QString TabelaObjetosWidget::obterRotuloCabecalho(unsigned idx_col) +{ + QTableWidgetItem *item=NULL; + + /* Caso o índice da coluna do cabeçalho a ser referenciado seja inválida + dispara um erro indicando a situação */ + if(idx_col >= static_cast(tabela_tbw->columnCount())) + throw Excecao(ERR_PGMODELERUI_REFCOLTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Obtém o cabeçalho e retorna seu texto + item=tabela_tbw->horizontalHeaderItem(idx_col); + return(item->text()); +} +//----------------------------------------------------------- +QString TabelaObjetosWidget::obterTextoCelula(unsigned idx_lin, unsigned idx_col) +{ + QTableWidgetItem *item=NULL; + + /* Caso o índice da linha da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_lin >= static_cast(tabela_tbw->rowCount())) + throw Excecao(ERR_PGMODELERUI_REFLINTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + /* Caso o índice da coluna da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_col >= static_cast(tabela_tbw->columnCount())) + throw Excecao(ERR_PGMODELERUI_REFCOLTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + /* Obtém o item que representa a célula na linha e coluna especificadas + e procede com o retorno do seu texto */ + item=tabela_tbw->item(idx_lin,idx_col); + return(item->text()); +} +//----------------------------------------------------------- +QVariant TabelaObjetosWidget::obterDadoLinha(unsigned idx_lin) +{ + QTableWidgetItem *item=NULL; + + /* Caso o índice da linha a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_lin >= static_cast(tabela_tbw->rowCount())) + throw Excecao(ERR_PGMODELERUI_REFLINTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Obtém o cabeçalho vertical da linha o qual armazena o dado desta + item=tabela_tbw->verticalHeaderItem(idx_lin); + //Retorna o dado armazenado pelo item + return(item->data(Qt::UserRole)); +} +//----------------------------------------------------------- +int TabelaObjetosWidget::obterLinhaSelecionada(void) +{ + return(tabela_tbw->currentRow()); +} +//----------------------------------------------------------- +int TabelaObjetosWidget::obterIndiceLinha(const QVariant &dado) +{ + unsigned i, qtd; + QTableWidgetItem *item=NULL; + bool enc=false; + QVariant dado_aux; + + //Obtém a quantidade de linhas da tabela + qtd=tabela_tbw->rowCount(); + + /* Varre as linhas da tabela comparando o dado armazenado + em cada uma delas com o dado vindo do parâmetro */ + for(i=0; !enc && i < qtd; i++) + { + //Obtém o item que armazena o dado da linha + item=tabela_tbw->verticalHeaderItem(i); + + //Faz a comparação entre os valores do mesmo e do parâmetro + enc=(item && + item->data(Qt::UserRole).value() == dado.value()); + } + + /* Caso o mesmo não seja encontrado retorna -1 + caso contrário retorna o índice da linha onde + o mesmo se encontra */ + if(!enc) + return(-1); + else + return(i); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::adicionarColuna(unsigned idx_col) +{ + /* Caso o índice da coluna anterior à coluna a ser adcionada seja inválido + adiciona a coluna ao final da lista de colunas */ + if(idx_col >= static_cast(tabela_tbw->columnCount())) + idx_col=tabela_tbw->columnCount(); + + //Adiciona a coluna + tabela_tbw->insertColumn(idx_col); + tabela_tbw->clearSelection(); + habilitarBotoes(); + + //Emite um sinal indicando em qual índice foi adicionada uma coluna + emit s_colunaAdicionada(idx_col); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::selecionarLinha(int idx_lin) +{ + QTableWidgetItem *item=NULL; + + item=tabela_tbw->item(0,idx_lin); + + if(item) + { + item=tabela_tbw->item(idx_lin,0); + item->setSelected(true); + tabela_tbw->setCurrentItem(item); + habilitarBotoes(); + } +} +//----------------------------------------------------------- +void TabelaObjetosWidget::adicionarLinha(void) +{ + QTableWidgetItem *item=NULL; + unsigned i, lin, qtd_col=tabela_tbw->columnCount(); + + //A nova linha será inserida após a última linha + lin=tabela_tbw->rowCount(); + tabela_tbw->insertRow(lin); + + //Cria o cabeçalho vertical da linha adicionada + item=new QTableWidgetItem; + item->setText(QString("%1").arg(lin+1)); + tabela_tbw->setVerticalHeaderItem(lin,item); + + /* Após inserida a linha as colunas da nova linha + precisam ser criadas */ + for(i=0; i < qtd_col; i++) + { + //Cria um item que representa a coluna atual da nova linha + item=new QTableWidgetItem; + //Insere o item criado na coluna atual (i) + tabela_tbw->setItem(lin,i,item); + } + + //Seleciona os itens da linha inserida + item=tabela_tbw->item(lin,0); + item->setSelected(true); + tabela_tbw->setCurrentItem(item); + + /* Executa o método de habilitação dos botões de acordo + com a linha atual */ + habilitarBotoes(); + //Emite um sinal com o índice da linha adicionada + emit s_linhaAdicionada(lin); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::removerLinha(unsigned idx_lin) +{ + unsigned i, qtd; + bool conf; + + /* Caso o índice da linha da célula a ser referenciada seja inválida + dispara um erro indicando a situação */ + if(idx_lin >= static_cast(tabela_tbw->rowCount())) + throw Excecao(ERR_PGMODELERUI_REFLINTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Limpa a seleção da linha atual + tabela_tbw->clearSelection(); + qtd=tabela_tbw->columnCount(); + + //Seleciona todas a colunas da linha a ser removida + for(i=0; i < qtd; i++) + tabela_tbw->item(idx_lin, i)->setSelected(true); + + //Marca a linha cujo índice é idx_lin como sendo a linha atual da tabela + tabela_tbw->setCurrentItem(tabela_tbw->item(idx_lin,0)); + + conf=conf_exclusoes; + conf_exclusoes=false; + //Remove a linha selecionada + removerLinha(); + conf_exclusoes=conf; +} +//----------------------------------------------------------- +void TabelaObjetosWidget::removerLinha(void) +{ + /* Caso haja alguma linha selecionada ou seja o índice + da linha atual seja igual ou superior a zero */ + if(tabela_tbw->currentRow()>=0) + { + unsigned /*qtd_lin,*/ + idx_lin=tabela_tbw->currentRow(); + //Obtém o item selecionado na linha atual + QTableWidgetItem *item=tabela_tbw->currentItem(); + + if(item->isSelected()) + { + if(conf_exclusoes) + caixa_msg->show(trUtf8("Confirmação"),trUtf8("Tem certeza de que deseja remover o item selecionado?"), + CaixaMensagem::ICONE_CONFIRM, CaixaMensagem::BOTAO_SIM_NAO); + + if(!conf_exclusoes || (conf_exclusoes && caixa_msg->result()==QDialog::Accepted)) + { + //Remove a linha atual + tabela_tbw->removeRow(idx_lin); + tabela_tbw->setCurrentItem(NULL); + habilitarBotoes(); + + //Emite o sinal de linha removida com o índice da linha excluída + emit s_linhaRemovida(idx_lin); + } + } + } +} +//----------------------------------------------------------- +void TabelaObjetosWidget::removerLinhas(void) +{ + if(tabela_tbw->rowCount() > 0) + { + QObject *obj_sender=sender(); + + /* A caixa de mensagem só é exibida caso a confirmação de exclusão esteja configurada + e o objeto sender esteja setado para o botão "remover todas". + Este objeto sender indica que o método foi + chamado através do acionamento deste objeto. Este método pode ser chamado diretamente + sem ser através de outro objeto, desta forma, todos os itens são removidos sem confirmação + independente da confirmação estar configurada ou não. Isto é util no caso de uma limpeza + da tabela para reuso. */ + if(conf_exclusoes && obj_sender==remover_todas_tb) + caixa_msg->show(trUtf8("Confirmação"),trUtf8("Tem certeza de que deseja remover todos os itens?"), + CaixaMensagem::ICONE_CONFIRM, CaixaMensagem::BOTAO_SIM_NAO); + + if(!conf_exclusoes || (conf_exclusoes && obj_sender!=remover_todas_tb) || + (conf_exclusoes && obj_sender==remover_todas_tb && caixa_msg->result()==QDialog::Accepted)) + { + //Remove as linhas enquanto a quantidade não atinge zero + while(tabela_tbw->rowCount() > 0) + tabela_tbw->removeRow(0); + + habilitarBotoes(); + + // Emite o sinal indicando que as linhas da tabela foram removidas caso + emit s_linhasRemovidas(); + } + } +} +//----------------------------------------------------------- +void TabelaObjetosWidget::removerColuna(unsigned idx_col) +{ + /* Caso o índice da coluna a ser removida seja inválido retorna um erro + e aborta a operação */ + if(idx_col >= static_cast(tabela_tbw->columnCount())) + throw Excecao(ERR_PGMODELERUI_REFCOLTABOBJIDXINV,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Remove a coluna no indice especificado e limpa a seleção + tabela_tbw->removeColumn(idx_col); + tabela_tbw->clearSelection(); + habilitarBotoes(); + //Emite o sinal indicando a coluna removida + emit s_colunaRemovida(idx_col); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::moverLinhas(void) +{ + QObject *obj_sender=sender(); + QTableWidgetItem *item=NULL, *item1=NULL; + int lin=-1, lin1=-1; + unsigned col, qtd_col=tabela_tbw->columnCount(); + QVariant dado_aux; + + /* Obtém o índice da linha atual. É com base nesse índice + que será verificado com qual linha será trocada a posição + da linha selecionada */ + lin=tabela_tbw->currentRow(); + + /* Caso o botão de mover uma linha para baixo for acionado + a linha selecionada terá sua posição trocada com a linha + imediatamente abaixo dela */ + if(obj_sender==mover_baixo_tb) + lin1=lin+1; + /* Caso o botão de mover uma linha para cima for acionado + a linha selecionada terá sua posição trocada com a linha + imediatamente acima dela */ + else if(obj_sender==mover_cima_tb) + lin1=lin-1; + /* Caso o botão de mover para a primeira linha for acionado + a linha selecionada terá sua posição trocada com a + primeira linha da tabela */ + else if(obj_sender==mover_primeiro_tb) + lin1=0; + /* Caso o botão de mover para a última linha for acionado + a linha selecionada terá sua posição trocada com a + última linha da tabela */ + else if(obj_sender==mover_ultimo_tb) + lin1=tabela_tbw->rowCount()-1; + /* Verifica se os índices da linhas a serem trocadas são válidos + ou seja, são diferentes entre si e não ultrapassam o limite de + linhas presentes na tabela */ + if(lin >= 0 && lin < tabela_tbw->rowCount() && + lin1 >= 0 && lin1 < tabela_tbw->rowCount() && + lin != lin1) + { + /* Para se trocar a posição da linhas é necessário trocar coluna por coluna + desta forma o for a seguir executa a troca de cada coluna das linhas + envolvida */ + for(col=0; col < qtd_col; col++) + { + /* Obtém uma coluna da linha atual e em seguida remove + a mesma sem desalocá-la */ + item=tabela_tbw->item(lin, col); + tabela_tbw->takeItem(lin, col); + + /* Obtém uma coluna da linha que será trocada com atual + e em seguida remove a mesma sem desalocá-la */ + item1=tabela_tbw->item(lin1, col); + tabela_tbw->takeItem(lin1, col); + + /* Efetiva a troca das linhas, onde o item obtido da linha atual + passa a pertencer a linha vizinha e o item da linha vizinha + passa a fazer parte da linha atual */ + tabela_tbw->setItem(lin, col, item1); + tabela_tbw->setItem(lin1, col, item); + + item1->setSelected(false); + item->setSelected(true); + } + + tabela_tbw->setCurrentItem(item); + + /* Fazendo a troca dos dados das linhas. Para isso + é necessário obter os cabeçalhos verticais os quais + guardam a informação em si da linha da tabela */ + item=tabela_tbw->verticalHeaderItem(lin); + item1=tabela_tbw->verticalHeaderItem(lin1); + + if(item && item1) + { + //Obtido os items faz a troca dos dados entre eles + dado_aux=item->data(Qt::UserRole); + item->setData(Qt::UserRole, item1->data(Qt::UserRole)); + item1->setData(Qt::UserRole, dado_aux); + } + + habilitarBotoes(); + emit s_linhasMovidas(lin, lin1); + } +} +//----------------------------------------------------------- +void TabelaObjetosWidget::editarLinha(void) +{ + /* Para este método nada é executado apenas um sinal é emitido + com o índice da linha a ser editada. Quem deve tratar a edição + da linha é o objeto externo o qual faz uso da tabela. */ + emit s_linhaEditada(tabela_tbw->currentRow()); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::atualizarLinha(void) +{ + /* Para este método nada é executado apenas um sinal é emitido + com o índice da linha a ser editada. Quem deve tratar a edição + da linha é o objeto externo o qual faz uso da tabela. */ + emit s_linhaAtualizada(tabela_tbw->currentRow()); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::limparSelecao(void) +{ + tabela_tbw->clearSelection(); + tabela_tbw->setCurrentItem(NULL); + habilitarBotoes(); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::habilitarBotoes(unsigned conf_botoes, bool valor) +{ + int lin=-1; + //Obtém o item atual caso haja algum selecionado + QTableWidgetItem *item=tabela_tbw->currentItem(); + + //Obtém a linha a qual o item pertence + if(item) + lin=item->row(); + + /* Atribui o valor booleano passado caso o botão esteja presente + na configuração de botões informada */ + if((conf_botoes & BTN_MOVER_ITENS) == BTN_MOVER_ITENS) + { + /* O botão de mover uma linha para cima deve ser habilitado + caso a linha selecionada não seja a primeira linha */ + mover_cima_tb->setEnabled(valor && lin > 0); + + /* O botão de mover uma linha para baixo deve ser habilitado + caso a linha selecionada não seja a última linha */ + mover_baixo_tb->setEnabled(valor && lin >= 0 && lin < tabela_tbw->rowCount()-1); + + /* O botão de mover para última linha deve ser habilitado + caso a linha selecionada não seja a última */ + mover_primeiro_tb->setEnabled(valor && lin > 0 && lin<=tabela_tbw->rowCount()-1); + + /* O botão de mover para primeira linha deve ser habilitado + caso a linha selecionada não seja a primeira */ + mover_ultimo_tb->setEnabled(valor && lin >=0 && lin < tabela_tbw->rowCount()-1); + } + + if((conf_botoes & BTN_EDITAR_ITEM) == BTN_EDITAR_ITEM) + editar_tb->setEnabled(valor && lin >= 0); + + if((conf_botoes & BTN_INSERIR_ITEM) == BTN_INSERIR_ITEM) + adicionar_tb->setEnabled(valor); + + if((conf_botoes & BTN_REMOVER_ITEM) == BTN_REMOVER_ITEM) + remover_tb->setEnabled(valor && lin >= 0); + + if((conf_botoes & BTN_LIMPAR_ITENS) == BTN_LIMPAR_ITENS) + remover_todas_tb->setEnabled(valor && tabela_tbw->rowCount() > 0); + + if((conf_botoes & BTN_ATUALIZAR_ITEM) == BTN_ATUALIZAR_ITEM) + atualizar_tb->setEnabled(valor && lin >= 0); +} +//----------------------------------------------------------- +void TabelaObjetosWidget::habilitarBotoes(void) +{ + //Obtém o item atual caso haja algum selecionado + QTableWidgetItem *item=tabela_tbw->currentItem(); + + habilitarBotoes(TODOS_BOTOES, true); + + /* Caso uma linha esteja selecionada emite o sinal indicativo de seleção de linha, + este sinal é interessante quando se quer ter acesso direto à linha selecionada + sem ter que chamar o método de obterLinhaSelecionada() */ + if(item && item->row() >= 0) + emit s_linhaSelecionada(item->row()); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/tabelaobjetoswidget.h b/libpgmodeler_ui/src/tabelaobjetoswidget.h new file mode 100644 index 000000000..424291089 --- /dev/null +++ b/libpgmodeler_ui/src/tabelaobjetoswidget.h @@ -0,0 +1,189 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: TabelaObjetosWidget +# Descrição: Definição da classe que implementa uma tabela para manipulação +# vários objetos em uma grade. Incluíndo funções de inclusão e exclusão +# de objeto e movimentação dos mesmos nas linhas da tabela. Esta classe +# é usada como auxiliar em formulários os quais trabalham com vários objetos +# filhos de um objeto pai único (ex.: Tabelas, Indices, Restrições). +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef TABELA_OBJETOS_WIDGET_H +#define TABELA_OBJETOS_WIDGET_H + +#include "ui_tabelaobjetoswidget.h" +#include "objetobasewidget.h" +//*********************************************************** +class TabelaObjetosWidget: public QWidget, public Ui::TabelaObjetosWidget { + Q_OBJECT + + private: + /* Indica se caixas de confirmação serão exibidas a cada exclusão de + itens da tabela, por padrão as exclusões são feitas sem confirmação */ + bool conf_exclusoes; + + public: + //Constantes usadas ativa/desativa um conjunto de botões da tabela + const static unsigned BTN_INSERIR_ITEM=1, + BTN_REMOVER_ITEM=2, + BTN_ATUALIZAR_ITEM=4, + BTN_MOVER_ITENS=8, + BTN_EDITAR_ITEM=16, + BTN_LIMPAR_ITENS=32, + TODOS_BOTOES=63, + SEM_BOTOES=0; + + TabelaObjetosWidget(unsigned conf_botoes=TODOS_BOTOES,/*BTN_INSERIR_ITEM | BTN_REMOVER_ITEM | BTN_MOVER_ITENS | + BTN_EDITAR_ITEM | BTN_LIMPAR_ITENS*/ + bool conf_exclusoes=false, QWidget * parent = 0); + + //Define o número de colunas da tabela + void definirNumColunas(unsigned num_colunas); + + //Define o rótulo do cabeçalho de uma coluna + void definirRotuloCabecalho(const QString &rotulo, unsigned idx_col); + + //Define o ícone do rótulo de uma coluna + void definirIconeCabecalho(const QIcon &icone, unsigned idx_col); + + //Define o ícone de uma dada célula + void definirIconeCelula(const QIcon &icone, unsigned idx_lin, unsigned idx_col); + + //Define o texto de uma dada célula + void definirTextoCelula(const QString &texto, unsigned idx_lin, unsigned idx_col); + + //Define o dado que uma linha armazena + void definirDadoLinha(const QVariant &dado, unsigned idx_lin); + + void definirFonteLinha(int idx_lin, const QFont &fonte, const QColor &cor_texto, const QColor &cor_fundo); + + //Retorna o número de colunas definidas na tabela + unsigned obterNumColunas(void); + + //Retorna o número de linhas atuais na tabela + unsigned obterNumLinhas(void); + + //Retorna o rótulo de um cabeçalho de colun + QString obterRotuloCabecalho(unsigned idx_col); + + //Retorna o texto de uma célula + QString obterTextoCelula(unsigned idx_lin, unsigned idx_col); + + //Retorna o dado armazenado numa linha + QVariant obterDadoLinha(unsigned idx_lin); + + //Remove uma coluna através de seu índice + void removerColuna(unsigned idx_col); + + //Adiciona uma coluna no índice especificado + void adicionarColuna(unsigned idx_col); + + //Retorna o índice da linha selecionada na tabela + int obterLinhaSelecionada(void); + + /* Retorna o índice da linha buscando-a através do dado + que ela armazena. Caso este não seja encontrada + o método retorna -1 */ + int obterIndiceLinha(const QVariant &dado); + + //Define os botões disponíveis para controle da tabela + void definirConfiguracaoBotoes(unsigned botoes); + + private slots: + /* Move a linha selecionada para cima ou para baixo de acordo com o + botão de movimentação acionado pelo usuário */ + void moverLinhas(void); + + //Remove a linha selecionada atualmente + void removerLinha(void); + + /* Dispara um sinal indicando que uma linha está preparada para edição. + A edição da linha deve ser manipulada/implementada no objeto o qual + fizer uso da tabela de objetos pois por ser tratar de um procedimento + especifico não foi implementado nesta classe, por isso o método apenas + dispara o sinal de edição da linha. */ + void editarLinha(void); + + /* Dispara um sinal indicando que uma linha está preparada para atualização. + A atualização da linha deve ser manipulada/implementada no objeto o qual + fizer uso da tabela de objetos pois por ser tratar de um procedimento + especifico não foi implementado nesta classe, por isso o método apenas + dispara o sinal de atualização da linha. */ + void atualizarLinha(void); + + //Habilita os botões de acordo com a linha selecionada na tabela + void habilitarBotoes(void); + + public slots: + //Adiciona uma linha ao final da tabela + void adicionarLinha(void); + + //Remove todas as lista da tabela + void removerLinhas(void); + + //Remove uma linha na posição selecionada + void removerLinha(unsigned idx_lin); + + //Limpa a seleção da tabela desmarcando cada linha selecionada + void limparSelecao(void); + + //Seleciona a linha cujo indice está especificado + void selecionarLinha(int idx_lin); + + //Define o estado de habilitação dos botãos especificados + void habilitarBotoes(unsigned conf_botoes, bool valor); + + signals: + /* Sinal disparando quando uma linha é adicionada. + O índice da linha adicionada é enviado com o sinal. */ + void s_linhaAdicionada(int); + + /* Sinal disparado quando duas linhas tem suas posições trocadas. + O índice das linhas trocadas são enviado com o sinal. */ + void s_linhasMovidas(int,int); + + //Sinal disparado quano todas as linhas da tabela são excluídas + void s_linhasRemovidas(void); + + /* Sinal disparado quando uma dada linha é removida. O índice da linha + removida é enviado com o sinal. */ + void s_linhaRemovida(int); + + /* Sinal disparado quando uma dada linha é selecionada. O índice da linha + selecionada é enviado com o sinal. */ + void s_linhaSelecionada(int); + + /* Sinal disparado quando uma dada linha é editada. + O índice da linha editada é enviado com o sinal. */ + void s_linhaEditada(int); + + /* Sinal disparado quando o botão de atualizar a linha e acionado. + O índice da linha atualizada é enviado com o sinal. */ + void s_linhaAtualizada(int); + + /* Sinal disparado quando uma dada coluna é removida. + O índice da coluna removida é enviado com o sinal. */ + void s_colunaRemovida(int); + + /* Sinal disparado quando uma dada coluna é adicionada. + O índice da coluna adicionada é enviado com o sinal. */ + void s_colunaAdicionada(int); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/tabelawidget.cpp b/libpgmodeler_ui/src/tabelawidget.cpp new file mode 100644 index 000000000..addda6309 --- /dev/null +++ b/libpgmodeler_ui/src/tabelawidget.cpp @@ -0,0 +1,653 @@ +#include "tabelawidget.h" +#include "colunawidget.h" +#include "restricaowidget.h" +#include "regrawidget.h" +#include "indicewidget.h" +#include "gatilhowidget.h" +#include "caixamensagem.h" + +extern RestricaoWidget *restricao_wgt; +extern ColunaWidget *coluna_wgt; +extern RegraWidget *regra_wgt; +extern IndiceWidget *indice_wgt; +extern GatilhoWidget *gatilho_wgt; +extern CaixaMensagem *caixa_msg; +//*********************************************************** +TabelaWidget::TabelaWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_TABELA) +{ + //QStringList lista; + QGridLayout *grid=NULL; + TabelaObjetosWidget *tab=NULL; + TipoObjetoBase tipos[]={ OBJETO_COLUNA, OBJETO_RESTRICAO, OBJETO_GATILHO, + OBJETO_REGRA, OBJETO_INDICE }; + + Ui_TabelaWidget::setupUi(this); + + qtd_operacoes=0; + + //Configura as tabelas que armazenam os objetos da tabela + for(unsigned i=0; i < 5; i++) + { + //Aloca a tabela do tipo atual + tab=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + (TabelaObjetosWidget::BTN_ATUALIZAR_ITEM), true, this); + /* Armazena sua referência no mapa para facilitar as operações onde + se precisa obter a tabela de um tipo de objeto de tabela específico */ + mapa_tab_objetos[tipos[i]]=tab; + + grid=new QGridLayout; + grid->addWidget(tab, 0,0,1,1); + grid->setContentsMargins(2,2,2,2); + atributos_tbw->widget(i)->setLayout(grid); + + //Conecta os sinais/slots na tabela alocada + connect(tab, SIGNAL(s_linhasRemovidas(void)), this, SLOT(removerObjetos(void))); + connect(tab, SIGNAL(s_linhaRemovida(int)), this, SLOT(removerObjeto(int))); + connect(tab, SIGNAL(s_linhaAdicionada(int)), this, SLOT(manipularObjeto(void))); + connect(tab, SIGNAL(s_linhaEditada(int)), this, SLOT(manipularObjeto(void))); + connect(tab, SIGNAL(s_linhasMovidas(int,int)), this, SLOT(moverObjetos(int,int))); + } + + //Configura as colunas e rótulos das tabelas de objetos + mapa_tab_objetos[OBJETO_COLUNA]->definirNumColunas(4); + mapa_tab_objetos[OBJETO_COLUNA]->definirRotuloCabecalho(trUtf8("Nome"), 0); + mapa_tab_objetos[OBJETO_COLUNA]->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + mapa_tab_objetos[OBJETO_COLUNA]->definirRotuloCabecalho(trUtf8("Tipo"), 1); + mapa_tab_objetos[OBJETO_COLUNA]->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + mapa_tab_objetos[OBJETO_COLUNA]->definirRotuloCabecalho(trUtf8("Valor Padrão"), 2); + mapa_tab_objetos[OBJETO_COLUNA]->definirRotuloCabecalho(trUtf8("Atributos"), 3); + + mapa_tab_objetos[OBJETO_RESTRICAO]->definirNumColunas(4); + mapa_tab_objetos[OBJETO_RESTRICAO]->definirRotuloCabecalho(trUtf8("Nome"), 0); + mapa_tab_objetos[OBJETO_RESTRICAO]->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + mapa_tab_objetos[OBJETO_RESTRICAO]->definirRotuloCabecalho(trUtf8("Tipo"), 1); + mapa_tab_objetos[OBJETO_RESTRICAO]->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + mapa_tab_objetos[OBJETO_RESTRICAO]->definirRotuloCabecalho(trUtf8("ON DELETE"), 2); + mapa_tab_objetos[OBJETO_RESTRICAO]->definirRotuloCabecalho(trUtf8("ON UPDATE"), 3); + + mapa_tab_objetos[OBJETO_GATILHO]->definirNumColunas(4); + mapa_tab_objetos[OBJETO_GATILHO]->definirRotuloCabecalho(trUtf8("Nome"), 0); + mapa_tab_objetos[OBJETO_GATILHO]->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + mapa_tab_objetos[OBJETO_GATILHO]->definirRotuloCabecalho(trUtf8("Tab. Refer."), 1); + mapa_tab_objetos[OBJETO_GATILHO]->definirIconeCabecalho(QPixmap(":/icones/icones/table.png"),1); + mapa_tab_objetos[OBJETO_GATILHO]->definirRotuloCabecalho(trUtf8("Disparo"), 2); + mapa_tab_objetos[OBJETO_GATILHO]->definirIconeCabecalho(QPixmap(":/icones/icones/trigger.png"),2); + mapa_tab_objetos[OBJETO_GATILHO]->definirRotuloCabecalho(trUtf8("Eventos"), 3); + + mapa_tab_objetos[OBJETO_REGRA]->definirNumColunas(3); + mapa_tab_objetos[OBJETO_REGRA]->definirRotuloCabecalho(trUtf8("Nome"), 0); + mapa_tab_objetos[OBJETO_REGRA]->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + mapa_tab_objetos[OBJETO_REGRA]->definirRotuloCabecalho(trUtf8("Execução"), 1); + mapa_tab_objetos[OBJETO_REGRA]->definirRotuloCabecalho(trUtf8("Evento"), 2); + + mapa_tab_objetos[OBJETO_INDICE]->definirNumColunas(2); + mapa_tab_objetos[OBJETO_INDICE]->definirRotuloCabecalho(trUtf8("Nome"), 0); + mapa_tab_objetos[OBJETO_INDICE]->definirIconeCabecalho(QPixmap(":/icones/icones/column.png"),0); + mapa_tab_objetos[OBJETO_INDICE]->definirRotuloCabecalho(trUtf8("Indexação"), 1); + + configurarLayouFormulario(tabela_grid, OBJETO_TABELA); + janela_pai->setMinimumSize(550, 500); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(janela_pai->cancelar_btn,SIGNAL(clicked(bool)), this, SLOT(cancelarConfiguracao(void))); +} +//---------------------------------------------------------- +void TabelaWidget::hideEvent(QHideEvent *evento) +{ + map::iterator itr, itr_end; + Tabela *tab=dynamic_cast(this->objeto); + + aceita_oids_chk->setChecked(false); + atributos_tbw->setCurrentIndex(0); + tabs_ancestrais_lst->clear(); + tabs_copiadas_lst->clear(); + + //Varre o mapa de tabelas e remove as linhas de cada uma + itr=mapa_tab_objetos.begin(); + itr_end=mapa_tab_objetos.end(); + while(itr!=itr_end) + { + (itr->second)->blockSignals(true); + (itr->second)->removerLinhas(); + (itr->second)->blockSignals(false); + itr++; + } + + if(this->novo_obj && !tab->objetoModificado()) + this->cancelarConfiguracao(); + + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void TabelaWidget::exibirFormObjetoTabela(TipoObjetoBase tipo_obj) +{ + ObjetoTabela *objeto=NULL; + TabelaObjetosWidget *tab_obj=NULL; + Tabela *tabela=NULL; + + //Seleciona a tabela de objeto conforme o tipo passado + tab_obj=selecionarTabelaObjetos(tipo_obj); + + /* Caso haja um item selecionado na tabela, obtém a referência ao objeto + de tabela que ela representa */ + if(tab_obj->obterLinhaSelecionada()>=0) + objeto=reinterpret_cast(tab_obj->obterDadoLinha(tab_obj->obterLinhaSelecionada()).value()); + + //Obtém a referência a tabela que é dona do objeto a ser editado + tabela=dynamic_cast(this->objeto); + + //Exibe o formulário correto de acordo com o tipo de objeto de tabela + switch(tipo_obj) + { + case OBJETO_COLUNA: + coluna_wgt->definirAtributos(this->modelo, tabela, this->lista_op, dynamic_cast(objeto)); + coluna_wgt->show(); + break; + + case OBJETO_RESTRICAO: + restricao_wgt->definirAtributos(this->modelo, tabela, this->lista_op, dynamic_cast(objeto)); + restricao_wgt->show(); + break; + + case OBJETO_GATILHO: + gatilho_wgt->definirAtributos(this->modelo, tabela, this->lista_op, dynamic_cast(objeto)); + gatilho_wgt->show(); + break; + + case OBJETO_INDICE: + indice_wgt->definirAtributos(this->modelo, tabela, this->lista_op, dynamic_cast(objeto)); + indice_wgt->show(); + break; + + default: + case OBJETO_REGRA: + regra_wgt->definirAtributos(this->modelo, tabela, this->lista_op, dynamic_cast(objeto)); + regra_wgt->show(); + break; + } +} +//---------------------------------------------------------- +TabelaObjetosWidget *TabelaWidget::selecionarTabelaObjetos(TipoObjetoBase tipo_obj) +{ + if(mapa_tab_objetos.count(tipo_obj) > 0) + return(mapa_tab_objetos[tipo_obj]); + else + return(NULL); +} +//---------------------------------------------------------- +TipoObjetoBase TabelaWidget::selecionarTipoObjeto(QObject *tab_sender) +{ + TipoObjetoBase tipo_obj=OBJETO_BASE; + + if(tab_sender) + { + map::iterator itr, itr_end; + + /* Varre o mapa de tabelas caso o sender no parâmetro seja + igual a alguma tabela dentro do mapa retorna a chave + do mapa para a tabela encontrada */ + itr=mapa_tab_objetos.begin(); + itr_end=mapa_tab_objetos.end(); + + while(itr!=itr_end && tipo_obj==OBJETO_BASE) + { + if(itr->second==tab_sender) + tipo_obj=itr->first; + + itr++; + } + } + + return(tipo_obj); +} +//---------------------------------------------------------- +void TabelaWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Tabela *tabela, float pos_x, float pos_y) +{ + unsigned i, qtd; + TipoObjetoBase tipos[]={ OBJETO_COLUNA, OBJETO_RESTRICAO, OBJETO_GATILHO, + OBJETO_REGRA, OBJETO_INDICE }; + + /* Inicia o encademanento de operações, assim todo objeto editado dentro + da tabela será encadeado na lista, desta forma quando o usuário + necessitar desfazer as modificações da tabela, os objetos da + tabela também serão restaurados */ + lista_op->iniciarEncadeamentoOperacoes(); + qtd_operacoes=lista_op->obterTamanhoAtual(); + + if(!tabela) + { + QString nome; + + nome=trUtf8("nova_tabela"); + //Aloca o novo relacionamento + tabela=new Tabela; + tabela->definirNome(nome); + + /* Marca como novo objeto o relacionamento gerado, assim o mesmo é tratado + de forma diferente nos métodos de configuração da classe superior */ + this->novo_obj=true; + + //Adiciona o relacionamento criado à lista de operações + lista_op->adicionarObjeto(tabela, Operacao::OBJETO_CRIADO); + } + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, tabela, NULL, pos_x, pos_y); + + //Lista todos os objetos da tabela + for(i=0; i < 5; i++) + { + listarObjetos(tipos[i]); + + /* Caso o tipo atual seja um coluna ou restrição: + Desabilita (esconde) os botões de mover objetos na tabela + pois esta movimentação só pode ser feita antes da ligação de + relacionamentos à tabela */ + if(tipos[i]==OBJETO_COLUNA || tipos[i]==OBJETO_RESTRICAO) + { + if(this->novo_obj || !tabela->referenciaObjetoIncRelacao()) + mapa_tab_objetos[tipos[i]]->definirConfiguracaoBotoes(TabelaObjetosWidget::TODOS_BOTOES ^ + (TabelaObjetosWidget::BTN_ATUALIZAR_ITEM)); + else + mapa_tab_objetos[tipos[i]]->definirConfiguracaoBotoes(TabelaObjetosWidget::TODOS_BOTOES ^ + (TabelaObjetosWidget::BTN_ATUALIZAR_ITEM | + TabelaObjetosWidget::BTN_MOVER_ITENS)); + } + } + + //Lista a as tabelas ancestrais da tabela em edição + qtd=tabela->obterNumTabelasPai(); + for(i=0; i < qtd; i++) + tabs_ancestrais_lst->addItem(QString::fromUtf8(tabela->obterTabelaPai(i)->obterNome(true))); + + //Lista a as tabelas copiadas pela tabela em edição + qtd=tabela->obterNumTabelasCopia(); + for(i=0; i < qtd; i++) + tabs_copiadas_lst->addItem(QString::fromUtf8(tabela->obterTabelaCopia(i)->obterNome(true))); +} +//---------------------------------------------------------- +void TabelaWidget::listarObjetos(TipoObjetoBase tipo_obj) +{ + TabelaObjetosWidget *tab=NULL; + unsigned qtd, i; + Tabela *tabela=NULL; + + try + { + //Obtém a tabela de objetos referente ao tipo passado + tab=mapa_tab_objetos[tipo_obj]; + + //Obtém a referência à tabela em edição + tabela=dynamic_cast(this->objeto); + + //Remove as linhas da tabela antes da exibição dos elementos + tab->blockSignals(true); + tab->removerLinhas(); + + //Obtém a quantidade de elementos a serem exibidos + qtd=tabela->obterNumObjetos(tipo_obj); + for(i=0; i < qtd; i++) + { + //Adicionar uma linha + tab->adicionarLinha(); + //Exibe o objeto atual na linha atual da tabela + exibirDadosObjeto(dynamic_cast(tabela->obterObjeto(i, tipo_obj)), i); + } + tab->limparSelecao(); + tab->blockSignals(false); + + if(tipo_obj==OBJETO_COLUNA) + { + //Habilita o botão de inserção de restrições, gatilhos e índices somente quando há colunas na tabela + mapa_tab_objetos[OBJETO_RESTRICAO]->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, + mapa_tab_objetos[OBJETO_COLUNA]->obterNumLinhas() > 0); + mapa_tab_objetos[OBJETO_GATILHO]->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, + mapa_tab_objetos[OBJETO_COLUNA]->obterNumLinhas() > 0); + mapa_tab_objetos[OBJETO_INDICE]->habilitarBotoes(TabelaObjetosWidget::BTN_INSERIR_ITEM, + mapa_tab_objetos[OBJETO_COLUNA]->obterNumLinhas() > 0); + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void TabelaWidget::manipularObjeto(void) +{ + TipoObjetoBase tipo_obj; + + try + { + //Obtém o tipo de objetos referênte a tabela sender + tipo_obj=selecionarTipoObjeto(sender()); + + //Exibe o formulário de edição de objetos conforme o tipo do objeto obtido + exibirFormObjetoTabela(tipo_obj); + + //Atualiza a lista de objetos exibindo o objeto recém criado + listarObjetos(tipo_obj); + } + catch(Excecao &e) + { + listarObjetos(tipo_obj); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void TabelaWidget::exibirDadosObjeto(ObjetoTabela *objeto, int idx_lin) +{ + TabelaObjetosWidget *tab=NULL; + Coluna *coluna=NULL; + Restricao *restricao=NULL; + Gatilho *gatilho=NULL; + Regra *regra=NULL; + Indice *indice=NULL; + TipoObjetoBase tipo_obj; + QString str_aux, str_aux1, + vet_tipo_rest[]={ ~TipoRestricao(TipoRestricao::primary_key), ~TipoRestricao(TipoRestricao::foreign_key), + ~TipoRestricao(TipoRestricao::check), ~TipoRestricao(TipoRestricao::unique), + QString("NOT NULL") }, + + vet_cod_rest[]={ "pk", "fk", "ck", "uq", "nn"}; + QFont fonte; + unsigned i; + TipoEvento eventos[]={ TipoEvento::on_insert, + TipoEvento::on_delete, + TipoEvento::on_truncate, + TipoEvento::on_update }; + + tipo_obj=objeto->obterTipoObjeto(); + + //Obtém a tabela referênte ao tipo do objeto + tab=mapa_tab_objetos[tipo_obj]; + + //Coluna 0: Nome do objeto + tab->definirTextoCelula(QString::fromUtf8(objeto->obterNome()),idx_lin,0); + + /* Para cada tipo de objeto existe uma rotina + de exibição do objeto na respectiva tabela. */ + if(tipo_obj==OBJETO_COLUNA) + { + coluna=dynamic_cast(objeto); + //Coluna 1: Tipo da coluna + tab->definirTextoCelula(QString::fromUtf8(~coluna->obterTipo()),idx_lin,1); + + //Coluna 2: Valor padrão da coluna + str_aux=coluna->obterValorPadrao(); + if(str_aux.isEmpty()) str_aux="-"; + tab->definirTextoCelula(str_aux,idx_lin,2); + + //Coluna 3: Atributos da coluna (restrições a qual ela pertence) + str_aux=QString::fromUtf8(OGSubItemObjeto::obterStringRestricoes(coluna)); + for(i=0; i < 5; i++) + { + if(str_aux.indexOf(vet_cod_rest[i]) >= 0) + str_aux1+=vet_tipo_rest[i] + QString(", "); + } + + if(str_aux1.isEmpty()) str_aux1="-"; + else str_aux1.remove(str_aux1.size()-2, 2); + + tab->definirTextoCelula(str_aux1,idx_lin,3); + } + else if(tipo_obj==OBJETO_RESTRICAO) + { + restricao=dynamic_cast(objeto); + //Coluna 1: Tipo de comparação da restrição + tab->definirTextoCelula(~restricao->obterTipoComparacao(),idx_lin,1); + //Coluna 2: Tipo de ação ON UPDATE da restrição + tab->definirTextoCelula(~restricao->obterTipoAcao(false),idx_lin,2); + //Coluna 3: Tipo de ação ON UPDATE da restrição + tab->definirTextoCelula(~restricao->obterTipoAcao(true),idx_lin,3); + } + else if(tipo_obj==OBJETO_GATILHO) + { + gatilho=dynamic_cast(objeto); + //Coluna 2: Tipo de disparo do gatilho + tab->definirTextoCelula(~gatilho->obterTipoDisparo(),idx_lin,2); + + //Coluna 1: Tabela referenciada pelo gatilho + if(gatilho->obterTabReferenciada()) + tab->definirTextoCelula(QString::fromUtf8(gatilho->obterTabReferenciada()->obterNome(true)),idx_lin,1); + else + tab->definirTextoCelula(QString("-"),idx_lin,1); + + //Coluna 3: Eventos que disparam o gatilho + for(i=0; i < 4; i++) + { + if(gatilho->executaNoEvento(eventos[i])) + str_aux+=~eventos[i] + QString(", "); + } + str_aux.remove(str_aux.size()-2, 2); + tab->definirTextoCelula(str_aux ,idx_lin,3); + } + else if(tipo_obj==OBJETO_REGRA) + { + regra=dynamic_cast(objeto); + //Coluna 1: Tipo de execução da regra + tab->definirTextoCelula(~regra->obterTipoExecucao(),idx_lin,1); + //Coluna 2: Tipo de evento que dispara a regra + tab->definirTextoCelula(~regra->obterTipoEvento(),idx_lin,2); + } + else + { + indice=dynamic_cast(objeto); + //Coluna 1: Tipo de indexação do índice + tab->definirTextoCelula(~indice->obterTipoIndexacao(),idx_lin,1); + } + + /* Caso o objeto esteja protegido ou foi incluído por relacionamento + muda a coloração da linha para denotar o fato */ + if(objeto->incluidoPorRelacionamento() || objeto->objetoProtegido()) + { + fonte=tab->font(); + fonte.setItalic(true); + + if(objeto->objetoProtegido()) + tab->definirFonteLinha(idx_lin, fonte, COR_TEXTO_LIN_PROT, COR_FUNDO_LIN_PROT); + else + tab->definirFonteLinha(idx_lin, fonte, COR_TEXTO_LIN_INCREL, COR_FUNDO_LIN_INCREL); + } + + //Define como dado da linha o próprio objeto para facilitar referências ao mesmo + tab->definirDadoLinha(QVariant::fromValue(objeto), idx_lin); +} +//---------------------------------------------------------- +void TabelaWidget::removerObjetos(void) +{ + Tabela *tabela=NULL; + unsigned qtd, qtd_op=0, i; + ObjetoBase *objeto=NULL; + TipoObjetoBase tipo_obj; + + try + { + tabela=dynamic_cast(this->objeto); + tipo_obj=selecionarTipoObjeto(sender()); + qtd=tabela->obterNumObjetos(tipo_obj); + + /* Armazena a quantidade de operações antes da remoção de objetos. + Caso um erro seja gerado e a quantidade de operações na lista + seja diferente do valor na variável 'qtd_op' indica que operações + foram inseridas na lista e precisam ser removidas */ + qtd_op=lista_op->obterTamanhoAtual(); + + for(i=0; i < qtd; i++) + { + //Obtém o objeto da tabela + objeto=tabela->obterObjeto(0, tipo_obj); + + if(!objeto->objetoProtegido() && + !dynamic_cast(objeto)->incluidoPorRelacionamento()) + { + //Tenta removê-lo da tabela + tabela->removerObjeto(objeto); + + //Adiciona o objeto removido na lista de operações para ser restaurado se necessário + lista_op->adicionarObjeto(objeto, Operacao::OBJETO_REMOVIDO, 0, this->objeto); + } + else + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_REMOBJPROTEGIDO) + .arg(objeto->obterNome()) + .arg(objeto->obterNomeTipoObjeto()), + ERR_PGMODELERUI_REMOBJPROTEGIDO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + } + catch(Excecao &e) + { + /* Caso a quantidade de operações seja diferente da quantidade inicial + obtida antes da remoção dos objetos */ + if(qtd_op < lista_op->obterTamanhoAtual()) + { + //Obtém a quantidade de operações que necessitam ser removidas + qtd=lista_op->obterTamanhoAtual()-qtd_op; + + /* Anula o encadeamento de operações para que as mesmas seja + desfeitas uma a uma ignorando o encadeamento */ + lista_op->anularEncadeamentoOperacoes(true); + + /* Desfaz as operações na quantidade calculada e remove a + operação da lista */ + for(i=0; i < qtd; i++) + { + lista_op->desfazerOperacao(); + lista_op->removerUltimaOperacao(); + } + + //Desfaz a anulação do encadeamento + lista_op->anularEncadeamentoOperacoes(false); + } + + //Atualiza a lista de objeto da tabela + listarObjetos(tipo_obj); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void TabelaWidget::removerObjeto(int idx_lin) +{ + Tabela *tabela=NULL; + ObjetoBase *objeto=NULL; + TipoObjetoBase tipo_obj; + + try + { + tabela=dynamic_cast(this->objeto); + tipo_obj=selecionarTipoObjeto(sender()); + + //Obtém o objeto da tabela + objeto=tabela->obterObjeto(idx_lin, tipo_obj); + + if(!objeto->objetoProtegido() && + !dynamic_cast(objeto)->incluidoPorRelacionamento()) + { + //Tenta removê-lo da tabela + tabela->removerObjeto(objeto); + + //Adiciona o objeto removido na lista de operações para ser restaurado se necessário + lista_op->adicionarObjeto(objeto, Operacao::OBJETO_REMOVIDO, idx_lin, this->objeto); + } + else + throw Excecao(Excecao::obterMensagemErro(ERR_PGMODELERUI_REMOBJPROTEGIDO) + .arg(objeto->obterNome()) + .arg(objeto->obterNomeTipoObjeto()), + ERR_PGMODELERUI_REMOBJPROTEGIDO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + } + catch(Excecao &e) + { + //Atualiza a lista de objeto da tabela + listarObjetos(tipo_obj); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void TabelaWidget::TabelaWidget::moverObjetos(int idx1, int idx2) +{ + TipoObjetoBase tipo_obj; + Tabela *tabela=NULL; + + try + { + tipo_obj=selecionarTipoObjeto(sender()); + tabela=dynamic_cast(this->objeto); + lista_op->atualizarIndiceObjeto(tabela->obterObjeto(idx1, tipo_obj), idx2); + lista_op->atualizarIndiceObjeto(tabela->obterObjeto(idx2, tipo_obj), idx1); + tabela->trocarIndicesObjetos(tipo_obj, idx1, idx2); + } + catch(Excecao &e) + { + //Atualiza a lista de objeto do relacionamento + listarObjetos(tipo_obj); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void TabelaWidget::aplicarConfiguracao(void) +{ + try + { + Tabela *tabela=NULL; + + if(!this->novo_obj) + { + //Adiciona o relacionamento à lista de operações antes de ser modificado + lista_op->adicionarObjeto(this->objeto, Operacao::OBJETO_MODIFICADO); + } + + tabela=dynamic_cast(this->objeto); + tabela->definirAceitaOids(aceita_oids_chk->isChecked()); + + //Aplica as configurações básicas + ObjetoBaseWidget::aplicarConfiguracao(); + + try + { + if(modelo->obterRelacionamento(tabela, NULL)) + /* Faz a validação dos relacionamentos para refletir a nova configuração + da tabela */ + modelo->validarRelacionamentos(); + } + catch(Excecao &e) + { + /* O único erro que é desconsiderado é o de invalidação de objetos, pois, + mesmo com a restauração do estado original da tabela estes + objetos não são recuperados */ + if(e.obterTipoErro()==ERR_PGMODELER_REFCOLUNAINVTABELA) + //Exibe uma mensagem de erro com o conteúdo da exceção + caixa_msg->show(e); + //Para os demais erros a exceção é encaminhada + else + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + + //Finaliza o encademanto de operações aberto + lista_op->finalizarEncadeamentoOperacoes(); + + //Finaliza a configuração da tabela + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + lista_op->anularEncadeamentoOperacoes(true); + this->cancelarConfiguracao(); + lista_op->anularEncadeamentoOperacoes(false); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void TabelaWidget::cancelarConfiguracao(void) +{ + if(lista_op->encadeamentoIniciado()) + lista_op->finalizarEncadeamentoOperacoes(); + + //Caso a lista de operações sofreu modificações + if(qtd_operacoes < lista_op->obterTamanhoAtual()) + /* Executa o cancelamento da configuração e remove as operações + adicionadas durante a edição da tabela */ + ObjetoBaseWidget::cancelarConfiguracao(); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/tabelawidget.h b/libpgmodeler_ui/src/tabelawidget.h new file mode 100644 index 000000000..ef410364f --- /dev/null +++ b/libpgmodeler_ui/src/tabelawidget.h @@ -0,0 +1,82 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: RestricaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de tabela. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef TABELA_WIDGET_H +#define TABELA_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_tabelawidget.h" +#include "tabelaobjetoswidget.h" +#include "ogtabela.h" +//*********************************************************** +class TabelaWidget: public ObjetoBaseWidget, public Ui::TabelaWidget { + Q_OBJECT + + private: + /* Quantidade de elementos na lista de operações antes da tabela + ser editada. Este atributo é usado para se saber, em caso de cancelamento + da edição da tabela, a quantidade de operações relacionadas ao + objeto que necessitam ser removidas. Vide: cancelarConfiguracao() */ + unsigned qtd_operacoes; + + //Armazena as tabelas de objetos filhos da tabela (colunas, restrições, índices, etc) + map mapa_tab_objetos; + + /* Lista os objetos do relacionamento na tabela respectiva, de acordo + com o tipo do objeto passado */ + void listarObjetos(TipoObjetoBase tipo_obj); + + //Exibe os dados de um objeto do relacionamento na lista específica de sua tabela + void exibirDadosObjeto(ObjetoTabela *objeto, int idx_lin); + + //Seleciona a tabela de objetos de acordo com o tipo passado + TabelaObjetosWidget *selecionarTabelaObjetos(TipoObjetoBase tipo_obj); + + //Seleciona o tipo de objeto de acordo com o objeto sender informado + TipoObjetoBase selecionarTipoObjeto(QObject *tab_sender); + + //Exibe o formulário de edição de objetos de tabela conforme o tipo passado + void exibirFormObjetoTabela(TipoObjetoBase tipo_obj); + + public: + TabelaWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Tabela *tabela, float pos_x, float pos_y); + + private slots: + void hideEvent(QHideEvent *); + + //Adiciona ou edita um objeto da tabela a qual aciona o método + void manipularObjeto(void); + //Remove um objeto selecionado na tabela a qual aciona o método + void removerObjeto(int idx_lin); + //Remove todos os objetos da tabela a qual aciona o método + void removerObjetos(void); + //Faz a movimentação entre dois objetos da tabela + void moverObjetos(int idx1, int idx2); + + public slots: + void aplicarConfiguracao(void); + void cancelarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/tipopgsqlwidget.cpp b/libpgmodeler_ui/src/tipopgsqlwidget.cpp new file mode 100644 index 000000000..7d6bf02a8 --- /dev/null +++ b/libpgmodeler_ui/src/tipopgsqlwidget.cpp @@ -0,0 +1,195 @@ +#include "tipopgsqlwidget.h" +//*********************************************************** +TipoPgSQLWidget::TipoPgSQLWidget(QWidget *parent, const QString &rotulo) : QWidget(parent) +{ + try + { + QStringList tipo_interv; + + setupUi(this); + + if(!rotulo.isEmpty()) + groupBox->setTitle(rotulo); + + this->setWindowTitle(groupBox->title()); + + //Aloca um destacador de código fonte para o campo de formato do tipo + destaque_fmt=NULL; + destaque_fmt=new DestaqueSintaxe(formato_txt, false); + + //A configuração padrão carregada é a de destaque de código SQL + destaque_fmt->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + //Configura o combo de tipos de intervalo + TipoIntervalo::obterTipos(tipo_interv); + tipo_interv_cmb->addItem(""); + tipo_interv_cmb->addItems(tipo_interv); + + //Conecta os objetos do formulário com o método de atualização do formato do tipo + connect(tipo_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(atualizarFormatoTipo(void))); + connect(precisao_sb, SIGNAL(valueChanged(int)), this, SLOT(atualizarFormatoTipo(void))); + connect(comprimento_sb, SIGNAL(valueChanged(int)), this, SLOT(atualizarFormatoTipo(void))); + connect(dimensao_sb, SIGNAL(valueChanged(int)), this, SLOT(atualizarFormatoTipo(void))); + connect(tipo_interv_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(atualizarFormatoTipo(void))); + connect(timezone_chk, SIGNAL(toggled(bool)), this, SLOT(atualizarFormatoTipo(void))); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void TipoPgSQLWidget::atualizarFormatoTipo(void) +{ + try + { + QVariant dado; + + //Obtém o índice relacionado ao tipo de dados selecionado no combo + dado=tipo_cmb->itemData(tipo_cmb->currentIndex()); + + /* Caso o índice seja 0 indica que o tipo é uma tipo built-in do postgresql + não devendo ser tratado como um tipo definido pelo usuário */ + if(dado.toUInt()==0) + tipo=tipo_cmb->currentText(); + else + //Caso o índice seja superior a zero trata-se de um tipo definido pelo usuário + tipo=dado.toUInt(); + + /* O campo de comprimento só deve ser ativado quando o tipo de + dado é de comprimento variável: varchar, char, varbit, etc */ + comprimento_sb->setEnabled(tipo.tipoCompVariavel()); + + //O campo de timezone só deve ser ativado quando se tratar de um tipo relacionado a tempo + timezone_chk->setVisible(tipo=="timestamp" || tipo=="time"); + timezone_lbl->setVisible(timezone_chk->isVisible()); + + //O campo de precisão só é ativado quando o tipo em questão aceita precisão + precisao_sb->setEnabled(tipo.tipoAceitaPrecisao()); + + //O campo de dimensão só é ativado quando o tipo não é void + dimensao_sb->setEnabled(tipo!="void"); + + /* O campo de intervalo só é ativado quando o tipo é 'interval' (o único + que aceita esse dado) */ + tipo_interv_cmb->setVisible(tipo=="interval"); + tipo_interv_lbl->setVisible(tipo_interv_cmb->isVisible()); + + //Configura o tipo com os valores do formulário + tipo.definirComprimento(comprimento_sb->value()); + tipo.definirPrecisao(precisao_sb->value()); + tipo.definirDimensao(dimensao_sb->value()); + tipo.definirTipoIntervalo(tipo_interv_cmb->currentText()); + tipo.definirComTimezone(timezone_chk->isChecked()); + + //Atualiza o formato do tipo exibido no campo + formato_txt->setPlainText(QString::fromUtf8(*tipo)); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +void TipoPgSQLWidget::obterTiposPgSQL(QComboBox *combo, ModeloBD *modelo, bool tipo_usr, bool dominio, bool tipo_oid, bool pseudo) +{ + if(combo) + { + QStringList tipos; + int idx, qtd; + + combo->clear(); + + if(tipo_usr) + { + //Obtém os tipo definidos pelo usuário e insere ao combo de tipo + TipoPgSQL::obterTiposUsuario(tipos,modelo,true,false); + tipos.sort(); + qtd=tipos.size(); + + /* Adiciona cada indice referente ao tipo como dado do elemento do combobox + para se referenciar de forma mais direta o tipo definido pelo usuário */ + for(idx=0; idx < qtd; idx++) + combo->addItem(QString::fromUtf8(tipos[idx]), QVariant(TipoPgSQL::obterIndiceTipoUsuario(tipos[idx],NULL,modelo))); + } + + if(dominio) + { + //Obtém os domínios definidos pelo usuário e insere ao combo de tipo + TipoPgSQL::obterTiposUsuario(tipos,modelo,false,true); + tipos.sort(); + qtd=tipos.size(); + + /* Adiciona cada índice referente ao tipo como dado do elemento do combobox + para se referenciar de forma mais direta o tipo definido pelo usuário */ + for(idx=0; idx < qtd; idx++) + combo->addItem(QString::fromUtf8(tipos[idx]), QVariant(TipoPgSQL::obterIndiceTipoUsuario(tipos[idx],NULL,modelo))); + } + + /* Obtendo os demais tipos (builtin) do PostgreSQL. Neste caso, por serem tipos + de fácil acesso não é necessário armazena os índices dos mesmos como + acontece com os tipos definidos pelo usuário */ + TipoPgSQL::obterTipos(tipos, tipo_oid, pseudo); + tipos.sort(); + combo->addItems(tipos); + } +} +//----------------------------------------------------------- +void TipoPgSQLWidget::definirAtributos(TipoPgSQL tipo, ModeloBD *modelo, bool tipo_usr, bool dominio, bool tipo_oid, bool pseudo) +{ + try + { + int idx; + + /* Bloqueia os sinais que são emitidos pelo combo de tipo + para evitar a atualização desnecessária do formato do tipo + pois o método de obtenção dos tipos obterTiposPgSQL() limpa + automaticamente o combo e isso evita que erros sejam disparados */ + tipo_cmb->blockSignals(true); + + //Obtém os tipos PgSQL + obterTiposPgSQL(tipo_cmb, modelo, tipo_usr, dominio, tipo_oid, pseudo); + + //Reativa os sinais do combo de tipos + tipo_cmb->blockSignals(false); + + /* Obtém o índice do tipo no combo de tipos de acordo com o tipo de dados + passado no parâmetro */ + idx=tipo_cmb->findText(~tipo); + + //Seleciona o tipo no combobox + tipo_cmb->setCurrentIndex(idx); + + /* Configura os campos do formulário com os respectivos valores + configurados no tipo de dado passado ao método */ + precisao_sb->setValue(tipo.obterPrecisao()); + dimensao_sb->setValue(tipo.obterDimensao()); + comprimento_sb->setValue(tipo.obterComprimento()); + + idx=tipo_interv_cmb->findText(~(tipo.obterTipoIntervalo())); + tipo_interv_cmb->setCurrentIndex(idx); + + timezone_chk->setChecked(tipo.comTimezone()); + + /* Atribui o tipo do parâmetro ao tipo de dado configurado + pelo formulário o qual é retornado ao usuário */ + this->tipo=tipo; + + //Atualiza a exibição do formato do tipo configurado + atualizarFormatoTipo(); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//----------------------------------------------------------- +TipoPgSQL TipoPgSQLWidget::obterTipoPgSQL(void) +{ + return(tipo); +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/tipopgsqlwidget.h b/libpgmodeler_ui/src/tipopgsqlwidget.h new file mode 100644 index 000000000..b397d22ff --- /dev/null +++ b/libpgmodeler_ui/src/tipopgsqlwidget.h @@ -0,0 +1,70 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: TipoPgSQLWidget +# Descrição: Definição da classe que implementa o formulário de +# edição de tipos nativos do PostgreSQL. Este formulário +# é compartilhado por vários outros por isso a necessidade +# de se criar esta classe com esse fim específico evitando +# a redundância de código e de objetos gráficos. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef TIPOPGSQL_WIDGET_H +#define TIPOPGSQL_WIDGET_H + +#include +#include "ui_tipopgsqlwidget.h" +#include "tipospgsql.h" +#include "destaquesintaxe.h" +#include "modelobd.h" +//*********************************************************** +class TipoPgSQLWidget: public QWidget, public Ui::TipoPgSQLWidget { + Q_OBJECT + + private: + //Tipo configurado pelo formulário + TipoPgSQL tipo; + + //Destacador de sintaxe usado para destacar o formato do tipo + DestaqueSintaxe *destaque_fmt; + + public: + TipoPgSQLWidget(QWidget * parent = 0, const QString &rotulo=""); + + /* Método utilitário disponibilizado para as demais classes o qual + obtém a lista de tipos do modelo em questão dando a possiblidade + de quais tipos obter */ + static void obterTiposPgSQL(QComboBox *combo, ModeloBD *modelo, + bool tipo_usr=true, bool dominio=true, + bool tipo_oid=true, bool pseudo=true); + + private slots: + /* Atualiza o formato do tipo à medida que os campos + do formulário são modificados */ + void atualizarFormatoTipo(void); + + public slots: + void definirAtributos(TipoPgSQL tipo, ModeloBD *modelo, + bool tipo_usr=true, bool dominio=true, + bool tipo_oid=true, bool pseudo=true); + + //Obtém o tipo configurado no formulário + TipoPgSQL obterTipoPgSQL(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/tipowidget.cpp b/libpgmodeler_ui/src/tipowidget.cpp new file mode 100644 index 000000000..5f29fc23c --- /dev/null +++ b/libpgmodeler_ui/src/tipowidget.cpp @@ -0,0 +1,423 @@ +#include "tipowidget.h" +#include "parametrowidget.h" + +extern ParametroWidget *parametro_wgt; +//*********************************************************** +TipoWidget::TipoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_TIPO) +{ + try + { + QGridLayout *grid=NULL; + QFrame *frame=NULL; + QSpacerItem *spacer=NULL; + map > mapa_campos; + QStringList lista; + unsigned i; + + Ui_TipoWidget::setupUi(this); + configurarLayouFormulario(tipo_grid, OBJETO_TIPO); + + //Aloca os widgets de configuração de tipos + tipo_copia=NULL; + tipo_copia=new TipoPgSQLWidget(this, trUtf8("Tipo Cópia")); + tipo_elemento=NULL; + tipo_elemento=new TipoPgSQLWidget(this, trUtf8("Tipo Elemento")); + + //Cria um layout e insere os widgets de tipo + grid=dynamic_cast(atrib_base_twg->widget(0)->layout()); + spacer=new QSpacerItem(20, 1, QSizePolicy::Minimum, QSizePolicy::Expanding); + grid->addWidget(tipo_copia,6,0,1,0); + grid->addWidget(tipo_elemento,7,0,1,0); + grid->addItem(spacer,8,0); + + //Aloca os seletores de funções e os insere do layout da aba de funções + grid=dynamic_cast(atrib_base_twg->widget(1)->layout()); + for(i=Tipo::FUNCAO_INPUT; i <= Tipo::FUNCAO_ANALYZE; i++) + { + sel_funcoes[i]=NULL; + sel_funcoes[i]=new SeletorObjetoWidget(OBJETO_FUNCAO, true, this); + grid->addWidget(sel_funcoes[i],i,1,1,1); + } + + //Aloca a tabela de enumerações e a insere no layout do grupo de atributos de enumerações + tab_enumeracoes=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + TabelaObjetosWidget::BTN_EDITAR_ITEM, false, this); + grid=dynamic_cast(enumeracoes_gb->layout()); + grid->addWidget(tab_enumeracoes,1,0,1,2); + enumeracoes_gb->setVisible(false); + + //Aloca a tabela de atributos e a insere no layout do grupo de atributos de tipo composto + tab_atributos=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES ^ + TabelaObjetosWidget::BTN_ATUALIZAR_ITEM, false, this); + tab_atributos->definirNumColunas(2); + tab_atributos->definirRotuloCabecalho(trUtf8("Nome"),0); + tab_atributos->definirIconeCabecalho(QPixmap(":/icones/icones/uid.png"),0); + tab_atributos->definirRotuloCabecalho(trUtf8("Tipo"),1); + tab_atributos->definirIconeCabecalho(QPixmap(":/icones/icones/usertype.png"),1); + + grid=new QGridLayout; + grid->setContentsMargins(2,2,2,2); + grid->addWidget(tab_atributos,0,0); + atributos_gb->setLayout(grid); + atributos_gb->setVisible(false); + + //Configura um alerta de versão com os campos específicos das versões + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_83)].push_back(enumeracao_rb); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(categoria_lbl); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(preferido_lbl); + mapa_campos[gerarIntervaloVersoes(APOS_VERSAO, ParserEsquema::VERSAO_PGSQL_84)].push_back(tipo_copia); + frame=gerarFrameAlertaVersao(mapa_campos); + tipo_grid->addWidget(frame, tipo_grid->count()+1, 0, 1, 0); + frame->setParent(this); + + //Gera o frame de informação + grid=dynamic_cast(atrib_base_twg->widget(1)->layout()); + frame=gerarFrameInformacao(trUtf8("As funções a serem atribuídas ao tipo devem ser todas escritas em linguagem C e possuirem, respectivamente, as seguintes assinaturas:
\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
INPUT: any funcao(cstring, oid, integer)OUTPUT: cstring funcao(any)
SEND: byta funcao(any)RECV: any funcao(internal, oid, integer)
TPMOD_IN: integer funcao(cstring[])TPMOD_OUT: cstring funcao(integer)
ANALYZE: boolean funcao(internal)
")); + grid->addWidget(frame, grid->count()+1, 0, 1, 0); + frame->setParent(atrib_base_twg->widget(1)); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(tipo_base_rb, SIGNAL(toggled(bool)), this, SLOT(selecionarConfiguracaoTipo(void))); + connect(composto_rb, SIGNAL(toggled(bool)), this, SLOT(selecionarConfiguracaoTipo(void))); + connect(enumeracao_rb, SIGNAL(toggled(bool)), this, SLOT(selecionarConfiguracaoTipo(void))); + + connect(tab_enumeracoes, SIGNAL(s_linhaAdicionada(int)), this, SLOT(manipularEnumeracao(int))); + connect(tab_enumeracoes, SIGNAL(s_linhaAtualizada(int)), this, SLOT(manipularEnumeracao(int))); + + connect(tab_atributos, SIGNAL(s_linhaAdicionada(int)), this, SLOT(exibirFormAtributo(void))); + connect(tab_atributos, SIGNAL(s_linhaEditada(int)), this, SLOT(exibirFormAtributo(void))); + + janela_pai->setMinimumSize(580, 680); + + //Preenche o combo box com os tipos de armazenamento disponíveis + TipoArmazenamento::obterTipos(lista); + armazenamento_cmb->addItems(lista); + + //Preenche o combo box com os tipos de categoria disponíveis + TipoCategoria::obterTipos(lista); + categoria_cmb->addItems(lista); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +/*TipoWidget::~TipoWidget(void) +{ + for(unsigned i=Tipo::FUNCAO_INPUT; i <= Tipo::FUNCAO_ANALYZE; i++) + if(sel_funcoes[i]) delete(sel_funcoes[i]); + + if(tab_enumeracoes) delete(tab_enumeracoes); + if(tab_atributos) delete(tab_atributos); + if(tipo_copia) delete(tipo_copia); + if(tipo_elemento) delete(tipo_elemento); +} */ +//---------------------------------------------------------- +void TipoWidget::hideEvent(QHideEvent *evento) +{ + //Limpa as tabelas + tab_enumeracoes->removerLinhas(); + tab_atributos->removerLinhas(); + + //Limpa os valores dos seletores de funções + for(unsigned i=Tipo::FUNCAO_INPUT; i <= Tipo::FUNCAO_ANALYZE; i++) + sel_funcoes[i]->removerObjetoSelecionado(); + + //Reinicia os demais campos do formulário para seus valores padrão + tipo_base_rb->setChecked(true); + comp_int_sb->setValue(0); + por_valor_chk->setChecked(false); + preferido_chk->setChecked(false); + delimitador_edt->clear(); + valor_padrao_edt->clear();; + categoria_cmb->setCurrentIndex(0); + armazenamento_cmb->setCurrentIndex(0); + alinhamento_cmb->setCurrentIndex(0); + atrib_base_twg->setCurrentIndex(0); + + /* Desconecta todos os slots ligados ao formulário + de configuração de parâmetro, permitindo que esse possa + ser usado por outros formulários sem disparar os slots + da classe atual */ + disconnect(parametro_wgt,NULL,this,NULL); + + //Executa o método que trata o evento de esconder da classe superior + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void TipoWidget::selecionarConfiguracaoTipo(void) +{ + atrib_base_twg->setVisible(tipo_base_rb->isChecked()); + enumeracoes_gb->setVisible(enumeracao_rb->isChecked()); + atributos_gb->setVisible(composto_rb->isChecked()); +} +//---------------------------------------------------------- +void TipoWidget::manipularEnumeracao(int idx_linha) +{ + //Caso o nome da enumeração esteja preenchido + if(!nome_enum_edt->text().isEmpty()) + { + //Insere o nome na tabela e limpa o campo de nome + tab_enumeracoes->definirTextoCelula(nome_enum_edt->text(), idx_linha, 0); + nome_enum_edt->clear(); + } + //Caso o nome esteja vazio mas o usuário tente inserir mesmo assim + else if(tab_enumeracoes->obterTextoCelula(idx_linha, 0).isEmpty()) + /* Remove a linha inserido para que a tabela não fique com + uma linha em branco */ + tab_enumeracoes->removerLinha(idx_linha); +} +//---------------------------------------------------------- +void TipoWidget::manipularAtributo(int res) +{ + int lin; + Parametro param; + + //Obtém a linha selecionada da tabela. + lin=tab_atributos->obterLinhaSelecionada(); + + //Caso o usuário clique no botão 'aplicar' da janela de conf. de parâmetro + if(res==QDialog::Accepted) + { + //Obtém o parâmetro configurado + param=parametro_wgt->obterParametro(); + //Insere-o na tabela de atributos + tab_atributos->definirTextoCelula(QString::fromUtf8(param.obterNome()), lin, 0); + tab_atributos->definirTextoCelula(QString::fromUtf8(*param.obterTipo()), lin, 1); + tab_atributos->definirDadoLinha(QVariant::fromValue(param), lin); + } + //Caso o usuário clique no botão 'cancelar' da janela de conf. de parâmetro + else if(res==QDialog::Rejected) + { + //Remove a última linha da tabela quando se tratar de adição de novo parâmetro + if(tab_atributos->obterTextoCelula(lin,0).isEmpty()) + tab_atributos->removerLinha(lin); + } +} +//---------------------------------------------------------- +void TipoWidget::exibirFormAtributo(void) +{ + int idx_lin; + + /* Desabilita alguns campos do formulário de parâmetro + pois os campos desabilitados não são se aplicam + ao atributos de um tipo */ + parametro_wgt->param_in_chk->setEnabled(false); + parametro_wgt->param_out_chk->setEnabled(false); + parametro_wgt->valorpadrao_edt->setEnabled(false); + + //Obtém a linha selecionada na tabela + idx_lin=tab_atributos->obterLinhaSelecionada(); + + //Caso haja uma linha selecionada + if(idx_lin >= 0) + /* Preenche o formulário de edição de parâmetros com os dados do atributo + especificado na linha selecionada */ + parametro_wgt->definirAtributos(tab_atributos->obterDadoLinha(idx_lin).value(), this->modelo); + + parametro_wgt->show(); +} +//---------------------------------------------------------- +void TipoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Tipo *tipo) +{ + TipoPgSQL tp_copia, tp_elem; + unsigned conf_tipo, i, qtd; + Parametro param; + + //Conecta o método de manipulação de atributos ao formulário de parâmetros + connect(parametro_wgt, SIGNAL(finished(int)), this, SLOT(manipularAtributo(int))); + + //Define os atributos do formulários e da janela pai + ObjetoBaseWidget::definirAtributos(modelo, lista_op, tipo); + + //Define o modelo de dados de referência dos seletores de função + for(i=Tipo::FUNCAO_INPUT; i <= Tipo::FUNCAO_ANALYZE; i++) + sel_funcoes[i]->definirModelo(modelo); + + //Caso o tipo esteja especificado + if(tipo) + { + //Obtém a configuração do mesmo + conf_tipo=tipo->obterConfiguracao(); + + //Caso o tipo seja composto + if(conf_tipo==Tipo::TIPO_COMPOSTO) + { + //Marca o radiobox no formulário que indica o tipo composto + composto_rb->setChecked(true); + + /* Desabilita os sinais da tabela de atributos para inserção + de todos os atributos do tipo sem disparar sinais e executar slots */ + tab_atributos->blockSignals(true); + + //Obtém a quantidade de atributos do tipo + qtd=tipo->obterNumAtributos(); + + /* Preenche a tabela de atributos, obtendo cada um e + exibindo os dados na tabela */ + for(i=0; i < qtd; i++) + { + //Adiciona uma linha na tabela + tab_atributos->adicionarLinha(); + //Obtém um atributo do tipo + param=tipo->obterAtributo(i); + //Exibe os dados do atributo na tabela + tab_atributos->definirTextoCelula(QString::fromUtf8(param.obterNome()), i, 0); + tab_atributos->definirTextoCelula(QString::fromUtf8(*param.obterTipo()), i, 1); + //Armazena o próprio atributo na linha da tabela + tab_atributos->definirDadoLinha(QVariant::fromValue(param), i); + } + + //Desbloqueia os sinais da tabela de atributos + tab_atributos->blockSignals(false); + //Limpa a seleção da tabela + tab_atributos->limparSelecao(); + } + //Caso o tipo seja enumeração + else if(conf_tipo==Tipo::TIPO_ENUMERACAO) + { + //Marca o campo respectivo no formulário + enumeracao_rb->setChecked(true); + + /* Desabilita os sinais da tabela de enumerações para inserção + de todos as enumerações do tipo sem disparar sinais e executar slots */ + tab_enumeracoes->blockSignals(true); + qtd=tipo->obterNumEnumeracoes(); + + //Insere todos as enumerações do tipo na tabela + for(i=0; i < qtd; i++) + { + tab_enumeracoes->adicionarLinha(); + tab_enumeracoes->definirTextoCelula(tipo->obterEnumeracao(i), i, 0); + } + //Desbloqueia os sinais da tabela de enumerações + tab_enumeracoes->blockSignals(false); + tab_enumeracoes->limparSelecao(); + } + //Caso o tipo seja base + else + { + //Marca o radiobox no formulário que indica o tipo base + tipo_base_rb->setChecked(true); + + //Obtém o tipo cópia do tipo + tp_copia=tipo->obterTipoCopia(); + //Obtém o tipo de elemento do tipo + tp_elem=tipo->obterElemento(); + + /* Configura os campos do formulário relacionados ao tipo base + com os valores definidos na instância de tipo passada */ + comp_int_sb->setValue(tipo->obterCompInterno()); + por_valor_chk->setChecked(tipo->passadoPorValor()); + preferido_chk->setChecked(tipo->tipoPreferido()); + delimitador_edt->setText(QString(tipo->obterDelimitador())); + valor_padrao_edt->setText(QString::fromUtf8(tipo->obterValorPadrao())); + categoria_cmb->setCurrentIndex(categoria_cmb->findText(~tipo->obterCategoria())); + armazenamento_cmb->setCurrentIndex(armazenamento_cmb->findText(~tipo->obterArmazenamento())); + alinhamento_cmb->setCurrentIndex(alinhamento_cmb->findText(~tipo->obterAlinhamento())); + + //Atribui aos seletores de funções todas as funções configuradas na instância + for(i=Tipo::FUNCAO_INPUT; i <= Tipo::FUNCAO_ANALYZE; i++) + sel_funcoes[i]->definirObjeto(tipo->obterFuncao(i)); + } + } + + //Configura o widget de tipo de cópia com o tipo obtido da instância de tipo + tipo_copia->definirAtributos(tp_copia, modelo); + //Configura o widget de tipo de elemento com o tipo obtido da instância de tipo + tipo_elemento->definirAtributos(tp_elem, modelo); +} +//---------------------------------------------------------- +void TipoWidget::aplicarConfiguracao(void) +{ + try + { + Tipo *tipo=NULL; + unsigned i, qtd; + + iniciarConfiguracao(); + + //Obtém a referência ao tipo que está sendo configurado + tipo=dynamic_cast(this->objeto); + + //Caso o mesmo seja marcado como uma enumeração no formulário + if(enumeracao_rb->isChecked()) + { + //Configura a instância como tipo enumeração + tipo->definirConfiguracao(Tipo::TIPO_ENUMERACAO); + //Remove todas as enumerações atuais do tipo + tipo->removerEnumeracoes(); + + //Insere na instância de tipo as enumerações configuradas no formulário + qtd=tab_enumeracoes->obterNumLinhas(); + for(i=0; i < qtd; i++) + tipo->adicionarEnumeracao(tab_enumeracoes->obterTextoCelula(i,0)); + } + //Caso o mesmo seja marcado como um tipo composto no formulário + else if(composto_rb->isChecked()) + { + //Configura a instância como tipo composto + tipo->definirConfiguracao(Tipo::TIPO_COMPOSTO); + //Remove todos os atributos do tipo + tipo->removerAtributos(); + + //Insere na instância de tipo os atributos configurados no formulário + qtd=tab_atributos->obterNumLinhas(); + for(i=0; i < qtd; i++) + tipo->adicionarAtributo(tab_atributos->obterDadoLinha(i).value()); + } + //Caso o mesmo seja marcado como um tipo base no formulário + else + { + //Configura a instância como tipo base + tipo->definirConfiguracao(Tipo::TIPO_BASE); + + //Atribui todos os valores configurados no formulário à instância de tipo + tipo->definirTipoCopia(tipo_copia->obterTipoPgSQL()); + tipo->definirElemento(tipo_elemento->obterTipoPgSQL()); + tipo->definirCompInterno(comp_int_sb->value()); + tipo->definirPorValor(por_valor_chk->isChecked()); + tipo->definirPreferido(preferido_chk->isChecked()); + tipo->definirDelimitador(delimitador_edt->text().at(0).toAscii()); + tipo->definirValorPadrao(valor_padrao_edt->text()); + tipo->definirCategoria(TipoCategoria(categoria_cmb->currentText())); + tipo->definirAlinhamento(TipoPgSQL(alinhamento_cmb->currentText())); + tipo->definirArmazenamento(TipoArmazenamento(armazenamento_cmb->currentText())); + + //Atribui todas as funções definidas nos seletores à instância de tipo + for(i=Tipo::FUNCAO_INPUT; i <= Tipo::FUNCAO_ANALYZE; i++) + tipo->definirFuncao(i, dynamic_cast(sel_funcoes[i]->obterObjeto())); + } + + ObjetoBaseWidget::aplicarConfiguracao(); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/tipowidget.h b/libpgmodeler_ui/src/tipowidget.h new file mode 100644 index 000000000..87fc5ab7a --- /dev/null +++ b/libpgmodeler_ui/src/tipowidget.h @@ -0,0 +1,81 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: TipoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de tipos definidos pelo usuário. +# +# Copyleft 2006-2012 - Raphael Araújo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef TIPO_WIDGET_H +#define TIPO_WIDGET_H + +#include "objetobasewidget.h" +#include "ui_tipowidget.h" +#include "tipopgsqlwidget.h" +#include "tabelaobjetoswidget.h" + +/* Declarando a classe Parametro como metatype para que esta + possa ser usada em conjunto com a classe QVariant (vide documentação + da classe QVariant e QMetaType). Esta declaração é uma macro específica + do Qt e está sendo usada para facilitar o uso com classes que necessitam + armazenar instancias de classes em seus containeres (TabelaObjetosWidget). + Essa declaração não afeta o comportamento das demais classes que de algum + modo referenciam a classe Parametro.*/ +#include +Q_DECLARE_METATYPE(Parametro) +//*********************************************************** +class TipoWidget: public ObjetoBaseWidget, public Ui::TipoWidget { + Q_OBJECT + + private: + //Widgets seletores de funções do tipo + SeletorObjetoWidget *sel_funcoes[7]; + + //Widgets de configuração de tipo cópia e tipo de elemento + TipoPgSQLWidget *tipo_copia, + *tipo_elemento; + + //Tabelas para armazenamento das enumerações e atributos de tipos compostos + TabelaObjetosWidget *tab_enumeracoes, + *tab_atributos; + + public: + TipoWidget(QWidget * parent = 0); + //~TipoWidget(void); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Tipo *tipo); + + private slots: + void hideEvent(QHideEvent *); + + /* Manipula o formulário exibindo os campos de acordo com a configuração + de tipo selecionada */ + void selecionarConfiguracaoTipo(void); + + //Manipula as enumerações do tipo + void manipularEnumeracao(int idx_linha); + + //Exibe o form de parâmetros usado como editor de atributos de tipos compostos + void exibirFormAtributo(void); + //Exibe os atributos do tipo composto na tabela de atributos + void manipularAtributo(int res); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/visaoobjetoswidget.cpp b/libpgmodeler_ui/src/visaoobjetoswidget.cpp new file mode 100644 index 000000000..95272f573 --- /dev/null +++ b/libpgmodeler_ui/src/visaoobjetoswidget.cpp @@ -0,0 +1,1221 @@ +#include "visaoobjetoswidget.h" +#include "codigofontewidget.h" +#include "bancodadoswidget.h" +#include "esquemawidget.h" +#include "papelwidget.h" +#include "espacotabelawidget.h" +#include "linguagemwidget.h" +#include "funcaowidget.h" +#include "conversaotipowidget.h" +#include "conversaocodificacaowidget.h" +#include "dominiowidget.h" +#include "funcaoagregacaowidget.h" +#include "sequenciawidget.h" +#include "operadorwidget.h" +#include "familiaoperadoreswidget.h" +#include "classeoperadoreswidget.h" +#include "tipowidget.h" +#include "visaowidget.h" +#include "caixatextowidget.h" +#include "colunawidget.h" +#include "restricaowidget.h" +#include "regrawidget.h" +#include "gatilhowidget.h" +#include "indicewidget.h" +#include "relacionamentowidget.h" +#include "tabelawidget.h" +//*********************************************************** +extern CaixaMensagem *caixa_msg; +extern BancoDadosWidget *bancodados_wgt; +extern EsquemaWidget *esquema_wgt; +extern PapelWidget *papel_wgt; +extern EspacoTabelaWidget *espacotabela_wgt; +extern LinguagemWidget *linguagem_wgt; +extern CodigoFonteWidget *codigofonte_wgt; +extern FuncaoWidget *funcao_wgt; +extern ConversaoTipoWidget *convtipo_wgt; +extern ConversaoCodificacaoWidget *convcodif_wgt; +extern DominioWidget *dominio_wgt; +extern FuncaoAgregacaoWidget *funcaoag_wgt; +extern SequenciaWidget *sequencia_wgt; +extern OperadorWidget *operador_wgt; +extern FamiliaOperadoresWidget *familiaop_wgt; +extern ClasseOperadoresWidget *classeop_wgt; +extern TipoWidget *tipo_wgt; +extern VisaoWidget *visao_wgt; +extern CaixaTextoWidget *caixatexto_wgt; +extern ColunaWidget *coluna_wgt; +extern RestricaoWidget *restricao_wgt; +extern RegraWidget *regra_wgt; +extern GatilhoWidget *gatilho_wgt; +extern IndiceWidget *indice_wgt; +extern RelacionamentoWidget *relacao_wgt; +extern TabelaWidget *tabela_wgt; +//----------------------------------------------------------- +VisaoObjetosWidget::VisaoObjetosWidget(bool visao_simplificada, QWidget *parent, Qt::WindowFlags f) : QDockWidget(parent, f) +{ + TipoObjetoBase tipos[]={ OBJETO_BANCO_DADOS, OBJETO_TABELA, OBJETO_FUNCAO, OBJETO_VISAO, OBJETO_DOMINIO, + OBJETO_ESQUEMA, OBJETO_FUNC_AGREGACAO, OBJETO_OPERADOR, OBJETO_SEQUENCIA, + OBJETO_PAPEL, OBJETO_CONV_CODIFICACAO, OBJETO_CONV_TIPO, OBJETO_LINGUAGEM, + OBJETO_TIPO, OBJETO_ESPACO_TABELA, OBJETO_FAMILIA_OPER, OBJETO_CLASSE_OPER, + OBJETO_RELACAO, OBJETO_CAIXA_TEXTO, OBJETO_COLUNA, OBJETO_RESTRICAO, + OBJETO_GATILHO, OBJETO_INDICE, OBJETO_REGRA, OBJETO_RELACAO_BASE }; + int id_tipo, qtd_tipos=25; + QListWidgetItem *item=NULL; + QPixmap icone; + QString str_aux; + + setupUi(this); + modelo_wgt=NULL; + modelo_bd=NULL; + this->visao_simplificada=visao_simplificada; + + selecionar_tb->setVisible(visao_simplificada); + cancelar_tb->setVisible(visao_simplificada); + opcoesvisao_tb->setVisible(!visao_simplificada); + objetosvisiveis_grp->setVisible(false); + + //Cria a lista de objetos os quais pode ser visíveis ou não na visão + for(id_tipo=0; !visao_simplificada && id_tipo < qtd_tipos; id_tipo++) + { + //Alocando um item da lista + item=new QListWidgetItem; + + //Caso o tipo do objeto seja um relacionamento base, configura um ícone específico para o mesmo + if(tipos[id_tipo]==OBJETO_RELACAO_BASE) + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[id_tipo])) + "tv"; + else + //Caso contrario, configura o ícone do próprio tipo + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[id_tipo])); + + //Carrega o icone do tipo em um pixmap + icone=QPixmap(QString::fromUtf8(":/icones/icones/") + str_aux + QString(".png")); + + //Configura o texto do item como sendo o nome do tipo de objeto + item->setText(QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(tipos[id_tipo]))); + //Atribui o ícone do objeto ao item + item->setIcon(icone); + //Define o item como marcado + item->setCheckState(Qt::Checked); + //Armazena dentro do item o código do tipo de objeto para referências em outros métodos + item->setData(Qt::UserRole, QVariant(tipos[id_tipo])); + //Insere o item na lista + objetosvisiveis_lst->insertItem(id_tipo, item); + //Marca no mapa de objetos visíveis que o dado tipo está visivel na visão + map_objs_visiveis[tipos[id_tipo]]=true; + } + + objeto_selecao=NULL; + //Desabilita o handler do splitter da visão para evitar movimentação do usuário + splitter->handle(1)->setEnabled(false); + + connect(arvoreobjetos_tw,SIGNAL(itemPressed(QTreeWidgetItem*,int)),this, SLOT(selecionarObjeto(void))); + connect(listaobjetos_tbw,SIGNAL(itemPressed(QTableWidgetItem*)),this, SLOT(selecionarObjeto(void))); + + if(!visao_simplificada) + { + //Armazena o tamanho do splitter na variável + config_widgets.setValue("splitterSize", splitter->saveState()); + + connect(opcoesvisao_tb,SIGNAL(clicked(void)),this,SLOT(mudarVisaoObjetos(void))); + connect(objetosvisiveis_lst,SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(definirObjetoVisivel(QListWidgetItem*))); + connect(marcar_tb,SIGNAL(clicked(bool)), this, SLOT(definirTodosObjetosVisiveis(bool))); + connect(desmarcar_tb,SIGNAL(clicked(bool)), this, SLOT(definirTodosObjetosVisiveis(bool))); + connect(arvoreobjetos_tw,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this, SLOT(editarObjeto(void))); + connect(listaobjetos_tbw,SIGNAL(itemDoubleClicked(QTableWidgetItem*)),this, SLOT(editarObjeto(void))); + } + else + { + setWindowModality(Qt::ApplicationModal); + setAllowedAreas(Qt::NoDockWidgetArea); + setWindowFlags(Qt::Dialog | Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint); + setFeatures(QDockWidget::DockWidgetMovable); + setFeatures(QDockWidget::DockWidgetClosable); + + connect(arvoreobjetos_tw,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this, SLOT(close(void))); + connect(listaobjetos_tbw,SIGNAL(itemDoubleClicked(QTableWidgetItem*)),this, SLOT(close(void))); + connect(selecionar_tb,SIGNAL(clicked(void)),this,SLOT(close(void))); + connect(cancelar_tb,SIGNAL(clicked(void)),this,SLOT(close(void))); + } + + connect(visaoarvore_tb,SIGNAL(clicked(void)),this,SLOT(mudarVisaoObjetos(void))); + connect(visaolista_tb,SIGNAL(clicked(void)),this,SLOT(mudarVisaoObjetos(void))); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::exibirMenuObjeto(void) +{ + if(objeto_selecao && QApplication::mouseButtons()==Qt::RightButton && modelo_wgt && !visao_simplificada) + { + vector vet; + vet.push_back(objeto_selecao); + modelo_wgt->cena->clearSelection(); + modelo_wgt->configurarMenuPopup(vet); + modelo_wgt->menu_popup.exec(QCursor::pos()); + } +} +//---------------------------------------------------------- +void VisaoObjetosWidget::editarObjeto(void) +{ + if(objeto_selecao && modelo_wgt && !visao_simplificada) + { + vector vet; + vet.push_back(objeto_selecao); + modelo_wgt->cena->clearSelection(); + modelo_wgt->configurarMenuPopup(vet); + modelo_wgt->editarObjeto(); + } +} +//---------------------------------------------------------- +void VisaoObjetosWidget::selecionarObjeto(void) +{ + if(visaoarvore_tb->isChecked()) + { + QTreeWidgetItem *item_arv=arvoreobjetos_tw->currentItem(); + if(item_arv) + objeto_selecao=reinterpret_cast(item_arv->data(0,Qt::UserRole).value()); + } + else + { + QTableWidgetItem *item_tab=listaobjetos_tbw->currentItem(); + if(item_tab) + objeto_selecao=reinterpret_cast(item_tab->data(Qt::UserRole).value()); + } + + exibirMenuObjeto(); +} +//---------------------------------------------------------- +QVariant VisaoObjetosWidget::gerarValorItem(ObjetoBase *objeto) +{ + void *p_aux=NULL; + //Converte o ponteiro para o objeto em um ponteiro void + p_aux=reinterpret_cast(objeto); + //Retorna um QVariant armazenando o endereço do objeto passado + return(QVariant::fromValue(p_aux)); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::definirObjetoVisivel(TipoObjetoBase tipo_obj, bool visivel) +{ + if(tipo_obj!=OBJETO_BASE && tipo_obj!=OBJETO_TABELA_BASE) + map_objs_visiveis[tipo_obj]=visivel; + + if(visivel && visao_simplificada) + { + if(tipo_obj!=OBJETO_BANCO_DADOS) + map_objs_visiveis[OBJETO_BANCO_DADOS]=true; + + if(tipo_obj==OBJETO_COLUNA || tipo_obj==OBJETO_RESTRICAO || tipo_obj==OBJETO_REGRA || + tipo_obj==OBJETO_GATILHO || tipo_obj==OBJETO_INDICE) + map_objs_visiveis[OBJETO_TABELA]=map_objs_visiveis[OBJETO_ESQUEMA]=true; + + if(tipo_obj==OBJETO_TABELA || tipo_obj==OBJETO_VISAO || tipo_obj==OBJETO_FUNCAO || + tipo_obj==OBJETO_FUNC_AGREGACAO || tipo_obj==OBJETO_DOMINIO || tipo_obj==OBJETO_TIPO || + tipo_obj==OBJETO_CONV_CODIFICACAO || tipo_obj==OBJETO_OPERADOR || tipo_obj==OBJETO_FAMILIA_OPER || + tipo_obj==OBJETO_CLASSE_OPER || tipo_obj==OBJETO_SEQUENCIA) + map_objs_visiveis[OBJETO_ESQUEMA]=true; + } +} +//---------------------------------------------------------- +void VisaoObjetosWidget::definirObjetoVisivel(QListWidgetItem *item) +{ + TipoObjetoBase tipo_obj; + + //Obtém o tipo de objeto do item selecionado + tipo_obj=static_cast(item->data(Qt::UserRole).toInt()); + //Marca o flag de visível caso o item esteja com seu checkbox marcado na lista + //map_objs_visiveis[tipo_obj]=(item->checkState()==Qt::Checked); + definirObjetoVisivel(tipo_obj, item->checkState()==Qt::Checked); + //Atualiza a visão de objetos para aplicar as modificações + atualizarVisaoObjetos(); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::definirTodosObjetosVisiveis(bool) +{ + int qtd, i; + TipoObjetoBase tipo_obj; + QListWidgetItem *item=NULL; + bool marcado; + + /* Caso o objeto remetente do sinal seja o botão de marcar todos + o flag 'marcado' terá valor true */ + marcado=(sender()==marcar_tb); + qtd=objetosvisiveis_lst->count(); + + for(i=0; i < qtd; i++) + { + //Obtém um item da lista + item=objetosvisiveis_lst->item(i); + //Obtém o tipo de objeto ao qual ele está ligado + tipo_obj=static_cast(item->data(Qt::UserRole).toInt()); + //Atribui a flag 'marcado' ao tipo de objeto no mapa + map_objs_visiveis[tipo_obj]=marcado; + + if(marcado) + item->setCheckState(Qt::Checked); + else + item->setCheckState(Qt::Unchecked); + } + + atualizarVisaoObjetos(); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::mudarVisaoObjetos(void) +{ + if(sender()==visaolista_tb) + { + if(!visaolista_tb->isChecked()) + visaolista_tb->setChecked(true); + else + { + visaoarvore_tb->setChecked(false); + visaoobjetos_stw->setCurrentIndex(1); + } + } + else if(sender()==visaoarvore_tb) + { + if(!visaoarvore_tb->isChecked()) + visaoarvore_tb->setChecked(true); + else + { + visaolista_tb->setChecked(false); + visaoobjetos_stw->setCurrentIndex(0); + } + } + else if(sender()==opcoesvisao_tb) + { + objetosvisiveis_grp->setVisible(opcoesvisao_tb->isChecked()); + splitter->handle(1)->setEnabled(opcoesvisao_tb->isChecked()); + + /* Caso as configurações não estejam visíveis ou seja o botão + de configuração não está acionado, o splitter das configurações + é restaurado ao seu tamanho inicial ou seja, totalmente + recolhido, escondendo assim os widgets de configuração */ + if(!opcoesvisao_tb->isChecked()) + splitter->restoreState(config_widgets.value("splitterSize").toByteArray()); + } +} +//---------------------------------------------------------- +void VisaoObjetosWidget::atualizarVisaoObjetos(void) +{ + atualizarArvoreObjetos(); + atualizarListaObjetos(); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::atualizarListaObjetos(void) +{ + while(listaobjetos_tbw->rowCount() > 0) + listaobjetos_tbw->removeRow(listaobjetos_tbw->rowCount()-1); + + if(modelo_bd) + { + ObjetoBase *objeto=NULL, *esquema=NULL; + ObjetoTabela *objeto_tab=NULL; + QTableWidgetItem *item_tab=NULL, *item_tab1=NULL; + Tabela *tabela=NULL; + Funcao *funcao=NULL; + Operador *operador=NULL; + QPixmap icone; + QFont fonte; + QString str_aux; + unsigned tipo_rel; + TipoObjetoBase tipos[]={ OBJETO_BANCO_DADOS, OBJETO_TABELA, OBJETO_FUNCAO, OBJETO_VISAO, OBJETO_DOMINIO, + OBJETO_ESQUEMA, OBJETO_FUNC_AGREGACAO, OBJETO_OPERADOR, OBJETO_SEQUENCIA, + OBJETO_PAPEL, OBJETO_CONV_CODIFICACAO, OBJETO_CONV_TIPO, OBJETO_LINGUAGEM, + OBJETO_TIPO, OBJETO_ESPACO_TABELA, OBJETO_FAMILIA_OPER, OBJETO_CLASSE_OPER, + OBJETO_RELACAO, OBJETO_CAIXA_TEXTO, OBJETO_RELACAO_BASE }, + subtipos[]={ OBJETO_COLUNA, OBJETO_RESTRICAO, + OBJETO_GATILHO, OBJETO_INDICE, OBJETO_REGRA }; + + int qtd_tipos=20, qtd_subtipos=5, id_tipo, qtd, qtd1, id_lin, id_tab; + + try + { + /* Desativa a ordenação temporáriamente evitando que os itens + sejam ordenados no momento da criação e causando falhas no + configuraçao dos mesmos */ + listaobjetos_tbw->setSortingEnabled(false); + + for(id_tipo=0; id_tipo < qtd_tipos; id_tipo++) + { + /* Caso o tipo de objeto seja de banco de dados a quantidade de objetos + a serem inseridos na lista é igual a 1 */ + if(tipos[id_tipo]==OBJETO_BANCO_DADOS) + qtd=1; + else + //Para os demais objetos, a quantidade é obtida através de uma consulta ao modelo + qtd=modelo_bd->obterNumObjetos(tipos[id_tipo]); + + /* O preenchimento da tabela só é executando quando o tipo de objeto está + marcado para ser exibido e exista pelo menos 1 objeto do tipo em questão + a ser exibido */ + for(id_lin=0; map_objs_visiveis[tipos[id_tipo]] && id_lin < qtd; id_lin++) + { + listaobjetos_tbw->insertRow(id_lin); + + if(tipos[id_tipo]!=OBJETO_BANCO_DADOS) + objeto=modelo_bd->obterObjeto(id_lin, tipos[id_tipo]); + else + objeto=modelo_bd; + + //Cria o item descritor de nome do objeto + item_tab=new QTableWidgetItem; + item_tab->setData(Qt::UserRole, gerarValorItem(objeto)); + listaobjetos_tbw->setItem(id_lin, 0, item_tab); + + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + if(objeto->objetoProtegido()) + { + fonte=item_tab->font(); + fonte.setItalic(true); + item_tab->setFont(fonte); + item_tab->setForeground(ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + //Caso o objeto seja uma função ou operador a assinatura será exibida ao invés do nome do objeto + if(tipos[id_tipo]!=OBJETO_FUNCAO && tipos[id_tipo]!=OBJETO_OPERADOR) + { + item_tab->setText(QString::fromUtf8(objeto->obterNome())); + item_tab->setToolTip(QString::fromUtf8(objeto->obterNome())); + } + else if(tipos[id_tipo]==OBJETO_FUNCAO) + { + funcao=dynamic_cast(objeto); + funcao->criarAssinatura(false); + item_tab->setText(QString::fromUtf8(funcao->obterAssinatura())); + item_tab->setToolTip(QString::fromUtf8(funcao->obterAssinatura())); + funcao->criarAssinatura(true); + } + else + { + operador=dynamic_cast(objeto); + item_tab->setText(QString::fromUtf8(operador->obterAssinatura(false))); + item_tab->setToolTip(QString::fromUtf8(operador->obterAssinatura(false))); + } + + //Cria o item descritor de tipo do objeto + item_tab=new QTableWidgetItem; + item_tab->setData(Qt::UserRole, gerarValorItem(objeto)); + + if(tipos[id_tipo]==OBJETO_RELACAO_BASE || tipos[id_tipo]==OBJETO_RELACAO) + { + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(objeto->obterTipoObjeto())); + + if(tipos[id_tipo]==OBJETO_RELACAO_BASE) + str_aux+="tv"; + else + { + tipo_rel=dynamic_cast(objeto)->obterTipoRelacionamento(); + //Concatena a uma string auxiliar a designação do tipo de relacionamento + if(tipo_rel==Relacionamento::RELACIONAMENTO_11) + str_aux+="11"; + else if(tipo_rel==Relacionamento::RELACIONAMENTO_1N) + str_aux+="1n"; + else if(tipo_rel==Relacionamento::RELACIONAMENTO_NN) + str_aux+="nn"; + else if(tipo_rel==Relacionamento::RELACIONAMENTO_DEP) + str_aux+="dep"; + else if(tipo_rel==Relacionamento::RELACIONAMENTO_GEN) + str_aux+="gen"; + } + } + else + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(objeto->obterTipoObjeto())); + + icone=QPixmap(QString(":/icones/icones/") + str_aux + QString(".png")); + + listaobjetos_tbw->setItem(id_lin, 1, item_tab); + item_tab->setText(QString::fromUtf8(objeto->obterNomeTipoObjeto())); + item_tab->setIcon(icone); + fonte=item_tab->font(); + fonte.setItalic(true); + item_tab->setFont(fonte); + + //Cria o item descritor de nome do container do objeto e de tipo do container + item_tab=new QTableWidgetItem; + item_tab1=new QTableWidgetItem; + fonte=item_tab1->font(); + fonte.setItalic(true); + item_tab1->setFont(fonte); + + listaobjetos_tbw->setItem(id_lin, 2, item_tab); + listaobjetos_tbw->setItem(id_lin, 3, item_tab1); + item_tab->setData(Qt::UserRole, gerarValorItem(objeto)); + item_tab1->setData(Qt::UserRole, gerarValorItem(objeto)); + + /* Configurando o tipo e o nome do container do objeto de + acordo com o seu próprio tipo */ + switch(tipos[id_tipo]) + { + /* O objeto banco de dados não está ligado a um container sendo + assim, as colunas descritoras do container terão um valor + indicativo de não existência do mesmo */ + case OBJETO_BANCO_DADOS: + item_tab->setText("-"); + item_tab1->setText("-"); + break; + + //Objetos cujo container direto é um esquema + case OBJETO_FUNCAO: + case OBJETO_TABELA: + case OBJETO_VISAO: + case OBJETO_DOMINIO: + case OBJETO_FUNC_AGREGACAO: + case OBJETO_OPERADOR: + case OBJETO_SEQUENCIA: + case OBJETO_CONV_CODIFICACAO: + case OBJETO_TIPO: + case OBJETO_FAMILIA_OPER: + case OBJETO_CLASSE_OPER: + //Configura o ícone de esquema + icone=QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_ESQUEMA)) + + QString(".png")); + + item_tab->setText(QString::fromUtf8(objeto->obterEsquema()->obterNome())); + + //Atribui o icone ao item da tabela e configura o nome do tipo + item_tab1->setIcon(icone); + item_tab1->setText(QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(OBJETO_ESQUEMA))); + + //Armazenando o endereço da esquema do objeto nos itens descritores do container + esquema=objeto->obterEsquema(); + + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + if(esquema && esquema->objetoProtegido()) + { + fonte=item_tab->font(); + fonte.setItalic(true); + item_tab->setFont(fonte); + item_tab->setForeground(ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + break; + + //Demais objetos cujo container direto é o banco de dados + default: + icone=QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_BANCO_DADOS)) + + QString(".png")); + item_tab->setText(QString::fromUtf8(modelo_bd->obterNome())); + item_tab1->setIcon(icone); + item_tab1->setText(QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(OBJETO_BANCO_DADOS))); + + //Armazenando o endereço do modelo de banco de dados nos itens descritores do container + break; + } + } + } + + //Insere os objetos (colunas, restrições, indices, gatilhos, etc) das tabelas do modelo + qtd=/*modelo_wgt->*/modelo_bd->obterNumObjetos(OBJETO_TABELA); + + for(id_tab=0; id_tab < qtd; id_tab++) + { + //Obtém uma tabela do modelo + tabela=dynamic_cast(modelo_bd->obterTabela(id_tab)); + + for(id_tipo=0; id_tipo < qtd_subtipos; id_tipo++) + { + //Obtém o número de objetos do subtipo atual + qtd1=tabela->obterNumObjetos(subtipos[id_tipo]); + + /* Os objetos do subtipo atual só serão exibidos caso exista pelo menos um objeto + e além disso o mesmo esteja marcado como visível na visão de objetos */ + for(id_lin=0; map_objs_visiveis[subtipos[id_tipo]] && id_lin < qtd1; id_lin++) + { + listaobjetos_tbw->insertRow(id_lin); + objeto_tab=dynamic_cast(tabela->obterObjeto(id_lin, subtipos[id_tipo])); + + //Cria o item descritor de nome do objeto + item_tab=new QTableWidgetItem; + listaobjetos_tbw->setItem(id_lin, 0, item_tab); + item_tab->setText(QString::fromUtf8(objeto_tab->obterNome())); + item_tab->setToolTip(QString::fromUtf8(objeto_tab->obterNome())); + item_tab->setData(Qt::UserRole, gerarValorItem(objeto_tab)); + + /* Caso o objeto seja uma coluna ou restrição e o mesmo foi incluído por relacionamento, + configura um estilo de fonte para indicar esta situação */ + if(objeto_tab->incluidoPorRelacionamento()) + { + fonte=item_tab->font(); + fonte.setItalic(true); + item_tab->setFont(fonte); + item_tab->setForeground(ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_HERDADA).foreground()); + } + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + else if(objeto_tab->objetoProtegido()) + { + fonte=item_tab->font(); + fonte.setItalic(true); + item_tab->setFont(fonte); + item_tab->setForeground(ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + //Cria o item descritor de tipo do objeto + item_tab=new QTableWidgetItem; + icone=QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(objeto_tab->obterTipoObjeto())) + + QString(".png")); + listaobjetos_tbw->setItem(id_lin, 1, item_tab); + item_tab->setText(QString::fromUtf8(objeto_tab->obterNomeTipoObjeto())); + item_tab->setIcon(icone); + fonte=item_tab->font(); + fonte.setItalic(true); + item_tab->setFont(fonte); + item_tab->setData(Qt::UserRole, gerarValorItem(objeto_tab)); + + //Cria o item descritor de nome do container do objeto e de tipo do container + item_tab=new QTableWidgetItem; + item_tab1=new QTableWidgetItem; + fonte=item_tab1->font(); + fonte.setItalic(true); + item_tab1->setFont(fonte); + item_tab1->setData(Qt::UserRole, gerarValorItem(objeto_tab)); + + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + if(tabela->objetoProtegido()) + { + fonte=item_tab->font(); + fonte.setItalic(true); + item_tab->setFont(fonte); + item_tab->setForeground(ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + listaobjetos_tbw->setItem(id_lin, 2, item_tab); + listaobjetos_tbw->setItem(id_lin, 3, item_tab1); + item_tab->setText(QString::fromUtf8(tabela->obterNome())); + item_tab->setData(Qt::UserRole, gerarValorItem(objeto_tab)); + + //Configura o ícone de tabela (container) + icone=QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_TABELA)) + + QString(".png")); + + //Atribui o icone ao item da tabela e configura o nome do tipo do container + item_tab1->setIcon(icone); + item_tab1->setText(QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(OBJETO_TABELA))); + item_tab1->setData(Qt::UserRole, gerarValorItem(objeto_tab)); + } + } + } + listaobjetos_tbw->setSortingEnabled(true); + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } +} +//---------------------------------------------------------- +void VisaoObjetosWidget::atualizarSubArvoreEsquema(QTreeWidgetItem *raiz) +{ + if(modelo_bd && map_objs_visiveis[OBJETO_ESQUEMA]) + { + ObjetoBase *objeto=NULL, *esquema=NULL; + Funcao *funcao=NULL; + Operador *operador=NULL; + vector lista_obj; + QFont fonte; + QTreeWidgetItem *item=NULL, *item1=NULL, *item2=NULL, *item3=NULL, *item4=NULL; + int qtd, qtd2, i, i1, i2; + TipoObjetoBase tipos[]={ OBJETO_VISAO, OBJETO_FUNCAO, OBJETO_FUNC_AGREGACAO, + OBJETO_DOMINIO, OBJETO_TIPO, OBJETO_CONV_CODIFICACAO, + OBJETO_OPERADOR, OBJETO_FAMILIA_OPER, OBJETO_CLASSE_OPER, + OBJETO_SEQUENCIA }; + //Configura o ícone que designa um esquema + QPixmap icone_esq=QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_ESQUEMA)) + + QString(".png")), + //Configura o ícone que designa um grupo de esquemas + icone_grupo=QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_ESQUEMA)) + + QString("_grp") + + QString(".png")); + + //Obtém a quantidade de esquemas existentes no modelo + qtd=(modelo_bd->obterNumObjetos(OBJETO_ESQUEMA)); + item=new QTreeWidgetItem(raiz); + item->setIcon(0,icone_grupo); + + //Configura o texto do item como sendo o nome do tipo "esquema" com a quantidade obtida + item->setText(0,QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(OBJETO_ESQUEMA)) + + QString(" (%1)").arg(qtd)); + fonte=item->font(0); + fonte.setItalic(true); + item->setFont(0, fonte); + + try + { + //Varre a lista de esquemas do modelo + for(i=0; i < qtd; i++) + { + //Caso especial para o esquema público + if(i==-1) + { + /* O novo sub-item a ser configurado, será o próprio item + que designa o esquema público */ + item2=item1; + esquema=NULL; + } + else + { + //Obtém o esquema no índice atual + esquema=/*modelo_wgt->*/modelo_bd->obterObjeto(i,OBJETO_ESQUEMA); + /* Configura um item para o esquema obtido, cujo texto + será o próprio nome do objeto obtido */ + item2=new QTreeWidgetItem(item); + item2->setText(0,QString::fromUtf8(esquema->obterNome())); + item2->setToolTip(0,QString::fromUtf8(esquema->obterNome())); + item2->setIcon(0,icone_esq); + item2->setData(0, Qt::UserRole, gerarValorItem(esquema)); + } + + + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + if(esquema && esquema->objetoProtegido()) + { + fonte=item2->font(0); + fonte.setItalic(true); + item2->setFont(0,fonte); + item2->setForeground(0,ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + //Atualiza a subárvore de tabelas para o esquema atual + atualizarSubArvoreTabela(item2, esquema); + + //Varre a lista de objetos a nível de esquema + for(i1=0; i1 < 10; i1++) + { + if(map_objs_visiveis[tipos[i1]]) + { + //Cria um item que designa um grupo de objetos do tipo atual + item3=new QTreeWidgetItem(item2); + item3->setIcon(0,QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[i1])) + + QString("_grp") + + QString(".png"))); + + //Obtém os objetos do tipo atual dentro do esquema atual + lista_obj=/*modelo_wgt->*/modelo_bd->obterObjetos(tipos[i1], esquema); + /* Configura o texto do item como sendo o nome do tipo atual com a + quantidade de objetos encontrados */ + qtd2=lista_obj.size(); + item3->setText(0,trUtf8(ObjetoBase::obterNomeTipoObjeto(tipos[i1])) + + QString(" (%1)").arg(qtd2)); + fonte=item3->font(0); + fonte.setItalic(true); + item3->setFont(0, fonte); + + //Varre a lista do objetos encontrados + for(i2=0; i2 < qtd2; i2++) + { + //Cria um item específico para o objeto atual + objeto=lista_obj[i2]; + item4=new QTreeWidgetItem(item3); + item4->setData(0, Qt::UserRole, gerarValorItem(objeto)); + + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + if(objeto->objetoProtegido()) + { + fonte=item4->font(0); + fonte.setItalic(true); + item4->setFont(0,fonte); + item4->setForeground(0,ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + //Caso particular para funções + if(tipos[i1]==OBJETO_FUNCAO) + { + funcao=dynamic_cast(objeto); + //Cria a assinatura sem formatar o nome + funcao->criarAssinatura(false); + //O texto do ítem será a assinatura da função e não o nome do objeto + item4->setText(0,QString::fromUtf8(funcao->obterAssinatura())); + item4->setToolTip(0,QString::fromUtf8(funcao->obterAssinatura())); + /* Cria a assinatura formatando o nome, para não quebrar possíveis + referências a esse objeto */ + funcao->criarAssinatura(true); + } + else if(tipos[i1]==OBJETO_OPERADOR) + { + operador=dynamic_cast(objeto); + item4->setText(0, QString::fromUtf8(operador->obterAssinatura(false))); + item4->setToolTip(0, QString::fromUtf8(operador->obterAssinatura(false))); + } + else + { + //Caso não seja uma função, o texto do item será o próprio nome do objeto + item4->setText(0,QString::fromUtf8(objeto->obterNome())); + item4->setToolTip(0,QString::fromUtf8(objeto->obterNome())); + } + + //Configura o icone do do item como sendo o icone para o tipo atual + item4->setIcon(0,QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[i1])) + + QString(".png"))); + } + } + } + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } +} +//---------------------------------------------------------- +void VisaoObjetosWidget::atualizarSubArvoreTabela(QTreeWidgetItem *raiz, ObjetoBase *esquema) +{ + if(modelo_bd && map_objs_visiveis[OBJETO_TABELA]) + { + ObjetoBase *objeto=NULL; + vector lista_obj; + Tabela *tabela=NULL; + QTreeWidgetItem *item=NULL, *item1=NULL, *item2=NULL, *item3=NULL; + int qtd, qtd1, i, i1, i2; + QString str_aux; + QFont fonte; + TipoRestricao tipo_rest; + TipoObjetoBase tipos[]={ OBJETO_COLUNA, OBJETO_RESTRICAO, OBJETO_REGRA, + OBJETO_GATILHO, OBJETO_INDICE }; + //Configura o ícone que designa uma tabela + QPixmap icone_tab=QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_TABELA)) + QString(".png")), + //Configura o ícone que designa um grupo de tabelas + icone_grupo=QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_TABELA)) + + QString("_grp") + QString(".png")); + + try + { + //Obtém a lista de objetos do tipo tabela presentes no esquema passado + lista_obj=/*modelo_wgt->*/modelo_bd->obterObjetos(OBJETO_TABELA, esquema); + //Configura o elemento raiz como sendo um grupo de tabelas + item=new QTreeWidgetItem(raiz); + item->setIcon(0,icone_grupo); + /* O texto do ícone será o nome do tipo do objeto (no caso, tabela) e a + quantidade de objetos encontrado */ + item->setText(0,QString::fromUtf8(ObjetoBase::obterNomeTipoObjeto(OBJETO_TABELA)) + + QString(" (%1)").arg(lista_obj.size())); + fonte=item->font(0); + fonte.setItalic(true); + item->setFont(0, fonte); + + //Varre a lista de objetos obtidos do modelo + qtd=lista_obj.size(); + for(i=0; i < qtd; i++) + { + //Configura o elemento como sendo a tabela atual + tabela=dynamic_cast(lista_obj[i]); + item1=new QTreeWidgetItem(item); + //O nome do item será o próprio nome da tabela + item1->setText(0,QString::fromUtf8(tabela->obterNome())); + item1->setToolTip(0,QString::fromUtf8(tabela->obterNome())); + //Configura o ícone do item como sendo o ícone de tabela + item1->setIcon(0,QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_TABELA)) + + QString(".png"))); + item1->setData(0, Qt::UserRole, gerarValorItem(tabela)); + + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + if(tabela->objetoProtegido()) + { + fonte=item1->font(0); + fonte.setItalic(true); + item1->setFont(0,fonte); + item1->setForeground(0,ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + //Configura os elementos filhos da tabela, de acordo com a lista de tipos + for(i1=0; i1 < 5; i1++) + { + if(map_objs_visiveis[tipos[i1]]) + { + /* Configura o item atual atribuindo-lhe o ícone específico para o + grupo do tipo atual */ + item2=new QTreeWidgetItem(item1); + item2->setIcon(0,QPixmap(QString(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[i1])) + + QString("_grp") + + QString(".png"))); + fonte=item2->font(0); + fonte.setItalic(true); + item2->setFont(0, fonte); + + /* Configura o texto do item como sendo o nome do tipo e a quantidade de + objetos deste tipo presente na tabela */ + qtd1=tabela->obterNumObjetos(tipos[i1]); + item2->setText(0,trUtf8(ObjetoBase::obterNomeTipoObjeto(tipos[i1])) + + QString(" (%1)").arg(qtd1)); + + //Varre a lista de elementos filhos da tabela + for(i2=0; i2 < qtd1; i2++) + { + //Obtém o elemento na posição atual do tipo atual + objeto=tabela->obterObjeto(i2,tipos[i1]); + //Configura o item atribuindo-lhe o texto como sendo o próprio nome do objeto + item3=new QTreeWidgetItem(item2); + item3->setText(0,QString::fromUtf8(objeto->obterNome())); + item3->setToolTip(0,QString::fromUtf8(objeto->obterNome())); + item3->setData(0, Qt::UserRole, gerarValorItem(objeto)); + + /* Caso o objeto foi incluido à tabela por um relacionamento, configura um estilo de fonte para + indicar esta situação */ + if(dynamic_cast(objeto)->incluidoPorRelacionamento()) + { + fonte=item3->font(0); + fonte.setItalic(true); + item3->setFont(0,fonte); + item3->setForeground(0,ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_HERDADA).foreground()); + } + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + else if(objeto->objetoProtegido()) + { + fonte=item3->font(0); + fonte.setItalic(true); + item3->setFont(0,fonte); + item3->setForeground(0,ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + switch(tipos[i1]) + { + case OBJETO_RESTRICAO: + /* Fazendo uma configuração específica de ícone para restrições. + Cada tipo de restrição tem seu ícone específico. + O sufixos sufixo _pk, _fk, _ck, e _uq, são concatenados + ao nome do tipo (constraint) para identificar o ícone */ + tipo_rest=dynamic_cast(objeto)->obterTipoRestricao(); + if(tipo_rest==TipoRestricao::primary_key) + str_aux="_pk"; + else if(tipo_rest==TipoRestricao::foreign_key) + str_aux="_fk"; + else if(tipo_rest==TipoRestricao::check) + str_aux="_ck"; + else if(tipo_rest==TipoRestricao::unique) + str_aux="_uq"; + break; + + default: + str_aux=""; + break; + } + + //Configura o caminho do ícone e o atribui ao item + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[i1])) + str_aux; + item3->setIcon(0,QPixmap(QString(":/icones/icones/") + str_aux + QString(".png"))); + } + } + } + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + } +} +//---------------------------------------------------------- +void VisaoObjetosWidget::atualizarArvoreObjetos(void) +{ + arvoreobjetos_tw->clear(); + if(modelo_bd) + { + QString str_aux; + ObjetoBase *objeto=NULL; + unsigned qtd, i, i1, tipo_rel; + QTreeWidgetItem *raiz=NULL,*item1=NULL, *item2=NULL; + QFont fonte; + + //Lista de tipos de objetos a nivel de banco de dados + TipoObjetoBase tipos[]={ OBJETO_PAPEL, OBJETO_ESPACO_TABELA, + OBJETO_LINGUAGEM, OBJETO_CONV_TIPO, OBJETO_CAIXA_TEXTO, + OBJETO_RELACAO, OBJETO_RELACAO_BASE }; + + try + { + /* Só executa a exibição dos objetos do banco de dados caso o tipo + banco de dados esteja marcado como visível */ + if(map_objs_visiveis[OBJETO_BANCO_DADOS]) + { + //Configura o item raiz da árvore + raiz=new QTreeWidgetItem; + //O ícone é o descritor de banco de dados + raiz->setIcon(0,QPixmap(QString::fromUtf8(":/icones/icones/") + + QString(ObjetoBase::obterNomeEsquemaObjeto(OBJETO_BANCO_DADOS)) + + QString(".png"))); + arvoreobjetos_tw->insertTopLevelItem(0,raiz); + //O texto do item é o próprio nome do banco de dados + raiz->setText(0,QString::fromUtf8(/*modelo_wgt->*/modelo_bd->obterNome())); + raiz->setToolTip(0,QString::fromUtf8(/*modelo_wgt->*/modelo_bd->obterNome())); + raiz->setData(0, Qt::UserRole, gerarValorItem(/*modelo_wgt->*/modelo_bd)); + + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + if(/*modelo_wgt->*/modelo_bd->objetoProtegido()) + { + fonte=raiz->font(0); + fonte.setItalic(true); + raiz->setFont(0,fonte); + raiz->setForeground(0,ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + //Atualiza a subárvore de esquemas + atualizarSubArvoreEsquema(raiz); + + //Varre a lista de objetos a nível de banco de dados e cria os respectivos itens + for(i=0; i < 7; i++) + { + if(map_objs_visiveis[tipos[i]]) + { + /* Cria o item que designa o grupo de objetos do tipo atual + o sufixo '_grp' no caminho do ícone indica que será carregado + o ícone do grupo daquele tipo */ + item1=new QTreeWidgetItem(raiz); + if(tipos[i]==OBJETO_RELACAO_BASE) + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[i])) + "tv"; + else + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[i])); + + item1->setIcon(0,QPixmap(QString(":/icones/icones/") + + str_aux + QString("_grp") + QString(".png"))); + + //Obtém a quantidade de objetos do tipo atual + qtd=/*modelo_wgt->*/modelo_bd->obterNumObjetos(tipos[i]); + /* Configura o texto do item de grupo com o nome do tipo e a quantidade + de objetos daquele tipo presente no modelo */ + item1->setText(0,trUtf8(ObjetoBase::obterNomeTipoObjeto(tipos[i])) + + QString(" (%1)").arg(qtd)); + fonte=item1->font(0); + fonte.setItalic(true); + item1->setFont(0, fonte); + + /* Com o total de objeto do tipo atual, varre a lista de objetos daquele tipo + e atribuindo como subitens do item configurado atualmente (grupo) */ + for(i1=0; i1 < qtd; i1++) + { + //Obtém o objeto atual do tipo atual + objeto=/*modelo_wgt->*/modelo_bd->obterObjeto(i1,tipos[i]); + //Cria um item na árvore e seta seu texto como sendo próprio nome do objeto + item2=new QTreeWidgetItem(item1); + item2->setText(0,QString::fromUtf8(objeto->obterNome())); + item2->setToolTip(0,QString::fromUtf8(objeto->obterNome())); + item2->setData(0, Qt::UserRole, gerarValorItem(objeto)); + + /* Caso o objeto esteja protegido, configura um estilo de fonte para + indicar esta situação */ + if(objeto->objetoProtegido()) + { + fonte=item2->font(0); + fonte.setItalic(true); + item2->setFont(0,fonte); + item2->setForeground(0,ObjetoGrafico::obterEstiloFonte(AtributosParsers::COLUNA_PROTEGIDA).foreground()); + } + + /* Configurando o ícone especialmente para relacionamentos + pois cada tipo tem seu ícone especifico. */ + switch(tipos[i]) + { + //Configura o ícone apenas para relacionamento + case OBJETO_RELACAO: + tipo_rel=dynamic_cast(objeto)->obterTipoRelacionamento(); + //Concatena a uma string auxiliar a designação do tipo de relacionamento + if(tipo_rel==Relacionamento::RELACIONAMENTO_11) + str_aux="11"; + else if(tipo_rel==Relacionamento::RELACIONAMENTO_1N) + str_aux="1n"; + else if(tipo_rel==Relacionamento::RELACIONAMENTO_NN) + str_aux="nn"; + else if(tipo_rel==Relacionamento::RELACIONAMENTO_DEP) + str_aux="dep"; + else if(tipo_rel==Relacionamento::RELACIONAMENTO_GEN) + str_aux="gen"; + break; + + case OBJETO_RELACAO_BASE: + str_aux="tv"; + break; + /* Para os demais objetos o ícone será aquele referente ao seu + próprio tipo, portanto nenhum sufixo para identificação do ícone + será usado */ + default: + str_aux=""; + break; + } + + //Configura o caminho do ícone e o atribui ao elemento + str_aux=QString(ObjetoBase::obterNomeEsquemaObjeto(tipos[i])) + str_aux; + item2->setIcon(0,QPixmap(QString(":/icones/icones/") + str_aux + QString(".png"))); + } + } + } + //Expande o item raiz da árvore + arvoreobjetos_tw->expandItem(raiz); + } + } + catch(Excecao &e) + { + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } + + //Ordena os itens da árvore + arvoreobjetos_tw->sortByColumn(0, Qt::AscendingOrder); + } +} +//---------------------------------------------------------- +ObjetoBase *VisaoObjetosWidget::obterObjetoSelecao(void) +{ + return(objeto_selecao); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::expandirItemArvore(ObjetoBase *objeto) +{ + if(objeto) + { + QList itens; + QList::iterator itr, itr_end; + ObjetoBase *obj_aux=NULL; + QTreeWidgetItem *item_arv=NULL; + + //Obtém todos os elementos da árvore e os dispoem em forma de lista + itens=arvoreobjetos_tw->findItems("(.)*",Qt::MatchRegExp | Qt::MatchRecursive,0); + itr=itens.begin(); + itr_end=itens.end(); + + //Varre a lista obtida em busca do objeto passado no parâmetro + while(itr!=itr_end) + { + //Obtém cada objeto que cada item da lista armazena + item_arv=(*itr); + obj_aux=reinterpret_cast(item_arv->data(0,Qt::UserRole).value()); + + /* Compara o objeto obtido da lista com o objeto do parâmeto + caso os dois sejam os mesmo procede com a expansão do elemento + referente ao objeto */ + if(obj_aux==objeto) + { + arvoreobjetos_tw->expandItem(item_arv); + arvoreobjetos_tw->scrollToItem(item_arv); + break; + } + + itr++; + } + } +} +//---------------------------------------------------------- +void VisaoObjetosWidget::close(void) +{ + QObject *obj_sender=sender(); + + /* Caso o sender do comando close seja o botão de selecionar objeto + quando o dockwidget está sendo usado de forma simplificada. Isso indica + que o comando close configurará o objeto a ser retornado pela visão de objetos + ao formulário que solicitou a seleção */ + if(obj_sender==selecionar_tb) + { + QVariant dado; + + /* Obtém o dado do elemento selecionado atualmente em uma dos + containeres de objetos */ + if(visaoarvore_tb->isChecked() && arvoreobjetos_tw->currentItem()) + dado=arvoreobjetos_tw->currentItem()->data(0,Qt::UserRole); + else if(listaobjetos_tbw->currentItem()) + dado=listaobjetos_tbw->currentItem()->data(Qt::UserRole); + + //Converte o conteúdo do dado para um void * + objeto_selecao=reinterpret_cast(dado.value()); + } + else + objeto_selecao=NULL; + + QDockWidget::close(); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::definirModelo(ModeloWidget *modelo_wgt) +{ + this->modelo_wgt=modelo_wgt; + + if(modelo_wgt) + definirModelo(modelo_wgt->modelo); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::definirModelo(ModeloBD *modelo_bd) +{ + this->modelo_bd=modelo_bd; + + /* Caso um model esteja atribuído, os widgets da visão serão habilitados + caso contrário serão desabiltados */ + if(modelo_bd) + dockWidgetContents->setEnabled(true); + else + dockWidgetContents->setEnabled(false); + + atualizarVisaoObjetos(); + visaoobjetos_stw->setEnabled(true); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::closeEvent(QCloseEvent *) +{ + /* Quando usado de forma simplificada, ao esconder o dock todos + os objetos são marcadas como invisíveis para forçar a configuração + de exibição no momento em que o formulário (dockwidget) for exibido novamento */ + if(visao_simplificada) + { + map::iterator itr, itr_end; + + itr=map_objs_visiveis.begin(); + itr_end=map_objs_visiveis.end(); + while(itr!=itr_end) + { itr->second=false; itr++; } + } + + emit s_visibilityChanged(objeto_selecao, !this->isVisible()); +} +//---------------------------------------------------------- +void VisaoObjetosWidget::mouseMoveEvent(QMouseEvent *) +{ + static QPoint pos=QCursor::pos(), pos1=QCursor::pos(); + + /* Obtém a posição global atual do cursor armazenando a posição + capturada anteriormente para cálculo do deslocamento da janela */ + pos=pos1; + pos1=QCursor::pos(); + + if(visao_simplificada && QApplication::mouseButtons()==Qt::LeftButton) + { + QPoint dif_pos; + QDesktopWidget desktop; + QRect ret=desktop.screenGeometry(); + int px, py; + + //Calcula o deslocamento + dif_pos=pos1-pos; + + //Calcula a nova posição da janela + px=this->pos().x() + dif_pos.x(); + py=this->pos().y() + dif_pos.y(); + + //Validando a posição X da janela para não ultrapassar os limites da tela + if(px<0) + px=0; + else if((px + this->width()) > ret.right()) + px=ret.right() - this->width(); + + //Validando a posição Y da janela para não ultrapassar os limites da tela + if(py<0) + py=0; + else if((py + this->height()) > ret.bottom()) + py=ret.bottom() - this->height(); + + //Move a janela + this->move(px,py); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/visaoobjetoswidget.h b/libpgmodeler_ui/src/visaoobjetoswidget.h new file mode 100644 index 000000000..a74ce7d7c --- /dev/null +++ b/libpgmodeler_ui/src/visaoobjetoswidget.h @@ -0,0 +1,125 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: VisaoObjetosWidget +# Descrição: Definição da classe que implementa a arvore e lista de objetos +# no modelo de banco de dados. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef VISAO_OBJETOS_WIDGET_H +#define VISAO_OBJETOS_WIDGET_H + +#include +#include "ui_visaoobjetoswidget.h" +#include "modelowidget.h" +#include "caixamensagem.h" +//*********************************************************** +class VisaoObjetosWidget: public QDockWidget, public Ui::VisaoObjetosWidget { + Q_OBJECT + + private: + /* Indica que a visão de objetos é usada de forma simplificada como + seletora de objetos auxiliar de outros formulários. Interações + como excluir, destacar, editar e exibir código dos objetos + são desabilitadas */ + bool visao_simplificada; + + /* Armazena o endereço do objeto relacionado ao item marcado na árvore + ou na lista de objetos */ + ObjetoBase *objeto_selecao; + + /* Menu popup o qual contém as ações: destacar objeto no modelo, + excluir do modelo, edição do objeto */ + QMenu *menu_popup; + + /* Armazena a configuração de tamanho inicial do splitter para + para uso em conjunto com o botão de exibição das configurações + da visão de objetos. + Armazena a configuração de posição da slider da barra de rolagem + vertical da árvore de objetos para que a mesma seja restaurada + sempre que a mesma sofrer atualizações */ + QSettings config_widgets; + + //Widget de Modelo de objetos o qual é acessado + ModeloWidget *modelo_wgt; + + //Modelo o qual é acessado quando um modelo widget não é especificado + ModeloBD *modelo_bd; + + //Armazena quais os tipos de objetos são visíveis na visão + map map_objs_visiveis; + + //Atualiza a árvore inteira do banco de dados + void atualizarSubBancoDados(void); + + //Atualiza somente a árvore de esquema e seus subitens + void atualizarSubArvoreEsquema(QTreeWidgetItem *raiz); + + //Atualiza somente a árvore de tabelas em um determinado esquema + void atualizarSubArvoreTabela(QTreeWidgetItem *raiz, ObjetoBase *esquema); + + //Atualiza a arvore de objetos + void atualizarArvoreObjetos(void); + + //Atualiza a lista de objetos + void atualizarListaObjetos(void); + + /* Gera um valor em um objeto QVariant para armazenamento dos + endereços dos objetos do modelo para armazenamento em + itens de QTreeWidgets e QListWidgetItem para permitir + a interação entre direta como os objetos sem selecioná-los + no modelo */ + QVariant gerarValorItem(ObjetoBase *objeto); + + /* Expande os itens da árvore até que o item refente ao objeto informado + no parâmetro esteja visível */ + void expandirItemArvore(ObjetoBase *objeto); + + public: + VisaoObjetosWidget(bool visao_simplificada=false, QWidget * parent = 0, Qt::WindowFlags f = 0); + void closeEvent(QCloseEvent *); + ObjetoBase *obterObjetoSelecao(void); + + private: + //Implementa a movimentação da janela quando esta é exibida de forma simplificada + void mouseMoveEvent(QMouseEvent *); + + public slots: + void definirModelo(ModeloWidget *modelo_wgt); + void definirModelo(ModeloBD *modelo_bd); + void mudarVisaoObjetos(void); + void atualizarVisaoObjetos(void); + void definirObjetoVisivel(TipoObjetoBase tipo_obj, bool visivel); + void close(void); + + private slots: + void definirObjetoVisivel(QListWidgetItem *item); + void definirTodosObjetosVisiveis(bool); + void selecionarObjeto(void); + void exibirMenuObjeto(void); + void editarObjeto(void); + + signals: + /* Sinais personalizados usados para sinalizarem + a modificação da visão de objetos. Este sinal é capturado pelo + form principal para atualizar as ferramentas */ + void s_visaoObjetosModificada(void); + void s_visibilityChanged(ObjetoBase *,bool); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/src/visaowidget.cpp b/libpgmodeler_ui/src/visaowidget.cpp new file mode 100644 index 000000000..d1602526a --- /dev/null +++ b/libpgmodeler_ui/src/visaowidget.cpp @@ -0,0 +1,453 @@ +#include "visaowidget.h" +//*********************************************************** +VisaoWidget::VisaoWidget(QWidget *parent): ObjetoBaseWidget(parent, OBJETO_VISAO) +{ + try + { + Ui_VisaoWidget::setupUi(this); + //QGridLayout *grid=NULL; + + //Cria um destacador de sintaxe no campo de expressão e código fonte + destaque_expr=NULL; + destaque_expr=new DestaqueSintaxe(expressao_txt, false); + destaque_expr->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + destaque_codigo=NULL; + destaque_codigo=new DestaqueSintaxe(codigo_txt, false); + destaque_codigo->carregarConfiguracao(AtributosGlobais::DIR_CONFIGURACOES + + AtributosGlobais::SEP_DIRETORIO + + AtributosGlobais::CONF_DESTAQUE_SQL + + AtributosGlobais::EXT_CONFIGURACAO); + + //Alocando os seletores de objetos (tabela e coluna) que são atribuídos às referências da visão + sel_tabela=NULL; + sel_tabela=new SeletorObjetoWidget(OBJETO_TABELA, true, this); + sel_coluna=NULL; + sel_coluna=new SeletorObjetoWidget(OBJETO_COLUNA, true, this); + + //Alocando a tabela que armazena todas as referências da visão + tab_referencias=new TabelaObjetosWidget(TabelaObjetosWidget::TODOS_BOTOES, true, this); + tab_referencias->definirNumColunas(4); + tab_referencias->definirRotuloCabecalho(trUtf8("Col./Expr."),0); + tab_referencias->definirRotuloCabecalho(trUtf8("Alias"),1); + tab_referencias->definirRotuloCabecalho(trUtf8("Alias Col."),2); + tab_referencias->definirRotuloCabecalho(trUtf8("SF FW AW"),3); + + //Gera o frame de informação sobre a referência a todas as colunas da tabela + frame_info=gerarFrameInformacao(trUtf8("Para se referenciar todas as colunas de uma tabela (*) basta não preencher\ + o campo Coluna, isso é equivalente a se \ + escrever [esquema].[tabela].*")); + + //grid=dynamic_cast(referencias_gb->layout()); + referencias_grid->addWidget(sel_tabela, 2,1,1,2); + referencias_grid->addWidget(sel_coluna, 3,1,1,2); + referencias_grid->addWidget(frame_info, 6, 0, 1, 0); + referencias_grid->addWidget(tab_referencias, 7,0,2,0); + + configurarLayouFormulario(visao_grid, OBJETO_VISAO); + + connect(janela_pai->aplicar_ok_btn,SIGNAL(clicked(bool)), this, SLOT(aplicarConfiguracao(void))); + connect(tipo_ref_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(selecionarTipoReferencia(void))); + + connect(sel_coluna, SIGNAL(s_objetoSelecionado(void)), this, SLOT(exibirNomeObjeto(void))); + connect(sel_coluna, SIGNAL(s_objetoRemovido(void)), this, SLOT(exibirNomeObjeto(void))); + connect(sel_tabela, SIGNAL(s_objetoSelecionado(void)), this, SLOT(exibirNomeObjeto(void))); + + connect(tab_referencias, SIGNAL(s_linhaAdicionada(int)), this, SLOT(manipularReferencia(int))); + connect(tab_referencias, SIGNAL(s_linhaAtualizada(int)), this, SLOT(manipularReferencia(int))); + connect(tab_referencias, SIGNAL(s_linhaEditada(int)), this, SLOT(editarReferencia(int))); + + connect(tab_referencias, SIGNAL(s_linhasMovidas(int,int)), this, SLOT(atualizarPrevisaoCodigo(void))); + connect(tab_referencias, SIGNAL(s_linhasRemovidas(void)), this, SLOT(atualizarPrevisaoCodigo(void))); + connect(tab_referencias, SIGNAL(s_linhaRemovida(int)), this, SLOT(atualizarPrevisaoCodigo(void))); + + janela_pai->setMinimumSize(650, 630); + selecionarTipoReferencia(); + } + catch(Excecao &e) + { + //Redireciona o erro + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void VisaoWidget::hideEvent(QHideEvent *evento) +{ + tab_referencias->removerLinhas(); + ObjetoBaseWidget::hideEvent(evento); +} +//---------------------------------------------------------- +void VisaoWidget::limparFormReferencia(void) +{ + sel_coluna->removerObjetoSelecionado(); + sel_tabela->removerObjetoSelecionado(); + alias_col_edt->clear(); + alias_exp_edt->clear(); + alias_tab_edt->clear(); + expressao_txt->clear(); + select_from_chk->setChecked(false); + from_where_chk->setChecked(false); + apos_where_chk->setChecked(false); +} +//---------------------------------------------------------- +void VisaoWidget::selecionarTipoReferencia(void) +{ + /* Marca na variável 'ref_obj' se o índice do combo de tipo de referência + se trata de uma referência a uma coluna */ + bool ref_obj=(tipo_ref_cmb->currentIndex()==static_cast(Referencia::REFER_COLUNA)); + + //Exibe todos os campos do formulário referentes à referência de coluna + tabela_lbl->setVisible(ref_obj); + coluna_lbl->setVisible(ref_obj); + sel_tabela->setVisible(ref_obj); + sel_coluna->setVisible(ref_obj); + alias_col_lbl->setVisible(ref_obj); + alias_col_edt->setVisible(ref_obj); + alias_tab_edt->setVisible(ref_obj); + alias_tab_lbl->setVisible(ref_obj); + frame_info->setVisible(ref_obj); + + /* Esconde todos os objetos que não são relacionados a refência a coluna + e sim a expressão */ + expressao_lbl->setVisible(!ref_obj); + expressao_txt->setVisible(!ref_obj); + alias_exp_edt->setVisible(!ref_obj); + alias_exp_lbl->setVisible(!ref_obj); +} +//---------------------------------------------------------- +void VisaoWidget::manipularReferencia(int idx_ref) +{ + try + { + Referencia ref; + + /* Se o combo de tipo de referência estiver selecionado como referência a uma coluna + cria uma referência como tal */ + if(static_cast(tipo_ref_cmb->currentIndex())==Referencia::REFER_COLUNA) + { + /* Chama o método de construtor de referência informando os parâmetros necessários + para relacioná-la a uma coluna de tabela */ + ref=Referencia(dynamic_cast(sel_tabela->obterObjeto()), + dynamic_cast(sel_coluna->obterObjeto()), + alias_tab_edt->text(), alias_col_edt->text()); + } + /* Se o combo de tipo de referência estiver selecionado como referência a uma expressão + cria uma referência como tal */ + else + { + //Chama o método de construção de uma referência a uma expressão + ref=Referencia(expressao_txt->toPlainText(), alias_tab_edt->text()); + } + + /* Obrigatoriamente, a referência deve possuir um aplicação SQL + (ver método adicionarReferencia() da classe Visao). No formulário + caso o usuário não marqui nenhuma aplição SQL, será disparado + um erro e a criação da referência será abortada */ + if(!select_from_chk->isChecked() && + !from_where_chk->isChecked() && + !apos_where_chk->isChecked()) + throw Excecao(ERR_PGMODELERUI_TIPOSQLINDEFREFVISAO,__PRETTY_FUNCTION__,__FILE__,__LINE__); + + //Exibe os dados da referência recém-criada na tabela de referências + exibirDadosReferencia(ref, select_from_chk->isChecked(), from_where_chk->isChecked(), + apos_where_chk->isChecked(), idx_ref); + + //Limpa o formulário e a seleção de linha na tabela + limparFormReferencia(); + tab_referencias->limparSelecao(); + } + catch(Excecao &e) + { + /* Caso o método esteja no meio de uma inserção de nova referência, + e um erro seja disparado, a nova linha da tabela precisa será + removida pois não será inserida nenhuma referência */ + if(tab_referencias->obterTextoCelula(idx_ref, 0).isEmpty()) + //Remove a linha da tabela + tab_referencias->removerLinha(idx_ref); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//---------------------------------------------------------- +void VisaoWidget::editarReferencia(int idx_ref) +{ + Referencia ref; + QString str_aux; + + //Obtém a referência da linha especificada por 'idx_ref' + ref=tab_referencias->obterDadoLinha(idx_ref).value(); + //Seleciona o tipo de referência no formulário de acordo com o tipo da referência obtida + tipo_ref_cmb->setCurrentIndex(ref.obterTipoReferencia()); + + //Caso seja uma referência a uma coluna + if(ref.obterTipoReferencia()==Referencia::REFER_COLUNA) + { + /* Verifica se a referência está ligada a uma coluna específica + ou a todas as colunas de uma tabela (* --> quando ref.obterColuna() == NULL) */ + if(ref.obterColuna()) + /* Define o objeto no seletor de coluna e automaticamente o seletor + de tabelas é definido com o objeto pai da coluna */ + sel_coluna->definirObjeto(ref.obterColuna()); + else + /* Caso a refência esteja ligada a todas a colunas da tabela (*) + configura o seletor de tabelas com a tabela usada na referência */ + sel_tabela->definirObjeto(ref.obterTabela()); + + //Configura os campos de alias de tabela e coluna com os valores da referência + alias_col_edt->setText(QString::fromUtf8(ref.obterAliasColuna())); + alias_tab_edt->setText(QString::fromUtf8(ref.obterAlias())); + } + //Caso seja uma referência a uma expressão + else + { + //Configura a caixa de texto de expressão com a expressão usada na referência + expressao_txt->setPlainText(QString::fromUtf8(ref.obterExpressao())); + //Configura o campo de alias de expressão com o valor presente na referência + alias_exp_edt->setText(QString::fromUtf8(ref.obterAlias())); + } + + /* Configura uma string de acordo com as aplicações SQL da referência. + Quando uma dada aplicação está marcada a mesma será exibida como '1' + caso contrário como '0'. O formato possível para esta strig será: + + [SELECT-FROM] [FROM-WHERE] [APÓS-WHERE] + 0|1 0|1 0|1 */ + str_aux=tab_referencias->obterTextoCelula(idx_ref,3); + select_from_chk->setChecked(str_aux[0]=='1'); + from_where_chk->setChecked(str_aux[1]=='1'); + apos_where_chk->setChecked(str_aux[2]=='1'); +} +//---------------------------------------------------------- +void VisaoWidget::exibirNomeObjeto(void) +{ + Coluna *col=NULL; + QObject *obj_sender=sender(); + + /* Caso o objeto sender seja o seletor de tabela, isso indica + que o usuário quer referenciar todas as colunas da tabela */ + if(obj_sender==sel_tabela) + { + /* Para isso, bloqueia os sinais do seletor de coluna pois qualquer + alteração sem bloqueio de sinal pode causar a chamada indefinida + a este método pois ambos os seletores estão conectados a este */ + sel_coluna->blockSignals(true); + /* Define como NULL o objeto no seletor de coluna indicado + que nenhuma coluna específica deve ser referenciada (*) */ + sel_coluna->removerObjetoSelecionado(); + //Reativa os sinais do seletor de coluna + sel_coluna->blockSignals(false); + } + /* Caso o objeto sender seja o seletor de tabela, isso indica + que o usuário quer referenciar uma coluna específica da tabela */ + else + { + //Obtém a coluna do seletor + col=dynamic_cast(sel_coluna->obterObjeto()); + + /* Bloqueia os sinais do seletor de tabela pois qualquer + alteração sem bloqueio de sinal pode causar a chamada indefinida + a este método pois ambos os seletores estão conectados a este */ + sel_tabela->blockSignals(true); + + /* Caso a coluna esteja alocada, o seletor de tabela recebe automaticamente + o nome da tabela pai desta coluna */ + if(col) + sel_tabela->definirObjeto(col->obterTabelaPai()); + else + sel_tabela->removerObjetoSelecionado(); + + //Reativa os sinais do seletor de tabela + sel_tabela->blockSignals(false); + } +} +//---------------------------------------------------------- +void VisaoWidget::exibirDadosReferencia(Referencia refer, bool selec_from, bool from_where, bool apos_where, unsigned idx_lin) +{ + Tabela *tab=NULL; + Coluna *col=NULL; + QString str_aux; + + //Caso a referência seja a uma coluna + if(refer.obterTipoReferencia()==Referencia::REFER_COLUNA) + { + //Obtém a tabela e coluna referenciadas + tab=refer.obterTabela(); + col=refer.obterColuna(); + + /* Caso a tabela esteja alocada e a coluna não, indica que a referência + será para todas as colunas (*), para isso exibe uma string + no formatdo: [NOME_ESQUEMA].[NOME_TABELA].* */ + if(tab && !col) + tab_referencias->definirTextoCelula(QString::fromUtf8(tab->obterNome(true) + QString(".*")),idx_lin,0); + /* Caso a tabela e coluna estejam alocadas indica que a referência + será para a coluna em questão para isso exibe uma string + no formatdo: [NOME_ESQUEMA].[NOME_TABELA].[NOME_COLUNA] */ + else + tab_referencias->definirTextoCelula(QString::fromUtf8(tab->obterNome(true) + QString(".") + col->obterNome(true)),idx_lin,0); + + //Exibe o alias da tabela e a exibe na segunda coluna da linha + tab_referencias->definirTextoCelula(QString::fromUtf8(refer.obterAlias()),idx_lin,1); + + /* Caso a coluna esteja alocada, exibe o alias da mesma na terceira coluna da linha + caso contrário exibe um '-' */ + if(col) + tab_referencias->definirTextoCelula(QString::fromUtf8(refer.obterAliasColuna()),idx_lin,2); + else + tab_referencias->definirTextoCelula(QString("-"),idx_lin,2); + } + //Caso seja uma referência a uma expressão + else + { + //Exibe a expressão na primeira coluna da linha + tab_referencias->definirTextoCelula(QString::fromUtf8(refer.obterExpressao()),idx_lin,0); + //Exibe o alias da expressão na segunda coluna da linha + tab_referencias->definirTextoCelula(QString::fromUtf8(refer.obterAlias()),idx_lin,1); + /* Exibe um '-' na terceira coluna que armazena o alias da coluna por este campo + não se aplicar a uma expressão */ + tab_referencias->definirTextoCelula(QString("-"),idx_lin,2); + } + + //Configura a string de aplicação SQL e exibe na quarta coluna + str_aux+=(selec_from ? "1" : "0"); + str_aux+=(from_where ? "1" : "0"); + str_aux+=(apos_where ? "1" : "0"); + tab_referencias->definirTextoCelula(str_aux,idx_lin,3); + + //Define a referência obtida como dado da linha + tab_referencias->definirDadoLinha(QVariant::fromValue(refer), idx_lin); + + /* Atualiza a previsão de código para exibir a nova referência + no código SQL da visão */ + atualizarPrevisaoCodigo(); +} +//---------------------------------------------------------- +void VisaoWidget::atualizarPrevisaoCodigo(void) +{ + Referencia refer; + QString str_aux; + unsigned i, qtd, i1, tipo_exp[3]={Referencia::SQL_REFER_SELECT, + Referencia::SQL_REFER_FROM, + Referencia::SQL_REFER_WHERE}; + try + { + /* Remove todas as referências da visão auxiliar para inserção daquelas + presente na tabela */ + visao_aux.removerReferencias(); + + //Configura o nome da visão com o que está no formulário + visao_aux.definirNome(nome_edt->text()); + + //Configura o esquema da visão com o que está no formulário + visao_aux.definirEsquema(sel_esquema->obterObjeto()); + + /* Insere as referências da tabela na visão auxiliar + porém estas são inseridas conforme a string de + aplicação sql */ + qtd=tab_referencias->obterNumLinhas(); + for(i=0; i < qtd; i++) + { + //Obtém a referência da tabela + refer=tab_referencias->obterDadoLinha(i).value(); + //Obtém a string de aplicação + str_aux=tab_referencias->obterTextoCelula(i,3); + + //Varre a string de aplicação. + for(i1=0; i1 < 3; i1++) + { + /* Caso a string na posição atual (SELECT-FROM|FROM-WHERE|Após WHERE] + esteja marcada com um 1, a referência será inserida no final da + lista de referências cuja aplicação seja a atual */ + if(str_aux[i1]=='1') + visao_aux.adicionarReferencia(refer, tipo_exp[i1]); + } + } + //Exibe o código fonte da visão auxliar, para refletir a configuração atual da mesma + codigo_txt->setPlainText(QString::fromUtf8(visao_aux.obterDefinicaoObjeto(ParserEsquema::DEFINICAO_SQL))); + } + catch(Excecao &e) + { + /* Caso algum erro seja disparado durante a configuração da visão auxiliar + exibe uma mensagem ao usuário no próprio campo de código fonte */ + codigo_txt->setPlainText(trUtf8("-- Impossível gerar código. Verifique se todos os atributos foram preenchidos corretamente! --")); + } +} +//---------------------------------------------------------- +void VisaoWidget::definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Visao *visao, float px, float py) +{ + unsigned i, qtd; + bool sel_from, from_where, apos_where; + Referencia refer; + + //Preenchendo os campos básicos do formulário com os atributos da visão + ObjetoBaseWidget::definirAtributos(modelo,lista_op, visao, NULL, px, py); + + //Configurado o modelo de banco de dados referênciado pelos widget seletores + sel_coluna->definirModelo(modelo); + sel_tabela->definirModelo(modelo); + + //Caso a visão esteja alocada (sendo editada) + if(visao) + { + //Obtém o número de referências da visão + qtd=visao->obterNumReferencias(); + + /* Bloqueia os sinais da tabela de referências para inserção de vários + itens sem disparo de sinais */ + tab_referencias->blockSignals(true); + for(i=0; i < qtd; i++) + { + tab_referencias->adicionarLinha(); + + //Obtém a referência da visão + refer=visao->obterReferencia(i); + + //Verifica qual a aplicação SQL da referência na visão + sel_from=(visao->obterIndiceReferencia(refer,Referencia::SQL_REFER_SELECT) >= 0); + from_where=(visao->obterIndiceReferencia(refer,Referencia::SQL_REFER_FROM) >= 0); + apos_where=(visao->obterIndiceReferencia(refer,Referencia::SQL_REFER_WHERE)>= 0); + + //Exibe a referência na tabela + exibirDadosReferencia(refer, sel_from, from_where, apos_where, i); + } + //Desbloqueia os sinais da tabela + tab_referencias->blockSignals(false); + //Limpa a seleção da tabela + tab_referencias->limparSelecao(); + } +} +//--------------------------------------------------------- +void VisaoWidget::aplicarConfiguracao(void) +{ + try + { + Visao *visao=NULL; + + iniciarConfiguracao(); + + //Obtém a referência à visao que está sendo editada/criada + visao=dynamic_cast(this->objeto); + + //Faz a cópia da visão auxiliar para a visão que está sendo editada + (*visao)=visao_aux; + + //Restaura a posição original da visão + //visao->definirPosicaoObjeto(QPointF(this->px_objeto, this->py_objeto)); + + //Finaliza a configuração da função de agregação + ObjetoBaseWidget::aplicarConfiguracao(); + + this->modelo->atualizarRelTabelaVisao(visao); + finalizarConfiguracao(); + } + catch(Excecao &e) + { + /* Cancela a configuração o objeto removendo a ultima operação adicionada + referente ao objeto editado/criado e desaloca o objeto + caso o mesmo seja novo */ + cancelarConfiguracao(); + throw Excecao(e.obterMensagemErro(),e.obterTipoErro(),__PRETTY_FUNCTION__,__FILE__,__LINE__, &e); + } +} +//*********************************************************** diff --git a/libpgmodeler_ui/src/visaowidget.h b/libpgmodeler_ui/src/visaowidget.h new file mode 100644 index 000000000..ad6aede34 --- /dev/null +++ b/libpgmodeler_ui/src/visaowidget.h @@ -0,0 +1,103 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: Biblioteca libpgsqldbm_ui +# Classe: VisaoWidget +# Descrição: Definição da classe que implementa o formulário de +# edição dos atributos de visões. +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef VISAO_WIDGET_H +#define VISAO_WIDGET_H + +#include +#include "objetobasewidget.h" +#include "ui_visaowidget.h" +#include "tabelaobjetoswidget.h" + +/* Declarando a classe Referencia como metatype para que esta + possa ser usada em conjunto com a classe QVariant (vide documentação + da classe QVariant e QMetaType). Esta declaração é uma macro específica + do Qt e está sendo usada para facilitar o uso com classes que necessitam + armazenar instancias de classes em seus containeres (TabelaObjetosWidget). + Essa declaração não afeta o comportamento das demais classes que de algum + modo referenciam a classe Referencia.*/ +#include +Q_DECLARE_METATYPE(Referencia) +//*********************************************************** +class VisaoWidget: public ObjetoBaseWidget, public Ui::VisaoWidget { + Q_OBJECT + + private: + //Frame usado como dica para criação de uma referência a todas as colunas de uma tabela + QFrame *frame_info; + + /* Esta instância de visão é usada para receber todos os atributos configurados no formulário. + Uma vez atribuídos os dados e validados a mesma tem seus atributos copiados para a visão + que realemente precisa ser modificada/criada (this->objeto) */ + Visao visao_aux; + + //Tabela de listagem das referências cadastradas para a visão + TabelaObjetosWidget *tab_referencias; + + //Destacador de sintaxe usado no campo de expressão e de código fonte da visão + DestaqueSintaxe *destaque_expr, + *destaque_codigo; + + //Seletores de tabela e coluna relacionados à visao + SeletorObjetoWidget *sel_tabela, + *sel_coluna; + + //Exibe os dados de uma dada referência na tabela de referências + void exibirDadosReferencia(Referencia refer, bool selec_from, bool from_where, + bool apos_where, unsigned idx_ref); + + //Método auxiliar que limpa os campos do formulário de referências + void limparFormReferencia(void); + + public: + VisaoWidget(QWidget * parent = 0); + void definirAtributos(ModeloBD *modelo, ListaOperacoes *lista_op, Visao *visao, float px, float py); + + private slots: + void hideEvent(QHideEvent *); + + /* Exibe os campos necessários no formulário conforme o + tipo de referencia selecionado */ + void selecionarTipoReferencia(void); + + /* Cria uma referência com base no que está no formulário + e a exibe na tabela no índice informado no parâmetro */ + void manipularReferencia(int); + + /* Obtém a referência na linha especificada no parâmetro + e exibe seus dados no formulário para edição */ + void editarReferencia(int); + + /* Controla a forma como é exibida os nomes da tabela e coluna + selecionada na referência */ + void exibirNomeObjeto(void); + + /* Atualiza o campo de código fonte da visão. Este campo + é preenchido com o código gerado pelo atributo 'visao_aux' */ + void atualizarPrevisaoCodigo(void); + + public slots: + void aplicarConfiguracao(void); +}; +//*********************************************************** +#endif diff --git a/libpgmodeler_ui/ui/bancodadoswidget.ui b/libpgmodeler_ui/ui/bancodadoswidget.ui new file mode 100644 index 000000000..9cd1944d5 --- /dev/null +++ b/libpgmodeler_ui/ui/bancodadoswidget.ui @@ -0,0 +1,237 @@ + + + BancoDadosWidget + + + + 0 + 0 + 394 + 142 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 96 + 0 + + + + BD Modelo: + + + + + + + + 0 + 25 + + + + + + + + + 0 + 0 + + + + Autor do Modelo: + + + + + + + + 0 + 25 + + + + + + + + + 0 + 0 + + + + + 96 + 0 + + + + Codificação: + + + + + + + + 0 + 25 + + + + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 50 + false + false + + + + LC_COLLATE: + + + + + + + + 0 + 25 + + + + QComboBox::InsertAlphabetically + + + + + + + + 0 + 0 + + + + + 96 + 0 + + + + + 50 + false + false + + + + Conexões: + + + + + + + + 0 + 25 + + + + -1 + + + 65535 + + + -1 + + + + + + + + 0 + 0 + + + + + 70 + 0 + + + + + 50 + false + false + + + + LC_CTYPE: + + + + + + + + 0 + 25 + + + + QComboBox::InsertAlphabetically + + + + + + + + diff --git a/libpgmodeler_ui/ui/caixamensagem.ui b/libpgmodeler_ui/ui/caixamensagem.ui new file mode 100644 index 000000000..accbb87cb --- /dev/null +++ b/libpgmodeler_ui/ui/caixamensagem.ui @@ -0,0 +1,514 @@ + + + CaixaMensagem + + + Qt::ApplicationModal + + + + 0 + 0 + 500 + 210 + + + + + 0 + 0 + + + + + 500 + 210 + + + + Dialog + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + + 2 + + + 4 + + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + background-image: url(:/imagens/imagens/barra_logo_meio_cinza.png); background-repeat: repeat-y; +border: 1px #ff00ff solid; + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 60 + 82 + + + + + 60 + 82 + + + + + + + :/imagens/imagens/barra_logo_topo.png + + + + + + + Qt::Vertical + + + + 20 + 15 + + + + + + + + + 60 + 119 + + + + + 60 + 119 + + + + + + + :/imagens/imagens/barra_logo_base.png + + + + + + + + + + + 0 + 0 + + + + + 432 + 168 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + 0 + + + 2 + + + + + Qt::Horizontal + + + + 361 + 27 + + + + + + + + + 30 + 30 + + + + Exibir/Esconder pilha de exceções. + + + ... + + + + :/icones/icones/refazer.png:/icones/icones/refazer.png + + + + 22 + 22 + + + + true + + + + + + + + + + 0 + 0 + + + + + 424 + 122 + + + + QFrame::NoFrame + + + QFrame::Plain + + + 0 + + + + + 0 + + + 0 + + + + + 2 + + + + + + 40 + 40 + + + + + 40 + 40 + + + + + + + :/icones/icones/msgbox_erro.png + + + Qt::AlignCenter + + + + + + + true + + + + 0 + 0 + + + + + 0 + 40 + + + + + 16777215 + 16777215 + + + + false + + + false + + + + + + mensagem + + + Qt::AutoText + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + 1 + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + Qt::Vertical + + + + 37 + 26 + + + + + + + + + + + + 2 + + + 2 + + + 0 + + + 0 + + + 0 + + + + + + 8 + + + + 1 + + + 1 + + + 16 + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::NoSelection + + + QAbstractItemView::SelectItems + + + 15 + + + false + + + false + + + false + + + + Exceções + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 298 + 27 + + + + + + + + + 0 + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + &Sim + + + + :/icones/icones/confirmar.png:/icones/icones/confirmar.png + + + true + + + false + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + &Não + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + + + + + + 90 + 32 + + + + Cancelar + + + + :/icones/icones/msgbox_erro.png:/icones/icones/msgbox_erro.png + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/caixatextowidget.ui b/libpgmodeler_ui/ui/caixatextowidget.ui new file mode 100644 index 000000000..9fd7ff176 --- /dev/null +++ b/libpgmodeler_ui/ui/caixatextowidget.ui @@ -0,0 +1,121 @@ + + + CaixaTextoWidget + + + + 0 + 0 + 578 + 204 + + + + Form + + + + 2 + + + 6 + + + + + + + Negrito + + + + + + + Itálico + + + + + + + + + Qt::Horizontal + + + + 365 + 21 + + + + + + + + + + + + + + + + 45 + 23 + + + + + 45 + 23 + + + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + + + 0 + 0 + 0 + + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/classeoperadoreswidget.ui b/libpgmodeler_ui/ui/classeoperadoreswidget.ui new file mode 100644 index 000000000..29d64057e --- /dev/null +++ b/libpgmodeler_ui/ui/classeoperadoreswidget.ui @@ -0,0 +1,218 @@ + + + ClasseOperadoresWidget + + + + 0 + 0 + 489 + 194 + + + + + 0 + 0 + + + + Form + + + + + 85 + 5 + 25 + 21 + + + + + + + + + + 4 + 4 + 91 + 16 + + + + + 0 + 0 + + + + + 90 + 0 + + + + Classe Padrão: + + + + + + 114 + 4 + 68 + 16 + + + + + 0 + 0 + + + + + 68 + 0 + + + + Indexação: + + + + + + 178 + 4 + 78 + 24 + + + + + + + 0 + 50 + 481 + 141 + + + + Elementos + + + + 4 + + + 6 + + + + + Tipo de Elemento: + + + + + + + + 0 + 0 + + + + + Operador + + + + + Função + + + + + Armazenamento + + + + + + + + Qt::Horizontal + + + + 271 + 20 + + + + + + + + Função: + + + + + + + Operador: + + + + + + + Suporte/Estratégia: + + + + + + + 1 + + + + + + + Rechecar + + + + + + + + + 4 + 32 + 68 + 16 + + + + + 68 + 0 + + + + Família: + + + + + + diff --git a/libpgmodeler_ui/ui/codigofontewidget.ui b/libpgmodeler_ui/ui/codigofontewidget.ui new file mode 100644 index 000000000..598bd6ce3 --- /dev/null +++ b/libpgmodeler_ui/ui/codigofontewidget.ui @@ -0,0 +1,234 @@ + + + CodigoFonteWidget + + + + 0 + 0 + 515 + 336 + + + + Form + + + + 2 + + + 6 + + + + + + + + 50 + 0 + + + + + 50 + 16777215 + + + + Versão: + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + + 0 + 0 + + + + + 75 + 0 + + + + + 65 + 16777215 + + + + + true + + + + PostgreSQL + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QComboBox::InsertAtBottom + + + + + + + Qt::Horizontal + + + + 28 + 20 + + + + + + + + + 32 + 32 + + + + + 32 + 32 + + + + iconecodigo + + + + + + + + + QTabWidget::North + + + 0 + + + + SQL + + + + 4 + + + 6 + + + + + + DejaVu Sans Mono + 9 + + + + false + + + QTextEdit::NoWrap + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + XML + + + + 4 + + + 6 + + + + + + DejaVu Sans Mono + 9 + + + + false + + + QTextEdit::NoWrap + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans Mono'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p></body></html> + + + true + + + Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/colunawidget.ui b/libpgmodeler_ui/ui/colunawidget.ui new file mode 100644 index 000000000..59a87efaa --- /dev/null +++ b/libpgmodeler_ui/ui/colunawidget.ui @@ -0,0 +1,107 @@ + + + ColunaWidget + + + + 0 + 0 + 347 + 52 + + + + Form + + + + 2 + + + 6 + + + + + + 80 + 0 + + + + + 75 + 16777215 + + + + Valor Padrão: + + + + + + + + 16777215 + 25 + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + false + + + Qt::TextEditorInteraction + + + + + + + Não-Nulo: + + + + + + + + + + + + + + Qt::Horizontal + + + + 240 + 20 + + + + + + + + + diff --git a/libpgmodeler_ui/ui/confaparenciawidget.ui b/libpgmodeler_ui/ui/confaparenciawidget.ui new file mode 100644 index 000000000..41409ec70 --- /dev/null +++ b/libpgmodeler_ui/ui/confaparenciawidget.ui @@ -0,0 +1,472 @@ + + + ConfAparenciaWidget + + + + 0 + 0 + 400 + 131 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + Elemento: + + + + + + + + Global: Estilo de fonte + + + + + Global: Descritor de restrições + + + + + Global: Seleção de objetos + + + + + Global: Texto informativo de posição + + + + + Global: Caixa do informativo de posição + + + + + Global: Tipo de objetos + + + + + Global: Arco de cadeado + + + + + Global: Corpo do cadeado + + + + + Tabela: Nome de esquema + + + + + Tabela: Nome de tabela + + + + + Tabela: Caixa de colunas + + + + + Tabela: Caixa de atributos extendidos + + + + + Tabela: Caixa de título + + + + + Regra: Nome de regra + + + + + Regra: Descritor + + + + + Índice: Nome de índice + + + + + Índice: Descritor + + + + + Gatilho: Nome de gatilho + + + + + Gatilho: Descritor + + + + + Visão: Nome de esquema + + + + + Visão: Nome de visão + + + + + Visão: Caixa de referências + + + + + Visão: Caixa de título + + + + + Visão: Alias de tabela / coluna + + + + + Visão: Coluna referenciada + + + + + Visão: Tabela referenciada + + + + + Visão: Descritor de referência + + + + + Caixa de Texto: Corpo + + + + + Coluna: Nome de coluna + + + + + Coluna: Descritor + + + + + Coluna: Incluída / Herdada por relacionamento + + + + + Coluna: Protegida + + + + + Coluna (pk): Nome de coluna + + + + + Coluna (pk): Descritor + + + + + Coluna (fk): Nome de coluna + + + + + Coluna (fk): Descritor + + + + + Coluna (uq): Nome de coluna + + + + + Coluna (uq): Descritor + + + + + Coluna (nn): Nome de coluna + + + + + Coluna (nn): Descritor + + + + + Relacionamento: Descritor + + + + + Relacionamento: Texto do rótulo + + + + + Relacionamento: Caixa do rótulo + + + + + Relacionamento: Texto do atributo + + + + + Relacionamento: Descritor do atributo + + + + + + + + + 0 + 0 + + + + Fonte: + + + + + + + + 0 + 0 + + + + + + + + 0 + + + + + 1 + + + 5.000000000000000 + + + 100.000000000000000 + + + 0.500000000000000 + + + 8.000000000000000 + + + + + + + pt + + + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Negrito + + + + + + + + 0 + 0 + + + + + 50 + false + + + + Itálico + + + + + + + + 0 + 0 + + + + Cores: + + + + + + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + Cor da fonte / preenchimento 1 + + + + + + + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + Cor de preenchimento 2 + + + + + + + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + Cor da borda + + + + + + + + + + Qt::Horizontal + + + + 188 + 20 + + + + + + + + + + + 0 + 0 + + + + Sublinhado + + + + + + + + diff --git a/libpgmodeler_ui/ui/confconexoeswidget.ui b/libpgmodeler_ui/ui/confconexoeswidget.ui new file mode 100644 index 000000000..70d60e6f8 --- /dev/null +++ b/libpgmodeler_ui/ui/confconexoeswidget.ui @@ -0,0 +1,682 @@ + + + ConfConexoesWidget + + + + 0 + 0 + 519 + 461 + + + + Form + + + + 2 + + + 6 + + + + + Conexões: + + + + + + + 6 + + + + + QComboBox::InsertAlphabetically + + + + + + + true + + + + 30 + 25 + + + + Criar nova conexão + + + + + + + :/icones/icones/novo.png:/icones/icones/novo.png + + + + + + + true + + + + 30 + 25 + + + + Cancelar edição + + + + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + + + + + false + + + + 30 + 25 + + + + Editar conexão selecionada + + + + + + + :/icones/icones/editar.png:/icones/icones/editar.png + + + + + + + false + + + + 30 + 25 + + + + Excluir conexão selecionada + + + + + + + :/icones/icones/excluir.png:/icones/icones/excluir.png + + + + + + + + + + 0 + 10 + + + + QFrame::HLine + + + QFrame::Raised + + + + + + + + 0 + 0 + + + + Alias Conexão: + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + BD Conexão: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + 0 + + + + Host/Porta: + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + 1025 + + + 65535 + + + 5432 + + + + + + + + + + 0 + 0 + + + + Usuário: + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + 0 + 0 + + + + Senha: + + + + + + + + + + + 0 + 0 + + + + Timeout: + + + + + + + + + 2 + + + + + + + + 0 + 0 + + + + segundo(s) + + + + + + + + + + 0 + 0 + + + + Modo SSL: + + + + + + + + 200 + 0 + + + + + Desativado + + + + + Permitir + + + + + Requerido + + + + + Verificação de AC + + + + + Verificação Completa + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + + 0 + 0 + + + + Certificado Cliente: + + + + + + + false + + + ~/.postgresql/postgresql.crt + + + + + + + + + + false + + + + 0 + 0 + + + + Chave Cliente: + + + + + + + false + + + ~/.postgresql/postgresql.key + + + + + + + + + + false + + + + 0 + 0 + + + + Certificado Raiz: + + + + + + + false + + + ~/.postgresql/root.crt + + + + + + + + + + false + + + + 0 + 0 + + + + Cert. Revogados: + + + + + + + false + + + ~/.postgresql/root.crl + + + + + + + + + + true + + + + 0 + 0 + + + + Servidor Kerberus: + + + + + + + + + true + + + + + + + + 0 + 0 + + + + Forçar GSSAPI + + + + + + + + + + 0 + 0 + + + + Opções: + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + false + + + + 100 + 25 + + + + + 90 + 25 + + + + Adicionar + + + + :/icones/icones/adicionar.png:/icones/icones/adicionar.png + + + + + + + false + + + + 100 + 25 + + + + + 90 + 25 + + + + Atualizar + + + + :/icones/icones/padroes.png:/icones/icones/padroes.png + + + + + + + false + + + + 100 + 25 + + + + + 90 + 25 + + + + Testar + + + + :/icones/icones/conexaobd.png:/icones/icones/conexaobd.png + + + + + + + + + Qt::Vertical + + + + 20 + 0 + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/confgeralwidget.ui b/libpgmodeler_ui/ui/confgeralwidget.ui new file mode 100644 index 000000000..5712521c6 --- /dev/null +++ b/libpgmodeler_ui/ui/confgeralwidget.ui @@ -0,0 +1,728 @@ + + + ConfGeralWidget + + + + 0 + 0 + 481 + 288 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 120 + 0 + + + + Tamanho da grade: + + + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + 10 + + + 100 + + + 1 + + + 20 + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 16777215 + 16777215 + + + + pixels + + + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + Histórico de operações: + + + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + 500 + + + 1000 + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 16777215 + 16777215 + + + + itens + + + + + + + + + + 0 + 0 + + + + + 160 + 0 + + + + Salvar modelo a cada: + + + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + 1 + + + 30 + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 16777215 + 16777215 + + + + minuto(s) + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Salvar posição de widgets + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Salvar sessão atual + + + + + + + + 0 + 10 + + + + QFrame::HLine + + + QFrame::Raised + + + + + + + + 0 + 0 + + + + Papel: + + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + 0 + + + + A0 (841 x 1189 mm) + + + + + A1 (594 x 841 mm) + + + + + A2 (420 x 594 mm) + + + + + A3 (297 x 420 mm) + + + + + A4 (210 x 297 mm) + + + + + A5 (148 x 210 mm) + + + + + A6 (105 x 148 mm) + + + + + A7 (74 x 105 mm) + + + + + A8 (52 x 74 mm) + + + + + A9 (37 x 52 mm) + + + + + B0 (1030 x 1456 mm) + + + + + B1 (728 x 1030 mm) + + + + + B10 (32 x 45 mm) + + + + + B2 (515 x 728 mm) + + + + + B3 (364 x 515 mm) + + + + + B4 (257 x 364 mm) + + + + + B5 (182 x 257 mm) + + + + + B6 (128 x 182 mm) + + + + + B7 (91 x 128 mm) + + + + + B8 (64 x 91 mm) + + + + + B9 (45 x 64 mm) + + + + + C5E (163 x 229 mm) + + + + + Comm10E (105 x 241 mm) + + + + + DLE (110 x 220 mm) + + + + + Executive (191 x 254 mm) + + + + + Folio (210 x 330 mm) + + + + + Ledger (432 x 279 mm) + + + + + Legal (216 x 356 mm) + + + + + Letter (216 x 279 mm) + + + + + Tabloid (279 x 432 mm) + + + + + Personalizado (Baseado nas margens) + + + + + + + + + 0 + 0 + + + + Orientação: + + + + + + + + + + 0 + 0 + + + + Retrato + + + + + + + + 0 + 0 + + + + Paisagem + + + true + + + + + + + + + + 0 + 0 + + + + Margens: + + + + + + + + 0 + 0 + + + + 0 + + + + Milímetros + + + + + Pixels + + + + + Polegadas + + + + + Centímetros + + + + + + + + + + Esq.: + + + + + + + + 0 + 0 + + + + + 50 + 23 + + + + Margem esquerda + + + 5000.000000000000000 + + + + + + + Topo: + + + + + + + + 0 + 0 + + + + + 50 + 23 + + + + Margem topo + + + 5000.000000000000000 + + + + + + + Dir.: + + + + + + + + 0 + 0 + + + + + 50 + 23 + + + + Margem direita + + + 5000.000000000000000 + + + + + + + Base: + + + + + + + + 0 + 0 + + + + + 50 + 23 + + + + Margem base + + + 5000.000000000000000 + + + + + + + + + Qt::Horizontal + + + + 181 + 22 + + + + + + + + Qt::Vertical + + + + 20 + 30 + + + + + + + + + diff --git a/libpgmodeler_ui/ui/conversaocodificacaowidget.ui b/libpgmodeler_ui/ui/conversaocodificacaowidget.ui new file mode 100644 index 000000000..a5ab87d32 --- /dev/null +++ b/libpgmodeler_ui/ui/conversaocodificacaowidget.ui @@ -0,0 +1,179 @@ + + + ConversaoCodificacaoWidget + + + + 0 + 0 + 439 + 74 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 107 + 0 + + + + + 16777215 + 16777215 + + + + Codificação Origem: + + + + + + + true + + + + 0 + 25 + + + + + + + + + 0 + 0 + + + + + 107 + 0 + + + + + 16777215 + 16777215 + + + + Codificação Destino: + + + + + + + true + + + + 0 + 25 + + + + + + + + + 0 + 0 + + + + + 138 + 0 + + + + + 121 + 16777215 + + + + Função de Conversão: + + + + + + + Qt::Horizontal + + + + 273 + 20 + + + + + + + + + 0 + 0 + + + + + 50 + 0 + + + + + 16777215 + 16777215 + + + + Conversão Padrão: + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/conversaotipowidget.ui b/libpgmodeler_ui/ui/conversaotipowidget.ui new file mode 100644 index 000000000..e18b50373 --- /dev/null +++ b/libpgmodeler_ui/ui/conversaotipowidget.ui @@ -0,0 +1,162 @@ + + + ConversaoTipoWidget + + + + 0 + 0 + 446 + 78 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 121 + 0 + + + + + 121 + 16777215 + + + + Tipo da Conversão: + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + Implícita + + + true + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + 80 + 16777215 + + + + Atribuição + + + + + + + + 0 + 0 + + + + Entrada / Saída + + + + + + + + 0 + 0 + + + + + 138 + 0 + + + + + 121 + 16777215 + + + + Função de Conversão: + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + diff --git a/libpgmodeler_ui/ui/dominiowidget.ui b/libpgmodeler_ui/ui/dominiowidget.ui new file mode 100644 index 000000000..b76d056f2 --- /dev/null +++ b/libpgmodeler_ui/ui/dominiowidget.ui @@ -0,0 +1,102 @@ + + + DominioWidget + + + + 0 + 0 + 434 + 106 + + + + Form + + + + 2 + + + 6 + + + + + Não-Nulo: + + + + + + + + + + + + + + Valor Padrão: + + + + + + + + + + Nome da Restrição: + + + + + + + + + + Expressão de Checagem: + + + + + + + + 0 + 0 + + + + + 16777215 + 25 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + + true + + + QTextEdit::NoWrap + + + Qt::TextEditorInteraction + + + + + + + + diff --git a/libpgmodeler_ui/ui/espacotabelawidget.ui b/libpgmodeler_ui/ui/espacotabelawidget.ui new file mode 100644 index 000000000..61345bacc --- /dev/null +++ b/libpgmodeler_ui/ui/espacotabelawidget.ui @@ -0,0 +1,61 @@ + + + EspacoTabelaWidget + + + + 0 + 0 + 239 + 37 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + Diretório: + + + + + + + + 0 + 25 + + + + + false + + + + Qt::ImhNone + + + false + + + + + + + + diff --git a/libpgmodeler_ui/ui/familiaoperadoreswidget.ui b/libpgmodeler_ui/ui/familiaoperadoreswidget.ui new file mode 100644 index 000000000..e99a5de35 --- /dev/null +++ b/libpgmodeler_ui/ui/familiaoperadoreswidget.ui @@ -0,0 +1,68 @@ + + + FamiliaOperadoresWidget + + + + 0 + 0 + 243 + 24 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 68 + 0 + + + + Indexação: + + + + + + + + + + Qt::Horizontal + + + + 86 + 20 + + + + + + + + + diff --git a/libpgmodeler_ui/ui/formbasico.ui b/libpgmodeler_ui/ui/formbasico.ui new file mode 100644 index 000000000..b04067eb2 --- /dev/null +++ b/libpgmodeler_ui/ui/formbasico.ui @@ -0,0 +1,240 @@ + + + FormBasico + + + Qt::ApplicationModal + + + + 0 + 0 + 662 + 534 + + + + + 250 + 0 + + + + Dialog + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + + 2 + + + 4 + + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + background-image: url(:/imagens/imagens/barra_logo_meio_cinza.png); background-repeat: repeat-y; +border: 1px #ff00ff solid; + + + + 0 + + + 0 + + + + + + 60 + 81 + + + + + 60 + 81 + + + + + + + :/imagens/imagens/barra_logo_topo.png + + + + + + + Qt::Vertical + + + + 20 + 103 + + + + + + + + + 0 + 0 + + + + + 60 + 119 + + + + + 60 + 119 + + + + + + + :/imagens/imagens/barra_logo_base.png + + + + + + + + + + 4 + + + 2 + + + 0 + + + + + Qt::Horizontal + + + + 91 + 27 + + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + &Aplicar + + + + :/icones/icones/confirmar.png:/icones/icones/confirmar.png + + + true + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + &Cancelar + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + false + + + + + + + + + + 0 + 40 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + 0 + + + + + 0 + + + 0 + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/formconfiguracao.ui b/libpgmodeler_ui/ui/formconfiguracao.ui new file mode 100644 index 000000000..af79da0c2 --- /dev/null +++ b/libpgmodeler_ui/ui/formconfiguracao.ui @@ -0,0 +1,487 @@ + + + FormConfiguracao + + + Qt::ApplicationModal + + + + 0 + 0 + 630 + 530 + + + + + 0 + 0 + + + + + 630 + 530 + + + + Configurações do pgModeler + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + + 2 + + + 4 + + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + background-image: url(:/imagens/imagens/barra_logo_meio_cinza.png); background-repeat: repeat-y; +border: 1px #ff00ff solid; + + + + 0 + + + 0 + + + + + + 60 + 81 + + + + + 60 + 81 + + + + + + + :/imagens/imagens/barra_logo_topo.png + + + + + + + Qt::Vertical + + + + 20 + 103 + + + + + + + + + 0 + 0 + + + + + 60 + 119 + + + + + 60 + 119 + + + + + + + :/imagens/imagens/barra_logo_base.png + + + + + + + + + + 2 + + + 2 + + + 0 + + + + + Qt::Horizontal + + + + 91 + 27 + + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + &Aplicar + + + + :/icones/icones/confirmar.png:/icones/icones/confirmar.png + + + true + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + &Cancelar + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + false + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + Padrões + + + + :/icones/icones/padroes.png:/icones/icones/padroes.png + + + false + + + false + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + 2 + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + 90 + 16777215 + + + + + 9 + + + + QFrame::StyledPanel + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + QAbstractItemView::NoEditTriggers + + + false + + + QAbstractItemView::NoDragDrop + + + false + + + + 32 + 32 + + + + Qt::ElideLeft + + + QListView::Static + + + QListView::TopToBottom + + + true + + + QListView::Adjust + + + QListView::Batched + + + 8 + + + QListView::IconMode + + + 0 + + + true + + + 200 + + + false + + + false + + + 0 + + + + Geral + + + AlignHCenter|AlignVCenter|AlignCenter + + + + :/icones/icones/config.png:/icones/icones/config.png + + + ItemIsSelectable|ItemIsEnabled + + + + + Aparência + + + AlignHCenter|AlignVCenter|AlignCenter + + + + :/icones/icones/aparencia.png:/icones/icones/aparencia.png + + + ItemIsSelectable|ItemIsEnabled + + + + + Conexões + + + AlignHCenter|AlignVCenter|AlignCenter + + + + :/icones/icones/conexaobd.png:/icones/icones/conexaobd.png + + + ItemIsSelectable|ItemIsEnabled + + + + + + + + + 0 + 0 + + + + Qt::LeftToRight + + + 0 + + + + + 1 + + + + + + 420 + 250 + + + + QFrame::Box + + + QFrame::Sunken + + + + + + + + + 1 + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + + + + 1 + + + + + QFrame::Box + + + QFrame::Sunken + + + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/formexportacao.ui b/libpgmodeler_ui/ui/formexportacao.ui new file mode 100644 index 000000000..be1eee41f --- /dev/null +++ b/libpgmodeler_ui/ui/formexportacao.ui @@ -0,0 +1,1008 @@ + + + FormExportacao + + + Qt::ApplicationModal + + + + 0 + 0 + 580 + 535 + + + + + 0 + 0 + + + + + 580 + 450 + + + + + 580 + 535 + + + + Exportação do Modelo + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + + 2 + + + 4 + + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + background-image: url(:/imagens/imagens/barra_logo_meio_cinza.png); background-repeat: repeat-y; +border: 1px #ff00ff solid; + + + + 0 + + + 0 + + + + + + 60 + 81 + + + + + 60 + 81 + + + + + + + :/imagens/imagens/barra_logo_topo.png + + + + + + + Qt::Vertical + + + + 20 + 103 + + + + + + + + + 0 + 0 + + + + + 60 + 119 + + + + + 60 + 119 + + + + + + + :/imagens/imagens/barra_logo_base.png + + + + + + + + + + 4 + + + 2 + + + 0 + + + + + Qt::Horizontal + + + + 91 + 27 + + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + &Exportar + + + + :/icones/icones/exportar.png:/icones/icones/exportar.png + + + true + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + &Fechar + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + false + + + + + + + + + true + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 4 + + + + + + 0 + 0 + + + + + 13 + 75 + true + + + + Selecione o tipo de exportação do modelo: + + + + + + + + 0 + 15 + + + + QFrame::HLine + + + QFrame::Raised + + + + + + + 15 + + + + + Exportação para arquivo: + + + + + + + + 0 + 0 + + + + + 73 + 0 + + + + Arquivo: + + + + + + + + + false + + + true + + + + + + + + 30 + 23 + + + + Selecionar arquivo de destino + + + ... + + + + :/icones/icones/abrir.png:/icones/icones/abrir.png + + + + 16 + 16 + + + + + + + + + + + 0 + 0 + + + + + 50 + 100 + + + + + 50 + 100 + + + + + + + :/imagens/imagens/model2sql.png + + + + + + + + 0 + 0 + + + + + 75 + 0 + + + + + 65 + 16777215 + + + + + false + + + + PostgreSQL: + + + + + + + + + true + + + + 100 + 0 + + + + + 100 + 16777215 + + + + Versão do PostgreSQL no qual do código SQL deve ser gerado + + + QComboBox::InsertAtBottom + + + + + + + Qt::Horizontal + + + + 158 + 20 + + + + + + + + + + + 0 + 0 + + + + + + + true + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 24 + 26 + + + + + + + + true + + + + + + + + 0 + 0 + 255 + + + + + + + + + 0 + 0 + 255 + + + + + + + + + 117 + 114 + 112 + + + + + + + + + DejaVu Sans + 8 + true + + + + Certifique-se que o usuário do sistema possui permissão de gravação sobre a pasta de destino do arquivo SQL. + + + Qt::PlainText + + + true + + + + + + + + + + + + + + 50 + false + false + + + + Exportação para o SGBD: + + + + + + + false + + + + 0 + 0 + + + + + 105 + 0 + + + + Conexão: + + + + + + + false + + + + 200 + 0 + + + + QComboBox::InsertAlphabetically + + + + + + + false + + + + 0 + 0 + + + + + 50 + 100 + + + + + 50 + 16777215 + + + + + + + :/imagens/imagens/model2sgdb.png + + + Qt::AlignCenter + + + + + + + false + + + + 0 + 0 + + + + PostgreSQL: + + + false + + + false + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + 100 + 16777215 + + + + Versão do PostgreSQL no qual do código SQL deve ser gerado + + + QComboBox::InsertAtBottom + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + true + + + + 0 + 0 + + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + false + + + + + + + + 0 + 0 + 255 + + + + + + + + + 0 + 0 + 255 + + + + + + + + + 117 + 114 + 112 + + + + + + + + + DejaVu Sans + 8 + true + + + + Recomenda-se marcar esta opção somente quando a versão do SGBD, de alguma forma, não seja identificável ou se é necessário gerar uma versão específica de código SQL para testes. + + + Qt::PlainText + + + true + + + + + + + + + + + + + false + + + + 0 + 0 + + + + + + + + + + + false + + + Ignorar duplicidade de objetos + + + true + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 30 + 20 + + + + + + + + false + + + + + + + + 0 + 0 + 255 + + + + + + + + + 0 + 0 + 255 + + + + + + + + + 117 + 114 + 112 + + + + + + + + + DejaVu Sans + 8 + true + + + + O pgModeler ignora os erros gerados por duplicidade de objetos e cria apenas objetos do modelo não existentes no banco de dados serão. Esta opção pode ser usada quando um objeto foi criado no modelo posteriormente a uma exportação. + + + Qt::PlainText + + + true + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 15 + + + + QFrame::HLine + + + QFrame::Raised + + + + + + + 4 + + + + + + 0 + 0 + + + + Rótulo progresso... + + + + + + + 0 + + + + + + + + 0 + 0 + + + + + 22 + 22 + + + + + 22 + 22 + + + + ico + + + true + + + Qt::AlignCenter + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/formprincipal.ui b/libpgmodeler_ui/ui/formprincipal.ui new file mode 100644 index 000000000..cd3c41395 --- /dev/null +++ b/libpgmodeler_ui/ui/formprincipal.ui @@ -0,0 +1,812 @@ + + + FormPrincipal + + + Qt::NonModal + + + + 0 + 0 + 1323 + 480 + + + + + 640 + 480 + + + + true + + + pgModeler - PostgreSQL Database Modeler + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + + + + Qt::LeftToRight + + + false + + + + + + Qt::ToolButtonTextOnly + + + false + + + true + + + + + 6 + + + 6 + + + + + + 0 + 0 + + + + true + + + -1 + + + false + + + true + + + + + + + + true + + + + 0 + 0 + 1323 + 25 + + + + false + + + + Arquivo + + + + + + + + + + + + + + + + + Editar + + + + + + + + + + Ajuda + + + + + + Exibir + + + + Ferramentas + + + + + + + + + + + + + + + + + + + + + + false + + + Plugins + + + + + + + + + + + + + 8 + + + + Arquivo + + + + 22 + 22 + + + + Qt::ToolButtonTextUnderIcon + + + false + + + TopToolBarArea + + + false + + + + + + + + + + + + + true + + + + 8 + + + + Visualização + + + + 22 + 22 + + + + Qt::ToolButtonTextUnderIcon + + + TopToolBarArea + + + false + + + + + + + + + + + + + + + true + + + + 8 + + + + Edição + + + true + + + + 22 + 22 + + + + Qt::ToolButtonTextUnderIcon + + + false + + + TopToolBarArea + + + false + + + + + + + true + + + + 0 + 0 + + + + + 8 + + + + Modelo + + + + 22 + 22 + + + + Qt::ToolButtonTextUnderIcon + + + true + + + BottomToolBarArea + + + false + + + + + false + + + + 8 + + + + Plugins + + + Qt::ToolButtonTextUnderIcon + + + TopToolBarArea + + + false + + + + + + :/icones/icones/novo.png:/icones/icones/novo.png + + + Novo + + + Ctrl+N + + + + + false + + + + :/icones/icones/salvar.png:/icones/icones/salvar.png + + + Salvar + + + Ctrl+S + + + + + false + + + + :/icones/icones/zoom_mais.png:/icones/icones/zoom_mais.png + + + Zoom + + + + Ampliar zoom + + + Ctrl+= + + + QAction::PreferencesRole + + + QAction::HighPriority + + + + + false + + + + :/icones/icones/zoom_menos.png:/icones/icones/zoom_menos.png + + + Zoom - + + + Zoom - + + + Diminuir zoom + + + Ctrl+- + + + + + + :/icones/icones/abrir.png:/icones/icones/abrir.png + + + Carregar + + + Ctrl+O + + + + + false + + + + :/icones/icones/proximo.png:/icones/icones/proximo.png + + + Próximo + + + + + false + + + + :/icones/icones/anterior.png:/icones/icones/anterior.png + + + Anterior + + + + + + :/icones/icones/msgbox_quest.png:/icones/icones/msgbox_quest.png + + + Ajuda + + + F1 + + + + + false + + + + :/icones/icones/salvar_como.png:/icones/icones/salvar_como.png + + + Salvar Como + + + + + + :/icones/icones/sair.png:/icones/icones/sair.png + + + Sair + + + QAction::QuitRole + + + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + Sobre o pgModeler + + + F2 + + + + + false + + + + :/icones/icones/imprimir.png:/icones/icones/imprimir.png + + + Imprimir + + + Ctrl+P + + + + + false + + + + :/icones/icones/desfazer.png:/icones/icones/desfazer.png + + + Desfazer + + + Ctrl+Z + + + + + false + + + + :/icones/icones/refazer.png:/icones/icones/refazer.png + + + Refazer + + + Ctrl+Y + + + + + + :/icones/icones/config.png:/icones/icones/config.png + + + Preferências + + + Ctrl+Shift+P + + + + + false + + + + :/icones/icones/exportar.png:/icones/icones/exportar.png + + + Exportar + + + + + true + + + true + + + false + + + + :/icones/icones/grade.png:/icones/icones/grade.png + + + Exibir grade + + + Exibir grade + + + Ctrl+G + + + + + true + + + true + + + Arquivo + + + + + true + + + true + + + Edição + + + + + true + + + true + + + Exibição + + + + + true + + + true + + + Configuração + + + + + true + + + true + + + Ajuda + + + + + false + + + + :/icones/icones/fechar.png:/icones/icones/fechar.png + + + Fechar Modelo + + + + + false + + + + :/icones/icones/zoom_normal.png:/icones/icones/zoom_normal.png + + + Zoom Normal + + + Ctrl+0 + + + + + true + + + false + + + false + + + + :/icones/icones/alinhargrade.png:/icones/icones/alinhargrade.png + + + Alinhar à grade + + + Alinhar objetos à grade + + + + + true + + + false + + + + :/icones/icones/telacheia.png:/icones/icones/telacheia.png + + + Tela cheia + + + Exibe o modelo em tela cheia + + + F11 + + + + + true + + + true + + + false + + + + :/icones/icones/exibirlimpag.png:/icones/icones/exibirlimpag.png + + + Exibir Limites + + + Exibe os limitadores de página + + + Ctrl+L + + + + + + :/icones/icones/config.png:/icones/icones/config.png + + + Configurações + + + + + Widgets + + + + + true + + + Arquivo + + + + + true + + + Exibição + + + + + true + + + Edição + + + + + true + + + Modelo + + + + + true + + + Operações + + + + + true + + + Visão de Objetos + + + + + Salvar Tudo + + + + + + + + diff --git a/libpgmodeler_ui/ui/formsobre.ui b/libpgmodeler_ui/ui/formsobre.ui new file mode 100644 index 000000000..6c0a3c70f --- /dev/null +++ b/libpgmodeler_ui/ui/formsobre.ui @@ -0,0 +1,771 @@ + + + FormSobre + + + Qt::ApplicationModal + + + + 0 + 0 + 645 + 520 + + + + + 0 + 0 + + + + + 645 + 520 + + + + + 645 + 520 + + + + Sobre o pgModeler + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + + 2 + + + 4 + + + + + + 48 + 0 + + + + + 60 + 16777215 + + + + background-image: url(:/imagens/imagens/barra_logo_meio_cinza.png); background-repeat: repeat-y; +border: 1px #ff00ff solid; + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 60 + 82 + + + + + 60 + 82 + + + + + + + :/imagens/imagens/barra_logo_topo.png + + + + + + + Qt::Vertical + + + + 20 + 362 + + + + + + + + + 0 + 0 + + + + + 60 + 119 + + + + + 60 + 119 + + + + + + + :/imagens/imagens/barra_logo_base.png + + + + + + + + + + + + Qt::Horizontal + + + + 278 + 17 + + + + + + + + + 90 + 32 + + + + + 90 + 16777215 + + + + Ok + + + + :/icones/icones/confirmar.png:/icones/icones/confirmar.png + + + true + + + + + + + + + + 0 + 0 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 4 + + + + + + 0 + 0 + + + + + 128 + 128 + + + + + 128 + 128 + + + + + + + :/imagens/imagens/pgsqldbm_logo_grande.png + + + true + + + + + + + 6 + + + + + + 0 + 0 + + + + + DejaVu Sans + 18 + 75 + true + + + + PostgreSQL Database Modeler + + + + + + + + 0 + 0 + + + + + 230 + 0 + + + + + 16777215 + 16777215 + + + + + DejaVu Sans + 12 + 50 + true + false + + + + Desenhe, configure, implante + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + + 16777215 + 18 + + + + + DejaVu Sans + 12 + 75 + true + true + + + + 0.0.0.0 + + + + + + + + + 6 + + + 4 + + + + + + 0 + 0 + + + + + 40 + 40 + + + + + 40 + 40 + + + + http://pgmodeler.github.com/pgmodeler/ + + + + + + QFrame::Panel + + + QFrame::Sunken + + + + + + :/imagens/imagens/github.png + + + false + + + Qt::AlignCenter + + + -1 + + + + + + + + 0 + 0 + + + + + 40 + 40 + + + + + 40 + 40 + + + + http://twitter.com/pgmodeler + + + + + + QFrame::Panel + + + QFrame::Sunken + + + + + + :/imagens/imagens/twitter.png + + + false + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 40 + 40 + + + + + 40 + 40 + + + + http://facebook.com/pgmodeler + + + + + + QFrame::Panel + + + QFrame::Sunken + + + + + + :/imagens/imagens/facebook.png + + + false + + + Qt::AlignCenter + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 8 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Tahoma'; font-size:8pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://pgmodeler.github.com/pgmodeler/"><span style=" text-decoration: underline; color:#0000ff;">GitHub</span></a></p></body></html> + + + Qt::AlignCenter + + + true + + + Qt::LinksAccessibleByMouse + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 8 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Tahoma'; font-size:8pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://twitter.com/pgmodeler"><span style=" text-decoration: underline; color:#0000ff;">Twitter</span></a></p></body></html> + + + Qt::AlignCenter + + + true + + + Qt::LinksAccessibleByMouse + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + 8 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Tahoma'; font-size:8pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://facebook.com/pgmodeler"><span style=" text-decoration: underline; color:#0000ff;">Facebook</span></a></p></body></html> + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + true + + + Qt::LinksAccessibleByMouse + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 20 + + + + QFrame::HLine + + + QFrame::Raised + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + DejaVu Sans + 10 + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'DejaVu Sans'; font-size:10pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Tahoma';">Copyleft 2006-2012 - Raphael Araújo e Silva &lt;</span><a href="rkhaotix@gmail.com"><span style=" font-family:'Tahoma'; text-decoration: underline; color:#0000ff;">rkhaotix@gmail.com</span></a><span style=" font-family:'Tahoma';">&gt;</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Tahoma';"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Tahoma';">O projeto pgModeler consiste numa ferramenta CASE para modelagem de bancos de dados relacionais para o SGBD PostgreSQL pelo uso das técnicas de modelagem provenientes dos Diagramas de Entidade-Relacionamento.</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Tahoma';"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'Tahoma';">Agradecimentos especiais aos amigos da equipe de desenvolvimento de software da Assembleia Legislativa, Tocantins, Brasil: </span><span style=" font-family:'Tahoma'; font-weight:600;">Michel de Almeida</span><span style=" font-family:'Tahoma';">, </span><span style=" font-family:'Tahoma'; font-weight:600;">Filipe Santana</span><span style=" font-family:'Tahoma';">, </span><span style=" font-family:'Tahoma'; font-weight:600;">Jonas Nepomuceno</span><span style=" font-family:'Tahoma';">, </span><span style=" font-family:'Tahoma'; font-weight:600;">Ricardo Ishibashi</span><span style=" font-family:'Tahoma';"> e </span><span style=" font-family:'Tahoma'; font-weight:600;">Álvaro Nunes.</span></p></body></html> + + + Qt::RichText + + + Qt::AlignJustify|Qt::AlignTop + + + true + + + + + + + + 0 + 0 + + + + + 0 + 20 + + + + QFrame::HLine + + + QFrame::Raised + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + DejaVu Sans + 10 + + + + QFrame::Sunken + + + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (GPL) as published by the Free Software Foundation; either version 2. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + + Qt::PlainText + + + false + + + Qt::AlignJustify|Qt::AlignVCenter + + + true + + + + + + + + + + + + + + ok_btn + clicked() + FormSobre + close() + + + 493 + 432 + + + 59 + 418 + + + + + diff --git a/libpgmodeler_ui/ui/funcaoagregacaowidget.ui b/libpgmodeler_ui/ui/funcaoagregacaowidget.ui new file mode 100644 index 000000000..5d0566768 --- /dev/null +++ b/libpgmodeler_ui/ui/funcaoagregacaowidget.ui @@ -0,0 +1,115 @@ + + + FuncaoAgregacaoWidget + + + + 0 + 0 + 508 + 373 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + Função Final: + + + + + + + Função de Transição: + + + + + + + Operador de Ordenação: + + + + + + + Condição Inicial: + + + + + + + + 0 + 0 + + + + + 16777215 + 25 + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + + + + true + + + QTextEdit::NoWrap + + + true + + + Qt::TextEditorInteraction + + + + + + + 0 + + + + Entradas da Função + + + + + Estado da Função + + + + + + + + + diff --git a/libpgmodeler_ui/ui/funcaowidget.ui b/libpgmodeler_ui/ui/funcaowidget.ui new file mode 100644 index 000000000..377a7f663 --- /dev/null +++ b/libpgmodeler_ui/ui/funcaowidget.ui @@ -0,0 +1,493 @@ + + + FuncaoWidget + + + + 0 + 0 + 588 + 412 + + + + + 0 + 0 + + + + + 465 + 216 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 0 + 273 + + + + 0 + + + + Atributos + + + + 4 + + + 6 + + + + + + 110 + 16777215 + + + + Linguagem: + + + + + + + + + + QFrame::HLine + + + QFrame::Raised + + + + + + + + 110 + 16777215 + + + + Tipo de Função: + + + + + + + + + + + 110 + 16777215 + + + + Função Janela: + + + + + + + + + + + + + + + 125 + 0 + + + + + 110 + 16777215 + + + + Custo de Execução: + + + + + + + 10000 + + + + + + + + 110 + 16777215 + + + + Linhas Retornadas: + + + + + + + 1000000000 + + + + + + + + 110 + 16777215 + + + + Comportamento: + + + + + + + + + + + 110 + 16777215 + + + + Segurança: + + + + + + + + + + QFrame::HLine + + + QFrame::Raised + + + + + + + + 110 + 16777215 + + + + Método de Retorno: + + + + + + + + + + 0 + 0 + + + + Simples + + + true + + + true + + + + + + + + 0 + 0 + + + + Conjunto + + + true + + + + + + + + 0 + 0 + + + + Tabela + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Tabela de Retorno + + + + + + + + Parâmetros + + + + + Definição + + + + 4 + + + 6 + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 2 + + + 6 + + + + + Biblioteca Dinâmica: + + + + + + + Qt::Horizontal + + + + 450 + 20 + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + true + + + + 60 + 16777215 + + + + Símbolo: + + + + + + + true + + + + 0 + 0 + + + + + + + + true + + + + 60 + 16777215 + + + + Biblioteca: + + + + + + + true + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + + 20 + 61 + + + + + + + + + + + QFrame::NoFrame + + + QFrame::Raised + + + + 2 + + + 6 + + + + + Código-Fonte: + + + + + + + Qt::Horizontal + + + + 485 + 20 + + + + + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/gatilhowidget.ui b/libpgmodeler_ui/ui/gatilhowidget.ui new file mode 100644 index 000000000..53feaec9d --- /dev/null +++ b/libpgmodeler_ui/ui/gatilhowidget.ui @@ -0,0 +1,601 @@ + + + GatilhoWidget + + + + 0 + 0 + 511 + 347 + + + + + 430 + 310 + + + + Form + + + + 2 + + + 6 + + + + + true + + + + 0 + 0 + + + + + 110 + 0 + + + + + 110 + 16777215 + + + + Modo Disparo: + + + + + + + + + true + + + + 0 + 0 + + + + + 113 + 0 + + + + + 16777215 + 16777215 + + + + + INSTEAD OF + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 76 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Executar por linha + + + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + + 110 + 16777215 + + + + Evento: + + + + + + + QLayout::SetDefaultConstraint + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + 16777215 + 16777215 + + + + INSERT + + + + + + + + 0 + 0 + + + + + 95 + 0 + + + + + 16777215 + 16777215 + + + + DELETE + + + + + + + + 0 + 0 + + + + + 95 + 0 + + + + + 16777215 + 16777215 + + + + UPDATE + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 16777215 + 16777215 + + + + TRUNCATE + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Postergável: + + + + + + + + + + 0 + 0 + + + + + 95 + 0 + + + + + 90 + 16777215 + + + + + + + + + + + false + + + + 0 + 0 + + + + + 92 + 0 + + + + + 16777215 + 16777215 + + + + Postergação: + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + + true + + + + 0 + 0 + + + + + 110 + 0 + + + + + 110 + 16777215 + + + + Tab. Referenciada: + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + + 110 + 16777215 + + + + Expr. Condicional: + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + + 16777215 + 90 + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + true + + + false + + + Qt::TextEditorInteraction + + + + + + + 0 + + + + Colunas + + + + 2 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Coluna: + + + + + + + + 0 + 0 + + + + + 180 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + Argumentos + + + + 2 + + + + + Argumento: + + + + + + + + 180 + 0 + + + + + + + + + + + + true + + + + 0 + 0 + + + + + 110 + 0 + + + + + 110 + 16777215 + + + + Função: + + + + + + + Gatilho Restrição + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/indicewidget.ui b/libpgmodeler_ui/ui/indicewidget.ui new file mode 100644 index 000000000..ec2a5786f --- /dev/null +++ b/libpgmodeler_ui/ui/indicewidget.ui @@ -0,0 +1,540 @@ + + + IndiceWidget + + + + 0 + 0 + 543 + 301 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 100 + 0 + + + + + 100 + 16777215 + + + + + 50 + false + false + + + + Tipo Indexação: + + + + + + + + 0 + 0 + + + + + 127 + 0 + + + + + 127 + 16777215 + + + + + + + + + 0 + 0 + + + + + 105 + 0 + + + + + 110 + 16777215 + + + + + 50 + false + false + true + + + + Fator Preenc.: + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + + 16777215 + 16777215 + + + + 10 + + + 100 + + + + + + + + 0 + 0 + + + + + 95 + 0 + + + + + 95 + 16777215 + + + + Opções: + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Concorrente + + + + + + + + 0 + 0 + + + + + 140 + 0 + + + + + 128 + 16777215 + + + + Checar duplicados + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Atual. Rápida + + + + + + + + + + 0 + 0 + + + + + 110 + 0 + + + + + 95 + 16777215 + + + + Expr. Condicional: + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + + 16777215 + 90 + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + true + + + false + + + Qt::TextEditorInteraction + + + + + + + Elementos + + + + 4 + + + 6 + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + 90 + 16777215 + + + + Coluna: + + + true + + + false + + + + + + + + 0 + 0 + + + + + 180 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + 90 + 16777215 + + + + Expressão: + + + false + + + false + + + + + + + false + + + + 0 + 0 + + + + + 0 + 50 + + + + + 16777215 + 50 + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + true + + + false + + + Qt::TextEditorInteraction + + + + + + + + 0 + 0 + + + + + 105 + 16777215 + + + + Classe Operadores: + + + + + + + + 0 + 0 + + + + + 105 + 16777215 + + + + Ordenação: + + + + + + + + + Ascendente + + + true + + + + + + + Descendente + + + + + + + Nulos primeiro + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/linguagemwidget.ui b/libpgmodeler_ui/ui/linguagemwidget.ui new file mode 100644 index 000000000..08105689d --- /dev/null +++ b/libpgmodeler_ui/ui/linguagemwidget.ui @@ -0,0 +1,116 @@ + + + LinguagemWidget + + + + 0 + 0 + 337 + 120 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Confiável: + + + + + + + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Função Handler: + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Função Validator: + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Função Inline: + + + + + + + + diff --git a/libpgmodeler_ui/ui/listaobjetoswidget.ui b/libpgmodeler_ui/ui/listaobjetoswidget.ui new file mode 100644 index 000000000..c529a9d61 --- /dev/null +++ b/libpgmodeler_ui/ui/listaobjetoswidget.ui @@ -0,0 +1,273 @@ + + + ListaObjetosWidget + + + + 0 + 0 + 702 + 359 + + + + Form + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + + 0 + + + 4 + + + 0 + + + + + 0 + + + + 22 + 22 + + + + + Dependências + + + + 4 + + + 6 + + + + + true + + + + 9 + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::NoSelection + + + QAbstractItemView::SelectRows + + + Qt::SolidLine + + + true + + + true + + + 96 + + + 23 + + + true + + + true + + + false + + + false + + + 20 + + + false + + + 19 + + + false + + + false + + + + Objeto + + + + :/icones/icones/table.png:/icones/icones/table.png + + + + + Tipo + + + + :/icones/icones/usertype.png:/icones/icones/usertype.png + + + + + Objeto Pai + + + + :/icones/icones/schema.png:/icones/icones/schema.png + + + + + Tipo Pai + + + + :/icones/icones/usertype.png:/icones/icones/usertype.png + + + + + + + + + Referências + + + + 4 + + + 6 + + + + + true + + + + 9 + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::NoSelection + + + QAbstractItemView::SelectRows + + + Qt::SolidLine + + + true + + + true + + + 96 + + + true + + + true + + + false + + + false + + + 20 + + + false + + + false + + + false + + + + Objeto + + + + :/icones/icones/table.png:/icones/icones/table.png + + + + + Tipo + + + + :/icones/icones/usertype.png:/icones/icones/usertype.png + + + + + Objeto Pai + + + + :/icones/icones/schema.png:/icones/icones/schema.png + + + + + Tipo Pai + + + + :/icones/icones/usertype.png:/icones/icones/usertype.png + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/listaoperacoeswidget.ui b/libpgmodeler_ui/ui/listaoperacoeswidget.ui new file mode 100644 index 000000000..aa3ed7a79 --- /dev/null +++ b/libpgmodeler_ui/ui/listaoperacoeswidget.ui @@ -0,0 +1,279 @@ + + + ListaOperacoesWidget + + + true + + + + 0 + 0 + 414 + 304 + + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + Qt::AllDockWidgetAreas + + + Operações Executadas + + + + true + + + + 4 + + + + + true + + + + + + + + 0 + 170 + 255 + + + + + + + + + 0 + 170 + 255 + + + + + + + + + 0 + 170 + 255 + + + + + + + + + 8 + + + + QFrame::Sunken + + + QAbstractItemView::NoEditTriggers + + + true + + + true + + + QAbstractItemView::NoSelection + + + QAbstractItemView::SelectItems + + + + 14 + 14 + + + + 20 + + + false + + + true + + + false + + + true + + + true + + + false + + + + 1 + + + + + + + + + + true + + + Operações: + + + + + + + true + + + 0 + + + + + + + true + + + Posição: + + + + + + + true + + + 0 + + + + + + + + + Qt::Horizontal + + + + 178 + 20 + + + + + + + + + + false + + + Excluir histórico de operações + + + + + + + :/icones/icones/excluir.png:/icones/icones/excluir.png + + + + 22 + 22 + + + + false + + + + + + + false + + + Desfazer + + + + + + + :/icones/icones/desfazer.png:/icones/icones/desfazer.png + + + + 22 + 22 + + + + false + + + + + + + false + + + Refazer + + + + + + + :/icones/icones/refazer.png:/icones/icones/refazer.png + + + + 22 + 22 + + + + false + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/objetobasewidget.ui b/libpgmodeler_ui/ui/objetobasewidget.ui new file mode 100644 index 000000000..2ca7671ef --- /dev/null +++ b/libpgmodeler_ui/ui/objetobasewidget.ui @@ -0,0 +1,439 @@ + + + ObjetoBaseWidget + + + + 0 + 0 + 634 + 588 + + + + + 0 + 0 + + + + Form + + + + + 10 + 88 + 50 + 16 + + + + + 50 + 16777215 + + + + Nome: + + + + + + 82 + 88 + 111 + 25 + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + + + + + + 200 + 88 + 32 + 32 + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::NoFrame + + + QFrame::Plain + + + icone + + + false + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 8 + 170 + 75 + 16 + + + + + 75 + 0 + + + + + 68 + 16777215 + + + + Comentário: + + + + + + 80 + 170 + 114 + 25 + + + + + 0 + 25 + + + + + + + 10 + 130 + 364 + 16 + + + + + 0 + 5 + + + + Qt::Horizontal + + + + + + 10 + 204 + 91 + 16 + + + + Esp. de Tabela: + + + + + + 10 + 236 + 41 + 16 + + + + Dono: + + + + + + 10 + 268 + 61 + 16 + + + + Esquema: + + + + + + 10 + 350 + 364 + 16 + + + + + 0 + 5 + + + + Qt::Horizontal + + + + + + 10 + 300 + 71 + 16 + + + + Permissões: + + + + + + 120 + 300 + 30 + 25 + + + + + 30 + 25 + + + + Editar Permissões + + + + + + + :/icones/icones/editar.png:/icones/icones/editar.png + + + + + + 20 + 10 + 511 + 48 + + + + + 0 + 0 + + + + + 0 + 48 + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 2 + + + + + + 32 + 32 + + + + + 32 + 32 + + + + + + + Qt::AutoText + + + :/icones/icones/msgbox_alerta.png + + + + + + + + 8 + 50 + true + false + false + false + true + + + + Este o objeto encontra-se protegido, assim nenhuma alteração no formulário será aplicada ao mesmo. + + + true + + + + + + + + + 10 + 330 + 71 + 16 + + + + Objeto Pai: + + + + + + 230 + 320 + 32 + 32 + + + + + 32 + 32 + + + + + 32 + 32 + + + + QFrame::NoFrame + + + QFrame::Plain + + + icone + + + false + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + 80 + 320 + 131 + 25 + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + true + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + QTextEdit::NoWrap + + + true + + + Qt::NoTextInteraction + + + + + + + + diff --git a/libpgmodeler_ui/ui/operadorwidget.ui b/libpgmodeler_ui/ui/operadorwidget.ui new file mode 100644 index 000000000..a3cfabf91 --- /dev/null +++ b/libpgmodeler_ui/ui/operadorwidget.ui @@ -0,0 +1,194 @@ + + + OperadorWidget + + + + 0 + 0 + 522 + 297 + + + + Form + + + + 2 + + + 6 + + + + + + 70 + 0 + + + + Opções: + + + + + + + Suporta MERGES + + + + + + + Suporta HASHES + + + + + + + Qt::Horizontal + + + + 229 + 20 + + + + + + + + 0 + + + + Argumentos + + + + + Funções + + + + 2 + + + 6 + + + + + Junção: + + + + + + + Restrição: + + + + + + + Qt::Vertical + + + + 20 + 193 + + + + + + + + Operador: + + + + + + + + Operadores + + + + 2 + + + 6 + + + + + Comutação: + + + + + + + Negação: + + + + + + + Ordenação (1): + + + + + + + Ordenação (2): + + + + + + + Menor que: + + + + + + + Maior que: + + + + + + + Qt::Vertical + + + + 20 + 96 + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/papelwidget.ui b/libpgmodeler_ui/ui/papelwidget.ui new file mode 100644 index 000000000..f07f48d13 --- /dev/null +++ b/libpgmodeler_ui/ui/papelwidget.ui @@ -0,0 +1,198 @@ + + + PapelWidget + + + + 0 + 0 + 493 + 399 + + + + + 400 + 0 + + + + Form + + + + 2 + + + 6 + + + + + SysID: + + + + + + + + 0 + 25 + + + + 0 + + + 65535 + + + 100 + + + + + + + Senha: + + + + + + + + + + Validade: + + + + + + + yyyy-MMM-dd hh:mm + + + true + + + + + + + + 50 + false + false + + + + Conexões: + + + + + + + + 0 + 25 + + + + -1 + + + 65535 + + + -1 + + + + + + + Atributos + + + + 4 + + + 6 + + + + + Superusuário + + + + + + + Herdar Permissões + + + + + + + Criar Banco de Dados + + + + + + + Permitir Login + + + + + + + Criar Usuários/Grupos + + + + + + + Senha Criptografada + + + + + + + + + + 0 + + + + Membros + + + + + Membro de + + + + + Membros (Administradores) + + + + + + + + + diff --git a/libpgmodeler_ui/ui/parametrowidget.ui b/libpgmodeler_ui/ui/parametrowidget.ui new file mode 100644 index 000000000..5d03e5a32 --- /dev/null +++ b/libpgmodeler_ui/ui/parametrowidget.ui @@ -0,0 +1,121 @@ + + + ParametroWidget + + + + 0 + 0 + 436 + 204 + + + + + 430 + 0 + + + + Form + + + + + 4 + 53 + 80 + 16 + + + + + 80 + 0 + + + + + 75 + 16777215 + + + + Valor Padrão: + + + + + + 83 + 53 + 112 + 23 + + + + + + + 4 + 129 + 34 + 16 + + + + + 75 + 16777215 + + + + Modo: + + + + + + 83 + 129 + 137 + 24 + + + + + 4 + + + + + IN + + + + + + + OUT + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/permissaowidget.ui b/libpgmodeler_ui/ui/permissaowidget.ui new file mode 100644 index 000000000..0584d1c0a --- /dev/null +++ b/libpgmodeler_ui/ui/permissaowidget.ui @@ -0,0 +1,257 @@ + + + PermissaoWidget + + + + 0 + 0 + 550 + 475 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Form + + + + 2 + + + 6 + + + + + + + + 16777215 + 16777215 + + + + ID: + + + + + + + + 0 + 25 + + + + + true + + + + true + + + + + + + + + + 0 + 0 + + + + + 250 + 0 + + + + + 16777215 + 16777215 + + + + Permissões + + + + + + + + 0 + 0 + + + + + 220 + 150 + + + + + 270 + 16777215 + + + + Papéis + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 270 + 99999 + + + + Privilégios + + + + 4 + + + 6 + + + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + false + + + true + + + false + + + + Privilégio + + + + + GRANT OPTION + + + + + + + + + + + false + + + Cancelar Operação + + + + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + + 20 + 20 + + + + + + + + false + + + Atualizar Permissão + + + + + + + :/icones/icones/atualizar.png:/icones/icones/atualizar.png + + + + 20 + 20 + + + + + + + + false + + + Adicionar Permissão + + + + + + + :/icones/icones/adicionar.png:/icones/icones/adicionar.png + + + + 20 + 20 + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/progressotarefa.ui b/libpgmodeler_ui/ui/progressotarefa.ui new file mode 100644 index 000000000..a0782b0c1 --- /dev/null +++ b/libpgmodeler_ui/ui/progressotarefa.ui @@ -0,0 +1,172 @@ + + + ProgressoTarefa + + + + 0 + 0 + 606 + 77 + + + + + 550 + 77 + + + + + 16777215 + 77 + + + + Executando tarefas + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + true + + + + 0 + + + 0 + + + + + QFrame::Panel + + + QFrame::Raised + + + + 4 + + + 4 + + + + + + 0 + 0 + + + + + 64 + 64 + + + + + 64 + 64 + + + + + + + Qt::PlainText + + + :/imagens/imagens/pgsqldbm_logo_grande.png + + + true + + + Qt::AlignCenter + + + + + + + + + + 0 + 0 + + + + + false + + + + Carregando objeto: [objeto] (tipo) + + + + + + + 50 + + + Qt::AlignCenter + + + false + + + %p% + + + + + + + + 0 + 0 + + + + + 35 + 32 + + + + + 35 + 32 + + + + + + + Qt::AlignCenter + + + 0 + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/regrawidget.ui b/libpgmodeler_ui/ui/regrawidget.ui new file mode 100644 index 000000000..c39cdb545 --- /dev/null +++ b/libpgmodeler_ui/ui/regrawidget.ui @@ -0,0 +1,276 @@ + + + RegraWidget + + + + 0 + 0 + 404 + 193 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Evento: + + + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + 16777215 + 16777215 + + + + QComboBox::AdjustToContents + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Tipo Execução: + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + 16777215 + 16777215 + + + + QComboBox::AdjustToContents + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Expr. Condicional: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 65 + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + true + + + false + + + Qt::TextEditorInteraction + + + + + + + Comandos Executados + + + + 4 + + + 6 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Comando SQL: + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + + 16777215 + 120 + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + true + + + false + + + Qt::TextEditorInteraction + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/relacionamentowidget.ui b/libpgmodeler_ui/ui/relacionamentowidget.ui new file mode 100644 index 000000000..e5145d600 --- /dev/null +++ b/libpgmodeler_ui/ui/relacionamentowidget.ui @@ -0,0 +1,750 @@ + + + RelacionamentoWidget + + + + 0 + 0 + 511 + 344 + + + + + 0 + 0 + + + + + 480 + 270 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + 0 + + + + Geral + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 105 + 0 + + + + + 105 + 16777215 + + + + Relacionamento: + + + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + true + + + + Relacionamento de um para um + + + 1-1 + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + true + + + + Relacionamento de um para muitos + + + 1-n + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + true + + + + Relacionamento de muitos para muitos + + + n-n + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + true + + + + Relacionamento de generalização (herança) + + + gen + + + + + + + false + + + + 0 + 0 + + + + + 50 + 0 + + + + + 16777215 + 16777215 + + + + + true + + + + Relacionamento de dependência entre tabelas ou entre uma tabela e visão + + + dep + + + + + + + + + + 0 + 0 + + + + Identificador + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Tabela Origem: + + + + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + true + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + QTextEdit::NoWrap + + + true + + + Qt::NoTextInteraction + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Tabela Destino: + + + + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + true + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + QTextEdit::NoWrap + + + true + + + Qt::NoTextInteraction + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Cardinalidade: + + + + + + + + + + 0 + 0 + + + + Origem Obrigatória + + + + + + + + 0 + 0 + + + + Destino Obrigatória + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Nome da tabela gerada pelo relacionamento muitos para muitos + + + Nome Tab. N-N: + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Sufixo Origem: + + + + + + + + 16777215 + 16777215 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Sufixo Destino: + + + + + + + + 16777215 + 16777215 + + + + + + + + + 0 + 0 + + + + Chave-estrangeira + + + + 4 + + + 6 + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + 90 + 16777215 + + + + Postergável: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + Postergação: + + + + + + + false + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QComboBox::AdjustToContents + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Atributos + + + + + Restrições + + + + + Chave-primária + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + QAbstractItemView::SelectedClicked + + + QAbstractItemView::NoSelection + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/restricaowidget.ui b/libpgmodeler_ui/ui/restricaowidget.ui new file mode 100644 index 000000000..4eced23c3 --- /dev/null +++ b/libpgmodeler_ui/ui/restricaowidget.ui @@ -0,0 +1,487 @@ + + + RestricaoWidget + + + + 0 + 0 + 513 + 352 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Tipo de Restrição: + + + + + + + + 100 + 0 + + + + + + + + Qt::Horizontal + + + + 226 + 21 + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Expr.Checagem: + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + + 16777215 + 16777215 + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + true + + + false + + + Qt::TextEditorInteraction + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Fator Preenc.: + + + + + + + + 0 + 0 + + + + 10 + + + 100 + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 75 + 16777215 + + + + Comparação: + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + Postergável: + + + + + + + + 0 + 0 + + + + + + + + + + + false + + + + 0 + 0 + + + + + 80 + 0 + + + + + 75 + 16777215 + + + + Postergação: + + + + + + + false + + + + 0 + 0 + + + + + 120 + 0 + + + + + + + + + 0 + 0 + + + + + 100 + 0 + + + + ON DELETE: + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + + + + + 0 + 0 + + + + + 75 + 0 + + + + + 75 + 16777215 + + + + ON UPDATE: + + + + + + + + 0 + 0 + + + + + 120 + 0 + + + + + + + + 0 + + + + Colunas + + + + 4 + + + 6 + + + + + + 0 + 0 + + + + Coluna: + + + + + + + + 0 + 0 + + + + + 180 + 0 + + + + + + + + + Colunas Referenciadas + + + + 4 + + + 6 + + + + + + 0 + 0 + + + + Tabela: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Coluna: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/seletorobjetowidget.ui b/libpgmodeler_ui/ui/seletorobjetowidget.ui new file mode 100644 index 000000000..56af52996 --- /dev/null +++ b/libpgmodeler_ui/ui/seletorobjetowidget.ui @@ -0,0 +1,123 @@ + + + SeletorObjetoWidget + + + + 0 + 0 + 277 + 33 + + + + + 0 + 25 + + + + + 16777215 + 33 + + + + Form + + + + 2 + + + 4 + + + + + + 0 + 25 + + + + + 16777215 + 25 + + + + + true + + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + QTextEdit::NoWrap + + + true + + + Qt::NoTextInteraction + + + + + + + false + + + + 30 + 25 + + + + Limpar campo + + + + + + + :/icones/icones/limpartexto.png:/icones/icones/limpartexto.png + + + + + + + + 30 + 25 + + + + Selecionar Objeto + + + + + + + :/icones/icones/visaogeral.png:/icones/icones/visaogeral.png + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/sequenciawidget.ui b/libpgmodeler_ui/ui/sequenciawidget.ui new file mode 100644 index 000000000..291596065 --- /dev/null +++ b/libpgmodeler_ui/ui/sequenciawidget.ui @@ -0,0 +1,200 @@ + + + SequenciaWidget + + + + 0 + 0 + 400 + 122 + + + + + 0 + 0 + + + + + 400 + 102 + + + + Form + + + + 2 + + + 6 + + + + + Cíclica: + + + + + + + + + + + + + + Início: + + + + + + + + 0 + 25 + + + + + false + + + + Qt::ImhFormattedNumbersOnly + + + false + + + + + + + Máximo: + + + + + + + + 0 + 25 + + + + + false + + + + Qt::ImhFormattedNumbersOnly + + + false + + + + + + + Mínimo: + + + + + + + + 0 + 25 + + + + + false + + + + Qt::ImhFormattedNumbersOnly + + + false + + + + + + + Incremento: + + + + + + + + 0 + 25 + + + + + false + + + + Qt::ImhFormattedNumbersOnly + + + false + + + + + + + Cache: + + + + + + + + 0 + 25 + + + + + false + + + + Qt::ImhFormattedNumbersOnly + + + false + + + + + + + Possuidora: + + + + + + + + diff --git a/libpgmodeler_ui/ui/tabelaobjetoswidget.ui b/libpgmodeler_ui/ui/tabelaobjetoswidget.ui new file mode 100644 index 000000000..3d2b05357 --- /dev/null +++ b/libpgmodeler_ui/ui/tabelaobjetoswidget.ui @@ -0,0 +1,339 @@ + + + TabelaObjetosWidget + + + + 0 + 0 + 461 + 307 + + + + Form + + + + 0 + + + 4 + + + + + Qt::Horizontal + + + + 97 + 22 + + + + + + + + + + true + + + + 30 + 25 + + + + Adicionar Item + + + + + + + :/icones/icones/adicionar.png:/icones/icones/adicionar.png + + + Ins + + + + + + + false + + + + 30 + 25 + + + + Remover Item + + + + + + + :/icones/icones/remover.png:/icones/icones/remover.png + + + Del + + + + + + + false + + + + 30 + 25 + + + + Atualizar Item + + + + + + + :/icones/icones/atualizar.png:/icones/icones/atualizar.png + + + Alt+R + + + + + + + false + + + + 30 + 25 + + + + Excluir Todos + + + + + + + :/icones/icones/limpartexto.png:/icones/icones/limpartexto.png + + + Shift+Del + + + + + + + false + + + + 30 + 25 + + + + Editar Item + + + + + + + :/icones/icones/editar.png:/icones/icones/editar.png + + + Space + + + + + + + false + + + + 30 + 25 + + + + Mover para cima + + + + + + + :/icones/icones/movercima.png:/icones/icones/movercima.png + + + Ctrl+Up + + + + + + + false + + + + 30 + 25 + + + + Mover para baixo + + + + + + + :/icones/icones/moverbaixo.png:/icones/icones/moverbaixo.png + + + Ctrl+Down + + + + + + + false + + + + 30 + 25 + + + + Mover para o início + + + + + + + :/icones/icones/moverprimeiro.png:/icones/icones/moverprimeiro.png + + + Ctrl+Home + + + + + + + false + + + + 30 + 25 + + + + Mover para o fim + + + + + + + :/icones/icones/moverultimo.png:/icones/icones/moverultimo.png + + + Ctrl+End, Ctrl+S + + + + + + + + + Qt::Horizontal + + + + 92 + 22 + + + + + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + + 16 + 16 + + + + false + + + true + + + true + + + false + + + 20 + + + true + + + 15 + + + false + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/tabelawidget.ui b/libpgmodeler_ui/ui/tabelawidget.ui new file mode 100644 index 000000000..e7a5da159 --- /dev/null +++ b/libpgmodeler_ui/ui/tabelawidget.ui @@ -0,0 +1,174 @@ + + + TabelaWidget + + + + 0 + 0 + 473 + 255 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 85 + 0 + + + + + 85 + 16777215 + + + + Aceita OIDs: + + + + + + + + + + + + + + 0 + + + + Colunas + + + + + Restrições + + + + + Gatilhos + + + + + Rules + + + + + Índices + + + + + Tabelas + + + + 2 + + + + + Qt::Horizontal + + + + + + + Tabelas Ancestrais: + + + + + + + QAbstractItemView::NoEditTriggers + + + false + + + true + + + QAbstractItemView::NoSelection + + + true + + + true + + + + + + + + + + + Tabelas Copiadas: + + + + + + + QAbstractItemView::NoEditTriggers + + + false + + + true + + + QAbstractItemView::NoSelection + + + true + + + true + + + + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/tipopgsqlwidget.ui b/libpgmodeler_ui/ui/tipopgsqlwidget.ui new file mode 100644 index 000000000..88d29e2ad --- /dev/null +++ b/libpgmodeler_ui/ui/tipopgsqlwidget.ui @@ -0,0 +1,498 @@ + + + TipoPgSQLWidget + + + + 0 + 0 + 430 + 135 + + + + + 0 + 0 + + + + + 430 + 0 + + + + + 16777215 + 16777215 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Tipo de Dado + + + + 4 + + + 6 + + + + + + 0 + 0 + + + + + 55 + 0 + + + + + 55 + 16777215 + + + + font-weight: normal; + + + Tipo: + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + PreferDefault + + + + font-weight: normal; + + + QComboBox::AdjustToContentsOnFirstShow + + + + + + + + 0 + 0 + + + + + 20 + 0 + + + + + 16 + 16777215 + + + + + false + + + + Comprimento + + + font-weight: normal; + + + (c): + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + Comprimento + + + font-weight: normal; + + + 1 + + + 2147483647 + + + 1 + + + + + + + + 0 + 0 + + + + + 20 + 0 + + + + + 16 + 16777215 + + + + + false + + + + Precisão + + + font-weight: normal; + + + (p): + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + + 60 + 16777215 + + + + Precisão + + + font-weight: normal; + + + -1 + + + 1000 + + + 1 + + + -1 + + + + + + + + 0 + 0 + + + + + 20 + 0 + + + + + 16 + 16777215 + + + + + false + + + + Dimensão + + + font-weight: normal; + + + [ ]: + + + + + + + + 0 + 0 + + + + + 40 + 0 + + + + + 40 + 16777215 + + + + Dimensão + + + font-weight: normal; + + + 99 + + + 0 + + + + + + + true + + + + 0 + 0 + + + + + 55 + 0 + + + + + 55 + 16777215 + + + + + false + + + + font-weight: normal; + + + Intervalo: + + + + + + + true + + + + 0 + 0 + + + + + 0 + 0 + + + + font-weight: normal; + + + + + + + + 0 + 0 + + + + + 55 + 0 + + + + + 55 + 16777215 + + + + font-weight: normal; + + + Formato: + + + + + + + + 16777215 + 25 + + + + QFrame::Sunken + + + 1 + + + 0 + + + Qt::ScrollBarAlwaysOff + + + Qt::ScrollBarAlwaysOff + + + false + + + true + + + Qt::NoTextInteraction + + + + + + + true + + + + 0 + 0 + + + + Qt::LeftToRight + + + font-weight: normal; + + + + + + + + + + font-weight: normal; + + + Timezone: + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/tipowidget.ui b/libpgmodeler_ui/ui/tipowidget.ui new file mode 100644 index 000000000..fd3dfc7b4 --- /dev/null +++ b/libpgmodeler_ui/ui/tipowidget.ui @@ -0,0 +1,383 @@ + + + TipoWidget + + + + 0 + 0 + 491 + 502 + + + + + 0 + 0 + + + + Form + + + + 2 + + + 6 + + + + + + 0 + 0 + + + + Configuração: + + + + + + + + 80 + 0 + + + + Tipo Base + + + true + + + + + + + + 95 + 0 + + + + Enumeração + + + + + + + + 80 + 0 + + + + Composto + + + + + + + Qt::Horizontal + + + + 92 + 20 + + + + + + + + + 0 + 100 + + + + Enumerações + + + + 4 + + + 6 + + + + + Enumeração: + + + + + + + + + + + + + + 0 + 0 + + + + + 0 + 100 + + + + Atributos + + + + + + + 0 + + + + Atributos + + + + 4 + + + 6 + + + + + Comp. Interno: + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + + + + Armazenamento: + + + + + + + + + + Por Valor: + + + + + + + + 0 + 0 + + + + + + + + + + + Categoria: + + + + + + + + + + Preferido: + + + + + + + + 0 + 0 + + + + + + + + + + + Delimitador: + + + + + + + 1 + + + + + + + Alinhamento: + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + + char + + + + + smallint + + + + + integer + + + + + double precision + + + + + + + + Valor Padrão: + + + + + + + + + + + Funções + + + + 4 + + + 6 + + + + + Função INPUT: + + + + + + + Função OUTPUT: + + + + + + + Função RECV: + + + + + + + Função SEND: + + + + + + + Função TPMOD_IN: + + + + + + + Função TPMOD_OUT: + + + + + + + Função ANALYZE: + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/visaoobjetoswidget.ui b/libpgmodeler_ui/ui/visaoobjetoswidget.ui new file mode 100644 index 000000000..f002462b2 --- /dev/null +++ b/libpgmodeler_ui/ui/visaoobjetoswidget.ui @@ -0,0 +1,545 @@ + + + VisaoObjetosWidget + + + true + + + + 0 + 0 + 281 + 343 + + + + + :/icones/icones/pgsqlModeler48x48.png:/icones/icones/pgsqlModeler48x48.png + + + Qt::AllDockWidgetAreas + + + Objetos do Modelo + + + + true + + + + 4 + + + + + Qt::Vertical + + + + true + + + + 0 + 0 + + + + 0 + + + + true + + + + 0 + + + 0 + + + + + true + + + + + + + + 0 + 170 + 255 + + + + + + + + + 0 + 170 + 255 + + + + + + + + + 0 + 170 + 255 + + + + + + + + + 9 + + + + QFrame::Sunken + + + Qt::ScrollBarAsNeeded + + + true + + + QAbstractItemView::NoEditTriggers + + + true + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectItems + + + + 18 + 18 + + + + 20 + + + false + + + true + + + true + + + false + + + true + + + false + + + true + + + false + + + true + + + + 1 + + + + + + + + + + 0 + + + 0 + + + + + true + + + + 9 + + + + QAbstractItemView::NoEditTriggers + + + true + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + Qt::SolidLine + + + true + + + true + + + 96 + + + true + + + true + + + false + + + false + + + 20 + + + false + + + false + + + false + + + + Objeto + + + + :/icones/icones/table.png:/icones/icones/table.png + + + + + Tipo + + + + :/icones/icones/usertype.png:/icones/icones/usertype.png + + + + + Objeto Pai + + + + :/icones/icones/schema.png:/icones/icones/schema.png + + + + + Tipo Objeto Pai + + + + :/icones/icones/usertype.png:/icones/icones/usertype.png + + + + + + + + + + + + + + 16777215 + 16777215 + + + + Tipos de Objetos Visíveis + + + false + + + false + + + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + QAbstractItemView::NoEditTriggers + + + true + + + -1 + + + true + + + + + + + Qt::Horizontal + + + + 58 + 20 + + + + + + + + + + Marcar Todos + + + + + + + Desmarcar Todos + + + + + + + + + Qt::Horizontal + + + + 58 + 20 + + + + + + + + + + + + + + + + + Qt::Horizontal + + + + 118 + 20 + + + + + + + + Selecionar + + + + + + + :/icones/icones/confirmar.png:/icones/icones/confirmar.png + + + + 20 + 20 + + + + + + + + Cancelar + + + + + + + :/icones/icones/fechar1.png:/icones/icones/fechar1.png + + + + 20 + 20 + + + + + + + + + 30 + 30 + + + + Configuração da visão de objetos + + + ... + + + + :/icones/icones/config.png:/icones/icones/config.png + + + + 20 + 20 + + + + true + + + false + + + + + + + + 30 + 30 + + + + Visão em árvore + + + + + + ... + + + + :/icones/icones/visaoarvore.png:/icones/icones/visaoarvore.png + + + + 20 + 20 + + + + true + + + true + + + + + + + + 30 + 30 + + + + Visão em lista + + + ... + + + + :/icones/icones/visaolista.png:/icones/icones/visaolista.png + + + + 20 + 20 + + + + true + + + + + + + + + + + + + diff --git a/libpgmodeler_ui/ui/visaowidget.ui b/libpgmodeler_ui/ui/visaowidget.ui new file mode 100644 index 000000000..166b255c2 --- /dev/null +++ b/libpgmodeler_ui/ui/visaowidget.ui @@ -0,0 +1,272 @@ + + + VisaoWidget + + + + 0 + 0 + 473 + 250 + + + + Form + + + + 2 + + + 4 + + + + + 0 + + + + Referências + + + + 4 + + + 6 + + + + + Tipo: + + + + + + + + Coluna + + + + + Expressão + + + + + + + + Qt::Horizontal + + + + 249 + 21 + + + + + + + + Usado em: + + + + + + + + + SELECT-FROM + + + + + + + FROM-WHERE + + + + + + + Após WHERE + + + + + + + + + Tabela: + + + + + + + + 0 + 0 + + + + Alias Tabela: + + + + + + + + 0 + 0 + + + + + + + + Coluna: + + + + + + + + 0 + 0 + + + + Alias Coluna: + + + + + + + + 0 + 0 + + + + + + + + Expressão: + + + + + + + + 0 + 0 + + + + + 0 + 60 + + + + + 16777215 + 16777215 + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAsNeeded + + + + + + + + 0 + 0 + + + + Alias Expressão: + + + + + + + + 0 + 0 + + + + + + + + Qt::Horizontal + + + + 203 + 20 + + + + + + + + + Previsão de Código + + + + 4 + + + 6 + + + + + + DejaVu Sans Mono + + + + false + + + true + + + + + + + + + + + + diff --git a/libutil/libutil.pro b/libutil/libutil.pro index 662e68510..cd1603e6c 100644 --- a/libutil/libutil.pro +++ b/libutil/libutil.pro @@ -1,12 +1,12 @@ -#include(../pgmodeler.pro) +include(../pgmodeler.pro) -#CONFIG += qt warn_on uitools uic4 -#QT = core gui qt3support -#TEMPLATE = lib -#TARGET = util -#DESTDIR = ../build/lib -#DEPENDPATH = ". res src ui moc obj" -#OBJECTS_DIR = obj +CONFIG += qt warn_on uitools uic4 +QT = core gui qt3support +TEMPLATE = lib +TARGET = util +DESTDIR = ../build/lib +DEPENDPATH = ". res src ui moc obj" +OBJECTS_DIR = obj HEADERS += $$PWD/src/excecao.h \ $$PWD/src/atributosglobais.h \ diff --git a/main/main.pro b/main/main.pro new file mode 100644 index 000000000..aef4969b3 --- /dev/null +++ b/main/main.pro @@ -0,0 +1,32 @@ +include(../pgmodeler.pro) + +CONFIG += qt warn_on uitools uic4 +QT = core gui qt3support +TEMPLATE = app +TARGET = pgmodeler + +DEPENDPATH = ". moc obj" +OBJECTS_DIR = obj +DESTDIR = ../build/ + +QMAKE_POST_LINK+= "cp -r ../schemas/ $$DESTDIR; \ + cp -r ../conf/ $$DESTDIR; \ + cp -r ../lang/ $$DESTDIR; \ + cp ../*.md $$DESTDIR; \ + cp ../LICENSE $$DESTDIR;" + +QMAKE_DISTCLEAN+= "-r $$DESTDIR/schemas \ + $$DESTDIR/conf \ + $$DESTDIR/lang \ + $$DESTDIR/*.md \ + $$DESTDIR/LICENSE" + +LIBS = $$DESTDIR/lib/$$LIBUTIL \ + $$DESTDIR/lib/$$LIBPARSERS \ + $$DESTDIR/lib/$$LIBCONEXBD \ + $$DESTDIR/lib/$$LIBOBJRENDERER \ + $$DESTDIR/lib/$$LIBPGMODELER \ + $$DESTDIR/lib/$$LIBPGMODELERUI + +HEADERS += src/aplicacao.h +SOURCES += src/main.cpp diff --git a/main/src/aplicacao.h b/main/src/aplicacao.h new file mode 100644 index 000000000..580f1a24d --- /dev/null +++ b/main/src/aplicacao.h @@ -0,0 +1,68 @@ +/* +# Projeto: Modelador de Banco de Dados PostgreSQL (pgModeler) +# Sub-projeto: main +# Classe: Aplicacao +# Descrição: Esta classe é uma derivação da classe QApplication. +# A mesa apenas sobrecarrega o método notify() de sua +# classe pai para tratar as execeções disparadas cujas +# instâncias são da classe Excecao. +# Data de Criação: 30/08/2007 +# +# Copyleft 2006-2012 - Raphael Araujo e Silva +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License + +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +#ifndef APLICACAO_H +#define APLICACAO_H + +#include +#include +#include "caixamensagem.h" +//*********************************************************** +extern CaixaMensagem *caixa_msg; +//----------------------------------------------------------- +class Aplicacao: public QApplication { + private: + public: + + //O construtor da classe executa o construtor da classe pai + Aplicacao(int & argc, char ** argv) : QApplication(argc,argv) + { + + } + + bool notify(QObject * receiver, QEvent * event) + { + try + { + //Executa normalmente o notify da classe pai + return(QApplication::notify(receiver,event)); + } + catch(Excecao &e) + { + //Exibe uma caixa de mensagem de erro crítico com a mensagem da exceção + caixa_msg->show(e); + return(false); + } + catch(...) //Capturando as demais execeções + { + //Exibe uma caixa de mensagem de erro crítico com a mensagem da exceção + caixa_msg->show(trUtf8("Erro"),trUtf8("Exceção desconhecida capturada!"), CaixaMensagem::ICONE_ERRO); + return(false); + } + } +}; +//*********************************************************** +#endif diff --git a/main/src/main.cpp b/main/src/main.cpp new file mode 100644 index 000000000..e75ba7ea7 --- /dev/null +++ b/main/src/main.cpp @@ -0,0 +1,87 @@ +#include "formprincipal.h" +#include "aplicacao.h" +#include + +int main(int argc, char **argv) +{ + try + { + Aplicacao app(argc,argv); + QTranslator tradutor; + + //Obtém os valores das variáveis de ambiente + QString dir_conf=getenv("PGMODELER_CONF_DIR"), + dir_sch=getenv("PGMODELER_SCHEMAS_DIR"), + dir_lang=getenv("PGMODELER_LANG_DIR"), + dir_plugins=getenv("PGMODELER_PLUGINS_DIR"); + + /* Caso alguma das variáveis de ambiente esteja setada + atribui a mesma a configuração global respectiva sobrescrevendo + a configuração padrão */ + if(!dir_conf.isEmpty()) + AtributosGlobais::DIR_CONFIGURACOES=dir_conf.replace("\\","/"); + + if(!dir_sch.isEmpty()) + AtributosGlobais::DIR_RAIZ_ESQUEMAS=dir_sch.replace("\\","/"); + + if(!dir_lang.isEmpty()) + AtributosGlobais::DIR_RAIZ_ESQUEMAS=dir_lang.replace("\\","/"); + + if(!dir_plugins.isEmpty()) + AtributosGlobais::DIR_PLUGINS=dir_plugins.replace("\\","/"); + + app.addLibraryPath(AtributosGlobais::DIR_PLUGINS); + + //Carrega o arquivo de tradução da interface de acordo com o locale do sistema + tradutor.load(QString("pgmodeler.") + QLocale::system().name(), AtributosGlobais::DIR_LINGUAS); + + //Instala o tradutor na aplicação + app.installTranslator(&tradutor); + + /* Aloca o formulário principal. + Durante a sua alocação pode ser disparadas uma série de exceções que a + aplicação não é capaz de caputar pois o formulário ainda não foi atribuído + a esta, desta forma, a alocação do formulário e feita dentro de um + try-catch para possível captura de erros. A aplicação será abortada + e o erro mostrado no console caso ocorra. */ + FormPrincipal fmain;//=new FormPrincipal; + + //Atribui o formulário alocado à aplicação + app.setMainWidget(&fmain); + + //Exibe o formulário principal e prossegue com a execução da aplicação + fmain.showMaximized(); + + //Executa a aplicação + app.exec(); + + //Desloca a janela principal ao término do loop principal + //delete(fmain); + return(0); + } + //Caso um erro seja capturado durante a inicialização da aplicação + catch(Excecao &e) + { + deque excecoes; + deque::iterator itr, itr_end; + unsigned idx=0; + + //Obtém a lista de exceções geradas + e.obterListaExcecoes(excecoes); + itr=excecoes.begin(); + itr_end=excecoes.end(); + + //Exibe todas as exceções no console + while(itr!=itr_end) + { + cout << "[" << idx << "] " << itr->obterArquivo().toStdString() << " (" << itr->obterLinha().toStdString() << ")" << endl; + cout << " " << itr->obterLocal().toStdString() << endl; + cout << " [" << Excecao::obterNomeErro(itr->obterTipoErro()).toStdString() << "] "; + cout << itr->obterMensagemErro().toStdString() << endl << endl; + itr++; idx++; + } + + //Retorna o código de erro da última exceção e aborta a aplicação + return(e.obterTipoErro()); + } +} diff --git a/pgmodeler.pro b/pgmodeler.pro index bf8a28056..0b5df8a86 100644 --- a/pgmodeler.pro +++ b/pgmodeler.pro @@ -1,5 +1,7 @@ CONFIG += ordered TEMPLATE = subdirs +TARGET = pgmodeler +DESTDIR = build/ unix { GLOBAL_INCLUDES = .\ @@ -10,6 +12,13 @@ unix { GLOBAL_LIBS = /usr/local/pgsql/lib/libpq.so \ -lxml2 + + LIBUTIL=libutil.so + LIBPARSERS=libparsers.so + LIBCONEXBD=libconexbd.so + LIBPGMODELER=libpgmodeler.so + LIBOBJRENDERER=libobjrenderer.so + LIBPGMODELERUI=libpgmodeler_ui.so } windows { @@ -21,6 +30,13 @@ windows { "C:/QtSDK/mingw/bin/libxml2.dll" QMAKE_LFLAGS=-Wl,-enable-auto-import + + LIBUTIL=util.dll + LIBPARSERS=parsers.dll + LIBCONEXBD=conexbd.dll + LIBPGMODELER=pgmodeler.dll + LIBOBJRENDERER=objrenderer.dll + LIBPGMODELERUI=pgmodeler_ui.dll } INCLUDEPATH = $${GLOBAL_INCLUDES} \ @@ -29,12 +45,18 @@ INCLUDEPATH = $${GLOBAL_INCLUDES} \ $$PWD/libparsers/src \ $$PWD/libpgmodeler/src \ $$PWD/libobjrenderer/src \ - $$PWD/pgmodeler_ui/src + $$PWD/libpgmodeler_ui/src LIBS = $${GLOBAL_LIBS} -SUBDIRS = pgmodeler_ui plugins/dummyplugin - +SUBDIRS = libutil \ + libparsers \ + libconexbd \ + libpgmodeler \ + libobjrenderer \ + libpgmodeler_ui \ + main \ + plugins/dummyplugin sources.files = models schemas lang conf README.md COMPILING.md PLUGINS.md LICENSE sources.path = . diff --git a/plugins/dummyplugin/dummyplugin.pro b/plugins/dummyplugin/dummyplugin.pro index cb772aa06..ed2871f95 100644 --- a/plugins/dummyplugin/dummyplugin.pro +++ b/plugins/dummyplugin/dummyplugin.pro @@ -1,4 +1,5 @@ PGMODELER_SRC_DIR=/root/pgmodeler +PGMODELER_LIB_DIR=/root/pgmodeler/build/lib !exists($$PGMODELER_SRC_DIR) { warning("pt_BR: O diretório de código fonte do pgModeler '$$PGMODELER_SRC_DIR' não foi encontrado! Certifique-se de que a variável PGMODELER_SRC_DIR aponta para uma localização válida!") @@ -12,7 +13,7 @@ CONFIG += plugin qt warn_on uitools uic4 QT = core gui qt3support TEMPLATE = lib TARGET = dummyplugin -TRANSLATIONS = $$PWD/lang/dummyplugin.en_US.ts +TRANSLATIONS += $$PWD/lang/dummyplugin.en_US.ts CODECFORTR = UTF-8 @@ -22,7 +23,7 @@ INCLUDEPATH = $${GLOBAL_INCLUDES} \ $$PGMODELER_SRC_DIR/libparsers/src \ $$PGMODELER_SRC_DIR/libpgmodeler/src \ $$PGMODELER_SRC_DIR/libobjrenderer/src \ - $$PGMODELER_SRC_DIR/pgmodeler_ui/src + $$PGMODELER_SRC_DIR/libpgmodeler_ui/src DEPENDPATH = ". res src ui moc obj" MOC_DIR = moc @@ -30,17 +31,18 @@ OBJECTS_DIR = obj UI_DIR = src DESTDIR = ../../build/plugins/dummyplugin +LIBS = $$PGMODELER_LIB_DIR/$$LIBUTIL \ + $$PGMODELER_LIB_DIR/$$LIBPARSERS \ + $$PGMODELER_LIB_DIR/$$LIBCONEXBD \ + $$PGMODELER_LIB_DIR/$$LIBOBJRENDERER \ + $$PGMODELER_LIB_DIR/$$LIBPGMODELER \ + $$PGMODELER_LIB_DIR/$$LIBPGMODELERUI + QMAKE_DISTCLEAN+= "-r $$MOC_DIR $$OBJECTS_DIR" QMAKE_POST_LINK+= "cp res/dummyplugin.png $$DESTDIR;\ cp -r lang/ $$DESTDIR;" -HEADERS += src/dummyplugin.h \ - $$PGMODELER_SRC_DIR/pgmodeler_ui/src/pgmodelerplugin.h \ - $$PGMODELER_SRC_DIR/pgmodeler_ui/src/caixamensagem.h \ - $$PGMODELER_SRC_DIR/libutil/src/excecao.h - -SOURCES += src/dummyplugin.cpp \ - $$PGMODELER_SRC_DIR/pgmodeler_ui/src/caixamensagem.cpp \ - $$PGMODELER_SRC_DIR/libutil/src/excecao.cpp +HEADERS += src/dummyplugin.h +SOURCES += src/dummyplugin.cpp diff --git a/start-pgmodeler.bat b/start-pgmodeler.bat index 304683b87..fc11dd85a 100644 --- a/start-pgmodeler.bat +++ b/start-pgmodeler.bat @@ -1,9 +1,7 @@ set PGMODELER_ROOT="C:\Users\raphael\Desktop\pgmodeler-code\build" set PGMODELER_CONFIGS_DIR=%PGMODELER_ROOT%\conf - set PGMODELER_SCHEMAS_DIR=%PGMODELER_ROOT%\schemas - set PGMODELER_LANG_DIR=%PGMODELER_ROOT%\lang - +set PGMODELER_LANG_DIR=%PGMODELER_ROOT%\plugins %PGMODELER_ROOT%\pgmodeler.exe diff --git a/start-pgmodeler.sh b/start-pgmodeler.sh index 38e3a0c7a..99a712e20 100755 --- a/start-pgmodeler.sh +++ b/start-pgmodeler.sh @@ -3,6 +3,8 @@ export PGMODELER_ROOT=`pwd`/build export PGMODELER_CONF_DIR=$PGMODELER_ROOT/conf export PGMODELER_SCHEMAS_DIR=$PGMODELER_ROOT/schemas export PGMODELER_LANG_DIR=$PGMODELER_ROOT/lang +export PGMODELER_PLUGINS_DIR=$PGMODELER_ROOT/plugins export LANG=pt_BR.UTF-8 +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PGMODELER_ROOT/lib $PGMODELER_ROOT/pgmodeler