From 0904b9b12134772a4ecaf3e4662c6bccaa5d7d49 Mon Sep 17 00:00:00 2001 From: Jose Alberto Guerra Ugalde Date: Thu, 6 Feb 2025 22:24:11 -0600 Subject: [PATCH] =?UTF-8?q?-=20VERSION=205.02.05=20-=20Se=20agreg=C3=B3=20?= =?UTF-8?q?que=20una=20vez=20impresa=20la=20venta,=20ya=20no=20se=20pueda?= =?UTF-8?q?=20modificar,=20y=20si=20se=20quiere=20modificar,=20es=20necesa?= =?UTF-8?q?rio=20pedir=20al=20supervisor=20una=20clave=20de=20autorizaci?= =?UTF-8?q?=C3=B3n.=20-=20Se=20agreg=C3=B3=20a=20"Cliente"=20un=20boton=20?= =?UTF-8?q?de=20"Enviar=20Ticket",=20que=20genera=20un=20PDF=20con=20el=20?= =?UTF-8?q?ticket=20y=20lo=20envia=20por=20WhatsApp=20o=20correo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- B4A/B4XMainPage.bas | 3 +- B4A/C_Cliente.bas | 381 +++++++++++-- B4A/C_Nota.bas | 142 ++--- B4A/C_Principal.bas | 2 + B4A/Files/cliente.bal | Bin 47652 -> 52093 bytes B4A/Files/guna-fondo.jpg | Bin 0 -> 54011 bytes B4A/Files/guna_192x192.jpg | Bin 0 -> 11096 bytes B4A/Guna Vistas V3.1.b4a | 69 +-- B4A/Guna Vistas V3.1.b4a.meta | 17 +- B4A/Starter.bas | 2 + B4A/Subs.bas | 31 +- B4A/cPDF.bas | 1004 +++++++++++++++++++++++++++++++++ C_Bitacora.bas | 2 +- 13 files changed, 1494 insertions(+), 159 deletions(-) create mode 100644 B4A/Files/guna-fondo.jpg create mode 100644 B4A/Files/guna_192x192.jpg create mode 100644 B4A/cPDF.bas diff --git a/B4A/B4XMainPage.bas b/B4A/B4XMainPage.bas index b88f5d1..635c6cb 100644 --- a/B4A/B4XMainPage.bas +++ b/B4A/B4XMainPage.bas @@ -179,7 +179,8 @@ Private Sub B4XPage_Created (Root1 As B4XView) skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS HIST_PRO3054(H_IDCLIENTE TEXT)") skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS HIST_PRO3055(H_IDCLIENTE TEXT)") skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS RUTA_SUPLENCIA(RS_RUTA TEXT)") - skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS CAT_GUNAPROD2 (CAT_GP_INICIATIVA TEXT, CAT_GP_TIPOPROD TEXT, CAT_GP_DEV TEXT, CAT_GP_ALMACEN NUMERIC, CAT_GP_ID TEXT, CAT_GP_NOMBRE TEXT, CAT_GP_IMP1 TEXT, CAT_GP_IMP2 TEXT, CAT_GP_PRECIO TEXT, CAT_GP_CLASIF TEXT, CAT_GP_STS TEXT, CAT_GP_TIPO TEXT, CAT_GP_SUBTIPO TEXT, CAT_GP_IMG BLOB, CAT_GP_CODPROMO TEXT)") + skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS RUTA_SUPLENCIA(RS_RUTA TEXT)") + skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS TICKET_IMPRESO (idCliente TEXT)") ' skmt.ExecNonQuery("CREATE TABLE IF NOT EXISTS CAT_VARIABLES (CAT_VA_DESCRIPCION TEXT, CAT_VA_VALOR TEXT)") Subs.agregaColumna("HIST_ENCUESTA", "HE_LAT", "TEXT") Subs.agregaColumna("HIST_ENCUESTA", "HE_FOTO", "BLOB") diff --git a/B4A/C_Cliente.bas b/B4A/C_Cliente.bas index de9fc91..e1f6049 100644 --- a/B4A/C_Cliente.bas +++ b/B4A/C_Cliente.bas @@ -431,6 +431,13 @@ Sub Class_Globals Private b_preventa As Button Dim bitacora As C_Bitacora + Dim p_transparenteTicketImpreso As Panel + Private et_codigoAutorizacion As EditText + Private b_codigoAutorizacion As Button + Private b_cancelarCodigoAutorizacion As Button + Private p_ticketImpreso As Panel + Private b_enviarTicket As Button + Dim archivoTicketPDF As String End Sub 'You can add more parameters here. @@ -473,6 +480,7 @@ Private Sub B4XPage_Created (Root1 As B4XView) End If c.Close s.Close + File.Copy(File.DirAssets,"guna-fondo.jpg",xui.DefaultFolder,"guna-fondo.jpg") TOMAR_FOTO = 0 btAdmin.Initialize("BlueTeeth") cmp20.Initialize("Printer") @@ -480,6 +488,9 @@ Private Sub B4XPage_Created (Root1 As B4XView) SV_ENCUESTA.Width = Root.Height p_pregunta1.Height = Root.Height p_pregunta1.Width = Root.Height + p_transparenteTicketImpreso.Left = 0 : p_transparenteTicketImpreso.top = 0 + p_transparenteTicketImpreso.Width = Root.Width : p_transparenteTicketImpreso.Height = Root.Height + Subs.centraPanel(p_ticketImpreso, p_transparenteTicketImpreso.Width) Tels.Visible = False gest.Visible = False l_version.Left = Root.Width - (l_version.Width + 10) @@ -498,14 +509,14 @@ Sub B4XPage_Appear indicePregunta = 0 If TOMAR_FOTO <> 0 Then Cuestionario Starter.idCliente = Subs.traeCliente - Log(Subs.traeCliente) +' Log(Subs.traeCliente) If Subs.traeCliente = "0" Then tipo_venta = "ABORDO" Log(1) Log("ABORDO") Else tipo_venta = Subs.traeTipoVentaDeBD - Log(2) +' Log(2) Log(Subs.traeTipoVentaDeBD) End If B4XPages.MainPage.tipo_venta = tipo_venta @@ -979,7 +990,7 @@ Sub GPS_LocationChanged (Location1 As Location) gest.Visible = False Tels.Visible = False ' p_transparenteInicioFin.Visible = False - Log(999) +' Log(999) ' b_Inicio_Fin_venta.Visible = False End If End If @@ -1230,8 +1241,45 @@ Sub JobDone(Job As HttpJob) End If Next End If + + If result1.Tag = "codigoAutorizacion" Then + If result1.Rows.Size > 0 Then + Log("Si hay codigo de autorizaion") + For Each records() As Object In result1.Rows + For Each k As String In result1.Columns.Keys + Log(k & ": " & records(result1.Columns.Get(k))) + Next + Next + Dim cmd As DBCommand + cmd.Initialize + cmd.Name = "delete_codigoAutorizacion" + cmd.Parameters = Array As Object(et_codigoAutorizacion.Text.Trim, Subs.traeRuta, Subs.traeAlmacen) + reqManager.ExecuteCommand(cmd , "deleteCodigoAutorizacion") + DateTime.DateFormat = "YYYY/MM/dd HH:mm:ss" + cmd.Initialize + cmd.Name = "update_codigoAutorizacion" +' Log($"(${DateTime.Date(DateTime.Now)}, ${Subs.traeUsuarioDeBD}, ${et_codigoAutorizacion.Text.Trim}, ${Subs.traeRuta}, ${Subs.traeAlmacen}"$) + cmd.Parameters = Array As Object(DateTime.Date(DateTime.Now), Subs.traeUsuarioDeBD, et_codigoAutorizacion.Text.Trim, Subs.traeRuta, Subs.traeAlmacen) + reqManager.ExecuteCommand(cmd , "updateCodigoAutorizacion") + Starter.skmt.ExecNonQuery("delete from ticket_impreso where idCliente in (select cuenta from cuentaa)") + p_transparenteTicketImpreso.Visible = False + et_codigoAutorizacion.Text = "" + teclado.HideKeyboard + ToastMessageShow("Listo, ya se puede modificar la venta.", True) + Else + ToastMessageShow("El codigo es incorrecto, por favor revise y vuelva a intentar!!", True) + End If + End If + If result1.Tag = "delete_codigoAutorizacion" Then + Log("Codigo Borrado!!") + End If + If result1.Tag = "updateCodigoAutorizacion" Then + Log("Codigo Actualizado") + End If End If + + ' If Job.JobName = "DBRequest" Then ' Dim result1 As DBResult = reqManager.HandleJob(Job) ' If result1.Tag = "CHECAENCUESTA" Then 'query tag @@ -1260,52 +1308,40 @@ Sub ListView1_ItemLongClick (Position As Int, Value As Object) End Sub Sub gest_Click - - c=B4XPages.MainPage.skmt.ExecQuery("select IFNULL(encuesta,0) AS encuesta from kmt_info2 where CAT_CL_CODIGO IN (SELECT CUENTA FROM CUENTAA)") - c.Position = 0 - If c.GetString("encuesta") = "0" Then - Dim Intent1 As Intent - Dim enviorutas As String = "guna://tienda360/config?clienteId="&la_cuenta.Text&"&almacen="&ALMACEN&"&ruta="&Subs.traeRuta - Log(enviorutas) - Intent1.Initialize(Intent1.ACTION_VIEW, enviorutas) - Try - Starter.encuesta = 1 - - Dim cmd As DBCommand - - - - - - - skmt.ExecNonQuery2("UPDATE kmt_info2 SET encuesta = (?) WHERE CAT_CL_CODIGO IN (SELECT CUENTA FROM CUENTAA)",Array As Object(1)) - StartActivity(Intent1) + If Not(Subs.revisaImpreso) Then + c=B4XPages.MainPage.skmt.ExecQuery("select IFNULL(encuesta,0) AS encuesta from kmt_info2 where CAT_CL_CODIGO IN (SELECT CUENTA FROM CUENTAA)") + c.Position = 0 + If c.GetString("encuesta") = "0" Then + Dim Intent1 As Intent + Dim enviorutas As String = "guna://tienda360/config?clienteId="&la_cuenta.Text&"&almacen="&ALMACEN&"&ruta="&Subs.traeRuta + Log(enviorutas) + Intent1.Initialize(Intent1.ACTION_VIEW, enviorutas) + Try + Starter.encuesta = 1 + Dim cmd As DBCommand + skmt.ExecNonQuery2("UPDATE kmt_info2 SET encuesta = (?) WHERE CAT_CL_CODIGO IN (SELECT CUENTA FROM CUENTAA)",Array As Object(1)) + StartActivity(Intent1) + compra + Catch + Starter.encuesta = 0 + Dim cmd As DBCommand + skmt.ExecNonQuery2("UPDATE kmt_info2 SET encuesta = (?) WHERE CAT_CL_CODIGO IN (SELECT CUENTA FROM CUENTAA)",Array As Object(2)) + ToastMessageShow("La aplicación Tienda 360 no está instalada o no puede manejar la URL.", True) + compra + End Try + cmd.Initialize + cmd.Name = "SELECT_TMP_DROP_ENCUESTA_GUNA" + cmd.Parameters = Array As Object(usuario, B4XPages.MainPage.principal.e_ruta.text, ALMACEN, "ENCUESTA") + B4XPages.MainPage.reqManager.ExecuteQuery(cmd , 0, "CHECAENCUESTA") + Else compra - Catch - - - Starter.encuesta = 0 - Dim cmd As DBCommand - - - - skmt.ExecNonQuery2("UPDATE kmt_info2 SET encuesta = (?) WHERE CAT_CL_CODIGO IN (SELECT CUENTA FROM CUENTAA)",Array As Object(2)) - ToastMessageShow("La aplicación Tienda 360 no está instalada o no puede manejar la URL.", True) - compra - End Try - cmd.Initialize - cmd.Name = "SELECT_TMP_DROP_ENCUESTA_GUNA" - cmd.Parameters = Array As Object(usuario, B4XPages.MainPage.principal.e_ruta.text, ALMACEN, "ENCUESTA") - B4XPages.MainPage.reqManager.ExecuteQuery(cmd , 0, "CHECAENCUESTA") - + End If Else - compra + p_transparenteTicketImpreso.Visible = True End If - End Sub Sub compra - ' If ALMACEN = "4" Or ALMACEN = "36" Then ' Log(Subs.traeAlmacen) @@ -1320,7 +1356,6 @@ Sub compra ' IZTAPALAPA- 43-- ' CEDA- 54-- ' PACHUCA- 15-- - Private rutasEncuesta As List rutasEncuesta.Initialize2(Array As Int(702, 703, 707, 718, 730, 732, 733, 734)) Private alamcenesEncuesta As List @@ -2076,7 +2111,7 @@ Sub Guardar_Click 'AQUI CAMBIAR Private s3 As Cursor=B4XPages.MainPage.skmt.ExecQuery2("select * FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) and PE_RECALCULO <> ? AND PE_RECALCULO <> ? AND PE_RECALCULO <> ?",Array As String("","null",Null)) - LogColor(s3.RowCount,Colors.Yellow) +' LogColor(s3.RowCount,Colors.Yellow) If s3.RowCount > 0 Then Private s As Cursor=B4XPages.MainPage.skmt.ExecQuery2("select iFNULL(sum(pe_costo_tot),0) as TOTAL_CLIE, SUM(PE_CANT) AS CANT_CLIE FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) and PE_RECALCULO = ? AND PE_RECALCULO = ? AND PE_RECALCULO = ?",Array As String("","null",Null)) s.Position = 0 @@ -2096,6 +2131,8 @@ Sub Guardar_Click B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)") B4XPages.MainPage.skmt.ExecNonQuery2("insert into pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT) VALUES (?,?,?,?,?,?,?)", Array As Object(clie_id, sDate & sTime, usuario, c.GetString("CANT_CLIE"),NumberFormat2(suma,0,2,2,False), B4XPages.MainPage.lon_gps, B4XPages.MainPage.lat_gps)) B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info2 set gestion = 2 where CAT_CL_CODIGO In (select cuenta from cuentaa)") + B4XPages.MainPage.skmt.ExecNonQuery("delete from TICKET_IMPRESO where idCliente In (select cuenta from cuentaa)") + B4XPages.MainPage.skmt.ExecNonQuery($"insert into TICKET_IMPRESO (idCliente) values ('${Subs.traeCliente}')"$) End If c.Close DateTime.TimeFormat = "HHmmss" @@ -4885,4 +4922,258 @@ End Sub Private Sub b_preventa_Click +End Sub + +Private Sub p_transparenteTicketImpreso_Click + +End Sub + +Private Sub b_codigoAutorizacion_Click + Dim cmd As DBCommand + cmd.Initialize + cmd.Name = "select_codigoAutorizacion" + cmd.Parameters = Array As Object(et_codigoAutorizacion.Text.Trim, Subs.traeRuta, Subs.traeAlmacen) + reqManager.ExecuteQuery(cmd , 0, "codigoAutorizacion") +' p_transparenteTicketImpreso.Visible = False +End Sub + +Private Sub b_cancelarCodigoAutorizacion_Click + p_transparenteTicketImpreso.Visible = False +End Sub + +Private Sub PDFGENERAR + ESPACIO = 0 + DateTime.DateFormat = "MM/dd/yyyy" + DateTime.TimeFormat = "HH:mm:ss" + sDate=DateTime.Date(DateTime.Now) + sTime=DateTime.Time(DateTime.Now) + Dim PDF As cPDF + 'initialize with mm unit + PDF.Initialize("mm") + 'set properties + PDF.sProperty(PDF.PropertyAuthor,"Keymonsoft"). _ + sProperty(PDF.PropertyTitle,"Ticket"). _ + sProperty(PDF.PropertyKeywords,"B4X,PDF,Cross platform") + 'add a page + + Dim s56 As Cursor=skmt.ExecQuery2("select PE_PRONOMBRE, PE_CANT, length(pe_cant) as L_CANT, PE_COSTOU, length(PE_COSTOU) as L_COSTOU,PE_CANT * PE_COSTOU AS PE_COSTO_TOT, length(PE_CANT * PE_COSTOU) as L_COSTO_TOT,PE_PROID, PE_CEDIS FROM PEDIDO WHERE PE_FOLIO = ? AND LENGTH(PE_CEDIS) < 4 AND PE_CLIENTE IN (Select CUENTA from cuentaa) order by PE_PROID", Array As String("PREVENTA")) + Dim s57 As Cursor = skmt.ExecQuery2("select PE_PRONOMBRE, PE_CANT, length(pe_cant) as L_CANT, PE_COSTOU, length(PE_COSTOU) as L_COSTOU,PE_CANT * PE_COSTOU AS PE_COSTO_TOT, length(PE_CANT * PE_COSTOU) as L_COSTO_TOT,PE_PROID, PE_CEDIS FROM PEDIDO WHERE PE_FOLIO = ? AND LENGTH(PE_CEDIS) > 3 AND PE_CLIENTE IN (Select CUENTA from cuentaa) order by PE_CEDIS, PE_COSTOU", Array As String("PREVENTA")) + + Dim pagina As Double = ((18 + (s56.RowCount*2) + (s57.RowCount*2)) * (6)) + 18 +' Dim pagina As Double = ((18 + s56.RowCount + s57.RowCount +2) * (6)) + 18 + Dim multiplicador As Int = 0 + PDF.pageAdd(-300,pagina) +' pdf.pageAdd(-350,-1900) + + PDF.sFont(PDF.fontHelvetica,0,10,PDF.colorBlack) + + PDF.outImage(xui.DefaultFolder,"guna-fondo.jpg",1,pagina-45,45,0) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"GUNA") + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,sDate& " " & sTime) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"Vendedor:" & Subs.traeUsuarioDeBD) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"Tienda: " & La_nombre.Text) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"ID.Cliente: " & la_cuenta.Text) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"Calle: " & la_Calle.Text) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"Colonia: " & la_col.Text) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6," ") + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6," ") + c = skmt.ExecQuery2("SELECT * FROM PEDIDO WHERE PE_FOLIO = ?",Array As String("PREVENTA")) + If c.RowCount > 0 Then + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"------------------------------------PREVENTA-----------------------------------------") + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"Cant. Precio Importe") + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"-----------------------------------------------------------------------------------------") + s=skmt.ExecQuery2("select PE_PRONOMBRE, PE_CANT, length(pe_cant) as L_CANT, PE_COSTOU, length(PE_COSTOU) as L_COSTOU,PE_CANT * PE_COSTOU AS PE_COSTO_TOT, length(PE_CANT * PE_COSTOU) as L_COSTO_TOT,PE_PROID, PE_CEDIS FROM PEDIDO WHERE PE_FOLIO = ? AND LENGTH(PE_CEDIS) < 4 AND PE_CLIENTE IN (Select CUENTA from cuentaa) order by PE_PROID", Array As String("PREVENTA")) + If S.RowCount>0 Then + For i=0 To S.RowCount -1 + S.Position=i + If s.GetString("PE_CEDIS") = s.GetString("PE_PROID") Then + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,s.GetString("PE_PRONOMBRE") ) + Else + PDF.sFont(PDF.fontHelvetica,0,7,PDF.colorBlack) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,s.GetString("PE_PRONOMBRE")) +' LogColor(s.GetLong("L_CANT"),Colors.Magenta) +' LogColor(s.GetLong("L_COSTOU"),Colors.Magenta) +' LogColor(s.GetLong("L_COSTO_TOT"),Colors.Magenta) + TAMANO = s.GetLong("L_CANT") + s.GetLong("L_COSTOU") + s.GetLong("L_COSTO_TOT") + ESPACIO = 92 + BLANCO = " " + ESPACIO = ESPACIO - TAMANO + ESPACIO = ESPACIO / 2 + For E=0 To ESPACIO -1 + BLANCO = " " & BLANCO + Next + PDF.sFont(PDF.fontHelvetica,0,10,PDF.colorBlack) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6, s.GETSTRING("PE_CANT") & BLANCO & s.GETSTRING("PE_COSTOU") & BLANCO & s.GETSTRING("PE_COSTO_TOT")) +' pdf.outtext(1,108-9*6,s.GETSTRING("PE_COSTOU")) + +' pdf.outtext(1,108-9*6,s.GETSTRING("PE_COSTO_TOT") ) + End If + Next + End If + s.Close + PDF.outtext(1,108-9*6," " ) + s=skmt.ExecQuery2("select PE_PRONOMBRE, PE_CANT, length(pe_cant) as L_CANT, PE_COSTOU, length(PE_COSTOU) as L_COSTOU,PE_CANT * PE_COSTOU AS PE_COSTO_TOT, length(PE_CANT * PE_COSTOU) as L_COSTO_TOT,PE_PROID, PE_CEDIS FROM PEDIDO WHERE PE_FOLIO = ? AND LENGTH(PE_CEDIS) > 3 AND PE_CLIENTE IN (Select CUENTA from cuentaa) order by PE_CEDIS, PE_COSTOU", Array As String("PREVENTA")) + If S.RowCount>0 Then + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"--------------------------PROMOS PREVENTA-------------------------------------") + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"Cant. Precio Importe") + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"-----------------------------------------------------------------------------------------") + For i=0 To S.RowCount -1 + S.Position=i + If s.GetString("PE_CEDIS") = s.GetString("PE_PROID") Then + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,s.GetString("PE_PRONOMBRE") ) + Else + PDF.sFont(PDF.fontHelvetica,0,7,PDF.colorBlack) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,s.GetString("PE_PRONOMBRE")) + LogColor(s.GetLong("L_CANT"),Colors.Magenta) + LogColor(s.GetLong("L_COSTOU"),Colors.Magenta) + LogColor(s.GetLong("L_COSTO_TOT"),Colors.Magenta) + TAMANO = s.GetLong("L_CANT") + s.GetLong("L_COSTOU") + s.GetLong("L_COSTO_TOT") + ESPACIO = 92 + BLANCO = " " + ESPACIO = ESPACIO - TAMANO + ESPACIO = ESPACIO / 2 + For E=0 To ESPACIO -1 + BLANCO = " " & BLANCO + Next + PDF.sFont(PDF.fontHelvetica,0,10,PDF.colorBlack) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6, s.GETSTRING("PE_CANT") & BLANCO & s.GETSTRING("PE_COSTOU") & BLANCO & s.GETSTRING("PE_COSTO_TOT")) + End If + Next + End If + s.Close +' multiplicador = multiplicador +1 +' pdf.outtext(1,pagina-multiplicador*6," " ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6," " ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"-----------------------------------------------------------------------------------------") + s=skmt.ExecQuery2("select SUM(PE_COSTO_TOT) AS TOTAL FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa) AND PE_FOLIO = ?", Array As String("PREVENTA")) + s.Position =0 + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"Total preventa: $" & s.GetString("TOTAL") ) + s.Close + c= skmt.ExecQuery2("select sum(PE_CANT) as PC_NOART from PEDIDO where PE_CLIENTE in (Select CUENTA from cuentaa) AND PE_PROID NOT IN (SELECT CAT_PA_ID FROM PROMOS_COMP ) AND PE_FOLIO = ?", Array As String("PREVENTA")) + C.Position=0 + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"Total articulos preventa: " & c.GetString("PC_NOART") ) + c.Close + End If +' multiplicador = multiplicador +1 +' pdf.outtext(1,pagina-multiplicador*6," " ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"-----------------------------------------------------------------------------------------" ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"--------------------------ESTE TICKET NO ES UN ---------------------------" ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"-------------------COMPROBANTE FISCAL, SOLO ES--------------------" ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"---------------------------------INFORMATIVO-----------------------------------" ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"-----------------------------------------------------------------------------------------" ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6," " ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6," " ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6," " ) + multiplicador = multiplicador +1 + PDF.outtext(1,pagina-multiplicador*6,"-----------------------------------------------------------------------------------------" ) +' 'all combinations of font normal, bold,italic,underline and strikethrough +' For i=0 To 15 +' 'select a font +' pdf.sFont(pdf.fontHelvetica,s,30,pdf.colorBlack) +' 'draw a text at position 20 (from left) and 277 (from bottom) +' pdf.outtext(20,277-i*15,"Hello world!") +' Next + DateTime.DateFormat = "ddmmyyyy" + DateTime.TimeFormat = "HHmmss" + sDate=DateTime.Date(DateTime.Now) + sTime=DateTime.Time(DateTime.Now) + archivoTicketPDF = sDate&sTime&".pdf" + 'save to file with compression if data compressed are smaller + savePDF(PDF, archivoTicketPDF, PDF.CompressAlways) + 'open with default viewer +' openPDF(sDate&sTime&".pdf") +End Sub + +private Sub savePDF(apdf As cPDF,afile As String,acompress As Int) + Dim folder As String + #if B4J + folder=xui.DefaultFolder + #End If + #if B4A + folder = Starter.fFileProvider.SharedFolder + #End If + #if B4I + '...... + #End If +' Log("aaa:" & folder) +' Log("bbb:" & B4XPages.MainPage.Provider.SharedFolder) + apdf.saveToFile(folder, afile, acompress) +End Sub + +private Sub openPDF(afile As String) + #if B4J + fx.ShowExternalDocument(File.GetUri(xui.DefaultFolder,afile)) + #end if + #if B4A + Dim in As Intent + in.Initialize(in.ACTION_VIEW, "") + Starter.ffileProvider.SetFileUriAsIntentData(in, afile) + in.SetComponent("android/com.android.internal.app.ResolverActivity") + in.SetType("application/pdf") + StartActivity(in) + #end if + #if B4I + '...... + #End If +End Sub + +Private Sub b_enviarTicket_Click + ProgressDialogShow("Enviando ticket, un momento por favor.") + Log("Progress 1") + PDFGENERAR + enviaTicket + Sleep(1500) + Guardar_Click + ProgressDialogHide + Log("Progress 2") +End Sub + +Private Sub b_enviarTicket_LongClick +' deleteFolder(Starter.fFileProvider.SharedFolder) +End Sub + +Sub enviaTicket + 'copy the shared file to the shared folder +' Log("xxxxxx:"&Starter.fFileProvider) + Sleep(1000) + Dim email As Email + email.To.Add("cheveguerra@gmail.com") + email.Subject = "subject" + email.Attachments.Add(Starter.fFileProvider.GetFileUri(archivoTicketPDF)) + Dim in As Intent = email.GetIntent + in.Flags = 1 'FLAG_GRANT_READ_URI_PERMISSION + StartActivity(in) End Sub \ No newline at end of file diff --git a/B4A/C_Nota.bas b/B4A/C_Nota.bas index 7e358b6..f1942f8 100644 --- a/B4A/C_Nota.bas +++ b/B4A/C_Nota.bas @@ -159,101 +159,113 @@ Private Sub B4XPage_CloseRequest As ResumableSub End Sub Sub borra_Click - If folio <> "" Then - result = Msgbox2("Seguro que desa borrar el pedido?","Cancelar pedido", "Si", "", "No",LoadBitmap(File.DirAssets,"alert2.png")) 'ignore - If result = DialogResponse.POSITIVE Then - c=B4XPages.MainPage.skmt.ExecQuery("select PE_PROID,PE_CANT FROM PEDIDO where pe_cliente in (Select CUENTA from cuentaa) ") - If c.RowCount>0 Then - For i=0 To c.RowCount -1 - c.Position=i - B4XPages.MainPage.skmt.ExecNonQuery2($"update ${Subs.traeTablaProds(tipo_venta)} set cat_gp_almacen = cat_gp_almacen + ? where cat_gp_id = ?"$, Array As Object(c.GetString("PE_CANT"),c.GetString("PE_PROID"))) - B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO INVENT_X_ENVIAR (ALMACEN , PROID , CANTIDAD ) VALUES(?,?,?) ", Array As Object (almacen,c.GetString("PE_PROID"),c.GetString("PE_CANT")* -1)) - Next + If Not(Subs.revisaImpreso) Then + If folio <> "" Then + result = Msgbox2("Seguro que desa borrar el pedido?","Cancelar pedido", "Si", "", "No",LoadBitmap(File.DirAssets,"alert2.png")) 'ignore + If result = DialogResponse.POSITIVE Then + c=B4XPages.MainPage.skmt.ExecQuery("select PE_PROID,PE_CANT FROM PEDIDO where pe_cliente in (Select CUENTA from cuentaa) ") + If c.RowCount>0 Then + For i=0 To c.RowCount -1 + c.Position=i + B4XPages.MainPage.skmt.ExecNonQuery2($"update ${Subs.traeTablaProds(tipo_venta)} set cat_gp_almacen = cat_gp_almacen + ? where cat_gp_id = ?"$, Array As Object(c.GetString("PE_CANT"),c.GetString("PE_PROID"))) + B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO INVENT_X_ENVIAR (ALMACEN , PROID , CANTIDAD ) VALUES(?,?,?) ", Array As Object (almacen,c.GetString("PE_PROID"),c.GetString("PE_CANT")* -1)) + Next + End If + B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where pc_cliente in (Select CUENTA from cuentaa)") + B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido where pe_cliente in (Select CUENTA from cuentaa)") + B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info2 set gestion = 0 where CAT_CL_CODIGO In (select cuenta from cuentaa)") + B4XPage_Appear End If - B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where pc_cliente in (Select CUENTA from cuentaa)") - B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido where pe_cliente in (Select CUENTA from cuentaa)") - B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info2 set gestion = 0 where CAT_CL_CODIGO In (select cuenta from cuentaa)") - B4XPage_Appear + Else + Msgbox("CLIENTE YA SE TRANSMITIO, FAVOR DE LLAMAR A SOPORTE PARA ASISTENCIA","AVISO") 'ignore End If Else - Msgbox("CLIENTE YA SE TRANSMITIO, FAVOR DE LLAMAR A SOPORTE PARA ASISTENCIA","AVISO") 'ignore + ToastMessageShow("La venta ya esta impresa, no se puede modificar!!", True) + B4XPages.MainPage.cliente.p_transparenteTicketImpreso.Visible = True + B4XPages.ShowPage("cliente") End If End Sub Sub ListView1_ItemLongClick (Position As Int, Value As Object) - result = Msgbox2("Seguro que desea borrar este articulo?","Borrar Articulo", "Si", "", "No",LoadBitmap(File.DirAssets,"alert2.png")) 'ignore - If result = DialogResponse.POSITIVE Then - Private X() As String = Regex.Split(" ", Value) - Log(X) - Log(X.Length) - Private nom As String = "" - For i = 0 To X.Length -1 + If Not(Subs.revisaImpreso) Then + result = Msgbox2("Seguro que desea borrar este articulo?","Borrar Articulo", "Si", "", "No",LoadBitmap(File.DirAssets,"alert2.png")) 'ignore + If result = DialogResponse.POSITIVE Then + Private X() As String = Regex.Split(" ", Value) + Log(X) + Log(X.Length) + Private nom As String = "" + For i = 0 To X.Length -1 ' Log(X(i)) - If X(i).Contains(CRLF) Then + If X(i).Contains(CRLF) Then ' Log("Retorno") - End If - If Not(X(i).Contains(CRLF)) Then - nom = nom & " " & X(i) - Else - Exit - End If + End If + If Not(X(i).Contains(CRLF)) Then + nom = nom & " " & X(i) + Else + Exit + End If ' Log(nom) - Next + Next ' Log(nom) - nom = nom.Trim - Private cedis As String = X(X.Length-1) - c=B4XPages.MainPage.skmt.ExecQuery($"select PE_PROID,PE_CANT, PE_FOLIO, PE_CEDIS, PE_PRONOMBRE FROM PEDIDO where pe_pronombre = '${nom}' AND PE_CEDIS = '${cedis}' and pe_cliente in (Select CUENTA from cuentaa)"$) - Log($"select PE_PROID,PE_CANT, PE_FOLIO, PE_CEDIS FROM PEDIDO where pe_pronombre = '${nom}' AND PE_CEDIS = '${cedis}' and pe_cliente in (Select CUENTA from cuentaa)"$) - Log(c.RowCount) - c.Position=0 + nom = nom.Trim + Private cedis As String = X(X.Length-1) + c=B4XPages.MainPage.skmt.ExecQuery($"select PE_PROID,PE_CANT, PE_FOLIO, PE_CEDIS, PE_PRONOMBRE FROM PEDIDO where pe_pronombre = '${nom}' AND PE_CEDIS = '${cedis}' and pe_cliente in (Select CUENTA from cuentaa)"$) + Log($"select PE_PROID,PE_CANT, PE_FOLIO, PE_CEDIS FROM PEDIDO where pe_pronombre = '${nom}' AND PE_CEDIS = '${cedis}' and pe_cliente in (Select CUENTA from cuentaa)"$) + Log(c.RowCount) + c.Position=0 ' If c.RowCount > 0 Then ' B4XPages.MainPage.skmt.ExecNonQuery2("update cat_gunaprod set cat_gp_almacen = cat_gp_almacen + ? where cat_gp_id = ?", Array As Object(c.GetString("PE_CANT"),c.GetString("PE_PROID"))) - B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO INVENT_X_ENVIAR (ALMACEN , PROID , CANTIDAD) VALUES(?,?,?) ", Array As Object (almacen,c.GetString("PE_PROID"),c.GetString("PE_CANT")* -1)) + B4XPages.MainPage.skmt.ExecNonQuery2("INSERT INTO INVENT_X_ENVIAR (ALMACEN , PROID , CANTIDAD) VALUES(?,?,?) ", Array As Object (almacen,c.GetString("PE_PROID"),c.GetString("PE_CANT")* -1)) ' c2=B4XPages.MainPage.skmt.ExecQuery($"select count(*) AS CUANTOS from CAT_GUNAPROD where CAT_GP_ID in (select pe_cedis from pedido where pe_pronombre = '${nom}' and pe_cliente in (Select CUENTA from cuentaa)) and CAT_GP_CLASIF = 'PROMOS' AND CAT_GP_TIPO = 'PROMOS' AND CAT_GP_SUBTIPO = 'PROMOS'"$)'Con esto revisamos si el nombre es de una promo ' c2=B4XPages.MainPage.skmt.ExecQuery($"select ISNUMERIC(pe_cedis) AS noEsPromo from pedido where pe_pronombre = '${nom}' and pe_cliente in (Select CUENTA from cuentaa) and pe_cedis = '${cedis}'"$)'Con esto revisamos si el nombre es de una promo ' Log($"select count(*) AS CUANTOS from CAT_GUNAPROD where CAT_GP_ID in (select pe_cedis from pedido where pe_pronombre = '${nom}' and pe_cliente in (Select CUENTA from cuentaa)) and CAT_GP_CLASIF = 'PROMOS' AND CAT_GP_TIPO = 'PROMOS' AND CAT_GP_SUBTIPO = 'PROMOS'"$) ' Log($"select ISNUMERIC(pe_cedis) AS noEsPromo from pedido where pe_pronombre = '${nom}' and pe_cliente in (Select CUENTA from cuentaa) and pe_cedis = '${cedis}'"$) ' c2.Position=0 ' Log("Algo "&c2.GetString("noEsPromo")) - If Not(IsNumber(cedis)) Then + If Not(IsNumber(cedis)) Then ' j3 = B4XPages.MainPage.skmt.ExecQuery2("SELECT PE_CEDIS, PE_CANT,PE_PROID, PE_PRONOMBRE FROM PEDIDO WHERE PE_CEDIS IN (SELECT PE_CEDIS FROM PEDIDO WHERE PE_PRONOMBRE = ?)",Array As String(nom)) ' Log(j3.RowCount) ' If j3.RowCount > 0 Then Log("Soy promo") ' For j = 0 To c.RowCount -1 ' Log("aqui tronare?") -'' c.Position = j - B4XPages.MainPage.skmt.ExecNonQuery($"update ${Subs.traeTablaProds(tipo_venta)} set cat_gp_almacen = cat_gp_almacen + ${c.GetString("PE_CANT")} where cat_gp_id = '${c.GetString("PE_PROID")}'"$) - B4XPages.MainPage.skmt.ExecNonQuery2("delete from pedido where pe_cedis= ? and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = ?", Array As Object(cedis, c.GetString("PE_FOLIO"))) + '' c.Position = j + B4XPages.MainPage.skmt.ExecNonQuery($"update ${Subs.traeTablaProds(tipo_venta)} set cat_gp_almacen = cat_gp_almacen + ${c.GetString("PE_CANT")} where cat_gp_id = '${c.GetString("PE_PROID")}'"$) + B4XPages.MainPage.skmt.ExecNonQuery2("delete from pedido where pe_cedis= ? and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = ?", Array As Object(cedis, c.GetString("PE_FOLIO"))) ' Next ' End If ' j3.Close - Else - B4XPages.MainPage.skmt.ExecNonQuery($"update ${Subs.traeTablaProds(tipo_venta)} set cat_gp_almacen = cat_gp_almacen + ${c.GetString("PE_CANT")} where cat_gp_id = '${c.Getstring("PE_PROID")}'"$) - B4XPages.MainPage.skmt.ExecNonQuery2("delete from pedido where pe_pronombre = ? and pe_cedis = ? and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = ?", Array As Object(nom, cedis, c.GetString("PE_FOLIO"))) - End If - c.Close + Else + B4XPages.MainPage.skmt.ExecNonQuery($"update ${Subs.traeTablaProds(tipo_venta)} set cat_gp_almacen = cat_gp_almacen + ${c.GetString("PE_CANT")} where cat_gp_id = '${c.Getstring("PE_PROID")}'"$) + B4XPages.MainPage.skmt.ExecNonQuery2("delete from pedido where pe_pronombre = ? and pe_cedis = ? and pe_cliente in (Select CUENTA from cuentaa) AND PE_FOLIO = ?", Array As Object(nom, cedis, c.GetString("PE_FOLIO"))) + End If + c.Close ' c2.Close - DateTime.DateFormat = "MM/dd/yyyy" - sDate=DateTime.Date(DateTime.Now) - sTime=DateTime.Time(DateTime.Now) - c=B4XPages.MainPage.skmt.ExecQuery("Select CUENTA from cuentaa") - c.Position=0 - clie_id = c.GetString("CUENTA") - c=B4XPages.MainPage.skmt.ExecQuery("select USUARIO from usuarioa") - c.Position=0 - usuario = c.GetString("USUARIO") - c=B4XPages.MainPage.skmt.ExecQuery("select sum(pe_costo_tot) as TOTAL_CLIE, SUM(PE_CANT) AS CANT_CLIE, count(*) as CUANTOS FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa)") - c.Position=0 - If c.GetString("CUANTOS") > 0 Then - B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)") - B4XPages.MainPage.skmt.ExecNonQuery2("insert into pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT) VALUES (?,?,?,?,?,?,?)", Array As Object(clie_id, sDate & sTime, usuario, c.GetString("CANT_CLIE"),c.GetString("TOTAL_CLIE"), B4XPages.MainPage.lon_gps, B4XPages.MainPage.lat_gps)) - B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info2 set gestion = 2 where CAT_CL_CODIGO In (select cuenta from cuentaa)") - Else - B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)") - B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info2 set gestion = 0 where CAT_CL_CODIGO In (select cuenta from cuentaa)") + DateTime.DateFormat = "MM/dd/yyyy" + sDate=DateTime.Date(DateTime.Now) + sTime=DateTime.Time(DateTime.Now) + c=B4XPages.MainPage.skmt.ExecQuery("Select CUENTA from cuentaa") + c.Position=0 + clie_id = c.GetString("CUENTA") + c=B4XPages.MainPage.skmt.ExecQuery("select USUARIO from usuarioa") + c.Position=0 + usuario = c.GetString("USUARIO") + c=B4XPages.MainPage.skmt.ExecQuery("select sum(pe_costo_tot) as TOTAL_CLIE, SUM(PE_CANT) AS CANT_CLIE, count(*) as CUANTOS FROM PEDIDO WHERE PE_CLIENTE IN (Select CUENTA from cuentaa)") + c.Position=0 + If c.GetString("CUANTOS") > 0 Then + B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)") + B4XPages.MainPage.skmt.ExecNonQuery2("insert into pedido_cliente(PC_CLIENTE, PC_FECHA, PC_USER, PC_NOART, PC_MONTO,PC_LON, PC_LAT) VALUES (?,?,?,?,?,?,?)", Array As Object(clie_id, sDate & sTime, usuario, c.GetString("CANT_CLIE"),c.GetString("TOTAL_CLIE"), B4XPages.MainPage.lon_gps, B4XPages.MainPage.lat_gps)) + B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info2 set gestion = 2 where CAT_CL_CODIGO In (select cuenta from cuentaa)") + Else + B4XPages.MainPage.skmt.ExecNonQuery("delete from pedido_cliente where PC_CLIENTE In (select cuenta from cuentaa)") + B4XPages.MainPage.skmt.ExecNonQuery("UPDATE kmt_info2 set gestion = 0 where CAT_CL_CODIGO In (select cuenta from cuentaa)") + End If + B4XPage_Appear End If - B4XPage_Appear + Else + B4XPages.MainPage.cliente.p_transparenteTicketImpreso.Visible = True + B4XPages.ShowPage("cliente") + ToastMessageShow("La venta ya esta impresa, no se puede modificar!!", True) End If End Sub diff --git a/B4A/C_Principal.bas b/B4A/C_Principal.bas index f05bf12..24a5d55 100644 --- a/B4A/C_Principal.bas +++ b/B4A/C_Principal.bas @@ -2231,6 +2231,7 @@ Sub t2_tick B4XPages.MainPage.skmt.ExecNonQuery("DELETE FROM ENCUESTA_MODULO5") B4XPages.MainPage.skmt.ExecNonQuery("DELETE FROM BITACORAGPS") B4XPages.MainPage.skmt.ExecNonQuery("DELETE FROM RUTA_SUPLENCIA") + B4XPages.MainPage.skmt.ExecNonQuery("DELETE FROM TICKET_IMPRESO") B4XPages.MainPage.skmt.ExecNonQuery2("DELETE FROM CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?",Array As String("CARGA_DIA")) B4XPages.MainPage.skmt.ExecNonQuery2("DELETE FROM CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?",Array As String("pasword")) B4XPages.MainPage.skmt.ExecNonQuery2("DELETE FROM CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?",Array As String("LATITUD")) @@ -2239,6 +2240,7 @@ Sub t2_tick ' B4XPages.MainPage.skmt.ExecNonQuery2("DELETE FROM CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?",Array As String("FORZAR_ACTUALIZACION")) ' B4XPages.MainPage.skmt.ExecNonQuery2("DELETE FROM CAT_VARIABLES WHERE CAT_VA_DESCRIPCION = ?",Array As String("VERSION_NUEVA")) B4XPages.MainPage.skmt.ExecNonQuery2("UPDATE GPS SET HABILITADO = (?)",Array As Object(0)) + Subs.deleteFolder(Starter.fFileProvider.SharedFolder) ' B4XPage_Appear E_RUTA2.Visible = False E_RUTA2.Text = "" diff --git a/B4A/Files/cliente.bal b/B4A/Files/cliente.bal index a66cfc04249fb593cfd287d1eed195d363bd551d..16836813fa71ba6c5a3962a7228acee9274a8a37 100644 GIT binary patch delta 2823 zcmaKuYitx%6vua_583IvTWjAtEG^x(+jj-}g2J}Y#Vt@QzKYiAcG^xKv)kE+fGt}B z2^ulb9z%>otj0t?nUIMwCZ=GB3G%@ZBz`c#$QS)&G|@y;HTB%t&i3@>hqL>;_kZvI z+&gn~?tJ(M|L@g=v?Png@@<;MBH;hIxwKJt5yIerPf~sIgrvFsL&}JMe>mjVlrxe~ z@vD!;^wIGFIVXl2hRn_OWv3gOtVR?`>r;H=a_Ghbnah71yXDY;Z^InDnHRV`<~Xs5 z3hsn5Z>}Ns$ZAj;lVhHq$$%yY{fVe}2YQd=K5%+S33aKyupA6YES=F2p75`kp`S~* z&)G6i4&ZpUycH|>C%w>K80*(0H5iaISq-gC2Wrv-PSxGX8C*00hqCkq7$&pnCbP#` zj8TGN#}F~LV>k%!AY4kg4B7PAiCm81#Hd*1sHJkXVW}eQLN+H?6Rsg#OUBnB*JCtb zG!kwi{3PLB21jEPb`xO_;b!C(j8=>`!tI3j65dC+gYbUB2MD_{e>_1a;V!}l2_GWd zP1r;DFyW^NdkOcfaFp%r2oa7FK1R5g@NvRV6Ye8?g77nhpC$a9#S)G0{&^z2K)9dq zNy0A@eu?k^;g<}Sm0KT8%M z!W3bRaFB2aIgAm(c!lsO!lwzJA^a-xG{y`@{#pDnPdHnQ`6OobKZUnBu0g+&I+hvb zQEA+@u_m&D)n(L3F;<=mu>&j8R+VRyg0*FdW7%S+VsxdrZCyd%#lc=lj9{&k#M6?9 z#q;+2qGFU+>=0GI7?j08SRRtaNi5#Oiciv9Vo(t^c`B^P8tI;pTw=hliNjI^e|`SR za8y;MupZ0UP(^t{42A=;7EyvIV||rG|6oW~WsOO`+d8{(M9d?_Z=Kt^TEq6a>CLg# zosowV+%dNk8|>I5yyZ4rL#$l?-|e@JnXcT8`cl!QB%$Q*V|A$gv=M%A-Ah?8^}d+?%j*IZL|S3C+p6!b`8q#W z#V-J3{ok4EVJm?8<}$styQC@Ck-T0%yR@ReHQm}izhD(w@OT?Ly$Ww$bMiYl$UN8& z#jkzEmvZpvgQHw2^nTvNmBGTt9$Pj(5+h%HRusOhc0$K7f%^-xBAtnVBjDk*gWt&k zH&ey_ZUjoeJChAJyK>;0PpshZwBarq;HI3-36Qn7h%aYj9r^4thP_*BIqrsCjj8P1 zSkdB<#|eS!=`ho7wXynWEZBjgL~L*___eD5j(Rd+vRC4rY}rka{#jwBbBzyX>Ah^{ zD>!)QYk`I8bm$LR1(wvXTV(s6uN&tp(Lkz#AA78ZN#%Nz?PYepYSqM}WefMw#8`?7 z`-kihsCV!#=8^;NO`gnjt#?RK`$2po84BFRwna1lCDX%Ycq|^Nfk0b3U%k4W>h(Ts zJ2ml@*w~vf-p)s+=l5(+u++qkVLz8M-?L|1o+SlUE(bc^*@wTq&h30HOHl>>ktd&w*vGk$%DpXM_iU>Zy2dLCiS6k4wwpANLvU=iz z2b{!kFa{I7cp#Cv=*1&vVmuM9UPw$d@hH}Rfo*>tzUgN=v+3++x~s3u?|z%?R>s(5 zEn|W{i_`X`t%fifOC-l*+VrPE<=`4uuT6r>FJ`w~HP@?vs|s%0cZ0JHdOvO=L4=pniN z+zCDjJ_YWg->>W_3O)_)2A=_+1^0l@fqTK{!F?On%a5WTCN6+4f-iwDg9pHa;49#( z;A`OPjOmrTAA*Tt@D1=yvT=xRkw>T)bsHQ9kAf56I~CLO*D3?X?t<@uli(D13_MQ0 zPd%X0;0!nmepq(-l$S5aQF*FBJ)(?L`j~9o@e|cmJHxq4E!)TH)DGvARWz=aO67kn z?@)8@A{XDQ$hfU^J^Pi z;p^`e9+jn!UNzL~Xxr9IFOUBxC;q&g_o#WjJtBYRHuJDtnhMF00U?8V>qZt6Xa4{k C1hf+X diff --git a/B4A/Files/guna-fondo.jpg b/B4A/Files/guna-fondo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d7c1cd65e15ef150640283caaa0b8f59f8f7a553 GIT binary patch literal 54011 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 literal 0 HcmV?d00001 diff --git a/B4A/Files/guna_192x192.jpg b/B4A/Files/guna_192x192.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4c14d2f90ff40735183ba5285309fe4a817d3304 GIT binary patch literal 11096 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 literal 0 HcmV?d00001 diff --git a/B4A/Guna Vistas V3.1.b4a b/B4A/Guna Vistas V3.1.b4a index 0657757..8c1b015 100644 --- a/B4A/Guna Vistas V3.1.b4a +++ b/B4A/Guna Vistas V3.1.b4a @@ -189,37 +189,37 @@ FileGroup93=Default Group FileGroup94=Default Group Group=Default Group Library1=appupdating -Library10=firebaseanalytics -Library11=firebasenotifications -Library12=fusedlocationprovider -Library13=googlemaps -Library14=googlemapsextras -Library15=gps -Library16=ime -Library17=javaobject -Library18=jhsicezxing1 -Library19=json +Library10=fileprovider +Library11=firebaseanalytics +Library12=firebasenotifications +Library13=fusedlocationprovider +Library14=googlemaps +Library15=googlemapsextras +Library16=gps +Library17=ime +Library18=javaobject +Library19=jhsicezxing1 Library2=b4xpages -Library20=okhttputils2 -Library21=phone -Library22=preoptimizedclv -Library23=randomaccessfile -Library24=rspopupmenu -Library25=runtimepermissions -Library26=serial -Library27=sql -Library28=togglelibrary -Library29=xcustomlistview +Library20=json +Library21=okhttputils2 +Library22=phone +Library23=preoptimizedclv +Library24=randomaccessfile +Library25=rspopupmenu +Library26=runtimepermissions +Library27=serial +Library28=sql +Library29=togglelibrary Library3=baqrcode -Library30=xui -Library31=xui views -Library32=compressstrings +Library30=xcustomlistview +Library31=xui +Library32=xui views Library4=batteryprogressview Library5=bitmapcreator Library6=byteconverter Library7=camera -Library8=core -Library9=fileprovider +Library8=compressstrings +Library9=core ManifestCode='This code will be applied to the manifest file during compilation.~\n~'You do not need to modify it in most cases.~\n~'See this link for for more information: https://www.b4x.com/forum/showthread.php?p=78136~\n~AddManifestText(~\n~~\n~)~\n~SetApplicationAttribute(android:icon, "@drawable/icon")~\n~SetApplicationAttribute(android:label, "$LABEL$")~\n~CreateResourceFromFile(Macro, Themes.LightTheme)~\n~AddApplicationText(~\n~)~\n~CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)~\n~ 'End of default text.~\n~ ~\n~ ''''' CAMBIA LA CLAVE API~\n~AddApplicationText(~\n~~\n~ ~\n~)~\n~AddApplicationText(~\n~~\n~)~\n~AddManifestText(~\n~~\n~)~\n~~\n~''CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)~\n~ 'End of default text.~\n~ ~\n~SetApplicationAttribute(android:usesCleartextTraffic, "true")~\n~ AddManifestText(~\n~~\n~)~\n~AddPermission(android.permission.ACCESS_BACKGROUND_LOCATION)~\n~AddManifestText(~\n~~\n~)~\n~AddManifestText(~\n~~\n~) 'in order to access the device non-resettable identifiers such as IMEI and serial number.~\n~~\n~'///////////////////////// FLP Y PUSH /////////////~\n~ CreateResourceFromFile(Macro, FirebaseAnalytics.GooglePlayBase)~\n~ CreateResourceFromFile(Macro, FirebaseAnalytics.Firebase)~\n~ CreateResourceFromFile(Macro, FirebaseAnalytics.FirebaseAnalytics)~\n~ CreateResourceFromFile(Macro, FirebaseNotifications.FirebaseNotifications)~\n~ SetServiceAttribute(Tracker, android:foregroundServiceType, "location")~\n~'//////////////////////////////////////////////////////~\n~~\n~'/////////////////////// App Updating ////////////////~\n~ AddManifestText(~\n~ )~\n~ AddApplicationText(~\n~ ~\n~ ~\n~ ~\n~ )~\n~ CreateResource(xml, provider_paths,~\n~ ~\n~ ~\n~ ~\n~ ~\n~ ~\n~ )~\n~AddManifestText()~\n~AddManifestText()~\n~AddManifestText()~\n~AddManifestText()~\n~~\n~AddPermission(android.permission.REQUEST_INSTALL_PACKAGES)~\n~AddPermission(android.permission.INTERNET)~\n~AddPermission(android.permission.INSTALL_PACKAGES)~\n~AddPermission(android.permission.READ_EXTERNAL_STORAGE)~\n~AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)~\n~AddPermission(android.permission.READ_PHONE_STATE)~\n~AddPermission(android.permission.WAKE_LOCK)~\n~CreateResourceFromFile(Macro, JhsIceZxing1.CaturePortrait)~\n~ ~\n~SetApplicationAttribute(android:largeHeap, "true")~\n~SetApplicationAttribute(android:allowBackup, "false")~\n~AddPermission(android.permission.BLUETOOTH_ADVERTISE)~\n~AddPermission(android.permission.BLUETOOTH_CONNECT)~\n~AddPermission(android.permission.BLUETOOTH_SCAN)~\n~AddManifestText(~\n~ ~\n~ )~\n~AddManifestText()~\n~~\n~AddManifestText(~\n~ ~\n~ )~\n~ AddPermission(android.permission.MANAGE_EXTERNAL_STORAGE)~\n~ SetApplicationAttribute(android:allowBackup, "false")~\n~ ~\n~ ~\n~ AddManifestText(~\n~ )~\n~ AddPermission(android.permission.READ_EXTERNAL_STORAGE)~\n~~\n~ 'Para que se registre para abrir bases de datos~\n~' AddActivityText(main,~\n~'~\n~'~\n~'~\n~'~\n~')~\n~~\n~ 'Para que se registre para abrir bases de datos~\n~ AddActivityText(main,~\n~~\n~~\n~~\n~~\n~~\n~)~\n~~\n~ Module1=appUpdater Module10=C_Nota @@ -233,13 +233,14 @@ Module17=C_TicketsDia Module18=C_UpdateAvailable Module19=CameraExClass Module2=B4XMainPage -Module20=DBRequestManager -Module21=EscPosPrinter -Module22=FirebaseMessaging -Module23=MAPA_RUTAS -Module24=Starter -Module25=Subs -Module26=Tracker +Module20=cPDF +Module21=DBRequestManager +Module22=EscPosPrinter +Module23=FirebaseMessaging +Module24=MAPA_RUTAS +Module25=Starter +Module26=Subs +Module27=Tracker Module3=BatteryUtilities Module4=|relative|..\C_Bitacora Module5=C_Cliente @@ -249,13 +250,13 @@ Module8=C_Historico Module9=C_Mapas NumberOfFiles=94 NumberOfLibraries=32 -NumberOfModules=26 +NumberOfModules=27 Version=12.8 @EndOfDesignText@ #Region Project Attributes #ApplicationLabel: Guna Preventa #VersionCode: 1 - #VersionName: 5.01.30 + #VersionName: 5.02.05 'SupportedOrientations possible values: unspecified, landscape or portrait. #SupportedOrientations: portrait #CanInstallToExternalStorage: False diff --git a/B4A/Guna Vistas V3.1.b4a.meta b/B4A/Guna Vistas V3.1.b4a.meta index 10f645e..2cadfef 100644 --- a/B4A/Guna Vistas V3.1.b4a.meta +++ b/B4A/Guna Vistas V3.1.b4a.meta @@ -18,6 +18,7 @@ ModuleBookmarks23= ModuleBookmarks24= ModuleBookmarks25= ModuleBookmarks26= +ModuleBookmarks27= ModuleBookmarks3= ModuleBookmarks4= ModuleBookmarks5= @@ -45,6 +46,7 @@ ModuleBreakpoints23= ModuleBreakpoints24= ModuleBreakpoints25= ModuleBreakpoints26= +ModuleBreakpoints27= ModuleBreakpoints3= ModuleBreakpoints4= ModuleBreakpoints5= @@ -68,17 +70,18 @@ ModuleClosedNodes2= ModuleClosedNodes20= ModuleClosedNodes21= ModuleClosedNodes22= -ModuleClosedNodes23=3,4 -ModuleClosedNodes24=4,6,7,8,9 -ModuleClosedNodes25= +ModuleClosedNodes23= +ModuleClosedNodes24=3,4 +ModuleClosedNodes25=4,6,7,8,9 ModuleClosedNodes26= +ModuleClosedNodes27= ModuleClosedNodes3= -ModuleClosedNodes4=5,6,7,8,9,10,11,12,13 -ModuleClosedNodes5=1,3 +ModuleClosedNodes4=5,8,9,10,11,12,13 +ModuleClosedNodes5= ModuleClosedNodes6= ModuleClosedNodes7=5,6,8,9,10,11 ModuleClosedNodes8= ModuleClosedNodes9= -NavigationStack=DBRequestManager,HandleJob,250,0,C_Principal,JobDone,1230,0,C_Principal,Class_Globals,44,0,C_Principal,B4XPage_Created,273,0,B4XMainPage,B4XPage_Created,100,2,B4XMainPage,JobDone,525,4,Starter,Process_Globals,34,0,C_Cliente,JobDone,1236,6,Starter,ENVIA_ULTIMA_GPS,107,0,C_Cliente,gest_Click,1261,6 +NavigationStack=C_Cliente,enviaTicket,5164,6,C_Cliente,savePDF,5124,5,C_Cliente,openPDF,5141,0,C_Cliente,b_enviarTicket_LongClick,5156,1,C_Cliente,Guardar_Click,2107,0,C_Cliente,B4XPage_Appear,512,0,C_Cliente,GPS_LocationChanged,989,0,C_Cliente,b_enviarTicket_Click,5146,6,C_Cliente,PDFGENERAR,4965,1,B4XMainPage,JobDone,484,0,Main,Process_Globals,21,0 SelectedBuild=0 -VisibleModules=24,2,14,25,4,5,7,6,15,12,20 +VisibleModules=25,2,14,26,5,10,15,20,4 diff --git a/B4A/Starter.bas b/B4A/Starter.bas index e5e24a2..43834e5 100644 --- a/B4A/Starter.bas +++ b/B4A/Starter.bas @@ -39,6 +39,7 @@ Sub Process_Globals Dim nuevoLink As String Dim idCliente As String = "" Dim encuesta As String = 0 + Public fFileProvider As FileProvider End Sub Sub Service_Create @@ -54,6 +55,7 @@ Sub Service_Create logcat.LogCatStart(Array As String("-v","raw","*:F","B4A:v"), "logcat") #end if logs.Initialize + fFileProvider.Initialize CallSubDelayed(FirebaseMessaging, "SubscribeToTopics") 'Para Push FirebaseMessaging ubicacionActual.Initialize If File.Exists(File.DirInternal, "kmt.db") = False Then diff --git a/B4A/Subs.bas b/B4A/Subs.bas index e449290..6f7a4e4 100644 --- a/B4A/Subs.bas +++ b/B4A/Subs.bas @@ -674,17 +674,17 @@ Sub traeRuta As String 'ignore idCliente = elCc.GetString("CUENTA") Log("|"&elCc.GetString("CUENTA")&"|") End If - Log($"#########################${CRLF}HAY USUARIO EN CUENTAA: ${elCc.RowCount}${CRLF}#########################"$) +' Log($"#########################${CRLF}HAY USUARIO EN CUENTAA: ${elCc.RowCount}${CRLF}#########################"$) If idCliente <> "" Then - Log(1) +' Log(1) c = B4XPages.MainPage.skmt.ExecQuery($"select distinct CAT_CL_RUTA from kmt_info2 where CAT_CL_CODIGO = '${idCliente}'"$) Else - Log(2) +' Log(2) c = B4XPages.MainPage.skmt.ExecQuery("select distinct CAT_CL_RUTA from kmt_info2 where CAT_CL_RUTA not in (select * from ruta_suplencia)") End If - Log($"#########################${CRLF}ENCONTRAMOS RUTA EN KMT_INFO2: ${c.RowCount}${CRLF}#########################"$) +' Log($"#########################${CRLF}ENCONTRAMOS RUTA EN KMT_INFO2: ${c.RowCount}${CRLF}#########################"$) If c.RowCount > 0 Then - Log(3) +' Log(3) c.Position=0 r = c.GetString("CAT_CL_RUTA") End If @@ -692,7 +692,7 @@ Sub traeRuta As String 'ignore Catch Log(LastException) End Try - Log($"#########################${CRLF}RUTA ENCONTRADA: |${r}|${CRLF}#########################"$) +' Log($"#########################${CRLF}RUTA ENCONTRADA: |${r}|${CRLF}#########################"$) Return r End Sub @@ -1739,4 +1739,23 @@ Sub traeVariable(nombre As String) As String valor = laVc.GetString("CAT_VA_VALOR") End If Return valor +End Sub + +Sub revisaImpreso As Boolean 'ignore + Private impreso As Boolean = False + Private c As Cursor = Starter.skmt.ExecQuery("select idCliente from ticket_impreso where idCliente in (select cuenta from cuentaa)") + If c.RowCount > 0 Then impreso = True + Return impreso +End Sub + +Sub deleteFolder(folder As String) + Log("Borrando " & folder) + For Each f As String In File.ListFiles(folder) + Log(f) + If File.IsDirectory(folder, f) Then + deleteFolder(File.Combine(folder, f)) + Log($"Borramos ${File.Combine(folder, f)}"$) + End If + File.Delete(folder, f) + Next End Sub \ No newline at end of file diff --git a/B4A/cPDF.bas b/B4A/cPDF.bas new file mode 100644 index 0000000..85bb6d2 --- /dev/null +++ b/B4A/cPDF.bas @@ -0,0 +1,1004 @@ +B4J=true +Group=Default Group +ModulesStructureVersion=1 +Type=Class +Version=9.8 +@EndOfDesignText@ +'releases +'0.1 : first version +'0.2 : add support fo image PNG with colorspace Indexed (palette) +'0.3 : add raw command to enter PDF command directly +'0.4 : add strikeThrough style for font +' add constants for font style +' add constants for colors +' add methods gMultilineTextSize and outTextFlow +' add setter/getter sX, sY, sY and gY to get/set the current position +'0.5 : add suport for all images type. image is convert to PNG before inserted. a temp file is created, insert into the pdf and deleted +'0.6 : add justify align +Sub Class_Globals + Type TPDFContext(fX As Double,fY As Double, _ + fFontFamily As String,fFontSize As Double,fFontStyle As Int,fFontColor(3) As Double, _ + fDrawWidth As Double,fDrawColor(3) As Double,fFillColor(3) As Double) + Type TPDFPage(fWidth As Double,fHeight As Double,fBuffer As String) + Type TPDFImageInfo(fError As Int,fWidth As Int,fHeight As Int,fBPP As Int,fColorSpace As Int,fCompression As Int,fFilter As Int,fInterlacing As Int,fData() As Byte,fPalette() As Byte) + Type TPDFFontInfo(fCharsWidths(256) As Int,fYUnderline As Int,fHUnderline As Int,fYStrikeThrough As Int,fHStrikeThrough As Int,fYBottom As Int,fYTop As Int) + Type TPDFTextSize(fWidth As Double,fTop As Double,fBottom As Double,fHeight As Double) + Type TPDFMultilineTextSize(fWidth As Double,fHeight As Double,fParagraphs As List) + + 'use to convert image to png + Private fXUI As XUI + + 'encoding file + Private const fTextEncoding As String="cp1252" + 'versions + Private fLibVersion As String + Private fPDFVersion As String + 'factor between user unit and pt + Private fUnitFactor As Double + 'current context + Private fContext As TPDFContext + 'properties of PDF document + Private fProperties As Map + 'list of objects in the PDF + Private fObjs As List + 'current page + Private fPage As Int + 'liste of pages (TPDFPage) + Private fPages As List + 'list of used images in the document, each item in a map (path,imageinfo) + Private fUsedImages As List + 'list of used fonts in the document + Private fUsedFonts As List + 'font info for all the stadards fonts (TPDFFontInfo) + Private fFontsInfos As Map + + 'constants for page size + Public const pageSizeA3PortraitWidth As Double=-841.89 + Public const pageSizeA3PortraitHeight As Double=-1190.55 +' Public const pageSizeA4PortraitWidth As Double=-595.28 +' Public const pageSizeA4PortraitHeight As Double=-841.89 + Public const pageSizeA4PortraitWidth As Double=-370 + Public const pageSizeA4PortraitHeight As Double=-72 + Public const pageSizeA5PortraitWidth As Double=-420.94 + Public const pageSizeA5PortraitHeight As Double=-595.28 + Public const pageSizeLetterPortraitWidth As Double=-612 + Public const pageSizeLetterPortraitHeight As Double=-792 + Public const pageSizeLegalPortraitWidth As Double=-612 + Public const pageSizeLegalPortraitHeight As Double=-1008 + Public const pageSizeA3LandscapeWidth As Double=-1190.55 + Public const pageSizeA3LandscapeHeight As Double=-841.89 + Public const pageSizeA4LandscapeWidth As Double=-841.89 + Public const pageSizeA4LandscapeHeight As Double=-595.28 + Public const pageSizeA5LandscapeWidth As Double=-595.28 + Public const pageSizeA5LandscapeHeight As Double=-420.94 + Public const pageSizeLetterLandscapeWidth As Double=-792 + Public const pageSizeLetterLandscapeHeight As Double=-612 + Public const pageSizeLegalLandscapeWidth As Double=-1008 + Public const pageSizeLegalLandscapeHeight As Double=-612 + + 'constants for standards fonts + Public const fontCourier As String="Courier" + Public const fontHelvetica As String="Helvetica" + Public const fontTimes As String="Times" + Public const fontSymbol As String="Symbol" + Public const fontZapfdingbats As String="zapfdingbats" + + 'constants for fonts styles + Public const fontNormal As Int=0 + Public const fontBold As Int=1 + Public const fontItalic As Int=2 + Public const fontUnderline As Int=4 + Public const fontStrikeThrough As Int=8 + + 'constants for properties + Public const PropertyAuthor As String="Author" + Public const PropertyCreator As String="Creator" + Public const PropertyProducer As String="Producer" + Public const PropertyTitle As String="Title" + Public const PropertySubject As String="Subject" + Public const PropertyKeywords As String="Keywords" + + 'constants for rectangle style + Public const RectangleBorderOnly As String="S" + Public const RectangleFillOnly As String="f" + Public const RectangleBorderAndFill As String="B" + + 'constants for text align + Public const AlignLeft As String="L" + Public const AlignCenter As String="C" + Public const AlignRight As String="R" + Public const AlignJusify As String="J" + + 'constants for compression + Public const CompressAlways As Int=0 + Public const CompressIfSmaller As Int=1 + Public const CompressNever As Int=2 + + Public const colorBlack(3) As Double=Array As Double(0,0,0) + Public const colorWhite(3) As Double=Array As Double(1,1,1) + Public const colorGray(3) As Double=Array As Double(0.5,0.5,0.5) + Public const colorRed(3) As Double=Array As Double(1,0,0) + Public const colorGreen(3) As Double=Array As Double(0,1,0) + Public const colorBlue(3) As Double=Array As Double(0,0,1) + +End Sub + +'initialize and set unit to use : mm, cm, pt, in +Public Sub Initialize(aunit As String) As cPDF + fLibVersion="0.6" + fPDFVersion="1.3" + sUnit(aunit) + fProperties=CreateMap("Producer":"B4XPDF","CreationDate":gCreationDate,"ModDate":gCreationDate) + fContext.Initialize + fObjs.Initialize + fPages.Initialize + fPage=0 + fUsedImages.Initialize + fUsedFonts.Initialize + initFontsInfos + Return Me +End Sub + +private Sub createFontInfo(acharsWidths() As Int,ayunderline As Int,ahunderline As Int,aystrikethrough As Int,ahstrikethrough As Int,aytop As Int,aybottom As Int) As TPDFFontInfo + Dim fi As TPDFFontInfo + fi.Initialize + 'width of each 256 chars + fi.fCharsWidths=acharsWidths + 'bottom of underline rectangle + fi.fYUnderline=ayunderline + 'height of underine rectangle + fi.fHUnderline=ahunderline + 'bottom of strikethrough rectangle + fi.fYStrikeThrough=aystrikethrough + 'height of strikethrough rectangle + fi.fHStrikeThrough=ahstrikethrough + 'distance between baseline and top + fi.fYTop=aytop + 'distance between baseline and bottom + fi.fybottom=aybottom + Return fi +End Sub + +private Sub initFontsInfos + fFontsInfos.Initialize + fFontsInfos.Put(calcFontKey("Courier",fontNormal),createFontInfo(Array As Int(600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Courier",fontBold),createFontInfo(Array As Int(600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Courier",fontItalic),createFontInfo(Array As Int(600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Courier",fontBold+fontItalic),createFontInfo(Array As Int(600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600,600),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Helvetica",fontNormal),createFontInfo(Array As Int(278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,355,556,556,889,667,191,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,350,556,350,222,556,333,1000,556,556,333,1000,667,333,1000,350,611,350,350,222,222,333,333,350,556,1000,333,1000,500,333,944,350,500,667,278,333,556,556,556,556,260,556,333,737,370,556,584,333,737,333,400,584,333,333,333,556,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667,1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556,556,556,556,556,556,584,611,556,556,556,556,500,556,500),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Helvetica",fontBold),createFontInfo(Array As Int(278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,333,474,556,556,889,722,238,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,350,556,350,278,556,500,1000,556,556,333,1000,667,333,1000,350,611,350,350,278,278,500,500,350,556,1000,333,1000,556,333,944,350,500,667,278,333,556,556,556,556,280,556,333,737,370,556,584,333,737,333,400,584,333,333,333,611,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722,1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611,611,611,611,611,611,584,611,611,611,611,611,556,611,556),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Helvetica",fontItalic),createFontInfo(Array As Int(278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,355,556,556,889,667,191,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,278,278,584,584,584,556,1015,667,667,722,722,667,611,778,722,278,500,667,556,833,722,778,667,778,722,667,611,722,667,944,667,667,611,278,278,278,469,556,333,556,556,500,556,556,278,556,556,222,222,500,222,833,556,556,556,556,333,500,278,556,500,722,500,500,500,334,260,334,584,350,556,350,222,556,333,1000,556,556,333,1000,667,333,1000,350,611,350,350,222,222,333,333,350,556,1000,333,1000,500,333,944,350,500,667,278,333,556,556,556,556,260,556,333,737,370,556,584,333,737,333,400,584,333,333,333,556,537,278,333,333,365,556,834,834,834,611,667,667,667,667,667,667,1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,500,556,556,556,556,278,278,278,278,556,556,556,556,556,556,556,584,611,556,556,556,556,500,556,500),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Helvetica",fontBold+fontItalic),createFontInfo(Array As Int(278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,278,333,474,556,556,889,722,238,333,333,389,584,278,333,278,278,556,556,556,556,556,556,556,556,556,556,333,333,584,584,584,611,975,722,722,722,722,667,611,778,722,278,556,722,611,833,722,778,667,778,722,667,611,722,667,944,667,667,611,333,278,333,584,556,333,556,611,556,611,556,333,611,611,278,278,556,278,889,611,611,611,611,389,556,333,611,556,778,556,556,500,389,280,389,584,350,556,350,278,556,500,1000,556,556,333,1000,667,333,1000,350,611,350,350,278,278,500,500,350,556,1000,333,1000,556,333,944,350,500,667,278,333,556,556,556,556,280,556,333,737,370,556,584,333,737,333,400,584,333,333,333,611,556,278,333,333,365,556,834,834,834,611,722,722,722,722,722,722,1000,722,667,667,667,667,278,278,278,278,722,722,778,778,778,778,778,584,778,722,722,722,722,667,667,611,556,556,556,556,556,556,889,556,556,556,556,556,278,278,278,278,611,611,611,611,611,611,611,584,611,611,611,611,611,556,611,556),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Times",fontNormal),createFontInfo(Array As Int(250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,333,408,500,500,833,778,180,333,333,500,564,250,333,250,278,500,500,500,500,500,500,500,500,500,500,278,278,564,564,564,444,921,722,667,667,722,611,556,722,722,333,389,722,611,889,722,722,556,722,667,556,611,722,722,944,722,722,611,333,278,333,469,500,333,444,500,444,500,444,333,500,500,278,278,500,278,778,500,500,500,500,333,389,278,500,500,722,500,500,444,480,200,480,541,350,500,350,333,500,444,1000,500,500,333,1000,556,333,889,350,611,350,350,333,333,444,444,350,500,1000,333,980,389,333,722,350,444,722,250,333,500,500,500,500,200,500,333,760,276,500,564,333,760,333,400,564,300,300,333,500,453,250,333,300,310,500,750,750,750,444,722,722,722,722,722,722,889,667,611,611,611,611,333,333,333,333,722,722,722,722,722,722,722,564,722,722,722,722,722,722,556,500,444,444,444,444,444,444,667,444,444,444,444,444,278,278,278,278,500,500,500,500,500,500,500,564,500,500,500,500,500,500,500,500),-60,40,2200,40,800,-230)) + fFontsInfos.Put(calcFontKey("Times",fontBold),createFontInfo(Array As Int(250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,333,555,500,500,1000,833,278,333,333,500,570,250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,570,570,570,500,930,722,667,722,722,667,611,778,778,389,500,778,667,944,722,778,611,778,722,556,667,722,722,1000,722,722,667,333,278,333,581,500,333,500,556,444,556,444,333,500,556,278,333,556,278,833,556,500,556,556,444,389,333,556,500,722,500,500,444,394,220,394,520,350,500,350,333,500,500,1000,500,500,333,1000,556,333,1000,350,667,350,350,333,333,500,500,350,500,1000,333,1000,389,333,722,350,444,722,250,333,500,500,500,500,220,500,333,747,300,500,570,333,747,333,400,570,300,300,333,556,540,250,333,300,330,500,750,750,750,500,722,722,722,722,722,722,1000,722,667,667,667,667,389,389,389,389,722,722,778,778,778,778,778,570,778,722,722,722,722,722,611,556,500,500,500,500,500,500,722,444,444,444,444,444,278,278,278,278,500,556,500,500,500,500,500,570,500,556,556,556,556,500,556,500),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Times",fontItalic),createFontInfo(Array As Int(250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,333,420,500,500,833,778,214,333,333,500,675,250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,675,675,675,500,920,611,611,667,722,611,611,722,722,333,444,667,556,833,667,722,611,722,611,500,556,722,611,833,611,556,556,389,278,389,422,500,333,500,500,444,500,444,278,500,500,278,278,444,278,722,500,500,500,500,389,389,278,500,444,667,444,444,389,400,275,400,541,350,500,350,333,500,556,889,500,500,333,1000,500,333,944,350,556,350,350,333,333,556,556,350,500,889,333,980,389,333,667,350,389,556,250,389,500,500,500,500,275,500,333,760,276,500,675,333,760,333,400,675,300,300,333,500,523,250,333,300,310,500,750,750,750,500,611,611,611,611,611,611,889,667,611,611,611,611,333,333,333,333,722,667,722,722,722,722,722,675,722,722,722,722,722,556,611,500,500,500,500,500,500,500,667,444,444,444,444,444,278,278,278,278,500,500,500,500,500,500,500,675,500,500,500,500,500,444,500,444),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Times",fontBold+fontItalic),createFontInfo(Array As Int(250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,389,555,500,500,833,778,278,333,333,500,570,250,333,250,278,500,500,500,500,500,500,500,500,500,500,333,333,570,570,570,500,832,667,667,667,722,667,667,722,778,389,500,667,611,889,722,722,611,722,667,556,611,722,667,889,667,611,611,333,278,333,570,500,333,500,500,444,500,444,333,500,556,278,278,500,278,778,556,500,500,500,389,389,278,556,444,667,500,444,389,348,220,348,570,350,500,350,333,500,500,1000,500,500,333,1000,556,333,944,350,611,350,350,333,333,500,500,350,500,1000,333,1000,389,333,722,350,389,611,250,389,500,500,500,500,220,500,333,747,266,500,606,333,747,333,400,570,300,300,333,576,500,250,333,300,300,500,750,750,750,500,667,667,667,667,667,667,944,667,667,667,667,667,389,389,389,389,722,722,722,722,722,722,722,570,722,722,722,722,722,611,611,500,500,500,500,500,500,500,722,444,444,444,444,444,278,278,278,278,500,556,500,500,500,500,500,570,500,556,556,556,556,444,500,444),-60,40,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("Symbol",fontNormal),createFontInfo(Array As Int(250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,250,333,713,500,549,833,778,439,333,333,500,549,250,549,250,278,500,500,500,500,500,500,500,500,500,500,278,278,549,549,549,444,549,722,667,722,612,611,763,603,722,333,631,722,686,889,722,722,768,741,556,592,611,690,439,768,645,795,611,333,863,333,658,500,500,631,549,549,494,439,521,411,603,329,603,549,549,576,521,549,549,521,549,603,439,576,713,686,493,686,494,480,200,480,549,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,750,620,247,549,167,713,500,753,753,753,753,1042,987,603,987,603,400,549,411,549,549,713,494,460,549,549,549,549,1000,603,1000,658,823,686,795,987,768,768,823,768,768,713,713,713,713,713,713,713,768,713,790,790,890,823,549,250,713,603,603,1042,987,603,987,603,494,329,790,790,786,713,384,384,384,384,384,384,494,494,494,494,0,329,274,686,686,686,384,384,384,384,384,384,494,494,494,0),-60,10,220,40,800,-230)) + fFontsInfos.Put(calcFontKey("zapfdingbats",fontNormal),createFontInfo(Array As Int(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,278,974,961,974,980,719,789,790,791,690,960,939,549,855,911,933,911,945,974,755,846,762,761,571,677,763,760,759,754,494,552,537,577,692,786,788,788,790,793,794,816,823,789,841,823,833,816,831,923,744,723,749,790,792,695,776,768,792,759,707,708,682,701,826,815,789,789,707,687,696,689,786,787,713,791,785,791,873,761,762,762,759,759,892,892,788,784,438,138,277,415,392,392,668,668,0,390,390,317,317,276,276,509,509,410,410,234,234,334,334,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,732,544,544,910,667,760,760,776,595,694,626,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,788,894,838,1016,458,748,924,748,918,927,928,928,834,873,828,924,924,917,930,931,463,883,836,836,867,867,696,696,874,0,874,760,946,771,865,771,888,967,888,831,873,927,970,918,0),-60,40,220,40,800,-230)) +End Sub + +'set factor to convert user unit to pt +private Sub sUnit(aunit As String) As cPDF + Select aunit.ToLowerCase + Case "pt" + fUnitFactor=1.0 + Case "mm" + fUnitFactor=72.0/25.4 + Case "cm" + fUnitFactor=72.0/2.54 + Case "in" + fUnitFactor=72.0 + Case Else + fUnitFactor=1.0 + End Select + Return Me +End Sub + +'return current date and time in format D:YYYYMMDDHHMMSS±hh'mm' +private Sub gCreationDate As String + DateTime.DateFormat="yyyyMMdd" + DateTime.TimeFormat="hhmmss" + Dim z As String=NumberFormat2(DateTime.TimeZoneOffset,2,2,2,False) + z=IIf(z.SubString2(0,1)<>"-","+","") & z + z=z.SubString2(0,3) & "'" & z.SubString(4) & "'" + Return "D:" & DateTime.Date(DateTime.Now) & DateTime.Time(DateTime.Now) & z +End Sub + +'all the ....write methods write a part of the pdf +private Sub headerWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + bb.Append($"%PDF-${NumberFormat2(fPDFVersion,1,1,1,False)}${Chr(10)}"$.getBytes(fTextEncoding)) + Return bb.toarray +End Sub + +private Sub catalogWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + bb.Append($"${fObjs.Size+1} 0 obj <> endobj${Chr(10)}"$.getBytes(fTextEncoding)) + fObjs.Add(bb.Length) + Return bb.toarray +End Sub + +private Sub kidsWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + bb.Append($"${fObjs.Size+1} 0 obj <> endobj${Chr(10)}"$.getbytes(fTextEncoding)) + fObjs.Add(bb.Length) + Return bb.ToArray +End Sub + +private Sub pagesWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + Dim r As Int=fObjs.Size+1+fPages.Size*2 + For i=0 To fPages.Size-1 + bb.append(pageWrite(i,r)) + Next + Return bb.ToArray +End Sub + +private Sub pageWrite(apage As Int,aresource As Int) As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + Dim p As TPDFPage=fPages.Get(apage) + bb.Append($"${fObjs.Size+1} 0 obj <> endobj${Chr(10)}"$.getbytes(fTextEncoding)) + fObjs.Add(bb.Length) + Return bb.ToArray +End Sub + +private Sub contentsWrite(acompress As Int) As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + For i=0 To fPages.Size-1 + bb.append(contentWrite(acompress,i)) + Next + Return bb.toarray +End Sub + +private Sub contentWrite(acompress As Int,apage As Int) As Byte() + Dim const compress As String="/Filter/FlateDecode" + Dim bb As B4XBytesBuilder + bb.Initialize + + Dim c() As Byte=fPages.Get(apage).As(TPDFPage).fBuffer.GetBytes(fTextEncoding) + Dim filter As String="" + + If acompress<>CompressNever Then + Dim cs As CompressedStreams + Dim b() As Byte=cs.CompressBytes(c,"zlib") + If acompress=CompressAlways Or b.Length+compress.length>${Chr(10)}stream${Chr(10)}"$.getbytes(fTextEncoding)) + bb.Append(c) + bb.Append($"${Chr(10)}endstream${Chr(10)}endobj${Chr(10)}"$.getBytes(fTextEncoding)) + fObjs.Add(bb.Length) + Return bb.ToArray +End Sub + +private Sub resourcesWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + bb.Append($"${fObjs.size+1} 0 obj << "$.getBytes(fTextEncoding)) + + bb.Append($"/ProcSet [/PDF /Text /ImageB /ImageC /ImageI] ${Chr(10)}"$.getBytes(fTextEncoding)) + + bb.append($"/Font << ${Chr(10)}"$.getBytes(fTextEncoding)) + For i=0 To fUsedFonts.Size-1 + bb.Append($"/F${i} ${fObjs.Size+1+i+1} 0 R "$.getBytes(fTextEncoding)) + Next + bb.append($" >> ${Chr(10)}"$.getBytes(fTextEncoding)) + + bb.append($"/XObject << ${Chr(10)}"$.getBytes(fTextEncoding)) + For i=0 To fUsedImages.Size-1 + bb.Append($"/I${i} ${fObjs.Size+1+i+1+fUsedFonts.size} 0 R "$.getBytes(fTextEncoding)) + Next + bb.append($" >> ${Chr(10)}"$.getBytes(fTextEncoding)) + + bb.Append($" >> endobj${Chr(10)}"$.getBytes(fTextEncoding)) + fObjs.Add(bb.Length) + Return bb.ToArray +End Sub + +private Sub fontsWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + For i=0 To fUsedFonts.Size-1 + bb.append(fontWrite(i)) + Next + Return bb.ToArray +End Sub + +private Sub fontWrite(afont As Int) As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + Dim c As String=fUsedFonts.Get(afont) + bb.Append($"${fObjs.Size+1} 0 obj << /Type /Font /Subtype /Type1 /BaseFont /${c} /Encoding /WinAnsiEncoding>> endobj${Chr(10)}"$.getbytes(fTextEncoding)) + fObjs.Add(bb.Length) + Return bb.ToArray +End Sub + +private Sub imagesWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + For i=0 To fUsedImages.Size-1 + bb.append(imageWrite(i)) + Next + Return bb.toarray +End Sub + +private Sub imageWrite(aimage As Int) As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + Dim ii As TPDFImageInfo=fUsedImages.Get(aimage).As(Map).Get("info") + bb.Append($"${fObjs.Size+1} 0 obj${Chr(10)}<>${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append($"/Length ${ii.fData.length}>>${Chr(10)}stream${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append(ii.fdata) + bb.Append($"${Chr(10)}endstream${Chr(10)}endobj${Chr(10)}"$.getBytes(fTextEncoding)) + fObjs.Add(bb.Length) + If cs="Indexed" Then + bb.Append(paletteWrite(ii.fPalette)) + End If + Return bb.ToArray +End Sub + +private Sub paletteWrite(apalette() As Byte) As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + bb.Append($"${fObjs.Size+1} 0 obj${Chr(10)}<>${Chr(10)}stream${Chr(10)}"$.getbytes(fTextEncoding)) + bb.Append(apalette) + bb.Append($"${Chr(10)}endstream${Chr(10)}endobj${Chr(10)}"$.getBytes(fTextEncoding)) + fObjs.Add(bb.Length) + Return bb.ToArray +End Sub + +private Sub propertiesWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + bb.Append($"${fObjs.Size+1} 0 obj <<${Chr(10)}"$.getBytes(fTextEncoding)) + For Each k As String In fProperties.keys + bb.Append($"/${k}(${escapeText(fProperties.Get(k))})${Chr(10)}"$.getBytes(fTextEncoding)) + Next + bb.Append($" >> endobj${Chr(10)}"$.getBytes(fTextEncoding)) + fObjs.Add(bb.Length) + Return bb.ToArray +End Sub + +private Sub refWrite(astart As Long,ageneration As Int,astatus As String) As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + bb.Append($"${NumberFormat2(astart,10,0,0,False)} ${NumberFormat2(ageneration,5,0,0,False)} ${astatus}${Chr(10)}"$.getBytes(fTextEncoding)) + Return bb.ToArray +End Sub + +private Sub xrefWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + Dim s As Long=headerWrite.length + bb.Append($"xref${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append($"0 ${fObjs.Size+1}${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append(refWrite(0,65535,"f")) + For i=0 To fObjs.Size-1 + Dim l As Int=fObjs.Get(i) + bb.Append(refWrite(s,0,"n")) + s=s+l + Next + Return bb.ToArray +End Sub + +private Sub trailerWrite As Byte() + Dim bb As B4XBytesBuilder + bb.Initialize + Dim s As Long=headerWrite.length + For i=0 To fObjs.Size-1 + Dim l As Int=fObjs.Get(i) + s=s+l + Next + bb.Append($"trailer <<${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append($"/Size ${fObjs.Size+1}${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append($"/Info ${fObjs.Size} 0 R${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append($"/Root 1 0 R${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append($">>${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append($"startxref${Chr(10)}"$.getBytes(fTextEncoding)) + bb.Append($"${s}${Chr(10)}"$.getBytes(fTextEncoding)) + Return bb.ToArray +End Sub + +private Sub footerWrite As Byte() + Return "%%EOF".GetBytes(fTextEncoding) +End Sub + +'calc a unique key for a specific font (family ans style (bold, italic)) +private Sub calcFontKey(afamily As String,astyle As Int) As String + If afamily="zapfdingbats" Or afamily="Symbol" Then + astyle=Bit.And(astyle,Bit.Not(Bit.Or(fontBold,fontItalic))) + End If + If Bit.And(astyle,fontBold)<>0 And Bit.And(astyle,fontItalic)<>0 Then + Return afamily & "-BoldOblique" + End If + If Bit.And(astyle,fontBold)<>0 Then + Return afamily & "-Bold" + End If + If Bit.And(astyle,fontItalic)<>0 Then + Return afamily & "-Oblique" + End If + If afamily="Times" Then + Return "Times-Roman" + End If + Return afamily +End Sub + +'add content to a page +private Sub contentAdd(apage As Int,acontent As String) + Dim sb As StringBuilder + sb.Initialize + sb.Append(fPages.Get(apage).As(TPDFPage).fbuffer) + sb.Append(acontent) + fPages.Get(apage).As(TPDFPage).fbuffer=sb.ToString +End Sub + +'escape characters ( ) \ +private Sub escapeText(atext As String) As String + Return atext.Replace("\","\\").Replace("(","\(").Replace(")","\)") +End Sub + +'initialize, set properties and return a TPDFPage +private Sub createPage(awidth As Double,aheight As Double,abuffer As String) As TPDFPage + Dim p As TPDFPage + p.Initialize + p.fWidth=awidth + p.fHeight=aheight + p.fBuffer=abuffer + Return p +End Sub + +private Sub rafReadString(araf As RandomAccessFile,astart As Long,acount As Long) As String + Dim s As String + For i=0 To acount-1 + s=s & Chr(araf.ReadUnsignedByte(astart+i)) + Next + Return s +End Sub + +'calc a unique key for a specific image (adir & afile) +private Sub imageKey(adir As String,afile As String) As String + Return adir & afile +End Sub + +'parse png file +private Sub imageInfo(adir As String,afile As String) As TPDFImageInfo + Dim ii As TPDFImageInfo + Dim raf As RandomAccessFile + Dim rafpos As Long + Dim bbData As B4XBytesBuilder + Dim bbPalette As B4XBytesBuilder + + bbData.Initialize + bbPalette.Initialize + ii.Initialize + ii.fError=0 + raf.Initialize(adir,afile,True) + rafpos=0 + + + 'signture PNG + If rafReadString(raf,rafpos,8)<>Chr(137) & "PNG" & Chr(13) & Chr(10) & Chr(26) & Chr(10) Then + ii.fError=1 + End If + rafpos=rafpos+8 + + 'chunks (length, type, data, CRC) + Dim chunkLength As Int + Dim chunkType As String + Do While (ii.fError=0) And (chunkType<>"IEND") + chunkLength=raf.ReadInt(rafpos) + rafpos=rafpos+4 + chunkType=rafReadString(raf,rafpos,4) + rafpos=rafpos+4 + Select chunkType + 'header + Case "IHDR" + ii.fWidth=raf.ReadInt(rafpos) + rafpos=rafpos+4 + + ii.fHeight=raf.ReadInt(rafpos) + rafpos=rafpos+4 + + ii.fBPP=raf.ReadUnsignedByte(rafpos) + If ii.fBPP>8 Then + ii.fError=2 + End If + rafpos=rafpos+1 + + ii.fColorSpace=raf.ReadUnsignedByte(rafpos) + If ii.fColorSpace<>0 And ii.fColorSpace<>2 And ii.fColorSpace<>3 And ii.fColorSpace<>4 Then + ii.FError=3 + End If + rafpos=rafpos+1 + + ii.FCompression=raf.ReadUnsignedByte(rafpos) + If ii.FCompression<>0 Then + ii.FError=4 + End If + rafpos=rafpos+1 + + ii.FFilter=raf.ReadUnsignedByte(rafpos) + If ii.FFilter<>0 Then + ii.FError=5 + End If + rafpos=rafpos+1 + + ii.FInterlacing=raf.ReadUnsignedByte(rafpos) + If ii.FInterlacing<>0 Then + ii.FError=6 + End If + rafpos=rafpos+1 + 'data + Case "IDAT" + Dim b(chunkLength) As Byte + raf.ReadBytes(b,0,chunkLength,rafpos) + bbData.Append(b) + rafpos=rafpos+chunkLength + 'palette + Case "PLTE" + Dim b(chunkLength) As Byte + raf.ReadBytes(b,0,chunkLength,rafpos) + bbPalette.Append(b) + rafpos=rafpos+chunkLength + 'ignore other chunktype + Case Else + 'skip Data + rafpos=rafpos+chunkLength + End Select + 'skip CRC + rafpos=rafpos+4 + Loop + + raf.close + ii.fData=bbData.ToArray + ii.fPalette=bbPalette.ToArray + + Return ii +End Sub + + + +'save to stream +public Sub saveToStream(aoutputstream As OutputStream,acompress As Int) As cPDF + Dim b() As Byte=headerWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=catalogWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=kidsWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=pagesWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=contentsWrite(acompress) + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=resourcesWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=fontsWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=imagesWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=propertiesWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=xrefWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=trailerWrite + aoutputstream.WriteBytes(b,0,b.length) + Dim b() As Byte=footerWrite + aoutputstream.WriteBytes(b,0,b.length) + Return Me +End Sub + +'save pdf to a file +public Sub saveToFile(adir As String, afile As String, acompress As Int) As cPDF + Log(afile) + File.Delete(adir,afile) + Dim outputstream As OutputStream=File.OpenOutput(adir,afile,False) + saveToStream(outputstream,acompress) + outputstream.Close + Return Me +End Sub + + +'return the index of the image with path=akey in fUSedImages +'return -1 if not found +private Sub findImageKey(akey As String) As Int + For i=0 To fUsedImages.Size-1 + If fUsedImages.Get(i).As(Map).Get("path")=akey Then + Return i + End If + Next + Return -1 +End Sub + + +'get the number of pages in the pdf +public Sub gPagesCount As Int + Return fPages.size +End Sub + +'get the width of the page +'apage : 1 to n +public Sub gPageWidth(apage As Int) As Double + Return fPages.Get(apage-1).As(TPDFPage).fWidth/fUnitFactor +End Sub + +'get the height of the page +'apage : 1 to n +public Sub gPageHeight(apage As Int) As Double + Return fPages.Get(apage-1).As(TPDFPage).fHeight/fUnitFactor +End Sub + +'add a new page with width and height +'use predefined constants pageSize... +'or enter custom size (unit is unit defined in intialize method) +'the new page becomes the current page +public Sub pageAdd(awidth As Double,aheight As Double) As cPDF + fPages.Add(createPage(IIf(awidth<0,-awidth,awidth*fUnitFactor),IIf(aheight<0,-aheight,aheight*fUnitFactor),"")) + fPage=fPages.Size-1 + sFont(fContext.fFontFamily,fContext.fFontStyle,fContext.fFontSize,fContext.fFontColor) + sDrawColor(fContext.fDrawColor) + sDrawWidth(fContext.fDrawWidth) + sFillColor(fContext.fFillColor) + Return Me +End Sub + +'get current page +public Sub gPage As Int + Return fPage+1 +End Sub + +'set current page +'apage : 1 to n +public Sub sPage(apage As Int) As cPDF + fPage=apage-1 + Return Me +End Sub + +'set draw color for line +'argb : Red Green Blue +'values from 0.000 to 1.000 +public Sub sDrawColor(argb() As Double) As cPDF + fContext.fDrawColor=argb + contentAdd(fPage,$"${NumberFormat2(argb(0),1,3,3,False)} ${NumberFormat2(argb(1),1,3,3,False)} ${NumberFormat2(argb(2),1,3,3,False)} RG${Chr(10)}"$) + Return Me +End Sub + +'set draw width for line +public Sub sDrawWidth(awidth As Double) As cPDF + fContext.fDrawWidth=awidth + contentAdd(fPage,$"${NumberFormat2(awidth*fUnitFactor,1,3,3,False)} w${Chr(10)}"$) + Return Me +End Sub + +'set fill color +'argb : Red Green Blue +'values from 0.000 to 1.000 +public Sub sFillColor(argb() As Double) As cPDF + fContext.fFillColor=argb + Return Me +End Sub + +'set font +'family : Helvetica,Times,Courier,Symbol,zapfdingbats (use predefined constants font...) +'size in pts +'font uses cp-1252 windows encoding +public Sub sFont(afamily As String,astyle As Int,asize As Double,acolor() As Double) As cPDF + Dim k As String=calcFontKey(afamily,astyle) + Dim i As Int=fUsedFonts.IndexOf(k) + If i=-1 Then + fUsedFonts.Add(k) + i=fUsedFonts.Size-1 + End If + contentAdd(fPage,$"BT /F${i} ${NumberFormat2(asize,1,3,3,False)} Tf ET${Chr(10)}"$) + fContext.fFontFamily=afamily + fContext.fFontStyle=astyle + fContext.fFontSize=asize + fContext.fFontColor=acolor + Return Me +End Sub + +'draw text on current page at position ax,ay with current font and current text color +'(0,0) is bottom left of the page +'(w,h) if top right of the page +public Sub outText(ax As Double,ay As Double,atext As String) As cPDF + contentAdd(fPage,$"${NumberFormat2(fContext.fFontColor(0),1,3,3,False)} ${NumberFormat2(fContext.fFontColor(1),1,3,3,False)} ${NumberFormat2(fContext.fFontColor(2),1,3,3,False)} rg${Chr(10)}"$) + contentAdd(fPage,$"BT ${NumberFormat2(ax*fUnitFactor,1,3,3,False)} ${NumberFormat2(ay*fUnitFactor,1,3,3,False)} Td (${escapeText(atext)})Tj ET${Chr(10)}"$) + If Bit.And(fContext.fFontstyle,fontUnderline+fontStrikeThrough)<>0 Then + Dim fi As TPDFFontInfo=fFontsInfos.Get(calcFontKey(fContext.fFontFamily,fContext.fFontStyle)).As(TPDFFontInfo) + Dim ts As TPDFTextSize=gTextSize(atext) + End If + If Bit.And(fContext.fFontstyle,fontUnderline)<>0 Then + contentAdd(fPage,$"${NumberFormat2(ax*fUnitFactor,1,3,3,False)} ${NumberFormat2(ay*fUnitFactor+fi.fYUnderline*fContext.fFontSize/1000,1,3,3,False)} ${NumberFormat2(ts.fWidth*fUnitFactor,1,3,3,False)} ${NumberFormat2((fi.fHUnderline)*fContext.fFontSize/1000,1,3,3,False)} re f ${Chr(10)}"$) + End If + If Bit.And(fContext.fFontstyle,fontStrikeThrough)<>0 Then + contentAdd(fPage,$"${NumberFormat2(ax*fUnitFactor,1,3,3,False)} ${NumberFormat2(ay*fUnitFactor+fi.fYStrikeThrough*fContext.fFontSize/1000,1,3,3,False)} ${NumberFormat2(ts.fWidth*fUnitFactor,1,3,3,False)} ${NumberFormat2((fi.fHStrikeThrough)*fContext.fFontSize/1000,1,3,3,False)} re f ${Chr(10)}"$) + End If + Return Me +End Sub + +'draw text on current page at position ax,ay with current font and current text color +'explicit CRLF in atext +'automatic CRLF when awidth is reached +'(0,0) is bottom left of the page +'(w,h) if top right of the page +public Sub outTextFlow(aleftMargin As Double,arightMargin As Double,aalign As String,atext As String) As cPDF + Dim mts As TPDFMultilineTextSize=gMultilineTextSize(arightMargin-aleftMargin,atext) + Dim ts As TPDFTextSize + For p=0 To mts.fParagraphs.Size-1 + Dim lines As List=mts.fParagraphs.Get(p).As(List) + For i=0 To lines.Size-1 + Dim l As String=lines.Get(i) + ts=gTextSize(l) + Select Case aalign + Case "L" + outText(aleftMargin,fContext.fy,l) + Case "C" + outText(aleftMargin+(arightMargin-aleftMargin-ts.fWidth)/2,fContext.fy,l) + Case "R" + outText(arightMargin-ts.fWidth,fContext.fy,l) + Case "J" + If i=lines.Size-1 Then + 'last line if left aligned + outText(aleftMargin,fContext.fy,l) + Else + 'other lines are justified + Dim w() As String=Regex.split(" ",l) + Dim x As Double=aleftMargin + 'calc space between each word + Dim s As Double=((arightMargin-aleftMargin)-ts.fWidth+(gTextSize(" ").fWidth*(w.Length-1)))/(w.Length-1) + For j=0 To w.Length-1 + Dim ww As TPDFTextSize=gTextSize(w(j)) + outText(x,fContext.fy,w(j)) + x=x+s+ww.fWidth + Next + End If + End Select + fContext.fX=aleftMargin + fContext.fy=fContext.fy+ts.fHeight + Next + Next + Return Me +End Sub + +'draw a line on current page from ax1,ay1 to ax2,ay2 with current width and color +'(0,0) is bottom left of the page +'(w,h) if top right of the page +public Sub outLine(ax1 As Double,ay1 As Double,ax2 As Double,ay2 As Double) As cPDF + contentAdd(fPage,$"${NumberFormat2(ax1*fUnitFactor,1,3,3,False)} ${NumberFormat2(ay1*fUnitFactor,1,3,3,False)} m ${NumberFormat2(ax2*fUnitFactor,1,3,3,False)} ${NumberFormat2(ay2*fUnitFactor,1,3,3,False)} l h S${Chr(10)}"$) + Return Me +End Sub + +'draw a rectangle on current page starting at ax,ay with dimension aw,ah,current width, color and textAndFillColor are used +'(0,0) is bottom left of the page +'(w,h) if top right of the page +'astyle : use predefined constants RectangleBorderOnly,RectangleFillOnly,RectangleBorderAndFill +public Sub outRectangle(ax As Double,ay As Double,aw As Double,ah As Double,astyle As String) As cPDF + If astyle=RectangleBorderAndFill Or astyle=RectangleFillOnly Then + contentAdd(fPage,$"${NumberFormat2(fContext.fFillColor(0),1,3,3,False)} ${NumberFormat2(fContext.fFillColor(1),1,3,3,False)} ${NumberFormat2(fContext.fFillColor(2),1,3,3,False)} rg${Chr(10)}"$) + End If + contentAdd(fPage,$"${NumberFormat2(ax*fUnitFactor,1,3,3,False)} ${NumberFormat2(ay*fUnitFactor,1,3,3,False)} ${NumberFormat2(aw*fUnitFactor,1,3,3,False)} ${NumberFormat2(ah*fUnitFactor,1,3,3,False)} re ${astyle} ${Chr(10)}"$) + Return Me +End Sub + +private Sub convertImage(adir As String,afile As String) As String + 'convert to JPG + Dim img As B4XBitmap + img=fXUI.LoadBitmap(adir,afile) + Dim out As OutputStream=File.OpenOutput(adir,afile & ".jpg",False) + img.WriteToStream(out,100,"JPEG") + out.close + + 'then convert to PNG + Dim img As B4XBitmap + img=fXUI.LoadBitmap(adir,afile & ".jpg") + Dim out As OutputStream=File.OpenOutput(adir,afile & ".png",False) + img.WriteToStream(out,100,"PNG") + out.close + + File.Delete(adir,afile & ".jpg") + Return afile & ".png" +End Sub + +'draw an image +'only PNG +public Sub outImage(adir As String,afile As String,ax As Double,ay As Double,aw As Double,ah As Double) As cPDF + Dim ii As TPDFImageInfo + afile=convertImage(adir,afile) + 'check if this image is already used + Dim k As String=imageKey(adir,afile) + Dim i As Int=findImageKey(k) + 'if not add it to the list + If i=-1 Then + 'get informations about the image + ii=imageInfo(adir,afile) + 'store it in the list + fUsedImages.add(CreateMap("path":k,"info":ii)) + i=fUsedImages.Size-1 + Else + ii=fUsedImages.Get(i).As(Map).Get("info") + End If + + File.Delete(adir,afile) + + If ii.fError=0 Then + 'originals width and height + If aw=0 And ah=0 Then + aw=-96 + ah=-96 + End If + + '-aw is horizontal resolution in dpi + If aw<0 Then + aw=-ii.fWidth*72/aw/fUnitFactor + End If + '-ah is vertical resolution in dpi + If ah<0 Then + ah=-ii.fHeight*72/ah/fUnitFactor + End If + + 'calc aw proportionnaly to ah + If aw=0 Then + aw=ah*ii.fWidth/ii.fHeight + End If + 'calc ah proportionnaly to aw + If ah=0 Then + ah=aw*ii.fHeight/ii.fWidth + End If + + contentAdd(fPage,$"q ${NumberFormat2(aw*fUnitFactor,1,3,3,False)} 0 0 ${NumberFormat2(ah*fUnitFactor,1,3,3,False)} ${NumberFormat2(ax*fUnitFactor,1,3,3,False)} ${NumberFormat2(ay*fUnitFactor,1,3,3,False)} cm /I${i} Do Q${Chr(10)}"$) + End If + Return Me +End Sub + +'add raw content to the current page +'all the positions and dimensions are in user unit +'LF is added at the end of text +public Sub outRaw(atext As String) As cPDF + If fUnitFactor<>1 Then + 'convert user unit in atext to pt + Dim shift As Int=0 + atext=atext & Chr(10) + Dim m As Matcher = Regex.Matcher("([+-]?[0-9]{1,}[\.]{0,1}[0-9]{0,})",atext) + Do While m.Find + For g=1 To m.GroupCount + Dim v As String=NumberFormat2(fUnitFactor*m.Group(g),1,3,3,False) + atext=atext.SubString2(0,m.getstart(g)+shift) & v & atext.SubString(m.GetEnd(g)+shift) + shift=shift+v.Length-m.Group(g).Length + Next + Loop + End If + contentAdd(fPage,atext) + Return Me +End Sub + +'set a document's property +'use predefined constants propertyAuthor.... +public Sub sProperty(aproperty As String,avalue As String) As cPDF + fProperties.Put(aproperty,avalue) + Return Me +End Sub + +'convert signed byte to unsigned +private Sub ToUnsigned(b As Byte) As Int + Return Bit.And(0xFF, b) +End Sub + +'get the text size with the current font and size +'fwidth : width of the text +'fTop : distance between baseline and top of the text +'fBottom : distance between baseline and bottom of the text +'fHeight : total height of the text +public Sub gTextSize(atext As String) As TPDFTextSize + Dim bb As B4XBytesBuilder + Dim ts As TPDFTextSize + bb.Initialize + bb.Append(atext.GetBytes(fTextEncoding)) + ts.Initialize + Dim fi As TPDFFontInfo=fFontsInfos.Get(calcFontKey(fContext.fFontFamily,fContext.fFontStyle)).As(TPDFFontInfo) + Dim w As Double + For i=0 To bb.Length-1 + w=w+fi.fCharsWidths(ToUnsigned(bb.InternalBuffer(i))) + Next + ts.fWidth=w*fContext.fFontSize/1000/fUnitFactor + ts.fTop=fi.fYTop*fContext.fFontSize/1000/fUnitFactor + ts.fBottom=fi.fYBottom*fContext.fFontSize/1000/fUnitFactor + ts.fHeight=ts.fBottom-ts.fTop + Return ts +End Sub + + + +'add line to TPDFMultilineTextSize and return rest of line +private Sub MultilineTextSizeAddLine(amts As TPDFMultilineTextSize,ats As TPDFTextSize,atext As String,awidth As Double) As String + Dim s As String + If ats.fWidth>awidth Then + Dim p As Int=atext.LastIndexOf(" ") + If p=-1 Then + p=atext.Length-1 + End If + s=atext.SubString(p+1) + atext=atext.SubString2(0,p) + Else + s="" + End If + amts.fparagraphs.Get(amts.fParagraphs.Size-1).As(List).Add(atext) + amts.fHeight=amts.fHeight+ats.fHeight + Return s +End Sub + +'get the size of multiline text with the current font and size +public Sub gMultilineTextSize(awidth As Double,atext As String) As TPDFMultilineTextSize + Dim mts As TPDFMultilineTextSize + Dim ts As TPDFTextSize + Dim c As Char + Dim l As String="" + mts.Initialize + mts.fParagraphs.Initialize + mts.fWidth=awidth + 'split text with CRLF + Dim paragraphs() As String=Regex.Split(CRLF,atext) + Dim p As String + For j=0 To paragraphs.Length-1 + Dim lines As List + lines.Initialize + mts.fParagraphs.Add(lines) + p=paragraphs(j) + l="" + For i=0 To p.Length-1 + c=p.CharAt(i) + If Asc(c)>31 Then + l=l & c + ts=gTextSize(l) + If ts.fWidth>awidth Then + l=MultilineTextSizeAddLine(mts,ts,l,awidth) + End If + End If + Next + ts=gTextSize(l) + l=MultilineTextSizeAddLine(mts,ts,l,awidth) + Next + + Return mts +End Sub + +public Sub sX(avalue As Double) As cPDF + fContext.fX=avalue + Return Me +End Sub + +public Sub sY(avalue As Double) As cPDF + fContext.fy=avalue + Return Me +End Sub + +public Sub gX As Double + Return fContext.fX +End Sub + +public Sub gy As Double + Return fContext.fy +End Sub + +'get the lib version +public Sub glibversion As String + Return fLibVersion +End Sub \ No newline at end of file diff --git a/C_Bitacora.bas b/C_Bitacora.bas index c67c73f..0b4ae55 100644 --- a/C_Bitacora.bas +++ b/C_Bitacora.bas @@ -24,7 +24,7 @@ Public Sub Initialize (vCallback As Object, vEventName As String, vRoot As B4XVi Root2 = vRoot reqManager = DBReq db.ExecNonQuery("CREATE TABLE IF NOT EXISTS BITACORAGPS(fechab TEXT, usuariob TEXT, almacenb TEXT, rutab TEXT, eventob TEXT, clienteb TEXT, iniciob TEXT, finb TEXT, latitudb TEXT, longitudb TEXT, precision TEXT, motivonoventa TEXT, motivonovisita TEXT, BAN_GEOB TEXT)") -' agregaColumna("BITACORAGPS", "BAN_GEOB", "TEXT") + agregaColumna("BITACORAGPS", "BAN_GEOB", "TEXT") contadorIniciarVenta = 0 cargamosPanel Return Me