Árvore de páginas

Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

Portuguese

Este arquivo PRW contém o ferramental necessário para customizações ADVPL à partir do CloudBridge, nele você entenderá todo o mecanismo de comunicação entre o Navegador Embedado (JavaScript) e o ADVPL.

As funções mais importantes são:

Function u_CBCustom()
Função principal, deve ser inserida na TAG mainFunction no arquivo .cloud, base do aplicativo, para ser instanciada no momento da abertura.

Function loadFinished()
Função atribuida como bloco de código do oWebEngine:bLoadFinished, ela será disparada ao termino da carga das páginas e como parâmetro recebe a URL carregada.

Function notificationTapped()
Função atribuida como bloco de código do oMobile:bNotificationTapped, ela será disparada quando a notificação for selecionada no dispositivo móvel. Ela recebe o ID inserido na notificação.

Function jsToAdvpl()
Função atribuida como bloco de código do oWebChannel:bJsToAdvpl, ela será disparada durante o recebimento da Função dialog.jsToAdvpl() que será disparada via JavaScript.

Arquivo

Bloco de código
languagecpp
themeEclipse
linenumberstrue
collapsefalse
#include "TOTVS.CH"
#include "FILEIO.CH"
#INCLUDE "TBIConn.ch"

Function u_CBCustom()
    	// ---------------------------------------------------------------
    	local i
    	local oWebChannel
    	local cMultGet := ""
    	local cHost,nPort,lConnected
    	local tempPath := GetTempPath()
    	PRIVATE oWebEngine
    	PRIVATE oMultGet
    	PRIVATE oGetLink
    PRIVATE    oDlg

    	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       PRIVATE oMobile := TMobile:= 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        tempPath := "file::= "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
    , scalesize
	Local xVal, fnCallBack, cFile, aBarResult,;
    	aDevicesResult, sMsg, cPosition, id, title, message,;
    	cQuery, nFields, nRecords, aAccelerometerSensor

    	if valType(codeType) == "C"
        		_conout("jsToAdvpl->codeType: " + codeType + " = " + codeContent)

        		if codeType == "runAdvpl"
            if 			if getJsonHash(codeContent, @oTmpHash)
                				xVal := &("{|| " + getHField(oTmpHash, "codeBlock") + "}")
                				if valType(xVal) == "B"
                    					xRet := eval(xVal)
					xRet := cValToChar(xRet) // Converte                xRet := cValToChar(xRet) // Converte pra String

                    // pra String
					// Executa o CallBack
                    					fnCallBack = getHField(oTmpHash, "callBack")+"('" +xRet+ "')"
                    oWebEngine:runJavaScript(fnCallBack)
                endif
            else
                					oWebEngine:runJavaScript(fnCallBack)
				endif
			else
				_msgAlert("RunAdvpl command not executed", "CloudBridge")
			endif
			return
		endif
		// Android Ou iOS
		if _rmtType == 8 .Or. _rmtType == 9
			// Tira endiffoto
			if codeType == "getPicture"
			  _conout("entrou no getPicture! " + ValType(codeContent))
			   return
if getJsonHash(codeContent, @oTmpHash)
			    scalesize :=   endif
getHField(oTmpHash, "ScaletoWidth")
        // Android Ou iOS
cFile:= oMobile:TakePicture(scalesize)
			    fnCallBack =   if _rmtType == 8 .Or. _rmtType == 9

  getHField(oTmpHash, "callBack")+"('" +cFile+ "')"
			  else
			    
			  endif
        _conout("[getPicture] - //" Tira+ fotocFile)
        // Executa   if codeType == "getPicture"o CallBack
                cFile:= oMobile:TakePicture(oWebEngine:runJavaScript(fnCallBack)
        return
        _conout("[getPicture] - " + cFile)

                // Executa o CallBack
                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+"('" +cFileaBarResult[1]+ "')"
                					oWebEngine:runJavaScript(fnCallBack)
                return
            endif

            // Codigo de  barras
            				EndIf
				return
			endif
			// Verifica dispositivos pareados
			if codeType == "barCodeScanner"
                aBarResult pairedDevices"
				aDevicesResult:= oMobile:BarCodeGetPairedBluetoothDevices()
                If aBarResult				sMsg := ""
				For i := 1 to len(aDevicesResult)
					sMsg := sMsg + "Nome: " + aDevicesResult[i][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
            + 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

            				return
			endif
			// Trava orientacao
            			if codeType == "lockOrientation"
                				oMobile:SetScreenOrientation(2)
                				_conout("[lockOrientation]")
                return
            endif

            				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

            				oWebEngine:runJavaScript(fnCallBack)
				return
			endif
			// Testa perifericos
            			if codeType == "testDevice"
                				if getJsonHash(codeContent, @oTmpHash)
                     @oTmpHash)
					lRet := oMobile:TestDevice(getHField(oTmpHash, "testFeature"))

                    					// Executa o CallBack
                    					fnCallBack = getHField(oTmpHash, "callBack")+"('" +cValToChar(lRet)+ "')"
                    oWebEngine:runJavaScript(fnCallBack)
                else
                    					oWebEngine:runJavaScript(fnCallBack)
				else
					_msgAlert("testDevice command not executed", "CloudBridge")
                endif
                return
            endif

            				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
                     title, message)
				else
					_msgAlert("createNotification command not executed", "CloudBridge")
                endif
                return
            endif

            				endif
				return
			endif
			// Abre configuracoes
            			if codeType == "openSettings"
                				oWebEngine:runJavaScript("openSettings")

                				oMobile:OpenSettings(val(codeContent))
                return
            endif
            
            				return
			endif
			
			// Recupera diretorio temporario 
            			if codeType == "getTempPath"
                				fnCallBack = codeContent + "('" + oMobile:GetTempPath() + "');"
                				oWebEngine:runJavaScript(fnCallBack)
            endif
            
            			endif
			
			// Aciona o vibracall do dispositivo 
            			if codeType == "vibrate"
                				oMobile:vibrate(val(codeContent))
            endif
            
            			endif
			
			// Efetua uma leitura no sensor de acelerômetro do dispositivo 
             acelerômetro do dispositivo 
			if codeType == "readAccelerometer"
                				aAccelerometerSensor:= oMobile:ReadAccelerometer()

                				sMsg := "Valores lidos do sensor acelerometro (m/s2):" + "\n"
                				sMsg += "x:" + str(aAccelerometerSensor[1]) + "\n"
				sMsg += "y:" + str(aAccelerometerSensor[2])            + "\n"
				sMsg += "yz:" + str(aAccelerometerSensor[23])
				_conout("accelerometer - " + "\n"
                sMsg += "z:" + str(aAccelerometerSensor[3])

                _conout("accelerometer - " + sMsg)

                // Executa o CallBack
                fnCallBack = codeContent+"('" +sMsg+ "')"
                oWebEngine:runJavaScript(fnCallBack)
                return
            endif

            // Pre-insere um contato da agenda do dispositivo 
            if codeType == "addContact"
                sMsg)
				// Executa o CallBack
				fnCallBack = codeContent+"('" +sMsg+ "')"
				oWebEngine:runJavaScript(fnCallBack)
				return
			endif
			// Pre-insere um contato da agenda do dispositivo 
			if codeType == "addContact"
				if getJsonHash(codeContent, @oTmpHash)
					aEmails := {}
					aPhones := {}
					aPostals := {}
					oTMobCont := TMobileContact():New()
					oTMobCont:cName := getHField(oTmpHash, "name")
					oTMobCont:cCompany := getHField(oTmpHash, "company")
					oTMobCont:cJobTitle := getHField(oTmpHash, "jobTitle")
					oTMobCont:cNote := getHField(oTmpHash, "note")
					cEmail1 := getHField(oTmpHash, "email1")
					nEmailType1 := getHField(oTmpHash, "emailType1")
					aAdd( aEmails, TMobileContactEmail():New2( nEmailType1, cEmail1 ) )
					cPhone1 := getHField(oTmpHash, "phone1")
					nPhoneType1 := getHField(oTmpHash, "phoneType1")
					aAdd( aPhones, TMobileContactPhone():New2( nPhoneType1, cPhone1 ) )
					aAdd( aPostals, TMobileContactPostal():New2( 2, getHField(oTmpHash, "postal") ) )
					oTMobCont:aEmails := aEmails
					oTMobCont:aPhones := aPhones
					oTMobCont:aPostals := aPostals
					oMobile:AddContact( oTMobCont )
				else
					_msgAlert("addContact command not executed", "CloudBridge")
				endif
				return
			endif
			
			// Procura contatos no dispositivo
			if codeType == "findContact"
				if getJsonHash(codeContent, @oTmpHash)
                    aEmails 					aContacts := {}
                    aPhones := {}
                    aPostals := {}

          					oTMobCont := TMobileContact():New()
					aContacts := oTMobCont:FindContact( getHField( oTmpHash, "filter" ) )
					VarInfo( "Contatos encontrados", aContacts )
				else
					_msgAlert("findContact command not executed", "CloudBridge")
				endif
				return
			endif
			
	  // Pre-insere um evento de calendario do dispositivo 
      if codeType == "addCalendar"
 oTMobCont := TMobileContact():New()
     if   getJsonHash(codeContent, @oTmpHash)
          datai  oTMobCont:cName := getHField(oTmpHash, "namestartdate")
          datae := getHField(oTmpHash, "enddate")
        oTMobCont:cCompany  dataictod := getHFieldright(oTmpHashdatai,2) + "company/")
 + substr(datai,6,2) + "/" + left(datai,4)
          dataectod := right(datae,2)  oTMobCont:cJobTitle := getHField(oTmpHash, "jobTitle"+ "/" + substr(datae,6,2) + "/" + left(datae,4)
          oTmpCalEv := TCalendarEvent():New()
          oTMobContoTmpCalEv:cNotecTitle := getHField(oTmpHash, "notetitle")

                    cEmail1 oTmpCalEv:cDescription := getHField(oTmpHash, "email1descr")
                    nEmailType1 oTmpCalEv:cLocation := getHField(oTmpHash, "emailType1addr")
          oTmpCalEv:dStartDate          aAdd( aEmails, TMobileContactEmail():New2( nEmailType1, cEmail1 ) )

       := ctod(dataictod,"ddmmyyyy")
             cPhone1 oTmpCalEv:cStartTime := getHField(oTmpHash, "phone1starttime")
          oTmpCalEv:dEndDate := ctod(dataectod,"ddmmyyyy")
        nPhoneType1  oTmpCalEv:cEndTime := getHField(oTmpHash, "phoneType1endtime")
          if getHField(oTmpHash, "allday") == "True"
        aAdd( aPhones, TMobileContactPhone():New2( nPhoneType1, cPhone1 ) )

oTmpCalEv:lAllDay := .T.
          else
          aAdd( aPostals, TMobileContactPostal():New2( 2, getHField(oTmpHash, "postal") ) )

oTmpCalEv:lAllDay := .F.
          endif
          oTMobCont:aEmailsiRet := aEmailsoMobile:addCalendarEvent(oTmpCalEv)
          fnCallBack = getHField(oTmpHash, "callBack")+"('" +cValToChar(iRet)+ "')"
      oTMobCont:aPhones := aPhones
  oWebEngine:runJavaScript(fnCallBack)
        endif
      endif
    oTMobCont:aPostals := aPostals

      // Procura eventos de calendario no dispositivo
      if  oMobile:AddContact( oTMobCont )codeType == "findCalendar"
        if getJsonHash(codeContent, @oTmpHash)
      else
    datai := getHField(oTmpHash, "startdate")
          datae :=  _msgAlert("addContact command not executed"getHField(oTmpHash, "CloudBridgeenddate")
          dataictod := right(datai,2) + "/"  endif
    + substr(datai,6,2) + "/" + left(datai,4)
          dataectod  return
            endif:= right(datae,2) + "/" + substr(datae,6,2) + "/" + left(datae,4)
          aCalIds := oMobile:findCalendarEvent(ctod(dataictod,"ddmmyyyy"), ctod(dataectod,"ddmmyyyy"))
          cIds  // Procura contatos no dispositivo:= '{"ids": ['
            if codeType == "findContact"Len(aCalIds) > 0
            for i := 1 ifto getJsonHash(codeContent, @oTmpHashlen(aCalIds)
              cIds += '"' + cvaltochar(aCalIds[i]) + '",'
  aContacts := {}

        next
            oTMobContcIds := TMobileContactleft(cIds,Len(cIds):New(-1)
          endif
          aContactscIds :+= oTMobCont:FindContact( getHField( oTmpHash, "filter" ) )"]}"
          fnCallBack          VarInfo( "Contatos encontrados", aContacts )= getHField(oTmpHash, "callBack")+"('" +cIds+ "')"
                else
  oWebEngine:runJavaScript(fnCallBack)
        endif
      endif
    _msgAlert("findContact command not executed", "CloudBridge")
      // Visualiza evento do calendario do dispositivo
    endif
  if codeType == "viewCalendar"
        oMobile:viewCalendarEvent(codecontent)
   return
   endif
      
   endif

   // Retorna informações do evento endifinformado

        if codeType == "change_linkgetCalendar"
        if getJsonHash(codeContent, @oTmpHash)
    oGetLink:cText := codeContent+space(1000)
    id := getHField(oTmpHash, "id")
     return
     oCalEv   endif

:= oMobile:getCalendarEvent(id)
        // SQLITE - BEGIN -----------------------------------------------------------------------------
  
        // SQLITE -dateic Begin transction:= dtos(oCalEv:dStartDate)
        if  codeTypedateec =:= "dbBegin" .and. getJsonHash(codeContent, @oTmpHashdtos(oCalEv:dEndDate)
          dateijs  if:= TCSQLExec("BEGIN")
  < 0
       dateejs := ""
        // Executa o CallBack de ERRO
    if Len(dateic) == 8 .AND. Len(dateec) == 8
            fnCallBackdateijs := getHFieldleft(oTmpHash, "callBackError"dateic,4) + "('-" +TcSqlError() substr(dateic,5,2) + "');-"
 + right(dateic,2)
            dateejs := oWebEngine:runJavaScript(fnCallBack)
            elseleft(dateec,4) + "-" + substr(dateec,5,2) + "-" + right(dateec,2)
          endif
      // Executa o CallBack deif SUCESSOoCalEv:lAllDay
            cAllday    fnCallBack := getHField(oTmpHash, "callBackSuccess") + "();"True"
          else
      oWebEngine:runJavaScript(fnCallBack)
      cAllDay := "False"
    endif
      endif  endif

        // SQLITE -
 Commit
        if codeTypecCalEv :== "dbCommit{" .and. getJsonHash(codeContent, @oTmpHash)
   
          cCalEv += '"title":"'     + oCalEv:cTitle   if TCSQLExec("COMMIT") < 0
     + '",'
          //cCalEv Executa o CallBack de ERRO
   += '"descr":"'     + oCalEv:cDescription     + '",'
       fnCallBack = getHField(oTmpHash, "callBackError") cCalEv += '"('" +TcSqlError()+ "');"
addr":"'      + oCalEv:cLocation         oWebEngine:runJavaScript(fnCallBack)+ '",'
          cCalEv  else
+= '"startdate":"'  + dateijs             // Executa o CallBack de SUCESSO+ '",'
          cCalEv += '"starttime":"'  + oCalEv:cStartTime   fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"'",'
          cCalEv += '"enddate":"'    oWebEngine:runJavaScript(fnCallBack)
+ dateejs            endif
     + '",'
  endif

        //cCalEv SQLITE - RollBack
+= '"endtime":"'   + oCalEv:cEndTime     if codeType == "dbRollback" .and. getJsonHash(codeContent, @oTmpHash) + '",'
          cCalEv  if TCSQLExec("ROLLBACK") < 0
+= '"allday":"'    + cAllDay                 // Executa o CallBack de ERRO
+ '"}'
          
          fnCallBack = getHField(oTmpHash, "callBackErrorcallBack") + "('" +TcSqlError()cCalEv+ "');"
                oWebEngine:runJavaScript(fnCallBack)
            elseendif
                // Executa o CallBack de SUCESSO
                fnCallBack = getHField(oTmpHash, "callBackSuccess") + "();"endif
      
		endif
		
		
		if codeType == "change_link"
			oGetLink:cText := codeContent+space(1000)
			return
		endif
		// SQLITE -   oWebEngine:runJavaScript(fnCallBack)
            endif
        endif

        BEGIN -----------------------------------------------------------------------------
		// SQLITE - ExecutaBegin query
        transction
		if codeType == "dbExecdbBegin"
            if .and. getJsonHash(codeContent, @oTmpHash)
			if TCSQLExec("BEGIN") < 0
				// Executa o CallBack de         cQuery :ERRO
				fnCallBack = getHField(oTmpHash, "querycallBackError")

 + "('"              // Testa query
                if TCSQLExec(cQuery) < 0
                    +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
                    			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") <     endif
            else
                _msgAlert("dbExec command not executed", "CloudBridge")
            endif
        endif

        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 - Recupera dadosExecuta da query
        		if codeType == "dbGetdbExec"
            			if getJsonHash(codeContent, @oTmpHash)
                , @oTmpHash)
				cQuery := getHField(oTmpHash, "query")

                				// Testa query
                				if TCSQLExec(cQuery) < 0
                    // Executa o CallBack de ERRO
                    					// 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)

                    return
                endif

                + "();"
					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( fieldName(i) )+":"
						xRet += quotedStr( fieldGet(i) ) + iif(i < nFields, ",", "")
                    next i

                    					next i
					xRet += '}' + iif(TRB->(recno()) < nRecords, ",", "")
                    (recno()) < nRecords, ",", "")
					TRB->(DbSkip())
                end
                				end
				xRet += "]"
                				TRB->(dbCloseArea())

                				// Executa o CallBack
                				fnCallBack = getHField(oTmpHash, "callBackSuccess") + "(" +xRet+ ");"
                				oWebEngine:runJavaScript(fnCallBack)
            else
                			else
				_msgAlert("dbGet command not executed", "CloudBridge")
            endif
        endif
         command not executed", "CloudBridge")
			endif
		endif
		// SQLITE - END -----------------------------------------------------------------------------

        		if codeType == "page_started"
            			//form:loadForm()
        endif

    endif

return
		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         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) +'"')