#include "TOTVS.CH"
#include "FILEIO.CH"
#INCLUDE "TBIConn.ch"
Function u_CBCustom()
// ---------------------------------------------------------------
local i
local oWebChannel
local cMultGet := ""
local cHost,nPort,lConnected
local tempPath := ""
PRIVATE oWebEngine
PRIVATE oMultGet
PRIVATE oGetLink
PRIVATE oDlg
oDlg := TWindow():New(10, 10, 800, 600, "TOTVS - CloudBridge", NIL, NIL, NIL, NIL, NIL, NIL, NIL,;
CLR_BLACK, CLR_WHITE, NIL, NIL, NIL, NIL, NIL, NIL, .T. )
oDlg:setCSS("QPushButton{margin: 1px; background-color: "+_colorTOTVS+"; border: none; color: #fff; }")
// Android ou iOS
if _rmtType == 8 .Or. _rmtType == 9
// Libera rotacao do dispositivo
PRIVATE oMobile := TMobile():New(oDlg)
oMobile:SetScreenOrientation(-1)
// Temporario do dispositivo
tempPath := oMobile:GetTempPath() + "/"
// Prepara bloco de codigo pra callBack de notificacao
oMobile:bNotificationTapped := {|id| notificationTapped(id) }
endif
// Prepara o conector WebSocket, sempre pra LOCALHOST e retorna a PORTA LIVRE
oWebChannel := TWebChannel():New()
nPort := oWebChannel::connect()
cHost := oWebChannel:cHost
nPort := oWebChannel:nPort
lConnected := oWebChannel:lConnected
// Verifica conexão
if !lConnected
msgStop("Erro na conexão com o WebSocket")
return
endif
// Define o CallBack JavaScript
oWebChannel:bJsToAdvpl := {|self,codeType,codeContent| jsToAdvpl(self,codeType,codeContent) }
// Monta link GLOBAL
if subs(_tempPath,1,2) == "C:"
_tempPath := "file:///" + strTran(_tempPath, "\", "/")
endif
mainHtml := _tempPath + mainHtml
oWebEngine := TWebEngine():New(oDlg, 0, 0, 100, 100,, nPort)
oWebEngine:bLoadFinished := {|self,url| loadFinished(self,url) }
oWebEngine:setAsMain() // Define como WebEngine que recebera o KEY_BACK (Android)
// Painel superior
@ 000, 000 MSPANEL pnTop SIZE 250, 024 OF oDlg COLORS 0, 16777215 RAISED // Mansano: 250, 012
pnTop:setCss("QFrame{background-color: #6BB4F1;}")
// Alinha componentes
pnTop:Align := CONTROL_ALIGN_TOP
oWebEngine:Align := CONTROL_ALIGN_ALLCLIENT
// CONOUT fake para exibir a mensageria
oFont1 := TFont():New("Courier",,018,,.F.,,,,,.F.,.F.)
@ 038, 000 MSPANEL ConOut SIZE 250, 16 OF oDlg COLORS 0, 16777215 RAISED
oMultGet := TSimpleEditor():New( 0,0,ConOut, 50,50,"",, {| u | if( pCount() > 0, cMultGet := u, cMultGet )}, oFont1, .T.)
ConOut:Align := CONTROL_ALIGN_BOTTOM
oMultGet:Align := CONTROL_ALIGN_ALLCLIENT
CreateFormTop(pnTop)
oDlg:Activate("MAXIMIZED")
Return
// Parseia o Json em um Hash
Static Function getJsonHash(jsonData, oHash)
// ---------------------------------------------------------------
Local oJson := tJsonParser():New()
Local jsonfields := {}
Local nRetParser := 0
if empty(jsonData)
return .F.
endif
// Converte JSON pra Hash
return oJson:Json_Hash(jsonData, len(jsonData), @jsonfields, @nRetParser, @oHash)
return
// Retorna valor do campo no Hash
Static Function getHField(oHash, jsonField)
// ---------------------------------------------------------------
Local xGet := Nil
// Recupera valor do campo
if HMGet(oHash, jsonField, xGet)
return xGet
else
return ""
endif
return
// Bloco de codigo do termino da carga da pagina
static function loadFinished(self,url)
// ---------------------------------------------------------------
oGetLink:cText := url+space(1000)
return
// CALLBACK das notificacoes
static function notificationTapped(id)
conout("createNotification: id: " + cValToChar(id))
return
// CALLBACK JavaScript
static function jsToAdvpl(self,codeType,codeContent)
// ---------------------------------------------------------------
Local i
Local oTmpHash := .F.
Local xRet, lRet
Local xVal, fnCallBack, cFile, aBarResult,;
aDevicesResult, sMsg, cPosition, id, title, message,;
cQuery, nFields, nRecords
if valType(codeType) == "C"
_conout("jsToAdvpl->codeType: " + codeType + " = " + codeContent)
if codeType == "runAdvpl"
if getJsonHash(codeContent, @oTmpHash)
xVal := &("{|| " + getHField(oTmpHash, "codeBlock") + "}")
if valType(xVal) == "B"
xRet := eval(xVal)
xRet := cValToChar(xRet) // Converte pra String
// Executa o CallBack
fnCallBack = getHField(oTmpHash, "callBack")+"('" +xRet+ "')"
oWebEngine:runJavaScript(fnCallBack)
endif
else
_msgAlert("RunAdvpl command not executed", "CloudBridge")
endif
return
endif
// Android Ou iOS
if _rmtType == 8 .Or. _rmtType == 9
// Tira foto
if codeType == "getPicture"
cFile:= oMobile:TakePicture()
_conout("[getPicture] - " + cFile)
// Executa o CallBack
fnCallBack = codeContent+"('" +cFile+ "')"
oWebEngine:runJavaScript(fnCallBack)
return
endif
// Codigo de barras
if codeType == "barCodeScanner"
aBarResult := oMobile:BarCode()
If aBarResult[1] = ""
_conout("[barCode] - " + "Nenhum código de barras disponÃvel.")
Else
_conout("[barCode] - " + "Código: " + aBarResult[1] + chr(13) + "Formato: " + aBarResult[2])
// Executa o CallBack
fnCallBack = codeContent+"('" +aBarResult[1]+ "')"
oWebEngine:runJavaScript(fnCallBack)
EndIf
return
endif
// Verifica dispositivos pareados
if codeType == "pairedDevices"
aDevicesResult:= oMobile:GetPairedBluetoothDevices()
sMsg := ""
For i := 1 to len(aDevicesResult)
sMsg := sMsg + "Nome: " + aDevicesResult[i][1] + chr(13)
sMsg := sMsg + "Endereço: " + aDevicesResult[i][2] + chr(13) + chr(13)
Next i
If sMsg = ""
sMsg := "Nenhum dispositivo pareado ou interface Bluetooth desligada."
Else
sMsg := "Dispositivos Bluetooth Pareados:" + chr(13) + chr(13) + sMsg
EndIf
_conout("[bluetooth] - " + sMsg)
// Executa o CallBack
fnCallBack = codeContent+"('" +SubStr(sMsg,1,30)+ "')"
oWebEngine:runJavaScript(fnCallBack)
return
endif
// Libera orientacao
if codeType == "unlockOrientation"
oMobile:SetScreenOrientation(-1)
_conout("[unlockOrientation]")
return
endif
// Trava orientacao
if codeType == "lockOrientation"
oMobile:SetScreenOrientation(2)
_conout("[lockOrientation]")
return
endif
// GPS
if codeType == "getCurrentPosition"
cPosition := oMobile:getGeoCoordinate(1)
// PARA LIMPAR O SINAL DE GRAUS CHR(176)
//cPosition := StrTran(cPosition, chr(176), "")
_conout("[getCurrentPosition] - " + cPosition)
// Executa o CallBack
fnCallBack = codeContent+"('" +cPosition+ "')"
oWebEngine:runJavaScript(fnCallBack)
return
endif
// Testa perifericos
if codeType == "testDevice"
if getJsonHash(codeContent, @oTmpHash)
lRet := oMobile:TestDevice(getHField(oTmpHash, "testFeature"))
// Executa o CallBack
fnCallBack = getHField(oTmpHash, "callBack")+"('" +cValToChar(lRet)+ "')"
oWebEngine:runJavaScript(fnCallBack)
else
_msgAlert("testDevice command not executed", "CloudBridge")
endif
return
endif
// Cria notificacao
// O callBack sera disparado pelo bloco de codigo bNotificationTapped
if codeType == "createNotification"
if getJsonHash(codeContent, @oTmpHash)
id := getHField(oTmpHash, "id")
title := getHField(oTmpHash, "title")
message := getHField(oTmpHash, "message")
oMobile:CreateNotification(id, title, message)
else
_msgAlert("createNotification command not executed", "CloudBridge")
endif
return
endif
// Abre configuracoes
if "CloudBridge")codeType == "openSettings"
oWebEngine:runJavaScript("openSettings")
oMobile:OpenSettings(val(codeContent))
return
endif
// Recupera diretorio temporario
if codeType == "getTempPath"
fnCallBack = codeContent + "('" + oMobile:GetTempPath() + "');"
endifoWebEngine:runJavaScript(fnCallBack)
returnendif
endif
// Abre configuracoes Aciona o vibracall do dispositivo
if codeType == "openSettings"
oWebEngine:runJavaScript("openSettings")
vibrate"
oMobile:OpenSettingsvibrate(val(codeContent))
returnendif
endif
endif
if codeType == "change_link"
oGetLink:cText := codeContent+space(1000)
return
endif
// SQLITE - BEGIN -----------------------------------------------------------------------------
// SQLITE - Begin transction
if codeType == "dbBegin" .and. getJsonHash(codeContent, @oTmpHash)
if TCSQLExec("BEGIN") < 0
// Executa o CallBack de ERRO
fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
oWebEngine:runJavaScript(fnCallBack)
else
// Executa o CallBack de SUCESSO
fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
oWebEngine:runJavaScript(fnCallBack)
endif
endif
// SQLITE - Commit
if codeType == "dbCommit" .and. getJsonHash(codeContent, @oTmpHash)
if TCSQLExec("COMMIT") < 0
// Executa o CallBack de ERRO
fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
oWebEngine:runJavaScript(fnCallBack)
else
// Executa o CallBack de SUCESSO
fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
oWebEngine:runJavaScript(fnCallBack)
endif
endif
// SQLITE - RollBack
if codeType == "dbRollback" .and. getJsonHash(codeContent, @oTmpHash)
if TCSQLExec("ROLLBACK") < 0
// Executa o CallBack de ERRO
fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
oWebEngine:runJavaScript(fnCallBack)
else
// Executa o CallBack de SUCESSO
fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
oWebEngine:runJavaScript(fnCallBack)
endif
endif
// SQLITE - Executa query
if codeType == "dbExec"
if getJsonHash(codeContent, @oTmpHash)
cQuery := getHField(oTmpHash, "query")
// Testa query
if TCSQLExec(cQuery) < 0
// Executa o CallBack de ERRO
fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
oWebEngine:runJavaScript(fnCallBack)
else
// Executa o CallBack de SUCESSO
fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"
oWebEngine:runJavaScript(fnCallBack)
endif
else
_msgAlert("dbExec command not executed", "CloudBridge")
endif
endif
// SQLITE - Recupera dados da query
if codeType == "dbGet"
if getJsonHash(codeContent, @oTmpHash)
cQuery := getHField(oTmpHash, "query")
// Testa query
if TCSQLExec(cQuery) < 0
// Executa o CallBack de ERRO
fnCallBack = getHField(oTmpHash, "callBackError") + "('" +TcSqlError()+ "');"
oWebEngine:runJavaScript(fnCallBack)
return
endif
// Recupera os dados
dbUseArea(.T., 'TOPCONN', TCGenQry(,,cQuery),'TRB', .F., .T.)
nFields := TRB->(fCount())
nRecords := TRB->(recCount())
xRet := "["
while !TRB->(eof())
xRet += '{'
for i := 1 to nFields
xRet += quotedStr( fieldName(i) )+":"
xRet += quotedStr( fieldGet(i) ) + iif(i < nFields, ",", "")
next i
xRet += '}' + iif(TRB->(recno()) < nRecords, ",", "")
TRB->(DbSkip())
end
xRet += "]"
TRB->(dbCloseArea())
// Executa o CallBack
fnCallBack = getHField(oTmpHash, "callBackSuccess") + "(" +xRet+ ");"
oWebEngine:runJavaScript(fnCallBack)
else
_msgAlert("dbGet command not executed", "CloudBridge")
endif
endif
// SQLITE - END -----------------------------------------------------------------------------
if codeType == "page_started"
//form:loadForm()
endif
endif
return
// Cria componentes superiores
static function CreateFormTop(pnTop)
// ---------------------------------------------------------------
Local oButton1
Local cLink := mainHtml + space(1000)
Local oFontBtn := TFont():New("Arial Narrow",,022,,.F.,,,,,.F.,.F.)
Local oFontGet := TFont():New("Arial",,022,,.F.,,,,,.F.,.F.)
oWebEngine:navigate(mainHtml)
@ 000, 221 BUTTON oButtonL1 PROMPT "<" SIZE 028, 011 OF pnTop ACTION {|| oWebEngine:goBack() } FONT oFontBtn PIXEL
@ 000, 221 BUTTON oButtonL2 PROMPT ">" SIZE 028, 011 OF pnTop ACTION {|| oWebEngine:goForward() } FONT oFontBtn PIXEL
oGetLink := TGet():New( 000, 000, { | u | If( PCount() == 0, cLink, cLink := u ) },pnTop, 220, 011,,, 0, 16777215,,.F.,,.T.,,.F.,,.F.,.F.,,.F.,.F. ,,"cLink",,,, )
oGetLink:setFont(oFontGet)
@ 000, 221 BUTTON oButton1 PROMPT "Go" SIZE 028, 011 OF pnTop ACTION {|| oWebEngine:navigate(cLink) } FONT oFontBtn PIXEL
@ 000, 221 BUTTON oButton2 PROMPT "Menu" SIZE 028, 011 OF pnTop ACTION {|| oGetLink:cText:=mainHtml, oMultGet:Load(""), oWebEngine:Navigate(mainHtml) } FONT oFontBtn PIXEL
@ 000, 221 BUTTON oButtonClose PROMPT "X" SIZE 028, 011 OF pnTop ACTION {|| oDlg:end() } FONT oFontBtn PIXEL
oButtonClose:setCSS("QPushButton{margin: 1px; background-color: #C75050; border: none; color: #fff; }")
oGetLink:setCSS("QLineEdit{margin: 1px; border: 1px solid "+_colorTOTVS)
oButtonL1:Align := CONTROL_ALIGN_LEFT
oButtonL2:Align := CONTROL_ALIGN_LEFT
oButtonClose:Align := CONTROL_ALIGN_RIGHT
oButton2:Align := CONTROL_ALIGN_RIGHT
oButton1:Align := CONTROL_ALIGN_RIGHT
oGetLink:Align := CONTROL_ALIGN_ALLCLIENT
return
// ---------------------------------------------------------------
// Funcoes de apoio
// ---------------------------------------------------------------
static function _conout(cText)
conOut(cText)
oMultGet:Load(cText)
Return
Static function _msgAlert(cText)
// Android Ou iOS
if _rmtType == 8 .Or. _rmtType == 9
oMobile:CreateNotification(999, "CloudBridge", cText)
else
msgAlert(cText)
conout(cText)
endif
Return
static function quotedStr(xText)
return ('"'+ cValToChar(xText) +'"')
|