Estou tentando fazer funcionar no Harbour 3.0 modo console a interface com acentos
no linux ubuntu 12.04. Mudei a codificação do terminal para UTF-8, usei o Gedit
para escrever o código no formato UTF-8. Os acentos aparecem sem problemas mas
nas telas de entradas de dados (GET) acontecem alguns problemas.
A codificação UTF-8 utiliza 1, 2, 3 ou até 4 bytes para representar um caracter.
Isto faz com que quando se digita um acento o sistema apresente alguns erros.
Nas telas a seguir vocês podem ver que se os caracteres acentuados são apresentados
através de @ say não há nenhum problema. Mas com o GET nós temos.
Além disto pelo fato da codificação UTF-8 usar mais de um byte para representar
determinados caracteres as funções substr(), len(), at(), rat() retornam dados incorretos.
Questões:
1. Existe uma classe GET preparada para ler UTF-8 no harbour em modo console?
2. Existem funções no harbour preparadas para substituir substr(), len(), at(), rat() e outras
correlatas compatíveis com UTF-8 em modo console?
3. Já tentei usar outras codificações no linux para tentar aceitar os acentos mas não deu certo.
Alguém já conseguiu usar outra codificação com sucesso? Em caso positivo qual e site seus passos.
Do jeito que está é possível criar a interface em modo console com todos os acentos, exceto nos GETS.
Uma saída seria vincular uma função na cláusula VALID do GET para permitir somente letras, números, espaços
e sinais aritméticos. Mas eu ainda não fico satisfeito desta forma...
Obrigado desde já por qualquer ajuda.
Um abraço a todos!!!
Código fonte:
/**
---------------------------------------------------------------------------
Rotinas codificadas em Harbour 3.0.0 (Rev. 16951)
Problemas com GET no UBUNTU 12.04 LTS quando se usa a codificação UTF-8
Yugi386
---------------------------------------------------------------------------
*/
REQUEST HB_LANG_PT
REQUEST HB_CODEPAGE_UTF8
#define YLIB_CARAC_VALIDOS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%&*()-_+={}[],.;<>:?/\| "
function main()
ylib_iniciar() // Configurações Iniciais
do while .t.
ylib_JanelaMain("H a r b o u r","W+/g","N/B","N/W,W+/R","N/W")
opc := ylib_criaMenu(01,01,{{" Iniciar ","Iniciar"},{" Menu ","Menu de opções"},{" Sair ","Sair"}},"N/W,W+/R",1)
Do case
case opc = 3 .or. opc = 0
exit
case opc = 2
menuVertical := {{"Clientes","Clientes"},{"Fornecedores","Fornecedores"},{"Movimento","Movimento"},;
{"Nota Fiscal","Notas"}, {"Sair","Sair"}}
opc := ylib_criaMenuVertical(02,11,menuVertical,"N/W,W+/R")
case opc = 1
// Informações dos campos: campo, tipo, tamanho, cabeçalho, mascara, edição, conteudo
campos := { ;
{"Codigo","N",12,"Código","999999999999",.F.,1},;
{"Nome","C",50,"Nome","@s40 ",.t.,padr("",50," ")},;
{"CPF","C",12,"CPF","9999999999-9",.t.,padr("",11," ")},;
{"Data","D",10,"Data","",.t.,CtoD("01/01/2014")},;
{"Endereço","C",50,"Endereço","@s40 ",.t.,padr("",50," ")} ,;
{"Bairro","C",50,"Bairro","@s40 ",.t.,padr("",50," ")} ,;
{"Complemento","C",50,"Complemento","@s40 ",.t.,padr("",50," ")} ,;
{"Cidade","C",50,"Cidade","@s40 ",.t.,padr("",50," ")} ,;
{"Estado","C",2,"Estado","",.t.,padr("",2," ")} }
do while.t.
ret := ylib_formulario("Clientes",05,10,16,65,"W/g","N/W",1,campos,"N/W,W/R,,,N/BG")
if ret == nil
exit
else
campos = aclone(ret)
ret = ylib_ValidaString(campos[2][7])
// rotinas de validação (???)
if empty(ret)
ylib_Msg("Aviso",09,30,14,60,"W/B","N/W",1,"Dados Corretos!!!")
exit
else
ylib_Msg("Erro",09,20,14,62,"W/R","N/W",1,"O Sistema não aceita acentos!!!")
endif
endif
enddo
// cancelamento do cadastro
if ret == nil
ylib_Msg("Erro",07,20,12,50,"W/R","N/W",1,"Você cancelou o cadastro!!!")
endif
Endcase
Enddo
close all
clear all
quit
return nil
/**
--------------------------------------------------------------------------------------------------------------------
Descrição:
Configurações Iniciais Gerais do Sistema
Esta função seta várias configurações gerais do Sistema
Parâmetros:
Nenhum
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_iniciar()
HB_LANGSELECT( 'PT' )
HB_CDPSELECT( "UTF8" )
set date french
set century on
set scoreboard off
set cursor off
setblink(.f.)
set confirm on
setmode(25,80)
set message to 24 center
set wrap On
return nil
/**
--------------------------------------------------------------------------------------------------------------------
Descrição:
Criar Janela Genérica com controle de cor, posição, cor do título e sombra com 4 posições
Parâmetros:
1. mTitulo....: Titulo da janela
2. l1.........: Linha inicial da janela
3. c1.........: Coluna inicial da janela
4. l2.........: Linha final da janela
5. c2.........: Coluna final da janela
6. corTitulo..: Cor do Título da janela (Frente e Fundo)
7. corJanela..: Cor da janela (Frente e Fundo)
8. tipoSombra.: pode ser 1, 2, 3, 4, respectivamente, sombra na posição inferior esquerdo, inferior direito, superior esquerdo e superior direito
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_janela(mTitulo,l1,c1,l2,c2,corTitulo,corJanela,tipoSombra)
if corTitulo == NIL
corTitulo = "W/B"
endif
if corJanela == NIL
corJanela = "N/W"
endif
// Posicionamento da sombra da Janela
setcolor("N/N+")
do case
case tipoSombra == 1 // inferior esquerdo
ylib_Sombra(l1+1,c1-1,l2+1,c2-1)
case tipoSombra == 2 // inferior direito
ylib_Sombra(l1+1,c1+1,l2+1,c2+1)
case tipoSombra == 3 // superior esquerdo
ylib_Sombra(l1-1,c1-1,l2-1,c2-1)
case tipoSombra == 4 // superior direito
ylib_Sombra(l1-1,c1+1,l2-1,c2+1)
otherwise
ylib_Sombra(l1+1,c1-1,l2+1,c2-1) // Padrão inferior esquerdo
endcase
// Posicionamento da Janela e Título
setcolor(corJanela)
@ l1,c1 clear to l2,c2
setcolor(corTitulo)
@ l1,c1 clear to l1,c2
@ l1,c1+1 say mTitulo
return nil
/**
--------------------------------------------------------------------------------------------------------------------
Descrição:
Construindo a Janela Principal do Programa
Parâmetros:
1. mTitulo.....: Título da tela principal do programa
2. CorTitulo...: Cor do título da janela (frente e fundo)
3. CorJanela...: Cor da Janela Principal do sistema
4. CorMenu.....: Cor do Menu principal do sistema
5. CorStatus...: Cor da barra de status do sistema (frente e fundo)
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_JanelaMain(mTitulo,CorTitulo,CorJanela,CorMenu,CorStatus)
if CorTitulo == nil
CorTitulo = "W+/B"
endif
if CorJanela == nil
CorJanela = "N/BG"
endif
if CorMenu = nil
CorMenu = "N/W,W+/R"
endif
if CorStatus = nil
CorStatus = "N/W,W+/R"
endif
setcolor(CorJanela)
cls
setcolor(CorTitulo)
@ 00,00 clear to 00,79
ylib_center(00,mTitulo,CorTitulo,80,0)
setcolor(CorStatus)
@ 24,00 clear to 24,79
setcolor(CorMenu)
@ 01,00 clear to 01,79
return nil
/**
--------------------------------------------------------------------------------------------------------------------
Descrição:
Centraliza mensagem na Tela em uma determinada linha ou em uma janela
Parâmetros:
1. linha.........: Linha em que a mensagem vai aparecer
2. mensagem......: Informação a ser apresentada
3. cor...........: Cor que a mensagem será apresentada (Frente e Fundo)
4. tamanhoLinha..: Define o tamanho da linha do sistema (padrão 80)
5. inicio........: Coluna inicial a ser considerada para a centralização da mensagem
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_center(linha,mensagem,cor,tamanhoLinha,inicio)
local lcor := setcolor(), posicao := 0
if cor == nil
cor = "N/W"
endif
if tamanhoLinha == nil
tamanhoLinha = 80
endif
if inicio == nil
iniciao = 0
endif
posicao = int((tamanhoLinha - len(alltrim(Mensagem))) / 2) + inicio
setcolor(cor)
@linha,posicao say mensagem
setcolor(lcor)
return nil
/**
--------------------------------------------------------------------------------------------------------------------
Descrição:
Cria um Menu Horizontal
Parâmetros:
1. l1...........: Linha inicial do Menu
2. c1...........: Coluna inicial do Menu
3. opcoes.......: Matriz com opções e mensagens de status do Menu
4. corMenu......: Cor do menu padrão e selecionado
5. espacamento..: Espaçamento entre os menus
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_criaMenu(l1,c1,opcoes,corMenu,espacamento)
local tam := 0, ct:=0, opc:= 0
if corMenu == nil
corMenu = "N/W,W+/R"
endif
if espacamento == nil
espacamento = 2
endif
tam:= len(opcoes)
setcolor(corMenu)
ylib_status(corMenu,24)
for ct:= 1 to tam
@ l1,c1 prompt opcoes[ct][1] message alltrim(opcoes[ct][2])
c1 = c1 + len(opcoes[ct][1]) + espacamento
next
menu to opc
return opc
/**
--------------------------------------------------------------------------------------------------------------------
Cria Um Formulário para Edição de Dados tipo Caracter, Numérico e Data
Parâmetros:
01. mTitulo....: Titulo do formulário
02. l1.........: Linha inicial da janela
03. c1.........: Coluna inicial da janela
04. l2.........: Linha final da janela
05. c2.........: Coluna final da janela
06. corTitulo..: Cor do Título da janela (Frente e Fundo)
07. corJanela..: Cor da janela (Frente e Fundo)
08. tipoSombra.: pode ser 1, 2, 3, 4, respectivamente, sombra na posição inferior esquerdo, inferior direito, superior esquerdo e superior direito
09. campos.....: Matriz com o nome do campo, tipo e tamanho
10. cor do get.: Cor do campo de leitura de variáveis
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_formulario(mTitulo,l1,c1,l2,c2,corTitulo,corJanela,tipoSombra,campos,corGet,conteudo)
local maxCabecalho := 0, ct:=0, tam:=0, wcampos := Array(len(campos)), tela
set cursor On
ylib_janela(mTitulo,l1,c1,l2,c2,corTitulo,corJanela,tipoSombra)
tam := len(campos)
for ct:= 1 to tam
maxCabecalho := max(maxCabecalho,len(alltrim(campos[ct][4])))
next
++maxcabecalho
for ct:= 1 to tam
if at(":",campos[ct][4]) == 0
campos[ct][4] := alltrim(campos[ct][4]) + replicate(".",maxcabecalho-len(alltrim(campos[ct][4]))) + ":"
endif
next
l1 = l1+2
for ct:= 1 to tam
if campos[ct][7] == NIL
do case
case upper(campos[ct][2]) == "C"
wcampos[ct] = space(campos[ct][3])
case upper(campos[ct][2]) == "D"
wcampos[ct] = CtoD(" / / ")
case upper(campos[ct][2]) == "N"
wcampos[ct] = 0
endcase
else
wcampos[ct] = campos[ct][7]
endif
next
setcolor(corGet)
for ct:= 1 to tam
if campos[ct][6]
@ l1,c1+1 say campos[ct][4] get wcampos[ct] pict campos[ct][5]
else
@ l1,c1+1 say campos[ct][4] get wcampos[ct] pict campos[ct][5] WHEN .F.
endif
++l1
next
read
if lastkey() = 27 // se pressionar ESC o retorno é NIL
return NIL
else
for ct:= 1 to tam // preenchendo os campos de retorno
campos[ct][7] = wcampos[ct]
next
endif
set cursor off
return campos
/**
--------------------------------------------------------------------------------------------------------------------
Tela Para Mensagem
Parâmetros:
01. mTitulo....: Titulo da Janela
02. l1.........: Linha inicial da janela
03. c1.........: Coluna inicial da janela
04. l2.........: Linha final da janela
05. c2.........: Coluna final da janela
06. corTitulo..: Cor do Título da janela (Frente e Fundo)
07. corJanela..: Cor da janela (Frente e Fundo)
08. tipoSombra.: pode ser 1, 2, 3, 4, respectivamente, sombra na posição inferior esquerdo, inferior direito, superior esquerdo e superior direito
09. Mensagem...: Mensagem de Erro
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_Msg(mTitulo,l1,c1,l2,c2,corTitulo,corJanela,tipoSombra,mensagem)
local tela
save screen to tela
set cursor off
ylib_janela(mTitulo,l1,c1,l2,c2,corTitulo,corJanela,tipoSombra)
setcolor(corJanela)
keyboard chr(27)
memoedit(mensagem,l1+2,c1+1,l2-1,c2-1,.F.)
setcolor(cortitulo)
@ l2-1,c1 + int(((c2-c1+1)-6)/2) say " OK "
inkey(0)
restore screen from tela
return nil
/**
--------------------------------------------------------------------------------------------------------------------
Validação de caracteres aceitáveis como entrada de dados
Parâmetros:
01. mEntrada...: Entrada de dados a ser validada (String)
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_ValidaString(mEntrada)
local ret := "", ct:= 0
for ct:= 1 to len(mEntrada)
if !(substr(mEntrada,ct,1) $ YLIB_CARAC_VALIDOS)
if at(substr(mEntrada,ct,1),ret) == 0
ret += substr(mEntrada,ct,1) + ", "
endif
endif
if len(mEntrada) == ct
ret := substr(ret,1,len(ret)-2)
endif
next
return ret
/**
--------------------------------------------------------------------------------------------------------------------
Sombra Real na tela
Parâmetros:
01. l1...: Linha inicial
02. c1...: Coluna Inicial
03. l2...: Linha final
04. c2...: Coluna final
---------------------------------------------------------------------------------------------------------------------
*/
function ylib_Sombra(l1,c1,l2,c2)
local ret := "", ct:= 0, tela, coluna:=c1, linha:=l1, cor, tam:=0
tela :=savescreen(l1,c1,l2,c2)
cor := setcolor()
setcolor("N+/N")
tam := len(tela)
for ct:= 1 to tam step 4
@ linha,coluna say substr(tela,ct,1)
++ coluna
if coluna > c2
coluna = c1
++ linha
endif
if linha > l2
exit
endif
next
setcolor(cor)
return nil
/**
--------------------------------------------------------------------------------------------------------------------
Descrição:
Cria um Menu Vertical
Parâmetros:
1. l1...........: Linha inicial do Menu
2. c1...........: Coluna inicial do Menu
3. opcoes.......: Matriz com opções e mensagens de status do Menu
4. corMenu......: Cor do menu padrão e selecionado
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_criaMenuVertical(l1,c1,opcoes,corMenu)
local tam := 0, ct:=0, opc:= 0, maxMenu:=0, l2, c2, contador:=1
if corMenu == nil
corMenu = "N/W,W+/R"
endif
// verificando o tamanho do Menu
tam:= len(opcoes)
for ct:= 1 to tam
maxMenu = Max(maxMenu,len(alltrim(opcoes[ct][1])))
next
l2 = l1 + tam + 1
c2 = c1 + 8 + maxMenu
setcolor(corMenu)
ylib_status(corMenu,24)
ylib_Sombra(l1+1,c1-1,l2+1,c2-1)
@ l1,c1 clear to l2,c2
@ l1,c1 to l2,c2
++l1
for ct:= 1 to tam
@ l1,c1+1 prompt alltrim(str(contador)) + ". " + padr(opcoes[ct][1],c2-c1-4," ") message alltrim(opcoes[ct][2])
++contador
++l1
next
menu to opc
return opc
/**
--------------------------------------------------------------------------------------------------------------------
Descrição:
Limpa a Barra de Status
Parâmetros:
1. cor.........: Cor da barra de status
2. linha.......: linha
--------------------------------------------------------------------------------------------------------------------
*/
function ylib_status(cor,linha)
setcolor(cor)
@linha,00 clear to linha,79
return nil
Imagens das telas: