Salvar configurações de layout do FwBrowse

Estou desenvolvendo um FwBrowse baseado em um array, esse componente tem uma função muito interessante que estou utilizando que é a possibilidade do usuário personalizar as colunas, tamanho, layout, etc.

Agora eu queria saber se é possível facilitar um pouco esse trabalho de personalização, no FwMBrowse ele tem um recurso muito interessante que ele salva o layout das colunas (tamanho e posição) de forma automática quando o usuário fecha a tela. No meu caso usando o FwBrowse ele não tem esse mesmo comportamento, seria possível salvar essa configuração (tamanho e posições das colunas) de forma automática, algo do tipo antes de fechar a rotina chamar o método oBrw:Save() para fazer isso?


#INCLUDE "RWMake.ch"
#INCLUDE "Totvs.ch"
#INCLUDE "ParmType.ch"
#include "FWBrowse.CH"

//##################################################################################################
//##+========+=================================+=======+====================+======+=============+##
//##|Programa| MSDTeste                        | Autor | Cirilo Rocha       | Data | 29/12/2022  |##
//##+========+=================================+=======+====================+======+=============+##
//##|Desc.   | Função de exemplo de uso do FwBrowse como MarkBrowser usando arrays como origem   |##
//##+========+==========+========================================================================+##
//##|  DATA  | ANALISTA | MANUTENÇÃO EFETUADA                                                    |##
//##+========+==========+========================================================================+##
//##|        |          |                                                                        |##
//##|        |          |                                                                        |##
//##|        |          |                                                                        |##
//##+========+==========+========================================================================+##
//##################################################################################################
User Function MSDTeste()

    //Declaração de Variáveis----------------------------------------------------------------------
    Local aSX5            := {}    AS Array
    Local lOk            := .F.    AS Logical
    Local nX                    AS Numeric

    //Tamanho dos botões da tela
    Local nLarBt        := 050    AS Numeric
    Local nAltBt        := 015    AS Numeric

    //Posições do array aDados
    Local lBL_MARK        := 01    AS Numeric
    Local cBL_COD        := 02    AS Numeric
    Local cBL_DESC        := 03    AS Numeric

    Local nBL_TAMARR    := 03    AS Numeric

    //Posições de retorno da função FwGetSX5
    Local _X5_FILIAL    := 01    AS Numeric
    Local _X5_TABELA    := 02    AS Numeric
    Local _X5_CHAVE     := 03    AS Numeric
    Local _X5_DESCRI    := 04    AS Numeric

    //Deixei privado caso alguma função chamada precise manipular a tela
    Private aDados        := {}    AS Array
    Private oDlg                AS Object
    Private oLst                AS Object
    Private oPnl                AS Object

    //Carrega dados para o array da lista----------------------------------------------------------
    aSX5    := FwGetSX5('12',/*cChave*/) //Retorna os dados SX5, USEI A TABELA 12 ESTADOS APENAS COMO EXEMPLO
    For nX := 1 to Len(aSX5)
        aAdd(aDados,Array(nBL_TAMARR))
        aTail(aDados)[lBL_MARK]    := .F.    //Por padrão vem desmarcado
        aTail(aDados)[cBL_COD]    := aSX5[nX][_X5_CHAVE]
        aTail(aDados)[cBL_DESC]    := aSX5[nX][_X5_DESCRI]
    Next

    If Len(aDados) == 0
        ApMsgStop(    'Nenhum dado localizado para seleção.','! ! ! ATENÇÃO ! ! !')
        Return .F.
    EndIf

    //---------------------------------------------------------------------------------------------
    oDlg    := MSDialog():New(    000,000,550,650,'Selecione os registros',/*cPar6*/,/*nPar7*/,/*lPar8*/,;
                                /*DS_MODALFRAME*/,/*anClrText*/,/*anClrBack*/,/*oPar12*/,/*oWnd*/,.T.,,,,/*lTransparent*/)


        oPnl := tPanel():New(010,010,,oDlg,,,,,,(oDlg:nWidth/2)-15,(oDlg:nHeight/2)-20-2*nAltBt)
        oLst := fwBrowse():New(oPnl)
        //oLst:setOwner( oPnl )

        oLst:setDataArray()
        oLst:setArray( aDados )
        //oLst:disableConfig()
        //oLst:disableReport()
        //oLst:SetLocate() // Habilita a Localização de registros

        // Evento de DuploClick (troca o valor do primeiro elemento do Vetor)
        oLst:bLDblClick := {|| aDados[oLst:nAt][lBL_MARK] := !aDados[oLst:nAt][lBL_MARK] }

        oLst:AddStatusColumns({|| IIF(aDados[oLst:nAt][lBL_MARK ],'LBTIK','LBNO') })    //Adiciona coluna legenda

        //               Descrição            bDados              Tipo  Pic   Alinhamento     Tam Dec Edita
        oLst:addColumn({"UF"    , {|| aDados[oLst:nAt][cBL_COD] }, "C", "@!" ,COLUMN_ALIGN_LEFT,4 ,  ,.F.})
        oLst:addColumn({"Nome"    , {|| aDados[oLst:nAt][cBL_DESC]}, "C", "@!" ,COLUMN_ALIGN_LEFT,15,  ,.F.})
        oLst:Activate(.T.)

        //-----------------------------------------------------------------------------------------
        tButton():New(250,005,'Cancelar'    ,oDlg,{|| lOk := .F. , oDlg:End()             },nLarBt,nAltBt,,,,.T.)
            //AQUI PODEM SER IMPLEMENTADOS BOTÕES DO TIPO MARCA TODOS, DESMARCA TODOS, INVERTE SELEÇÃO
        tButton():New(250,269,'OK'            ,oDlg,{|| IIf((lOk := VldOK()),oDlg:End(),) },nLarBt,nAltBt,,,,.T.)

    // ativa diálogo centralizado
    oDlg:Activate(/*uPar1*/,/*uPar2*/,/*uPar3*/,.T./*lCenter*/,/*{|Self| Valid }*/,/*uPar6*/,/*{|Self| Init }*/ )

    If lOK
        //COLOQUE AQUI ALGUMA GRAVAÇÃO OU PROCESSAMENTO CASO O USUÁRIO TENHA CONFIRMADO A TELA#####
    EndIf

Return lOk

//-------------------------------------------------------------------------------------------------
Static Function VldOK()

    //Declaração de variáveis----------------------------------------------------------------------
    Local lOK        := .T.     AS Logical

    //COLOQUE AQUI AS VALIDAÇÕES DOS DADOS#########################################################

Return lOK

Olá,

A classe FWBrowse é a mais simples dentre as classes de browse, como a FWMBrowse e a FWFormBrowse, essas por sua vez herdam de FWBrowse e implementam diversas questões do Protheus, como profile, privilégios etc.

Ela foi criada com o intuito de ser genérica, podendo ser utilizada em ambientes diferentes do Protheus padrão, por conta disso, ela procura não acessar diretamente o profile do usuário, visto que em alguns produtos, o profile não existe. Logo ela não faz essa gravação por padrão.

Então se eu entendi bem eu poderia usar qualquer uma dessas classe (FWMBrowse e FWFormBrowse) usando os mesmos métodos, vai funcionar igual (com array como eu preciso) e vai ter essa funcionalidade de salvamento?

Troquei aqui e abriu o componente, mas não salva quando fecho a janela. Preciso chamar algum método para que ele salve a ordem e tamanho das colunas quando fechar a janela?

O método seria VerifyLayout() mas ele não consegue entender quando usa Array ou tabela temporária. O que ele faz é carregar os dados da personalização para o sub-objeto oConfig e depois chamar o método Save() que faz o processo de gravação. Como eu consigo capturar essas informações para atualizar o objeto oConfig? ou algum método que já faça isso?

Fiz progressos muito promissores nesse processo, já consigo ler e gravar as configurações, preciso apenas concluir alguns ajustes quando o usuário ocultar alguma coluna. Assim que tiver pronto publico aqui o fonte para todos.

Após um pouco de trabalho e engenharia reversa consegui montar funções que fazem a leitura da posição e tamanho das colunas, salva e recupera. Ficou funcional. Segue o fonte em anexo para quem precisar fazer o mesmo.

No meu cenário eu utilizei com um array, mas acredito que funcione perfeitamente com query e tabela temporária, porque o componente em si é o mesmo.

:warning: Atenção: Esta publicação foi transferida automaticamente do fórum antigo, mas os anexos não foram incluídos.